]> git.proxmox.com Git - mirror_edk2.git/commitdiff
1) Add in IfrParser so that the FrameworkHii->GetDefaultImage can scan UEFI IFR opcod...
authorqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 24 Apr 2008 07:08:46 +0000 (07:08 +0000)
committerqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 24 Apr 2008 07:08:46 +0000 (07:08 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5119 6f19259b-4bc3-4df7-8a09-765794883524

20 files changed:
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/ConfigAccess.c
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Fonts.c
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Forms.c
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/FrameworkHiiToUefiHiiThunk.inf
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.c
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.h
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Package.c
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/R8Lib.c [new file with mode: 0644]
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/R8Lib.h [new file with mode: 0644]
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Strings.c
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrDefault.c [new file with mode: 0644]
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrDefault.h [new file with mode: 0644]
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParser.c [new file with mode: 0644]
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParser.h [new file with mode: 0644]
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserCommon.c [new file with mode: 0644]
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserCommon.h [new file with mode: 0644]
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserExpression.c [new file with mode: 0644]
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserExpression.h [new file with mode: 0644]
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserExpressionInternal.h [new file with mode: 0644]
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserInternal.h [new file with mode: 0644]

index 0ab9074b752058c80c078943485d1220256c0b88..ab99d5d760613868c92ec27ba2a12e0358b31ef1 100644 (file)
@@ -332,8 +332,8 @@ ThunkExtractConfig (
   }\r
   \r
   if (!EFI_ERROR (Status)) {\r
-    Status = mUefiConfigRoutingProtocol->BlockToConfig (\r
-                                            mUefiConfigRoutingProtocol,\r
+    Status = mHiiConfigRoutingProtocol->BlockToConfig (\r
+                                            mHiiConfigRoutingProtocol,\r
                                             Request,\r
                                             Data,\r
                                             DataSize,\r
@@ -378,8 +378,8 @@ ThunkRouteConfig (
   if (Data == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  Status = mUefiConfigRoutingProtocol->ConfigToBlock (\r
-                                          mUefiConfigRoutingProtocol,\r
+  Status = mHiiConfigRoutingProtocol->ConfigToBlock (\r
+                                          mHiiConfigRoutingProtocol,\r
                                           Configuration,\r
                                           Data,\r
                                           &LastModifiedByteIndex,\r
index eadc5b35b43d3c6464836e80d8aac55b2e5bed22..29914064e54118b0f20e953b7a6af6a35c53bf9a 100644 (file)
@@ -16,6 +16,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "HiiDatabase.h"\r
 \r
+\r
+UINT8 mGlyphBuffer[EFI_GLYPH_WIDTH * 2 * EFI_GLYPH_HEIGHT];\r
+\r
 EFI_STATUS\r
 EFIAPI\r
 HiiGetGlyph (\r
@@ -47,7 +50,7 @@ Returns:
 --*/\r
 {\r
   ASSERT (FALSE);\r
-  return EFI_SUCCESS;\r
+  return EFI_UNSUPPORTED;\r
 }\r
 \r
 EFI_STATUS\r
@@ -64,5 +67,5 @@ HiiGlyphToBlt (
   )\r
 {\r
   ASSERT (FALSE);\r
-  return EFI_SUCCESS;\r
+  return EFI_UNSUPPORTED;\r
 }\r
index 59a859fc9336fea3b2d8b3cba34dddbec517e57c..e5615cf8a49e8ffcaf9a076997b0f2fa4a396710 100644 (file)
@@ -14,6 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 \r
 #include "HiiDatabase.h"\r
+#include "UefiIfrDefault.h"\r
 \r
 EFI_STATUS\r
 EFIAPI\r
@@ -89,6 +90,7 @@ Returns:
   return EFI_UNSUPPORTED;\r
 }\r
 \r
+\r
 EFI_STATUS\r
 EFIAPI\r
 HiiGetDefaultImage (\r
@@ -119,7 +121,31 @@ HiiGetDefaultImage (
 \r
 --*/\r
 {\r
-  return EFI_SUCCESS;\r
+  LIST_ENTRY        *UefiDefaults;\r
+  EFI_HII_HANDLE    UefiHiiHandle;\r
+  EFI_STATUS        Status;\r
+  EFI_HII_THUNK_PRIVATE_DATA *Private;\r
+\r
+  Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
+\r
+  UefiHiiHandle = FrameworkHiiHandleToUefiHiiHandle (Private, Handle);\r
+  if (UefiHiiHandle == NULL) {\r
+    ASSERT (FALSE);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  UefiDefaults = NULL;\r
+  Status = UefiIfrGetBufferTypeDefaults (UefiHiiHandle, &UefiDefaults);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  Status = UefiDefaultsToFrameworkDefaults (UefiDefaults, DefaultMask, VariablePackList);\r
+\r
+Done:\r
+  FreeDefaultList (UefiDefaults);\r
+  \r
+  return Status;\r
 }\r
 \r
 EFI_STATUS\r
@@ -143,8 +169,8 @@ ThunkUpdateFormCallBack (
     return EFI_INVALID_PARAMETER;\r
   }\r
   \r
-  Status = mUefiHiiDatabaseProtocol->GetPackageListHandle (\r
-                                        mUefiHiiDatabaseProtocol,\r
+  Status = mHiiDatabase->GetPackageListHandle (\r
+                                        mHiiDatabase,\r
                                         HandleMapEntry->UefiHiiHandle,\r
                                         &UefiDriverHandle\r
                                         );\r
@@ -191,7 +217,7 @@ AppendToUpdateBuffer (
 }\r
 \r
 EFI_STATUS\r
-Framework2UefiCreateSubtitleOpCode (\r
+F2UCreateSubtitleOpCode (\r
   IN CONST FRAMEWORK_EFI_IFR_SUBTITLE  *FwSubTitle,\r
   OUT      EFI_HII_UPDATE_DATA         *UefiData\r
   )\r
@@ -209,7 +235,7 @@ Framework2UefiCreateSubtitleOpCode (
 }\r
 \r
 EFI_STATUS\r
-Framework2UefiCreateTextOpCode (\r
+F2UCreateTextOpCode (\r
   IN CONST FRAMEWORK_EFI_IFR_TEXT      *FwText,\r
   OUT      EFI_HII_UPDATE_DATA         *UefiData\r
   )\r
@@ -260,11 +286,11 @@ ThunkFrameworkUpdateDataToUefiUpdateData (
   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
+        Status = F2UCreateSubtitleOpCode ((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
+        Status = F2UCreateTextOpCode ((FRAMEWORK_EFI_IFR_TEXT  *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer);  \r
         break;\r
         \r
       default:\r
@@ -285,6 +311,199 @@ ThunkFrameworkUpdateDataToUefiUpdateData (
   \r
   return EFI_SUCCESS;\r
 }\r
+\r
+STATIC\r
+EFI_STATUS\r
+GetPackageDataFromPackageList (\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
+  UINT32                        Index;\r
+  EFI_HII_PACKAGE_HEADER        *Package;\r
+  UINT32                        Offset;\r
+  UINT32                        PackageListLength;\r
+  EFI_HII_PACKAGE_HEADER        PackageHeader = {0, 0};\r
+\r
+  ASSERT(HiiPackageList != NULL);\r
+\r
+  if ((BufferLen == NULL) || (Buffer == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\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
+  *BufferLen = PackageHeader.Length;\r
+  *Buffer    = Package;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Check if Label exist in the IFR form package.\r
+\r
+  @param \r
+\r
+**/\r
+EFI_STATUS\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
+  UINTN                     Offset;\r
+  EFI_IFR_OP_HEADER         *IfrOpHdr;\r
+  UINT8                     ExtendOpCode;\r
+  UINT16                    LabelNumber;\r
+  EFI_GUID                  InternalFormSetGuid;\r
+  EFI_FORM_ID               InternalFormId;\r
+  BOOLEAN                   GetFormSet;\r
+  BOOLEAN                   GetForm;\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
+      ExtendOpCode = ((EFI_IFR_GUID_LABEL *) IfrOpHdr)->ExtendOpCode;\r
+      \r
+      if (ExtendOpCode != EFI_IFR_EXTEND_OP_LABEL) {\r
+        //\r
+        // Go to the next Op-Code\r
+        //\r
+        Offset   += IfrOpHdr->Length;\r
+        IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);\r
+        continue;\r
+      }\r
+      \r
+      CopyMem (&LabelNumber, &((EFI_IFR_GUID_LABEL *)IfrOpHdr)->Number, sizeof (UINT16));\r
+      if (LabelNumber == Label) {\r
+        ASSERT (GetForm && GetFormSet);\r
+        CopyGuid (FormsetGuid, &InternalFormSetGuid);\r
+        *FormId = InternalFormId;\r
+        return EFI_SUCCESS;\r
+      }\r
+      \r
+\r
+      break;\r
+    default :\r
+      break;\r
+    }\r
+\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
+  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
+ThunkLocateFormId (\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
+  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
+      goto Done;\r
+    }\r
+  }\r
+\r
+  for (Index = 0; ; Index++) {\r
+    Status = GetPackageDataFromPackageList (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_FORM) {\r
+        Status = LocateLabel (Package, Label, FormsetGuid, FormId);\r
+        if (!EFI_ERROR(Status)) {\r
+          break;\r
+        }\r
+      }\r
+    } else {\r
+      break;\r
+    }\r
+  }\r
+\r
+  \r
+Done:\r
+  FreePool (HiiPackageList);\r
+  \r
+  return Status;\r
+}\r
 EFI_STATUS\r
 EFIAPI\r
 HiiUpdateForm (\r
@@ -317,6 +536,8 @@ Returns:
   HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY  *HandleMapEntry;\r
   EFI_HII_UPDATE_DATA                       *UefiHiiUpdateData;\r
   EFI_HII_HANDLE                            UefiHiiHandle;\r
+  EFI_GUID                                  FormsetGuid;\r
+  EFI_FORM_ID                               FormId;\r
 \r
   Status = EFI_SUCCESS;\r
 \r
@@ -350,7 +571,10 @@ Returns:
     \r
     ThunkFrameworkUpdateDataToUefiUpdateData (Data, AddData, &UefiHiiUpdateData);\r
 \r
-    Status = IfrLibUpdateForm (UefiHiiHandle, NULL, 0, Label, AddData, UefiHiiUpdateData);\r
+    Status = ThunkLocateFormId (UefiHiiHandle, Label, &FormsetGuid, &FormId);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    Status = IfrLibUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, Label, AddData, UefiHiiUpdateData);\r
     ASSERT_EFI_ERROR (Status);\r
     \r
     if (UefiHiiUpdateData != NULL) {\r
index e90fe65d9cf7976a398276f36c7a1a8ffdf5e215..9026256f491525ea9ad962f036c22d443851894e 100644 (file)
 #\r
 \r
 [Sources.common]\r
+  UefiIfrParserInternal.h\r
+  UefiIfrParserCommon.c\r
+  UefiIfrParserCommon.h\r
+  UefiIfrParser.c\r
+  UefiIfrParser.h\r
+  UefiIfrParserExpression.c\r
+  UefiIfrParserExpressionInternal.h\r
+  UefiIfrDefault.c\r
+  UefiIfrDefault.h\r
   Keyboard.c\r
   Fonts.c\r
   Package.c\r
@@ -44,6 +53,8 @@
   ConfigAccess.h\r
   Utility.c\r
   Utility.h\r
+  R8Lib.c\r
+  R8Lib.h\r
   \r
 \r
 [Packages]\r
@@ -63,6 +74,7 @@
   ExtendedHiiLib\r
   IfrSupportLib\r
   ExtendedIfrSupportLib\r
+  PrintLib\r
 \r
 [Protocols]\r
   gEfiHiiProtocolGuid\r
@@ -73,6 +85,7 @@
   gEfiHiiConfigRoutingProtocolGuid\r
   gEfiHiiConfigAccessProtocolGuid\r
   gEfiFormCallbackProtocolGuid\r
+  gEfiUnicodeCollation2ProtocolGuid\r
 \r
 [Depex]\r
   gEfiHiiImageProtocolGuid AND\r
index e2e2ded7c3ee20f85360168f56826895f83fa0e1..09c571dfaab26631d6fd5fb67127c3af704341d4 100644 (file)
@@ -56,11 +56,11 @@ EFI_HII_THUNK_PRIVATE_DATA HiiThunkPrivateDataTempate = {
   },\r
 };\r
 \r
-CONST EFI_HII_DATABASE_PROTOCOL            *mUefiHiiDatabaseProtocol;\r
-CONST EFI_HII_FONT_PROTOCOL                *mUefiHiiFontProtocol;\r
-CONST EFI_HII_IMAGE_PROTOCOL               *mUefiHiiImageProtocol;\r
-CONST EFI_HII_STRING_PROTOCOL              *mUefiStringProtocol;\r
-CONST EFI_HII_CONFIG_ROUTING_PROTOCOL      *mUefiConfigRoutingProtocol;\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
 \r
 \r
 EFI_STATUS\r
@@ -96,35 +96,35 @@ Returns:
   Status = gBS->LocateProtocol (\r
                   &gEfiHiiDatabaseProtocolGuid,\r
                   NULL,\r
-                  (VOID **) &mUefiHiiDatabaseProtocol\r
+                  (VOID **) &mHiiDatabase\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   Status = gBS->LocateProtocol (\r
                   &gEfiHiiFontProtocolGuid,\r
                   NULL,\r
-                  (VOID **) &mUefiHiiFontProtocol\r
+                  (VOID **) &mHiiFontProtocol\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   Status = gBS->LocateProtocol (\r
                   &gEfiHiiImageProtocolGuid,\r
                   NULL,\r
-                  (VOID **) &mUefiHiiImageProtocol\r
+                  (VOID **) &mHiiImageProtocol\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   Status = gBS->LocateProtocol (\r
                   &gEfiHiiStringProtocolGuid,\r
                   NULL,\r
-                  (VOID **) &mUefiStringProtocol\r
+                  (VOID **) &mHiiStringProtocol\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   Status = gBS->LocateProtocol (\r
                   &gEfiHiiConfigRoutingProtocolGuid,\r
                   NULL,\r
-                  (VOID **) &mUefiConfigRoutingProtocol\r
+                  (VOID **) &mHiiConfigRoutingProtocol\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
index 662f8b04e833994dcb538045b5fb02540bb50b01..4ad98561411d8935e9c32b44f598ef0de90b2b3a 100644 (file)
@@ -46,18 +46,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/HiiLib.h>\r
 #include <Library/ExtendedHiiLib.h>\r
 \r
-//\r
-// There are some type redefinitions between Framework Ifr Support Library and \r
-// UEFI HII Ifr Support Library. We undefine the duplicated Framework  definition here \r
-// so that the duplicated definitions in UEFI HII Ifr can be defined.\r
-// In this Thunk Module, we will access all Framework definition with "FRAMEWORK_" prefix.\r
-//\r
-#undef IFR_OPTION\r
-#undef EFI_HII_UPDATE_DATA\r
-\r
 #include <Library/IfrSupportLib.h>\r
 #include <Library/ExtendedIfrSupportLib.h>\r
 \r
+#include <MdeModuleHii.h>\r
+\r
 //\r
 // Macros\r
 //\r
@@ -147,11 +140,11 @@ typedef struct {
 //\r
 // Extern Variables\r
 //\r
-extern CONST EFI_HII_DATABASE_PROTOCOL            *mUefiHiiDatabaseProtocol;\r
-extern CONST EFI_HII_FONT_PROTOCOL                *mUefiHiiFontProtocol;\r
-extern CONST EFI_HII_IMAGE_PROTOCOL               *mUefiHiiImageProtocol;\r
-extern CONST EFI_HII_STRING_PROTOCOL              *mUefiStringProtocol;\r
-extern CONST EFI_HII_CONFIG_ROUTING_PROTOCOL      *mUefiConfigRoutingProtocol;\r
+extern CONST EFI_HII_DATABASE_PROTOCOL            *mHiiDatabase;\r
+extern CONST EFI_HII_FONT_PROTOCOL                *mHiiFontProtocol;\r
+extern CONST EFI_HII_IMAGE_PROTOCOL               *mHiiImageProtocol;\r
+extern CONST EFI_HII_STRING_PROTOCOL              *mHiiStringProtocol;\r
+extern CONST EFI_HII_CONFIG_ROUTING_PROTOCOL      *mHiiConfigRoutingProtocol;\r
 \r
 //\r
 // Prototypes\r
index da0378f1ac90a1d9d156e93b0d89b93b0eead331..c22c5a65250bfb67fd5f8ead5512c363f0050693 100644 (file)
@@ -86,8 +86,8 @@ LibExportPackageLists (
 \r
   Size = 0;\r
   PackageListHdr = NULL;\r
-  Status = mUefiHiiDatabaseProtocol->ExportPackageLists (\r
-                                      mUefiHiiDatabaseProtocol,\r
+  Status = mHiiDatabase->ExportPackageLists (\r
+                                      mHiiDatabase,\r
                                       UefiHiiHandle,\r
                                       &Size,\r
                                       PackageListHdr\r
@@ -100,8 +100,8 @@ LibExportPackageLists (
     if (PackageListHeader == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     } else {\r
-      Status = mUefiHiiDatabaseProtocol->ExportPackageLists (\r
-                                          mUefiHiiDatabaseProtocol,\r
+      Status = mHiiDatabase->ExportPackageLists (\r
+                                          mHiiDatabase,\r
                                           UefiHiiHandle,\r
                                           &Size,\r
                                           PackageListHdr\r
@@ -140,8 +140,8 @@ InsertStringPackagesToIfrPackageList (
  )\r
 {\r
   EFI_STATUS                  Status;\r
-  Status = mUefiHiiDatabaseProtocol->UpdatePackageList (\r
-                                        mUefiHiiDatabaseProtocol,\r
+  Status = mHiiDatabase->UpdatePackageList (\r
+                                        mHiiDatabase,\r
                                         UefiHiiHandle,\r
                                         StringPackageListHeader\r
                                         );\r
@@ -253,23 +253,21 @@ PrepareUefiPackageListFromFrameworkHiiPackages (
   return PackageListHeader;  \r
 }\r
 \r
-EFI_GUID *\r
-UefiGeneratePackageListGuidId (\r
-  IN CONST EFI_HII_PACKAGES * Packages\r
+VOID\r
+GenerateGuidId (\r
+  IN      CONST EFI_GUID * InGuid,\r
+  OUT           EFI_GUID * OutGuid\r
   )\r
 {\r
-  EFI_GUID                 *Guid;\r
   UINT64                   MonotonicCount;\r
 \r
-  Guid = AllocateCopyPool (sizeof (EFI_GUID), Packages->GuidId);\r
+  CopyMem (OutGuid, InGuid, sizeof (EFI_GUID));\r
   \r
   gBS->GetNextMonotonicCount (&MonotonicCount);\r
   //\r
   // Use Monotonic Count as a psedo random number generator.\r
   //\r
-  *((UINT64 *) Guid) = *((UINT64 *) Guid) + MonotonicCount;\r
-  \r
-  return Guid;\r
+  *((UINT64 *) OutGuid) = *((UINT64 *) OutGuid) + MonotonicCount;\r
 }\r
 \r
 EFI_STATUS\r
@@ -310,6 +308,9 @@ FindAndAddStringPackageToIfrPackageList(
 \r
 }\r
 \r
+CONST EFI_GUID mAGuid = \r
+  { 0x14f95e01, 0xd562, 0x432e, { 0x84, 0x4a, 0x95, 0xa4, 0x39, 0x5, 0x10, 0x7e } };\r
+\r
 EFI_STATUS\r
 UefiRegisterPackageList(\r
   EFI_HII_THUNK_PRIVATE_DATA  *Private,\r
@@ -322,20 +323,35 @@ UefiRegisterPackageList(
   UINTN                       IfrPackNum;\r
   EFI_HII_PACKAGE_LIST_HEADER *UefiPackageListHeader;\r
   HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMappingEntry;\r
-  EFI_GUID                    *GuidId;\r
+  EFI_GUID                    GuidId;\r
   EFI_HANDLE                  UefiHiiDriverHandle;\r
 \r
-  GuidId = NULL;\r
   UefiHiiDriverHandle = NULL;\r
 \r
   Status = GetIfrAndStringPackNum (Packages, &IfrPackNum, &StringPackNum);\r
   ASSERT_EFI_ERROR (Status);\r
+  //\r
+  // Thunk Layer only handle the following combinations of IfrPack, StringPkg and FontPack\r
+  //\r
+  if (IfrPackNum > 1) {\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
   HandleMappingEntry->FrameworkHiiHandle = Private->StaticHiiHandle++;\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
+    Packages->GuidId = &GuidId;\r
+    GenerateGuidId (&mAGuid, Packages->GuidId);\r
+  }\r
+  \r
   CopyGuid (&HandleMappingEntry->TagGuid, Packages->GuidId);\r
 \r
   if ((StringPackNum == 0) && (IfrPackNum != 0)) {\r
@@ -344,7 +360,7 @@ UefiRegisterPackageList(
     // In Framework HII implementation, Packages->GuidId is used as an identifier to associate \r
     // a PackageList with only IFR to a Package list the with String package.\r
     //\r
-    GuidId = UefiGeneratePackageListGuidId (Packages);\r
+    GenerateGuidId (Packages->GuidId, &GuidId);\r
   }\r
 \r
   //\r
@@ -354,9 +370,9 @@ UefiRegisterPackageList(
   if (IfrPackNum != 0) {\r
     InstallDefaultUefiConfigAccessProtocol (Packages, &UefiHiiDriverHandle, HandleMappingEntry);\r
   }\r
-  UefiPackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, GuidId);\r
-  Status = mUefiHiiDatabaseProtocol->NewPackageList (\r
-              mUefiHiiDatabaseProtocol,\r
+  UefiPackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &GuidId);\r
+  Status = mHiiDatabase->NewPackageList (\r
+              mHiiDatabase,\r
               UefiPackageListHeader,  \r
               UefiHiiDriverHandle,\r
               &HandleMappingEntry->UefiHiiHandle\r
@@ -413,7 +429,6 @@ Done:
   }\r
 \r
   FreePool (UefiPackageListHeader);\r
-  SafeFreePool (GuidId);\r
   \r
   return Status;\r
 }\r
@@ -493,8 +508,8 @@ Returns:
   HandleMapEntry = FrameworkHiiHandleToMapDatabaseEntry (Private, Handle);\r
 \r
   if (HandleMapEntry->UefiHiiHandle != NULL) {\r
-    Status = mUefiHiiDatabaseProtocol->RemovePackageList (\r
-                                          mUefiHiiDatabaseProtocol,\r
+    Status = mHiiDatabase->RemovePackageList (\r
+                                          mHiiDatabase,\r
                                           HandleMapEntry->UefiHiiHandle\r
                                           );\r
     ASSERT_EFI_ERROR (Status);\r
diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/R8Lib.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/R8Lib.c
new file mode 100644 (file)
index 0000000..54693f7
--- /dev/null
@@ -0,0 +1,244 @@
+/**@file
+  Copyright (c) 2007, Intel Corporation
+
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+#include <PiDxe.h>
+#include "R8Lib.h"
+
+CHAR16
+NibbleToHexChar (
+  IN UINT8      Nibble
+  )
+/*++
+
+  Routine Description:
+    Converts the low nibble of a byte  to hex unicode character.
+
+  Arguments:
+    Nibble - lower nibble of a byte.
+
+  Returns:
+    Hex unicode character.
+
+--*/
+{
+  Nibble &= 0x0F;
+  if (Nibble <= 0x9) {
+    return (CHAR16)(Nibble + L'0');
+  }
+
+  return (CHAR16)(Nibble - 0xA + L'A');
+}
+
+
+
+/**
+  Converts binary buffer to Unicode string.
+  At a minimum, any blob of data could be represented as a hex string.
+
+  @param  Str                    Pointer to the string.
+  @param  HexStringBufferLength  Length in bytes of buffer to hold the hex string.
+                                 Includes tailing '\0' character. If routine return
+                                 with EFI_SUCCESS, containing length of hex string
+                                 buffer. If routine return with
+                                 EFI_BUFFER_TOO_SMALL, containg length of hex
+                                 string buffer desired.
+  @param  Buf                    Buffer to be converted from.
+  @param  Len                    Length in bytes of the buffer to be converted.
+
+  @retval EFI_SUCCESS            Routine success.
+  @retval EFI_BUFFER_TOO_SMALL   The hex string buffer is too small.
+
+**/
+EFI_STATUS
+R8_BufToHexString (
+  IN OUT CHAR16                    *Str,
+  IN OUT UINTN                     *HexStringBufferLength,
+  IN     UINT8                     *Buf,
+  IN     UINTN                      Len
+  )
+{
+  //
+  // Porting Guide:
+  // This library interface is simply obsolete.
+  // Include the source code to user code.
+  //
+  UINTN       Idx;
+  UINT8       Byte;
+  UINTN       StrLen;
+
+  //
+  // Make sure string is either passed or allocate enough.
+  // It takes 2 Unicode characters (4 bytes) to represent 1 byte of the binary buffer.
+  // Plus the Unicode termination character.
+  //
+  StrLen = Len * 2;
+  if (StrLen > ((*HexStringBufferLength) - 1)) {
+    *HexStringBufferLength = StrLen + 1;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  *HexStringBufferLength = StrLen + 1;
+  //
+  // Ends the string.
+  //
+  Str[StrLen] = L'\0';
+
+  for (Idx = 0; Idx < Len; Idx++) {
+
+    Byte = Buf[Idx];
+    Str[StrLen - 1 - Idx * 2] = NibbleToHexChar (Byte);
+    Str[StrLen - 2 - Idx * 2] = NibbleToHexChar ((UINT8)(Byte >> 4));
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+
+
+/**
+  Converts Unicode string to binary buffer.
+  The conversion may be partial.
+  The first character in the string that is not hex digit stops the conversion.
+  At a minimum, any blob of data could be represented as a hex string.
+
+  @param  Buf                    Pointer to buffer that receives the data.
+  @param  Len                    Length in bytes of the buffer to hold converted
+                                 data. If routine return with EFI_SUCCESS,
+                                 containing length of converted data. If routine
+                                 return with EFI_BUFFER_TOO_SMALL, containg length
+                                 of buffer desired.
+  @param  Str                    String to be converted from.
+  @param  ConvertedStrLen        Length of the Hex String consumed.
+
+  @retval EFI_SUCCESS            Routine Success.
+  @retval EFI_BUFFER_TOO_SMALL   The buffer is too small to hold converted data.
+
+**/
+EFI_STATUS
+R8_HexStringToBuf (
+  IN OUT UINT8                     *Buf,
+  IN OUT UINTN                    *Len,
+  IN     CHAR16                    *Str,
+  OUT    UINTN                     *ConvertedStrLen  OPTIONAL
+  )
+{
+  //
+  // Porting Guide:
+  // This library interface is simply obsolete.
+  // Include the source code to user code.
+  //
+
+  UINTN       HexCnt;
+  UINTN       Idx;
+  UINTN       BufferLength;
+  UINT8       Digit;
+  UINT8       Byte;
+
+  //
+  // Find out how many hex characters the string has.
+  //
+  for (Idx = 0, HexCnt = 0; R8_IsHexDigit (&Digit, Str[Idx]); Idx++, HexCnt++);
+
+  if (HexCnt == 0) {
+    *Len = 0;
+    return EFI_SUCCESS;
+  }
+  //
+  // Two Unicode characters make up 1 buffer byte. Round up.
+  //
+  BufferLength = (HexCnt + 1) / 2;
+
+  //
+  // Test if  buffer is passed enough.
+  //
+  if (BufferLength > (*Len)) {
+    *Len = BufferLength;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  *Len = BufferLength;
+
+  for (Idx = 0; Idx < HexCnt; Idx++) {
+
+    R8_IsHexDigit (&Digit, Str[HexCnt - 1 - Idx]);
+
+    //
+    // For odd charaters, write the lower nibble for each buffer byte,
+    // and for even characters, the upper nibble.
+    //
+    if ((Idx & 1) == 0) {
+      Byte = Digit;
+    } else {
+      Byte = Buf[Idx / 2];
+      Byte &= 0x0F;
+      Byte = (UINT8) (Byte | Digit << 4);
+    }
+
+    Buf[Idx / 2] = Byte;
+  }
+
+  if (ConvertedStrLen != NULL) {
+    *ConvertedStrLen = HexCnt;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+
+
+/**
+  Determines if a Unicode character is a hexadecimal digit.
+  The test is case insensitive.
+
+  @param  Digit                  Pointer to byte that receives the value of the hex
+                                 character.
+  @param  Char                   Unicode character to test.
+
+  @retval TRUE                   If the character is a hexadecimal digit.
+  @retval FALSE                  Otherwise.
+
+**/
+BOOLEAN
+R8_IsHexDigit (
+  OUT UINT8      *Digit,
+  IN  CHAR16      Char
+  )
+{
+  //
+  // Porting Guide:
+  // This library interface is simply obsolete.
+  // Include the source code to user code.
+  //
+
+  if ((Char >= L'0') && (Char <= L'9')) {
+    *Digit = (UINT8) (Char - L'0');
+    return TRUE;
+  }
+
+  if ((Char >= L'A') && (Char <= L'F')) {
+    *Digit = (UINT8) (Char - L'A' + 0x0A);
+    return TRUE;
+  }
+
+  if ((Char >= L'a') && (Char <= L'f')) {
+    *Digit = (UINT8) (Char - L'a' + 0x0A);
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+
diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/R8Lib.h b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/R8Lib.h
new file mode 100644 (file)
index 0000000..a090319
--- /dev/null
@@ -0,0 +1,97 @@
+/**@file
+  Copyright (c) 2007, Intel Corporation
+
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+**/
+
+
+
+/**
+  Converts binary buffer to Unicode string.
+  At a minimum, any blob of data could be represented as a hex string.
+
+  @param  Str                    Pointer to the string.
+  @param  HexStringBufferLength  Length in bytes of buffer to hold the hex string.
+                                 Includes tailing '\0' character. If routine return
+                                 with EFI_SUCCESS, containing length of hex string
+                                 buffer. If routine return with
+                                 EFI_BUFFER_TOO_SMALL, containg length of hex
+                                 string buffer desired.
+  @param  Buf                    Buffer to be converted from.
+  @param  Len                    Length in bytes of the buffer to be converted.
+
+  @retval EFI_SUCCESS            Routine success.
+  @retval EFI_BUFFER_TOO_SMALL   The hex string buffer is too small.
+
+**/
+EFI_STATUS
+R8_BufToHexString (
+  IN OUT CHAR16                    *Str,
+  IN OUT UINTN                     *HexStringBufferLength,
+  IN     UINT8                     *Buf,
+  IN     UINTN                      Len
+  )
+;
+
+
+
+
+/**
+  Converts Unicode string to binary buffer.
+  The conversion may be partial.
+  The first character in the string that is not hex digit stops the conversion.
+  At a minimum, any blob of data could be represented as a hex string.
+
+  @param  Buf                    Pointer to buffer that receives the data.
+  @param  Len                    Length in bytes of the buffer to hold converted
+                                 data. If routine return with EFI_SUCCESS,
+                                 containing length of converted data. If routine
+                                 return with EFI_BUFFER_TOO_SMALL, containg length
+                                 of buffer desired.
+  @param  Str                    String to be converted from.
+  @param  ConvertedStrLen        Length of the Hex String consumed.
+
+  @retval EFI_SUCCESS            Routine Success.
+  @retval EFI_BUFFER_TOO_SMALL   The buffer is too small to hold converted data.
+
+**/
+EFI_STATUS
+R8_HexStringToBuf (
+  IN OUT UINT8                     *Buf,
+  IN OUT UINTN                    *Len,
+  IN     CHAR16                    *Str,
+  OUT    UINTN                     *ConvertedStrLen  OPTIONAL
+  )
+;
+
+
+
+
+/**
+  Determines if a Unicode character is a hexadecimal digit.
+  The test is case insensitive.
+
+  @param  Digit                  Pointer to byte that receives the value of the hex
+                                 character.
+  @param  Char                   Unicode character to test.
+
+  @retval TRUE                   If the character is a hexadecimal digit.
+  @retval FALSE                  Otherwise.
+
+**/
+BOOLEAN
+R8_IsHexDigit (
+  OUT UINT8      *Digit,
+  IN  CHAR16      Char
+  )
+;
+
+
index 0054ee43fc38dc64591fa0836a77e0588f0db1bd..85124c0316132899acd01a27d5b85d1ec0f00dd6 100644 (file)
@@ -267,8 +267,8 @@ Returns:
       if (AsciiLanguage == NULL) {\r
         return HiiLibGetString (HandleMapEntry->UefiHiiHandle, Token, StringBuffer, BufferLengthTemp);\r
       } else {\r
-        return mUefiStringProtocol->GetString (\r
-                                     mUefiStringProtocol,\r
+        return mHiiStringProtocol->GetString (\r
+                                     mHiiStringProtocol,\r
                                      AsciiLanguage,\r
                                      HandleMapEntry->UefiHiiHandle,\r
                                      Token,\r
diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrDefault.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrDefault.c
new file mode 100644 (file)
index 0000000..2ba1ffc
--- /dev/null
@@ -0,0 +1,778 @@
+/** @file\r
+  Function and Macro defintions for to extract default values from UEFI Form package.\r
+\r
+  Copyright (c) 2008, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+\r
+#include <FrameworkDxe.h>\r
+\r
+#include <Protocol/FrameworkHii.h>\r
+#include <Protocol/HiiDatabase.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+#include "UefiIfrParser.h"\r
+#include "UefiIfrDefault.h"\r
+\r
+//\r
+// Extern Variables\r
+//\r
+extern CONST EFI_HII_DATABASE_PROTOCOL            *mHiiDatabase;\r
+extern CONST EFI_HII_FONT_PROTOCOL                *mHiiFontProtocol;\r
+extern CONST EFI_HII_IMAGE_PROTOCOL               *mHiiImageProtocol;\r
+extern CONST EFI_HII_STRING_PROTOCOL              *mHiiStringProtocol;\r
+extern CONST EFI_HII_CONFIG_ROUTING_PROTOCOL      *mHiiConfigRoutingProtocol;\r
+\r
+extern EFI_GUID          gZeroGuid;\r
+\r
+/**\r
+  Fetch the Ifr binary data of a FormSet.\r
+\r
+  @param  Handle                 PackageList Handle\r
+  @param  FormSetGuid            GUID of a formset. If not specified (NULL or zero\r
+                                 GUID), take the first FormSet found in package\r
+                                 list.\r
+  @param  BinaryLength           The length of the FormSet IFR binary.\r
+  @param  BinaryData             The buffer designed to receive the FormSet.\r
+\r
+  @retval EFI_SUCCESS            Buffer filled with the requested FormSet.\r
+                                 BufferLength was updated.\r
+  @retval EFI_INVALID_PARAMETER  The handle is unknown.\r
+  @retval EFI_NOT_FOUND          A form or FormSet on the requested handle cannot\r
+                                 be found with the requested FormId.\r
+\r
+**/\r
+EFI_STATUS\r
+GetIfrBinaryData (\r
+  IN  EFI_HII_HANDLE   Handle,\r
+  IN OUT EFI_GUID      *FormSetGuid,\r
+  OUT UINTN            *BinaryLength,\r
+  OUT UINT8            **BinaryData\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;\r
+  UINTN                        BufferSize;\r
+  UINT8                        *Package;\r
+  UINT8                        *OpCodeData;\r
+  UINT32                       Offset;\r
+  UINT32                       Offset2;\r
+  BOOLEAN                      ReturnDefault;\r
+  UINT32                       PackageListLength;\r
+  EFI_HII_PACKAGE_HEADER       PackageHeader;\r
+\r
+  OpCodeData = NULL;\r
+  Package = NULL;\r
+  ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));;\r
+\r
+  //\r
+  // if FormSetGuid is NULL or zero GUID, return first FormSet in the package list\r
+  //\r
+  if (FormSetGuid == NULL || CompareGuid (FormSetGuid, &gZeroGuid)) {\r
+    ReturnDefault = TRUE;\r
+  } else {\r
+    ReturnDefault = FALSE;\r
+  }\r
+\r
+  //\r
+  // Get HII PackageList\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
+  }\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Get Form package from this HII package List\r
+  //\r
+  Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+  Offset2 = 0;\r
+  CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
+\r
+  while (Offset < PackageListLength) {\r
+    Package = ((UINT8 *) HiiPackageList) + Offset;\r
+    CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+\r
+    if (PackageHeader.Type == EFI_HII_PACKAGE_FORM) {\r
+      //\r
+      // Search FormSet in this Form Package\r
+      //\r
+      Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
+      while (Offset2 < PackageHeader.Length) {\r
+        OpCodeData = Package + Offset2;\r
+\r
+        if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
+          //\r
+          // Check whether return default FormSet\r
+          //\r
+          if (ReturnDefault) {\r
+            break;\r
+          }\r
+\r
+          //\r
+          // FormSet GUID is specified, check it\r
+          //\r
+          if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
+            break;\r
+          }\r
+        }\r
+\r
+        Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
+      }\r
+\r
+      if (Offset2 < PackageHeader.Length) {\r
+        //\r
+        // Target formset found\r
+        //\r
+        break;\r
+      }\r
+    }\r
+\r
+    Offset += PackageHeader.Length;\r
+  }\r
+\r
+  if (Offset >= PackageListLength) {\r
+    //\r
+    // Form package not found in this Package List\r
+    //\r
+    gBS->FreePool (HiiPackageList);\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  if (ReturnDefault && FormSetGuid != NULL) {\r
+    //\r
+    // Return the default FormSet GUID\r
+    //\r
+    CopyMem (FormSetGuid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
+  }\r
+\r
+  //\r
+  // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes\r
+  // in this FormSet; So, here just simply copy the data from start of a FormSet to the end\r
+  // of the Form Package.\r
+  //\r
+  *BinaryLength = PackageHeader.Length - Offset2;\r
+  *BinaryData = AllocateCopyPool (*BinaryLength, OpCodeData);\r
+\r
+  gBS->FreePool (HiiPackageList);\r
+\r
+  if (*BinaryData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Initialize the internal data structure of a FormSet.\r
+\r
+  @param  Handle                 PackageList Handle\r
+  @param  FormSetGuid            GUID of a formset. If not specified (NULL or zero\r
+                                 GUID), take the first FormSet found in package\r
+                                 list.\r
+  @param  FormSet                FormSet data structure.\r
+\r
+  @retval EFI_SUCCESS            The function completed successfully.\r
+  @retval EFI_NOT_FOUND          The specified FormSet could not be found.\r
+\r
+**/\r
+EFI_STATUS\r
+InitializeFormSet (\r
+  IN  EFI_HII_HANDLE                   Handle,\r
+  IN OUT EFI_GUID                      *FormSetGuid,\r
+  OUT FORM_BROWSER_FORMSET             *FormSet\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_HANDLE                DriverHandle;\r
+\r
+  Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  FormSet->HiiHandle = Handle;\r
+  CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));\r
+\r
+  //\r
+  // Retrieve ConfigAccess Protocol associated with this HiiPackageList\r
+  //\r
+  Status = mHiiDatabase->GetPackageListHandle (mHiiDatabase, Handle, &DriverHandle);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  FormSet->DriverHandle = DriverHandle;\r
+  Status = gBS->HandleProtocol (\r
+                  DriverHandle,\r
+                  &gEfiHiiConfigAccessProtocolGuid,\r
+                  (VOID **) &FormSet->ConfigAccess\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Configuration Driver don't attach ConfigAccess protocol to its HII package\r
+    // list, then there will be no configuration action required\r
+    //\r
+    FormSet->ConfigAccess = NULL;\r
+  }\r
+\r
+  //\r
+  // Parse the IFR binary OpCodes\r
+  //\r
+  Status = ParseOpCodes (FormSet);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Set the data position at Offset with Width in Node->Buffer based \r
+  the value passed in.\r
+\r
+  @param  Node                    The Buffer Storage Node.\r
+  @param Value                    The input value.\r
+  @param Offset                   The offset in Node->Buffer for the update.\r
+  @param Width                    The length of the Value.\r
+  \r
+  @retval VOID\r
+\r
+**/\r
+VOID\r
+SetNodeBuffer (\r
+  OUT UEFI_IFR_BUFFER_STORAGE_NODE        *Node,\r
+  IN  CONST   EFI_HII_VALUE               *Value,\r
+  IN  UINTN                               Offset,\r
+  IN  UINTN                               Width\r
+  )\r
+{\r
+  ASSERT (Node->Signature == UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE);\r
+  ASSERT (Offset + Width <= Node->Size);\r
+\r
+  CopyMem (Node->Buffer + Offset, &Value->Value.u8, Width);\r
+}\r
+\r
+\r
+/**\r
+  Reset Question to its default value.\r
+\r
+  @param  FormSet                FormSet data structure.\r
+  @param  DefaultId              The Class of the default.\r
+\r
+  @retval EFI_SUCCESS            Question is reset to default value.\r
+\r
+**/\r
+EFI_STATUS\r
+GetQuestionDefault (\r
+  IN FORM_BROWSER_FORMSET             *FormSet,\r
+  IN FORM_BROWSER_FORM                *Form,\r
+  IN FORM_BROWSER_STATEMENT           *Question,\r
+  IN UINT16                           DefaultId,\r
+  IN UINT16                           VarStoreId,\r
+  OUT UEFI_IFR_BUFFER_STORAGE_NODE        *Node\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  LIST_ENTRY              *Link;\r
+  QUESTION_DEFAULT        *Default;\r
+  QUESTION_OPTION         *Option;\r
+  EFI_HII_VALUE           *HiiValue;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  // Statement don't have storage, skip them\r
+  //\r
+  if (Question->QuestionId == 0) {\r
+    return Status;\r
+  }\r
+\r
+  if (Question->VarStoreId != VarStoreId) {\r
+    return Status;\r
+  }\r
+\r
+  ASSERT (Question->Storage->Type == EFI_HII_VARSTORE_BUFFER);\r
+\r
+  //\r
+  // There are three ways to specify default value for a Question:\r
+  //  1, use nested EFI_IFR_DEFAULT (highest priority)\r
+  //  2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)\r
+  //  3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)\r
+  //\r
+  HiiValue = &Question->HiiValue;\r
+\r
+  //\r
+  // EFI_IFR_DEFAULT has highest priority\r
+  //\r
+  if (!IsListEmpty (&Question->DefaultListHead)) {\r
+    Link = GetFirstNode (&Question->DefaultListHead);\r
+    while (!IsNull (&Question->DefaultListHead, Link)) {\r
+      Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
+\r
+      if (Default->DefaultId == DefaultId) {\r
+        if (Default->ValueExpression != NULL) {\r
+          //\r
+          // Default is provided by an Expression, evaluate it\r
+          //\r
+          Status = EvaluateExpression (FormSet, Form, Default->ValueExpression);\r
+          if (EFI_ERROR (Status)) {\r
+            return Status;\r
+          }\r
+\r
+          CopyMem (HiiValue, &Default->ValueExpression->Result, sizeof (EFI_HII_VALUE));\r
+        } else {\r
+          //\r
+          // Default value is embedded in EFI_IFR_DEFAULT\r
+          //\r
+          CopyMem (HiiValue, &Default->Value, sizeof (EFI_HII_VALUE));\r
+        }\r
+       \r
+        SetNodeBuffer (Node, HiiValue, Question->VarStoreInfo.VarOffset, Question->StorageWidth);\r
+        return EFI_SUCCESS;\r
+      }\r
+\r
+      Link = GetNextNode (&Question->DefaultListHead, Link);\r
+    }\r
+  }\r
+\r
+  //\r
+  // EFI_ONE_OF_OPTION\r
+  //\r
+  if ((Question->Operand == EFI_IFR_ONE_OF_OP) && !IsListEmpty (&Question->OptionListHead)) {\r
+    if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING)  {\r
+      //\r
+      // OneOfOption could only provide Standard and Manufacturing default\r
+      //\r
+      Link = GetFirstNode (&Question->OptionListHead);\r
+      while (!IsNull (&Question->OptionListHead, Link)) {\r
+        Option = QUESTION_OPTION_FROM_LINK (Link);\r
+\r
+        if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && (Option->Flags & EFI_IFR_OPTION_DEFAULT)) ||\r
+            ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && (Option->Flags & EFI_IFR_OPTION_DEFAULT_MFG))\r
+           ) {\r
+          CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));\r
+\r
+          SetNodeBuffer (Node, HiiValue, Question->VarStoreInfo.VarOffset, Question->StorageWidth);\r
+          return EFI_SUCCESS;\r
+        }\r
+\r
+        Link = GetNextNode (&Question->OptionListHead, Link);\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // EFI_IFR_CHECKBOX - lowest priority\r
+  //\r
+  if (Question->Operand == EFI_IFR_CHECKBOX_OP) {\r
+    if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING)  {\r
+      //\r
+      // Checkbox could only provide Standard and Manufacturing default\r
+      //\r
+      if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && (Question->Flags & EFI_IFR_CHECKBOX_DEFAULT)) ||\r
+          ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && (Question->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG))\r
+         ) {\r
+        HiiValue->Value.b = TRUE;\r
+      } else {\r
+        HiiValue->Value.b = FALSE;\r
+      }\r
+\r
+      SetNodeBuffer (Node, HiiValue, Question->VarStoreInfo.VarOffset, Question->StorageWidth);\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Reset Questions in a Form to their default value.\r
+\r
+  @param  FormSet                FormSet data structure.\r
+  @param  Form                   The Form which to be reset.\r
+  @param  DefaultId              The Class of the default.\r
+\r
+  @retval EFI_SUCCESS            The function completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+ExtractFormDefault (\r
+  IN FORM_BROWSER_FORMSET             *FormSet,\r
+  IN FORM_BROWSER_FORM                *Form,\r
+  IN UINT16                           DefaultId,\r
+  IN UINT16                           VarStoreId,\r
+  OUT UEFI_IFR_BUFFER_STORAGE_NODE        *Node\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  LIST_ENTRY              *Link;\r
+  FORM_BROWSER_STATEMENT  *Question;\r
+\r
+  Link = GetFirstNode (&Form->StatementListHead);\r
+  while (!IsNull (&Form->StatementListHead, Link)) {\r
+    Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+    Link = GetNextNode (&Form->StatementListHead, Link);\r
+\r
+    //\r
+    // Reset Question to its default value\r
+    //\r
+    Status = GetQuestionDefault (FormSet, Form, Question, DefaultId, VarStoreId, Node);\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Destroy all the buffer allocated for the fileds of\r
+  UEFI_IFR_BUFFER_STORAGE_NODE. The Node itself\r
+  will be freed too.\r
+\r
+  @param  FormSet                FormSet data structure.\r
+  @param  DefaultId              The Class of the default.\r
+\r
+  @retval   VOID\r
+\r
+**/\r
+VOID\r
+DestroyDefaultNode (\r
+  IN UEFI_IFR_BUFFER_STORAGE_NODE        *Node\r
+  )\r
+{\r
+  SafeFreePool (Node->Buffer);\r
+  SafeFreePool (Node->Name);\r
+  SafeFreePool (Node);\r
+}\r
+\r
+\r
+/**\r
+  Get the default value for Buffer Type storage named by\r
+  a Default Store and a Storage Store from a FormSet.\r
+  The result is in the a instance of UEFI_IFR_BUFFER_STORAGE_NODE\r
+  allocated by this function. It is inserted to the link list.\r
+  \r
+  @param  DefaultStore            The Default Store.\r
+  @param  Storage                   The Storage.\r
+  @param  FormSet                  The Form Set.\r
+  @param  UefiDefaultsListHead The head of link list for the output.\r
+\r
+  @retval   EFI_SUCCESS          Successful.\r
+  \r
+**/\r
+EFI_STATUS\r
+GetBufferTypeDefaultIdAndStorageId (\r
+  IN        FORMSET_DEFAULTSTORE        *DefaultStore,\r
+  IN        FORMSET_STORAGE             *Storage,\r
+  IN        FORM_BROWSER_FORMSET        *FormSet,\r
+  OUT       LIST_ENTRY                  *UefiDefaultsListHead\r
+ )\r
+{\r
+  UEFI_IFR_BUFFER_STORAGE_NODE        *Node;\r
+  LIST_ENTRY              *Link;\r
+  FORM_BROWSER_FORM       *Form;\r
+  EFI_STATUS              Status;\r
+\r
+  Node = AllocateZeroPool (sizeof (UEFI_IFR_BUFFER_STORAGE_NODE));\r
+  ASSERT (Node != NULL);\r
+\r
+  Node->Signature = UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE;\r
+  Node->Name      = AllocateCopyPool (StrSize (Storage->Name), Storage->Name);\r
+  Node->DefaultId = DefaultStore->DefaultId;\r
+  CopyGuid (&Node->Guid, &Storage->Guid);\r
+  Node->Size      = Storage->Size;\r
+  Node->Buffer    = AllocateZeroPool (Node->Size);\r
+  //\r
+  // Extract default from IFR binary\r
+  //\r
+  Link = GetFirstNode (&FormSet->FormListHead);\r
+  while (!IsNull (&FormSet->FormListHead, Link)) {\r
+    Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+\r
+    Status = ExtractFormDefault (FormSet, Form, DefaultStore->DefaultId, Storage->VarStoreId, Node);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    Link = GetNextNode (&FormSet->FormListHead, Link);\r
+  }\r
+\r
+  InsertTailList (UefiDefaultsListHead, &Node->List);\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Get the default value for Buffer Type storage named by\r
+  a Default Store from a FormSet.\r
+  The result is in the a instance of UEFI_IFR_BUFFER_STORAGE_NODE\r
+  allocated by this function. The output can be multiple instances\r
+  of UEFI_IFR_BUFFER_STORAGE_NODE. It is inserted to the link list.\r
+  \r
+  @param  DefaultStore            The Default Store.\r
+  @param  FormSet                  The Form Set.\r
+  @param  UefiDefaultsListHead The head of link list for the output.\r
+\r
+  @retval   EFI_SUCCESS          Successful.\r
+  \r
+**/\r
+EFI_STATUS\r
+GetBufferTypeDefaultId (\r
+  IN  FORMSET_DEFAULTSTORE  *DefaultStore,\r
+  IN  FORM_BROWSER_FORMSET  *FormSet,\r
+  OUT       LIST_ENTRY      *UefiDefaultsListHead\r
+  )\r
+{\r
+  LIST_ENTRY                  *StorageListEntry;\r
+  FORMSET_STORAGE             *Storage;\r
+  EFI_STATUS                  Status;\r
+\r
+  StorageListEntry = GetFirstNode (&FormSet->StorageListHead);\r
+\r
+  while (!IsNull (&FormSet->StorageListHead, StorageListEntry)) {\r
+    Storage = FORMSET_STORAGE_FROM_LINK(StorageListEntry);\r
+\r
+    if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
+      Status = GetBufferTypeDefaultIdAndStorageId (DefaultStore, Storage, FormSet, UefiDefaultsListHead);\r
+    }\r
+\r
+    StorageListEntry = GetNextNode (&FormSet->StorageListHead, StorageListEntry);\r
+  }\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Get the default value for Buffer Type storage from the first FormSet\r
+  in the Package List specified by a EFI_HII_HANDLE.\r
+  \r
+  The results can be multiple instances of UEFI_IFR_BUFFER_STORAGE_NODE. \r
+  They are inserted to the link list.\r
+  \r
+  @param  UefiHiiHandle           The handle for the package list.\r
+  @param  UefiDefaultsListHead The head of link list for the output.\r
+\r
+  @retval   EFI_SUCCESS          Successful.\r
+  \r
+**/\r
+EFI_STATUS\r
+UefiIfrGetBufferTypeDefaults (\r
+  IN  EFI_HII_HANDLE      UefiHiiHandle,\r
+  OUT LIST_ENTRY          **UefiDefaults\r
+  )\r
+{\r
+  FORM_BROWSER_FORMSET *FormSet;\r
+  EFI_GUID              FormSetGuid;\r
+  LIST_ENTRY            *DefaultListEntry;\r
+  FORMSET_DEFAULTSTORE  *DefaultStore;\r
+  EFI_STATUS            Status;\r
+\r
+  ASSERT (UefiDefaults != NULL);\r
+\r
+  FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));    \r
+  ASSERT (FormSet != NULL);\r
+\r
+  CopyGuid (&FormSetGuid, &gZeroGuid);\r
+  Status = InitializeFormSet (UefiHiiHandle, &FormSetGuid, FormSet);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  *UefiDefaults = AllocateZeroPool (sizeof (LIST_ENTRY));\r
+  ASSERT (UefiDefaults != NULL);\r
+  InitializeListHead (*UefiDefaults);\r
+\r
+  DefaultListEntry = GetFirstNode (&FormSet->DefaultStoreListHead);\r
+  while (!IsNull (&FormSet->DefaultStoreListHead, DefaultListEntry)) {\r
+    DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultListEntry);\r
+\r
+    Status = GetBufferTypeDefaultId (DefaultStore, FormSet, *UefiDefaults);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    DefaultListEntry = GetNextNode (&FormSet->DefaultStoreListHead, DefaultListEntry);    \r
+  }\r
+\r
+  DestroyFormSet (FormSet);\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Convert the UEFI Buffer Type default values to a Framework HII default\r
+  values specified by a EFI_HII_VARIABLE_PACK_LIST structure.\r
+  \r
+  @param  ListHead                  The link list of UEFI_IFR_BUFFER_STORAGE_NODE\r
+                                              which contains the default values retrived from\r
+                                              a UEFI form set.\r
+  @param  DefaultMask            The default mask.\r
+                                             The valid values are FRAMEWORK_EFI_IFR_FLAG_DEFAULT\r
+                                             and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.\r
+                                            UEFI spec only map FRAMEWORK_EFI_IFR_FLAG_DEFAULT and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING \r
+                                            from specification to valid default class.\r
+  @param  VariablePackList     The output default value in a format defined in Framework.\r
+                                             \r
+\r
+  @retval   EFI_SUCCESS                       Successful.\r
+  @retval   EFI_INVALID_PARAMETER      The default mask is not FRAMEWORK_EFI_IFR_FLAG_DEFAULT or \r
+                                                           FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.\r
+**/\r
+EFI_STATUS\r
+UefiDefaultsToFrameworkDefaults (\r
+  IN     LIST_ENTRY                  *ListHead,\r
+  IN     UINTN                       DefaultMask,\r
+  OUT    EFI_HII_VARIABLE_PACK_LIST  **VariablePackList\r
+  )\r
+{\r
+  LIST_ENTRY                        *List;\r
+  UEFI_IFR_BUFFER_STORAGE_NODE      *Node;\r
+  UINTN                             Size;\r
+  UINTN                             Count;\r
+  UINT16                            DefaultId;\r
+  EFI_HII_VARIABLE_PACK             *Pack;\r
+  EFI_HII_VARIABLE_PACK_LIST        *PackList;\r
+\r
+  if (DefaultMask == FRAMEWORK_EFI_IFR_FLAG_DEFAULT) {\r
+    DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+  } else if (DefaultMask == FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING) {\r
+    DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+  } else {\r
+    //\r
+    // UEFI spec only map FRAMEWORK_EFI_IFR_FLAG_DEFAULT and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING \r
+    // from specification to valid default class.\r
+    //\r
+    ASSERT (FALSE);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  //\r
+  // Calculate the size of the output EFI_HII_VARIABLE_PACK_LIST structure\r
+  //\r
+  Size = 0;\r
+  Count = 0;\r
+  List = GetFirstNode (ListHead);\r
+  while (!IsNull (ListHead, List)) {\r
+    Node = UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(List);\r
+\r
+    if (Node->DefaultId == DefaultId) {\r
+      Size += Node->Size;\r
+      Size += StrSize (Node->Name);\r
+\r
+      Count++;\r
+    }\r
+    \r
+    List = GetNextNode (ListHead, List);  \r
+  }\r
+\r
+  Size = Size + Count * (sizeof (EFI_HII_VARIABLE_PACK_LIST) + sizeof (EFI_HII_VARIABLE_PACK));\r
+  \r
+  *VariablePackList = AllocateZeroPool (Size);\r
+  ASSERT (*VariablePackList != NULL);\r
+\r
+  List = GetFirstNode (ListHead);\r
+\r
+  PackList = (EFI_HII_VARIABLE_PACK_LIST *) *VariablePackList;\r
+  Pack     = (EFI_HII_VARIABLE_PACK *) (PackList + 1);\r
+  while (!IsNull (ListHead, List)) {\r
+    Node = UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(List);\r
+\r
+    Size = 0;    \r
+    if (Node->DefaultId == DefaultId) {\r
+      Size += Node->Size;\r
+      Size += StrSize (Node->Name);\r
+      Size += sizeof (EFI_HII_VARIABLE_PACK);      \r
+\r
+      //\r
+      // In UEFI, 0 is defined to be invalid for EFI_IFR_VARSTORE.VarStoreId.\r
+      // So the default storage of Var Store in VFR from a Framework module \r
+      // should be translated to 0xFFEE.\r
+      //\r
+      if (Node->StoreId == 0xFFEE) {\r
+        Pack->VariableId = 0;\r
+      }\r
+      //\r
+      // Initialize EFI_HII_VARIABLE_PACK\r
+      //\r
+      Pack->Header.Type   = 0;\r
+      Pack->Header.Length = Size;\r
+      Pack->VariableId = Node->StoreId;\r
+      Pack->VariableNameLength = StrSize (Node->Name);\r
+      CopyMem (&Pack->VariableGuid, &Node->Guid, sizeof (EFI_GUID));\r
+      \r
+      CopyMem ((UINT8 *) Pack + sizeof (EFI_HII_VARIABLE_PACK), Node->Name, StrSize (Node->Name));\r
+      CopyMem ((UINT8 *) Pack + sizeof (EFI_HII_VARIABLE_PACK) + Pack->VariableNameLength, Node->Buffer, Node->Size);\r
+\r
+      Size += sizeof (EFI_HII_VARIABLE_PACK_LIST);\r
+\r
+      //\r
+      // initialize EFI_HII_VARIABLE_PACK_LIST\r
+      //\r
+      PackList->VariablePack = Pack;\r
+      PackList->NextVariablePack = (EFI_HII_VARIABLE_PACK_LIST *)((UINT8 *) PackList + Size);\r
+            \r
+    }\r
+    \r
+    List = GetNextNode (ListHead, List);  \r
+  }\r
+  \r
+  \r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Free up all buffer allocated for the link list of UEFI_IFR_BUFFER_STORAGE_NODE.\r
+    \r
+  @param  ListHead                  The link list of UEFI_IFR_BUFFER_STORAGE_NODE\r
+                                              which contains the default values retrived from\r
+                                              a UEFI form set.\r
+                                             \r
+\r
+  @retval   EFI_SUCCESS                       Successful.\r
+  @retval   EFI_INVALID_PARAMETER      The default mask is not FRAMEWORK_EFI_IFR_FLAG_DEFAULT or \r
+                                                           FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.\r
+**/\r
+VOID\r
+FreeDefaultList (\r
+  IN     LIST_ENTRY                  *ListHead\r
+  )\r
+{\r
+  LIST_ENTRY *Node;\r
+  UEFI_IFR_BUFFER_STORAGE_NODE *Default;\r
+\r
+  Node = GetFirstNode (ListHead);\r
+  \r
+  while (!IsNull (ListHead, Node)) {\r
+    Default = UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(Node);\r
+\r
+    RemoveEntryList (Node);\r
+   \r
+    DestroyDefaultNode (Default);\r
+    \r
+    Node = GetFirstNode (ListHead);\r
+  }\r
+\r
+  FreePool (ListHead);\r
+}\r
+\r
diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrDefault.h b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrDefault.h
new file mode 100644 (file)
index 0000000..ee54e32
--- /dev/null
@@ -0,0 +1,101 @@
+/** @file\r
+  Header file for Function and Macro defintions for to extract default values from UEFI Form package.\r
+\r
+  Copyright (c) 2008, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _HII_THUNK_UEFI_IFR_DEFAULT_\r
+#define _HII_THUNK_UEFI_IFR_DEFAULT_\r
+\r
+\r
+#define UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(a) CR(a, UEFI_IFR_BUFFER_STORAGE_NODE, List, UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE)\r
+#define UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE  EFI_SIGNATURE_32 ('I', 'b', 'S', 'n')\r
+typedef struct {\r
+  LIST_ENTRY   List;\r
+  UINT32       Signature;\r
+\r
+  EFI_GUID     Guid;\r
+  CHAR16       *Name;\r
+  UINT16       DefaultId;\r
+  UINT16       StoreId;\r
+  UINTN        Size;\r
+  UINT8        *Buffer;\r
+  \r
+} UEFI_IFR_BUFFER_STORAGE_NODE;\r
+\r
+/**\r
+  Get the default value for Buffer Type storage from the first FormSet\r
+  in the Package List specified by a EFI_HII_HANDLE.\r
+  \r
+  The results can be multiple instances of UEFI_IFR_BUFFER_STORAGE_NODE. \r
+  They are inserted to the link list.\r
+  \r
+  @param  UefiHiiHandle           The handle for the package list.\r
+  @param  UefiDefaultsListHead The head of link list for the output.\r
+\r
+  @retval   EFI_SUCCESS          Successful.\r
+  \r
+**/\r
+EFI_STATUS\r
+UefiIfrGetBufferTypeDefaults (\r
+  EFI_HII_HANDLE      UefiHiiHandle,\r
+  LIST_ENTRY          **UefiDefaults\r
+);\r
+\r
+/**\r
+  Convert the UEFI Buffer Type default values to a Framework HII default\r
+  values specified by a EFI_HII_VARIABLE_PACK_LIST structure.\r
+  \r
+  @param  ListHead                  The link list of UEFI_IFR_BUFFER_STORAGE_NODE\r
+                                              which contains the default values retrived from\r
+                                              a UEFI form set.\r
+  @param  DefaultMask            The default mask.\r
+                                             The valid values are FRAMEWORK_EFI_IFR_FLAG_DEFAULT\r
+                                             and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.\r
+                                            UEFI spec only map FRAMEWORK_EFI_IFR_FLAG_DEFAULT and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING \r
+                                            from specification to valid default class.\r
+  @param  VariablePackList     The output default value in a format defined in Framework.\r
+                                             \r
+\r
+  @retval   EFI_SUCCESS                       Successful.\r
+  @retval   EFI_INVALID_PARAMETER      The default mask is not FRAMEWORK_EFI_IFR_FLAG_DEFAULT or \r
+                                                           FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.\r
+**/\r
+\r
+EFI_STATUS\r
+UefiDefaultsToFrameworkDefaults (\r
+  IN     LIST_ENTRY                  *UefiIfrDefaults,\r
+  IN     UINTN                       DefaultMask,\r
+  OUT    EFI_HII_VARIABLE_PACK_LIST  **VariablePackList\r
+  )\r
+;\r
+\r
+/**\r
+  Free up all buffer allocated for the link list of UEFI_IFR_BUFFER_STORAGE_NODE.\r
+    \r
+  @param  ListHead                  The link list of UEFI_IFR_BUFFER_STORAGE_NODE\r
+                                              which contains the default values retrived from\r
+                                              a UEFI form set.\r
+                                             \r
+\r
+  @retval   EFI_SUCCESS                       Successful.\r
+  @retval   EFI_INVALID_PARAMETER      The default mask is not FRAMEWORK_EFI_IFR_FLAG_DEFAULT or \r
+                                                           FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.\r
+**/\r
+VOID\r
+FreeDefaultList (\r
+  IN     LIST_ENTRY                  *UefiIfrDefaults\r
+  )\r
+;\r
+\r
+#endif\r
+\r
+\r
diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParser.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParser.c
new file mode 100644 (file)
index 0000000..5074e96
--- /dev/null
@@ -0,0 +1,1641 @@
+/** @file\r
+Parser for IFR binary encoding.\r
+\r
+Copyright (c) 2008, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "UefiIfrParser.h"\r
+#include "UefiIfrParserExpression.h"\r
+#include "UefiIfrParserInternal.h"\r
+#include "UefiIfrParserCommon.h"\r
+\r
+\r
+UINT16           mStatementIndex;\r
+UINT16           mExpressionOpCodeIndex;\r
+\r
+BOOLEAN          mInScopeSubtitle;\r
+BOOLEAN          mInScopeSuppress;\r
+BOOLEAN          mInScopeGrayOut;\r
+FORM_EXPRESSION  *mSuppressExpression;\r
+FORM_EXPRESSION  *mGrayOutExpression;\r
+\r
+EFI_GUID  gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
+EFI_GUID  gTianoHiiIfrGuid = EFI_IFR_TIANO_GUID;\r
+\r
+/**\r
+  Initialize Statement header members.\r
+\r
+  @param  OpCodeData             Pointer of the raw OpCode data.\r
+  @param  FormSet                Pointer of the current FormSe.\r
+  @param  Form                   Pointer of the current Form.\r
+\r
+  @return The Statement.\r
+\r
+**/\r
+FORM_BROWSER_STATEMENT *\r
+CreateStatement (\r
+  IN UINT8                        *OpCodeData,\r
+  IN OUT FORM_BROWSER_FORMSET     *FormSet,\r
+  IN OUT FORM_BROWSER_FORM        *Form\r
+  )\r
+{\r
+  FORM_BROWSER_STATEMENT    *Statement;\r
+  EFI_IFR_STATEMENT_HEADER  *StatementHdr;\r
+\r
+  if (Form == NULL) {\r
+    //\r
+    // We are currently not in a Form Scope, so just skip this Statement\r
+    //\r
+    return NULL;\r
+  }\r
+\r
+  Statement = &FormSet->StatementBuffer[mStatementIndex];\r
+  mStatementIndex++;\r
+\r
+  InitializeListHead (&Statement->DefaultListHead);\r
+  InitializeListHead (&Statement->OptionListHead);\r
+  InitializeListHead (&Statement->InconsistentListHead);\r
+  InitializeListHead (&Statement->NoSubmitListHead);\r
+\r
+  Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;\r
+\r
+  Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
+\r
+  StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
+  CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));\r
+  CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));\r
+\r
+  if (mInScopeSuppress) {\r
+    Statement->SuppressExpression = mSuppressExpression;\r
+  }\r
+\r
+  if (mInScopeGrayOut) {\r
+    Statement->GrayOutExpression = mGrayOutExpression;\r
+  }\r
+\r
+  Statement->InSubtitle = mInScopeSubtitle;\r
+\r
+  //\r
+  // Insert this Statement into current Form\r
+  //\r
+  InsertTailList (&Form->StatementListHead, &Statement->Link);\r
+\r
+  return Statement;\r
+}\r
+\r
+\r
+/**\r
+  Initialize Question's members.\r
+\r
+  @param  OpCodeData             Pointer of the raw OpCode data.\r
+  @param  FormSet                Pointer of the current FormSet.\r
+  @param  Form                   Pointer of the current Form.\r
+\r
+  @return The Question.\r
+\r
+**/\r
+FORM_BROWSER_STATEMENT *\r
+CreateQuestion (\r
+  IN UINT8                        *OpCodeData,\r
+  IN OUT FORM_BROWSER_FORMSET     *FormSet,\r
+  IN OUT FORM_BROWSER_FORM        *Form\r
+  )\r
+{\r
+  FORM_BROWSER_STATEMENT   *Statement;\r
+  EFI_IFR_QUESTION_HEADER  *QuestionHdr;\r
+  LIST_ENTRY               *Link;\r
+  FORMSET_STORAGE          *Storage;\r
+  NAME_VALUE_NODE          *NameValueNode;\r
+\r
+  Statement = CreateStatement (OpCodeData, FormSet, Form);\r
+  if (Statement == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
+  CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));\r
+  CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
+  CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));\r
+\r
+  Statement->QuestionFlags = QuestionHdr->Flags;\r
+\r
+  if (Statement->VarStoreId == 0) {\r
+    //\r
+    // VarStoreId of zero indicates no variable storage\r
+    //\r
+    return Statement;\r
+  }\r
+\r
+  //\r
+  // Find Storage for this Question\r
+  //\r
+  Link = GetFirstNode (&FormSet->StorageListHead);\r
+  while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+    Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
+\r
+    if (Storage->VarStoreId == Statement->VarStoreId) {\r
+      Statement->Storage = Storage;\r
+      break;\r
+    }\r
+\r
+    Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+  }\r
+  ASSERT (Statement->Storage != NULL);\r
+\r
+  //\r
+  // Initialilze varname for Name/Value or EFI Variable\r
+  //\r
+  if ((Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) ||\r
+      (Statement->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
+    Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->HiiHandle);\r
+    ASSERT (Statement->VariableName != NULL);\r
+\r
+    if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+      //\r
+      // Insert to Name/Value varstore list\r
+      //\r
+      NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE));\r
+      ASSERT (NameValueNode != NULL);\r
+      NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE;\r
+      NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName);\r
+      ASSERT (NameValueNode->Name != NULL);\r
+      NameValueNode->Value = AllocateZeroPool (0x10);\r
+      ASSERT (NameValueNode->Value != NULL);\r
+      NameValueNode->EditValue = AllocateZeroPool (0x10);\r
+      ASSERT (NameValueNode->EditValue != NULL);\r
+\r
+      InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link);\r
+    }\r
+  }\r
+\r
+  return Statement;\r
+}\r
+\r
+\r
+/**\r
+  Allocate a FORM_EXPRESSION node.\r
+\r
+  @param  Form                   The Form associated with this Expression\r
+\r
+  @return Pointer to a FORM_EXPRESSION data structure.\r
+\r
+**/\r
+FORM_EXPRESSION *\r
+CreateExpression (\r
+  IN OUT FORM_BROWSER_FORM        *Form\r
+  )\r
+{\r
+  FORM_EXPRESSION  *Expression;\r
+\r
+  Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
+  Expression->Signature = FORM_EXPRESSION_SIGNATURE;\r
+  InitializeListHead (&Expression->OpCodeListHead);\r
+\r
+  return Expression;\r
+}\r
+\r
+\r
+/**\r
+  Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.\r
+\r
+  @param  FormSet                Pointer of the current FormSet\r
+\r
+  @return Pointer to a FORMSET_STORAGE data structure.\r
+\r
+**/\r
+FORMSET_STORAGE *\r
+CreateStorage (\r
+  IN FORM_BROWSER_FORMSET  *FormSet\r
+  )\r
+{\r
+  FORMSET_STORAGE  *Storage;\r
+\r
+  Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));\r
+  Storage->Signature = FORMSET_STORAGE_SIGNATURE;\r
+  InitializeListHead (&Storage->NameValueListHead);\r
+  InsertTailList (&FormSet->StorageListHead, &Storage->Link);\r
+\r
+  return Storage;\r
+}\r
+\r
+\r
+/**\r
+  Create ConfigHdr string for a storage.\r
+\r
+  @param  FormSet                Pointer of the current FormSet\r
+  @param  Storage                Pointer of the storage\r
+\r
+  @retval EFI_SUCCESS            Initialize ConfigHdr success\r
+\r
+**/\r
+EFI_STATUS\r
+InitializeConfigHdr (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN OUT FORMSET_STORAGE   *Storage\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       StrBufferLen;\r
+  CHAR16      *Name;\r
+\r
+  if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
+    Name = Storage->Name;\r
+  } else {\r
+    Name = NULL;\r
+  }\r
+\r
+  StrBufferLen = 0;\r
+  Status = ConstructConfigHdr (\r
+             Storage->ConfigHdr,\r
+             &StrBufferLen,\r
+             &Storage->Guid,\r
+             Name,\r
+             FormSet->DriverHandle\r
+             );\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    Storage->ConfigHdr = AllocateZeroPool (StrBufferLen);\r
+    Status = ConstructConfigHdr (\r
+               Storage->ConfigHdr,\r
+               &StrBufferLen,\r
+               &Storage->Guid,\r
+               Name,\r
+               FormSet->DriverHandle\r
+               );\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Storage->ConfigRequest = AllocateCopyPool (StrBufferLen, Storage->ConfigHdr);\r
+  Storage->SpareStrLen = 0;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>\r
+\r
+  @param  FormSet                Pointer of the current FormSet.\r
+  @param  Question               The Question to be initialized.\r
+\r
+  @retval EFI_SUCCESS            Function success.\r
+  @retval EFI_INVALID_PARAMETER  No storage associated with the Question.\r
+\r
+**/\r
+EFI_STATUS\r
+InitializeRequestElement (\r
+  IN OUT FORM_BROWSER_FORMSET     *FormSet,\r
+  IN OUT FORM_BROWSER_STATEMENT   *Question\r
+  )\r
+{\r
+  FORMSET_STORAGE  *Storage;\r
+  UINTN            StrLen;\r
+  UINTN            StringSize;\r
+  CHAR16           *NewStr;\r
+  CHAR16           RequestElement[30];\r
+\r
+  Storage = Question->Storage;\r
+  if (Storage == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+    //\r
+    // <ConfigRequest> is unnecessary for EFI variable storage,\r
+    // GetVariable()/SetVariable() will be used to retrieve/save values\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Prepare <RequestElement>\r
+  //\r
+  if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
+    StrLen = UnicodeSPrint (\r
+               RequestElement,\r
+               30 * sizeof (CHAR16),\r
+               L"&OFFSET=%x&WIDTH=%x",\r
+               Question->VarStoreInfo.VarOffset,\r
+               Question->StorageWidth\r
+               );\r
+    Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);\r
+  } else {\r
+    StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);\r
+  }\r
+\r
+  if ((Question->Operand == EFI_IFR_PASSWORD_OP) && (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK)) {\r
+    //\r
+    // Password with CALLBACK flag is stored in encoded format,\r
+    // so don't need to append it to <ConfigRequest>\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Append <RequestElement> to <ConfigRequest>\r
+  //\r
+  if (StrLen > Storage->SpareStrLen) {\r
+    //\r
+    // Old String buffer is not sufficient for RequestElement, allocate a new one\r
+    //\r
+    StringSize = (Storage->ConfigRequest != NULL) ? StrSize (Storage->ConfigRequest) : sizeof (CHAR16);\r
+    NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));\r
+    if (Storage->ConfigRequest != NULL) {\r
+      CopyMem (NewStr, Storage->ConfigRequest, StringSize);\r
+      gBS->FreePool (Storage->ConfigRequest);\r
+    }\r
+    Storage->ConfigRequest = NewStr;\r
+    Storage->SpareStrLen   = CONFIG_REQUEST_STRING_INCREMENTAL;\r
+  }\r
+\r
+  StrCat (Storage->ConfigRequest, RequestElement);\r
+  Storage->ElementCount++;\r
+  Storage->SpareStrLen -= StrLen;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Free resources of a Expression\r
+\r
+  @param  FormSet                Pointer of the Expression\r
+\r
+  @return None.\r
+\r
+**/\r
+VOID\r
+DestroyExpression (\r
+  IN FORM_EXPRESSION   *Expression\r
+  )\r
+{\r
+  LIST_ENTRY         *Link;\r
+  EXPRESSION_OPCODE  *OpCode;\r
+\r
+  while (!IsListEmpty (&Expression->OpCodeListHead)) {\r
+    Link = GetFirstNode (&Expression->OpCodeListHead);\r
+    OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);\r
+    RemoveEntryList (&OpCode->Link);\r
+\r
+    SafeFreePool (OpCode->ValueList);\r
+  }\r
+\r
+  //\r
+  // Free this Expression\r
+  //\r
+  gBS->FreePool (Expression);\r
+}\r
+\r
+\r
+/**\r
+  Free resources of a storage\r
+\r
+  @param  Storage                Pointer of the storage\r
+\r
+  @return None.\r
+\r
+**/\r
+VOID\r
+DestroyStorage (\r
+  IN FORMSET_STORAGE   *Storage\r
+  )\r
+{\r
+  LIST_ENTRY         *Link;\r
+  NAME_VALUE_NODE    *NameValueNode;\r
+\r
+  if (Storage == NULL) {\r
+    return;\r
+  }\r
+\r
+  SafeFreePool (Storage->Name);\r
+  SafeFreePool (Storage->Buffer);\r
+  SafeFreePool (Storage->EditBuffer);\r
+\r
+  while (!IsListEmpty (&Storage->NameValueListHead)) {\r
+    Link = GetFirstNode (&Storage->NameValueListHead);\r
+    NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link);\r
+    RemoveEntryList (&NameValueNode->Link);\r
+\r
+    SafeFreePool (NameValueNode->Name);\r
+    SafeFreePool (NameValueNode->Value);\r
+    SafeFreePool (NameValueNode->EditValue);\r
+    SafeFreePool (NameValueNode);\r
+  }\r
+\r
+  SafeFreePool (Storage->ConfigHdr);\r
+  SafeFreePool (Storage->ConfigRequest);\r
+\r
+  gBS->FreePool (Storage);\r
+}\r
+\r
+\r
+/**\r
+  Free resources of a Statement\r
+\r
+  @param  Statement              Pointer of the Statement\r
+\r
+  @return None.\r
+\r
+**/\r
+VOID\r
+DestroyStatement (\r
+  IN OUT FORM_BROWSER_STATEMENT  *Statement\r
+  )\r
+{\r
+  LIST_ENTRY        *Link;\r
+  QUESTION_DEFAULT  *Default;\r
+  QUESTION_OPTION   *Option;\r
+  FORM_EXPRESSION   *Expression;\r
+\r
+  //\r
+  // Free Default value List\r
+  //\r
+  while (!IsListEmpty (&Statement->DefaultListHead)) {\r
+    Link = GetFirstNode (&Statement->DefaultListHead);\r
+    Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
+    RemoveEntryList (&Default->Link);\r
+\r
+    gBS->FreePool (Default);\r
+  }\r
+\r
+  //\r
+  // Free Options List\r
+  //\r
+  while (!IsListEmpty (&Statement->OptionListHead)) {\r
+    Link = GetFirstNode (&Statement->OptionListHead);\r
+    Option = QUESTION_OPTION_FROM_LINK (Link);\r
+    RemoveEntryList (&Option->Link);\r
+\r
+    gBS->FreePool (Option);\r
+  }\r
+\r
+  //\r
+  // Free Inconsistent List\r
+  //\r
+  while (!IsListEmpty (&Statement->InconsistentListHead)) {\r
+    Link = GetFirstNode (&Statement->InconsistentListHead);\r
+    Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
+    RemoveEntryList (&Expression->Link);\r
+\r
+    DestroyExpression (Expression);\r
+  }\r
+\r
+  //\r
+  // Free NoSubmit List\r
+  //\r
+  while (!IsListEmpty (&Statement->NoSubmitListHead)) {\r
+    Link = GetFirstNode (&Statement->NoSubmitListHead);\r
+    Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
+    RemoveEntryList (&Expression->Link);\r
+\r
+    DestroyExpression (Expression);\r
+  }\r
+\r
+  SafeFreePool (Statement->VariableName);\r
+  SafeFreePool (Statement->BlockName);\r
+}\r
+\r
+\r
+/**\r
+  Free resources of a Form\r
+\r
+  @param  Form                   Pointer of the Form\r
+\r
+  @return None.\r
+\r
+**/\r
+VOID\r
+DestroyForm (\r
+  IN OUT FORM_BROWSER_FORM  *Form\r
+  )\r
+{\r
+  LIST_ENTRY              *Link;\r
+  FORM_EXPRESSION         *Expression;\r
+  FORM_BROWSER_STATEMENT  *Statement;\r
+\r
+  //\r
+  // Free Form Expressions\r
+  //\r
+  while (!IsListEmpty (&Form->ExpressionListHead)) {\r
+    Link = GetFirstNode (&Form->ExpressionListHead);\r
+    Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
+    RemoveEntryList (&Expression->Link);\r
+\r
+    DestroyExpression (Expression);\r
+  }\r
+\r
+  //\r
+  // Free Statements/Questions\r
+  //\r
+  while (!IsListEmpty (&Form->StatementListHead)) {\r
+    Link = GetFirstNode (&Form->StatementListHead);\r
+    Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+    RemoveEntryList (&Statement->Link);\r
+\r
+    DestroyStatement (Statement);\r
+  }\r
+\r
+  //\r
+  // Free this Form\r
+  //\r
+  gBS->FreePool (Form);\r
+}\r
+\r
+\r
+/**\r
+  Free resources allocated for a FormSet\r
+\r
+  @param  FormSet                Pointer of the FormSet\r
+\r
+  @return None.\r
+\r
+**/\r
+VOID\r
+DestroyFormSet (\r
+  IN OUT FORM_BROWSER_FORMSET  *FormSet\r
+  )\r
+{\r
+  LIST_ENTRY            *Link;\r
+  FORMSET_STORAGE       *Storage;\r
+  FORMSET_DEFAULTSTORE  *DefaultStore;\r
+  FORM_BROWSER_FORM     *Form;\r
+\r
+  //\r
+  // Free IFR binary buffer\r
+  //\r
+  SafeFreePool (FormSet->IfrBinaryData);\r
+\r
+  //\r
+  // Free FormSet Storage\r
+  //\r
+  if (FormSet->StorageListHead.ForwardLink != NULL) {\r
+    while (!IsListEmpty (&FormSet->StorageListHead)) {\r
+      Link = GetFirstNode (&FormSet->StorageListHead);\r
+      Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
+      RemoveEntryList (&Storage->Link);\r
+\r
+      DestroyStorage (Storage);\r
+    }\r
+  }\r
+\r
+  //\r
+  // Free FormSet Default Store\r
+  //\r
+  if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {\r
+    while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {\r
+      Link = GetFirstNode (&FormSet->DefaultStoreListHead);\r
+      DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);\r
+      RemoveEntryList (&DefaultStore->Link);\r
+\r
+      gBS->FreePool (DefaultStore);\r
+    }\r
+  }\r
+\r
+  //\r
+  // Free Forms\r
+  //\r
+  if (FormSet->FormListHead.ForwardLink != NULL) {\r
+    while (!IsListEmpty (&FormSet->FormListHead)) {\r
+      Link = GetFirstNode (&FormSet->FormListHead);\r
+      Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+      RemoveEntryList (&Form->Link);\r
+\r
+      DestroyForm (Form);\r
+    }\r
+  }\r
+\r
+  SafeFreePool (FormSet->StatementBuffer);\r
+  SafeFreePool (FormSet->ExpressionBuffer);\r
+\r
+  SafeFreePool (FormSet);\r
+}\r
+\r
+\r
+/**\r
+  Tell whether this Operand is an Expression OpCode or not\r
+\r
+  @param  Operand                Operand of an IFR OpCode.\r
+\r
+  @retval TRUE                   This is an Expression OpCode.\r
+  @retval FALSE                  Not an Expression OpCode.\r
+\r
+**/\r
+BOOLEAN\r
+IsExpressionOpCode (\r
+  IN UINT8              Operand\r
+  )\r
+{\r
+  if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||\r
+      ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||\r
+      (Operand == EFI_IFR_CATENATE_OP)\r
+     ) {\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Calculate number of Statemens(Questions) and Expression OpCodes.\r
+\r
+  @param  FormSet                The FormSet to be counted.\r
+  @param  NumberOfStatement      Number of Statemens(Questions)\r
+  @param  NumberOfExpression     Number of Expression OpCodes\r
+\r
+  @return None.\r
+\r
+**/\r
+VOID\r
+CountOpCodes (\r
+  IN  FORM_BROWSER_FORMSET  *FormSet,\r
+  IN OUT  UINT16            *NumberOfStatement,\r
+  IN OUT  UINT16            *NumberOfExpression\r
+  )\r
+{\r
+  UINT16  StatementCount;\r
+  UINT16  ExpressionCount;\r
+  UINT8   *OpCodeData;\r
+  UINTN   Offset;\r
+  UINTN   OpCodeLen;\r
+\r
+  Offset = 0;\r
+  StatementCount = 0;\r
+  ExpressionCount = 0;\r
+\r
+  while (Offset < FormSet->IfrBinaryLength) {\r
+    OpCodeData = FormSet->IfrBinaryData + Offset;\r
+    OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
+    Offset += OpCodeLen;\r
+\r
+    if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {\r
+      ExpressionCount++;\r
+    } else {\r
+      StatementCount++;\r
+    }\r
+  }\r
+\r
+  *NumberOfStatement = StatementCount;\r
+  *NumberOfExpression = ExpressionCount;\r
+}\r
+\r
+\r
+/**\r
+  Parse opcodes in the formset IFR binary.\r
+\r
+  @param  FormSet                Pointer of the FormSet data structure.\r
+\r
+  @retval EFI_SUCCESS            Opcode parse success.\r
+  @retval Other                  Opcode parse fail.\r
+\r
+**/\r
+EFI_STATUS\r
+ParseOpCodes (\r
+  IN FORM_BROWSER_FORMSET              *FormSet\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  UINT16                  Index;\r
+  FORM_BROWSER_FORM       *CurrentForm;\r
+  FORM_BROWSER_STATEMENT  *CurrentStatement;\r
+  EXPRESSION_OPCODE       *ExpressionOpCode;\r
+  FORM_EXPRESSION         *CurrentExpression;\r
+  UINT8                   Operand;\r
+  UINT8                   Scope;\r
+  UINTN                   OpCodeOffset;\r
+  UINTN                   OpCodeLength;\r
+  UINT8                   *OpCodeData;\r
+  UINT8                   ScopeOpCode;\r
+  FORMSET_STORAGE         *Storage;\r
+  FORMSET_DEFAULTSTORE    *DefaultStore;\r
+  QUESTION_DEFAULT        *CurrentDefault;\r
+  QUESTION_OPTION         *CurrentOption;\r
+  CHAR8                   *AsciiString;\r
+  UINT16                  NumberOfStatement;\r
+  UINT16                  NumberOfExpression;\r
+  EFI_IMAGE_ID            *ImageId;\r
+  BOOLEAN                 SuppressForOption;\r
+  BOOLEAN                 InScopeOptionSuppress;\r
+  FORM_EXPRESSION         *OptionSuppressExpression;\r
+  BOOLEAN                 InScopeDisable;\r
+  UINT16                  DepthOfDisable;\r
+  BOOLEAN                 OpCodeDisabled;\r
+  BOOLEAN                 SingleOpCodeExpression;\r
+  BOOLEAN                 InScopeDefault;\r
+  EFI_HII_VALUE           *Value;\r
+\r
+  mInScopeSubtitle         = FALSE;\r
+  SuppressForOption        = FALSE;\r
+  mInScopeSuppress         = FALSE;\r
+  InScopeOptionSuppress    = FALSE;\r
+  mInScopeGrayOut          = FALSE;\r
+  InScopeDisable           = FALSE;\r
+  DepthOfDisable           = 0;\r
+  OpCodeDisabled           = FALSE;\r
+  SingleOpCodeExpression   = FALSE;\r
+  InScopeDefault           = FALSE;\r
+  CurrentExpression        = NULL;\r
+  CurrentDefault           = NULL;\r
+  CurrentOption            = NULL;\r
+  OptionSuppressExpression = NULL;\r
+\r
+  //\r
+  // Get the number of Statements and Expressions\r
+  //\r
+  CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);\r
+\r
+  mStatementIndex = 0;\r
+  FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));\r
+  if (FormSet->StatementBuffer == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  mExpressionOpCodeIndex = 0;\r
+  FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));\r
+  if (FormSet->ExpressionBuffer == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  InitializeListHead (&FormSet->StorageListHead);\r
+  InitializeListHead (&FormSet->DefaultStoreListHead);\r
+  InitializeListHead (&FormSet->FormListHead);\r
+\r
+  CurrentForm = NULL;\r
+  CurrentStatement = NULL;\r
+\r
+  ResetScopeStack ();\r
+\r
+  OpCodeOffset = 0;\r
+  while (OpCodeOffset < FormSet->IfrBinaryLength) {\r
+    OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;\r
+\r
+    OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
+    OpCodeOffset += OpCodeLength;\r
+    Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
+    Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;\r
+\r
+    //\r
+    // If scope bit set, push onto scope stack\r
+    //\r
+    if (Scope) {\r
+      PushScope (Operand);\r
+    }\r
+\r
+    if (OpCodeDisabled) {\r
+      //\r
+      // DisableIf Expression is evaluated to be TRUE, try to find its end.\r
+      // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END\r
+      //\r
+      if (Operand == EFI_IFR_DISABLE_IF_OP) {\r
+        DepthOfDisable++;\r
+      } else if (Operand == EFI_IFR_END_OP) {\r
+        Status = PopScope (&ScopeOpCode);\r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
+        }\r
+\r
+        if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {\r
+          if (DepthOfDisable == 0) {\r
+            InScopeDisable = FALSE;\r
+            OpCodeDisabled = FALSE;\r
+          } else {\r
+            DepthOfDisable--;\r
+          }\r
+        }\r
+      }\r
+      continue;\r
+    }\r
+\r
+    if (IsExpressionOpCode (Operand)) {\r
+      ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];\r
+      mExpressionOpCodeIndex++;\r
+\r
+      ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;\r
+      ExpressionOpCode->Operand = Operand;\r
+      Value = &ExpressionOpCode->Value;\r
+\r
+      switch (Operand) {\r
+      case EFI_IFR_EQ_ID_VAL_OP:\r
+        CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
+\r
+        Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
+        CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));\r
+        break;\r
+\r
+      case EFI_IFR_EQ_ID_ID_OP:\r
+        CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));\r
+        CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));\r
+        break;\r
+\r
+      case EFI_IFR_EQ_ID_LIST_OP:\r
+        CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
+        CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->ListLength, sizeof (UINT16));\r
+        ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->ValueList);\r
+        break;\r
+\r
+      case EFI_IFR_TO_STRING_OP:\r
+      case EFI_IFR_FIND_OP:\r
+        ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;\r
+        break;\r
+\r
+      case EFI_IFR_STRING_REF1_OP:\r
+        Value->Type = EFI_IFR_TYPE_STRING;\r
+        CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));\r
+        break;\r
+\r
+      case EFI_IFR_RULE_REF_OP:\r
+        ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;\r
+        break;\r
+\r
+      case EFI_IFR_SPAN_OP:\r
+        ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;\r
+        break;\r
+\r
+      case EFI_IFR_THIS_OP:\r
+        ExpressionOpCode->QuestionId = CurrentStatement->QuestionId;\r
+        break;\r
+\r
+      case EFI_IFR_QUESTION_REF1_OP:\r
+        CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
+        break;\r
+\r
+      case EFI_IFR_QUESTION_REF3_OP:\r
+        if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {\r
+          CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
+\r
+          if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {\r
+            CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
+          }\r
+        }\r
+        break;\r
+\r
+      //\r
+      // constant\r
+      //\r
+      case EFI_IFR_TRUE_OP:\r
+        Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
+        Value->Value.b = TRUE;\r
+        break;\r
+\r
+      case EFI_IFR_FALSE_OP:\r
+        Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
+        Value->Value.b = FALSE;\r
+        break;\r
+\r
+      case EFI_IFR_ONE_OP:\r
+        Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+        Value->Value.u8 = 1;\r
+        break;\r
+\r
+      case EFI_IFR_ZERO_OP:\r
+        Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+        Value->Value.u8 = 0;\r
+        break;\r
+\r
+      case EFI_IFR_ONES_OP:\r
+        Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+        Value->Value.u64 = 0xffffffffffffffffULL;\r
+        break;\r
+\r
+      case EFI_IFR_UINT8_OP:\r
+        Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+        Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;\r
+        break;\r
+\r
+      case EFI_IFR_UINT16_OP:\r
+        Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
+        CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));\r
+        break;\r
+\r
+      case EFI_IFR_UINT32_OP:\r
+        Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
+        CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));\r
+        break;\r
+\r
+      case EFI_IFR_UINT64_OP:\r
+        Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+        CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));\r
+        break;\r
+\r
+      case EFI_IFR_UNDEFINED_OP:\r
+        Value->Type = EFI_IFR_TYPE_OTHER;\r
+        break;\r
+\r
+      case EFI_IFR_VERSION_OP:\r
+        Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
+        Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;\r
+        break;\r
+\r
+      default:\r
+        break;\r
+      }\r
+\r
+      InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);\r
+\r
+      if (SingleOpCodeExpression) {\r
+        //\r
+        // There are two cases to indicate the end of an Expression:\r
+        // for single OpCode expression: one Expression OpCode\r
+        // for expression consists of more than one OpCode: EFI_IFR_END\r
+        //\r
+        SingleOpCodeExpression = FALSE;\r
+\r
+        if (InScopeDisable) {\r
+          //\r
+          // Evaluate DisableIf expression\r
+          //\r
+          Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
+          if (EFI_ERROR (Status)) {\r
+            return Status;\r
+          }\r
+          if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
+            return EFI_INVALID_PARAMETER;\r
+          }\r
+\r
+          OpCodeDisabled = CurrentExpression->Result.Value.b;\r
+        }\r
+\r
+        CurrentExpression = NULL;\r
+      }\r
+\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Parse the Opcode\r
+    //\r
+    switch (Operand) {\r
+\r
+    case EFI_IFR_FORM_SET_OP:\r
+      //\r
+      // check the formset GUID\r
+      //\r
+      if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
+      CopyMem (&FormSet->Help,         &((EFI_IFR_FORM_SET *) OpCodeData)->Help,         sizeof (EFI_STRING_ID));\r
+      break;\r
+\r
+    case EFI_IFR_FORM_OP:\r
+      //\r
+      // Create a new Form for this FormSet\r
+      //\r
+      CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
+      CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
+      InitializeListHead (&CurrentForm->ExpressionListHead);\r
+      InitializeListHead (&CurrentForm->StatementListHead);\r
+\r
+      CopyMem (&CurrentForm->FormId,    &((EFI_IFR_FORM *) OpCodeData)->FormId,    sizeof (UINT16));\r
+      CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r
+\r
+      //\r
+      // Insert into Form list of this FormSet\r
+      //\r
+      InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
+      break;\r
+\r
+    //\r
+    // Storage\r
+    //\r
+    case EFI_IFR_VARSTORE_OP:\r
+      //\r
+      // Create a buffer Storage for this FormSet\r
+      //\r
+      Storage = CreateStorage (FormSet);\r
+      Storage->Type = EFI_HII_VARSTORE_BUFFER;\r
+\r
+      CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
+      CopyMem (&Storage->Guid,       &((EFI_IFR_VARSTORE *) OpCodeData)->Guid,       sizeof (EFI_GUID));\r
+      CopyMem (&Storage->Size,       &((EFI_IFR_VARSTORE *) OpCodeData)->Size,       sizeof (UINT16));\r
+\r
+      Storage->Buffer = AllocateZeroPool (Storage->Size);\r
+      Storage->EditBuffer = AllocateZeroPool (Storage->Size);\r
+\r
+      AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;\r
+      Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);\r
+      ASSERT (Storage->Name != NULL);\r
+      for (Index = 0; AsciiString[Index] != 0; Index++) {\r
+        Storage->Name[Index] = (CHAR16) AsciiString[Index];\r
+      }\r
+\r
+      //\r
+      // Initialize <ConfigHdr>\r
+      //\r
+      InitializeConfigHdr (FormSet, Storage);\r
+      break;\r
+\r
+    case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
+      //\r
+      // Create a name/value Storage for this FormSet\r
+      //\r
+      Storage = CreateStorage (FormSet);\r
+      Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;\r
+\r
+      CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
+      CopyMem (&Storage->Guid,       &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid,       sizeof (EFI_GUID));\r
+\r
+      //\r
+      // Initialize <ConfigHdr>\r
+      //\r
+      InitializeConfigHdr (FormSet, Storage);\r
+      break;\r
+\r
+    case EFI_IFR_VARSTORE_EFI_OP:\r
+      //\r
+      // Create a EFI variable Storage for this FormSet\r
+      //\r
+      Storage = CreateStorage (FormSet);\r
+      Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;\r
+\r
+      CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
+      CopyMem (&Storage->Guid,       &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid,       sizeof (EFI_GUID));\r
+      CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));\r
+      break;\r
+\r
+    //\r
+    // DefaultStore\r
+    //\r
+    case EFI_IFR_DEFAULTSTORE_OP:\r
+      DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));\r
+      DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;\r
+\r
+      CopyMem (&DefaultStore->DefaultId,   &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId,   sizeof (UINT16));\r
+      CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));\r
+\r
+      //\r
+      // Insert to DefaultStore list of this Formset\r
+      //\r
+      InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
+      break;\r
+\r
+    //\r
+    // Statements\r
+    //\r
+    case EFI_IFR_SUBTITLE_OP:\r
+      CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
+      CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
+\r
+      if (Scope) {\r
+        mInScopeSubtitle = TRUE;\r
+      }\r
+      break;\r
+\r
+    case EFI_IFR_TEXT_OP:\r
+      CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
+\r
+      CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r
+      break;\r
+\r
+    //\r
+    // Questions\r
+    //\r
+    case EFI_IFR_ACTION_OP:\r
+      CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\r
+      if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {\r
+        //\r
+        // No QuestionConfig present, so no configuration string will be processed\r
+        //\r
+        CurrentStatement->QuestionConfig = 0;\r
+      } else {\r
+        CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));\r
+      }\r
+      break;\r
+\r
+    case EFI_IFR_RESET_BUTTON_OP:\r
+      CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\r
+      CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
+      break;\r
+\r
+    case EFI_IFR_REF_OP:\r
+      CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\r
+      CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r
+      if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r
+        CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
+\r
+        if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {\r
+          CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));\r
+\r
+          if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {\r
+            CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
+          }\r
+        }\r
+      }\r
+      break;\r
+\r
+    case EFI_IFR_ONE_OF_OP:\r
+    case EFI_IFR_NUMERIC_OP:\r
+      CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\r
+      CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r
+      Value = &CurrentStatement->HiiValue;\r
+\r
+      switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {\r
+      case EFI_IFR_NUMERIC_SIZE_1:\r
+        CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r
+        CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r
+        CurrentStatement->Step    = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r
+        CurrentStatement->StorageWidth = sizeof (UINT8);\r
+        Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+        break;\r
+\r
+      case EFI_IFR_NUMERIC_SIZE_2:\r
+        CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r
+        CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r
+        CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step,     sizeof (UINT16));\r
+        CurrentStatement->StorageWidth = sizeof (UINT16);\r
+        Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
+        break;\r
+\r
+      case EFI_IFR_NUMERIC_SIZE_4:\r
+        CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r
+        CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r
+        CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step,     sizeof (UINT32));\r
+        CurrentStatement->StorageWidth = sizeof (UINT32);\r
+        Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
+        break;\r
+\r
+      case EFI_IFR_NUMERIC_SIZE_8:\r
+        CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r
+        CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r
+        CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step,     sizeof (UINT64));\r
+        CurrentStatement->StorageWidth = sizeof (UINT64);\r
+        Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+        break;\r
+\r
+      default:\r
+        break;\r
+      }\r
+\r
+      InitializeRequestElement (FormSet, CurrentStatement);\r
+\r
+      if ((Operand == EFI_IFR_ONE_OF_OP) && Scope) {\r
+        SuppressForOption = TRUE;\r
+      }\r
+      break;\r
+\r
+    case EFI_IFR_ORDERED_LIST_OP:\r
+      CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\r
+      CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;\r
+      CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;\r
+      CurrentStatement->StorageWidth = (UINT16)(CurrentStatement->MaxContainers * sizeof (UINT8));\r
+      InitializeRequestElement (FormSet, CurrentStatement);\r
+\r
+      //\r
+      // No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver\r
+      // has to use FormBrowser2.Callback() to retrieve the uncommited data for\r
+      // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set).\r
+      //\r
+      CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_OTHER;\r
+      CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
+\r
+      if (Scope) {\r
+        SuppressForOption = TRUE;\r
+      }\r
+      break;\r
+\r
+    case EFI_IFR_CHECKBOX_OP:\r
+      CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\r
+      CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;\r
+      CurrentStatement->StorageWidth = sizeof (BOOLEAN);\r
+      CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r
+\r
+      InitializeRequestElement (FormSet, CurrentStatement);\r
+      break;\r
+\r
+    case EFI_IFR_STRING_OP:\r
+      CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\r
+      //\r
+      // MinSize is the minimum number of characters that can be accepted for this opcode,\r
+      // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
+      // The characters are stored as Unicode, so the storage width should multiply 2.\r
+      //\r
+      CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;\r
+      CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;\r
+      CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16));\r
+      CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;\r
+\r
+      CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
+      CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
+\r
+      InitializeRequestElement (FormSet, CurrentStatement);\r
+      break;\r
+\r
+    case EFI_IFR_PASSWORD_OP:\r
+      CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\r
+      //\r
+      // MinSize is the minimum number of characters that can be accepted for this opcode,\r
+      // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
+      // The characters are stored as Unicode, so the storage width should multiply 2.\r
+      //\r
+      CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));\r
+      CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));\r
+      CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16));\r
+\r
+      CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
+      CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
+\r
+      InitializeRequestElement (FormSet, CurrentStatement);\r
+      break;\r
+\r
+    case EFI_IFR_DATE_OP:\r
+      CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\r
+      CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;\r
+      CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;\r
+\r
+      if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {\r
+        CurrentStatement->StorageWidth = sizeof (EFI_HII_DATE);\r
+\r
+        InitializeRequestElement (FormSet, CurrentStatement);\r
+      } else {\r
+        //\r
+        // Don't assign storage for RTC type of date/time\r
+        //\r
+        CurrentStatement->Storage = NULL;\r
+        CurrentStatement->StorageWidth = 0;\r
+      }\r
+      break;\r
+\r
+    case EFI_IFR_TIME_OP:\r
+      CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+\r
+      CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;\r
+      CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;\r
+\r
+      if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {\r
+        CurrentStatement->StorageWidth = sizeof (EFI_IFR_TIME);\r
+\r
+        InitializeRequestElement (FormSet, CurrentStatement);\r
+      } else {\r
+        //\r
+        // Don't assign storage for RTC type of date/time\r
+        //\r
+        CurrentStatement->Storage = NULL;\r
+        CurrentStatement->StorageWidth = 0;\r
+      }\r
+      break;\r
+\r
+    //\r
+    // Default\r
+    //\r
+    case EFI_IFR_DEFAULT_OP:\r
+      //\r
+      // EFI_IFR_DEFAULT appear in scope of a Question,\r
+      // It creates a default value for the current question.\r
+      // A Question may have more than one Default value which have different default types.\r
+      //\r
+      CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
+      CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
+\r
+      CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;\r
+      CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));\r
+      CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
+      ExtendValueToU64 (&CurrentDefault->Value);\r
+\r
+      //\r
+      // Insert to Default Value list of current Question\r
+      //\r
+      InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);\r
+\r
+      if (Scope) {\r
+        InScopeDefault = TRUE;\r
+      }\r
+      break;\r
+\r
+    //\r
+    // Option\r
+    //\r
+    case EFI_IFR_ONE_OF_OPTION_OP:\r
+      //\r
+      // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.\r
+      // It create a selection for use in current Question.\r
+      //\r
+      CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));\r
+      CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;\r
+\r
+      CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;\r
+      CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;\r
+      CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));\r
+      CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
+      ExtendValueToU64 (&CurrentOption->Value);\r
+\r
+      if (InScopeOptionSuppress) {\r
+        CurrentOption->SuppressExpression = OptionSuppressExpression;\r
+      }\r
+\r
+      //\r
+      // Insert to Option list of current Question\r
+      //\r
+      InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);\r
+      break;\r
+\r
+    //\r
+    // Conditional\r
+    //\r
+    case EFI_IFR_NO_SUBMIT_IF_OP:\r
+    case EFI_IFR_INCONSISTENT_IF_OP:\r
+      //\r
+      // Create an Expression node\r
+      //\r
+      CurrentExpression = CreateExpression (CurrentForm);\r
+      CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));\r
+\r
+      if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {\r
+        CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;\r
+        InsertTailList (&CurrentStatement->NoSubmitListHead, &CurrentExpression->Link);\r
+      } else {\r
+        CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;\r
+        InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);\r
+      }\r
+      break;\r
+\r
+    case EFI_IFR_SUPPRESS_IF_OP:\r
+      //\r
+      // Question and Option will appear in scope of this OpCode\r
+      //\r
+      CurrentExpression = CreateExpression (CurrentForm);\r
+      CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;\r
+      InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
+\r
+      if (SuppressForOption) {\r
+        InScopeOptionSuppress = TRUE;\r
+        OptionSuppressExpression = CurrentExpression;\r
+      } else {\r
+        mInScopeSuppress = TRUE;\r
+        mSuppressExpression = CurrentExpression;\r
+      }\r
+      break;\r
+\r
+    case EFI_IFR_GRAY_OUT_IF_OP:\r
+      //\r
+      // Questions will appear in scope of this OpCode\r
+      //\r
+      CurrentExpression = CreateExpression (CurrentForm);\r
+      CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;\r
+      InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
+\r
+      mInScopeGrayOut = TRUE;\r
+      mGrayOutExpression = CurrentExpression;\r
+      break;\r
+\r
+    case EFI_IFR_DISABLE_IF_OP:\r
+      //\r
+      // The DisableIf expression should only rely on constant, so it could be\r
+      // evaluated at initialization and it will not be queued\r
+      //\r
+      CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
+      CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;\r
+      CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;\r
+      InitializeListHead (&CurrentExpression->OpCodeListHead);\r
+\r
+      InScopeDisable = TRUE;\r
+      OpCodeDisabled = FALSE;\r
+\r
+      //\r
+      // Take a look at next OpCode to see whether current expression consists\r
+      // of single OpCode\r
+      //\r
+      if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
+        SingleOpCodeExpression = TRUE;\r
+      }\r
+      break;\r
+\r
+    //\r
+    // Expression\r
+    //\r
+    case EFI_IFR_VALUE_OP:\r
+      CurrentExpression = CreateExpression (CurrentForm);\r
+      CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;\r
+      InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
+\r
+      if (InScopeDefault) {\r
+        //\r
+        // Used for default (EFI_IFR_DEFAULT)\r
+        //\r
+        CurrentDefault->ValueExpression = CurrentExpression;\r
+      } else {\r
+        //\r
+        // If used for a question, then the question will be read-only\r
+        //\r
+        CurrentStatement->ValueExpression = CurrentExpression;\r
+      }\r
+      break;\r
+\r
+    case EFI_IFR_RULE_OP:\r
+      CurrentExpression = CreateExpression (CurrentForm);\r
+      CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;\r
+\r
+      CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;\r
+      InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
+      break;\r
+\r
+    //\r
+    // Image\r
+    //\r
+    case EFI_IFR_IMAGE_OP:\r
+      //\r
+      // Get ScopeOpcode from top of stack\r
+      //\r
+      PopScope (&ScopeOpCode);\r
+      PushScope (ScopeOpCode);\r
+\r
+      switch (ScopeOpCode) {\r
+      case EFI_IFR_FORM_SET_OP:\r
+        ImageId = &FormSet->ImageId;\r
+        break;\r
+\r
+      case EFI_IFR_FORM_OP:\r
+        ImageId = &CurrentForm->ImageId;\r
+        break;\r
+\r
+      case EFI_IFR_ONE_OF_OPTION_OP:\r
+        ImageId = &CurrentOption->ImageId;\r
+        break;\r
+\r
+      default:\r
+        ImageId = &CurrentStatement->ImageId;\r
+        break;\r
+      }\r
+\r
+      CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));\r
+      break;\r
+\r
+    //\r
+    // Refresh\r
+    //\r
+    case EFI_IFR_REFRESH_OP:\r
+      CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;\r
+      break;\r
+\r
+    //\r
+    // Vendor specific\r
+    //\r
+    case EFI_IFR_GUID_OP:\r
+      if (CompareGuid (&gTianoHiiIfrGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
+        //\r
+        // Tiano specific GUIDed opcodes\r
+        //\r
+        switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {\r
+        case EFI_IFR_EXTEND_OP_LABEL:\r
+          //\r
+          // just ignore label\r
+          //\r
+          break;\r
+\r
+#if 0\r
+        case EFI_IFR_EXTEND_OP_BANNER:\r
+          if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {\r
+            CopyMem (\r
+              &BannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][\r
+              ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],\r
+              &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,\r
+              sizeof (EFI_STRING_ID)\r
+              );\r
+          }\r
+          break;\r
+#endif\r
+\r
+        case EFI_IFR_EXTEND_OP_CLASS:\r
+          CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));\r
+          break;\r
+\r
+        case EFI_IFR_EXTEND_OP_SUBCLASS:\r
+          CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));\r
+          break;\r
+\r
+        default:\r
+          break;\r
+        }\r
+      }\r
+      break;\r
+\r
+    //\r
+    // Scope End\r
+    //\r
+    case EFI_IFR_END_OP:\r
+      Status = PopScope (&ScopeOpCode);\r
+      if (EFI_ERROR (Status)) {\r
+        ResetScopeStack ();\r
+        return Status;\r
+      }\r
+\r
+      switch (ScopeOpCode) {\r
+      case EFI_IFR_FORM_SET_OP:\r
+        //\r
+        // End of FormSet, update FormSet IFR binary length\r
+        // to stop parsing substantial OpCodes\r
+        //\r
+        FormSet->IfrBinaryLength = OpCodeOffset;\r
+        break;\r
+\r
+      case EFI_IFR_FORM_OP:\r
+        //\r
+        // End of Form\r
+        //\r
+        CurrentForm = NULL;\r
+        break;\r
+\r
+      case EFI_IFR_ONE_OF_OPTION_OP:\r
+        //\r
+        // End of Option\r
+        //\r
+        CurrentOption = NULL;\r
+        break;\r
+\r
+      case EFI_IFR_SUBTITLE_OP:\r
+        mInScopeSubtitle = FALSE;\r
+        break;\r
+\r
+      case EFI_IFR_NO_SUBMIT_IF_OP:\r
+      case EFI_IFR_INCONSISTENT_IF_OP:\r
+        //\r
+        // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF\r
+        //\r
+        break;\r
+\r
+      case EFI_IFR_SUPPRESS_IF_OP:\r
+        if (SuppressForOption) {\r
+          InScopeOptionSuppress = FALSE;\r
+        } else {\r
+          mInScopeSuppress = FALSE;\r
+        }\r
+        break;\r
+\r
+      case EFI_IFR_GRAY_OUT_IF_OP:\r
+        mInScopeGrayOut = FALSE;\r
+        break;\r
+\r
+      case EFI_IFR_DISABLE_IF_OP:\r
+        InScopeDisable = FALSE;\r
+        OpCodeDisabled = FALSE;\r
+        break;\r
+\r
+      case EFI_IFR_ONE_OF_OP:\r
+      case EFI_IFR_ORDERED_LIST_OP:\r
+        SuppressForOption = FALSE;\r
+        break;\r
+\r
+      case EFI_IFR_DEFAULT_OP:\r
+        InScopeDefault = FALSE;\r
+        break;\r
+\r
+      default:\r
+        if (IsExpressionOpCode (ScopeOpCode)) {\r
+          if (InScopeDisable) {\r
+            //\r
+            // Evaluate DisableIf expression\r
+            //\r
+            Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
+            if (EFI_ERROR (Status)) {\r
+              return Status;\r
+            }\r
+            if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
+              return EFI_INVALID_PARAMETER;\r
+            }\r
+\r
+            OpCodeDisabled = CurrentExpression->Result.Value.b;\r
+            //\r
+            // DisableIf Expression is only used once and not quequed, free it\r
+            //\r
+            DestroyExpression (CurrentExpression);\r
+          }\r
+\r
+          //\r
+          // End of current Expression\r
+          //\r
+          CurrentExpression = NULL;\r
+        }\r
+        break;\r
+      }\r
+      break;\r
+\r
+    default:\r
+      break;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+\r
diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParser.h b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParser.h
new file mode 100644 (file)
index 0000000..7a811b1
--- /dev/null
@@ -0,0 +1,316 @@
+/** @file\r
+  Function and Macro defintions for IFR parsing. To get the default value from IFR package, the IFR\r
+  opcode needs to be parsed. Most of code is taken from MdeModulePkg\Universal\SetupBrowserDxe\IfrParse.c.\r
+\r
+  Copyright (c) 2008, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _HII_THUNK_UEFI_IFR_PARSER_\r
+#define _HII_THUNK_UEFI_IFR_PARSER_\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/Print.h>\r
+//#include <Protocol/SimpleTextOut.h>\r
+//#include <Protocol/SimpleTextIn.h>\r
+//#include <Protocol/FormBrowser2.h>\r
+//#include <Protocol/DevicePath.h>\r
+#include <Protocol/HiiConfigAccess.h>\r
+#include <Protocol/HiiConfigRouting.h>\r
+#include <Protocol/HiiDatabase.h>\r
+#include <Protocol/HiiString.h>\r
+\r
+//\r
+// IFR relative definition\r
+//\r
+#define EFI_HII_EXPRESSION_INCONSISTENT_IF   0\r
+#define EFI_HII_EXPRESSION_NO_SUBMIT_IF      1\r
+#define EFI_HII_EXPRESSION_GRAY_OUT_IF       2\r
+#define EFI_HII_EXPRESSION_SUPPRESS_IF       3\r
+#define EFI_HII_EXPRESSION_DISABLE_IF        4\r
+#define EFI_HII_EXPRESSION_VALUE             5\r
+#define EFI_HII_EXPRESSION_RULE              6\r
+\r
+#define EFI_HII_VARSTORE_BUFFER              0\r
+#define EFI_HII_VARSTORE_NAME_VALUE          1\r
+#define EFI_HII_VARSTORE_EFI_VARIABLE        2\r
+\r
+#define FORM_INCONSISTENT_VALIDATION         0\r
+#define FORM_NO_SUBMIT_VALIDATION            1\r
+\r
+\r
+typedef struct {\r
+  UINT8               Type;\r
+  EFI_IFR_TYPE_VALUE  Value;\r
+} EFI_HII_VALUE;\r
+\r
+#define NAME_VALUE_NODE_SIGNATURE  EFI_SIGNATURE_32 ('N', 'V', 'S', 'T')\r
+\r
+typedef struct {\r
+  UINTN            Signature;\r
+  LIST_ENTRY       Link;\r
+  CHAR16           *Name;\r
+  CHAR16           *Value;\r
+  CHAR16           *EditValue;\r
+} NAME_VALUE_NODE;\r
+\r
+#define NAME_VALUE_NODE_FROM_LINK(a)  CR (a, NAME_VALUE_NODE, Link, NAME_VALUE_NODE_SIGNATURE)\r
+\r
+#define FORMSET_STORAGE_SIGNATURE  EFI_SIGNATURE_32 ('F', 'S', 'T', 'G')\r
+\r
+typedef struct {\r
+  UINTN            Signature;\r
+  LIST_ENTRY       Link;\r
+\r
+  UINT8            Type;           // Storage type\r
+\r
+  UINT16           VarStoreId;\r
+  EFI_GUID         Guid;\r
+\r
+  CHAR16           *Name;          // For EFI_IFR_VARSTORE\r
+  UINT16           Size;\r
+  UINT8            *Buffer;\r
+  UINT8            *EditBuffer;    // Edit copy for Buffer Storage\r
+\r
+  LIST_ENTRY       NameValueListHead; // List of NAME_VALUE_NODE\r
+\r
+  UINT32           Attributes;     // For EFI_IFR_VARSTORE_EFI: EFI Variable attribute\r
+\r
+  CHAR16           *ConfigHdr;     // <ConfigHdr>\r
+  CHAR16           *ConfigRequest; // <ConfigRequest> = <ConfigHdr> + <RequestElement>\r
+  UINTN            ElementCount;   // Number of <RequestElement> in the <ConfigRequest>\r
+  UINTN            SpareStrLen;    // Spare length of ConfigRequest string buffer\r
+} FORMSET_STORAGE;\r
+\r
+#define FORMSET_STORAGE_FROM_LINK(a)  CR (a, FORMSET_STORAGE, Link, FORMSET_STORAGE_SIGNATURE)\r
+\r
+#define EXPRESSION_OPCODE_SIGNATURE  EFI_SIGNATURE_32 ('E', 'X', 'O', 'P')\r
+\r
+typedef struct {\r
+  UINTN             Signature;\r
+  LIST_ENTRY        Link;\r
+\r
+  UINT8             Operand;\r
+\r
+  UINT8             Format;      // For EFI_IFR_TO_STRING, EFI_IFR_FIND\r
+  UINT8             Flags;       // For EFI_IFR_SPAN\r
+  UINT8             RuleId;      // For EFI_IFR_RULE_REF\r
+\r
+  EFI_HII_VALUE     Value;       // For EFI_IFR_EQ_ID_VAL, EFI_IFR_UINT64, EFI_IFR_UINT32, EFI_IFR_UINT16, EFI_IFR_UINT8, EFI_IFR_STRING_REF1\r
+\r
+  EFI_QUESTION_ID   QuestionId;  // For EFI_IFR_EQ_ID_ID, EFI_IFR_EQ_ID_LIST, EFI_IFR_QUESTION_REF1\r
+  EFI_QUESTION_ID   QuestionId2;\r
+\r
+  UINT16            ListLength;  // For EFI_IFR_EQ_ID_LIST\r
+  UINT16            *ValueList;\r
+\r
+  EFI_STRING_ID     DevicePath;  // For EFI_IFR_QUESTION_REF3_2, EFI_IFR_QUESTION_REF3_3\r
+  EFI_GUID          Guid;\r
+} EXPRESSION_OPCODE;\r
+\r
+#define EXPRESSION_OPCODE_FROM_LINK(a)  CR (a, EXPRESSION_OPCODE, Link, EXPRESSION_OPCODE_SIGNATURE)\r
+\r
+#define FORM_EXPRESSION_SIGNATURE  EFI_SIGNATURE_32 ('F', 'E', 'X', 'P')\r
+\r
+typedef struct {\r
+  UINTN             Signature;\r
+  LIST_ENTRY        Link;\r
+\r
+  UINT8             Type;            // Type for this expression\r
+\r
+  UINT8             RuleId;          // For EFI_IFR_RULE only\r
+  EFI_STRING_ID     Error;           // For EFI_IFR_NO_SUBMIT_IF, EFI_IFR_INCONSISTENT_IF only\r
+\r
+  EFI_HII_VALUE     Result;          // Expression evaluation result\r
+\r
+  LIST_ENTRY        OpCodeListHead;  // OpCodes consist of this expression (EXPRESSION_OPCODE)\r
+} FORM_EXPRESSION;\r
+\r
+#define FORM_EXPRESSION_FROM_LINK(a)  CR (a, FORM_EXPRESSION, Link, FORM_EXPRESSION_SIGNATURE)\r
+\r
+#define QUESTION_DEFAULT_SIGNATURE  EFI_SIGNATURE_32 ('Q', 'D', 'F', 'T')\r
+\r
+typedef struct {\r
+  UINTN               Signature;\r
+  LIST_ENTRY          Link;\r
+\r
+  UINT16              DefaultId;\r
+  EFI_HII_VALUE       Value;              // Default value\r
+\r
+  FORM_EXPRESSION     *ValueExpression;   // Not-NULL indicates default value is provided by EFI_IFR_VALUE\r
+} QUESTION_DEFAULT;\r
+\r
+#define QUESTION_DEFAULT_FROM_LINK(a)  CR (a, QUESTION_DEFAULT, Link, QUESTION_DEFAULT_SIGNATURE)\r
+\r
+#define QUESTION_OPTION_SIGNATURE  EFI_SIGNATURE_32 ('Q', 'O', 'P', 'T')\r
+\r
+typedef struct {\r
+  UINTN               Signature;\r
+  LIST_ENTRY          Link;\r
+\r
+  EFI_STRING_ID       Text;\r
+  UINT8               Flags;\r
+  EFI_HII_VALUE       Value;\r
+  EFI_IMAGE_ID        ImageId;\r
+\r
+  FORM_EXPRESSION     *SuppressExpression; // Non-NULL indicates nested inside of SuppressIf\r
+} QUESTION_OPTION;\r
+\r
+#define QUESTION_OPTION_FROM_LINK(a)  CR (a, QUESTION_OPTION, Link, QUESTION_OPTION_SIGNATURE)\r
+\r
+#define FORM_BROWSER_STATEMENT_SIGNATURE  EFI_SIGNATURE_32 ('F', 'S', 'T', 'A')\r
+typedef struct {\r
+  UINTN                 Signature;\r
+  LIST_ENTRY            Link;\r
+\r
+  UINT8                 Operand;          // The operand (first byte) of this Statement or Question\r
+\r
+  //\r
+  // Statement Header\r
+  //\r
+  EFI_STRING_ID         Prompt;\r
+  EFI_STRING_ID         Help;\r
+  EFI_STRING_ID         TextTwo;          // For EFI_IFR_TEXT\r
+\r
+  //\r
+  // Question Header\r
+  //\r
+  EFI_QUESTION_ID       QuestionId;       // The value of zero is reserved\r
+  EFI_VARSTORE_ID       VarStoreId;       // A value of zero indicates no variable storage\r
+  FORMSET_STORAGE       *Storage;\r
+  union {\r
+    EFI_STRING_ID       VarName;\r
+    UINT16              VarOffset;\r
+  }  VarStoreInfo;\r
+  UINT16                StorageWidth;\r
+  UINT8                 QuestionFlags;\r
+  CHAR16                *VariableName;    // Name/Value or EFI Variable name\r
+  CHAR16                *BlockName;       // Buffer storage block name: "OFFSET=...WIDTH=..."\r
+\r
+  EFI_HII_VALUE         HiiValue;         // Edit copy for checkbox, numberic, oneof\r
+  UINT8                 *BufferValue;     // Edit copy for string, password, orderedlist\r
+\r
+  //\r
+  // OpCode specific members\r
+  //\r
+  UINT8                 Flags;            // for EFI_IFR_CHECKBOX, EFI_IFR_DATE, EFI_IFR_NUMERIC, EFI_IFR_ONE_OF,\r
+                                          // EFI_IFR_ORDERED_LIST, EFI_IFR_STRING,EFI_IFR_SUBTITLE,EFI_IFR_TIME, EFI_IFR_BANNER\r
+  UINT8                 MaxContainers;    // for EFI_IFR_ORDERED_LIST\r
+\r
+  UINT16                BannerLineNumber; // for EFI_IFR_BANNER, 1-based line number\r
+  EFI_STRING_ID         QuestionConfig;   // for EFI_IFR_ACTION, if 0 then no configuration string will be processed\r
+\r
+  UINT64                Minimum;          // for EFI_IFR_ONE_OF/EFI_IFR_NUMERIC, it's Min/Max value\r
+  UINT64                Maximum;          // for EFI_IFR_STRING/EFI_IFR_PASSWORD, it's Min/Max length\r
+  UINT64                Step;\r
+\r
+  EFI_DEFAULT_ID        DefaultId;        // for EFI_IFR_RESET_BUTTON\r
+  EFI_FORM_ID           RefFormId;        // for EFI_IFR_REF\r
+  EFI_QUESTION_ID       RefQuestionId;    // for EFI_IFR_REF2\r
+  EFI_GUID              RefFormSetId;     // for EFI_IFR_REF3\r
+  EFI_STRING_ID         RefDevicePath;    // for EFI_IFR_REF4\r
+\r
+  //\r
+  // Get from IFR parsing\r
+  //\r
+  FORM_EXPRESSION       *ValueExpression;    // nested EFI_IFR_VALUE, provide Question value and indicate Question is ReadOnly\r
+  LIST_ENTRY            DefaultListHead;     // nested EFI_IFR_DEFAULT list (QUESTION_DEFAULT), provide default values\r
+  LIST_ENTRY            OptionListHead;      // nested EFI_IFR_ONE_OF_OPTION list (QUESTION_OPTION)\r
+\r
+  EFI_IMAGE_ID          ImageId;             // nested EFI_IFR_IMAGE\r
+  UINT8                 RefreshInterval;     // nested EFI_IFR_REFRESH, refresh interval(in seconds) for Question value, 0 means no refresh\r
+  BOOLEAN               InSubtitle;          // nesting inside of EFI_IFR_SUBTITLE\r
+\r
+  LIST_ENTRY            InconsistentListHead;// nested inconsistent expression list (FORM_EXPRESSION)\r
+  LIST_ENTRY            NoSubmitListHead;    // nested nosubmit expression list (FORM_EXPRESSION)\r
+  FORM_EXPRESSION       *GrayOutExpression;  // nesting inside of GrayOutIf\r
+  FORM_EXPRESSION       *SuppressExpression; // nesting inside of SuppressIf\r
+\r
+} FORM_BROWSER_STATEMENT;\r
+\r
+#define FORM_BROWSER_STATEMENT_FROM_LINK(a)  CR (a, FORM_BROWSER_STATEMENT, Link, FORM_BROWSER_STATEMENT_SIGNATURE)\r
+\r
+#define FORM_BROWSER_FORM_SIGNATURE  EFI_SIGNATURE_32 ('F', 'F', 'R', 'M')\r
+\r
+typedef struct {\r
+  UINTN             Signature;\r
+  LIST_ENTRY        Link;\r
+\r
+  UINT16            FormId;\r
+  EFI_STRING_ID     FormTitle;\r
+\r
+  EFI_IMAGE_ID      ImageId;\r
+\r
+  LIST_ENTRY        ExpressionListHead;   // List of Expressions (FORM_EXPRESSION)\r
+  LIST_ENTRY        StatementListHead;    // List of Statements and Questions (FORM_BROWSER_STATEMENT)\r
+} FORM_BROWSER_FORM;\r
+\r
+#define FORM_BROWSER_FORM_FROM_LINK(a)  CR (a, FORM_BROWSER_FORM, Link, FORM_BROWSER_FORM_SIGNATURE)\r
+\r
+#define FORMSET_DEFAULTSTORE_SIGNATURE  EFI_SIGNATURE_32 ('F', 'D', 'F', 'S')\r
+\r
+typedef struct {\r
+  UINTN            Signature;\r
+  LIST_ENTRY       Link;\r
+\r
+  UINT16           DefaultId;\r
+  EFI_STRING_ID    DefaultName;\r
+} FORMSET_DEFAULTSTORE;\r
+\r
+#define FORMSET_DEFAULTSTORE_FROM_LINK(a)  CR (a, FORMSET_DEFAULTSTORE, Link, FORMSET_DEFAULTSTORE_SIGNATURE)\r
+\r
+typedef struct {\r
+  EFI_HII_HANDLE                  HiiHandle;\r
+  EFI_HANDLE                      DriverHandle;\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
+  EFI_DEVICE_PATH_PROTOCOL        *DevicePath;\r
+\r
+  UINTN                           IfrBinaryLength;\r
+  UINT8                           *IfrBinaryData;\r
+\r
+  EFI_GUID                        Guid;\r
+  EFI_STRING_ID                   FormSetTitle;\r
+  EFI_STRING_ID                   Help;\r
+  UINT16                          Class;\r
+  UINT16                          SubClass;\r
+  EFI_IMAGE_ID                    ImageId;\r
+\r
+  FORM_BROWSER_STATEMENT          *StatementBuffer;     // Buffer for all Statements and Questions\r
+  EXPRESSION_OPCODE               *ExpressionBuffer;    // Buffer for all Expression OpCode\r
+\r
+  LIST_ENTRY                      StorageListHead;      // Storage list (FORMSET_STORAGE)\r
+  LIST_ENTRY                      DefaultStoreListHead; // DefaultStore list (FORMSET_DEFAULTSTORE)\r
+  LIST_ENTRY                      FormListHead;         // Form list (FORM_BROWSER_FORM)\r
+} FORM_BROWSER_FORMSET;\r
+\r
+\r
+EFI_STATUS\r
+EvaluateExpression (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN FORM_BROWSER_FORM     *Form,\r
+  IN OUT FORM_EXPRESSION   *Expression\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+ParseOpCodes (\r
+  IN FORM_BROWSER_FORMSET              *FormSet\r
+  )\r
+;\r
+\r
+VOID\r
+DestroyFormSet (\r
+  IN OUT FORM_BROWSER_FORMSET  *FormSet\r
+  )\r
+;\r
+\r
+#endif\r
+\r
diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserCommon.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserCommon.c
new file mode 100644 (file)
index 0000000..eeb5767
--- /dev/null
@@ -0,0 +1,78 @@
+#include <PiDxe.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+\r
+CHAR16            *gEmptyString = L" ";\r
+\r
+/**\r
+  Get the string based on the StringId and HII Package List Handle.\r
+\r
+  @param  Token                  The String's ID.\r
+  @param  HiiHandle              The package list in the HII database to search for\r
+                                 the specified string.\r
+\r
+  @return The output string.\r
+\r
+**/\r
+CHAR16 *\r
+GetToken (\r
+  IN  EFI_STRING_ID                Token,\r
+  IN  EFI_HII_HANDLE               HiiHandle\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  CHAR16      *String;\r
+  UINTN       BufferLength;\r
+\r
+  //\r
+  // Set default string size assumption at no more than 256 bytes\r
+  //\r
+  BufferLength = 0x100;\r
+  String = AllocateZeroPool (BufferLength);\r
+  ASSERT (String != NULL);\r
+\r
+  Status = HiiLibGetString (HiiHandle, Token, String, &BufferLength);\r
+\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    gBS->FreePool (String);\r
+    String = AllocateZeroPool (BufferLength);\r
+    ASSERT (String != NULL);\r
+\r
+    Status = HiiLibGetString (HiiHandle, Token, String, &BufferLength);\r
+  }\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return String;\r
+}\r
+\r
+/**\r
+  Create a new string in HII Package List.\r
+\r
+  @param  String                 The String to be added\r
+  @param  HiiHandle              The package list in the HII database to insert the\r
+                                 specified string.\r
+\r
+  @return The output string.\r
+\r
+**/\r
+EFI_STRING_ID\r
+NewString (\r
+  IN  CHAR16                   *String,\r
+  IN  EFI_HII_HANDLE           HiiHandle\r
+  )\r
+{\r
+  EFI_STRING_ID  StringId;\r
+  EFI_STATUS     Status;\r
+\r
+  StringId = 0;\r
+  Status = HiiLibNewString (HiiHandle, &StringId, String);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return StringId;\r
+}\r
+\r
+\r
+\r
diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserCommon.h b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserCommon.h
new file mode 100644 (file)
index 0000000..8c45ee5
--- /dev/null
@@ -0,0 +1,61 @@
+/** @file\r
+  Common Function and Macro defintions used for both for IFR Parser and Expression evaluation. \r
+  This header file should only be included by UefiIfrParserExpression.c and UefiIfrParser.c\r
+\r
+  Copyright (c) 2008, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _HII_THUNK_UEFI_IFR_PARSER_COMMON_INTERNAL_\r
+#define _HII_THUNK_UEFI_IFR_PARSER_COMMON_INTERNAL_\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Protocol/UnicodeCollation.h>\r
+\r
+extern CHAR16            *gEmptyString;\r
+\r
+/**\r
+  Get the string based on the StringId and HII Package List Handle.\r
+\r
+  @param  Token                  The String's ID.\r
+  @param  HiiHandle              The package list in the HII database to search for\r
+                                 the specified string.\r
+\r
+  @return The output string.\r
+\r
+**/\r
+CHAR16 *\r
+GetToken (\r
+  IN  EFI_STRING_ID                Token,\r
+  IN  EFI_HII_HANDLE               HiiHandle\r
+  )\r
+;\r
+\r
+/**\r
+  Create a new string in HII Package List.\r
+\r
+  @param  String                 The String to be added\r
+  @param  HiiHandle              The package list in the HII database to insert the\r
+                                 specified string.\r
+\r
+  @return The output string.\r
+\r
+**/\r
+EFI_STRING_ID\r
+NewString (\r
+  IN  CHAR16                   *String,\r
+  IN  EFI_HII_HANDLE           HiiHandle\r
+  )\r
+;\r
+\r
+#endif\r
+\r
diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserExpression.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserExpression.c
new file mode 100644 (file)
index 0000000..66b3857
--- /dev/null
@@ -0,0 +1,1948 @@
+/** @file\r
+\r
+Copyright (c) 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+  Expression.c\r
+\r
+Abstract:\r
+\r
+  Expression evaluation.\r
+\r
+\r
+**/\r
+#include <PiDxe.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Protocol/UnicodeCollation.h>\r
+  \r
+#include "UefiIfrParser.h"\r
+#include "UefiIfrParserExpressionInternal.h"\r
+#include "UefiIfrParserCommon.h"\r
+#include "R8Lib.h"\r
+\r
+//\r
+// Global stack used to evaluate boolean expresions\r
+//\r
+EFI_HII_VALUE *mOpCodeScopeStack = NULL;\r
+EFI_HII_VALUE *mOpCodeScopeStackEnd = NULL;\r
+EFI_HII_VALUE *mOpCodeScopeStackPointer = NULL;\r
+\r
+EFI_HII_VALUE *mExpressionEvaluationStack = NULL;\r
+EFI_HII_VALUE *mExpressionEvaluationStackEnd = NULL;\r
+EFI_HII_VALUE *mExpressionEvaluationStackPointer = NULL;\r
+\r
+//\r
+// Unicode collation protocol interface\r
+//\r
+EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation = NULL;\r
+\r
+\r
+/**\r
+  Grow size of the stack\r
+\r
+  @param  Stack                  On input: old stack; On output: new stack\r
+  @param  StackPtr               On input: old stack pointer; On output: new stack\r
+                                 pointer\r
+  @param  StackPtr               On input: old stack end; On output: new stack end\r
+\r
+  @retval EFI_SUCCESS            Grow stack success.\r
+  @retval EFI_OUT_OF_RESOURCES   No enough memory for stack space.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+GrowStack (\r
+  IN OUT EFI_HII_VALUE  **Stack,\r
+  IN OUT EFI_HII_VALUE  **StackPtr,\r
+  IN OUT EFI_HII_VALUE  **StackEnd\r
+  )\r
+{\r
+  UINTN           Size;\r
+  EFI_HII_VALUE  *NewStack;\r
+\r
+  Size = EXPRESSION_STACK_SIZE_INCREMENT;\r
+  if (*StackPtr != NULL) {\r
+    Size = Size + (*StackEnd - *Stack);\r
+  }\r
+\r
+  NewStack = AllocatePool (Size * sizeof (EFI_HII_VALUE));\r
+  if (NewStack == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  if (*StackPtr != NULL) {\r
+    //\r
+    // Copy from Old Stack to the New Stack\r
+    //\r
+    CopyMem (\r
+      NewStack,\r
+      *Stack,\r
+      (*StackEnd - *Stack) * sizeof (EFI_HII_VALUE)\r
+      );\r
+\r
+    //\r
+    // Free The Old Stack\r
+    //\r
+    gBS->FreePool (*Stack);\r
+  }\r
+\r
+  //\r
+  // Make the Stack pointer point to the old data in the new stack\r
+  //\r
+  *StackPtr = NewStack + (*StackPtr - *Stack);\r
+  *Stack    = NewStack;\r
+  *StackEnd = NewStack + Size;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Push an element onto the Boolean Stack\r
+\r
+  @param  Stack                  On input: old stack; On output: new stack\r
+  @param  StackPtr               On input: old stack pointer; On output: new stack\r
+                                 pointer\r
+  @param  StackPtr               On input: old stack end; On output: new stack end\r
+  @param  Data                   Data to push.\r
+\r
+  @retval EFI_SUCCESS            Push stack success.\r
+\r
+**/\r
+EFI_STATUS\r
+PushStack (\r
+  IN OUT EFI_HII_VALUE       **Stack,\r
+  IN OUT EFI_HII_VALUE       **StackPtr,\r
+  IN OUT EFI_HII_VALUE       **StackEnd,\r
+  IN EFI_HII_VALUE           *Data\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Check for a stack overflow condition\r
+  //\r
+  if (*StackPtr >= *StackEnd) {\r
+    //\r
+    // Grow the stack\r
+    //\r
+    Status = GrowStack (Stack, StackPtr, StackEnd);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Push the item onto the stack\r
+  //\r
+  CopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE));\r
+  *StackPtr = *StackPtr + 1;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Pop an element from the stack.\r
+\r
+  @param  Stack                  On input: old stack; On output: new stack\r
+  @param  StackPtr               On input: old stack pointer; On output: new stack\r
+                                 pointer\r
+  @param  StackPtr               On input: old stack end; On output: new stack end\r
+  @param  Data                   Data to pop.\r
+\r
+  @retval EFI_SUCCESS            The value was popped onto the stack.\r
+  @retval EFI_ACCESS_DENIED      The pop operation underflowed the stack\r
+\r
+**/\r
+EFI_STATUS\r
+PopStack (\r
+  IN OUT EFI_HII_VALUE       **Stack,\r
+  IN OUT EFI_HII_VALUE       **StackPtr,\r
+  IN OUT EFI_HII_VALUE       **StackEnd,\r
+  OUT EFI_HII_VALUE          *Data\r
+  )\r
+{\r
+  //\r
+  // Check for a stack underflow condition\r
+  //\r
+  if (*StackPtr == *Stack) {\r
+    return EFI_ACCESS_DENIED;\r
+  }\r
+\r
+  //\r
+  // Pop the item off the stack\r
+  //\r
+  *StackPtr = *StackPtr - 1;\r
+  CopyMem (Data, *StackPtr, sizeof (EFI_HII_VALUE));\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Reset stack pointer to begin of the stack.\r
+\r
+  None.\r
+\r
+  @return None.\r
+\r
+**/\r
+VOID\r
+ResetScopeStack (\r
+  VOID\r
+  )\r
+{\r
+  mOpCodeScopeStackPointer = mOpCodeScopeStack;\r
+}\r
+\r
+\r
+/**\r
+  Push an Operand onto the Stack\r
+\r
+  @param  Operand                Operand to push.\r
+\r
+  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
+  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the\r
+                                 stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PushScope (\r
+  IN UINT8   Operand\r
+  )\r
+{\r
+  EFI_HII_VALUE  Data;\r
+\r
+  Data.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+  Data.Value.u8 = Operand;\r
+\r
+  return PushStack (\r
+           &mOpCodeScopeStack,\r
+           &mOpCodeScopeStackPointer,\r
+           &mOpCodeScopeStackEnd,\r
+           &Data\r
+           );\r
+}\r
+\r
+\r
+/**\r
+  Pop an Operand from the Stack\r
+\r
+  @param  Operand                Operand to pop.\r
+\r
+  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
+  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the\r
+                                 stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PopScope (\r
+  OUT UINT8     *Operand\r
+  )\r
+{\r
+  EFI_STATUS     Status;\r
+  EFI_HII_VALUE  Data;\r
+\r
+  Status = PopStack (\r
+             &mOpCodeScopeStack,\r
+             &mOpCodeScopeStackPointer,\r
+             &mOpCodeScopeStackEnd,\r
+             &Data\r
+             );\r
+\r
+  *Operand = Data.Value.u8;\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Reset stack pointer to begin of the stack.\r
+\r
+  None.\r
+\r
+  @return None.\r
+\r
+**/\r
+VOID\r
+ResetExpressionStack (\r
+  VOID\r
+  )\r
+{\r
+  mExpressionEvaluationStackPointer = mExpressionEvaluationStack;\r
+}\r
+\r
+\r
+/**\r
+  Push an Expression value onto the Stack\r
+\r
+  @param  Value                  Expression value to push.\r
+\r
+  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
+  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the\r
+                                 stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PushExpression (\r
+  IN EFI_HII_VALUE  *Value\r
+  )\r
+{\r
+  return PushStack (\r
+           &mExpressionEvaluationStack,\r
+           &mExpressionEvaluationStackPointer,\r
+           &mExpressionEvaluationStackEnd,\r
+           Value\r
+           );\r
+}\r
+\r
+\r
+/**\r
+  Pop an Expression value from the stack.\r
+\r
+  @param  Value                  Expression value to pop.\r
+\r
+  @retval EFI_SUCCESS            The value was popped onto the stack.\r
+  @retval EFI_ACCESS_DENIED      The pop operation underflowed the stack\r
+\r
+**/\r
+EFI_STATUS\r
+PopExpression (\r
+  OUT EFI_HII_VALUE  *Value\r
+  )\r
+{\r
+  return PopStack (\r
+           &mExpressionEvaluationStack,\r
+           &mExpressionEvaluationStackPointer,\r
+           &mExpressionEvaluationStackEnd,\r
+           Value\r
+           );\r
+}\r
+\r
+\r
+/**\r
+  Get Form given its FormId.\r
+\r
+  @param  FormSet                The formset which contains this form.\r
+  @param  FormId                 Id of this form.\r
+\r
+  @retval Pointer                The form.\r
+  @retval NULL                   Specified Form is not found in the formset.\r
+\r
+**/\r
+FORM_BROWSER_FORM *\r
+IdToForm (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN UINT16                FormId\r
+)\r
+{\r
+  LIST_ENTRY         *Link;\r
+  FORM_BROWSER_FORM  *Form;\r
+\r
+  Link = GetFirstNode (&FormSet->FormListHead);\r
+  while (!IsNull (&FormSet->FormListHead, Link)) {\r
+    Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+\r
+    if (Form->FormId == FormId) {\r
+      return Form;\r
+    }\r
+\r
+    Link = GetNextNode (&FormSet->FormListHead, Link);\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+\r
+/**\r
+  Search a Question in Form scope using its QuestionId.\r
+\r
+  @param  Form                   The form which contains this Question.\r
+  @param  QuestionId             Id of this Question.\r
+\r
+  @retval Pointer                The Question.\r
+  @retval NULL                   Specified Question not found in the form.\r
+\r
+**/\r
+FORM_BROWSER_STATEMENT *\r
+IdToQuestion2 (\r
+  IN FORM_BROWSER_FORM  *Form,\r
+  IN UINT16             QuestionId\r
+  )\r
+{\r
+  LIST_ENTRY              *Link;\r
+  FORM_BROWSER_STATEMENT  *Question;\r
+\r
+  if (QuestionId == 0) {\r
+    //\r
+    // The value of zero is reserved\r
+    //\r
+    return NULL;\r
+  }\r
+\r
+  Link = GetFirstNode (&Form->StatementListHead);\r
+  while (!IsNull (&Form->StatementListHead, Link)) {\r
+    Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+\r
+    if (Question->QuestionId == QuestionId) {\r
+      return Question;\r
+    }\r
+\r
+    Link = GetNextNode (&Form->StatementListHead, Link);\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+\r
+/**\r
+  Search a Question in Formset scope using its QuestionId.\r
+\r
+  @param  FormSet                The formset which contains this form.\r
+  @param  Form                   The form which contains this Question.\r
+  @param  QuestionId             Id of this Question.\r
+\r
+  @retval Pointer                The Question.\r
+  @retval NULL                   Specified Question not found in the form.\r
+\r
+**/\r
+FORM_BROWSER_STATEMENT *\r
+IdToQuestion (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN FORM_BROWSER_FORM     *Form,\r
+  IN UINT16                QuestionId\r
+  )\r
+{\r
+  LIST_ENTRY              *Link;\r
+  FORM_BROWSER_STATEMENT  *Question;\r
+\r
+  //\r
+  // Search in the form scope first\r
+  //\r
+  Question = IdToQuestion2 (Form, QuestionId);\r
+  if (Question != NULL) {\r
+    return Question;\r
+  }\r
+\r
+  //\r
+  // Search in the formset scope\r
+  //\r
+  Link = GetFirstNode (&FormSet->FormListHead);\r
+  while (!IsNull (&FormSet->FormListHead, Link)) {\r
+    Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+\r
+    Question = IdToQuestion2 (Form, QuestionId);\r
+    if (Question != NULL) {\r
+      return Question;\r
+    }\r
+\r
+    Link = GetNextNode (&FormSet->FormListHead, Link);\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+\r
+/**\r
+  Get Expression given its RuleId.\r
+\r
+  @param  Form                   The form which contains this Expression.\r
+  @param  RuleId                 Id of this Expression.\r
+\r
+  @retval Pointer                The Expression.\r
+  @retval NULL                   Specified Expression not found in the form.\r
+\r
+**/\r
+FORM_EXPRESSION *\r
+RuleIdToExpression (\r
+  IN FORM_BROWSER_FORM  *Form,\r
+  IN UINT8              RuleId\r
+  )\r
+{\r
+  LIST_ENTRY       *Link;\r
+  FORM_EXPRESSION  *Expression;\r
+\r
+  Link = GetFirstNode (&Form->ExpressionListHead);\r
+  while (!IsNull (&Form->ExpressionListHead, Link)) {\r
+    Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
+\r
+    if (Expression->Type == EFI_HII_EXPRESSION_RULE && Expression->RuleId == RuleId) {\r
+      return Expression;\r
+    }\r
+\r
+    Link = GetNextNode (&Form->ExpressionListHead, Link);\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+\r
+/**\r
+  Locate the Unicode Collation Protocol interface for later use.\r
+\r
+  None.\r
+\r
+  @retval EFI_SUCCESS            Protocol interface initialize success.\r
+  @retval Other                  Protocol interface initialize failed.\r
+\r
+**/\r
+EFI_STATUS\r
+InitializeUnicodeCollationProtocol (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  if (mUnicodeCollation != NULL) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // BUGBUG: Proper impelmentation is to locate all Unicode Collation Protocol\r
+  // instances first and then select one which support English language.\r
+  // Current implementation just pick the first instance.\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiUnicodeCollation2ProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &mUnicodeCollation\r
+                  );\r
+  return Status;\r
+}\r
+\r
+VOID\r
+IfrStrToUpper (\r
+  CHAR16                   *String\r
+  )\r
+{\r
+  while (*String != 0) {\r
+    if ((*String >= 'a') && (*String <= 'z')) {\r
+      *String = (UINT16) ((*String) & ((UINT16) ~0x20));\r
+    }\r
+    String++;\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Evaluate opcode EFI_IFR_TO_STRING.\r
+\r
+  @param  FormSet                Formset which contains this opcode.\r
+  @param  Format                 String format in EFI_IFR_TO_STRING.\r
+  @param  Result                 Evaluation result for this opcode.\r
+\r
+  @retval EFI_SUCCESS            Opcode evaluation success.\r
+  @retval Other                  Opcode evaluation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfrToString (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN UINT8                 Format,\r
+  OUT  EFI_HII_VALUE       *Result\r
+  )\r
+{\r
+  EFI_STATUS     Status;\r
+  EFI_HII_VALUE  Value;\r
+  CHAR16         *String;\r
+  CHAR16         *PrintFormat;\r
+  CHAR16         Buffer[MAXIMUM_VALUE_CHARACTERS];\r
+  UINTN          BufferSize;\r
+\r
+  Status = PopExpression (&Value);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  switch (Value.Type) {\r
+  case EFI_IFR_TYPE_NUM_SIZE_8:\r
+  case EFI_IFR_TYPE_NUM_SIZE_16:\r
+  case EFI_IFR_TYPE_NUM_SIZE_32:\r
+  case EFI_IFR_TYPE_NUM_SIZE_64:\r
+    BufferSize = MAXIMUM_VALUE_CHARACTERS * sizeof (CHAR16);\r
+    switch (Format) {\r
+    case EFI_IFR_STRING_UNSIGNED_DEC:\r
+    case EFI_IFR_STRING_SIGNED_DEC:\r
+      PrintFormat = L"%ld";\r
+      break;\r
+\r
+    case EFI_IFR_STRING_LOWERCASE_HEX:\r
+      PrintFormat = L"%lx";\r
+      break;\r
+\r
+    case EFI_IFR_STRING_UPPERCASE_HEX:\r
+      PrintFormat = L"%lX";\r
+      break;\r
+\r
+    default:\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+    UnicodeSPrint (Buffer, BufferSize, PrintFormat, Value.Value.u64);\r
+    String = Buffer;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_STRING:\r
+    CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));\r
+    return EFI_SUCCESS;\r
+\r
+  case EFI_IFR_TYPE_BOOLEAN:\r
+    String = (Value.Value.b) ? L"True" : L"False";\r
+    break;\r
+\r
+  default:\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Result->Type = EFI_IFR_TYPE_STRING;\r
+  Result->Value.string = NewString (String, FormSet->HiiHandle);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Evaluate opcode EFI_IFR_TO_UINT.\r
+\r
+  @param  FormSet                Formset which contains this opcode.\r
+  @param  Result                 Evaluation result for this opcode.\r
+\r
+  @retval EFI_SUCCESS            Opcode evaluation success.\r
+  @retval Other                  Opcode evaluation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfrToUint (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  OUT  EFI_HII_VALUE       *Result\r
+  )\r
+{\r
+  EFI_STATUS     Status;\r
+  EFI_HII_VALUE  Value;\r
+  CHAR16         *String;\r
+  CHAR16         *StringPtr;\r
+  UINTN          BufferSize;\r
+\r
+  Status = PopExpression (&Value);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (Value.Type >= EFI_IFR_TYPE_OTHER) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = EFI_SUCCESS;\r
+  if (Value.Type == EFI_IFR_TYPE_STRING) {\r
+    String = GetToken (Value.Value.string, FormSet->HiiHandle);\r
+    if (String == NULL) {\r
+      return EFI_NOT_FOUND;\r
+    }\r
+\r
+    IfrStrToUpper (String);\r
+    StringPtr = StrStr (String, L"0X");\r
+    if (StringPtr != NULL) {\r
+      //\r
+      // Hex string\r
+      //\r
+      BufferSize = sizeof (UINT64);\r
+      Status = R8_HexStringToBuf ((UINT8 *) &Result->Value.u64, &BufferSize, StringPtr + 2, NULL);\r
+    } else {\r
+      //\r
+      // BUGBUG: Need handle decimal string\r
+      //\r
+    }\r
+    gBS->FreePool (String);\r
+  } else {\r
+    CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));\r
+  }\r
+\r
+  Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Evaluate opcode EFI_IFR_CATENATE.\r
+\r
+  @param  FormSet                Formset which contains this opcode.\r
+  @param  Result                 Evaluation result for this opcode.\r
+\r
+  @retval EFI_SUCCESS            Opcode evaluation success.\r
+  @retval Other                  Opcode evaluation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfrCatenate (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  OUT  EFI_HII_VALUE       *Result\r
+  )\r
+{\r
+  EFI_STATUS     Status;\r
+  EFI_HII_VALUE  Value;\r
+  CHAR16         *String[2];\r
+  UINTN          Index;\r
+  CHAR16         *StringPtr;\r
+  UINTN          Size;\r
+\r
+  //\r
+  // String[0] - The second string\r
+  // String[1] - The first string\r
+  //\r
+  String[0] = NULL;\r
+  String[1] = NULL;\r
+  StringPtr = NULL;\r
+  Status = EFI_SUCCESS;\r
+\r
+  for (Index = 0; Index < 2; Index++) {\r
+    Status = PopExpression (&Value);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    if (Value.Type != EFI_IFR_TYPE_STRING) {\r
+      Status = EFI_UNSUPPORTED;\r
+      goto Done;\r
+    }\r
+\r
+    String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
+    if (String== NULL) {\r
+      Status = EFI_NOT_FOUND;\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  Size = StrSize (String[0]);\r
+  StringPtr= AllocatePool (StrSize (String[1]) + Size);\r
+  ASSERT (StringPtr != NULL);\r
+  StrCpy (StringPtr, String[1]);\r
+  StrCat (StringPtr, String[0]);\r
+\r
+  Result->Type = EFI_IFR_TYPE_STRING;\r
+  Result->Value.string = NewString (StringPtr, FormSet->HiiHandle);\r
+\r
+Done:\r
+  SafeFreePool (String[0]);\r
+  SafeFreePool (String[1]);\r
+  SafeFreePool (StringPtr);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Evaluate opcode EFI_IFR_MATCH.\r
+\r
+  @param  FormSet                Formset which contains this opcode.\r
+  @param  Result                 Evaluation result for this opcode.\r
+\r
+  @retval EFI_SUCCESS            Opcode evaluation success.\r
+  @retval Other                  Opcode evaluation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfrMatch (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  OUT  EFI_HII_VALUE       *Result\r
+  )\r
+{\r
+  EFI_STATUS     Status;\r
+  EFI_HII_VALUE  Value;\r
+  CHAR16         *String[2];\r
+  UINTN          Index;\r
+\r
+  //\r
+  // String[0] - The string to search\r
+  // String[1] - pattern\r
+  //\r
+  String[0] = NULL;\r
+  String[1] = NULL;\r
+  Status = EFI_SUCCESS;\r
+  for (Index = 0; Index < 2; Index++) {\r
+    Status = PopExpression (&Value);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    if (Value.Type != EFI_IFR_TYPE_STRING) {\r
+      Status = EFI_UNSUPPORTED;\r
+      goto Done;\r
+    }\r
+\r
+    String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
+    if (String== NULL) {\r
+      Status = EFI_NOT_FOUND;\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  Result->Type = EFI_IFR_TYPE_BOOLEAN;\r
+  Result->Value.b = mUnicodeCollation->MetaiMatch (mUnicodeCollation, String[0], String[1]);\r
+\r
+Done:\r
+  SafeFreePool (String[0]);\r
+  SafeFreePool (String[1]);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Evaluate opcode EFI_IFR_FIND.\r
+\r
+  @param  FormSet                Formset which contains this opcode.\r
+  @param  Format                 Case sensitive or insensitive.\r
+  @param  Result                 Evaluation result for this opcode.\r
+\r
+  @retval EFI_SUCCESS            Opcode evaluation success.\r
+  @retval Other                  Opcode evaluation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfrFind (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN UINT8                 Format,\r
+  OUT  EFI_HII_VALUE       *Result\r
+  )\r
+{\r
+  EFI_STATUS     Status;\r
+  EFI_HII_VALUE  Value;\r
+  CHAR16         *String[2];\r
+  UINTN          Base;\r
+  CHAR16         *StringPtr;\r
+  UINTN          Index;\r
+\r
+  if (Format > EFI_IFR_FF_CASE_INSENSITIVE) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = PopExpression (&Value);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  Base = (UINTN) Value.Value.u64;\r
+\r
+  //\r
+  // String[0] - sub-string\r
+  // String[1] - The string to search\r
+  //\r
+  String[0] = NULL;\r
+  String[1] = NULL;\r
+  for (Index = 0; Index < 2; Index++) {\r
+    Status = PopExpression (&Value);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    if (Value.Type != EFI_IFR_TYPE_STRING) {\r
+      Status = EFI_UNSUPPORTED;\r
+      goto Done;\r
+    }\r
+\r
+    String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
+    if (String== NULL) {\r
+      Status = EFI_NOT_FOUND;\r
+      goto Done;\r
+    }\r
+\r
+    if (Format == EFI_IFR_FF_CASE_INSENSITIVE) {\r
+      //\r
+      // Case insensitive, convert both string to upper case\r
+      //\r
+      IfrStrToUpper (String[Index]);\r
+    }\r
+  }\r
+\r
+  Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+  if (Base >= StrLen (String[1])) {\r
+    Result->Value.u64 = 0xFFFFFFFFFFFFFFFFULL;\r
+  } else {\r
+    StringPtr = StrStr (String[1] + Base, String[0]);\r
+    Result->Value.u64 = (StringPtr == NULL) ? 0xFFFFFFFFFFFFFFFFULL : (StringPtr - String[1]);\r
+  }\r
+\r
+Done:\r
+  SafeFreePool (String[0]);\r
+  SafeFreePool (String[1]);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Evaluate opcode EFI_IFR_MID.\r
+\r
+  @param  FormSet                Formset which contains this opcode.\r
+  @param  Result                 Evaluation result for this opcode.\r
+\r
+  @retval EFI_SUCCESS            Opcode evaluation success.\r
+  @retval Other                  Opcode evaluation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfrMid (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  OUT  EFI_HII_VALUE       *Result\r
+  )\r
+{\r
+  EFI_STATUS     Status;\r
+  EFI_HII_VALUE  Value;\r
+  CHAR16         *String;\r
+  UINTN          Base;\r
+  UINTN          Length;\r
+  CHAR16         *SubString;\r
+\r
+  Status = PopExpression (&Value);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  Length = (UINTN) Value.Value.u64;\r
+\r
+  Status = PopExpression (&Value);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  Base = (UINTN) Value.Value.u64;\r
+\r
+  Status = PopExpression (&Value);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  if (Value.Type != EFI_IFR_TYPE_STRING) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  String = GetToken (Value.Value.string, FormSet->HiiHandle);\r
+  if (String == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  if (Length == 0 || Base >= StrLen (String)) {\r
+    SubString = gEmptyString;\r
+  } else {\r
+    SubString = String + Base;\r
+    if ((Base + Length) < StrLen (String)) {\r
+      SubString[Length] = L'\0';\r
+    }\r
+  }\r
+\r
+  Result->Type = EFI_IFR_TYPE_STRING;\r
+  Result->Value.string = NewString (SubString, FormSet->HiiHandle);\r
+\r
+  gBS->FreePool (String);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Evaluate opcode EFI_IFR_TOKEN.\r
+\r
+  @param  FormSet                Formset which contains this opcode.\r
+  @param  Result                 Evaluation result for this opcode.\r
+\r
+  @retval EFI_SUCCESS            Opcode evaluation success.\r
+  @retval Other                  Opcode evaluation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfrToken (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  OUT  EFI_HII_VALUE       *Result\r
+  )\r
+{\r
+  EFI_STATUS     Status;\r
+  EFI_HII_VALUE  Value;\r
+  CHAR16         *String[2];\r
+  UINTN          Count;\r
+  CHAR16         *Delimiter;\r
+  CHAR16         *SubString;\r
+  CHAR16         *StringPtr;\r
+  UINTN          Index;\r
+\r
+  Status = PopExpression (&Value);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  Count = (UINTN) Value.Value.u64;\r
+\r
+  //\r
+  // String[0] - Delimiter\r
+  // String[1] - The string to search\r
+  //\r
+  String[0] = NULL;\r
+  String[1] = NULL;\r
+  for (Index = 0; Index < 2; Index++) {\r
+    Status = PopExpression (&Value);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    if (Value.Type != EFI_IFR_TYPE_STRING) {\r
+      Status = EFI_UNSUPPORTED;\r
+      goto Done;\r
+    }\r
+\r
+    String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
+    if (String== NULL) {\r
+      Status = EFI_NOT_FOUND;\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  Delimiter = String[0];\r
+  SubString = String[1];\r
+  while (Count > 0) {\r
+    SubString = StrStr (SubString, Delimiter);\r
+    if (SubString != NULL) {\r
+      //\r
+      // Skip over the delimiter\r
+      //\r
+      SubString = SubString + StrLen (Delimiter);\r
+    } else {\r
+      break;\r
+    }\r
+    Count--;\r
+  }\r
+\r
+  if (SubString == NULL) {\r
+    //\r
+    // nth delimited sub-string not found, push an empty string\r
+    //\r
+    SubString = gEmptyString;\r
+  } else {\r
+    //\r
+    // Put a NULL terminator for nth delimited sub-string\r
+    //\r
+    StringPtr = StrStr (SubString, Delimiter);\r
+    if (StringPtr != NULL) {\r
+      *StringPtr = L'\0';\r
+    }\r
+  }\r
+\r
+  Result->Type = EFI_IFR_TYPE_STRING;\r
+  Result->Value.string = NewString (SubString, FormSet->HiiHandle);\r
+\r
+Done:\r
+  SafeFreePool (String[0]);\r
+  SafeFreePool (String[1]);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Evaluate opcode EFI_IFR_SPAN.\r
+\r
+  @param  FormSet                Formset which contains this opcode.\r
+  @param  Flags                  FIRST_MATCHING or FIRST_NON_MATCHING.\r
+  @param  Result                 Evaluation result for this opcode.\r
+\r
+  @retval EFI_SUCCESS            Opcode evaluation success.\r
+  @retval Other                  Opcode evaluation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfrSpan (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN UINT8                 Flags,\r
+  OUT  EFI_HII_VALUE       *Result\r
+  )\r
+{\r
+  EFI_STATUS     Status;\r
+  EFI_HII_VALUE  Value;\r
+  CHAR16         *String[2];\r
+  CHAR16         *Charset;\r
+  UINTN          Base;\r
+  UINTN          Index;\r
+  CHAR16         *StringPtr;\r
+  BOOLEAN        Found;\r
+\r
+  Status = PopExpression (&Value);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  Base = (UINTN) Value.Value.u64;\r
+\r
+  //\r
+  // String[0] - Charset\r
+  // String[1] - The string to search\r
+  //\r
+  String[0] = NULL;\r
+  String[1] = NULL;\r
+  for (Index = 0; Index < 2; Index++) {\r
+    Status = PopExpression (&Value);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    if (Value.Type != EFI_IFR_TYPE_STRING) {\r
+      Status = EFI_UNSUPPORTED;\r
+      goto Done;\r
+    }\r
+\r
+    String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
+    if (String== NULL) {\r
+      Status = EFI_NOT_FOUND;\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  if (Base >= StrLen (String[1])) {\r
+    Status = EFI_UNSUPPORTED;\r
+    goto Done;\r
+  }\r
+\r
+  Found = FALSE;\r
+  StringPtr = String[1] + Base;\r
+  Charset = String[0];\r
+  while (*StringPtr != 0 && !Found) {\r
+    Index = 0;\r
+    while (Charset[Index] != 0) {\r
+      if (*StringPtr >= Charset[Index] && *StringPtr <= Charset[Index + 1]) {\r
+        if (Flags == EFI_IFR_FLAGS_FIRST_MATCHING) {\r
+          Found = TRUE;\r
+          break;\r
+        }\r
+      } else {\r
+        if (Flags == EFI_IFR_FLAGS_FIRST_NON_MATCHING) {\r
+          Found = TRUE;\r
+          break;\r
+        }\r
+      }\r
+      //\r
+      // Skip characters pair representing low-end of a range and high-end of a range\r
+      //\r
+      Index += 2;\r
+    }\r
+\r
+    if (!Found) {\r
+      StringPtr++;\r
+    }\r
+  }\r
+\r
+  Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+  Result->Value.u64 = StringPtr - String[1];\r
+\r
+Done:\r
+  SafeFreePool (String[0]);\r
+  SafeFreePool (String[1]);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Zero extend integer/boolean/date/time to UINT64 for comparing.\r
+\r
+  @param  Value                  HII Value to be converted.\r
+\r
+  @return None.\r
+\r
+**/\r
+VOID\r
+ExtendValueToU64 (\r
+  IN  EFI_HII_VALUE   *Value\r
+  )\r
+{\r
+  UINT64  Temp;\r
+\r
+  Temp = 0;\r
+  switch (Value->Type) {\r
+  case EFI_IFR_TYPE_NUM_SIZE_8:\r
+    Temp = Value->Value.u8;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_16:\r
+    Temp = Value->Value.u16;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_32:\r
+    Temp = Value->Value.u32;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_BOOLEAN:\r
+    Temp = Value->Value.b;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_TIME:\r
+    Temp = Value->Value.u32 & 0xffffff;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_DATE:\r
+    Temp = Value->Value.u32;\r
+    break;\r
+\r
+  default:\r
+    return;\r
+  }\r
+\r
+  Value->Value.u64 = Temp;\r
+}\r
+\r
+\r
+/**\r
+  Compare two Hii value.\r
+\r
+  @param  Value1                 Expression value to compare on left-hand\r
+  @param  Value2                 Expression value to compare on right-hand\r
+  @param  HiiHandle              Only required for string compare\r
+\r
+  @retval EFI_INVALID_PARAMETER  Could not perform comparation on two values\r
+  @retval 0                      Two operators equeal\r
+  @retval 0                      Value1 is greater than Value2\r
+  @retval 0                      Value1 is less than Value2\r
+\r
+**/\r
+INTN\r
+CompareHiiValue (\r
+  IN  EFI_HII_VALUE   *Value1,\r
+  IN  EFI_HII_VALUE   *Value2,\r
+  IN  EFI_HII_HANDLE  HiiHandle OPTIONAL\r
+  )\r
+{\r
+  INTN    Result;\r
+  INT64   Temp64;\r
+  CHAR16  *Str1;\r
+  CHAR16  *Str2;\r
+\r
+  if (Value1->Type >= EFI_IFR_TYPE_OTHER || Value2->Type >= EFI_IFR_TYPE_OTHER ) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Value1->Type == EFI_IFR_TYPE_STRING || Value2->Type == EFI_IFR_TYPE_STRING ) {\r
+    if (Value1->Type != Value2->Type) {\r
+      //\r
+      // Both Operator should be type of String\r
+      //\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if (Value1->Value.string == 0 || Value2->Value.string == 0) {\r
+      //\r
+      // StringId 0 is reserved\r
+      //\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if (Value1->Value.string == Value2->Value.string) {\r
+      return 0;\r
+    }\r
+\r
+    Str1 = GetToken (Value1->Value.string, HiiHandle);\r
+    if (Str1 == NULL) {\r
+      //\r
+      // String not found\r
+      //\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    Str2 = GetToken (Value2->Value.string, HiiHandle);\r
+    if (Str2 == NULL) {\r
+      gBS->FreePool (Str1);\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    Result = StrCmp (Str1, Str2);\r
+\r
+    gBS->FreePool (Str1);\r
+    gBS->FreePool (Str2);\r
+\r
+    return Result;\r
+  }\r
+\r
+  //\r
+  // Take remain types(integer, boolean, date/time) as integer\r
+  //\r
+  Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64);\r
+  if (Temp64 > 0) {\r
+    Result = 1;\r
+  } else if (Temp64 < 0) {\r
+    Result = -1;\r
+  } else {\r
+    Result = 0;\r
+  }\r
+\r
+  return Result;\r
+}\r
+\r
+\r
+/**\r
+  Evaluate the result of a HII expression\r
+\r
+  @param  FormSet                FormSet associated with this expression.\r
+  @param  Form                   Form associated with this expression.\r
+  @param  Expression             Expression to be evaluated.\r
+\r
+  @retval EFI_SUCCESS            The expression evaluated successfuly\r
+  @retval EFI_NOT_FOUND          The Question which referenced by a QuestionId\r
+                                 could not be found.\r
+  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the\r
+                                 stack.\r
+  @retval EFI_ACCESS_DENIED      The pop operation underflowed the stack\r
+  @retval EFI_INVALID_PARAMETER  Syntax error with the Expression\r
+\r
+**/\r
+EFI_STATUS\r
+EvaluateExpression (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN FORM_BROWSER_FORM     *Form,\r
+  IN OUT FORM_EXPRESSION   *Expression\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  LIST_ENTRY              *Link;\r
+  EXPRESSION_OPCODE       *OpCode;\r
+  FORM_BROWSER_STATEMENT  *Question;\r
+  FORM_BROWSER_STATEMENT  *Question2;\r
+  UINT16                  Index;\r
+  EFI_HII_VALUE           Data1;\r
+  EFI_HII_VALUE           Data2;\r
+  EFI_HII_VALUE           Data3;\r
+  FORM_EXPRESSION         *RuleExpression;\r
+  EFI_HII_VALUE           *Value;\r
+  INTN                    Result;\r
+  CHAR16                  *StrPtr;\r
+  UINT32                  TempValue;\r
+\r
+  //\r
+  // Always reset the stack before evaluating an Expression\r
+  //\r
+  ResetExpressionStack ();\r
+\r
+  Expression->Result.Type = EFI_IFR_TYPE_OTHER;\r
+\r
+  Link = GetFirstNode (&Expression->OpCodeListHead);\r
+  while (!IsNull (&Expression->OpCodeListHead, Link)) {\r
+    OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);\r
+\r
+    Link = GetNextNode (&Expression->OpCodeListHead, Link);\r
+\r
+    ZeroMem (&Data1, sizeof (EFI_HII_VALUE));\r
+    ZeroMem (&Data2, sizeof (EFI_HII_VALUE));\r
+    ZeroMem (&Data3, sizeof (EFI_HII_VALUE));\r
+\r
+    Value = &Data3;\r
+    Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
+    Status = EFI_SUCCESS;\r
+\r
+    switch (OpCode->Operand) {\r
+    //\r
+    // Built-in functions\r
+    //\r
+    case EFI_IFR_EQ_ID_VAL_OP:\r
+      Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
+      if (Question == NULL) {\r
+        return EFI_NOT_FOUND;\r
+      }\r
+\r
+      Result = CompareHiiValue (&Question->HiiValue, &OpCode->Value, NULL);\r
+      if (Result == EFI_INVALID_PARAMETER) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+      Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
+      break;\r
+\r
+    case EFI_IFR_EQ_ID_ID_OP:\r
+      Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
+      if (Question == NULL) {\r
+        return EFI_NOT_FOUND;\r
+      }\r
+\r
+      Question2 = IdToQuestion (FormSet, Form, OpCode->QuestionId2);\r
+      if (Question2 == NULL) {\r
+        return EFI_NOT_FOUND;\r
+      }\r
+\r
+      Result = CompareHiiValue (&Question->HiiValue, &Question2->HiiValue, FormSet->HiiHandle);\r
+      if (Result == EFI_INVALID_PARAMETER) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+      Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
+      break;\r
+\r
+    case EFI_IFR_EQ_ID_LIST_OP:\r
+      Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
+      if (Question == NULL) {\r
+        return EFI_NOT_FOUND;\r
+      }\r
+\r
+      Value->Value.b = FALSE;\r
+      for (Index =0; Index < OpCode->ListLength; Index++) {\r
+        if (Question->HiiValue.Value.u16 == OpCode->ValueList[Index]) {\r
+          Value->Value.b = TRUE;\r
+          break;\r
+        }\r
+      }\r
+      break;\r
+\r
+    case EFI_IFR_DUP_OP:\r
+      Status = PopExpression (Value);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      Status = PushExpression (Value);\r
+      break;\r
+\r
+    case EFI_IFR_QUESTION_REF1_OP:\r
+    case EFI_IFR_THIS_OP:\r
+      Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
+      if (Question == NULL) {\r
+        return EFI_NOT_FOUND;\r
+      }\r
+\r
+      Value = &Question->HiiValue;\r
+      break;\r
+\r
+    case EFI_IFR_QUESTION_REF3_OP:\r
+      if (OpCode->DevicePath == 0) {\r
+        //\r
+        // EFI_IFR_QUESTION_REF3\r
+        // Pop an expression from the expression stack\r
+        //\r
+        Status = PopExpression (Value);\r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
+        }\r
+\r
+        //\r
+        // Validate the expression value\r
+        //\r
+        if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {\r
+          return EFI_NOT_FOUND;\r
+        }\r
+\r
+        Question = IdToQuestion (FormSet, Form, Value->Value.u16);\r
+        if (Question == NULL) {\r
+          return EFI_NOT_FOUND;\r
+        }\r
+\r
+        //\r
+        // push the questions' value on to the expression stack\r
+        //\r
+        Value = &Question->HiiValue;\r
+      } else {\r
+        //\r
+        // BUGBUG: push 0 for EFI_IFR_QUESTION_REF3_2 and EFI_IFR_QUESTION_REF3_3,\r
+        // since it is impractical to evaluate the value of a Question in another\r
+        // Hii Package list.\r
+        //\r
+        ZeroMem (Value, sizeof (EFI_HII_VALUE));\r
+      }\r
+      break;\r
+\r
+    case EFI_IFR_RULE_REF_OP:\r
+      //\r
+      // Find expression for this rule\r
+      //\r
+      RuleExpression = RuleIdToExpression (Form, OpCode->RuleId);\r
+      if (RuleExpression == NULL) {\r
+        return EFI_NOT_FOUND;\r
+      }\r
+\r
+      //\r
+      // Evaluate this rule expression\r
+      //\r
+      Status = EvaluateExpression (FormSet, Form, RuleExpression);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      Value = &RuleExpression->Result;\r
+      break;\r
+\r
+    case EFI_IFR_STRING_REF1_OP:\r
+      Value->Type = EFI_IFR_TYPE_STRING;\r
+      Value->Value.string = OpCode->Value.Value.string;\r
+      break;\r
+\r
+    //\r
+    // Constant\r
+    //\r
+    case EFI_IFR_TRUE_OP:\r
+    case EFI_IFR_FALSE_OP:\r
+    case EFI_IFR_ONE_OP:\r
+    case EFI_IFR_ONES_OP:\r
+    case EFI_IFR_UINT8_OP:\r
+    case EFI_IFR_UINT16_OP:\r
+    case EFI_IFR_UINT32_OP:\r
+    case EFI_IFR_UINT64_OP:\r
+    case EFI_IFR_UNDEFINED_OP:\r
+    case EFI_IFR_VERSION_OP:\r
+    case EFI_IFR_ZERO_OP:\r
+      Value = &OpCode->Value;\r
+      break;\r
+\r
+    //\r
+    // unary-op\r
+    //\r
+    case EFI_IFR_LENGTH_OP:\r
+      Status = PopExpression (Value);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+      if (Value->Type != EFI_IFR_TYPE_STRING) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
+      if (StrPtr == NULL) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+      Value->Value.u64 = StrLen (StrPtr);\r
+      gBS->FreePool (StrPtr);\r
+      break;\r
+\r
+    case EFI_IFR_NOT_OP:\r
+      Status = PopExpression (Value);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+      if (Value->Type != EFI_IFR_TYPE_BOOLEAN) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+      Value->Value.b = (BOOLEAN) (!Value->Value.b);\r
+      break;\r
+\r
+    case EFI_IFR_QUESTION_REF2_OP:\r
+      //\r
+      // Pop an expression from the expression stack\r
+      //\r
+      Status = PopExpression (Value);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      //\r
+      // Validate the expression value\r
+      //\r
+      if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {\r
+        return EFI_NOT_FOUND;\r
+      }\r
+\r
+      Question = IdToQuestion (FormSet, Form, Value->Value.u16);\r
+      if (Question == NULL) {\r
+        return EFI_NOT_FOUND;\r
+      }\r
+\r
+      Value = &Question->HiiValue;\r
+      break;\r
+\r
+    case EFI_IFR_STRING_REF2_OP:\r
+      //\r
+      // Pop an expression from the expression stack\r
+      //\r
+      Status = PopExpression (Value);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      //\r
+      // Validate the expression value\r
+      //\r
+      if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {\r
+        return EFI_NOT_FOUND;\r
+      }\r
+\r
+      Value->Type = EFI_IFR_TYPE_STRING;\r
+      StrPtr = GetToken (Value->Value.u16, FormSet->HiiHandle);\r
+      if (StrPtr == NULL) {\r
+        //\r
+        // If String not exit, push an empty string\r
+        //\r
+        Value->Value.string = NewString (gEmptyString, FormSet->HiiHandle);\r
+      } else {\r
+        Index = (UINT16) Value->Value.u64;\r
+        Value->Value.string = Index;\r
+        gBS->FreePool (StrPtr);\r
+      }\r
+      break;\r
+\r
+    case EFI_IFR_TO_BOOLEAN_OP:\r
+      //\r
+      // Pop an expression from the expression stack\r
+      //\r
+      Status = PopExpression (Value);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      //\r
+      // Convert an expression to a Boolean\r
+      //\r
+      if (Value->Type <= EFI_IFR_TYPE_DATE) {\r
+        //\r
+        // When converting from an unsigned integer, zero will be converted to\r
+        // FALSE and any other value will be converted to TRUE.\r
+        //\r
+        Value->Value.b = (BOOLEAN) ((Value->Value.u64) ? TRUE : FALSE);\r
+\r
+        Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
+      } else if (Value->Type == EFI_IFR_TYPE_STRING) {\r
+        //\r
+        // When converting from a string, if case-insensitive compare\r
+        // with "true" is True, then push True. If a case-insensitive compare\r
+        // with "false" is True, then push False.\r
+        //\r
+        StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
+        if (StrPtr == NULL) {\r
+          return EFI_INVALID_PARAMETER;\r
+        }\r
+\r
+        if ((StrCmp (StrPtr, L"true") == 0) || (StrCmp (StrPtr, L"false") == 0)){\r
+          Value->Value.b = TRUE;\r
+        } else {\r
+          Value->Value.b = FALSE;\r
+        }\r
+        gBS->FreePool (StrPtr);\r
+        Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
+      }\r
+      break;\r
+\r
+    case EFI_IFR_TO_STRING_OP:\r
+      Status = IfrToString (FormSet, OpCode->Format, Value);\r
+      break;\r
+\r
+    case EFI_IFR_TO_UINT_OP:\r
+      Status = IfrToUint (FormSet, Value);\r
+      break;\r
+\r
+    case EFI_IFR_TO_LOWER_OP:\r
+    case EFI_IFR_TO_UPPER_OP:\r
+      Status = InitializeUnicodeCollationProtocol ();\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      Status = PopExpression (Value);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      if (Value->Type != EFI_IFR_TYPE_STRING) {\r
+        return EFI_UNSUPPORTED;\r
+      }\r
+\r
+      StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
+      if (StrPtr == NULL) {\r
+        return EFI_NOT_FOUND;\r
+      }\r
+\r
+      if (OpCode->Operand == EFI_IFR_TO_LOWER_OP) {\r
+        mUnicodeCollation->StrLwr (mUnicodeCollation, StrPtr);\r
+      } else {\r
+        mUnicodeCollation->StrUpr (mUnicodeCollation, StrPtr);\r
+      }\r
+      Value->Value.string = NewString (StrPtr, FormSet->HiiHandle);\r
+      gBS->FreePool (StrPtr);\r
+      break;\r
+\r
+    case EFI_IFR_BITWISE_NOT_OP:\r
+      //\r
+      // Pop an expression from the expression stack\r
+      //\r
+      Status = PopExpression (Value);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+      if (Value->Type > EFI_IFR_TYPE_DATE) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+      Value->Value.u64 = ~Value->Value.u64;\r
+      break;\r
+\r
+    //\r
+    // binary-op\r
+    //\r
+    case EFI_IFR_ADD_OP:\r
+    case EFI_IFR_SUBTRACT_OP:\r
+    case EFI_IFR_MULTIPLY_OP:\r
+    case EFI_IFR_DIVIDE_OP:\r
+    case EFI_IFR_MODULO_OP:\r
+    case EFI_IFR_BITWISE_AND_OP:\r
+    case EFI_IFR_BITWISE_OR_OP:\r
+    case EFI_IFR_SHIFT_LEFT_OP:\r
+    case EFI_IFR_SHIFT_RIGHT_OP:\r
+      //\r
+      // Pop an expression from the expression stack\r
+      //\r
+      Status = PopExpression (&Data2);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+      if (Data2.Type > EFI_IFR_TYPE_DATE) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      //\r
+      // Pop another expression from the expression stack\r
+      //\r
+      Status = PopExpression (&Data1);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+      if (Data1.Type > EFI_IFR_TYPE_DATE) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+\r
+      switch (OpCode->Operand) {\r
+        case EFI_IFR_ADD_OP:\r
+          Value->Value.u64 = Data1.Value.u64 + Data2.Value.u64;\r
+          break;\r
+\r
+        case EFI_IFR_SUBTRACT_OP:\r
+          Value->Value.u64 = Data1.Value.u64 - Data2.Value.u64;\r
+          break;\r
+\r
+        case EFI_IFR_MULTIPLY_OP:\r
+          Value->Value.u64 = MultU64x32 (Data1.Value.u64, (UINT32) Data2.Value.u64);\r
+          break;\r
+\r
+        case EFI_IFR_DIVIDE_OP:\r
+          Value->Value.u64 = DivU64x32 (Data1.Value.u64, (UINT32) Data2.Value.u64);\r
+          break;\r
+\r
+        case EFI_IFR_MODULO_OP:\r
+          DivU64x32Remainder  (Data1.Value.u64, (UINT32) Data2.Value.u64, &TempValue);\r
+          Value->Value.u64 = TempValue;\r
+          break;\r
+\r
+        case EFI_IFR_BITWISE_AND_OP:\r
+          Value->Value.u64 = Data1.Value.u64 & Data2.Value.u64;\r
+          break;\r
+\r
+        case EFI_IFR_BITWISE_OR_OP:\r
+          Value->Value.u64 = Data1.Value.u64 | Data2.Value.u64;\r
+          break;\r
+\r
+        case EFI_IFR_SHIFT_LEFT_OP:\r
+          Value->Value.u64 = LShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64);\r
+          break;\r
+\r
+        case EFI_IFR_SHIFT_RIGHT_OP:\r
+          Value->Value.u64 = RShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64);\r
+          break;\r
+\r
+        default:\r
+          break;\r
+      }\r
+      break;\r
+\r
+    case EFI_IFR_AND_OP:\r
+    case EFI_IFR_OR_OP:\r
+      //\r
+      // Two Boolean operator\r
+      //\r
+      Status = PopExpression (&Data2);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+      if (Data2.Type != EFI_IFR_TYPE_BOOLEAN) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      //\r
+      // Pop another expression from the expression stack\r
+      //\r
+      Status = PopExpression (&Data1);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+      if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      if (OpCode->Operand == EFI_IFR_AND_OP) {\r
+        Value->Value.b = (BOOLEAN) (Data1.Value.b && Data2.Value.b);\r
+      } else {\r
+        Value->Value.b = (BOOLEAN) (Data1.Value.b || Data2.Value.b);\r
+      }\r
+      break;\r
+\r
+    case EFI_IFR_EQUAL_OP:\r
+    case EFI_IFR_NOT_EQUAL_OP:\r
+    case EFI_IFR_GREATER_EQUAL_OP:\r
+    case EFI_IFR_GREATER_THAN_OP:\r
+    case EFI_IFR_LESS_EQUAL_OP:\r
+    case EFI_IFR_LESS_THAN_OP:\r
+      //\r
+      // Compare two integer, string, boolean or date/time\r
+      //\r
+      Status = PopExpression (&Data2);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+      if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && Data2.Type != EFI_IFR_TYPE_STRING) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      //\r
+      // Pop another expression from the expression stack\r
+      //\r
+      Status = PopExpression (&Data1);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      Result = CompareHiiValue (&Data1, &Data2, FormSet->HiiHandle);\r
+      if (Result == EFI_INVALID_PARAMETER) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      switch (OpCode->Operand) {\r
+      case EFI_IFR_EQUAL_OP:\r
+        Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
+        break;\r
+\r
+      case EFI_IFR_NOT_EQUAL_OP:\r
+        Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
+        break;\r
+\r
+      case EFI_IFR_GREATER_EQUAL_OP:\r
+        Value->Value.b = (BOOLEAN) ((Result >= 0) ? TRUE : FALSE);\r
+        break;\r
+\r
+      case EFI_IFR_GREATER_THAN_OP:\r
+        Value->Value.b = (BOOLEAN) ((Result > 0) ? TRUE : FALSE);\r
+        break;\r
+\r
+      case EFI_IFR_LESS_EQUAL_OP:\r
+        Value->Value.b = (BOOLEAN) ((Result <= 0) ? TRUE : FALSE);\r
+        break;\r
+\r
+      case EFI_IFR_LESS_THAN_OP:\r
+        Value->Value.b = (BOOLEAN) ((Result < 0) ? TRUE : FALSE);\r
+        break;\r
+\r
+      default:\r
+        break;\r
+      }\r
+      break;\r
+\r
+    case EFI_IFR_MATCH_OP:\r
+      Status = IfrMatch (FormSet, Value);\r
+      break;\r
+\r
+    case EFI_IFR_CATENATE_OP:\r
+      Status = IfrCatenate (FormSet, Value);\r
+      break;\r
+\r
+    //\r
+    // ternary-op\r
+    //\r
+    case EFI_IFR_CONDITIONAL_OP:\r
+      //\r
+      // Pop third expression from the expression stack\r
+      //\r
+      Status = PopExpression (&Data3);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      //\r
+      // Pop second expression from the expression stack\r
+      //\r
+      Status = PopExpression (&Data2);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      //\r
+      // Pop first expression from the expression stack\r
+      //\r
+      Status = PopExpression (&Data1);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+      if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      if (Data1.Value.b) {\r
+        Value = &Data3;\r
+      } else {\r
+        Value = &Data2;\r
+      }\r
+      break;\r
+\r
+    case EFI_IFR_FIND_OP:\r
+      Status = IfrFind (FormSet, OpCode->Format, Value);\r
+      break;\r
+\r
+    case EFI_IFR_MID_OP:\r
+      Status = IfrMid (FormSet, Value);\r
+      break;\r
+\r
+    case EFI_IFR_TOKEN_OP:\r
+      Status = IfrToken (FormSet, Value);\r
+      break;\r
+\r
+    case EFI_IFR_SPAN_OP:\r
+      Status = IfrSpan (FormSet, OpCode->Flags, Value);\r
+      break;\r
+\r
+    default:\r
+      break;\r
+    }\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    Status = PushExpression (Value);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Pop the final result from expression stack\r
+  //\r
+  Value = &Data1;\r
+  Status = PopExpression (Value);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // After evaluating an expression, there should be only one value left on the expression stack\r
+  //\r
+  if (PopExpression (Value) != EFI_ACCESS_DENIED) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  CopyMem (&Expression->Result, Value, sizeof (EFI_HII_VALUE));\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserExpression.h b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserExpression.h
new file mode 100644 (file)
index 0000000..c4ed930
--- /dev/null
@@ -0,0 +1,101 @@
+/** @file\r
+  Internal Function and Macro defintions for IFR Expression evaluation used in Ifr Parsing. This header file should only\r
+  be included by UefiIfrParserExpression.c and UefiIfrParser.c\r
+\r
+  Copyright (c) 2008, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _HII_THUNK_UEFI_IFR_PARSER_EXPRESSION_\r
+#define _HII_THUNK_UEFI_IFR_PARSER_EXPRESSION_\r
+\r
+/**\r
+  Reset stack pointer to begin of the stack.\r
+\r
+  None.\r
+\r
+  @return None.\r
+\r
+**/\r
+VOID\r
+ResetScopeStack (\r
+  VOID\r
+  )\r
+;\r
+\r
+/**\r
+  Push an Operand onto the Stack\r
+\r
+  @param  Operand                Operand to push.\r
+\r
+  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
+  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the\r
+                                 stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PushScope (\r
+  IN UINT8   Operand\r
+  )\r
+;\r
+\r
+\r
+/**\r
+  Pop an Operand from the Stack\r
+\r
+  @param  Operand                Operand to pop.\r
+\r
+  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
+  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the\r
+                                 stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PopScope (\r
+  OUT UINT8     *Operand\r
+  )\r
+;\r
+\r
+/**\r
+  Zero extend integer/boolean/date/time to UINT64 for comparing.\r
+\r
+  @param  Value                  HII Value to be converted.\r
+\r
+  @return None.\r
+\r
+**/\r
+VOID\r
+ExtendValueToU64 (\r
+  IN  EFI_HII_VALUE   *Value\r
+  )\r
+;\r
+\r
+/**\r
+  Compare two Hii value.\r
+\r
+  @param  Value1                 Expression value to compare on left-hand\r
+  @param  Value2                 Expression value to compare on right-hand\r
+  @param  HiiHandle              Only required for string compare\r
+\r
+  @retval EFI_INVALID_PARAMETER  Could not perform comparation on two values\r
+  @retval 0                      Two operators equeal\r
+  @retval 0                      Value1 is greater than Value2\r
+  @retval 0                      Value1 is less than Value2\r
+\r
+**/\r
+INTN\r
+CompareHiiValue (\r
+  IN  EFI_HII_VALUE   *Value1,\r
+  IN  EFI_HII_VALUE   *Value2,\r
+  IN  EFI_HII_HANDLE  HiiHandle OPTIONAL\r
+  )\r
+;\r
+\r
+#endif\r
diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserExpressionInternal.h b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserExpressionInternal.h
new file mode 100644 (file)
index 0000000..fea10aa
--- /dev/null
@@ -0,0 +1,42 @@
+/** @file\r
+  Internal Function and Macro defintions for IFR Expression evaluation used in Ifr Parsing. This header file should only\r
+  be included by UefiIfrParserExpression.c\r
+\r
+  Copyright (c) 2008, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _HII_THUNK_UEFI_IFR_PARSER_EXPRESSION_INTERNAL_\r
+#define _HII_THUNK_UEFI_IFR_PARSER_EXPRESSION_INTERNAL_\r
+\r
+//\r
+// Incremental size of stack for expression\r
+//\r
+#define EXPRESSION_STACK_SIZE_INCREMENT    0x100\r
+\r
+\r
+FORM_BROWSER_STATEMENT *\r
+IdToQuestion (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN FORM_BROWSER_FORM     *Form,\r
+  IN UINT16                QuestionId\r
+  )\r
+;\r
+\r
+\r
+FORM_EXPRESSION *\r
+IdToExpression (\r
+  IN FORM_BROWSER_FORM  *Form,\r
+  IN UINT8              RuleId\r
+  )\r
+;\r
+\r
\r
+#endif\r
diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserInternal.h b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserInternal.h
new file mode 100644 (file)
index 0000000..3e153e8
--- /dev/null
@@ -0,0 +1,56 @@
+/** @file\r
+  Internal Function and Macro defintions for IFR parsing. This header file should only\r
+  be included by UefiIfrParser.c\r
+\r
+  Copyright (c) 2008, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _HII_THUNK_UEFI_IFR_PARSER_INTERNAL_\r
+#define _HII_THUNK_UEFI_IFR_PARSER_INTERNAL_\r
+\r
+#include <Protocol/UnicodeCollation.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/IfrSupportLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+#include <MdeModuleHii.h>\r
+\r
+//\r
+// Extern Variables\r
+//\r
+extern CONST EFI_HII_DATABASE_PROTOCOL            *mHiiDatabase;\r
+extern CONST EFI_HII_FONT_PROTOCOL                *mHiiFontProtocol;\r
+extern CONST EFI_HII_IMAGE_PROTOCOL               *mHiiImageProtocol;\r
+extern CONST EFI_HII_STRING_PROTOCOL              *mHiiStringProtocol;\r
+extern CONST EFI_HII_CONFIG_ROUTING_PROTOCOL      *mHiiConfigRoutingProtocol;\r
+\r
+//\r
+// Incremental string lenght of ConfigRequest\r
+//\r
+#define CONFIG_REQUEST_STRING_INCREMENTAL  1024\r
+\r
+\r
+#define EFI_SPECIFICATION_ERRATA_VERSION   0\r
+\r
+#define EFI_IFR_SPECIFICATION_VERSION  \\r
+        ((((EFI_SPECIFICATION_VERSION) >> 8) & 0xff00) | \\r
+         (((EFI_SPECIFICATION_VERSION) & 0xf) << 4) | \\r
+         ((EFI_SPECIFICATION_ERRATA_VERSION) & 0xf))\r
+\r
+extern EFI_GUID          gZeroGuid;\r
+\r
+#endif\r