]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Forms.c
Clean ECP for build failure.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / Forms.c
index 59a859fc9336fea3b2d8b3cba34dddbec517e57c..0078082b7d09fd42e973220c201ebf01e436b898 100644 (file)
@@ -14,7 +14,64 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 \r
 #include "HiiDatabase.h"\r
+#include "UefiIfrDefault.h"\r
+#include "OpcodeCreation.h"\r
+\r
+//\r
+// This structure is only intended to be used in this file.\r
+//\r
+#pragma pack(1)\r
+typedef struct {\r
+  EFI_HII_PACK_HEADER            PackageHeader;\r
+  FRAMEWORK_EFI_IFR_FORM_SET     FormSet;\r
+  FRAMEWORK_EFI_IFR_END_FORM_SET EndFormSet;\r
+} FW_HII_FORMSET_TEMPLATE;\r
+#pragma pack()\r
+\r
+FW_HII_FORMSET_TEMPLATE FormSetTemplate = {\r
+  {\r
+    sizeof (FW_HII_FORMSET_TEMPLATE),\r
+    EFI_HII_IFR\r
+  },\r
+  {\r
+    {\r
+      FRAMEWORK_EFI_IFR_FORM_SET_OP,\r
+      sizeof (FRAMEWORK_EFI_IFR_FORM_SET)\r
+    },\r
+    {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}, //Guid\r
+    0,\r
+    0,\r
+    0,\r
+    0,\r
+    0,\r
+    0\r
+  },\r
+  {\r
+    {\r
+      FRAMEWORK_EFI_IFR_END_FORM_SET_OP,\r
+      sizeof (FRAMEWORK_EFI_IFR_END_FORM_SET)\r
+    }\r
+  }\r
+};\r
+\r
+\r
+EFI_GUID  mTianoHiiIfrGuid              = EFI_IFR_TIANO_GUID;\r
+\r
+/**\r
+\r
+  This thunk module only handles UEFI HII packages. The caller of this function \r
+  won¡¯t be able to parse the content. Therefore, it is not supported.\r
+  \r
+  This function will ASSERT and return EFI_UNSUPPORTED.\r
+\r
+  @param This            N.A.\r
+  @param Handle          N.A.\r
+  @param BufferSize      N.A.\r
+  @param Buffer          N.A.\r
+\r
+  @retval EFI_UNSUPPORTED\r
 \r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 HiiExportDatabase (\r
@@ -23,72 +80,102 @@ HiiExportDatabase (
   IN OUT UINTN            *BufferSize,\r
   OUT    VOID             *Buffer\r
   )\r
-/*++\r
+{\r
+  ASSERT (FALSE);\r
+  return EFI_UNSUPPORTED;\r
+}\r
 \r
-Routine Description:\r
 \r
+/**\r
   This function allows a program to extract a form or form package that has\r
   previously been registered with the EFI HII database.\r
 \r
-Arguments:\r
+  In this thunk module, this function will create a IFR Package with only \r
+  one Formset. Effectively, only the GUID of the Formset is updated and return\r
+  in this IFR package to caller. This is enable the Framework modules which call \r
+  a API named GetStringFromToken. GetStringFromToken retieves a String based on\r
+  a String Token from a Package List known only by the Formset GUID.\r
+  \r
 \r
-Returns:\r
 \r
---*/\r
-{\r
-  ASSERT (FALSE);\r
-  return EFI_UNSUPPORTED;\r
-}\r
+  @param This             A pointer to the EFI_HII_PROTOCOL instance.\r
+  @param Handle           Handle on which the form resides. Type FRAMEWORK_EFI_HII_HANDLE  is defined in\r
+                          EFI_HII_PROTOCOL.NewPack() in the Packages section.\r
+  @param FormId           Ignored by this implementation.\r
+  @param BufferLengthTemp On input, the size of input buffer. On output, it\r
+                          is the size of FW_HII_FORMSET_TEMPLATE.\r
+  @param Buffer           The buffer designed to receive the form(s).\r
 \r
