]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Package.c
Bug fixes for FrameworkHiiToUefiHiiThunk;
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / Package.c
index 847a8fbf574d2aa508e7c6c89f2d9e6914fefb6d..994c67b9a053a69b02e4f6d5f1efc36f40ff8571 100644 (file)
@@ -1,6 +1,5 @@
 /**@file\r
-\r
-  This file contains the keyboard processing code to the HII database.\r
+  Implement protocol interface related to package registrations.\r
 \r
 Copyright (c) 2006 - 2008, Intel Corporation\r
 All rights reserved. This program and the accompanying materials\r
@@ -17,42 +16,44 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include "HiiDatabase.h"\r
 \r
 \r
-BOOLEAN mInFrameworkHiiNewPack = FALSE;\r
-BOOLEAN mInFrameworkHiiRemovePack = FALSE;\r
+STATIC BOOLEAN mInFrameworkHiiNewPack = FALSE;\r
+STATIC BOOLEAN mInFrameworkHiiRemovePack = FALSE;\r
+BOOLEAN mInFrameworkUpdatePakcage = FALSE;\r
 \r
 \r
 EFI_STATUS\r
-GetIfrAndStringPackNum (\r
+GetPackageCount (\r
   IN CONST EFI_HII_PACKAGES               *Packages,\r
-  UINTN                                   *IfrPackNum,\r
-  UINTN                                   *StringPackNum\r
+  UINTN                                   *IfrPackageCount,\r
+  UINTN                                   *StringPackageCount\r
   )\r
 {\r
   UINTN                         Index;\r
   TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
 \r
   ASSERT (Packages != NULL);\r
-  ASSERT (IfrPackNum != NULL);\r
-  ASSERT (StringPackNum != NULL);\r
+  ASSERT (IfrPackageCount != NULL);\r
+  ASSERT (StringPackageCount != NULL);\r
 \r
-  *IfrPackNum = 0;\r
-  *StringPackNum = 0;\r
+  *IfrPackageCount = 0;\r
+  *StringPackageCount = 0;\r
 \r
   TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) (((UINT8 *) &Packages->GuidId) + sizeof (Packages->GuidId));\r
+  \r
   for (Index = 0; Index < Packages->NumberOfPackages; Index++) {\r
     //\r
     // BugBug: The current UEFI HII build tool generate a binary in the format defined in: \r
     // TIANO_AUTOGEN_PACKAGES_HEADER. We assume that all packages generated in\r
-    // this binary is with same package type. So the returned IfrPackNum and StringPackNum\r
+    // this binary is with same package type. So the returned IfrPackageCount and StringPackageCount\r
     // may not be the exact number of valid package number in the binary generated \r
     // by HII Build tool.\r
     //\r
     switch (TianoAutogenPackageHdrArray[Index]->PackageHeader.Type) {\r
       case EFI_HII_PACKAGE_FORM:\r
-        *IfrPackNum += 1;\r
+        *IfrPackageCount += 1;\r
         break;\r
       case EFI_HII_PACKAGE_STRINGS:\r
-        *StringPackNum += 1;\r
+        *StringPackageCount += 1;\r
         break;\r
 \r
       case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
@@ -74,71 +75,6 @@ GetIfrAndStringPackNum (
   return EFI_SUCCESS;\r
 }\r
 \r
-EFI_STATUS \r
-LibExportPackageLists (\r
-  IN EFI_HII_HANDLE                    UefiHiiHandle,\r
-  OUT EFI_HII_PACKAGE_LIST_HEADER      **PackageListHeader,\r
-  OUT UINTN                            *PackageListSize\r
-  )\r
-{\r
-  EFI_STATUS                       Status;\r
-  UINTN                            Size;\r
-  EFI_HII_PACKAGE_LIST_HEADER      *PackageListHdr;\r
-\r
-  ASSERT (PackageListSize != NULL);\r
-  ASSERT (PackageListHeader != NULL);\r
-\r
-  Size = 0;\r
-  PackageListHdr = NULL;\r
-  Status = mHiiDatabase->ExportPackageLists (\r
-                                      mHiiDatabase,\r
-                                      UefiHiiHandle,\r
-                                      &Size,\r
-                                      PackageListHdr\r
-                                      );\r
-  ASSERT_EFI_ERROR (Status == EFI_BUFFER_TOO_SMALL);\r
-  if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    PackageListHdr = AllocateZeroPool (Size);\r
-    ASSERT (PackageListHdr != NULL);\r
-    \r
-    if (PackageListHeader == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    } else {\r
-      Status = mHiiDatabase->ExportPackageLists (\r
-                                          mHiiDatabase,\r
-                                          UefiHiiHandle,\r
-                                          &Size,\r
-                                          PackageListHdr\r
-                                           );\r
-      ASSERT_EFI_ERROR (Status);\r
-    }\r
-  }\r
-\r
-  if (!EFI_ERROR (Status)) {\r
-    *PackageListHeader = PackageListHdr;\r
-    *PackageListSize   = Size;\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-InsertStringPackagesToIfrPackageList (\r
-  IN CONST EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader,\r
-  IN EFI_HII_HANDLE                    UefiHiiHandle  \r
- )\r
-{\r
-  EFI_STATUS                  Status;\r
-  Status = mHiiDatabase->UpdatePackageList (\r
-                                        mHiiDatabase,\r
-                                        UefiHiiHandle,\r
-                                        StringPackageListHeader\r
-                                        );\r
-\r
-  return Status;\r
-}\r
-\r
-\r
 /**\r
   Removes a node from a doubly linked list, and returns the node that follows\r
   the removed node.\r
@@ -161,27 +97,53 @@ InsertStringPackagesToIfrPackageList (
 \r
 **/\r
 EFI_STATUS\r
