]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.c
Bug fixes for FrameworkHiiToUefiHiiThunk;
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / HiiDatabase.c
index e33b2e277281db7306221a55c39b77b61e2acf5a..50b902a952cd08b01b8cb3eb79c2a36b06df983b 100644 (file)
@@ -15,16 +15,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "HiiDatabase.h"\r
 \r
-EFI_HII_THUNK_PRIVATE_DATA *mHiiThunkPrivateData;\r
-\r
-EFI_HII_THUNK_PRIVATE_DATA mHiiThunkPrivateDataTempate = {\r
-  //Signature\r
-  EFI_HII_THUNK_DRIVER_DATA_SIGNATURE \r
-  ,\r
-  //Handle\r
-  (EFI_HANDLE) NULL\r
-  ,\r
-  { //Hii\r
+HII_THUNK_PRIVATE_DATA *mHiiThunkPrivateData;\r
+\r
+HII_THUNK_PRIVATE_DATA mHiiThunkPrivateDataTempate = {\r
+  HII_THUNK_PRIVATE_DATA_SIGNATURE,\r
+  (EFI_HANDLE) NULL,\r
+  {\r
     HiiNewPack,\r
     HiiRemovePack,\r
     HiiFindHandles,\r
@@ -46,18 +42,21 @@ EFI_HII_THUNK_PRIVATE_DATA mHiiThunkPrivateDataTempate = {
     \r
     HiiGetKeyboardLayout\r
   },\r
+\r
+  //\r
   //StaticHiiHandle\r
   //The FRAMEWORK_EFI_HII_HANDLE starts from 1 \r
   // and increase upwords untill reach the value of StaticPureUefiHiiHandle. \r
   // The code will assert to prevent overflow.\r
-  (FRAMEWORK_EFI_HII_HANDLE) 1 \r
-  ,\r
+  (FRAMEWORK_EFI_HII_HANDLE) 1,\r
+\r
+  //\r
   //StaticPureUefiHiiHandle\r
   //The Static FRAMEWORK_EFI_HII_HANDLE starts from 0xFFFF \r
   // and decrease downwords untill reach the value of StaticHiiHandle. \r
   // The code will assert to prevent overflow.\r
-  (FRAMEWORK_EFI_HII_HANDLE) 0xFFFF \r
-  ,\r
+  //\r
+  (FRAMEWORK_EFI_HII_HANDLE) 0xFFFF,\r
   {\r
     NULL, NULL                  //HiiHandleLinkList\r
   },\r
@@ -66,6 +65,7 @@ EFI_HII_THUNK_PRIVATE_DATA mHiiThunkPrivateDataTempate = {
 EFI_FORMBROWSER_THUNK_PRIVATE_DATA mBrowserThunkPrivateDataTemplate = {\r
   EFI_FORMBROWSER_THUNK_PRIVATE_DATA_SIGNATURE,\r
   (EFI_HANDLE) NULL,\r
+  (HII_THUNK_PRIVATE_DATA *) NULL,\r
   {\r
     ThunkSendForm,\r
     ThunkCreatePopUp\r
@@ -74,276 +74,15 @@ EFI_FORMBROWSER_THUNK_PRIVATE_DATA mBrowserThunkPrivateDataTemplate = {
 \r
 \r
 CONST EFI_HII_DATABASE_PROTOCOL            *mHiiDatabase;\r
-CONST EFI_HII_FONT_PROTOCOL                *mHiiFontProtocol;\r
 CONST EFI_HII_IMAGE_PROTOCOL               *mHiiImageProtocol;\r
 CONST EFI_HII_STRING_PROTOCOL              *mHiiStringProtocol;\r
 CONST EFI_HII_CONFIG_ROUTING_PROTOCOL      *mHiiConfigRoutingProtocol;\r
+CONST EFI_FORM_BROWSER2_PROTOCOL           *mFormBrowser2Protocol;\r
 \r
-EFI_STATUS\r
-RegisterUefiHiiHandle (\r
-  EFI_HII_THUNK_PRIVATE_DATA *Private,\r
-  EFI_HII_HANDLE             UefiHiiHandle\r
- )\r
-{\r
-  EFI_STATUS     Status;\r
-  EFI_GUID       PackageGuid;\r
-  HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMappingEntry;\r
-\r
-  HandleMappingEntry = AllocateZeroPool (sizeof (*HandleMappingEntry));\r
-  HandleMappingEntry->Signature = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_SIGNATURE;\r
-\r
-  Status = AssignPureUefiHiiHandle (Private, &HandleMappingEntry->FrameworkHiiHandle);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  \r
-  HandleMappingEntry->UefiHiiHandle = UefiHiiHandle;\r
-  Status = HiiLibExtractGuidFromHiiHandle (UefiHiiHandle, &PackageGuid);\r
-  ASSERT_EFI_ERROR (Status);\r
-  \r
-  CopyGuid(&HandleMappingEntry->TagGuid, &PackageGuid);\r
-  \r
-  InsertTailList (&Private->HiiThunkHandleMappingDBListHead, &HandleMappingEntry->List);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-UnRegisterUefiHiiHandle (\r
-  EFI_HII_THUNK_PRIVATE_DATA *Private,\r
-  EFI_HII_HANDLE UefiHiiHandle\r
- )\r
-{\r
-  HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY     *MapEntry;\r
-\r
-  MapEntry = UefiHiiHandleToMapDatabaseEntry (Private, UefiHiiHandle);\r
-  ASSERT (MapEntry != NULL);\r
-  \r
-  RemoveEntryList (&MapEntry->List);\r
 \r
-  FreePool (MapEntry);\r
-    \r
-  return EFI_SUCCESS;\r
-}\r
 \r
-EFI_STATUS\r
-EFIAPI\r
-AddPackNotify (\r
-  IN UINT8                              PackageType,\r
-  IN CONST EFI_GUID                     *PackageGuid,\r
-  IN CONST EFI_HII_PACKAGE_HEADER       *Package,\r
-  IN EFI_HII_HANDLE                     Handle,\r
-  IN EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType\r
-  )\r
-{\r
-  EFI_STATUS   Status;\r
-  EFI_HII_THUNK_PRIVATE_DATA *Private;\r
-\r
-  ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS);\r
-  ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK);\r
-\r
-  Status  = EFI_SUCCESS;\r
-  Private = mHiiThunkPrivateData;\r
 \r
-  if (mInFrameworkHiiNewPack) {\r
-    return EFI_SUCCESS;\r
-  }\r
 \r
-  //\r
-  // We only create a MapEntry if the Uefi Hii Handle is only already registered\r
-  // by the HII Thunk Layer.\r
-  //\r
-  if (UefiHiiHandleToMapDatabaseEntry (Private, Handle) == NULL) {\r
-    Status = RegisterUefiHiiHandle (Private, Handle);\r
-  } \r
-\r
-  return Status;  \r
-}\r
-EFI_STATUS\r
-EFIAPI\r
-NewPackNotify (\r
-  IN UINT8                              PackageType,\r
-  IN CONST EFI_GUID                     *PackageGuid,\r
-  IN CONST EFI_HII_PACKAGE_HEADER       *Package,\r
-  IN EFI_HII_HANDLE                     Handle,\r
-  IN EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType\r
-  )\r
-{\r
-  EFI_STATUS   Status;\r
-  EFI_HII_THUNK_PRIVATE_DATA *Private;\r
-\r
-  ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS);\r
-  ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK);\r
-\r
-  if (mInFrameworkHiiNewPack) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  Status  = EFI_SUCCESS;\r
-  Private = mHiiThunkPrivateData;\r
-\r
-  //\r
-  // We only\r
-  //\r
-  if (UefiHiiHandleToMapDatabaseEntry (Private, Handle) == NULL) {\r
-    Status = RegisterUefiHiiHandle (Private, Handle);\r
-  } \r
-\r
-  return Status;\r
-}\r
-\r
-BOOLEAN\r
-IsLastStringPack (\r
-  IN CONST EFI_HII_PACKAGE_HEADER       *Package,\r
-  IN EFI_HII_HANDLE                     Handle\r
-  )\r
-{\r
-  EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
-  UINTN                        BufferSize;\r
-  EFI_STATUS                   Status;\r
-  EFI_HII_PACKAGE_HEADER       *PackageHdrPtr;\r
-  EFI_HII_PACKAGE_HEADER       PackageHeader;\r
-  BOOLEAN                      Match;\r
-\r
-  Match = FALSE;\r
-  HiiPackageList = NULL;\r
-  BufferSize = 0;\r
-  Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
-  ASSERT (Status != EFI_NOT_FOUND);\r
-  \r
-  if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    HiiPackageList = AllocateZeroPool (BufferSize);\r
-    ASSERT (HiiPackageList != NULL);\r
-\r
-    Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
-  }\r
-\r
-  \r
-  PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) HiiPackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
-  CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
-\r
-  Status = EFI_SUCCESS;\r
-\r
-  while (PackageHeader.Type != EFI_HII_PACKAGE_END) {\r
-    switch (PackageHeader.Type) {\r
-      case EFI_HII_PACKAGE_STRINGS:\r
-        if (CompareMem (Package, PackageHdrPtr, Package->Length) != 0) {\r
-          FreePool (HiiPackageList);\r
-          return FALSE;\r
-        }\r
-      break;      \r
-      default:\r
-        break;\r
-    }\r
-    //\r
-    // goto header of next package\r
-    //\r
-    PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);\r
-    CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
-  }\r
-\r
-  FreePool (HiiPackageList);\r
-  return TRUE;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RemovePackNotify (\r
-  IN UINT8                              PackageType,\r
-  IN CONST EFI_GUID                     *PackageGuid,\r
-  IN CONST EFI_HII_PACKAGE_HEADER       *Package,\r
-  IN EFI_HII_HANDLE                     Handle,\r
-  IN EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType\r
-  )\r
-{\r
-  EFI_STATUS   Status;\r
-  EFI_HII_THUNK_PRIVATE_DATA *Private;\r
-  HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY * MapEntry;\r
-\r
-  Status = EFI_SUCCESS;\r
-\r
-  ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS);\r
-  ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK);\r
-\r
-  if (mInFrameworkHiiRemovePack) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  Private = mHiiThunkPrivateData;\r
-\r
-  MapEntry = UefiHiiHandleToMapDatabaseEntry (Private, Handle);\r
-\r
-  if (MapEntry->FrameworkHiiHandle > Private->StaticHiiHandle) {\r
-    //\r
-    // This is a PackageList registered using UEFI HII Protocol Instance.\r
-    // The MapEntry->TagGuid for this type of PackageList is a auto generated GUID\r
-    // to link StringPack with IfrPack.\r
-    // RemovePackNotify is only used to remove PackageList when it is removed by\r
-    // calling mHiiDatabase->RemovePackageList interface.\r
-    if (IsLastStringPack (Package, Handle)) {\r
-      Status = UnRegisterUefiHiiHandle (Private, Handle);\r
-    }\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-MapUefiHiiHandles (\r
-  EFI_HII_THUNK_PRIVATE_DATA *Private\r
-  )\r
-{\r
-  UINTN          HandleBufferLength;\r
-  EFI_HII_HANDLE *HandleBuffer;\r
-  EFI_STATUS     Status;\r
-  UINTN          Index;\r
-  HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY * MapEntry;\r
-\r
-  HandleBufferLength = 0;\r
-  HandleBuffer       = NULL;\r
-  Status = mHiiDatabase->ListPackageLists (\r
-                            mHiiDatabase,\r
-                            EFI_HII_PACKAGE_TYPE_ALL,\r
-                            NULL,\r
-                            &HandleBufferLength,\r
-                            HandleBuffer\r
-                            );\r
-  if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {\r
-    //\r
-    // As no package is registered to UEFI HII Database, EFI_SUCCESS is returned.\r
-    // \r
-    //\r
-    if (Status == EFI_NOT_FOUND) {\r
-      return EFI_SUCCESS;\r
-    } else {\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  HandleBuffer = AllocateZeroPool (HandleBufferLength);\r
-  Status = mHiiDatabase->ListPackageLists (\r
-                            mHiiDatabase,\r
-                            EFI_HII_PACKAGE_TYPE_ALL,\r
-                            NULL,\r
-                            &HandleBufferLength,\r
-                            HandleBuffer\r
-                            );\r
-\r
-  for (Index = 0; Index < HandleBufferLength / sizeof (EFI_HII_HANDLE); Index++) {\r
-    MapEntry = UefiHiiHandleToMapDatabaseEntry (Private, HandleBuffer[Index]);\r
-    //\r
-    // Only register those UEFI HII Handles that are registered using the UEFI HII database interface.\r
-    //\r
-    if (MapEntry == NULL) {\r
-      Status = RegisterUefiHiiHandle (Private, HandleBuffer[Index]);\r
-      ASSERT_EFI_ERROR (Status);\r
-    }\r
-  }\r
-\r
-  return EFI_SUCCESS;                  \r
-}\r
 \r
 EFI_STATUS\r
 EFIAPI\r
@@ -365,17 +104,21 @@ Returns:
 \r
 --*/\r
 {\r
-  EFI_HII_THUNK_PRIVATE_DATA *HiiData;\r
-  EFI_HANDLE                 Handle;\r
-  EFI_STATUS                 Status;\r
+  HII_THUNK_PRIVATE_DATA *Private;\r
+  EFI_HANDLE              Handle;\r
+  EFI_STATUS              Status;\r
+  UINTN                   BufferLength;\r
+  EFI_HII_HANDLE          *Buffer;\r
+  UINTN                   Index;\r
+  \r
 \r
   ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiHiiProtocolGuid);\r
 \r
-  HiiData = AllocateCopyPool (sizeof (EFI_HII_THUNK_PRIVATE_DATA), &mHiiThunkPrivateDataTempate);\r
-  ASSERT (HiiData != NULL);\r
-  InitializeListHead (&HiiData->HiiThunkHandleMappingDBListHead);\r
+  Private = AllocateCopyPool (sizeof (HII_THUNK_PRIVATE_DATA), &mHiiThunkPrivateDataTempate);\r
+  ASSERT (Private != NULL);\r
+  InitializeListHead (&Private->ThunkContextListHead);\r
 \r
-  mHiiThunkPrivateData = HiiData;\r
+  mHiiThunkPrivateData = Private;\r
 \r
   Status = gBS->LocateProtocol (\r
                   &gEfiHiiDatabaseProtocolGuid,\r
@@ -385,55 +128,58 @@ Returns:
   ASSERT_EFI_ERROR (Status);\r
 \r
   Status = gBS->LocateProtocol (\r
-                  &gEfiHiiFontProtocolGuid,\r
+                  &gEfiHiiStringProtocolGuid,\r
                   NULL,\r
-                  (VOID **) &mHiiFontProtocol\r
+                  (VOID **) &mHiiStringProtocol\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   Status = gBS->LocateProtocol (\r
-                  &gEfiHiiImageProtocolGuid,\r
+                  &gEfiHiiConfigRoutingProtocolGuid,\r
                   NULL,\r
-                  (VOID **) &mHiiImageProtocol\r
+                  (VOID **) &mHiiConfigRoutingProtocol\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  Status = gBS->LocateProtocol (\r
-                  &gEfiHiiStringProtocolGuid,\r
-                  NULL,\r
-                  (VOID **) &mHiiStringProtocol\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
 \r
   Status = gBS->LocateProtocol (\r
-                  &gEfiHiiConfigRoutingProtocolGuid,\r
+                  &gEfiFormBrowser2ProtocolGuid,\r
                   NULL,\r
-                  (VOID **) &mHiiConfigRoutingProtocol\r
+                  (VOID **) &mFormBrowser2Protocol\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+\r
+  \r
+\r
   //\r
   // Install protocol interface\r
   //\r
-  Handle = NULL;\r
   Status = gBS->InstallProtocolInterface (\r
-                  &HiiData->Handle,\r
+                  &Private->Handle,\r
                   &gEfiHiiProtocolGuid,\r
                   EFI_NATIVE_INTERFACE,\r
-                  (VOID *) &HiiData->Hii\r
+                  (VOID *) &Private->Hii\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  Status = MapUefiHiiHandles (HiiData);\r
-  ASSERT_EFI_ERROR (Status);\r
+  Status = HiiLibListPackageLists (EFI_HII_PACKAGE_STRINGS, NULL, &BufferLength, &Buffer);\r
+  if (Status == EFI_SUCCESS) {\r
+    for (Index = 0; Index < BufferLength / sizeof (EFI_HII_HANDLE); Index++) {\r
+      CreateThunkContextForUefiHiiHandle (Private, Buffer[Index]);\r
+      ASSERT_EFI_ERROR (Status);\r
+    }\r
+\r
+    FreePool (Buffer);\r
+  }\r
 \r
   Status = mHiiDatabase->RegisterPackageNotify (\r
                            mHiiDatabase,\r
                            EFI_HII_PACKAGE_STRINGS,\r
                            NULL,\r
-                           NewPackNotify,\r
+                           NewOrAddPackNotify,\r
                            EFI_HII_DATABASE_NOTIFY_NEW_PACK,\r
-                           &HiiData->NewPackNotifyHandle\r
+                           &Handle\r
                            );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
@@ -441,9 +187,29 @@ Returns:
                            mHiiDatabase,\r
                            EFI_HII_PACKAGE_STRINGS,\r
                            NULL,\r
-                           AddPackNotify,\r
+                           NewOrAddPackNotify,\r
+                           EFI_HII_DATABASE_NOTIFY_ADD_PACK,\r
+                           &Handle\r
+                           );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = mHiiDatabase->RegisterPackageNotify (\r
+                           mHiiDatabase,\r
+                           EFI_HII_PACKAGE_FORM,\r
+                           NULL,\r
+                           NewOrAddPackNotify,\r
+                           EFI_HII_DATABASE_NOTIFY_NEW_PACK,\r
+                           &Handle\r
+                           );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = mHiiDatabase->RegisterPackageNotify (\r
+                           mHiiDatabase,\r
+                           EFI_HII_PACKAGE_FORM,\r
+                           NULL,\r
+                           NewOrAddPackNotify,\r
                            EFI_HII_DATABASE_NOTIFY_ADD_PACK,\r
-                           &HiiData->AddPackNotifyHandle\r
+                           &Handle\r
                            );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
@@ -453,10 +219,11 @@ Returns:
                            NULL,\r
                            RemovePackNotify,\r
                            EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
-                           &HiiData->RemovePackNotifyHandle\r
+                           &Handle\r
                            );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  mBrowserThunkPrivateDataTemplate.ThunkPrivate = Private;\r
   Status = gBS->InstallProtocolInterface (\r
                   &mBrowserThunkPrivateDataTemplate.Handle,\r
                   &gEfiFormBrowserProtocolGuid,\r
@@ -487,22 +254,24 @@ Returns:
 --*/\r
 {\r
   UINT16                                     Count;\r
-  LIST_ENTRY                                *ListEntry;\r
-  HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
-  EFI_HII_THUNK_PRIVATE_DATA               *Private;\r
+  LIST_ENTRY                                *Link;\r
+  HII_THUNK_CONTEXT *ThunkContext;\r
+  HII_THUNK_PRIVATE_DATA               *Private;\r
 \r
   if (HandleBufferLength == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);  \r
+  Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);  \r
 \r
+  //\r
+  // Count the number of handles.\r
+  //\r
   Count = 0;\r
-  for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;\r
-       ListEntry != &Private->HiiThunkHandleMappingDBListHead;\r
-       ListEntry = ListEntry->ForwardLink\r
-       ) {\r
+  Link = GetFirstNode (&Private->ThunkContextListHead);\r
+  while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
     Count++;\r
+    Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
   }\r
 \r
   if (Count > *HandleBufferLength) {\r
@@ -510,22 +279,71 @@ Returns:
     return EFI_BUFFER_TOO_SMALL;\r
   }\r
 \r
+  //\r
+  // Output the handles.\r
+  //\r
   Count = 0;\r
-  for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;\r
-       ListEntry != &Private->HiiThunkHandleMappingDBListHead;\r
-       ListEntry = ListEntry->ForwardLink\r
-       ) {\r
-    HandleMapEntry = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry);\r
+  Link = GetFirstNode (&Private->ThunkContextListHead);\r
+  while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
+\r
+    ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
+    Handle[Count] = ThunkContext->FwHiiHandle;\r
 \r
-    Handle[Count] = HandleMapEntry->FrameworkHiiHandle;\r
-  \r
     Count++;\r
-  }  \r
+    Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
+\r
+  }\r
 \r
   *HandleBufferLength = (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE));\r
   return EFI_SUCCESS;\r
 }\r
 \r
+EFI_STATUS\r
+LangCodes3066To639 (\r
+  IN CHAR8 *LangCodes3066,\r
+  IN CHAR8 **LangCodes639\r
+  )\r
+{\r
+  CHAR8                      *AsciiLangCodes;\r
+  CHAR8                      Lang[RFC_3066_ENTRY_SIZE];\r
+  UINTN                      Index;\r
+  UINTN                      Count;\r
+  EFI_STATUS                 Status;\r
+\r
+  ASSERT (LangCodes3066 != NULL);\r
+  ASSERT (LangCodes639 != NULL);\r
+  \r
+  //\r
+  // Count the number of RFC 3066 language codes.\r
+  //\r
+  Index = 0;\r
+  AsciiLangCodes = LangCodes3066;\r
+  while (AsciiStrLen (AsciiLangCodes) != 0) {\r
+    HiiLibGetNextLanguage (&AsciiLangCodes, Lang);\r
+    Index++;\r
+  }\r
+\r
+  Count = Index;\r
+\r
+  //\r
+  // \r
+  //\r
+  *LangCodes639 = AllocateZeroPool (ISO_639_2_ENTRY_SIZE * Count + 1);\r
+  if (*LangCodes639 == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  AsciiLangCodes = LangCodes3066;\r
+\r
+  for (Index = 0; Index < Count; Index++) {\r
+    HiiLibGetNextLanguage (&AsciiLangCodes, Lang);\r
+    Status = ConvertRfc3066LanguageToIso639Language (Lang, *LangCodes639 + Index * ISO_639_2_ENTRY_SIZE);\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 EFI_STATUS\r
 EFIAPI\r
 HiiGetPrimaryLanguages (\r
@@ -545,46 +363,61 @@ Returns:
 \r
 --*/\r
 {\r
-  EFI_HII_THUNK_PRIVATE_DATA *Private;\r
+  HII_THUNK_PRIVATE_DATA     *Private;\r
   EFI_HII_HANDLE             UefiHiiHandle;\r
-  CHAR8                      *AsciiLanguageCodes;\r
-  CHAR16                     *UnicodeLanguageCodes;\r
+  CHAR8                      *LangCodes3066;\r
+  CHAR16                     *UnicodeLangCodes639;\r
+  CHAR8                      *LangCodes639;\r
+  EFI_STATUS                 Status;\r
 \r
-  Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
+  Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
 \r
-  \r
-  \r
-  UefiHiiHandle = FrameworkHiiHandleToUefiHiiHandle (Private, Handle);\r
+  UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle);\r
   if (UefiHiiHandle == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  AsciiLanguageCodes = HiiLibGetSupportedLanguages (UefiHiiHandle);\r
+  LangCodes3066 = HiiLibGetSupportedLanguages (UefiHiiHandle);\r
 \r
-  if (AsciiLanguageCodes == NULL) {\r
+  if (LangCodes3066 == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  UnicodeLanguageCodes = AllocateZeroPool (AsciiStrSize (AsciiLanguageCodes) * sizeof (CHAR16));\r
-  if (UnicodeLanguageCodes == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+\r
+  LangCodes639 = NULL;\r
+  Status = LangCodes3066To639 (LangCodes3066, &LangCodes639);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+  \r
+  UnicodeLangCodes639 = AllocateZeroPool (AsciiStrSize (LangCodes639) * sizeof (CHAR16));\r
+  if (UnicodeLangCodes639 == NULL) {\r
+    Status =  EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
   }\r
 \r
   //\r
-  // The language returned is in RFC 3066 format.\r
+  // The language returned is in RFC 639-2 format.\r
   //\r
-  *LanguageString = AsciiStrToUnicodeStr (AsciiLanguageCodes, UnicodeLanguageCodes);\r
+  AsciiStrToUnicodeStr (LangCodes639, UnicodeLangCodes639);\r
+  *LanguageString = UnicodeLangCodes639;\r
 \r
-  return EFI_SUCCESS;\r
+Done:\r
+  FreePool (LangCodes3066);\r
+  SafeFreePool (LangCodes639);\r
+\r
+  return Status;\r
 }\r
 \r
+\r
+\r
 EFI_STATUS\r
 EFIAPI\r
 HiiGetSecondaryLanguages (\r
-  IN  EFI_HII_PROTOCOL      *This,\r
-  IN  FRAMEWORK_EFI_HII_HANDLE         Handle,\r
-  IN  CHAR16                *PrimaryLanguage,\r
-  OUT EFI_STRING            *LanguageString\r
+  IN  EFI_HII_PROTOCOL              *This,\r
+  IN  FRAMEWORK_EFI_HII_HANDLE      Handle,\r
+  IN  CHAR16                        *PrimaryLanguage,\r
+  OUT EFI_STRING                    *LanguageString\r
   )\r
 /*++\r
 \r
@@ -599,75 +432,68 @@ Returns:
 \r
 --*/\r
 {\r
-  EFI_HII_THUNK_PRIVATE_DATA *Private;\r
+  HII_THUNK_PRIVATE_DATA *Private;\r
   EFI_HII_HANDLE             UefiHiiHandle;\r
-  CHAR8                      *AsciiPrimaryLanguage;\r
-  CHAR8                      *AsciiLanguageCodes;\r
-  CHAR16                     *UnicodeLanguageCodes;\r
+  CHAR8                      PrimaryLang3066[RFC_3066_ENTRY_SIZE];\r
+  CHAR8                      *PrimaryLang639;\r
+  CHAR8                      *SecLangCodes3066;\r
+  CHAR8                      *SecLangCodes639;\r
+  CHAR16                     *UnicodeSecLangCodes639;\r
+  EFI_STATUS                 Status;\r
 \r
-  Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
+  Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
 \r
-  \r
-  \r
-  UefiHiiHandle = FrameworkHiiHandleToUefiHiiHandle (Private, Handle);\r
+  SecLangCodes639         = NULL;\r
+  SecLangCodes3066        = NULL;\r
+  UnicodeSecLangCodes639 = NULL;\r
+\r
+  UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle);\r
   if (UefiHiiHandle == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  AsciiPrimaryLanguage = AllocateZeroPool (StrLen (PrimaryLanguage) + 1);\r
+  PrimaryLang639 = AllocateZeroPool (StrLen (PrimaryLanguage) + 1);\r
+  if (PrimaryLang639 == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
 \r
-  UnicodeStrToAsciiStr (PrimaryLanguage, AsciiPrimaryLanguage);\r
+  UnicodeStrToAsciiStr (PrimaryLanguage, PrimaryLang639);\r
 \r
-  AsciiLanguageCodes = HiiLibGetSupportedSecondaryLanguages (UefiHiiHandle, AsciiPrimaryLanguage);\r
+  Status = ConvertIso639LanguageToRfc3066Language (PrimaryLang639, PrimaryLang3066);\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
-  if (AsciiLanguageCodes == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
+  SecLangCodes3066 = HiiLibGetSupportedSecondaryLanguages (UefiHiiHandle, PrimaryLang3066);\r
+\r
+  if (SecLangCodes3066 == NULL) {\r
+    Status =  EFI_INVALID_PARAMETER;\r
+    goto Done;\r
   }\r
 \r
-  UnicodeLanguageCodes = AllocateZeroPool (AsciiStrSize (AsciiLanguageCodes) * sizeof (CHAR16));\r
-  if (UnicodeLanguageCodes == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+  Status = LangCodes3066To639 (SecLangCodes3066, &SecLangCodes639);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  UnicodeSecLangCodes639 = AllocateZeroPool (AsciiStrSize (SecLangCodes639) * sizeof (CHAR16));\r
+  if (UnicodeSecLangCodes639 == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
   }\r
 \r
   //\r
   // The language returned is in RFC 3066 format.\r
   //\r
-  *LanguageString = AsciiStrToUnicodeStr (AsciiLanguageCodes, UnicodeLanguageCodes);\r
+  *LanguageString = AsciiStrToUnicodeStr (SecLangCodes639, UnicodeSecLangCodes639);\r
 \r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI \r
-ThunkSendForm (\r
-  IN  EFI_FORM_BROWSER_PROTOCOL       *This,\r
-  IN  BOOLEAN                         UseDatabase,\r
-  IN  FRAMEWORK_EFI_HII_HANDLE        *Handle,\r
-  IN  UINTN                           HandleCount,\r
-  IN  FRAMEWORK_EFI_IFR_PACKET                  *Packet, OPTIONAL\r
-  IN  EFI_HANDLE                      CallbackHandle, OPTIONAL\r
-  IN  UINT8                           *NvMapOverride, OPTIONAL\r
-  IN  FRAMEWORK_EFI_SCREEN_DESCRIPTOR            *ScreenDimensions, OPTIONAL\r
-  OUT BOOLEAN                         *ResetRequired OPTIONAL\r
-  )\r
-{\r
-  ASSERT (FALSE);\r
-  return EFI_UNSUPPORTED;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI \r
-ThunkCreatePopUp (\r
-  IN  UINTN                           NumberOfLines,\r
-  IN  BOOLEAN                         HotKey,\r
-  IN  UINTN                           MaximumStringSize,\r
-  OUT CHAR16                          *StringBuffer,\r
-  OUT EFI_INPUT_KEY                   *KeyValue,\r
-  IN  CHAR16                          *String,\r
-  ...\r
-  )\r
-{\r
-  ASSERT (FALSE);\r
-  return EFI_UNSUPPORTED;\r
+Done:\r
+  \r
+  SafeFreePool (PrimaryLang639);\r
+  SafeFreePool (SecLangCodes639);\r
+  SafeFreePool (SecLangCodes3066);\r
+  SafeFreePool (UnicodeSecLangCodes639);\r
+  \r
+  return Status;\r
 }\r
 \r
\r