+  @retval  EFI_SUCCESS            Buffer filled with the requested forms. BufferLength\r
+                                  was updated.\r
+  @retval  EFI_INVALID_PARAMETER  The handle is unknown.\r
+  @retval  EFI_NOT_FOUND          A form on the requested handle cannot be found with the\r
+                                  requested FormId.\r
+  @retval  EFI_BUFFER_TOO_SMALL   The buffer provided was not large enough to allow the form to be stored.\r
+\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 HiiGetForms (\r
-  IN     EFI_HII_PROTOCOL   *This,\r
-  IN     FRAMEWORK_EFI_HII_HANDLE      Handle,\r
-  IN     EFI_FORM_ID        FormId,\r
-  IN OUT UINTN              *BufferLengthTemp,\r
-  OUT    UINT8              *Buffer\r
+  IN     EFI_HII_PROTOCOL             *This,\r
+  IN     FRAMEWORK_EFI_HII_HANDLE     Handle,\r
+  IN     EFI_FORM_ID                  FormId,\r
+  IN OUT UINTN                        *BufferLengthTemp,\r
+  OUT    UINT8                        *Buffer\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  This function allows a program to extract a form or form package that has\r
-  previously been registered with the EFI HII database.\r
+{\r
+  HII_THUNK_PRIVATE_DATA                *Private;\r
+  HII_THUNK_CONTEXT  *ThunkContext;\r
+  FW_HII_FORMSET_TEMPLATE            *OutputFormSet;\r
 \r
-Arguments:\r
-  This         - A pointer to the EFI_HII_PROTOCOL instance.\r
+  if (*BufferLengthTemp < sizeof(FW_HII_FORMSET_TEMPLATE)) {\r
+    *BufferLengthTemp = sizeof(FW_HII_FORMSET_TEMPLATE);\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+  \r
+  Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
 \r
-  Handle       - Handle on which the form resides. Type FRAMEWORK_EFI_HII_HANDLE  is defined in\r
-                 EFI_HII_PROTOCOL.NewPack() in the Packages section.\r
+  ThunkContext = FwHiiHandleToThunkContext (Private, Handle);\r
 \r
-  FormId       - The ID of the form to return. If the ID is zero, the entire form package is returned.\r
-                 Type EFI_FORM_ID is defined in "Related Definitions" below.\r
+  if (ThunkContext == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
 \r
-  BufferLength - On input, the length of the Buffer. On output, the length of the returned buffer, if\r
-                 the length was sufficient and, if it was not, the length that is required to fit the\r
-                 requested form(s).\r
+  OutputFormSet = (FW_HII_FORMSET_TEMPLATE *) Buffer;\r
+  \r
+  CopyMem (OutputFormSet, &FormSetTemplate, sizeof (FW_HII_FORMSET_TEMPLATE));\r
+  CopyMem (&OutputFormSet->FormSet.Guid, &ThunkContext->TagGuid, sizeof (EFI_GUID)); \r
+\r
+  if (ThunkContext->FormSet != NULL) {\r
+    OutputFormSet->FormSet.Class = ThunkContext->FormSet->Class;\r
+    OutputFormSet->FormSet.SubClass = ThunkContext->FormSet->SubClass;\r
+    OutputFormSet->FormSet.Help     = ThunkContext->FormSet->Help;\r
+    OutputFormSet->FormSet.FormSetTitle = ThunkContext->FormSet->FormSetTitle;\r
+  }\r
 \r
-  Buffer       - The buffer designed to receive the form(s).\r
+  return EFI_SUCCESS;\r
+}\r
 \r
-Returns:\r
 \r
-  EFI_SUCCESS           -  Buffer filled with the requested forms. BufferLength\r
-                           was updated.\r
+/**\r
 \r
-  EFI_INVALID_PARAMETER -  The handle is unknown.\r
+  This function allows a program to extract the NV Image\r
+  that represents the default storage image\r
 \r
-  EFI_NOT_FOUND         -  A form on the requested handle cannot be found with the\r
-                           requested FormId.\r
 \r
-  EFI_BUFFER_TOO_SMALL  - The buffer provided was not large enough to allow the form to be stored.\r
+  @param This            A pointer to the EFI_HII_PROTOCOL instance.\r
+  @param Handle          The HII handle from which will have default data retrieved.\r
+                         UINTN            - Mask used to retrieve the default image.\r
+  @param DefaultMask     EDES_TODO: Add parameter description\r
+  @param VariablePackList Callee allocated, tightly-packed, link list data\r
+                         structure that contain all default varaible packs\r
+                         from the Hii Database.\r
 \r
---*/\r
-{\r
-  ASSERT (FALSE);\r
-  return EFI_UNSUPPORTED;\r
-}\r
+  @retval  EFI_NOT_FOUND          If Hii database does not contain any default images.\r
+  @retval  EFI_INVALID_PARAMETER  Invalid input parameter.\r
+  @retval  EFI_SUCCESS            Operation successful.\r
 \r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 HiiGetDefaultImage (\r
@@ -97,55 +184,70 @@ HiiGetDefaultImage (
   IN     UINTN                       DefaultMask,\r
   OUT    EFI_HII_VARIABLE_PACK_LIST  **VariablePackList\r
   )\r
-/*++\r
+{\r
+  LIST_ENTRY        *UefiDefaults;\r
+  EFI_STATUS        Status;\r
+  HII_THUNK_PRIVATE_DATA *Private;\r
+  HII_THUNK_CONTEXT *ThunkContext;\r
 \r
-  Routine Description:\r
+  Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
 \r
-  This function allows a program to extract the NV Image\r
-  that represents the default storage image\r
+  ThunkContext = FwHiiHandleToThunkContext (Private, Handle);\r
+  if (ThunkContext == NULL) {\r
+    ASSERT (FALSE);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 \r
-  Arguments:\r
-    This             - A pointer to the EFI_HII_PROTOCOL instance.\r
-    Handle           - The HII handle from which will have default data retrieved.\r
-    UINTN            - Mask used to retrieve the default image.\r
-    VariablePackList - Callee allocated, tightly-packed, link list data\r
-                         structure that contain all default varaible packs\r
-                         from the Hii Database.\r
+  UefiDefaults = NULL;\r
+  Status = UefiIfrGetBufferTypeDefaults (ThunkContext, &UefiDefaults);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
 \r
-  Returns:\r
-    EFI_NOT_FOUND         - If Hii database does not contain any default images.\r
-    EFI_INVALID_PARAMETER - Invalid input parameter.\r
-    EFI_SUCCESS           - Operation successful.\r
+  Status = UefiDefaultsToFwDefaults (UefiDefaults, DefaultMask, ThunkContext->FormSet->DefaultVarStoreId, VariablePackList);\r
 \r
---*/\r
-{\r
-  return EFI_SUCCESS;\r
+Done:\r
+  FreeDefaultList (UefiDefaults);\r
+  \r
+  return Status;\r
 }\r
 \r
+/**\r
+  This function update the FormCallbackProtocol cached in Config Access\r
+  private context data.\r
+\r
+  @param CallbackHandle  The EFI Handle on which the Framework FormCallbackProtocol is \r
+                         installed.\r
+  @param ThunkContext    The Thunk Context.\r
+\r
+  @retval EFI_SUCCESS             The update is successful.\r
+  @retval EFI_INVALID_PARAMETER   If no Framework FormCallbackProtocol is located on CallbackHandle.\r
+\r
+**/\r
 EFI_STATUS\r
-ThunkUpdateFormCallBack (\r
+UpdateFormCallBack (\r
   IN       EFI_HANDLE                                CallbackHandle,\r
-  IN CONST HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY  *HandleMapEntry\r
+  IN CONST HII_THUNK_CONTEXT                         *ThunkContext\r
   )\r
 {\r
   EFI_STATUS                                Status;\r
-  EFI_FORM_CALLBACK_PROTOCOL                *FrameworkFormCallbackProtocol;\r
+  EFI_FORM_CALLBACK_PROTOCOL                *FormCallbackProtocol;\r
   EFI_HII_CONFIG_ACCESS_PROTOCOL            *ConfigAccessProtocol;\r
   EFI_HANDLE                                UefiDriverHandle;\r
-  HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE *ConfigAccessProtocolInstance;\r
+  CONFIG_ACCESS_PRIVATE                     *ConfigAccessPrivate;\r
   \r
   Status = gBS->HandleProtocol (\r
                    CallbackHandle,\r
                    &gEfiFormCallbackProtocolGuid,\r
-                   (VOID **) &FrameworkFormCallbackProtocol\r
+                   (VOID **) &FormCallbackProtocol\r
                    );\r
   if (EFI_ERROR (Status)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   \r
-  Status = mUefiHiiDatabaseProtocol->GetPackageListHandle (\r
-                                        mUefiHiiDatabaseProtocol,\r
-                                        HandleMapEntry->UefiHiiHandle,\r
+  Status = mHiiDatabase->GetPackageListHandle (\r
+                                        mHiiDatabase,\r
+                                        ThunkContext->UefiHiiHandle,\r
                                         &UefiDriverHandle\r
                                         );\r
   ASSERT_EFI_ERROR (Status);\r
@@ -156,208 +258,320 @@ ThunkUpdateFormCallBack (
                    );\r
   ASSERT_EFI_ERROR (Status);\r
   \r
-  ConfigAccessProtocolInstance = HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_FROM_PROTOCOL (ConfigAccessProtocol);\r
+  ConfigAccessPrivate = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (ConfigAccessProtocol);\r
   \r
-  ConfigAccessProtocolInstance->FrameworkFormCallbackProtocol = FrameworkFormCallbackProtocol;\r
+  ConfigAccessPrivate->FormCallbackProtocol = FormCallbackProtocol;\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-#define LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL   0x1000\r
 \r
-EFI_STATUS\r
-AppendToUpdateBuffer (\r
-  IN CONST  UINT8                *OpCodeBuf,\r
-  IN        UINTN                BufSize,\r
-  OUT       EFI_HII_UPDATE_DATA  *UefiData\r
-  )\r
-{\r
-  UINT8 * NewBuff;\r
-  \r
-  if (UefiData->Offset + BufSize > UefiData->BufferSize) {\r
-    NewBuff = AllocateCopyPool (UefiData->BufferSize + LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL, UefiData->Data);\r
-    if (NewBuff == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-    UefiData->BufferSize += LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL;\r
-    FreePool (UefiData->Data);\r
-    UefiData->Data = NewBuff;\r
-  }\r
-  \r
-  CopyMem (UefiData->Data + UefiData->Offset, OpCodeBuf, BufSize);\r
-  UefiData->Offset += (UINT32) BufSize;\r
+/**\r
+  Get the package data from the Package List.\r
 \r
-  return EFI_SUCCESS;\r
-}\r
+  @param HiiPackageList  Package List.\r
+  @param PackageIndex    The index of the Package in the Package List.\r
+  @param BufferLen       The Length of the Pacage data.\r
+  @param Buffer          On output, the Package data.\r
 \r
+  @return EFI_NOT_FOUND  No Package is found for PackageIndex.\r
+  @return EFI_SUCCESS    The package data is returned.\r
+\r
+**/\r
 EFI_STATUS\r
-Framework2UefiCreateSubtitleOpCode (\r
-  IN CONST FRAMEWORK_EFI_IFR_SUBTITLE  *FwSubTitle,\r
-  OUT      EFI_HII_UPDATE_DATA         *UefiData\r
+GetPackageData (\r
+  IN  EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList,\r
+  IN  UINT32                      PackageIndex,\r
+  OUT UINT32                      *BufferLen,\r
+  OUT EFI_HII_PACKAGE_HEADER      **Buffer\r
   )\r
 {\r
-  EFI_IFR_SUBTITLE USubTitle;\r
+  UINT32                        Index;\r
+  EFI_HII_PACKAGE_HEADER        *Package;\r
+  UINT32                        Offset;\r
+  UINT32                        PackageListLength;\r
+  EFI_HII_PACKAGE_HEADER        PackageHeader = {0, 0};\r
 \r
-  ZeroMem (&USubTitle, sizeof(USubTitle));\r
+  ASSERT(HiiPackageList != NULL);\r
 \r
-  USubTitle.Header.OpCode = EFI_IFR_SUBTITLE_OP;\r
-  USubTitle.Header.Length = sizeof (EFI_IFR_SUBTITLE);\r
+  if ((BufferLen == NULL) || (Buffer == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 \r
-  USubTitle.Statement.Prompt = FwSubTitle->SubTitle;\r
+  Package = NULL;\r
+  Index   = 0;\r
+  Offset  = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+  CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
+  while (Offset < PackageListLength) {\r
+    Package = (EFI_HII_PACKAGE_HEADER *) (((UINT8 *) HiiPackageList) + Offset);\r
+    CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+    if (Index == PackageIndex) {\r
+      break;\r
+    }\r
+    Offset += PackageHeader.Length;\r
+    Index++;\r
+  }\r
+  if (Offset >= PackageListLength) {\r
+    //\r
+    // no package found in this Package List\r
+    //\r
+    return EFI_NOT_FOUND;\r
+  }\r
 \r
-  return AppendToUpdateBuffer ((UINT8 *)&USubTitle, sizeof(EFI_IFR_SUBTITLE), UefiData);\r
+  *BufferLen = PackageHeader.Length;\r
+  *Buffer    = Package;\r
+  return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Check if Label exist in the IFR form package and return the FormSet GUID\r
+  and Form ID.\r
+\r
+  @param Package      The Package Header.\r
+  @param Label        The Label ID.\r
+  @param FormsetGuid  Returns the FormSet GUID.\r
+  @param FormId       Returns the Form ID.\r
+\r
+  @retval EFI_SUCCESS     The FORM ID is found.\r
+  @retval EFI_NOT_FOUND   The FORM ID is not found.\r
+**/\r
 EFI_STATUS\r
-Framework2UefiCreateTextOpCode (\r
-  IN CONST FRAMEWORK_EFI_IFR_TEXT      *FwText,\r
-  OUT      EFI_HII_UPDATE_DATA         *UefiData\r
+LocateLabel (\r
+  IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
+  IN       EFI_FORM_LABEL          Label,\r
+  OUT      EFI_GUID                *FormsetGuid,\r
+  OUT      EFI_FORM_ID             *FormId\r
   )\r
 {\r
-  EFI_IFR_TEXT UText;\r
-\r
-  ZeroMem (&UText, sizeof(UText));\r
-  \r
-  UText.Header.OpCode = EFI_IFR_TEXT_OP;\r
-  UText.Header.Length = sizeof (EFI_IFR_TEXT);\r
+  UINTN                     Offset;\r
+  EFI_IFR_OP_HEADER         *IfrOpHdr;\r
+  EFI_GUID                  InternalFormSetGuid;\r
+  EFI_FORM_ID               InternalFormId;\r
+  BOOLEAN                   GetFormSet;\r
+  BOOLEAN                   GetForm;\r
+  EFI_IFR_GUID_LABEL        *LabelOpcode;\r
+\r
+  IfrOpHdr   = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + sizeof (EFI_HII_PACKAGE_HEADER));\r
+  Offset     = sizeof (EFI_HII_PACKAGE_HEADER);\r
+\r
+  InternalFormId= 0;\r
+  ZeroMem (&InternalFormSetGuid, sizeof (EFI_GUID));\r
+  GetFormSet = FALSE;\r
+  GetForm    = FALSE;\r
+\r
+  while (Offset < Package->Length) {\r
+    switch (IfrOpHdr->OpCode) {\r
+    case EFI_IFR_FORM_SET_OP :\r
+      CopyMem (&InternalFormSetGuid, &((EFI_IFR_FORM_SET *) IfrOpHdr)->Guid, sizeof (EFI_GUID));\r
+      GetFormSet = TRUE;\r
+      break;\r
+\r
+    case EFI_IFR_FORM_OP:\r
+      CopyMem (&InternalFormId, &((EFI_IFR_FORM *) IfrOpHdr)->FormId, sizeof (EFI_FORM_ID));\r
+      GetForm = TRUE;\r
+      break;\r
+\r
+    case EFI_IFR_GUID_OP :\r
+      LabelOpcode = (EFI_IFR_GUID_LABEL *) IfrOpHdr;\r
+      //\r
+      // If it is an Label opcode.\r
+      //\r
+      if ((LabelOpcode->ExtendOpCode == EFI_IFR_EXTEND_OP_LABEL) && (CompareMem (&LabelOpcode->Guid, &mTianoHiiIfrGuid, sizeof (EFI_GUID)) == 0)) {\r
+        if (CompareMem (&Label, &LabelOpcode->Number, sizeof (UINT16)) == 0) {\r
+          ASSERT (GetForm && GetFormSet);\r
+          CopyGuid (FormsetGuid, &InternalFormSetGuid);\r
+          *FormId = InternalFormId;\r
+          return EFI_SUCCESS;\r
+        }\r
+      }\r
+      break;\r
+    default :\r
+      break;\r
+    }\r
 \r
-  UText.Statement.Help   = FwText->Help;\r
+    //\r
+    // Go to the next Op-Code\r
+    //\r
+    Offset   += IfrOpHdr->Length;\r
+    IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);\r
+  }\r
 \r
-  UText.Statement.Prompt = FwText->Text;\r
-  UText.TextTwo          = FwText->TextTwo;\r
-  \r
-  return AppendToUpdateBuffer ((UINT8 *) &UText, sizeof(EFI_IFR_TEXT), UefiData);\r
+  return EFI_NOT_FOUND;\r
 }\r
 \r
+/**\r
+  Find the first EFI_FORM_LABEL in FormSets for a given EFI_HII_HANLDE defined.\r
+  \r
+  EFI_FORM_LABEL is a specific to Tiano implementation. The current implementation\r
+  does not restrict labels with same label value to be duplicated in either FormSet \r
+  scope or Form scope. This function will only locate the FIRST EFI_FORM_LABEL\r
+  with value as the same as the input Label in the Formset registered with UefiHiiHandle. The FormSet GUID \r
+  and Form ID is returned if such Label is found.\r
 \r
+  \r
+  @retval EFI_INVALID_PARAMETER If UefiHiiHandle is not a valid handle.\r
+  @retval EFI_NOT_FOUND   The package list identified by UefiHiiHandle deos not contain FormSet or\r
+                                         There is no Form ID with value Label found in all Form Sets in the pacakge\r
+                                         list.\r
+                                         \r
+  @retval EFI_SUCCESS       The first found Form ID is returned in FormId.\r
+**/\r
 EFI_STATUS\r
-ThunkFrameworkUpdateDataToUefiUpdateData (\r
-  IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA    *Data,\r
-  IN       BOOLEAN                          AddData,\r
-  OUT      EFI_HII_UPDATE_DATA              **UefiData\r
+LocateFormId (\r
+  IN  EFI_HII_HANDLE Handle,\r
+  IN  EFI_FORM_LABEL Label,\r
+  OUT EFI_GUID       *FormsetGuid,\r
+  OUT EFI_FORM_ID    *FormId\r
   )\r
 {\r
-  FRAMEWORK_EFI_IFR_OP_HEADER          *FrameworkOpcodeBuffer;\r
-  EFI_HII_UPDATE_DATA                  *UefiUpdateDataBuffer;\r
-  UINTN                                Index;\r
-  EFI_STATUS                           Status;\r
-\r
-  UefiUpdateDataBuffer = AllocateZeroPool (sizeof (EFI_HII_UPDATE_DATA));\r
-  if (UefiUpdateDataBuffer == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  \r
-  UefiUpdateDataBuffer->Data = AllocateZeroPool (LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL);\r
-  if (UefiUpdateDataBuffer->Data == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  UefiUpdateDataBuffer->BufferSize = LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL;\r
-  UefiUpdateDataBuffer->Offset = 0;\r
-\r
-  FrameworkOpcodeBuffer = (FRAMEWORK_EFI_IFR_OP_HEADER *) &Data->Data;\r
-\r
-  for (Index = 0; Index < Data->DataCount; Index++) {\r
-    switch (FrameworkOpcodeBuffer->OpCode) {\r
-      case FRAMEWORK_EFI_IFR_SUBTITLE_OP:\r
-        Status = Framework2UefiCreateSubtitleOpCode ((FRAMEWORK_EFI_IFR_SUBTITLE  *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer);\r
-        break;\r
-        \r
-      case FRAMEWORK_EFI_IFR_TEXT_OP:\r
-        Status = Framework2UefiCreateTextOpCode ((FRAMEWORK_EFI_IFR_TEXT  *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer);  \r
-        break;\r
-        \r
-      default:\r
-        ASSERT (FALSE);\r
-        return EFI_UNSUPPORTED;\r
-    }\r
-\r
+  EFI_STATUS                   Status;\r
+  EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;\r
+  UINT32                       Index;\r
+  UINTN                        BufferSize;\r
+  EFI_HII_PACKAGE_HEADER       PackageHeader;\r
+  EFI_HII_PACKAGE_HEADER       *Package;\r
+  UINT32                       PackageLength;\r
+\r
+  BufferSize = 0;\r
+  HiiPackageList   = NULL;\r
+  Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    HiiPackageList = AllocatePool (BufferSize);\r
+    ASSERT (HiiPackageList != NULL);\r
+\r
+    Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
     if (EFI_ERROR (Status)) {\r
-      FreePool (UefiUpdateDataBuffer->Data);\r
-      FreePool (UefiUpdateDataBuffer);\r
-      return Status;\r
+      goto Done;\r
     }\r
+  }\r
 \r
-    FrameworkOpcodeBuffer = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FrameworkOpcodeBuffer + FrameworkOpcodeBuffer->Length);\r
+  for (Index = 0; ; Index++) {\r
+    Status = GetPackageData (HiiPackageList, Index, &PackageLength, &Package);\r
+    if (!EFI_ERROR (Status)) {\r
+      CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+      if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
+        Status = LocateLabel (Package, Label, FormsetGuid, FormId);\r
+        if (!EFI_ERROR(Status)) {\r
+          break;\r
+        }\r
+      }\r
+    } else {\r
+      break;\r
+    }\r
   }\r
 \r
-  *UefiData = UefiUpdateDataBuffer;\r
   \r
-  return EFI_SUCCESS;\r
+Done:\r
+  FreePool (HiiPackageList);\r
+  \r
+  return Status;\r
 }\r
-EFI_STATUS\r
-EFIAPI\r
-HiiUpdateForm (\r
-  IN EFI_HII_PROTOCOL       *This,\r
-  IN FRAMEWORK_EFI_HII_HANDLE          Handle,\r
-  IN EFI_FORM_LABEL         Label,\r
-  IN BOOLEAN                AddData,\r
-  IN FRAMEWORK_EFI_HII_UPDATE_DATA    *Data\r
-  )\r
-/*++\r
 \r
-Routine Description:\r
+/**\r
   This function allows the caller to update a form that has\r
   previously been registered with the EFI HII database.\r
 \r
-Arguments:\r
-  Handle     - Hii Handle associated with the Formset to modify\r
-  Label      - Update information starting immediately after this label in the IFR\r
-  AddData    - If TRUE, add data.  If FALSE, remove data\r
-  Data       - If adding data, this is the pointer to the data to add\r
 \r
-Returns:\r
-  EFI_SUCCESS - Update success.\r
-  Other       - Update fail.\r
+  @param This            EDES_TODO: Add parameter description\r
+  @param Handle          Hii Handle associated with the Formset to modify\r
+  @param Label           Update information starting immediately after this label in the IFR\r
+  @param AddData         If TRUE, add data.  If FALSE, remove data\r
+  @param Data            If adding data, this is the pointer to the data to add\r
 \r
---*/\r
+  @retval  EFI_SUCCESS  Update success.\r
+  @retval  Other        Update fail.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HiiUpdateForm (\r
+  IN EFI_HII_PROTOCOL                  *This,\r
+  IN FRAMEWORK_EFI_HII_HANDLE          Handle,\r
+  IN EFI_FORM_LABEL                    Label,\r
+  IN BOOLEAN                           AddData,\r
+  IN FRAMEWORK_EFI_HII_UPDATE_DATA    *Data\r
+  )\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_HII_UPDATE_DATA                       *UefiHiiUpdateData;\r
   EFI_HII_HANDLE                            UefiHiiHandle;\r
+  EFI_GUID                                  FormsetGuid;\r
+  EFI_FORM_ID                               FormId;\r
+  EFI_TPL                                   OldTpl;\r
 \r
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+  \r
+  mInFrameworkUpdatePakcage = TRUE;\r
   Status = EFI_SUCCESS;\r
+  UefiHiiUpdateData = NULL;\r
 \r
-  Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
 \r
-  HandleMapEntry = FrameworkHiiHandleToMapDatabaseEntry (Private, Handle);\r
+  Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
 \r
-  if (HandleMapEntry == NULL) {\r
-    return EFI_NOT_FOUND;\r
+  ThunkContext = FwHiiHandleToThunkContext (Private, Handle);\r
+\r
+  if (ThunkContext == NULL) {\r
+    Status = EFI_NOT_FOUND;\r
+    goto Done;\r
   }\r
   \r
   if (Data->FormSetUpdate) {\r
-    Status = ThunkUpdateFormCallBack ((EFI_HANDLE) (UINTN) Data->FormCallbackHandle, HandleMapEntry);\r
+    Status = UpdateFormCallBack ((EFI_HANDLE) (UINTN) Data->FormCallbackHandle, ThunkContext);\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      goto Done;\r
     }\r
   }\r
 \r
-  if (Data->DataCount != 0) {\r
-    if (HandleMapEntry->IsPackageListWithOnlyStringPackages) {\r
-      UefiHiiHandle = TagGuidToUefiIfrHiiHandle (Private, &HandleMapEntry->TagGuid);\r
-\r
-      if (UefiHiiHandle == NULL) {\r
-        return EFI_INVALID_PARAMETER;\r
-      }\r
-    } else {\r
-      UefiHiiHandle = HandleMapEntry->UefiHiiHandle;\r
-    }\r
+  if (ThunkContext->IfrPackageCount == 0) {\r
+    ASSERT (FALSE);\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto Done;\r
+  } else {\r
+    UefiHiiHandle = ThunkContext->UefiHiiHandle;\r
+  }\r
 \r
-    UefiHiiUpdateData = NULL;\r
-    \r
-    ThunkFrameworkUpdateDataToUefiUpdateData (Data, AddData, &UefiHiiUpdateData);\r
+  Status = LocateFormId (UefiHiiHandle, Label, &FormsetGuid, &FormId);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Can't find the label.\r
+    //\r
+    goto Done;\r
+  }\r
 \r
-    Status = IfrLibUpdateForm (UefiHiiHandle, NULL, 0, Label, AddData, UefiHiiUpdateData);\r
+  if (AddData) {\r
+    if (Data->DataCount != 0) {\r
+\r
+      ThunkContext = UefiHiiHandleToThunkContext (Private, UefiHiiHandle);\r
+      Status = FwUpdateDataToUefiUpdateData (ThunkContext, Data, &UefiHiiUpdateData);\r
+      ASSERT_EFI_ERROR (Status);\r
+\r
+      Status = IfrLibUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, Label, TRUE, UefiHiiUpdateData);\r
+      ASSERT_EFI_ERROR (Status);\r
+      \r
+    } \r
+  } else {\r
+    //\r
+    // Delete Opcode starting from Labe in FormId found\r
+    //\r
+    UefiHiiUpdateData = AllocateZeroPool (sizeof (*UefiHiiUpdateData));\r
+       \r
+    Status = IfrLibUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, Label, FALSE, UefiHiiUpdateData);\r
     ASSERT_EFI_ERROR (Status);\r
-    \r
-    if (UefiHiiUpdateData != NULL) {\r
-      SafeFreePool (UefiHiiUpdateData->Data);\r
-      SafeFreePool (UefiHiiUpdateData);\r
+  }\r
+\r
+Done:\r
+  if (UefiHiiUpdateData != NULL) {\r
+    if (UefiHiiUpdateData->Data != NULL) {\r
+      FreePool (UefiHiiUpdateData->Data);\r
     }\r
+    FreePool (UefiHiiUpdateData);\r
   }\r
 \r
+  mInFrameworkUpdatePakcage = FALSE; \r
+\r
+  gBS->RestoreTPL (OldTpl);\r
+\r
   return Status;\r
 }\r