-AddStringPackagesToMatchingIfrPackageList (\r
-  IN       EFI_HII_THUNK_PRIVATE_DATA  *Private,\r
+FindPackListWithOnlyIfrPackAndAddStringPack (\r
+  IN       HII_THUNK_PRIVATE_DATA      *Private,\r
+  IN       HII_THUNK_CONTEXT            *StringPackageThunkContext,\r
   IN CONST EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader\r
   )\r
 {\r
   EFI_STATUS                 Status;\r
-  LIST_ENTRY                 *ListEntry;\r
-  HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
-\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
-    if (CompareGuid (&StringPackageListHeader->PackageListGuid, &HandleMapEntry->TagGuid)) {\r
-      Status = InsertStringPackagesToIfrPackageList (StringPackageListHeader, HandleMapEntry->UefiHiiHandle);\r
+  LIST_ENTRY                 *Link;\r
+  HII_THUNK_CONTEXT *ThunkContext;\r
+\r
+  Link = GetFirstNode (&Private->ThunkContextListHead);\r
+  while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
+\r
+    ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
+\r
+    if (StringPackageThunkContext != ThunkContext) {\r
+      //\r
+      // Skip the String Package Thunk Entry itself.\r
+      //\r
+    \r
+      if (CompareGuid (&StringPackageListHeader->PackageListGuid, &ThunkContext->TagGuid)) {\r
+\r
+        ASSERT (ThunkContext->StringPackageCount == 0 && ThunkContext->IfrPackageCount == 1);\r
+\r
+        ThunkContext->StringPackageCount = GetPackageCountByType (StringPackageListHeader, EFI_HII_PACKAGE_STRINGS);\r
+        \r
+        Status = mHiiDatabase->UpdatePackageList (\r
+                                              mHiiDatabase,\r
+                                              ThunkContext->UefiHiiHandle,\r
+                                              StringPackageListHeader\r
+                                              );\r
+        ASSERT (Status != EFI_NOT_FOUND);\r
+        \r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
+        }\r
+      }\r
     }\r
+    \r
+    Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
   }\r
   \r
+\r
   return EFI_NOT_FOUND;\r
 }\r
+\r
+\r
 EFI_HII_PACKAGE_LIST_HEADER *\r
 PrepareUefiPackageListFromFrameworkHiiPackages (\r
   IN CONST EFI_HII_PACKAGES            *Packages,\r
@@ -260,41 +222,169 @@ GenerateGuidId (
 }\r
 \r
 EFI_STATUS\r
-FindAndAddStringPackageToIfrPackageList(\r
-  EFI_HII_THUNK_PRIVATE_DATA  *Private,\r
-  EFI_GUID                    *GuidId,\r
-  EFI_HII_HANDLE              UefiIfrHiiHandle\r
+FindStringPackAndAddToPackListWithOnlyIfrPack(\r
+  IN HII_THUNK_PRIVATE_DATA          *Private,\r
+  IN HII_THUNK_CONTEXT                *IfrThunkContext\r
   )\r
 {\r
-  EFI_STATUS                 Status;\r
-  LIST_ENTRY                 *ListEntry;\r
-  HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
-  EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader;\r
-  UINTN                      Size;\r
-\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
-    if (CompareGuid (GuidId, &HandleMapEntry->TagGuid) && (!HandleMapEntry->DoesPackageListImportStringPackages)) {\r
-      Status = LibExportPackageLists (HandleMapEntry->UefiHiiHandle, &StringPackageListHeader, &Size);\r
-      ASSERT_EFI_ERROR (Status);\r
+  EFI_STATUS                      Status;\r
+  LIST_ENTRY                      *Link;\r
+  EFI_HII_PACKAGE_LIST_HEADER     *StringPackageListHeader;\r
+  UINTN                           Size;\r
+  HII_THUNK_CONTEXT                *ThunkContext;\r
 \r
-      //\r
-      // Add Function to only get only String Packages from the Package List\r
-      //\r
+  \r
+  Link = GetFirstNode (&Private->ThunkContextListHead);\r
+\r
+  while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
+\r
+    ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
+\r
+    if (ThunkContext != IfrThunkContext) {\r
+      if (CompareGuid (&IfrThunkContext->TagGuid, &ThunkContext->TagGuid) && (ThunkContext->IfrPackageCount == 0)) {\r
+        Status = HiiLibExportPackageLists (ThunkContext->UefiHiiHandle, &StringPackageListHeader, &Size);\r
+        ASSERT_EFI_ERROR (Status);\r
+\r
+        IfrThunkContext->StringPackageCount = GetPackageCountByType (StringPackageListHeader, EFI_HII_PACKAGE_STRINGS);\r
+        //\r
+        // Add Function to only get only String Packages from the Package List\r
+        //\r
+        Status = mHiiDatabase->UpdatePackageList (\r
+                                  mHiiDatabase,\r
+                                  IfrThunkContext->UefiHiiHandle,\r
+                                  StringPackageListHeader\r
+                                  );\r
+        ASSERT_EFI_ERROR (Status);\r
+        \r
+        FreePool (StringPackageListHeader);\r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
 \r
-      Status = InsertStringPackagesToIfrPackageList (StringPackageListHeader, UefiIfrHiiHandle);\r
-      ASSERT_EFI_ERROR (Status);\r
+    Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+\r
+}\r
+\r
+HII_THUNK_CONTEXT *\r
+CreateThunkContext (\r
+  IN  HII_THUNK_PRIVATE_DATA      *Private,\r
+  IN  UINTN                       StringPackageCount,\r
+  IN  UINTN                       IfrPackageCount\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  HII_THUNK_CONTEXT            *ThunkContext;\r
+\r
+  ThunkContext = AllocateZeroPool (sizeof (HII_THUNK_CONTEXT));\r
+  ASSERT (ThunkContext != NULL);\r
+  \r
+  ThunkContext->Signature = HII_THUNK_CONTEXT_SIGNATURE;\r
+  ThunkContext->IfrPackageCount = IfrPackageCount;\r
+  ThunkContext->StringPackageCount = StringPackageCount;\r
+  Status = AssignFrameworkHiiHandle (Private, TRUE, &ThunkContext->FwHiiHandle);\r
+  if (EFI_ERROR (Status)) {\r
+    return NULL;\r
+  }\r
+\r
+  InitializeListHead (&ThunkContext->QuestionIdMapListHead);\r
+  InitializeListHead (&ThunkContext->OneOfOptionMapListHead);\r
+\r
+\r
+  return ThunkContext;\r
+     \r
+}\r
+\r
+VOID\r
+FreeFrameworkHiiHandle (\r
+  IN  HII_THUNK_PRIVATE_DATA      *Private,\r
+  IN  FRAMEWORK_EFI_HII_HANDLE    FwHandle\r
+  )\r
+{\r
+  //\r
+  // TODO: \r
+  //\r
+  \r
+  return;\r
+}\r
+\r
+VOID\r
+DestoryOneOfOptionMap (\r
+  IN LIST_ENTRY     *OneOfOptionMapListHead\r
+  )\r
+{\r
+  ONE_OF_OPTION_MAP         *Map;\r
+  ONE_OF_OPTION_MAP_ENTRY   *MapEntry;\r
+  LIST_ENTRY                *Link;\r
+  LIST_ENTRY                *Link2;\r
+\r
+  while (!IsListEmpty (OneOfOptionMapListHead)) {\r
+    Link = GetFirstNode (OneOfOptionMapListHead);\r
+    \r
+    Map = ONE_OF_OPTION_MAP_FROM_LINK (Link);\r
+\r
+    while (!IsListEmpty (&Map->OneOfOptionMapEntryListHead)) {\r
+      Link2 = GetFirstNode (&Map->OneOfOptionMapEntryListHead);\r
       \r
-      FreePool (StringPackageListHeader);\r
-      return EFI_SUCCESS;\r
+      MapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link);\r
+\r
+      RemoveEntryList (Link2);\r
+\r
+      FreePool (MapEntry);\r
     }\r
+\r
+    RemoveEntryList (Link);\r
+    FreePool (Map);\r
   }\r
+}\r
 \r
-  return EFI_NOT_FOUND;\r
+VOID\r
+DestroyQuestionIdMap (\r
+  IN LIST_ENTRY     *QuestionIdMapListHead\r
+  )\r
+{\r
+  QUESTION_ID_MAP           *IdMap;\r
+  QUESTION_ID_MAP_ENTRY     *IdMapEntry;\r
+  LIST_ENTRY                *Link;\r
+  LIST_ENTRY                *Link2;\r
 \r
+  while (!IsListEmpty (QuestionIdMapListHead)) {\r
+    Link = GetFirstNode (QuestionIdMapListHead);\r
+    \r
+    IdMap = QUESTION_ID_MAP_FROM_LINK (Link);\r
+\r
+    while (!IsListEmpty (&IdMap->MapEntryListHead)) {\r
+      Link2 = GetFirstNode (&IdMap->MapEntryListHead);\r
+      \r
+      IdMapEntry = QUESTION_ID_MAP_ENTRY_FROM_LINK (Link);\r
+\r
+      RemoveEntryList (Link2);\r
+\r
+      FreePool (IdMapEntry);\r
+    }\r
+\r
+    RemoveEntryList (Link);\r
+    FreePool (IdMap);\r
+  }\r
+}\r
+\r
+VOID\r
+DestroyThunkContext (\r
+  IN  HII_THUNK_PRIVATE_DATA    *Private,\r
+  IN HII_THUNK_CONTEXT          *ThunkContext\r
+  )\r
+{\r
+  ASSERT (ThunkContext != NULL);\r
+\r
+  FreeFrameworkHiiHandle (Private, ThunkContext->FwHiiHandle);\r
+\r
+  DestroyQuestionIdMap (&ThunkContext->QuestionIdMapListHead);\r
+\r
+  DestoryOneOfOptionMap (&ThunkContext->OneOfOptionMapListHead);\r
+\r
+  FreePool (ThunkContext);\r
 }\r
 \r
 CONST EFI_GUID mAGuid = \r
@@ -302,53 +392,59 @@ CONST EFI_GUID mAGuid =
 \r
 EFI_STATUS\r
 UefiRegisterPackageList(\r
-  EFI_HII_THUNK_PRIVATE_DATA  *Private,\r
-  EFI_HII_PACKAGES            *Packages,\r
-  FRAMEWORK_EFI_HII_HANDLE    *Handle\r
+  IN  HII_THUNK_PRIVATE_DATA      *Private,\r
+  IN  EFI_HII_PACKAGES            *Packages,\r
+  OUT FRAMEWORK_EFI_HII_HANDLE    *Handle\r
   )\r
 {\r
   EFI_STATUS                  Status;\r
-  UINTN                       StringPackNum;\r
-  UINTN                       IfrPackNum;\r
-  EFI_HII_PACKAGE_LIST_HEADER *UefiPackageListHeader;\r
-  HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMappingEntry;\r
+  UINTN                       StringPackageCount;\r
+  UINTN                       IfrPackageCount;\r
+  EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
+  HII_THUNK_CONTEXT            *ThunkContext;\r
   EFI_GUID                    GuidId;\r
 \r
-  UefiPackageListHeader = NULL;\r
+  PackageListHeader = NULL;\r
 \r
-  Status = GetIfrAndStringPackNum (Packages, &IfrPackNum, &StringPackNum);\r
+  Status = GetPackageCount (Packages, &IfrPackageCount, &StringPackageCount);\r
   ASSERT_EFI_ERROR (Status);\r
-  //\r
-  // Thunk Layer only handle the following combinations of IfrPack, StringPkg and FontPack.\r
-  // Thunk Layer only allow zero or one IfrPack in the Package List.\r
-  //\r
-  if (IfrPackNum > 1) {\r
+  \r
+  if (IfrPackageCount > 1) {\r
+    //\r
+    // HII Thunk only handle package with 0 or 1 IFR package. \r
+    //\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  HandleMappingEntry = AllocateZeroPool (sizeof (*HandleMappingEntry));\r
-  ASSERT (HandleMappingEntry != NULL);\r
-  \r
-  HandleMappingEntry->Signature = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_SIGNATURE;\r
-  Status = AssignHiiHandle (Private, &HandleMappingEntry->FrameworkHiiHandle);\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
+  ThunkContext = CreateThunkContext (Private, StringPackageCount, IfrPackageCount);\r
+  if (ThunkContext == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  //\r
-  // Packages->GuidId may be NULL. In such case, caller of FramworkHii->NewPack is registering\r
-  // package with StringPack and IfrPack.\r
-  //\r
   if (Packages->GuidId == NULL) {\r
+    //\r
+    // UEFI HII Database require Package List GUID must be unique.\r
+    //\r
+    // If Packages->GuidId is NULL, the caller of FramworkHii->NewPack is registering\r
+    // packages with at least 1 StringPack and 1 IfrPack. Therefore, Packages->GuidId is\r
+    // not used as the name of the package list.  A GUID is generated as a Package List\r
+    // GUID.\r
+    //\r
+    ASSERT (StringPackageCount >=1 && IfrPackageCount == 1);\r
     Packages->GuidId = &GuidId;\r
     GenerateGuidId (&mAGuid, Packages->GuidId);\r
   } else {\r
+    //BugBug We need fix this.\r
+    //ASSERT (StringPackageCount == 0 || IfrPackageCount == 0);\r
     CopyGuid (&GuidId, Packages->GuidId);\r
   }\r
-  \r
-  CopyGuid (&HandleMappingEntry->TagGuid, Packages->GuidId);\r
 \r
-  if ((StringPackNum == 0) && (IfrPackNum != 0)) {\r
+  //\r
+  // Record the Package List GUID, it is used as a name for the package list by Framework HII.\r
+  //\r
+  CopyGuid (&ThunkContext->TagGuid, Packages->GuidId);\r
+\r
+  if ((StringPackageCount == 0) && (IfrPackageCount != 0)) {\r
     //\r
     // UEFI HII database does not allow two package list with the same GUID.\r
     // In Framework HII implementation, Packages->GuidId is used as an identifier to associate \r
@@ -361,68 +457,65 @@ UefiRegisterPackageList(
   // UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so\r
   // that Setup Utility can load the Buffer Storage using this protocol.\r
   //\r
-  if (IfrPackNum != 0) {\r
-    InstallDefaultUefiConfigAccessProtocol (Packages, HandleMappingEntry);\r
+  if (IfrPackageCount != 0) {\r
+    InstallDefaultConfigAccessProtocol (Packages, ThunkContext);\r
   }\r
-  UefiPackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &GuidId);\r
+  PackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &GuidId);\r
   Status = mHiiDatabase->NewPackageList (\r
               mHiiDatabase,\r
-              UefiPackageListHeader,  \r
-              HandleMappingEntry->UefiHiiDriverHandle,\r
-              &HandleMappingEntry->UefiHiiHandle\r
+              PackageListHeader,  \r
+              ThunkContext->UefiHiiDriverHandle,\r
+              &ThunkContext->UefiHiiHandle\r
               );\r
+\r
+  //\r
+  // BUGBUG: Remove when development is done\r
+  //\r
   ASSERT_EFI_ERROR (Status);\r
   if (EFI_ERROR (Status)) {\r
     goto Done;\r
   }\r
   \r
-  if (IfrPackNum == 0) {\r
-    if (StringPackNum != 0) {\r
+  if (IfrPackageCount == 0) {\r
+    if (StringPackageCount != 0) {\r
       //\r
-      // Look for a package list with IFR Pack which has already registed with HII Database\r
+      // Find if there is Package List with only IFR Package in the databasee with the same\r
+      // tag. If found, add the String Package to this Package List.\r
       //\r
-      HandleMappingEntry->IsPackageListWithOnlyStringPackages = TRUE;\r
-      Status = AddStringPackagesToMatchingIfrPackageList (\r
+      Status = FindPackListWithOnlyIfrPackAndAddStringPack (\r
                   Private,\r
-                  UefiPackageListHeader\r
+                  ThunkContext,\r
+                  PackageListHeader\r
                 );\r
 \r
-      if (!EFI_ERROR (Status) || Status == EFI_NOT_FOUND) {\r
-\r
-        if (Status == EFI_NOT_FOUND) {\r
-          Status = EFI_SUCCESS;\r
-        }\r
+      if (Status == EFI_NOT_FOUND) {\r
+        Status = EFI_SUCCESS;\r
       }\r
     }\r
   } else {\r
-    if (StringPackNum == 0) {\r
+    CreateQuestionIdMap (ThunkContext);\r
+    \r
+    if (StringPackageCount == 0) {\r
       //\r
       // Register the Package List to UEFI HII first.\r
       //\r
-      Status = FindAndAddStringPackageToIfrPackageList (\r
+      Status = FindStringPackAndAddToPackListWithOnlyIfrPack (\r
                   Private,\r
-                  Packages->GuidId,\r
-                  HandleMappingEntry->UefiHiiHandle\r
+                  ThunkContext\r
                   );\r
       ASSERT_EFI_ERROR (Status);\r
-      if (!EFI_ERROR (Status)) {\r
-        HandleMappingEntry->DoesPackageListImportStringPackages = TRUE;\r
-      }\r
     }\r
   }\r
 \r
-  if (!EFI_ERROR (Status)) {\r
-    InsertTailList (&Private->HiiThunkHandleMappingDBListHead, &HandleMappingEntry->List);\r
-  }\r
-\r
 Done:\r
   if (EFI_ERROR (Status)) {\r
-    FreePool (HandleMappingEntry);\r
+    DestroyThunkContext (Private, ThunkContext);\r
   } else {\r
-    *Handle = HandleMappingEntry->FrameworkHiiHandle;\r
+    InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link);\r
+    *Handle = ThunkContext->FwHiiHandle;\r
   }\r
 \r
-  SafeFreePool (UefiPackageListHeader);\r
+  SafeFreePool (PackageListHeader);\r
   \r
   return Status;\r
 }\r
@@ -455,7 +548,7 @@ Returns:
 --*/\r
 {\r
   EFI_STATUS                 Status;\r
-  EFI_HII_THUNK_PRIVATE_DATA *Private;\r
+  HII_THUNK_PRIVATE_DATA *Private;\r
   EFI_TPL                    OldTpl;\r
 \r
   if (Handle == NULL) {\r
@@ -476,7 +569,7 @@ Returns:
   //\r
   mInFrameworkHiiNewPack = TRUE;\r
 \r
-  Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
+  Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
 \r
   Status = UefiRegisterPackageList (\r
               Private,\r
@@ -509,49 +602,32 @@ Returns:
 --*/\r
 {\r
   EFI_STATUS                 Status;\r
-  EFI_HII_THUNK_PRIVATE_DATA *Private;\r
-  HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
+  HII_THUNK_PRIVATE_DATA *Private;\r
+  HII_THUNK_CONTEXT *ThunkContext;\r
   EFI_TPL                    OldTpl;\r
-  EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
 \r
   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
 \r
   mInFrameworkHiiRemovePack = TRUE;\r
 \r
-  Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
+  Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
 \r
-  HandleMapEntry = FrameworkHiiHandleToMapDatabaseEntry (Private, Handle);\r
+  ThunkContext = FwHiiHandleToThunkContext (Private, Handle);\r
 \r
-  if (HandleMapEntry != NULL) {\r
+  if (ThunkContext != NULL) {\r
     Status = mHiiDatabase->RemovePackageList (\r
                                           mHiiDatabase,\r
-                                          HandleMapEntry->UefiHiiHandle\r
+                                          ThunkContext->UefiHiiHandle\r
                                           );\r
     ASSERT_EFI_ERROR (Status);\r
 \r
-    HiiLibDestroyHiiDriverHandle (HandleMapEntry->UefiHiiHandle);\r
-\r
-    Status = gBS->HandleProtocol (\r
-                    HandleMapEntry->UefiHiiDriverHandle,\r
-                    &gEfiHiiConfigAccessProtocolGuid,\r
-                    (VOID **) &ConfigAccess\r
-                    );\r
-\r
-    if (!EFI_ERROR (Status)) {\r
-      Status = gBS->UninstallProtocolInterface (\r
-                      HandleMapEntry->UefiHiiDriverHandle,\r
-                      &gEfiHiiConfigAccessProtocolGuid,\r
-                      ConfigAccess\r
-                      );\r
-      ASSERT_EFI_ERROR (Status);\r
-    } else {\r
-      Status = EFI_SUCCESS;\r
+    if (ThunkContext->IfrPackageCount != 0) {\r
+      UninstallDefaultConfigAccessProtocol (ThunkContext);\r
     }\r
 \r
-    RemoveEntryList (&HandleMapEntry->List);\r
-\r
-    FreePool (HandleMapEntry);\r
+    RemoveEntryList (&ThunkContext->Link);\r
 \r
+    DestroyThunkContext (Private, ThunkContext);\r
   }else {\r
     Status = EFI_NOT_FOUND;\r
   }\r
@@ -562,3 +638,150 @@ Returns:
 \r
   return Status;\r
 }\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+NewOrAddPackNotify (\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
+  HII_THUNK_PRIVATE_DATA  *Private;\r
+  HII_THUNK_CONTEXT       *ThunkContext;\r
+\r
+  ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS || PackageType == EFI_HII_PACKAGE_FORM);\r
+  ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK || NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK);\r
+\r
+  Status  = EFI_SUCCESS;\r
+  Private = mHiiThunkPrivateData;\r
+\r
+  if (mInFrameworkHiiNewPack || mInFrameworkUpdatePakcage) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // We only create a ThunkContext if the Uefi Hii Handle is only already registered\r
+  // by the HII Thunk Layer.\r
+  //\r
+  ThunkContext = UefiHiiHandleToThunkContext (Private, Handle);\r
+  if (ThunkContext == NULL) {\r
+    ThunkContext = CreateThunkContextForUefiHiiHandle (Private, Handle);\r
+    ASSERT (ThunkContext != NULL);\r
+  } \r
+\r
+\r
+  if (PackageType == EFI_HII_PACKAGE_FORM) {\r
+    Status = CreateQuestionIdMap (ThunkContext);\r
+  }\r
+\r
+  return Status;  \r
+}\r
+\r
+\r
+BOOLEAN\r
+IsRemovingLastStringPack (\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       *PackageHeader;\r
+  UINTN                        StringPackageCount;\r
+\r
+  HiiPackageList = NULL;\r
+  BufferSize = 0;\r
+  StringPackageCount = 0;\r
+\r
+  Status = HiiLibExportPackageLists (Handle, &HiiPackageList, &BufferSize);\r
+  ASSERT_EFI_ERROR (Status);\r
+  \r
+  PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) HiiPackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
+\r
+  while (PackageHeader->Type != EFI_HII_PACKAGE_END) {\r
+    switch (PackageHeader->Type) {\r
+      case EFI_HII_PACKAGE_STRINGS:\r
+        StringPackageCount++;\r
+\r
+        if (StringPackageCount > 1) {\r
+          //\r
+          // More than one String Pack in the package list\r
+          //\r
+          FreePool (HiiPackageList);\r
+          return FALSE;\r
+        }\r
+      break;      \r
+\r
+      default:\r
+        break;\r
+    }\r
+    //\r
+    // goto header of next package\r
+    //\r
+    PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHeader + PackageHeader->Length);\r
+  }\r
+\r
+\r
+  //\r
+  // We will always be notified for the removal of String Pack from a package list.\r
+  // So StringPackageCount must be one at this point.\r
+  //\r
+  ASSERT (StringPackageCount == 1);\r
+  \r
+  FreePool (HiiPackageList);\r
+  return TRUE;\r
+}\r
+\r
+\r
+\r
+// Framework HII module may cache a GUID as the name of the package list.\r
+// Then search for the Framework HII handle database for the handle matching\r
+// this GUID\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
+  HII_THUNK_PRIVATE_DATA *Private;\r
+  HII_THUNK_CONTEXT * ThunkContext;\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 || mInFrameworkUpdatePakcage) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  Private = mHiiThunkPrivateData;\r
+\r
+  ThunkContext = UefiHiiHandleToThunkContext (Private, Handle);\r
+\r
+  if (ThunkContext->FwHiiHandle > Private->StaticHiiHandle) {\r
+    if (IsRemovingLastStringPack (Handle)) {\r
+      //\r
+      // If the string package will be removed is the last string package\r
+      // in the package list, we will remove the HII Thunk entry from the\r
+      // database.\r
+      //\r
+      Status = DestroyThunkContextForUefiHiiHandle (Private, Handle);\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+\r