Port DriverSample.inf, HiiDatabase.inf and SetupBrowser.inf
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 29 Jun 2007 15:14:00 +0000 (15:14 +0000)
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 29 Jun 2007 15:14:00 +0000 (15:14 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2915 6f19259b-4bc3-4df7-8a09-765794883524

38 files changed:
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc
IntelFrameworkModulePkg/Universal/DriverSampleDxe/CommonHeader.h [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.c [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.dxs [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.h [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.inf [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.msa [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/DriverSampleDxe/Inventory.vfr [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/DriverSampleDxe/InventoryStrings.uni [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/DriverSampleDxe/NVDataStruc.h [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/DriverSampleDxe/Vfr.vfr [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/DriverSampleDxe/VfrStrings.uni [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/CommonHeader.h [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Fonts.c [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Forms.c [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.c [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.dxs [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.h [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.inf [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.msa [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Keyboard.c [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Package.c [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Strings.c [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/SetupBrowserDxe/Boolean.c [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/SetupBrowserDxe/Colors.h [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/SetupBrowserDxe/CommonHeader.h [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/SetupBrowserDxe/InputHandler.c [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/SetupBrowserDxe/Presentation.c [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/SetupBrowserDxe/Print.c [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/SetupBrowserDxe/Print.h [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/SetupBrowserDxe/Setup.c [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/SetupBrowserDxe/Setup.h [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/SetupBrowserDxe/SetupBrowser.inf [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/SetupBrowserDxe/SetupBrowser.msa [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/SetupBrowserDxe/SetupBrowserStr.uni [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/SetupBrowserDxe/Ui.c [new file with mode: 0644]
IntelFrameworkModulePkg/Universal/SetupBrowserDxe/Ui.h [new file with mode: 0644]

index 1853aa66b295b4d85fb0b6cf2876cdc85e3d9f98..1382f9da88a7a1e7afbb673d4e1e8994a3d6854d 100644 (file)
   DxeServicesTableLib|${WORKSPACE}/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf\r
   FvbServiceLib|${WORKSPACE}/MdeModulePkg/Library/EdkFvbServiceLib/EdkFvbServiceLib.inf\r
   ReportStatusCodeLib|${WORKSPACE}/IntelFrameworkPkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf\r
+  HiiLibFramework|$(WORKSPACE)/IntelFrameworkPkg/Library/HiiLibFramework/HiiLib.inf\r
+  IfrSupportLibFramework|$(WORKSPACE)/IntelFrameworkPkg/Library/IfrSupportLibFramework/IfrSupportLib.inf\r
   PciIncompatibleDeviceSupportLib|${WORKSPACE}/IntelFrameworkModulePkg/Library/PciIncompatibleDeviceSupportLib/PciIncompatibleDeviceSupportLib.inf\r
 \r
+\r
 [LibraryClasses.common.DXE_RUNTIME_DRIVER]\r
   HobLib|${WORKSPACE}/MdePkg/Library/DxeHobLib/DxeHobLib.inf\r
   MemoryAllocationLib|${WORKSPACE}/MdePkg/Library/DxeMemoryAllocationLib/DxeMemoryAllocationLib.inf\r
@@ -91,6 +94,8 @@
   UefiRuntimeLib|${WORKSPACE}/MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf\r
   UefiRuntimeServicesTableLib|${WORKSPACE}/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf\r
   ReportStatusCodeLib|${WORKSPACE}/IntelFrameworkPkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf\r
+  HiiLibFramework|$(WORKSPACE)/IntelFrameworkPkg/Library/HiiLibFramework/HiiLib.inf\r
+  IfrSupportLibFramework|$(WORKSPACE)/IntelFrameworkPkg/Library/IfrSupportLibFramework/IfrSupportLib.inf\r
 \r
 ################################################################################\r
 #\r
   $(WORKSPACE)\IntelFrameworkModulePkg\Universal\DataHub\DataHubStdErr\Dxe\DataHubStdErr.inf\r
   $(WORKSPACE)\IntelFrameworkModulePkg\Universal\StatusCode\Dxe\DxeStatusCode.inf\r
   $(WORKSPACE)\IntelFrameworkModulePkg\Universal\StatusCode\Pei\PeiStatusCode.inf\r
+  $(WORKSPACE)\IntelFrameworkModulePkg\Universal\HiiDataBaseDxe\HiiDatabase.inf\r
+ # $(WORKSPACE)\IntelFrameworkModulePkg\Universal\UserInterface\SetupBrowser\Dxe\SetupBrowser.inf\r
+#  $(WORKSPACE)\IntelFrameworkModulePkg\Universal\DriverSampleDxe\DriverSample.inf\r
+\r
diff --git a/IntelFrameworkModulePkg/Universal/DriverSampleDxe/CommonHeader.h b/IntelFrameworkModulePkg/Universal/DriverSampleDxe/CommonHeader.h
new file mode 100644 (file)
index 0000000..da9f608
--- /dev/null
@@ -0,0 +1,42 @@
+/**@file\r
+  Common header file shared by all source files.\r
+\r
+  This file includes package header files, library classes and protocol, PPI & GUID definitions.\r
+\r
+  Copyright (c) 2006 - 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
+   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
+#ifndef __COMMON_HEADER_H_\r
+#define __COMMON_HEADER_H_\r
+\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <PiDxe.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Protocol/FormCallback.h>\r
+#include <Protocol/FrameworkHii.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/IfrSupportLibFramework.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/HiiLibFramework.h>\r
+\r
+#endif\r
diff --git a/IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.c b/IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.c
new file mode 100644 (file)
index 0000000..7415643
--- /dev/null
@@ -0,0 +1,598 @@
+/*++\r
+Copyright (c) 2006 - 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
+  DriverSample.c\r
+\r
+Abstract:\r
+\r
+  This is an example of how a driver might export data to the HII protocol to be \r
+  later utilized by the Setup Protocol\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "DriverSample.h"\r
+\r
+#define DISPLAY_ONLY_MY_ITEM  0x0001\r
+\r
+#define STRING_PACK_GUID \\r
+  { \\r
+    0x8160a85f, 0x934d, 0x468b, { 0xa2, 0x35, 0x72, 0x89, 0x59, 0x14, 0xf6, 0xfc } \\r
+  }\r
+\r
+EFI_GUID  mFormSetGuid    = FORMSET_GUID;\r
+EFI_GUID  mStringPackGuid = STRING_PACK_GUID; \r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+DriverCallback (\r
+  IN EFI_FORM_CALLBACK_PROTOCOL       *This,\r
+  IN UINT16                           KeyValue,\r
+  IN EFI_IFR_DATA_ARRAY               *Data,\r
+  OUT EFI_HII_CALLBACK_PACKET         **Packet\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This is the function that is called to provide results data to the driver.  This data\r
+  consists of a unique key which is used to identify what data is either being passed back\r
+  or being asked for. \r
+\r
+Arguments:\r
+\r
+  KeyValue -        A unique value which is sent to the original exporting driver so that it\r
+                    can identify the type of data to expect.  The format of the data tends to\r
+                    vary based on the op-code that geerated the callback.\r
+\r
+  Data -            A pointer to the data being sent to the original exporting driver.\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  EFI_CALLBACK_INFO       *Private;\r
+  EFI_HII_UPDATE_DATA     *UpdateData;\r
+  UINT8                   *Location;\r
+  EFI_HII_CALLBACK_PACKET *DataPacket;\r
+  UINT16                  Value;\r
+  CHAR16                  VariableName[40];\r
+  STATIC UINT16           QuestionId = 0;\r
+  IFR_OPTION              *OptionList;\r
+  UINTN                   Index;\r
+  MyIfrNVData             NVStruc;\r
+\r
+  Private     = EFI_CALLBACK_INFO_FROM_THIS (This);\r
+\r
+  //\r
+  // This should tell me the first offset AFTER the end of the compiled NV map\r
+  // If op-code results are not going to be saved to NV locations ensure the QuestionId\r
+  // is beyond the end of the NVRAM mapping.\r
+  //\r
+  if (QuestionId == 0) {\r
+    QuestionId = sizeof (MyIfrNVData);\r
+  }\r
+\r
+  ZeroMem (VariableName, (sizeof (CHAR16) * 40));\r
+\r
+  switch (KeyValue) {\r
+  case 0x0001:\r
+    //\r
+    // Create a small boot order list\r
+    //\r
+    QuestionId = (UINT16) ((UINTN) (&NVStruc.BootOrder) - (UINTN) (&NVStruc));\r
+\r
+    //\r
+    // Need some memory for OptionList. Allow for up to 8 options.\r
+    //\r
+    OptionList = AllocateZeroPool (sizeof (IFR_OPTION) * 8);\r
+    ASSERT (OptionList != NULL);\r
+\r
+    //\r
+    // Allocate space for creation of Buffer\r
+    //\r
+    UpdateData = AllocateZeroPool (0x1000);\r
+    ASSERT (UpdateData != NULL);\r
+\r
+    //\r
+    // Remove all the op-codes starting with Label 0x2222 to next Label (second label is for convenience\r
+    // so we don't have to keep track of how many op-codes we added or subtracted.  The rules for removal\r
+    // of op-codes are simply that the removal will always stop as soon as a label or the end of a form is\r
+    // encountered.  Therefore, giving a large obnoxious count such as below takes care of other complexities.\r
+    //\r
+    UpdateData->DataCount = 0xFF;\r
+\r
+    //\r
+    // Delete set of op-codes\r
+    //\r
+    Private->Hii->UpdateForm (\r
+                    Private->Hii,\r
+                    Private->RegisteredHandle,\r
+                    (EFI_FORM_LABEL) 0x2222,\r
+                    FALSE,  // If we aren't adding, we are deleting\r
+                    UpdateData\r
+                    );\r
+\r
+    //\r
+    // Create 3 options\r
+    //\r
+    for (Index = 0; Index < 3; Index++) {\r
+      OptionList[Index].StringToken = (UINT16) (STR_BOOT_OPTION1 + Index);\r
+      OptionList[Index].Value       = (UINT16) (Index + 1);\r
+      OptionList[Index].Flags       = RESET_REQUIRED;\r
+    }\r
+\r
+    CreateOrderedListOpCode (\r
+      QuestionId,                               // Question ID\r
+      8,                                        // Max Entries\r
+      (UINT16) STRING_TOKEN (STR_BOOT_OPTIONS), // Token value for the Prompt\r
+      (UINT16) STRING_TOKEN (STR_NULL_STRING),  // Token value for the Help\r
+      OptionList,\r
+      3,\r
+      &UpdateData->Data                         // Buffer location to place op-codes\r
+      );\r
+\r
+    //\r
+    // For one-of/ordered lists commands, they really consist of 2 op-codes (a header and a footer)\r
+    // Each option within a one-of/ordered list is also an op-code\r
+    // So this example has 5 op-codes it is adding since we have a one-of header + 3 options + one-of footer\r
+    //\r
+    UpdateData->DataCount = 0x5;\r
+\r
+    //\r
+    // Add one op-code\r
+    //\r
+    Private->Hii->UpdateForm (\r
+                    Private->Hii,\r
+                    Private->RegisteredHandle,\r
+                    (EFI_FORM_LABEL) 0x2222,\r
+                    TRUE,\r
+                    UpdateData\r
+                    );\r
+\r
+    FreePool (UpdateData);\r
+    FreePool (OptionList);\r
+    break;\r
+\r
+  case 0x0002:\r
+    //\r
+    // Create a large boot order list\r
+    //\r
+    QuestionId = (UINT16) ((UINTN) (&NVStruc.BootOrder) - (UINTN) (&NVStruc));\r
+\r
+    //\r
+    // Need some memory for OptionList. Allow for up to 8 options.\r
+    //\r
+    OptionList = AllocateZeroPool (sizeof (IFR_OPTION) * 8);\r
+    ASSERT (OptionList != NULL);\r
+\r
+    //\r
+    // Allocate space for creation of Buffer\r
+    //\r
+    UpdateData = AllocateZeroPool (0x1000);\r
+    ASSERT (UpdateData != NULL);\r
+\r
+    //\r
+    // Remove all the op-codes starting with Label 0x2222 to next Label (second label is for convenience\r
+    // so we don't have to keep track of how many op-codes we added or subtracted\r
+    //\r
+    UpdateData->DataCount = 0xFF;\r
+\r
+    //\r
+    // Delete one op-code\r
+    //\r
+    Private->Hii->UpdateForm (\r
+                    Private->Hii,\r
+                    Private->RegisteredHandle,\r
+                    (EFI_FORM_LABEL) 0x2222,\r
+                    FALSE,\r
+                    UpdateData\r
+                    );\r
+\r
+    //\r
+    // Create 4 options\r
+    //\r
+    for (Index = 0; Index < 4; Index++) {\r
+      OptionList[Index].StringToken = (UINT16) (STR_BOOT_OPTION1 + Index);\r
+      OptionList[Index].Value       = (UINT16) (Index + 1);\r
+      OptionList[Index].Flags       = RESET_REQUIRED;\r
+    }\r
+\r
+    CreateOrderedListOpCode (\r
+      QuestionId,                               // Question ID\r
+      8,                                        // Max Entries\r
+      (UINT16) STRING_TOKEN (STR_BOOT_OPTIONS), // Token value for the Prompt\r
+      (UINT16) STRING_TOKEN (STR_NULL_STRING),  // Token value for the Help\r
+      OptionList,\r
+      4,\r
+      &UpdateData->Data                         // Buffer location to place op-codes\r
+      );\r
+\r
+    //\r
+    // For one-of commands, they really consist of 2 op-codes (a header and a footer)\r
+    // Each option within a one-of is also an op-code\r
+    // So this example has 6 op-codes it is adding since we have a one-of header + 4 options + one-of footer\r
+    //\r
+    UpdateData->DataCount = 0x6;\r
+\r
+    //\r
+    // Add one op-code\r
+    //\r
+    Private->Hii->UpdateForm (\r
+                    Private->Hii,\r
+                    Private->RegisteredHandle,\r
+                    (EFI_FORM_LABEL) 0x2222,\r
+                    TRUE,\r
+                    UpdateData\r
+                    );\r
+\r
+    FreePool (UpdateData);\r
+    FreePool (OptionList);\r
+    break;\r
+\r
+  case 0x1234:\r
+    //\r
+    // Allocate space for creation of Buffer\r
+    //\r
+    QuestionId = (UINT16) ((UINTN) (&NVStruc.DynamicCheck) - (UINTN) (&NVStruc));\r
+    UpdateData = AllocateZeroPool (0x1000);\r
+    ASSERT (UpdateData != NULL);\r
+\r
+    Location                        = (UINT8 *) &UpdateData->Data;\r
+\r
+    UpdateData->FormSetUpdate       = TRUE;\r
+    UpdateData->FormCallbackHandle  = (EFI_PHYSICAL_ADDRESS) (UINTN) Private->CallbackHandle;\r
+    UpdateData->FormUpdate          = FALSE;\r
+    UpdateData->FormTitle           = 0;\r
+    UpdateData->DataCount           = 2;\r
+\r
+    CreateGotoOpCode (\r
+      1,\r
+      STR_GOTO_FORM1,                                   // Token value for the Prompt\r
+      0,                                                // Goto Help\r
+      0,                                                // Flags\r
+      0,                                                // Key\r
+      &UpdateData->Data                                 // Buffer location to place op-codes\r
+      );\r
+\r
+    Location = Location + ((EFI_IFR_OP_HEADER *) &UpdateData->Data)->Length;\r
+\r
+    CreateCheckBoxOpCode (\r
+      QuestionId,                                       // Question ID\r
+      1,                                                // Data width (BOOLEAN = 1)\r
+      (UINT16) STRING_TOKEN (STR_CHECK_DYNAMIC_PROMPT), // Token value for the Prompt\r
+      (UINT16) STRING_TOKEN (STR_CHECK_DYNAMIC_HELP),   // Token value for the Help\r
+      EFI_IFR_FLAG_INTERACTIVE,                         // Flags\r
+      0x1236,   // Key\r
+      Location  // Buffer location to place op-codes\r
+      );\r
+\r
+    Private->Hii->UpdateForm (\r
+                    Private->Hii,\r
+                    Private->RegisteredHandle,\r
+                    (EFI_FORM_LABEL) 0x1234,\r
+                    TRUE,\r
+                    UpdateData\r
+                    );\r
+\r
+    FreePool (UpdateData);\r
+    QuestionId++;\r
+    break;\r
+\r
+  case 0x1235:\r
+    //\r
+    // Allocate space for creation of Buffer\r
+    //\r
+    UpdateData = AllocateZeroPool (0x1000);\r
+    ASSERT (UpdateData != NULL);\r
+\r
+    //\r
+    // Initialize DataPacket with information intended to remove all\r
+    // previously created op-codes in the dynamic page\r
+    //\r
+    UpdateData->FormSetUpdate       = FALSE;\r
+    UpdateData->FormCallbackHandle  = 0;\r
+    UpdateData->FormUpdate          = FALSE;\r
+    UpdateData->FormTitle           = 0;\r
+    //\r
+    // Unlikely to be more than 0xff op-codes in the dynamic page to remove\r
+    //\r
+    UpdateData->DataCount           = 0xff;\r
+    UpdateData->Data = NULL;\r
+\r
+    //\r
+    // Remove all op-codes from dynamic page\r
+    //\r
+    Private->Hii->UpdateForm (\r
+                    Private->Hii,\r
+                    Private->RegisteredHandle,\r
+                    (EFI_FORM_LABEL) 0x1234,  // Label 0x1234\r
+                    FALSE,                    // Remove Op-codes (will never remove form/endform)\r
+                    UpdateData                // Significant value is UpdateData->DataCount\r
+                    );\r
+\r
+    UpdateData->FormSetUpdate       = FALSE;\r
+    UpdateData->FormCallbackHandle  = 0;\r
+    UpdateData->FormUpdate          = FALSE;\r
+    UpdateData->FormTitle           = 0;\r
+    UpdateData->DataCount           = 1;\r
+\r
+    CreateGotoOpCode (\r
+      1,\r
+      STR_GOTO_FORM1,                         // Token value for the Prompt\r
+      0,                                      // Goto Help\r
+      0,                                      // Flags\r
+      0,                                      // Key\r
+      &UpdateData->Data                       // Buffer location to place op-codes\r
+      );\r
+\r
+    Private->Hii->UpdateForm (\r
+                    Private->Hii,\r
+                    Private->RegisteredHandle,\r
+                    (EFI_FORM_LABEL) 0x1234,\r
+                    TRUE,\r
+                    UpdateData\r
+                    );\r
+\r
+    FreePool (UpdateData);\r
+    break;\r
+\r
+  case 0x1236:\r
+    //\r
+    // If I hit the checkbox, I enter this case statement...\r
+    //\r
+    //\r
+    // Since I am returning an error (for test purposes) I need to pass in the string for the error\r
+    // I will allocate space for the return value.  If an error occurs (which is the case) I can simply return\r
+    // an error and fill in the string parameter, otherwise, I will return information in the DataArray structure.\r
+    // The browser will free this packet structure\r
+    //\r
+    *Packet = AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET) + sizeof (SAMPLE_STRING) + 2);\r
+    ASSERT (*Packet != NULL);\r
+\r
+    //\r
+    // Assign the buffer address to DataPacket\r
+    //\r
+    DataPacket = *Packet;\r
+\r
+    StrCpy (DataPacket->String, (CHAR16 *) SAMPLE_STRING);\r
+    return EFI_DEVICE_ERROR;\r
+\r
+  case 0x1237:\r
+\r
+    *Packet = AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET) + 2);\r
+    ASSERT (*Packet != NULL);\r
+\r
+    //\r
+    // Assign the buffer address to DataPacket\r
+    //\r
+    DataPacket                        = *Packet;\r
+\r
+    DataPacket->DataArray.EntryCount  = 1;\r
+    DataPacket->DataArray.NvRamMap    = NULL;\r
+    ((EFI_IFR_DATA_ENTRY *) (&DataPacket->DataArray + 1))->Flags = EXIT_REQUIRED;\r
+    break;\r
+\r
+  case 0x1555:\r
+    Value = 0x0001;\r
+    UnicodeSPrint (VariableName, 0x80, (CHAR16 *) L"%d", VAR_EQ_TEST_NAME);\r
+\r
+    gRT->SetVariable (\r
+          VariableName,\r
+          &mFormSetGuid,\r
+          EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+          2,\r
+          (VOID *) &Value\r
+          );\r
+    break;\r
+\r
+  case 0x1556:\r
+    Value = 0x1000;\r
+    UnicodeSPrint (VariableName, 0x80, (CHAR16 *) L"%d", VAR_EQ_TEST_NAME);\r
+\r
+    gRT->SetVariable (\r
+          VariableName,\r
+          &mFormSetGuid,\r
+          EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+          2,\r
+          (VOID *) &Value\r
+          );\r
+    break;\r
+\r
+  case 0x1557:\r
+    Value = 0x0000;\r
+    UnicodeSPrint (VariableName, 0x80, (CHAR16 *) L"%d", VAR_EQ_TEST_NAME);\r
+\r
+    gRT->SetVariable (\r
+          VariableName,\r
+          &mFormSetGuid,\r
+          EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+          2,\r
+          (VOID *) &Value\r
+          );\r
+    break;\r
+\r
+  default:\r
+    break;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DriverSampleInit (\r
+  IN EFI_HANDLE                   ImageHandle,\r
+  IN EFI_SYSTEM_TABLE             *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  EFI_HII_PROTOCOL    *Hii;\r
+  //\r
+  //  EFI_FORM_BROWSER_PROTOCOL       *FormConfig;\r
+  //\r
+  EFI_HII_PACKAGES    *PackageList;\r
+  EFI_HII_HANDLE      HiiHandle;\r
+  STRING_REF          TokenToUpdate;\r
+  STRING_REF          TokenToUpdate2;\r
+  STRING_REF          TokenToUpdate3;\r
+  CHAR16              *NewString;\r
+  EFI_HII_UPDATE_DATA *UpdateData;\r
+  EFI_CALLBACK_INFO   *CallbackInfo;\r
+  EFI_HANDLE          Handle;\r
+  EFI_SCREEN_DESCRIPTOR   Screen;\r
+\r
+  ZeroMem (&Screen, sizeof (EFI_SCREEN_DESCRIPTOR));\r
+\r
+  gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Screen.RightColumn, &Screen.BottomRow);\r
+\r
+  //\r
+  // Remove 3 characters from top and bottom\r
+  //\r
+  Screen.TopRow     = 3;\r
+  Screen.BottomRow  = Screen.BottomRow - 3;\r
+\r
+  //\r
+  // There should only be one HII protocol\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiHiiProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &Hii\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;;\r
+  }\r
+\r
+  CallbackInfo = AllocatePool (sizeof (EFI_CALLBACK_INFO));\r
+  if (CallbackInfo == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  CallbackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE;\r
+  CallbackInfo->Hii       = Hii;\r
+\r
+  //\r
+  // This example does not implement worker functions for the NV accessor functions.  Only a callback evaluator\r
+  //\r
+  CallbackInfo->DriverCallback.NvRead   = NULL;\r
+  CallbackInfo->DriverCallback.NvWrite  = NULL;\r
+  CallbackInfo->DriverCallback.Callback = DriverCallback;\r
+\r
+  //\r
+  // Install protocol interface\r
+  //\r
+  Handle = NULL;\r
+  Status = gBS->InstallProtocolInterface (\r
+                  &Handle,\r
+                  &gEfiFormCallbackProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  &CallbackInfo->DriverCallback\r
+                  );\r
+\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  CallbackInfo->CallbackHandle  = Handle;\r
+\r
+  PackageList                   = PreparePackages (1, &mStringPackGuid, DriverSampleStrings);\r
+  Status                        = Hii->NewPack (Hii, PackageList, &HiiHandle);\r
+  FreePool (PackageList);\r
+\r
+  PackageList = PreparePackages (1, &mStringPackGuid, InventoryBin);\r
+  Status      = Hii->NewPack (Hii, PackageList, &HiiHandle);\r
+  FreePool (PackageList);\r
+\r
+  PackageList = PreparePackages (1, &mStringPackGuid, VfrBin);\r
+  Status      = Hii->NewPack (Hii, PackageList, &HiiHandle);\r
+  FreePool (PackageList);\r
+\r
+  CallbackInfo->RegisteredHandle = HiiHandle;\r
+\r
+  //\r
+  // Very simple example of how one would update a string that is already\r
+  // in the HII database\r
+  //\r
+  TokenToUpdate = (STRING_REF) STR_CPU_STRING2;\r
+  NewString     = (CHAR16 *) L"700 Mhz";\r
+\r
+  Hii->NewString (Hii, NULL, HiiHandle, &TokenToUpdate, NewString);\r
+\r
+  //\r
+  // Add a string - if 0 will be updated with new Token number\r
+  //\r
+  TokenToUpdate = (STRING_REF) 0;\r
+\r
+  //\r
+  // Add a string - if 0 will be updated with new Token number\r
+  //\r
+  TokenToUpdate2 = (STRING_REF) 0;\r
+\r
+  //\r
+  // Add a string - if 0 will be updated with new Token number\r
+  //\r
+  TokenToUpdate3 = (STRING_REF) 0;\r
+\r
+  Hii->NewString (Hii, NULL, HiiHandle, &TokenToUpdate, (CHAR16 *) L"Desired Speed");\r
+  Hii->NewString (Hii, NULL, HiiHandle, &TokenToUpdate2, (CHAR16 *) L"5 Thz");\r
+  Hii->NewString (Hii, NULL, HiiHandle, &TokenToUpdate3, (CHAR16 *) L"This is next year's desired speed - right?");\r
+\r
+  //\r
+  // Allocate space for creation of Buffer\r
+  //\r
+  UpdateData = AllocateZeroPool (0x1000);\r
+  ASSERT (UpdateData != NULL);\r
+\r
+  //\r
+  // Flag update pending in FormSet\r
+  //\r
+  UpdateData->FormSetUpdate = TRUE;\r
+  //\r
+  // Register CallbackHandle data for FormSet\r
+  //\r
+  UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) CallbackInfo->CallbackHandle;\r
+  UpdateData->FormUpdate  = FALSE;\r
+  UpdateData->FormTitle   = 0;\r
+  UpdateData->DataCount   = 1;\r
+\r
+  CreateTextOpCode (TokenToUpdate, TokenToUpdate2, TokenToUpdate3, 0, 0, &UpdateData->Data);\r
+\r
+  Hii->UpdateForm (Hii, HiiHandle, (EFI_FORM_LABEL) 100, TRUE, UpdateData);\r
+\r
+  FreePool (UpdateData);\r
+\r
+  //\r
+  // Example of how to display only the item we sent to HII\r
+  //\r
+  if (DISPLAY_ONLY_MY_ITEM == 0x0001) {\r
+    //\r
+    // Have the browser pull out our copy of the data, and only display our data\r
+    //\r
+    //    Status = FormConfig->SendForm (FormConfig, TRUE, HiiHandle, NULL, NULL, NULL, &Screen, NULL);\r
+    //\r
+  } else {\r
+    //\r
+    // Have the browser pull out all the data in the HII Database and display it.\r
+    //\r
+    //    Status = FormConfig->SendForm (FormConfig, TRUE, 0, NULL, NULL, NULL, NULL, NULL);\r
+    //\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.dxs b/IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.dxs
new file mode 100644 (file)
index 0000000..d88f568
--- /dev/null
@@ -0,0 +1,31 @@
+/*++\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
+  DriverSample.dxs\r
+\r
+Abstract:\r
+\r
+  Dependency expression source file.\r
+  \r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <DxeDepex.h>\r
+\r
+DEPENDENCY_START\r
+  EFI_SIMPLE_TEXT_OUT_PROTOCOL_GUID\r
+DEPENDENCY_END\r
diff --git a/IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.h b/IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.h
new file mode 100644 (file)
index 0000000..ba3a50d
--- /dev/null
@@ -0,0 +1,64 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  DriverSample.h\r
+\r
+Abstract:\r
+\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _DRIVER_SAMPLE_H\r
+#define _DRIVER_SAMPLE_H\r
+\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "NVDataStruc.h"\r
+\r
+//\r
+// This is the generated header file which includes whatever needs to be exported (strings + IFR)\r
+//\r
+\r
+extern UINT8  VfrBin[];\r
+//\r
+// extern UINT8 VfrStringsStr[];\r
+//\r
+extern UINT8  InventoryBin[];\r
+//\r
+// extern UINT8 InventoryStringsStr[];\r
+//\r
+extern UINT8  DriverSampleStrings[];\r
+\r
+#define SAMPLE_STRING               L"This is an error!"\r
+\r
+#define EFI_CALLBACK_INFO_SIGNATURE EFI_SIGNATURE_32 ('C', 'l', 'b', 'k')\r
+\r
+typedef struct {\r
+  UINTN                       Signature;\r
+  EFI_HANDLE                  CallbackHandle;\r
+  EFI_FORM_CALLBACK_PROTOCOL  DriverCallback;\r
+  UINT16                      *KeyList;\r
+  VOID                        *FormBuffer;\r
+  EFI_HII_HANDLE              RegisteredHandle;\r
+  EFI_HII_PROTOCOL            *Hii;\r
+} EFI_CALLBACK_INFO;\r
+\r
+#define EFI_CALLBACK_INFO_FROM_THIS(a)  CR (a, EFI_CALLBACK_INFO, DriverCallback, EFI_CALLBACK_INFO_SIGNATURE)\r
+\r
+#endif\r
diff --git a/IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.inf b/IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.inf
new file mode 100644 (file)
index 0000000..ea26648
--- /dev/null
@@ -0,0 +1,111 @@
+#/** @file\r
+# Component description file for DriverSample module.\r
+#\r
+# This is an example driver to introduce how to export data to the HII protocol to be later utilized by the Setup Protocol.\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\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
+#  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
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DriverSample\r
+  FILE_GUID                      = FE3542FE-C1D3-4EF8-657C-8048606FF670\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = DriverSampleInit\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+  DriverSample.dxs\r
+  DriverSample.h\r
+  NVDataStruc.h\r
+  DriverSample.c\r
+  Vfr.vfr\r
+  VfrStrings.uni\r
+  Inventory.vfr\r
+  InventoryStrings.uni\r
+  CommonHeader.h\r
+\r
+\r
+################################################################################\r
+#\r
+# Includes Section - list of Include locations that are required for\r
+#                    this module.\r
+#\r
+################################################################################\r
+\r
+[Includes]\r
+  $(WORKSPACE)/IntelFrameworkPkg/Include/Library\r
+  $(WORKSPACE)/MdePkg/Include/Library\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  IntelFrameworkPkg/IntelFrameworkPkg.dec\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+#                         this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+  HiiLibFramework\r
+  MemoryAllocationLib\r
+  BaseMemoryLib\r
+  IfrSupportLibFramework\r
+  PrintLib\r
+  BaseLib\r
+  UefiDriverEntryPoint\r
+  DebugLib\r
+  UefiRuntimeServicesTableLib\r
+  UefiBootServicesTableLib\r
+\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+#                           that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+  gEfiFormCallbackProtocolGuid                  # PROTOCOL ALWAYS_PRODUCED\r
+  gEfiHiiProtocolGuid                           # PROTOCOL ALWAYS_CONSUMED\r
+\r
diff --git a/IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.msa b/IntelFrameworkModulePkg/Universal/DriverSampleDxe/DriverSample.msa
new file mode 100644 (file)
index 0000000..4c96b5e
--- /dev/null
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">\r
+  <MsaHeader>\r
+    <ModuleName>DriverSample</ModuleName>\r
+    <ModuleType>DXE_DRIVER</ModuleType>\r
+    <GuidValue>FE3542FE-C1D3-4EF8-657C-8048606FF670</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Component description file for DriverSample module.</Abstract>\r
+    <Description>This is an example driver to introduce how to export data to the HII protocol to be later utilized by the Setup Protocol. </Description>\r
+    <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+    <License>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
+      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.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>DriverSample</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiRuntimeServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED" RecommendedInstanceGuid="bda39d3a-451b-4350-8266-81ab10fa0523">\r
+      <Keyword>DebugLib</Keyword>\r
+      <HelpText>Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg.</HelpText>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverEntryPoint</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED" RecommendedInstanceGuid="a86fbfca-0183-4eeb-aa8a-762e3b7da1f3">\r
+      <Keyword>PrintLib</Keyword>\r
+      <HelpText>Recommended libary Instance is BasePrintLib instance in MdePkg.</HelpText>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>EdkIfrSupportLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>MemoryAllocationLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>HiiLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>InventoryStrings.uni</Filename>\r
+    <Filename>Inventory.vfr</Filename>\r
+    <Filename>VfrStrings.uni</Filename>\r
+    <Filename>Vfr.vfr</Filename>\r
+    <Filename>DriverSample.c</Filename>\r
+    <Filename>NVDataStruc.h</Filename>\r
+    <Filename>DriverSample.h</Filename>\r
+    <Filename>DriverSample.dxs</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+    <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiHiiProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_PRODUCED">\r
+      <ProtocolCName>gEfiFormCallbackProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <HiiPackages>\r
+    <HiiPackage Usage="ALWAYS_PRODUCED">\r
+      <HiiCName>DriverSampleStrings</HiiCName>\r
+      <HelpText>EFI_HII_STRING type string package from UNI file.</HelpText>\r
+    </HiiPackage>\r
+    <HiiPackage Usage="ALWAYS_PRODUCED">\r
+      <HiiCName>InventoryBin</HiiCName>\r
+      <HelpText>EFI_HII_IFR type form package from VFR file.</HelpText>\r
+    </HiiPackage>\r
+    <HiiPackage Usage="ALWAYS_PRODUCED">\r
+      <HiiCName>VfrBin</HiiCName>\r
+      <HelpText>EFI_HII_IFR type form package from VFR file.</HelpText>\r
+    </HiiPackage>\r
+  </HiiPackages>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+    <Extern>\r
+      <ModuleEntryPoint>DriverSampleInit</ModuleEntryPoint>\r
+    </Extern>\r
+  </Externs>\r
+</ModuleSurfaceArea>
\ No newline at end of file
diff --git a/IntelFrameworkModulePkg/Universal/DriverSampleDxe/Inventory.vfr b/IntelFrameworkModulePkg/Universal/DriverSampleDxe/Inventory.vfr
new file mode 100644 (file)
index 0000000..434da17
--- /dev/null
@@ -0,0 +1,128 @@
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+// *++\r
+//\r
+// Copyright (c) 2006, 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
+//   Inventory.vfr \r
+// \r
+// Abstract:\r
+// \r
+//   Sample Inventory Data.\r
+// \r
+// Revision History: \r
+// \r
+// --*/\r
+\r
+#include "DriverSampleStrDefs.h"\r
+\r
+#define INVENTORY_GUID    { 0xb3f56470, 0x6141, 0x4621, { 0x8f, 0x19, 0x70, 0x4e, 0x57, 0x7a, 0xa9, 0xe8 } }\r
\r
+formset \r
+  guid     = INVENTORY_GUID,\r
+  title    = STRING_TOKEN(STR_INV_FORM_SET_TITLE),\r
+  help     = STRING_TOKEN(STR_INV_FORM_SET_HELP),\r
+  class    = 0x04,      \r
+  subclass = 0x03,\r
+\r
+  form formid = 1,\r
+       title  = STRING_TOKEN(STR_INV_FORM1_TITLE);  // note formid is a variable (for readability) (UINT16) - also added Form to the line to signify the Op-Code\r
+  \r
+       text \r
+      help   = STRING_TOKEN(STR_INV_VERSION_HELP),\r
+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT),\r
+           text   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      flags  = 0,\r
+      key    = 0;\r
+\r
+       text \r
+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT2),\r
+           text   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      flags  = 0,\r
+      key    = 0;\r
+\r
+       text \r
+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT3),\r
+           text   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      flags  = 0,\r
+      key    = 0;\r
+\r
+       text \r
+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT4),\r
+           text   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      flags  = 0,\r
+      key    = 0;\r
+\r
+    subtitle text = STRING_TOKEN(STR_INV_EMPTY_STRING);\r
+\r
+       text \r
+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT5),\r
+           text   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      flags  = 0,\r
+      key    = 0;\r
+\r
+       text \r
+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT6),\r
+           text   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      flags  = 0,\r
+      key    = 0;\r
+\r
+       text \r
+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT7),\r
+           text   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      flags  = 0,\r
+      key    = 0;\r
+\r
+       text \r
+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT8),\r
+           text   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      flags  = 0,\r
+      key    = 0;\r
+\r
+       text \r
+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT9),\r
+           text   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      flags  = 0,\r
+      key    = 0;\r
+\r
+       text \r
+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT10),\r
+           text   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      flags  = 0,\r
+      key    = 0;\r
+\r
+       text \r
+      help   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      text   = STRING_TOKEN(STR_INV_VERSION_TEXT11),\r
+           text   = STRING_TOKEN(STR_INV_EMPTY_STRING),\r
+      flags  = 0,\r
+      key    = 0;\r
+\r
+    subtitle text = STRING_TOKEN(STR_INV_EMPTY_STRING);\r
+\r
+    subtitle text = STRING_TOKEN(STR_INV_VERSION_TEXT12);\r
+\r
+  endform;\r
+\r
+endformset;\r
diff --git a/IntelFrameworkModulePkg/Universal/DriverSampleDxe/InventoryStrings.uni b/IntelFrameworkModulePkg/Universal/DriverSampleDxe/InventoryStrings.uni
new file mode 100644 (file)
index 0000000..4946b4a
Binary files /dev/null and b/IntelFrameworkModulePkg/Universal/DriverSampleDxe/InventoryStrings.uni differ
diff --git a/IntelFrameworkModulePkg/Universal/DriverSampleDxe/NVDataStruc.h b/IntelFrameworkModulePkg/Universal/DriverSampleDxe/NVDataStruc.h
new file mode 100644 (file)
index 0000000..5b51e94
--- /dev/null
@@ -0,0 +1,67 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  NVDataStruc.h \r
\r
+Abstract:\r
\r
+  NVData structure used by the sample driver\r
\r
+Revision History: \r
\r
+--*/\r
+\r
+#ifndef _NVDATASTRUC_H\r
+#define _NVDATASTRUC_H\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#define FORMSET_GUID \\r
+  { \\r
+    0xA04A27f4, 0xDF00, 0x4D42, { 0xB5, 0x52, 0x39, 0x51, 0x13, 0x02, 0x11, 0x3D } \\r
+  }\r
+\r
+#define INVENTORY_GUID \\r
+  { \\r
+    0xb3f56470, 0x6141, 0x4621, { 0x8f, 0x19, 0x70, 0x4e, 0x57, 0x7a, 0xa9, 0xe8 } \\r
+  }\r
+\r
+#define VAR_EQ_TEST_NAME  0x100\r
+\r
+#pragma pack(1)\r
+typedef struct {\r
+  UINT16  WhatIsThePassword[20];\r
+  UINT16  WhatIsThePassword2[20];\r
+  UINT16  MyStringData[20];\r
+  UINT16  SomethingHiddenForHtml;\r
+  UINT8   HowOldAreYouInYearsManual;\r
+  UINT16  HowTallAreYouManual;\r
+  UINT8   HowOldAreYouInYears;\r
+  UINT16  HowTallAreYou;\r
+  UINT8   MyFavoriteNumber;\r
+  UINT8   TestLateCheck;\r
+  UINT8   TestLateCheck2;\r
+  UINT8   QuestionAboutTreeHugging;\r
+  UINT8   ChooseToActivateNuclearWeaponry;\r
+  UINT8   SuppressGrayOutSomething;\r
+  UINT8   OrderedList[8];\r
+  UINT8   BootOrder[8];\r
+  UINT8   BootOrderLarge;\r
+  UINT8   DynamicCheck;\r
+} MyIfrNVData;\r
+#pragma pack()\r
+\r
+#endif\r
diff --git a/IntelFrameworkModulePkg/Universal/DriverSampleDxe/Vfr.vfr b/IntelFrameworkModulePkg/Universal/DriverSampleDxe/Vfr.vfr
new file mode 100644 (file)
index 0000000..ee8df04
--- /dev/null
@@ -0,0 +1,627 @@
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+// *++\r
+//\r
+// Copyright (c) 2006, 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
+//   Vfr.vfr \r
+// \r
+// Abstract:\r
+// \r
+//   Sample Setup formset\r
+// \r
+// Revision History: \r
+// \r
+// --*/\r
+\r
+\r
+#include "DriverSampleStrDefs.h" \r
\r
+#include "NVDataStruc.h"\r
+\r
+\r
+typedef struct {\r
+  UINT8         Field8;\r
+  UINT16        Field16;\r
+  UINT8         OrderedList[3];\r
+} MyIfrNVData2;\r
+\r
+typedef struct {\r
+  UINT8         Field8;\r
+  UINT16        Field16;\r
+  UINT8         OrderedList[3];\r
+} MyIfrNVData3;\r
+\r
+#define MY_TEXT_KEY                 0x100 \r
+\r
+#define LABEL_1_VALUE               0x01\r
+#define LABEL_2_VALUE               0x1000\r
+#define LABEL_UPDATE_BBS            0x2222\r
+#define LABEL_END_UPDATE_BBS        0x2223\r
+\r
+formset \r
+  guid     = FORMSET_GUID,\r
+  title    = STRING_TOKEN(STR_FORM_SET_TITLE),  \r
+  help     = STRING_TOKEN(STR_FORM_SET_TITLE_HELP), \r
+  class    = 0x10,      \r
+  subclass = 0,\r
+\r
+  varstore MyIfrNVData2, key = 0x1234, name = MY_DATA2, guid = FORMSET_GUID;\r
+\r
+\r
+  varstore MyIfrNVData3, key = 0x4321, name = MY_DATA3, guid = FORMSET_GUID;\r
+\r
+  form formid = 1,\r
+       title  = STRING_TOKEN(STR_FORM1_TITLE);  // note formid is a variable (for readability) (UINT16) - also added Form to the line to signify the Op-Code\r
+  \r
+    subtitle text = STRING_TOKEN(STR_SUBTITLE_TEXT);\r
+\r
+    subtitle text = STRING_TOKEN(STR_SUBTITLE_TEXT2);\r
+\r
+    banner \r
+      title = STRING_TOKEN(STR_BANNER_TITLE),\r
+      line  1,\r
+      align center;\r
+    \r
+    banner \r
+      title = STRING_TOKEN(STR_BANNER_TITLE),\r
+      line  2,\r
+      align left;\r
+\r
+    banner \r
+      title = STRING_TOKEN(STR_BANNER_TITLE),\r
+      line  2,\r
+      align right;\r
+\r
+       text \r
+      help   = STRING_TOKEN(STR_TEXT_HELP),  \r
+      text   = STRING_TOKEN(STR_CPU_STRING),\r
+           text   = STRING_TOKEN(STR_CPU_STRING2),\r
+      flags  = 0,\r
+      key    = 0;\r
+\r
+       text \r
+      help   = STRING_TOKEN(STR_EXIT_TEXT),  \r
+      text   = STRING_TOKEN(STR_EXIT_TEXT), \r
+           text   = STRING_TOKEN(STR_EXIT_TEXT),\r
+      flags  = INTERACTIVE,\r
+      key    = 0x1237;\r
+\r
+    oneof varid  = MyIfrNVData.SuppressGrayOutSomething,\r
+      prompt      = STRING_TOKEN(STR_ONE_OF_PROMPT),\r
+      help        = STRING_TOKEN(STR_ONE_OF_HELP),  \r
+      option text = STRING_TOKEN(STR_ONE_OF_TEXT4), value = 0x0, flags = 0; \r
+      option text = STRING_TOKEN(STR_ONE_OF_TEXT5), value = 0x1, flags = 0;\r
+      option text = STRING_TOKEN(STR_ONE_OF_TEXT6), value = 0x2, flags = DEFAULT;\r
+    endoneof;\r
+\r
+    oneof varid  = MyIfrNVData.BootOrderLarge,\r
+      prompt      = STRING_TOKEN(STR_ONE_OF_PROMPT),\r
+      help        = STRING_TOKEN(STR_ONE_OF_HELP),  \r
+      option text = STRING_TOKEN(STR_BOOT_ORDER1), value = 0x0, flags = INTERACTIVE, key = 1; \r
+      option text = STRING_TOKEN(STR_BOOT_ORDER2), value = 0x1, flags = INTERACTIVE | DEFAULT, key = 2;\r
+    endoneof;\r
+\r
+    grayoutif  ideqval MyIfrNVData.SuppressGrayOutSomething == 0x1;\r
+    suppressif ideqval MyIfrNVData.SuppressGrayOutSomething == 0x0;\r
+      label 0;\r
+      checkbox varid    = MyIfrNVData.ChooseToActivateNuclearWeaponry,\r
+              prompt   = STRING_TOKEN(STR_CHECK_BOX_PROMPT),\r
+              help     = STRING_TOKEN(STR_CHECK_BOX_HELP),  \r
+              flags    = 1,                  // Flags behavior for checkbox is overloaded so that it equals a DEFAULT value.  1 = ON, 0 = off\r
+              key      = 0,\r
+      endcheckbox;\r
+    endif;\r
+\r
+\r
+    //\r
+    // Ordered list: \r
+    //   sizeof(MyIfrNVData) storage must be UINT8 array, and\r
+    //   size written for the variable must be size of the entire\r
+    //   variable.\r
+    //\r
+    //\r
+    suppressif ideqval MyIfrNVData.SuppressGrayOutSomething == 0x0;\r
+      label LABEL_UPDATE_BBS;\r
+      orderedlist\r
+                varid       = MyIfrNVData.BootOrder,\r
+                prompt      = STRING_TOKEN(STR_BOOT_OPTIONS),\r
+                help        = STRING_TOKEN(STR_NULL_STRING),\r
+                option text = STRING_TOKEN(STR_BOOT_OPTION2), value = 2, flags = RESET_REQUIRED;\r
+                option text = STRING_TOKEN(STR_BOOT_OPTION1), value = 1, flags = RESET_REQUIRED;\r
+                option text = STRING_TOKEN(STR_BOOT_OPTION3), value = 3, flags = RESET_REQUIRED;\r
+                option text = STRING_TOKEN(STR_BOOT_OPTION4), value = 4, flags = RESET_REQUIRED;\r
+      endlist;      \r
+      label LABEL_END_UPDATE_BBS;\r
+    endif;\r
\r
+    suppressif ideqval MyIfrNVData.SuppressGrayOutSomething == 0x2;\r
+      orderedlist    \r
+        varid       = MyIfrNVData.OrderedList,\r
+        prompt      = STRING_TOKEN(STR_TEST_OPCODE),\r
+        help        = STRING_TOKEN(STR_TEXT_HELP),  \r
+        option text = STRING_TOKEN(STR_ONE_OF_TEXT1), value = 4, flags = RESET_REQUIRED;\r
+        option text = STRING_TOKEN(STR_ONE_OF_TEXT2), value = 3, flags = RESET_REQUIRED;\r
+        option text = STRING_TOKEN(STR_ONE_OF_TEXT3), value = 2, flags = RESET_REQUIRED;\r
+        option text = STRING_TOKEN(STR_TEXT_HELP),    value = 1, flags = RESET_REQUIRED;\r
+      endlist;\r
+    endif;\r
+     \r
+    label 100;\r
+\r
+    goto 0x1234, \r
+      prompt  = STRING_TOKEN(STR_GOTO_DYNAMIC), \r
+      help    = STRING_TOKEN(STR_GOTO_HELP),\r
+      flags   = INTERACTIVE, \r
+      key     = 0x1234;\r
+\r
+    goto 0x1234, \r
+      prompt  = STRING_TOKEN(STR_GOTO_DYNAMIC2), \r
+      help    = STRING_TOKEN(STR_GOTO_HELP),\r
+      flags   = INTERACTIVE, \r
+      key     = 0x1235;\r
+    \r
+    //\r
+    // VARSTORE tests\r
+    //\r
+    // Till now, been using variable NvData (must be reserved)\r
+    // now we do a varselect for variable NvData3\r
+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),\r
+      ideqid MyIfrNVData3.Field16 == MyIfrNVData3.Field16\r
+    endif;\r
+    // now we do a varselect_pair for variable NvData2 and NvData3\r
+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),\r
+      ideqid MyIfrNVData2.Field16 == MyIfrNVData3.Field16\r
+    endif;\r
+\r
+\r
+    // now we do a varselect_pair for variable NvData and NvData2\r
+//    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),\r
+//      ideqid MyIfrNVData2.Field16 == MyIfrNVData.TestLateCheck\r
+//    endif;\r
+\r
+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),\r
+      ideqid MyIfrNVData.TestLateCheck == MyIfrNVData.TestLateCheck2\r
+    endif;\r
+\r
+    oneof varid  = MyIfrNVData.TestLateCheck,\r
+      prompt      = STRING_TOKEN(STR_TEST_OPCODE),\r
+      help        = STRING_TOKEN(STR_ONE_OF_HELP),  \r
+      option text = STRING_TOKEN(STR_ONE_OF_TEXT1), value = 0, flags = LATE_CHECK | RESET_REQUIRED;\r
+      option text = STRING_TOKEN(STR_ONE_OF_TEXT2), value = 1, flags = LATE_CHECK | DEFAULT | RESET_REQUIRED;\r
+    endoneof;\r
+\r
+    oneof varid  = MyIfrNVData.TestLateCheck2,\r
+      prompt      = STRING_TOKEN(STR_TEST_OPCODE2),\r
+      help        = STRING_TOKEN(STR_ONE_OF_HELP),  \r
+      option text = STRING_TOKEN(STR_ONE_OF_TEXT1), value = 0, flags = LATE_CHECK | DEFAULT | RESET_REQUIRED;\r
+      option text = STRING_TOKEN(STR_ONE_OF_TEXT2), value = 1, flags = LATE_CHECK | RESET_REQUIRED;\r
+\r
+    endoneof;\r
+\r
+    oneof varid  = MyIfrNVData.QuestionAboutTreeHugging,\r
+      prompt      = STRING_TOKEN(STR_ONE_OF_PROMPT),\r
+      help        = STRING_TOKEN(STR_ONE_OF_HELP),  \r
+      option text = STRING_TOKEN(STR_ONE_OF_TEXT1), value = 0, flags = RESET_REQUIRED;\r
+      option text = STRING_TOKEN(STR_ONE_OF_TEXT2), value = 1, flags = DEFAULT | RESET_REQUIRED;\r
+      option text = STRING_TOKEN(STR_ONE_OF_TEXT3), value = 0x03, flags = RESET_REQUIRED;\r
+\r
+    endoneof;\r
+\r
+    string    varid    = MyIfrNVData.MyStringData,\r
+              prompt   = STRING_TOKEN(STR_MY_STRING_PROMPT2),\r
+              help     = STRING_TOKEN(STR_MY_STRING_HELP2),\r
+              flags    = INTERACTIVE,\r
+              key      = 0x1234,\r
+              minsize  = 6,\r
+              maxsize  = 0x14,\r
+    endstring; \r
+\r
+       text \r
+      help   = STRING_TOKEN(STR_GRAYOUT_TEST),  \r
+      text   = STRING_TOKEN(STR_GRAYOUT_TEST),\r
+           text   = STRING_TOKEN(STR_GRAYOUT_TEST),\r
+      flags  = INTERACTIVE,\r
+      key    = 0x1555;\r
+\r
+       text \r
+      help   = STRING_TOKEN(STR_SUPPRESS_TEST),  \r
+      text   = STRING_TOKEN(STR_SUPPRESS_TEST),\r
+           text   = STRING_TOKEN(STR_SUPPRESS_TEST),\r
+      flags  = INTERACTIVE,\r
+      key    = 0x1556;\r
+\r
+       text \r
+      help   = STRING_TOKEN(STR_CLEAR_TEST),  \r
+      text   = STRING_TOKEN(STR_CLEAR_TEST),\r
+           text   = STRING_TOKEN(STR_CLEAR_TEST),\r
+      flags  = INTERACTIVE,\r
+      key    = 0x1557;\r
+\r
+    grayoutif  vareqval var(VAR_EQ_TEST_NAME) == 0x1;\r
+    suppressif vareqval var(VAR_EQ_TEST_NAME) == 0x1000; \r
+      label 30;\r
+      checkbox varid    = MyIfrNVData.ChooseToActivateNuclearWeaponry,\r
+              prompt   = STRING_TOKEN(STR_CHECK_BOX_PROMPT),\r
+              help     = STRING_TOKEN(STR_CHECK_BOX_HELP),  \r
+              flags    = 1,\r
+              key      = 0,\r
+      endcheckbox;\r
+    endif;\r
+\r
+\r
+    numeric varid   = MyIfrNVData.HowOldAreYouInYearsManual, \r
+            prompt  = STRING_TOKEN(STR_NUMERIC_MANUAL_PROMPT),\r
+            help    = STRING_TOKEN(STR_NUMERIC_HELP0),\r
+            minimum = 0,\r
+            maximum = 0xf0,      // 0xf0 = 240 in decimal\r
+            step    = 0,         // Stepping of 0 equates to a manual entering\r
+                                 // of a value, otherwise it will auto-increment\r
+                                 // with a left/right arrow\r
+            default = 21, \r
+\r
+    endnumeric;\r
+\r
+    numeric varid   = MyIfrNVData.HowTallAreYouManual, \r
+            prompt  = STRING_TOKEN(STR_TALL_MANUAL_PROMPT),\r
+            help    = STRING_TOKEN(STR_NUMERIC_HELP1),\r
+            minimum = 0,\r
+            maximum = 300,\r
+            step    = 0,         // Stepping of 0 equates to a manual entering\r
+                                 // of a value, otherwise it will auto-increment\r
+                                 // with a left/right arrow\r
+            default = 175, \r
+\r
+    endnumeric;\r
+\r
+    inventory\r
+      help    = STRING_TOKEN(STR_INVENTORY_HELP),\r
+      text    = STRING_TOKEN(STR_INVENTORY_TEXT1),\r
+      text    = STRING_TOKEN(STR_INVENTORY_TEXT2);\r
+\r
+      \r
+    restore defaults,\r
+      formid  = 4,\r
+      prompt  = STRING_TOKEN(STR_RESTORE_DEFAULTS_PROMPT),\r
+      help    = STRING_TOKEN(STR_RESTORE_DEFAULTS_HELP),\r
+      flags   = 0,\r
+      key     = 0;\r
+\r
+    save defaults,\r
+      formid  = 4,\r
+      prompt  = STRING_TOKEN(STR_SAVE_DEFAULTS_PROMPT),\r
+      help    = STRING_TOKEN(STR_SAVE_DEFAULTS_HELP),\r
+      flags   = 0,\r
+      key     = 0;\r
+\r
+    // \r
+    // Case with no flags or key\r
+    //\r
+    save defaults,\r
+      formid  = 4,\r
+      prompt  = STRING_TOKEN(STR_SAVE_DEFAULTS_PROMPT),\r
+      help    = STRING_TOKEN(STR_SAVE_DEFAULTS_HELP);\r
+    //\r
+    // Case with no key\r
+    //\r
+    save defaults,\r
+      formid  = 4,\r
+      prompt  = STRING_TOKEN(STR_SAVE_DEFAULTS_PROMPT),\r
+      help    = STRING_TOKEN(STR_SAVE_DEFAULTS_HELP),\r
+      flags   = 0;\r
+    //\r
+    // Case with no flags\r
+    //\r
+    save defaults,\r
+      formid  = 4,\r
+      prompt  = STRING_TOKEN(STR_SAVE_DEFAULTS_PROMPT),\r
+      help    = STRING_TOKEN(STR_SAVE_DEFAULTS_HELP),\r
+      key     = 0;\r
+\r
+    label LABEL_2_VALUE;\r
+\r
+    grayoutif  ideqval MyIfrNVData.HowOldAreYouInYearsManual == 23 AND ideqval MyIfrNVData.SuppressGrayOutSomething == 0x1;\r
+    numeric varid   = MyIfrNVData.HowOldAreYouInYears,   \r
+            prompt  = STRING_TOKEN(STR_NUMERIC_PROMPT),\r
+            help    = STRING_TOKEN(STR_NUMERIC_HELP2),\r
+            minimum = 0,\r
+            maximum = 243,\r
+            step    = 3,\r
+            default = 18,\r
+\r
+    endnumeric;\r
+\r
+    label LABEL_1_VALUE;\r
+\r
+    //\r
+    // Numeric with no step or default specified\r
+    //\r
+    numeric varid   = MyIfrNVData.HowTallAreYou, \r
+            prompt  = STRING_TOKEN(STR_NUMERIC_PROMPT1),\r
+            help    = STRING_TOKEN(STR_NUMERIC_HELP3),\r
+            minimum = 0,\r
+            maximum = 190,\r
+    //        step    = 1,       // Stepping of 1 if not specified\r
+    //        default = minimum; // if not specified\r
+    endnumeric;\r
+    endif;\r
+\r
+    string    varid    = MyIfrNVData.MyStringData,\r
+              prompt   = STRING_TOKEN(STR_MY_STRING_PROMPT),\r
+              help     = STRING_TOKEN(STR_MY_STRING_HELP),\r
+              minsize  = 6,\r
+              maxsize  = 0x14,\r
+    endstring; \r
+        \r
+    password  varid    = MyIfrNVData.WhatIsThePassword,\r
+              prompt   = STRING_TOKEN(STR_PASSWORD_PROMPT),\r
+              help     = STRING_TOKEN(STR_PASSWORD_HELP),\r
+              minsize  = 6,\r
+              maxsize  = 20, // new opcode \r
+              encoding = 1,\r
+    endpassword; \r
+    password  varid    = MyIfrNVData.WhatIsThePassword2,\r
+              prompt   = STRING_TOKEN(STR_PASSWORD_PROMPT),\r
+              help     = STRING_TOKEN(STR_PASSWORD_HELP),\r
+              minsize  = 6,\r
+              maxsize  = 20, // new opcode \r
+              encoding = 1,\r
+    endpassword; \r
+    //\r
+    // Test with flags and key fields\r
+    //\r
+    password  varid    = MyIfrNVData.WhatIsThePassword,\r
+              prompt   = STRING_TOKEN(STR_PASSWORD_PROMPT),\r
+              help     = STRING_TOKEN(STR_PASSWORD_HELP),\r
+              flags    = INTERACTIVE,\r
+              key      = 0x2000,\r
+              minsize  = 6,\r
+              maxsize  = 20, // new opcode \r
+              encoding = 1,\r
+    endpassword;\r
+\r
+    goto 2, \r
+      prompt = STRING_TOKEN(STR_GOTO_FORM2), //SecondSetupPage  // this too has no end-op and basically it's a jump to a form ONLY\r
+      help   = STRING_TOKEN(STR_GOTO_HELP);\r
+\r
+    goto 3, \r
+      prompt = STRING_TOKEN(STR_GOTO_FORM3), //ThirdSetupPage  // this too has no end-op and basically it's a jump to a form ONLY\r
+      help   = STRING_TOKEN(STR_GOTO_HELP);\r
+\r
+  endform;\r
+\r
+  form formid = 2,               // SecondSetupPage, \r
+       title = STRING_TOKEN(STR_FORM2_TITLE);  // note formid is a variable (for readability) (UINT16) - also added Form to the line to signify the Op-Code\r
+\r
+\r
+    date    year varid  = Date.Year,    // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from\r
+            prompt      = STRING_TOKEN(STR_DATE_PROMPT),\r
+            help        = STRING_TOKEN(STR_DATE_YEAR_HELP),\r
+            minimum     = 1998,\r
+            maximum     = 2099,\r
+            step        = 1,\r
+            default     = 2004,\r
+\r
+            month varid = Date.Month,    // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from\r
+            prompt      = STRING_TOKEN(STR_DATE_PROMPT),\r
+            help        = STRING_TOKEN(STR_DATE_MONTH_HELP),\r
+            minimum     = 1,\r
+            maximum     = 12,\r
+            step        = 1,\r
+            default     = 1,\r
+\r
+            day varid   = Date.Day,          // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from\r
+            prompt      = STRING_TOKEN(STR_DATE_PROMPT),\r
+            help        = STRING_TOKEN(STR_DATE_DAY_HELP),\r
+            minimum     = 1,\r
+            maximum     = 31,\r
+            step        = 0x1,\r
+            default     = 1,\r
+\r
+    enddate;\r
+\r
+    time    hour varid  = Time.Hours,         // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from\r
+            prompt      = STRING_TOKEN(STR_TIME_PROMPT),\r
+            help        = STRING_TOKEN(STR_TIME_HOUR_HELP),\r
+            minimum     = 0,\r
+            maximum     = 23,\r
+            step        = 1,\r
+            default     = 0,\r
+\r
+            minute varid  = Time.Minutes,       // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from\r
+            prompt        = STRING_TOKEN(STR_TIME_PROMPT),\r
+            help          = STRING_TOKEN(STR_TIME_MINUTE_HELP),\r
+            minimum       = 0,\r
+            maximum       = 59,\r
+            step          = 1,\r
+            default       = 0,\r
+\r
+            second varid  = Time.Seconds,       // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from\r
+            prompt        = STRING_TOKEN(STR_TIME_PROMPT),\r
+            help          = STRING_TOKEN(STR_TIME_SECOND_HELP),\r
+            minimum       = 0,\r
+            maximum       = 59,\r
+            step          = 1,\r
+            default       = 0,\r
+\r
+    endtime;\r
+\r
+    date    year varid  = Date.Year,    // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from\r
+            prompt      = STRING_TOKEN(STR_DATE_PROMPT),\r
+            help        = STRING_TOKEN(STR_DATE_YEAR_HELP),\r
+            minimum     = 1939,\r
+            maximum     = 2101,\r
+            step        = 1,\r
+            default     = 1964,\r
+\r
+            month varid = Date.Month,    // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from\r
+            prompt      = STRING_TOKEN(STR_DATE_PROMPT),\r
+            help        = STRING_TOKEN(STR_DATE_MONTH_HELP),\r
+            minimum     = 1,\r
+            maximum     = 12,\r
+            step        = 1,\r
+            default     = 1,\r
+\r
+            day varid   = Date.Day,          // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from\r
+            prompt      = STRING_TOKEN(STR_DATE_PROMPT),\r
+            help        = STRING_TOKEN(STR_DATE_DAY_HELP),\r
+            minimum     = 1,\r
+            maximum     = 31,\r
+            step        = 0x1,\r
+            default     = 1,\r
+\r
+    enddate;\r
+\r
+    time    hour varid  = Time.Hours,         // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from\r
+            prompt      = STRING_TOKEN(STR_TIME_PROMPT),\r
+            help        = STRING_TOKEN(STR_TIME_HOUR_HELP),\r
+            minimum     = 0,\r
+            maximum     = 23,\r
+            step        = 1,\r
+            default     = 0,\r
+\r
+            minute varid  = Time.Minutes,       // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from\r
+            prompt        = STRING_TOKEN(STR_TIME_PROMPT),\r
+            help          = STRING_TOKEN(STR_TIME_MINUTE_HELP),\r
+            minimum       = 0,\r
+            maximum       = 59,\r
+            step          = 1,\r
+            default       = 0,\r
+\r
+            second varid  = Time.Seconds,       // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from\r
+            prompt        = STRING_TOKEN(STR_TIME_PROMPT),\r
+            help          = STRING_TOKEN(STR_TIME_SECOND_HELP),\r
+            minimum       = 0,\r
+            maximum       = 59,\r
+            step          = 1,\r
+            default       = 0,\r
+\r
+    endtime;\r
+\r
+    grayoutif \r
+      ideqval Date.Day == 21\r
+      AND\r
+      ideqval Date.Month == 8;\r
+    \r
+    hidden  value = 32, key = 0x7777;\r
+\r
+    endif; // grayoutif\r
+\r
+    suppressif\r
+      ideqval Date.Day == 8\r
+      AND\r
+      ideqval Date.Month == 21; \r
+    \r
+    hidden  value = 32, key = 0x7777;\r
+\r
+    endif; // suppressif\r
+\r
+\r
+    hidden  value = 32, key = 0x1234;\r
+\r
+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),\r
+      ideqval MyIfrNVData.HowOldAreYouInYearsManual == 4\r
+    endif;\r
+     \r
+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),\r
+      ideqvallist MyIfrNVData.HowOldAreYouInYearsManual == 1 2 3 4\r
+    endif;\r
+\r
+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),\r
+      ideqid MyIfrNVData.HowOldAreYouInYearsManual == MyIfrNVData.MyFavoriteNumber\r
+    endif;\r
+\r
+//    grayoutif \r
+//\r
+// If the day is 31 AND months is any of the following 2, 4, 6, 9, 11\r
+//\r
+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),\r
+      ideqval Date.Day == 31 \r
+      AND\r
+      ideqvallist Date.Month == 2 4 6 9 11\r
+    endif;\r
+\r
+//\r
+// If the day is 30 AND month is 2\r
+//\r
+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),\r
+      ideqval Date.Day == 30\r
+      AND\r
+      ideqval Date.Month == 2\r
+    endif;\r
+\r
+//\r
+// If the day is 29 AND month is 2 AND it year is NOT a leapyear\r
+//\r
+    inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP),\r
+      ideqval Date.Day == 0x1D\r
+      AND\r
+      ideqval Date.Month == 2 \r
+      AND\r
+      NOT\r
+      ideqvallist Date.Year == 2004 2008 20012 20016 2020 2024 2028 2032 2036\r
+    endif;\r
+\r
+    checkbox varid    = MyIfrNVData.ChooseToActivateNuclearWeaponry,\r
+            prompt   = STRING_TOKEN(STR_CHECK_BOX_PROMPT),\r
+            help     = STRING_TOKEN(STR_CHECK_BOX_HELP),  \r
+            flags    = 1,\r
+            key      = 0,\r
+    endcheckbox;\r
+\r
+    text  \r
+      help = STRING_TOKEN(STR_TEXT_HELP),  \r
+      text = STRING_TOKEN(STR_TEXT_TEXT_1);\r
+    \r
+    text \r
+      help   = STRING_TOKEN(STR_TEXT_HELP),  \r
+      text   = STRING_TOKEN(STR_TEXT_TEXT_1),\r
+      text   = STRING_TOKEN(STR_TEXT_TEXT_2),\r
+      flags  = 0,\r
+      key    = MY_TEXT_KEY;\r
+         \r
+    goto 1, \r
+      prompt = STRING_TOKEN(STR_GOTO_FORM1), //MainSetupPage  // this too has no end-op and basically it's a jump to a form ONLY\r
+      help   = STRING_TOKEN(STR_GOTO_HELP);\r
+\r
+  endform;\r
+\r
+  form formid = 3, title = STRING_TOKEN(STR_FORM3_TITLE);  // note formid is a variable (for readability) (UINT16) - also added Form to the line to signify the Op-Code\r
+\r
+    grayoutif  ideqval MyIfrNVData.SuppressGrayOutSomething == 0x1;\r
+      text  \r
+        help = STRING_TOKEN(STR_TEXT_HELP),  \r
+        text = STRING_TOKEN(STR_TEXT_TEXT_1);\r
+        \r
+    endif; //end grayoutif\r
+    \r
+    text  \r
+      help = STRING_TOKEN(STR_TEXT_HELP),  \r
+      text = STRING_TOKEN(STR_TEXT_TEXT_1);\r
+    \r
+  endform;\r
+  \r
+  form formid = 4, title = STRING_TOKEN(STR_FORM3_TITLE);\r
+\r
+  endform;\r
+\r
+  form formid = 0x1234,            // Dynamically created page, \r
+       title = STRING_TOKEN(STR_DYNAMIC_TITLE);  // note formid is a variable (for readability) (UINT16) - also added Form to the line to signify the Op-Code\r
+\r
+    label 0x1234;\r
+\r
+  endform;\r
+\r
+endformset;\r
diff --git a/IntelFrameworkModulePkg/Universal/DriverSampleDxe/VfrStrings.uni b/IntelFrameworkModulePkg/Universal/DriverSampleDxe/VfrStrings.uni
new file mode 100644 (file)
index 0000000..9e9dbf5
Binary files /dev/null and b/IntelFrameworkModulePkg/Universal/DriverSampleDxe/VfrStrings.uni differ
diff --git a/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/CommonHeader.h b/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/CommonHeader.h
new file mode 100644 (file)
index 0000000..2506b80
--- /dev/null
@@ -0,0 +1,41 @@
+/**@file\r
+  Common header file shared by all source files.\r
+\r
+  This file includes package header files, library classes and protocol, PPI & GUID definitions.\r
+\r
+  Copyright (c) 2006 - 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
+   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
+#ifndef __COMMON_HEADER_H_\r
+#define __COMMON_HEADER_H_\r
+\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <FrameworkDxe.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Guid/GlobalVariable.h>\r
+#include <Protocol/FormCallback.h>\r
+#include <Protocol/FrameworkHii.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/IfrSupportLibFramework.h>\r
+\r
+#endif\r
diff --git a/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Fonts.c b/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Fonts.c
new file mode 100644 (file)
index 0000000..2c3980d
--- /dev/null
@@ -0,0 +1,271 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  Fonts.c\r
+\r
+Abstract:\r
+\r
+  This file contains the Glyph/Font processing code to the HII database.\r
+\r
+--*/\r
+\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "HiiDatabase.h"\r
+\r
+//\r
+// We only need to define a wide glyph, since we will seed the narrow glyph with EFI_NARROW_GLYPH size of\r
+// this data structure\r
+//\r
+UINT8 mUnknownGlyph[38] = {\r
+  0xaa,\r
+  0x55,\r
+  0xaa,\r
+  0x55,\r
+  0xaa,\r
+  0x55,\r
+  0xaa,\r
+  0x55,\r
+  0xaa,\r
+  0x55,\r
+  0xaa,\r
+  0x55,\r
+  0xaa,\r
+  0x55,\r
+  0xaa,\r
+  0x55,\r
+  0xaa,\r
+  0x55,\r
+  0xAA,\r
+  0xaa,\r
+  0x55,\r
+  0xaa,\r
+  0x55,\r
+  0xaa,\r
+  0x55,\r
+  0xaa,\r
+  0x55,\r
+  0xaa,\r
+  0x55,\r
+  0xaa,\r
+  0x55,\r
+  0xaa,\r
+  0x55,\r
+  0xaa,\r
+  0x55,\r
+  0xaa,\r
+  0x55,\r
+  0xAA\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetGlyph (\r
+  IN     EFI_HII_PROTOCOL   *This,\r
+  IN     CHAR16             *Source,\r
+  IN OUT UINT16             *Index,\r
+  OUT    UINT8              **GlyphBuffer,\r
+  OUT    UINT16             *BitWidth,\r
+  IN OUT UINT32             *InternalStatus\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Translates a Unicode character into the corresponding font glyph.  \r
+  If the Source was pointing to a non-spacing character, the next Source[*Index]\r
+  character will be parsed and OR'd to the GlyphBuffer until a spacing character\r
+  is found in the Source.  Since non-spacing characters are considered to be the\r
+  same pixel width as a regular character their BitWidth will be reflected correctly\r
+  however due to their special attribute, they are considered to be zero advancing width.\r
+  This basically means that the cursor would not advance, thus the character that follows\r
+  it would overlay the non-spacing character.  The Index is modified to reflect both the\r
+  incoming array entry into the Source string but also the outgoing array entry after having\r
+  parsed the equivalent of a single Glyph's worth of data.\r
+\r
+Arguments:\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  EFI_HII_GLOBAL_DATA *GlobalData;\r
+  EFI_HII_DATA        *HiiData;\r
+  UINTN               Count;\r
+  BOOLEAN             Narrow;\r
+  UINTN               Location;\r
+  UINTN               SearchLocation;\r
+  UINTN               Value;\r
+  CHAR16              Character;\r
+  UINTN               Attributes;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  HiiData         = EFI_HII_DATA_FROM_THIS (This);\r
+\r
+  GlobalData      = HiiData->GlobalData;\r
+  Count           = sizeof (GlobalData->NarrowGlyphs->GlyphCol1);\r
+\r
+  Location        = *Index;\r
+  SearchLocation  = *Index;\r
+  Narrow          = TRUE;\r
+\r
+  if (Source[Location] == NARROW_CHAR || Source[Location] == WIDE_CHAR) {\r
+    *InternalStatus = 0;\r
+  }\r
+  //\r
+  // We don't know what glyph database to look in - let's figure it out\r
+  //\r
+  if (*InternalStatus == 0) {\r
+    //\r
+    // Determine if we are looking for narrow or wide glyph data\r
+    //\r
+    do {\r
+      if (Source[SearchLocation] == NARROW_CHAR || Source[SearchLocation] == WIDE_CHAR) {\r
+        //\r
+        // We found something that identifies what glyph database to look in\r
+        //\r
+        if (Source[SearchLocation] == WIDE_CHAR) {\r
+          Narrow          = FALSE;\r
+          *BitWidth       = WIDE_WIDTH;\r
+          *InternalStatus = WIDE_CHAR;\r
+          Location++;\r
+          break;\r
+        } else {\r
+          Narrow          = TRUE;\r
+          *BitWidth       = NARROW_WIDTH;\r
+          *InternalStatus = NARROW_CHAR;\r
+          Location++;\r
+          break;\r
+        }\r
+      }\r
+    } while (SearchLocation-- > 0);\r
+  }\r
+\r
+  if (*InternalStatus == NARROW_CHAR) {\r
+    Narrow    = TRUE;\r
+    *BitWidth = NARROW_WIDTH;\r
+  } else if (*InternalStatus == WIDE_CHAR) {\r
+    Narrow    = FALSE;\r
+    *BitWidth = WIDE_WIDTH;\r
+  } else {\r
+    //\r
+    // Without otherwise knowing what the width is narrow (e.g. someone passed in a string with index of 0\r
+    // we wouldn't be able to determine the width of the data.)\r
+    // BUGBUG - do we go to wide database and if exist, ignore narrow?  Check Unicode spec....\r
+    //\r
+    Narrow    = TRUE;\r
+    *BitWidth = NARROW_WIDTH;\r
+  }\r
+\r
+  Character = Source[Location];\r
+\r
+  if (Narrow) {\r
+    if (GlobalData->NarrowGlyphs[Character].UnicodeWeight != 0x0000) {\r
+      *GlyphBuffer  = (UINT8 *) (&GlobalData->NarrowGlyphs[Character]);\r
+      Attributes    = GlobalData->NarrowGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;\r
+    } else {\r
+      //\r
+      // Glyph is uninitialized - return an error, but hand back the glyph\r
+      //\r
+      *GlyphBuffer  = (UINT8 *) (&GlobalData->NarrowGlyphs[Character]);\r
+      *Index        = (UINT16) (Location + 1);\r
+      return EFI_NOT_FOUND;\r
+    }\r
+  } else {\r
+    //\r
+    // Wide character\r
+    //\r
+    if (GlobalData->WideGlyphs[Character].UnicodeWeight != 0x0000) {\r
+      *GlyphBuffer  = (UINT8 *) (&GlobalData->WideGlyphs[Character]);\r
+      Attributes    = GlobalData->WideGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;\r
+    } else {\r
+      //\r
+      // Glyph is uninitialized - return an error, but hand back the glyph\r
+      //\r
+      *GlyphBuffer  = (UINT8 *) (&GlobalData->WideGlyphs[Character]);\r
+      *Index        = (UINT16) (Location + 1);\r
+      return EFI_NOT_FOUND;\r
+    }\r
+  }\r
+  //\r
+  // This is a non-spacing character.  It will be followed by either more non-spacing\r
+  // characters or a regular character.  We need to OR together the data associated with each.\r
+  //\r
+  for (; Attributes != 0; Location++) {\r
+    //\r
+    // Character is the Unicode value which is the index into the Glyph array.\r
+    //\r
+    Character = Source[Location];\r
+\r
+    if (Narrow) {\r
+      for (Value = 0; Value != Count; Value++) {\r
+        *GlyphBuffer[Location + Value] = (UINT8) (*GlyphBuffer[Location + Value] |\r
+                                                  GlobalData->NarrowGlyphs[Character].GlyphCol1[Value]);\r
+      }\r
+\r
+      Attributes = GlobalData->NarrowGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;\r
+    } else {\r
+      for (Value = 0; Value != Count; Value++) {\r
+        *GlyphBuffer[Location + Value] = (UINT8) (*GlyphBuffer[Location + Value] | \r
+                                                  GlobalData->WideGlyphs[Character].GlyphCol1[Value]);\r
+        *GlyphBuffer[Location + Value + Count] = (UINT8) (*GlyphBuffer[Location + Value + Count] |\r
+                                                          GlobalData->WideGlyphs[Character].GlyphCol2[Value]);\r
+      }\r
+\r
+      Attributes = GlobalData->WideGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;\r
+    }\r
+  }\r
+  //\r
+  // Source[*Index] should point to the next character to process\r
+  //\r
+  *Index = (UINT16) (Location + 1);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGlyphToBlt (\r
+  IN     EFI_HII_PROTOCOL              *This,\r
+  IN     UINT8                         *GlyphBuffer,\r
+  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,\r
+  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,\r
+  IN     UINTN                         Count,\r
+  IN     UINTN                         Width,\r
+  IN     UINTN                         Height,\r
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer\r
+  )\r
+{\r
+  UINTN X;\r
+  UINTN Y;\r
+\r
+  //\r
+  // Convert Monochrome bitmap of the Glyph to BltBuffer structure\r
+  //\r
+  for (Y = 0; Y < Height; Y++) {\r
+    for (X = 0; X < Width; X++) {\r
+      if ((((EFI_NARROW_GLYPH *) GlyphBuffer)->GlyphCol1[Y] & (1 << X)) != 0) {\r
+        BltBuffer[Y * Width * Count + (Width - X - 1)] = Foreground;\r
+      } else {\r
+        BltBuffer[Y * Width * Count + (Width - X - 1)] = Background;\r
+      }\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Forms.c b/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Forms.c
new file mode 100644 (file)
index 0000000..c9a8d9a
--- /dev/null
@@ -0,0 +1,1582 @@
+/**@file\r
+  This file contains the form processing code to the HII database.\r
+  \r
+Copyright (c) 2006 - 2007 Intel Corporation. <BR>\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
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "HiiDatabase.h"\r
+\r
+STATIC\r
+CHAR16*\r
+Ascii2Unicode (\r
+  OUT CHAR16         *UnicodeStr,\r
+  IN  CHAR8          *AsciiStr\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+\r
+    This function converts ASCII string to Unicode string.\r
+  \r
+  Arguments:\r
+\r
+    UnicodeStr     - NULL terminated Unicode output string.\r
+    AsciieStr      - NULL terminated ASCII input string.\r
\r
+  Returns: \r
+\r
+    Start of the Unicode ouput string.\r
+    \r
+--*/\r
+\r
+{\r
+  CHAR16      *Str = UnicodeStr;  \r
+  while (TRUE) {\r
+    *(UnicodeStr++) = (CHAR16) *AsciiStr;\r
+    if (*(AsciiStr++) == '\0') {\r
+      return Str;\r
+    }\r
+  }\r
+}\r
+\r
+STATIC\r
+CHAR8*\r
+Unicode2Ascii (\r
+  OUT CHAR8          *AsciiStr,\r
+  IN  CHAR16         *UnicodeStr\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+\r
+    This function converts Unicode string to ASCII string.\r
+  \r
+  Arguments:\r
+\r
+    AsciieStr      - NULL terminated ASCII output string.\r
+    UnicodeStr     - NULL terminated Unicode input string.\r
\r
+  Returns: \r
+\r
+    Start of the ASCII ouput string.\r
+    \r
+--*/\r
+\r
+{\r
+  CHAR8      *Str = AsciiStr;  \r
+  while (TRUE) {\r
+    *(AsciiStr++) = (CHAR8) *UnicodeStr;\r
+    if (*(UnicodeStr++) == '\0') {\r
+      return Str;\r
+    }\r
+  }\r
+}\r
+\r
+STATIC\r
+VOID\r
+ExtractDevicePathData (\r
+  IN     EFI_HII_DATA_TABLE   *DataTable,\r
+  IN     UINT8                *IfrData,\r
+  IN OUT UINT8                **ExportBufferPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+Arguments:\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  UINT8 *ExportBuffer;\r
+\r
+  ExportBuffer = *ExportBufferPtr;\r
+\r
+  //\r
+  // BUGBUG - don't have devicepath data yet, setting dummy value\r
+  //\r
+  DataTable++;\r
+  ExportBuffer  = (UINT8 *) DataTable;\r
+  ((EFI_HII_DEVICE_PATH_PACK *) ExportBuffer)->Header.Type = EFI_HII_DEVICE_PATH;\r
+  ((EFI_HII_DEVICE_PATH_PACK *) ExportBuffer)->Header.Length = (UINT32) (sizeof (EFI_HII_DEVICE_PATH_PACK) + sizeof (EFI_DEVICE_PATH_PROTOCOL));\r
+\r
+  //\r
+  // BUGBUG - part of hack - skip the Device Path Pack.....place some data\r
+  //\r
+  ExportBuffer  = ExportBuffer + sizeof (EFI_HII_DEVICE_PATH_PACK);\r
+\r
+  ((EFI_DEVICE_PATH_PROTOCOL *) ExportBuffer)->Type     = EFI_END_ENTIRE_DEVICE_PATH;\r
+  ((EFI_DEVICE_PATH_PROTOCOL *) ExportBuffer)->SubType  = EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;\r
+\r
+  //\r
+  // BUGBUG - still part of hack....\r
+  //\r
+  ExportBuffer      = ExportBuffer + sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
+  *ExportBufferPtr  = ExportBuffer;\r
+}\r
+\r
+STATIC\r
+VOID\r
+ExtractVariableData (\r
+  IN OUT EFI_HII_DATA_TABLE   *DataTable,\r
+  IN     UINT8                *IfrData,\r
+  IN OUT UINT8                **ExportBufferPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function extract the EFI_HII_VARIABLE_PACK portion from the \r
+  each of the EFI_HII_PACKAGE_INSTANCE in HII handle database.\r
+  \r
+Arguments:\r
+\r
+  DataTable       - On input, this parameter point to the EFI_HII_DATA_TABLE structure\r
+                    of the final data buffer for the EFI_HII_EXPORT interface. This function\r
+                    update the NumberOfVariableData attribute.\r
+  IfrData         - It points to a staring address of a EFI_HII_IFR_PACK structure.\r
+  ExportBufferPtr - On input, it points the starting address of the data buffer to \r
+                    host the variable pack. On output, it is the starting address\r
+                    of data buffer for the next extraction operation.\r
+Returns: \r
+\r
+  VOID\r
+  \r
+--*/\r
+{\r
+  EFI_HII_VARIABLE_PACK       *VariableContents;\r
+  UINT8                       *ExportBuffer;\r
+  UINTN                       Index;\r
+  UINTN                       Index2;\r
+  UINTN                       TempValue;\r
+  UINTN                       TempValue2;\r
+  EFI_FORM_CALLBACK_PROTOCOL  *FormCallback;\r
+  EFI_PHYSICAL_ADDRESS        CallbackHandle;\r
+  EFI_STATUS                  Status;\r
+  CHAR16                      *String;\r
+\r
+  FormCallback    = NULL;\r
+  CallbackHandle  = 0;\r
+  ExportBuffer    = *ExportBufferPtr;\r
+\r
+  for (Index = 0; IfrData[Index] != EFI_IFR_END_FORM_SET_OP;) {\r
+    VariableContents = (EFI_HII_VARIABLE_PACK *) ExportBuffer;\r
+\r
+    switch (IfrData[Index]) {\r
+    case EFI_IFR_FORM_SET_OP:\r
+      TempValue = EFI_HII_VARIABLE;\r
+      CopyMem (&VariableContents->Header.Type, &TempValue, sizeof (UINT16));\r
+      CopyMem (&TempValue, &((EFI_IFR_FORM_SET *) &IfrData[Index])->NvDataSize, sizeof (UINT16));\r
+\r
+      //\r
+      // If the variable has 0 size, do not process it\r
+      //\r
+      if (TempValue == 0) {\r
+        break;\r
+      }\r
+      //\r
+      // Add the size of the variable pack overhead.  Later, will also add the size of the\r
+      // name of the variable.\r
+      //\r
+      TempValue = TempValue + sizeof (EFI_HII_VARIABLE_PACK);\r
+\r
+      CopyMem (&VariableContents->Header.Length, &TempValue, sizeof (UINT32));\r
+      CopyMem (\r
+        &CallbackHandle,\r
+        &((EFI_IFR_FORM_SET *) &IfrData[Index])->CallbackHandle,\r
+        sizeof (EFI_PHYSICAL_ADDRESS)\r
+        );\r
+      if (CallbackHandle != 0) {\r
+        Status = gBS->HandleProtocol (\r
+                        (EFI_HANDLE) (UINTN) CallbackHandle,\r
+                        &gEfiFormCallbackProtocolGuid,\r
+                        (VOID *) &FormCallback\r
+                        );\r
+        ASSERT_EFI_ERROR (Status);\r
+      }\r
+      //\r
+      // Since we have a "Setup" variable that wasn't specified by a variable op-code\r
+      // it will have a VariableId of 0.  All other variable op-codes will have a designation\r
+      // of VariableId 1+\r
+      //\r
+      TempValue = 0;\r
+      CopyMem (&VariableContents->VariableId, &TempValue, sizeof (UINT16));\r
+      CopyMem (&VariableContents->VariableGuid, &((EFI_IFR_FORM_SET *) &IfrData[Index])->Guid, sizeof (EFI_GUID));\r
+      TempValue = sizeof (SETUP_MAP_NAME);\r
+      CopyMem (&VariableContents->VariableNameLength, &TempValue, sizeof (UINT32));\r
+\r
+      //\r
+      // Add the size of the name to the Header Length\r
+      //\r
+      TempValue2 = 0;\r
+      CopyMem (&TempValue2, &VariableContents->Header.Length, sizeof (UINT32));\r
+      TempValue2 = TempValue + TempValue2;\r
+      CopyMem (&VariableContents->Header.Length, &TempValue2, sizeof (UINT32));\r
+\r
+      ExportBuffer = ExportBuffer + sizeof (EFI_HII_VARIABLE_PACK);\r
+      CopyMem (ExportBuffer, SETUP_MAP_NAME, sizeof (SETUP_MAP_NAME));\r
+      ExportBuffer = ExportBuffer + sizeof (SETUP_MAP_NAME);\r
+\r
+      CopyMem (&TempValue, &((EFI_IFR_FORM_SET *) &IfrData[Index])->NvDataSize, sizeof (UINT16));\r
+\r
+      if ((FormCallback != NULL) && (FormCallback->NvRead != NULL)) {\r
+        Status = FormCallback->NvRead (\r
+                                 FormCallback,\r
+                                 (CHAR16 *) SETUP_MAP_NAME,\r
+                                 (EFI_GUID *)(UINTN)&VariableContents->VariableGuid,\r
+                                 NULL,\r
+                                 &TempValue,\r
+                                 ExportBuffer\r
+                                 );\r
+        ASSERT_EFI_ERROR (Status);\r
+      } else {\r
+        Status = gRT->GetVariable (\r
+                        (CHAR16 *) SETUP_MAP_NAME,\r
+                        (EFI_GUID *)(UINTN)&VariableContents->VariableGuid,\r
+                        NULL,\r
+                        &TempValue,\r
+                        ExportBuffer\r
+                        );\r
+        ASSERT_EFI_ERROR (Status);\r
+      }\r
+\r
+      ExportBuffer = (UINT8 *) (UINTN) (((UINTN) ExportBuffer) + TempValue);\r
+      DataTable->NumberOfVariableData++;\r
+      break;\r
+\r
+    case EFI_IFR_VARSTORE_OP:\r
+      TempValue = EFI_HII_VARIABLE;\r
+      CopyMem (&VariableContents->Header.Type, &TempValue, sizeof (UINT16));\r
+      CopyMem (&TempValue, &((EFI_IFR_VARSTORE *) &IfrData[Index])->Size, sizeof (UINT16));\r
+\r
+      //\r
+      // If the variable has 0 size, do not process it\r
+      //\r
+      if (TempValue == 0) {\r
+        break;\r
+      }\r
+      //\r
+      // Add the size of the variable pack overhead.  Later, will also add the size of the\r
+      // name of the variable.\r
+      //\r
+      TempValue = TempValue + sizeof (EFI_HII_VARIABLE_PACK);\r
+\r
+      CopyMem (&VariableContents->Header.Length, &TempValue, sizeof (UINT32));\r
+      CopyMem (&VariableContents->VariableId, &((EFI_IFR_VARSTORE *) &IfrData[Index])->VarId, sizeof (UINT16));\r
+      CopyMem (&VariableContents->VariableGuid, &((EFI_IFR_VARSTORE *) &IfrData[Index])->Guid, sizeof (EFI_GUID));\r
+      TempValue = (UINTN) ((EFI_IFR_VARSTORE *) &IfrData[Index])->Header.Length - sizeof (EFI_IFR_VARSTORE);\r
+      TempValue = TempValue * 2;\r
+      CopyMem (&VariableContents->VariableNameLength, &TempValue, sizeof (UINT32));\r
+\r
+      //\r
+      // Add the size of the name to the Header Length\r
+      //\r
+      TempValue2 = 0;\r
+      CopyMem (&TempValue2, &VariableContents->Header.Length, sizeof (UINT32));\r
+      TempValue2 = TempValue + TempValue2;\r
+      CopyMem (&VariableContents->Header.Length, &TempValue2, sizeof (UINT32));\r
+\r
+      ExportBuffer  = ExportBuffer + sizeof (EFI_HII_VARIABLE_PACK);\r
+      String        = (CHAR16 *) ExportBuffer;\r
+      for (Index2 = 0; Index2 < TempValue / 2; Index2++) {\r
+        ExportBuffer[Index2 * 2]      = IfrData[Index + sizeof (EFI_IFR_VARSTORE) + Index2];\r
+        ExportBuffer[Index2 * 2 + 1]  = 0;\r
+      }\r
+\r
+      ExportBuffer = ExportBuffer + TempValue;\r
+\r
+      CopyMem (&TempValue, &((EFI_IFR_VARSTORE *) &IfrData[Index])->Size, sizeof (UINT16));\r
+\r
+      if ((FormCallback != NULL) && (FormCallback->NvRead != NULL)) {\r
+        Status = FormCallback->NvRead (\r
+                                 FormCallback,\r
+                                 String,\r
+                                 (EFI_GUID *)(UINTN)&VariableContents->VariableGuid,\r
+                                 NULL,\r
+                                 &TempValue,\r
+                                 ExportBuffer\r
+                                 );\r
+        ASSERT_EFI_ERROR (Status);\r
+      } else {\r
+        Status = gRT->GetVariable (\r
+                        String,\r
+                        (EFI_GUID *)(UINTN)&VariableContents->VariableGuid,\r
+                        NULL,\r
+                        &TempValue,\r
+                        ExportBuffer\r
+                        );\r
+        ASSERT_EFI_ERROR (Status);\r
+      }\r
+\r
+      ExportBuffer = (UINT8 *) (UINTN) (((UINTN) ExportBuffer) + TempValue);\r
+      DataTable->NumberOfVariableData++;\r
+      break;\r
+    }\r
+\r
+    Index = IfrData[Index + 1] + Index;\r
+  }\r
+  //\r
+  // If we have added a variable pack, add a dummy empty one to signify the end\r
+  //\r
+  if (ExportBuffer != *ExportBufferPtr) {\r
+    VariableContents  = (EFI_HII_VARIABLE_PACK *) ExportBuffer;\r
+    TempValue         = EFI_HII_VARIABLE;\r
+    CopyMem (&VariableContents->Header.Type, &TempValue, sizeof (UINT16));\r
+    TempValue = sizeof (EFI_HII_VARIABLE_PACK);\r
+    CopyMem (&VariableContents->Header.Length, &TempValue, sizeof (UINT32));\r
+    ExportBuffer = ExportBuffer + sizeof (EFI_HII_VARIABLE_PACK);\r
+  }\r
+\r
+  *ExportBufferPtr = ExportBuffer;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiExportDatabase (\r
+  IN     EFI_HII_PROTOCOL *This,\r
+  IN     EFI_HII_HANDLE   Handle,\r
+  IN OUT UINTN            *BufferSize,\r
+  OUT    VOID             *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  This function allows a program to extract a form or form package that has \r
+  previously been registered with the EFI HII database.\r
+\r
+Arguments:\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;\r
+  EFI_HII_DATA              *HiiData;\r
+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;\r
+  EFI_HII_IFR_PACK          *FormPack;\r
+  UINT8                     *RawData;\r
+  UINT8                     *ExportBuffer;\r
+  EFI_HII_EXPORT_TABLE      *ExportTable;\r
+  EFI_HII_DATA_TABLE        *DataTable;\r
+  BOOLEAN                   VariableExist;\r
+  UINT16                    NumberOfHiiDataTables;\r
+  UINTN                     SizeNeeded;\r
+  UINTN                     Index;\r
+  UINTN                     VariableSize;\r
+  UINTN                     TempValue;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  HiiData               = EFI_HII_DATA_FROM_THIS (This);\r
+\r
+  HandleDatabase        = HiiData->DatabaseHead;\r
+\r
+  FormPack              = NULL;\r
+  RawData               = NULL;\r
+  PackageInstance       = NULL;\r
+  NumberOfHiiDataTables = 0;\r
+  VariableSize          = 0;\r
+  TempValue             = 0;\r
+  SizeNeeded            = sizeof (EFI_HII_EXPORT_TABLE);\r
+\r
+  //\r
+  // How many total tables are there?\r
+  //\r
+  for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {\r
+    if ((Handle != 0) && (Handle != HandleDatabase->Handle)) {\r
+      continue;\r
+    }\r
+\r
+    VariableExist = FALSE;\r
+    NumberOfHiiDataTables++;\r
+    PackageInstance = HandleDatabase->Buffer;\r
+    if (PackageInstance == NULL) {\r
+      continue;\r
+    }\r
+    //\r
+    // Extract Size of Export Package\r
+    //\r
+    SizeNeeded = SizeNeeded + PackageInstance->IfrSize \r
+                            + PackageInstance->StringSize\r
+                            + sizeof (EFI_HII_DATA_TABLE)\r
+                            + sizeof (EFI_HII_DEVICE_PATH_PACK);\r
+\r
+    //\r
+    // BUGBUG We aren't inserting Device path data yet\r
+    //\r
+    SizeNeeded = SizeNeeded + sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
+\r
+    //\r
+    // Extract Size of Variable Data\r
+    //\r
+    if (PackageInstance->IfrSize > 0) {\r
+      FormPack = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));\r
+    } else {\r
+      //\r
+      // No IFR? No variable information\r
+      //\r
+      continue;\r
+    }\r
+\r
+    RawData = (UINT8 *) FormPack;\r
+\r
+    for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {\r
+      switch (RawData[Index]) {\r
+      case EFI_IFR_FORM_SET_OP:\r
+        CopyMem (&VariableSize, &((EFI_IFR_FORM_SET *) &RawData[Index])->NvDataSize, sizeof (UINT16));\r
+        SizeNeeded    = SizeNeeded + VariableSize + sizeof (SETUP_MAP_NAME) + sizeof (EFI_HII_VARIABLE_PACK);\r
+        VariableExist = TRUE;\r
+        break;\r
+\r
+      case EFI_IFR_VARSTORE_OP:\r
+        CopyMem (&VariableSize, &((EFI_IFR_VARSTORE *) &RawData[Index])->Size, sizeof (UINT16));\r
+        SizeNeeded = SizeNeeded + VariableSize + sizeof (EFI_HII_VARIABLE_PACK);\r
+        //\r
+        // We will be expanding the stored ASCII name to a Unicode string.  This will cause some memory overhead\r
+        // Since the VARSTORE size already takes in consideration the ASCII size, we need to size it and add another\r
+        // instance of it.  Essentially, 2 ASCII strings == 1 Unicode string in size.\r
+        //\r
+        TempValue     = (UINTN) ((EFI_IFR_VARSTORE *) &RawData[Index])->Header.Length - sizeof (EFI_IFR_VARSTORE);\r
+        SizeNeeded    = SizeNeeded + TempValue * 2;\r
+        VariableExist = TRUE;\r
+        break;\r
+      }\r
+\r
+      Index = RawData[Index + 1] + Index;\r
+    }\r
+    //\r
+    // If a variable exists for this handle, add an additional variable pack overhead to\r
+    // indicate that we will have an extra null Variable Pack to signify the end of the Variable Packs\r
+    //\r
+    if (VariableExist) {\r
+      SizeNeeded = SizeNeeded + sizeof (EFI_HII_VARIABLE_PACK);\r
+    }\r
+  }\r
+\r
+  if (SizeNeeded > *BufferSize) {\r
+    *BufferSize = SizeNeeded;\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+  //\r
+  // Zero out the incoming buffer\r
+  //\r
+  ZeroMem (Buffer, *BufferSize);\r
+\r
+  //\r
+  // Cast the Buffer to EFI_HII_EXPORT_TABLE\r
+  //\r
+  ExportTable = (EFI_HII_EXPORT_TABLE *) Buffer;\r
+\r
+  //\r
+  // Set the Revision for the Export Table\r
+  //\r
+  CopyMem (&ExportTable->Revision, &gEfiHiiProtocolGuid, sizeof (EFI_GUID));\r
+\r
+  ExportBuffer    = (UINT8 *) (UINTN) (((UINT8 *) ExportTable) + sizeof (EFI_HII_EXPORT_TABLE));\r
+  HandleDatabase  = HiiData->DatabaseHead;\r
+\r
+  //\r
+  // Check numeric value against the head of the database\r
+  //\r
+  for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {\r
+    DataTable       = (EFI_HII_DATA_TABLE *) ExportBuffer;\r
+    PackageInstance = HandleDatabase->Buffer;\r
+    //\r
+    // If not asking for a specific handle, export the entire database\r
+    //\r
+    if (Handle == 0) {\r
+      ExportTable->NumberOfHiiDataTables = NumberOfHiiDataTables;\r
+      CopyMem (&DataTable->PackageGuid, &PackageInstance->Guid, sizeof (EFI_GUID));\r
+      DataTable->HiiHandle        = PackageInstance->Handle;\r
+      DataTable->DevicePathOffset = (UINT32) (sizeof (EFI_HII_DATA_TABLE));\r
+\r
+      //\r
+      // Start Dumping DevicePath\r
+      //\r
+      ExtractDevicePathData (DataTable, RawData, &ExportBuffer);\r
+\r
+      if (((UINTN) ExportBuffer) == ((UINTN) DataTable)) {\r
+        //\r
+        // If there is no DevicePath information - set offset to 0 to signify the absence of data to parse\r
+        //\r
+        DataTable->DevicePathOffset = 0;\r
+      }\r
+\r
+      DataTable->VariableDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));\r
+\r
+      if (PackageInstance->IfrSize > 0) {\r
+        FormPack  = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));\r
+\r
+        RawData   = (UINT8 *) FormPack;\r
+        TempValue = 0;\r
+\r
+        //\r
+        // Start dumping the Variable Data\r
+        //\r
+        ExtractVariableData (DataTable, RawData, &ExportBuffer);\r
+        DataTable->IfrDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));\r
+\r
+        if (DataTable->VariableDataOffset == DataTable->IfrDataOffset) {\r
+          DataTable->VariableDataOffset = 0;\r
+        }\r
+        //\r
+        // Start dumping the IFR data (Note:  It is in an IFR PACK)\r
+        //\r
+        CopyMem (ExportBuffer, &PackageInstance->IfrData, PackageInstance->IfrSize);\r
+        ExportBuffer                = (UINT8 *) (UINTN) (((UINTN) ExportBuffer) + PackageInstance->IfrSize);\r
+        DataTable->StringDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));\r
+\r
+        //\r
+        // Start dumping the String data (Note:  It is in a String PACK)\r
+        //\r
+        if (PackageInstance->StringSize > 0) {\r
+          RawData = (UINT8 *) (((UINTN) &PackageInstance->IfrData) + PackageInstance->IfrSize);\r
+          CopyMem (ExportBuffer, RawData, PackageInstance->StringSize);\r
+          DataTable->DataTableSize = (UINT32) (DataTable->StringDataOffset + PackageInstance->StringSize);\r
+\r
+          CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));\r
+          for (; TempValue != 0;) {\r
+            DataTable->NumberOfLanguages++;\r
+            ExportBuffer = ExportBuffer + ((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length;\r
+            CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));\r
+          }\r
+\r
+          ExportBuffer = ExportBuffer + sizeof (EFI_HII_STRING_PACK);\r
+        } else {\r
+          DataTable->StringDataOffset = 0;\r
+        }\r
+      } else {\r
+        //\r
+        // No IFR? No variable information.  If Offset is 0, means there is none.  (Hmm - this might be prunable - no strings to export if no IFR - we always have a stub)\r
+        //\r
+        DataTable->VariableDataOffset = 0;\r
+        DataTable->IfrDataOffset      = 0;\r
+        DataTable->StringDataOffset   = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));\r
+\r
+        //\r
+        // Start dumping the String data - NOTE:  It is in String Pack form\r
+        //\r
+        if (PackageInstance->StringSize > 0) {\r
+          RawData = (UINT8 *) (((UINTN) &PackageInstance->IfrData) + PackageInstance->IfrSize);\r
+          CopyMem (ExportBuffer, RawData, PackageInstance->StringSize);\r
+          DataTable->DataTableSize = (UINT32) (DataTable->StringDataOffset + PackageInstance->StringSize);\r
+\r
+          CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));\r
+          for (; TempValue != 0;) {\r
+            DataTable->NumberOfLanguages++;\r
+            ExportBuffer = ExportBuffer + ((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length;\r
+            CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));\r
+          }\r
+\r
+          ExportBuffer = ExportBuffer + sizeof (EFI_HII_STRING_PACK);\r
+        } else {\r
+          DataTable->StringDataOffset = 0;\r
+        }\r
+      }\r
+    } else {\r
+      //\r
+      // Match the numeric value with the database entry - if matched, extract PackageInstance\r
+      //\r
+      if (Handle == HandleDatabase->Handle) {\r
+        PackageInstance                     = HandleDatabase->Buffer;\r
+        ExportTable->NumberOfHiiDataTables  = NumberOfHiiDataTables;\r
+        DataTable->HiiHandle                = PackageInstance->Handle;\r
+        CopyMem (&DataTable->PackageGuid, &PackageInstance->Guid, sizeof (EFI_GUID));\r
+\r
+        //\r
+        // Start Dumping DevicePath\r
+        //\r
+        ExtractDevicePathData (DataTable, RawData, &ExportBuffer);\r
+        DataTable->VariableDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));\r
+\r
+        if (PackageInstance->IfrSize > 0) {\r
+          FormPack  = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));\r
+\r
+          RawData   = (UINT8 *) FormPack;\r
+          TempValue = 0;\r
+\r
+          //\r
+          // Start dumping the Variable Data\r
+          //\r
+          ExtractVariableData (DataTable, RawData, &ExportBuffer);\r
+          DataTable->IfrDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));\r
+\r
+          if (DataTable->VariableDataOffset == DataTable->IfrDataOffset) {\r
+            DataTable->VariableDataOffset = 0;\r
+          }\r
+          //\r
+          // Start dumping the IFR data\r
+          //\r
+          CopyMem (ExportBuffer, &PackageInstance->IfrData, PackageInstance->IfrSize);\r
+          ExportBuffer                = (UINT8 *) (UINTN) (((UINTN) ExportBuffer) + PackageInstance->IfrSize);\r
+          DataTable->StringDataOffset = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));\r
+\r
+          //\r
+          // Start dumping the String data - NOTE:  It is in String Pack form\r
+          //\r
+          if (PackageInstance->StringSize > 0) {\r
+            RawData = (UINT8 *) (((UINTN) &PackageInstance->IfrData) + PackageInstance->IfrSize);\r
+            CopyMem (ExportBuffer, RawData, PackageInstance->StringSize);\r
+            DataTable->DataTableSize = (UINT32) (DataTable->StringDataOffset + PackageInstance->StringSize);\r
+\r
+            CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));\r
+            for (; TempValue != 0;) {\r
+              DataTable->NumberOfLanguages++;\r
+              ExportBuffer = ExportBuffer + ((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length;\r
+              CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));\r
+            }\r
+\r
+            ExportBuffer = ExportBuffer + sizeof (EFI_HII_STRING_PACK);\r
+          } else {\r
+            DataTable->StringDataOffset = 0;\r
+          }\r
+        } else {\r
+          //\r
+          // No IFR? No variable information.  If Offset is 0, means there is none.\r
+          //\r
+          DataTable->VariableDataOffset = 0;\r
+          DataTable->IfrDataOffset      = 0;\r
+          DataTable->StringDataOffset   = (UINT32) (((UINTN) ExportBuffer) - ((UINTN) DataTable));\r
+\r
+          //\r
+          // Start dumping the String data - Note:  It is in String Pack form\r
+          //\r
+          if (PackageInstance->StringSize > 0) {\r
+            RawData = (UINT8 *) (((UINTN) &PackageInstance->IfrData) + PackageInstance->IfrSize);\r
+            CopyMem (ExportBuffer, RawData, PackageInstance->StringSize);\r
+            DataTable->DataTableSize = (UINT32) (DataTable->StringDataOffset + PackageInstance->StringSize);\r
+\r
+            CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));\r
+            for (; TempValue != 0;) {\r
+              DataTable->NumberOfLanguages++;\r
+              ExportBuffer = ExportBuffer + ((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length;\r
+              CopyMem (&TempValue, &((EFI_HII_STRING_PACK *) ExportBuffer)->Header.Length, sizeof (UINT32));\r
+            }\r
+\r
+            ExportBuffer = ExportBuffer + sizeof (EFI_HII_STRING_PACK);\r
+          } else {\r
+            DataTable->StringDataOffset = 0;\r
+          }\r
+        }\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetForms (\r
+  IN     EFI_HII_PROTOCOL   *This,\r
+  IN     EFI_HII_HANDLE     Handle,\r
+  IN     EFI_FORM_ID        FormId,\r
+  IN OUT UINTN              *BufferLengthTemp,\r
+  OUT    UINT8              *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  This function allows a program to extract a form or form package that has \r
+  previously been registered with the EFI HII database.\r
+\r
+Arguments:\r
+  This         - A pointer to the EFI_HII_PROTOCOL instance.\r
+  \r
+  Handle       - Handle on which the form resides. Type EFI_HII_HANDLE is defined in \r
+                 EFI_HII_PROTOCOL.NewPack() in the Packages section.\r
+            \r
+  FormId       - The ID of the form to return. If the ID is zero, the entire form package is returned.\r
+                 Type EFI_FORM_ID is defined in "Related Definitions" below.\r
+            \r
+  BufferLength - On input, the length of the Buffer. On output, the length of the returned buffer, if\r
+                 the length was sufficient and, if it was not, the length that is required to fit the\r
+                 requested form(s).\r
+                  \r
+  Buffer       - The buffer designed to receive the form(s).\r
+\r
+Returns: \r
+\r
+  EFI_SUCCESS           -  Buffer filled with the requested forms. BufferLength\r
+                           was updated.\r
+                           \r
+  EFI_INVALID_PARAMETER -  The handle is unknown.\r
+  \r
+  EFI_NOT_FOUND         -  A form on the requested handle cannot be found with the\r
+                           requested FormId.\r
+                           \r
+  EFI_BUFFER_TOO_SMALL  - The buffer provided was not large enough to allow the form to be stored.\r
+\r
+--*/\r
+{\r
+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;\r
+  EFI_HII_DATA              *HiiData;\r
+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;\r
+  EFI_HII_IFR_PACK          *FormPack;\r
+  EFI_IFR_FORM              *Form;\r
+  EFI_IFR_OP_HEADER         *Location;\r
+  UINT16                    *BufferLength = (UINT16 *) BufferLengthTemp;\r
+  UINTN                     FormLength;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  HiiData         = EFI_HII_DATA_FROM_THIS (This);\r
+\r
+  HandleDatabase  = HiiData->DatabaseHead;\r
+\r
+  PackageInstance = NULL;\r
+\r
+  FormLength      = 0;\r
+\r
+  //\r
+  // Check numeric value against the head of the database\r
+  //\r
+  for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {\r
+    //\r
+    // Match the numeric value with the database entry - if matched, extract PackageInstance\r
+    //\r
+    if (Handle == HandleDatabase->Handle) {\r
+      PackageInstance = HandleDatabase->Buffer;\r
+      break;\r
+    }\r
+  }\r
+  //\r
+  // No handle was found - error condition\r
+  //\r
+  if (PackageInstance == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  //\r
+  // Based on if there is IFR data in this package instance, determine\r
+  // what the location is of the beginning of the string data.\r
+  //\r
+  if (PackageInstance->IfrSize > 0) {\r
+    FormPack = (EFI_HII_IFR_PACK *) (&PackageInstance->IfrData);\r
+  } else {\r
+    //\r
+    // If there is no IFR data return an error\r
+    //\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  //\r
+  // If requesting the entire Form Package\r
+  //\r
+  if (FormId == 0) {\r
+    //\r
+    // Return an error if buffer is too small\r
+    //\r
+    if (PackageInstance->IfrSize > *BufferLength || Buffer == NULL) {\r
+      *BufferLength = (UINT16) PackageInstance->IfrSize;\r
+      return EFI_BUFFER_TOO_SMALL;\r
+    }\r
+\r
+    CopyMem (Buffer, FormPack, PackageInstance->IfrSize);\r
+    return EFI_SUCCESS;\r
+  } else {\r
+    FormPack  = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));\r
+    Location  = (EFI_IFR_OP_HEADER *) FormPack;\r
+\r
+    //\r
+    // Look for the FormId requested\r
+    //\r
+    for (; Location->OpCode != EFI_IFR_END_FORM_SET_OP;) {\r
+      switch (Location->OpCode) {\r
+      case EFI_IFR_FORM_OP:\r
+        Form = (EFI_IFR_FORM *) Location;\r
+\r
+        //\r
+        // If we found a Form Op-code and it is of the correct Id, copy it and return\r
+        //\r
+        if (Form->FormId == FormId) {\r
+          //\r
+          // Calculate the total size of form\r
+          //\r
+          for (FormLength = 0; Location->OpCode != EFI_IFR_END_FORM_OP; ) {\r
+            FormLength += Location->Length;\r
+            Location    = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);\r
+          }\r
+          FormLength += Location->Length;\r
+          Location    = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);\r
+\r
+          if ((Buffer == NULL) || (FormLength > *BufferLength)) {\r
+            *BufferLengthTemp = FormLength;\r
+            return EFI_BUFFER_TOO_SMALL;\r
+          }\r
+          \r
+          //\r
+          // Rewind to start offset of the found Form\r
+          //\r
+          Location   = (EFI_IFR_OP_HEADER *) ((CHAR8 *)Location - FormLength);\r
+          CopyMem (Buffer, Location, FormLength);\r
+          return EFI_SUCCESS;\r
+        }\r
+\r
+      default:\r
+        break;\r
+      }\r
+      //\r
+      // Go to the next Op-Code\r
+      //\r
+      Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);\r
+    }\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+//\r
+// Helper functions to HiiGetDefaultImage()\r
+//\r
+\r
+STATIC\r
+UINT8*\r
+HiiGetDefaultImageInitPack (\r
+  IN OUT EFI_HII_VARIABLE_PACK_LIST  *VariablePackItem,\r
+  IN     EFI_IFR_VARSTORE            *VarStore\r
+  )\r
+/*++\r
+    \r
+  Routine Description:\r
+\r
+    Initialize the EFI_HII_VARIABLE_PACK_LIST structure and\r
+    prepare it ready to be used by HiiGetDefaultImagePopulateMap ().\r
+      \r
+  Arguments:\r
+\r
+    VariablePackItem     - Variable Package List.\r
+    VarStore             - IFR variable storage.\r
+   \r
+  Returns: \r
+\r
+    Return the pointer to the Map space.\r
+      \r
+--*/\r
+{\r
+  CHAR16                *Name16;\r
+  CHAR8                 *Name8;\r
+  CHAR8                 *Map;\r
+  EFI_HII_VARIABLE_PACK *VariablePack;\r
+\r
+  //\r
+  // Set pointer the pack right after the node\r
+  //\r
+  VariablePackItem->VariablePack = (EFI_HII_VARIABLE_PACK *) (VariablePackItem + 1);\r
+  VariablePack                   = VariablePackItem->VariablePack;\r
+\r
+  //\r
+  // Copy the var name to VariablePackItem from VarStore\r
+  // Needs ASCII->Unicode conversion.\r
+  //\r
+  ASSERT (VarStore->Header.Length > sizeof (*VarStore));\r
+  Name8  = (CHAR8 *) (VarStore + 1);\r
+  Name16 = (CHAR16 *) (VariablePack + 1);\r
+  Ascii2Unicode (Name16, Name8);\r
+\r
+  //\r
+  // Compute the other fields of the VariablePackItem\r
+  //\r
+  VariablePack->VariableId         = VarStore->VarId;\r
+  CopyMem (&VariablePack->VariableGuid, &VarStore->Guid, sizeof (EFI_GUID));\r
+  VariablePack->VariableNameLength = (UINT32) ((StrLen (Name16) + 1) * 2);\r
+  VariablePack->Header.Length      = sizeof (*VariablePack) \r
+                                              + VariablePack->VariableNameLength\r
+                                              + VarStore->Size;\r
+  //\r
+  // Return the pointer to the Map space.\r
+  //\r
+  Map = (CHAR8 *) Name16 + VariablePack->VariableNameLength;\r
+\r
+  return (UINT8 *)Map;\r
+}\r
+\r
+STATIC\r
+VOID\r
+HiiGetDefaultImagePopulateMap (\r
+  IN OUT UINT8                        *Map,  \r
+  IN     EFI_IFR_OP_HEADER            *FormSet,\r
+  IN     EFI_IFR_VARSTORE             *VarStore,\r
+  IN     UINTN                        DefaultMask\r
+  )\r
+/*++\r
+    \r
+  Routine Description:\r
+\r
+   Fill the Map with all the default values either from NV or Hii database.\r
+      \r
+  Arguments:\r
+\r
+   Map         - Memory pointer to hold the default values.\r
+   FormSet     - The starting EFI_IFR_OP_HEADER to begin retriving default values.\r
+   VarStore    - IFR variable storage.\r
+   DefaultMask - The mask used to get the default variable.\r
+   \r
+  Returns: \r
+\r
+   VOID\r
+      \r
+--*/\r
+{\r
+  EFI_STATUS                     Status;\r
+  EFI_IFR_OP_HEADER              *IfrItem;\r
+  UINT16                         VarId;\r
+  EFI_IFR_VARSTORE_SELECT        *VarSelect;\r
+  EFI_IFR_ONE_OF_OPTION          *OneOfOpt;\r
+  EFI_IFR_CHECKBOX               *CheckBox;\r
+  EFI_IFR_NUMERIC                *Numeric;\r
+  UINTN                          Size;\r
+  UINTN                          SizeTmp;\r
+  EFI_IFR_NV_DATA                *IfrNvData;\r
+  EFI_GUID                       Guid;\r
+  CHAR16                         *Name16;\r
+  CHAR8                          *Name8;  \r
+  EFI_HANDLE                      CallbackHandle;\r
+  EFI_FORM_CALLBACK_PROTOCOL     *FormCallbackProt;\r
+\r
+  //\r
+  // Get the Map's Name/Guid/Szie from the Varstore.\r
+  // VARSTORE contains the Name in ASCII format (@#$^&!), must convert it to Unicode.\r
+  //\r
+  ASSERT (VarStore->Header.Length >= sizeof (*VarStore));\r
+  Name8  = (CHAR8 *) (VarStore + 1);\r
+  Name16 = AllocateZeroPool ((VarStore->Header.Length - sizeof (*VarStore)) * sizeof (CHAR16));\r
+  Ascii2Unicode (Name16, Name8);\r
+  CopyMem (&Guid, &VarStore->Guid, sizeof(EFI_GUID));\r
+  Size = VarStore->Size;\r
+\r
+  //\r
+  // First, check if the map exists in the NV. If so, get it from NV and exit.\r
+  //\r
+  if (DefaultMask == EFI_IFR_FLAG_MANUFACTURING) {\r
+    //\r
+    // Check if Manufaturing Defaults exist in the NV.\r
+    //\r
+    Status = EfiLibHiiVariableOverrideBySuffix (\r
+                  HII_VARIABLE_SUFFIX_MANUFACTURING_OVERRIDE,\r
+                  Name16,\r
+                  &Guid,\r
+                  Size,\r
+                  Map\r
+                  );\r
+  } else {\r
+    //\r
+    // All other cases default to Defaults. Check if Defaults exist in the NV.\r
+    //\r
+    Status = EfiLibHiiVariableOverrideBySuffix (\r
+                  HII_VARIABLE_SUFFIX_DEFAULT_OVERRIDE,\r
+                  Name16,\r
+                  &Guid,\r
+                  Size,\r
+                  Map\r
+                  );\r
+  }\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Either Defaults/Manufacturing variable exists and appears to be valid. \r
+    // The map is read, exit w/ success now.\r
+    //\r
+    FreePool (Name16);\r
+    return;\r
+  }\r
+\r
+  //\r
+  // First, prime the map with what already is in the NV.\r
+  // This is needed to cover a situation where the IFR does not contain all the \r
+  // defaults; either deliberately not having appropriate IFR, or in case of IFR_STRING, there is no default.\r
+  // Ignore status. Either it gets read or not. \r
+  //  \r
+  FormCallbackProt = NULL;\r
+  CopyMem (&CallbackHandle, &((EFI_IFR_FORM_SET*) FormSet)->CallbackHandle, sizeof (CallbackHandle));\r
+  if (CallbackHandle != NULL) {\r
+    Status = gBS->HandleProtocol (\r
+                    (EFI_HANDLE) (UINTN) CallbackHandle,\r
+                    &gEfiFormCallbackProtocolGuid,\r
+                    (VOID *) &FormCallbackProt\r
+                    );\r
+  }\r
+  if ((NULL != FormCallbackProt) && (NULL != FormCallbackProt->NvRead)) {\r
+    //\r
+    // Attempt to read using NvRead() callback. Probe first for existence and correct variable size.\r
+    //\r
+    SizeTmp = 0;\r
+    Status = FormCallbackProt->NvRead (\r
+                    FormCallbackProt,\r
+                    Name16,\r
+                    &Guid,\r
+                    0,\r
+                    &SizeTmp,\r
+                    NULL\r
+                    );\r
+    if ((EFI_BUFFER_TOO_SMALL == Status) && (SizeTmp == Size)) {\r
+      Status = FormCallbackProt->NvRead (\r
+                      FormCallbackProt,\r
+                      Name16,\r
+                      &Guid,\r
+                      0,\r
+                      &SizeTmp,\r
+                      Map\r
+                      );\r
+      ASSERT_EFI_ERROR (Status);\r
+      ASSERT (SizeTmp == Size);\r
+    }\r
+  } else {\r
+    //\r
+    // No callback available for this formset, read straight from NV. Deliberately ignore the Status. \r
+    // The buffer will only be written if variable exists nd has correct size.\r
+    //\r
+    Status = EfiLibHiiVariableRetrieveFromNv (\r
+                    Name16,\r
+                    &Guid,\r
+                    Size,\r
+                    (VOID **) &Map\r
+                    );\r
+  }\r
+\r
+  //\r
+  // Iterate all IFR statements and for applicable, retrieve the default into the Map.\r
+  //\r
+  for (IfrItem = FormSet, VarId = 0; \r
+       IfrItem->OpCode != EFI_IFR_END_FORM_SET_OP; \r
+       IfrItem = (EFI_IFR_OP_HEADER *) ((UINT8*) IfrItem + IfrItem->Length)\r
+      ) {\r
+\r
+    //\r
+    // Observe VarStore switch.\r
+    //\r
+    if (EFI_IFR_VARSTORE_SELECT_OP == IfrItem->OpCode) {\r
+      VarSelect = (EFI_IFR_VARSTORE_SELECT *) IfrItem;\r
+      VarId = VarSelect->VarId;\r
+      continue;\r
+    }\r
+\r
+\r
+    //\r
+    // Skip opcodes that reference other VarStore than that specific to current map.\r
+    // \r
+    if (VarId != VarStore->VarId) {\r
+      continue;\r
+    }\r
+    \r
+    //\r
+    // Extract the default value from this opcode if applicable, and apply it to the map.\r
+    //\r
+    IfrNvData = (EFI_IFR_NV_DATA *) IfrItem;\r
+    switch (IfrItem->OpCode) {\r
+\r
+      case EFI_IFR_ONE_OF_OP:\r
+        ASSERT (IfrNvData->QuestionId + IfrNvData->StorageWidth <= VarStore->Size);\r
+        //\r
+        // Get to the first EFI_IFR_ONE_OF_OPTION_OP\r
+        //\r
+        IfrItem = (EFI_IFR_OP_HEADER *) ((UINT8*) IfrItem + IfrItem->Length); \r
+        ASSERT (EFI_IFR_ONE_OF_OPTION_OP == IfrItem->OpCode);\r
+\r
+        OneOfOpt = (EFI_IFR_ONE_OF_OPTION *)IfrItem;\r
+        //\r
+        // In the worst case, the first will be the default.\r
+        //\r
+        CopyMem (Map + IfrNvData->QuestionId, &OneOfOpt->Value, IfrNvData->StorageWidth);\r
+\r
+        while (EFI_IFR_ONE_OF_OPTION_OP == IfrItem->OpCode) {\r
+\r
+          OneOfOpt = (EFI_IFR_ONE_OF_OPTION *)IfrItem;\r
+            if (DefaultMask == EFI_IFR_FLAG_MANUFACTURING) {\r
+              if (0 != (OneOfOpt->Flags & EFI_IFR_FLAG_MANUFACTURING)) {\r
+                //\r
+                // In the worst case, the first will be the default.\r
+                //\r
+                CopyMem (Map + IfrNvData->QuestionId, &OneOfOpt->Value, IfrNvData->StorageWidth);\r
+                break;\r
+              }\r
+            } else {\r
+              if (OneOfOpt->Flags & EFI_IFR_FLAG_DEFAULT) {\r
+                //\r
+                // In the worst case, the first will be the default.\r
+                //\r
+                CopyMem (Map + IfrNvData->QuestionId, &OneOfOpt->Value, IfrNvData->StorageWidth);\r
+                break;\r
+              }\r
+            }\r
+\r
+          IfrItem = (EFI_IFR_OP_HEADER *)((UINT8*)IfrItem + IfrItem->Length);\r
+        }\r
+        continue;\r
+        break;\r
+\r
+      case EFI_IFR_CHECKBOX_OP:\r
+        ASSERT (IfrNvData->QuestionId + IfrNvData->StorageWidth <= VarStore->Size);\r
+        CheckBox = (EFI_IFR_CHECK_BOX *)IfrItem;        \r
+        if (DefaultMask == EFI_IFR_FLAG_MANUFACTURING) {\r
+          if (0 != (CheckBox->Flags & EFI_IFR_FLAG_MANUFACTURING)) {\r
+            *(UINT8 *) (Map + IfrNvData->QuestionId) = TRUE;\r
+          }\r
+        } else {\r
+          if (CheckBox->Flags & EFI_IFR_FLAG_DEFAULT) {\r
+            *(UINT8 *) (Map + IfrNvData->QuestionId) = TRUE;\r
+          }\r
+        }\r
+        break;\r
+\r
+      case EFI_IFR_NUMERIC_OP:\r
+        ASSERT (IfrNvData->QuestionId + IfrNvData->StorageWidth <= VarStore->Size);\r
+        Numeric = (EFI_IFR_NUMERIC *) IfrItem;\r
+        CopyMem (Map + IfrNvData->QuestionId, &Numeric->Default, IfrNvData->StorageWidth);\r
+        break;\r
+\r
+      case EFI_IFR_ORDERED_LIST_OP:\r
+      case EFI_IFR_PASSWORD_OP:\r
+      case EFI_IFR_STRING_OP:\r
+        //\r
+        // No support for default value for these opcodes.\r
+        //\r
+      break;\r
+    }\r
+  }\r
+\r
+  FreePool (Name16);\r
+\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetDefaultImage (\r
+  IN     EFI_HII_PROTOCOL            *This,\r
+  IN     EFI_HII_HANDLE              Handle,\r
+  IN     UINTN                       DefaultMask,\r
+  OUT    EFI_HII_VARIABLE_PACK_LIST  **VariablePackList\r
+  )\r
+/*++\r
+    \r
+  Routine Description:\r
+\r
+  This function allows a program to extract the NV Image \r
+  that represents the default storage image\r
+      \r
+  Arguments:\r
+    This             - A pointer to the EFI_HII_PROTOCOL instance.\r
+    Handle           - The HII handle from which will have default data retrieved.\r
+    UINTN            - Mask used to retrieve the default image.\r
+    VariablePackList - Callee allocated, tightly-packed, link list data \r
+                         structure that contain all default varaible packs\r
+                         from the Hii Database.\r
+    \r
+  Returns: \r
+    EFI_NOT_FOUND         - If Hii database does not contain any default images.\r
+    EFI_INVALID_PARAMETER - Invalid input parameter.\r
+    EFI_SUCCESS           - Operation successful.\r
+      \r
+--*/\r
+{\r
+  EFI_HII_HANDLE_DATABASE        *HandleDatabase;\r
+  EFI_HII_PACKAGE_INSTANCE       *PackageInstance;\r
+  EFI_IFR_OP_HEADER              *FormSet;\r
+  EFI_IFR_OP_HEADER              *IfrItem;\r
+  EFI_IFR_VARSTORE               *VarStore;\r
+  EFI_IFR_VARSTORE               *VarStoreDefault;\r
+  UINTN                          SetupMapNameSize;\r
+  UINTN                          SizeOfMaps;\r
+  EFI_HII_VARIABLE_PACK_LIST     *PackList;\r
+  EFI_HII_VARIABLE_PACK_LIST     *PackListNext;  \r
+  EFI_HII_VARIABLE_PACK_LIST     *PackListLast;\r
+  UINT8                          *Map;\r
+\r
+\r
+  //\r
+  // Find the IFR pack from the handle. Then get the formset from the pack.\r
+  //\r
+  PackageInstance = NULL;\r
+  HandleDatabase  = (EFI_HII_DATA_FROM_THIS (This))->DatabaseHead;\r
+  for ( ; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {\r
+    if (Handle == HandleDatabase->Handle) {\r
+      PackageInstance = HandleDatabase->Buffer;\r
+      break;\r
+    }\r
+  }\r
+  if (PackageInstance == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  FormSet = (EFI_IFR_OP_HEADER *) ((UINT8 *) &PackageInstance->IfrData + sizeof (EFI_HII_IFR_PACK));\r
+\r
+  //\r
+  // Get the sizes of all the VARSTOREs in this VFR.\r
+  // Then allocate enough space for all of them plus all maps\r
+  //\r
+  SizeOfMaps = 0;\r
+  IfrItem    = FormSet;\r
+  while (EFI_IFR_END_FORM_SET_OP != IfrItem->OpCode) {\r
+\r
+    if (EFI_IFR_VARSTORE_OP == IfrItem->OpCode) {\r
+      VarStore = (EFI_IFR_VARSTORE *) IfrItem;\r
+      //\r
+      // Size of the map\r
+      //\r
+      SizeOfMaps += VarStore->Size; \r
+      //\r
+      // add the size of the string, in Unicode\r
+      //\r
+      SizeOfMaps += (VarStore->Header.Length - sizeof (*VarStore)) * 2; \r
+      //\r
+      // Space for node\r
+      //\r
+      SizeOfMaps += sizeof (EFI_HII_VARIABLE_PACK);      \r
+      //\r
+      // Space for linked list node \r
+      //\r
+      SizeOfMaps += sizeof (EFI_HII_VARIABLE_PACK_LIST); \r
+    }\r
+\r
+    IfrItem = (EFI_IFR_OP_HEADER *) ((UINT8 *) IfrItem + IfrItem->Length);\r
+  }\r
+\r
+  //\r
+  // If the FormSet OpCode has a non-zero NvDataSize. There is a default \r
+  // NvMap with ID=0, GUID that of the formset itself and "Setup" as name.\r
+  //\r
+  SetupMapNameSize = StrLen (SETUP_MAP_NAME) + 1;\r
+  VarStoreDefault  = AllocateZeroPool (sizeof (*VarStoreDefault) + SetupMapNameSize);\r
+\r
+  if (0 != ((EFI_IFR_FORM_SET*)FormSet)->NvDataSize) {\r
+\r
+    VarStoreDefault->Header.OpCode = EFI_IFR_VARSTORE_OP;\r
+    VarStoreDefault->Header.Length = (UINT8) (sizeof (*VarStoreDefault) + SetupMapNameSize);\r
+    Unicode2Ascii ((CHAR8 *) (VarStoreDefault + 1), SETUP_MAP_NAME);\r
+    CopyMem (&VarStoreDefault->Guid, &((EFI_IFR_FORM_SET*) FormSet)->Guid, sizeof (EFI_GUID));\r
+    VarStoreDefault->VarId = 0;\r
+    VarStoreDefault->Size = ((EFI_IFR_FORM_SET*) FormSet)->NvDataSize;\r
+\r
+    //\r
+    // Size of the map\r
+    //\r
+    SizeOfMaps += VarStoreDefault->Size; \r
+    //\r
+    // add the size of the string\r
+    //\r
+    SizeOfMaps += sizeof (SETUP_MAP_NAME); \r
+    //\r
+    // Space for node\r
+    //\r
+    SizeOfMaps += sizeof (EFI_HII_VARIABLE_PACK);      \r
+    //\r
+    // Space for linked list node \r
+    //\r
+    SizeOfMaps += sizeof (EFI_HII_VARIABLE_PACK_LIST); \r
+  }\r
+\r
+  if (0 == SizeOfMaps) {\r
+    //\r
+    // The IFR does not have any explicit or default map(s).\r
+    //\r
+    return EFI_NOT_FOUND; \r
+  }\r
+\r
+  //\r
+  // Allocate the return buffer\r
+  //\r
+  PackList = AllocateZeroPool (SizeOfMaps);\r
+  ASSERT (NULL != PackList); \r
+\r
+  PackListNext = PackList;\r
+  PackListLast = PackList;\r
+\r
+  //\r
+  // Handle the default map first, if any.\r
+  //\r
+  if (0 != VarStoreDefault->Size) {\r
+\r
+    Map = HiiGetDefaultImageInitPack (PackListNext, VarStoreDefault);\r
+\r
+    HiiGetDefaultImagePopulateMap (Map, FormSet, VarStoreDefault, DefaultMask);\r
+\r
+    PackListNext->NextVariablePack = (EFI_HII_VARIABLE_PACK_LIST *) ((UINT8 *) PackListNext->VariablePack + PackListNext->VariablePack->Header.Length);\r
+    PackListLast = PackListNext;\r
+    PackListNext = PackListNext->NextVariablePack;\r
+  }\r
+\r
+\r
+  //\r
+  // Handle the explicit varstore(s)\r
+  //\r
+  IfrItem = FormSet;\r
+  while (EFI_IFR_END_FORM_SET_OP != IfrItem->OpCode) {\r
+\r
+    if (EFI_IFR_VARSTORE_OP == IfrItem->OpCode) {\r
+\r
+      Map = HiiGetDefaultImageInitPack (PackListNext, (EFI_IFR_VARSTORE *) IfrItem);\r
+\r
+      HiiGetDefaultImagePopulateMap (Map, FormSet, (EFI_IFR_VARSTORE *) IfrItem, DefaultMask);\r
+\r
+      PackListNext->NextVariablePack = (EFI_HII_VARIABLE_PACK_LIST *) ((UINT8 *) PackListNext->VariablePack + PackListNext->VariablePack->Header.Length);\r
+      PackListLast = PackListNext;\r
+      PackListNext = PackListNext->NextVariablePack;\r
+    }\r
+\r
+    IfrItem = (EFI_IFR_OP_HEADER *) ((UINT8 *) IfrItem + IfrItem->Length);\r
+  }\r
+\r
+  PackListLast->NextVariablePack = NULL;\r
+  *VariablePackList = PackList;\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiUpdateForm (\r
+  IN EFI_HII_PROTOCOL       *This,\r
+  IN EFI_HII_HANDLE         Handle,\r
+  IN EFI_FORM_LABEL         Label,\r
+  IN BOOLEAN                AddData,\r
+  IN EFI_HII_UPDATE_DATA    *Data\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  This function allows the caller to update a form that has \r
+  previously been registered with the EFI HII database.\r
+\r
+Arguments:\r
+  Handle     - Hii Handle associated with the Formset to modify\r
+  Label      - Update information starting immediately after this label in the IFR\r
+  AddData    - If TRUE, add data.  If FALSE, remove data\r
+  Data       - If adding data, this is the pointer to the data to add\r
+\r
+Returns: \r
+  EFI_SUCCESS - Update success.\r
+  Other       - Update fail.\r
+\r
+--*/\r
+{\r
+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;\r
+  EFI_HII_DATA              *HiiData;\r
+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;\r
+  EFI_HII_IFR_PACK          *FormPack;\r
+  EFI_IFR_OP_HEADER         *Location;\r
+  EFI_IFR_OP_HEADER         *DataLocation;\r
+  UINT8                     *OtherBuffer;\r
+  UINT8                     *TempBuffer;\r
+  UINT8                     *OrigTempBuffer;\r
+  UINTN                     TempBufferSize;\r
+  UINTN                     Index;\r
+\r
+  OtherBuffer = NULL;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  HiiData         = EFI_HII_DATA_FROM_THIS (This);\r
+\r
+  HandleDatabase  = HiiData->DatabaseHead;\r
+\r
+  PackageInstance = NULL;\r
+\r
+  //\r
+  // Check numeric value against the head of the database\r
+  //\r
+  for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {\r
+    //\r
+    // Match the numeric value with the database entry - if matched, extract PackageInstance\r
+    //\r
+    if (Handle == HandleDatabase->Handle) {\r
+      PackageInstance = HandleDatabase->Buffer;\r
+      break;\r
+    }\r
+  }\r
+  //\r
+  // No handle was found - error condition\r
+  //\r
+  if (PackageInstance == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Calculate and allocate space for retrieval of IFR data\r
+  //\r
+  DataLocation    = (EFI_IFR_OP_HEADER *) &Data->Data;\r
+  TempBufferSize  = (CHAR8 *) (&PackageInstance->IfrData) - (CHAR8 *) (PackageInstance);\r
+\r
+  for (Index = 0; Index < Data->DataCount; Index++) {\r
+    TempBufferSize += DataLocation->Length;\r
+    DataLocation = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (DataLocation) + DataLocation->Length);\r
+  }\r
+\r
+  TempBufferSize += PackageInstance->IfrSize + PackageInstance->StringSize;\r
+\r
+  TempBuffer      = AllocateZeroPool (TempBufferSize);\r
+  ASSERT (TempBuffer != NULL);\r
+\r
+  OrigTempBuffer  = TempBuffer;\r
+\r
+  //\r
+  // We update only packages with IFR information in it\r
+  //\r
+  if (PackageInstance->IfrSize == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  CopyMem (\r
+    TempBuffer,\r
+    PackageInstance,\r
+    ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER) - (CHAR8 *) (PackageInstance))\r
+    );\r
+\r
+  TempBuffer = TempBuffer + ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER) - (CHAR8 *) (PackageInstance));\r
+\r
+  //\r
+  // Based on if there is IFR data in this package instance, determine\r
+  // what the location is of the beginning of the string data.\r
+  //\r
+  FormPack  = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));\r
+  Location  = (EFI_IFR_OP_HEADER *) FormPack;\r
+\r
+  //\r
+  // Look for the FormId requested\r
+  //\r
+  for (; Location->OpCode != EFI_IFR_END_FORM_SET_OP;) {\r
+    switch (Location->OpCode) {\r
+    case EFI_IFR_FORM_SET_OP:\r
+      //\r
+      // If the FormSet has an update pending, pay attention.\r
+      //\r
+      if (Data->FormSetUpdate) {\r
+        ((EFI_IFR_FORM_SET *) Location)->CallbackHandle = Data->FormCallbackHandle;\r
+      }\r
+\r
+      CopyMem (TempBuffer, Location, Location->Length);\r
+      TempBuffer = TempBuffer + Location->Length;\r
+      break;\r
+\r
+    case EFI_IFR_FORM_OP:\r
+      //\r
+      // If the Form has an update pending, pay attention.\r
+      //\r
+      if (Data->FormUpdate) {\r
+        ((EFI_IFR_FORM *) Location)->FormTitle = Data->FormTitle;\r
+      }\r
+\r
+      CopyMem (TempBuffer, Location, Location->Length);\r
+      TempBuffer = TempBuffer + Location->Length;\r
+      break;\r
+\r
+    case EFI_IFR_LABEL_OP:\r
+      //\r
+      // If the label does not match the requested update point, ignore it\r
+      //\r
+      if (((EFI_IFR_LABEL *) Location)->LabelId != Label) {\r
+        //\r
+        // Copy the label\r
+        //\r
+        CopyMem (TempBuffer, Location, Location->Length);\r
+        TempBuffer = TempBuffer + Location->Length;\r
+\r
+        //\r
+        // Go to the next Op-Code\r
+        //\r
+        Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);\r
+        continue;\r
+      }\r
+\r
+      if (AddData) {\r
+        //\r
+        // Copy the label\r
+        //\r
+        CopyMem (TempBuffer, Location, Location->Length);\r
+        TempBuffer = TempBuffer + Location->Length;\r
+\r
+        //\r
+        // Add the DataCount amount of opcodes to TempBuffer\r
+        //\r
+        DataLocation = (EFI_IFR_OP_HEADER *) &Data->Data;\r
+        for (Index = 0; Index < Data->DataCount; Index++) {\r
+          CopyMem (TempBuffer, DataLocation, DataLocation->Length);\r
+          ((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->IfrSize += DataLocation->Length;\r
+          OtherBuffer = ((UINT8 *) &((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->StringSize + sizeof (UINTN));\r
+          CopyMem (OtherBuffer, &((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->IfrSize, 2);\r
+          TempBuffer    = TempBuffer + DataLocation->Length;\r
+          DataLocation  = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (DataLocation) + DataLocation->Length);\r
+        }\r
+        //\r
+        // Go to the next Op-Code\r
+        //\r
+        Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);\r
+        continue;\r
+      } else {\r
+        //\r
+        // Copy the label\r
+        //\r
+        CopyMem (TempBuffer, Location, Location->Length);\r
+        TempBuffer  = TempBuffer + Location->Length;\r
+        Location    = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);\r
+\r
+        //\r
+        // Remove the DataCount amount of opcodes unless we run into an end of form or a label\r
+        //\r
+        for (Index = 0; Index < Data->DataCount; Index++) {\r
+          //\r
+          // If we are about to skip an end form - bail out, since that is illegal\r
+          //\r
+          if ((Location->OpCode == EFI_IFR_END_FORM_OP) || (Location->OpCode == EFI_IFR_LABEL_OP)) {\r
+            break;\r
+          }\r
+          //\r
+          // By skipping Location entries, we are in effect not copying what was previously there\r
+          //\r
+          ((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->IfrSize -= Location->Length;\r
+          OtherBuffer = ((UINT8 *) &((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->StringSize + sizeof (UINTN));\r
+          CopyMem (OtherBuffer, &((EFI_HII_PACKAGE_INSTANCE *) OrigTempBuffer)->IfrSize, 2);\r
+          Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);\r
+        }\r
+      }\r
+\r
+    default:\r
+      CopyMem (TempBuffer, Location, Location->Length);\r
+      TempBuffer = TempBuffer + Location->Length;\r
+      break;\r
+    }\r
+    //\r
+    // Go to the next Op-Code\r
+    //\r
+    Location = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);\r
+  }\r
+  //\r
+  // Copy the last op-code left behind from the for loop\r
+  //\r
+  CopyMem (TempBuffer, Location, Location->Length);\r
+\r
+  //\r
+  // Advance to beginning of strings and copy them\r
+  //\r
+  TempBuffer  = TempBuffer + Location->Length;\r
+  Location    = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (Location) + Location->Length);\r
+  CopyMem (TempBuffer, Location, PackageInstance->StringSize);\r
+\r
+  //\r
+  // Free the old buffer, and assign into our database the latest buffer\r
+  //\r
+  FreePool (HandleDatabase->Buffer);\r
+  HandleDatabase->Buffer = OrigTempBuffer;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.c b/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.c
new file mode 100644 (file)
index 0000000..cac37e5
--- /dev/null
@@ -0,0 +1,412 @@
+/*++\r
+\r
+Copyright (c) 2006 - 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
+  HiiDatabase.c\r
+\r
+Abstract:\r
+\r
+  This file contains the entry code to the HII database.\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "HiiDatabase.h"\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeHiiDatabase (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Initialize HII Database\r
+  \r
+Arguments:\r
+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
+\r
+Returns: \r
+  EFI_SUCCESS - Setup loaded.\r
+  other       - Setup Error\r
+\r
+--*/\r
+{\r
+  EFI_STATUS          Status;\r
+  EFI_HII_DATA        *HiiData;\r
+  EFI_HII_GLOBAL_DATA *GlobalData;\r
+  EFI_HANDLE          *HandleBuffer;\r
+  EFI_HANDLE          Handle;\r
+  UINTN               HandleCount;\r
+  UINTN               Index;\r
+\r
+  //\r
+  // There will be only one HII Database in the system\r
+  // If there is another out there, someone is trying to install us\r
+  // again.  Fail that scenario.\r
+  //\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiHiiProtocolGuid,\r
+                  NULL,\r
+                  &HandleCount,\r
+                  &HandleBuffer\r
+                  );\r
+\r
+  //\r
+  // If there was no error, assume there is an installation and fail to load\r
+  //\r
+  if (!EFI_ERROR (Status)) {\r
+    if (HandleBuffer != NULL) {\r
+      FreePool (HandleBuffer);\r
+    }\r
+\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  HiiData = AllocatePool (sizeof (EFI_HII_DATA));\r
+\r
+  ASSERT (HiiData);\r
+\r
+  GlobalData = AllocateZeroPool (sizeof (EFI_HII_GLOBAL_DATA));\r
+\r
+  ASSERT (GlobalData);\r
+\r
+  //\r
+  // Seed the Font Database with a known non-character glyph\r
+  //\r
+  for (Index = 0; Index <= MAX_GLYPH_COUNT; Index++) {\r
+    //\r
+    // Seeding the UnicodeWeight with 0 signifies that it is uninitialized\r
+    //\r
+    GlobalData->NarrowGlyphs[Index].UnicodeWeight = 0;\r
+    GlobalData->WideGlyphs[Index].UnicodeWeight   = 0;\r
+    GlobalData->NarrowGlyphs[Index].Attributes    = 0;\r
+    GlobalData->WideGlyphs[Index].Attributes      = 0;\r
+    CopyMem (GlobalData->NarrowGlyphs[Index].GlyphCol1, &mUnknownGlyph, NARROW_GLYPH_ARRAY_SIZE);\r
+    CopyMem (GlobalData->WideGlyphs[Index].GlyphCol1, &mUnknownGlyph, WIDE_GLYPH_ARRAY_SIZE);\r
+  }\r
+  //\r
+  // Fill in HII data\r
+  //\r
+  HiiData->Signature                        = EFI_HII_DATA_SIGNATURE;\r
+  HiiData->GlobalData                       = GlobalData;\r
+  HiiData->GlobalData->SystemKeyboardUpdate = FALSE;\r
+  HiiData->DatabaseHead                     = NULL;\r
+  HiiData->Hii.NewPack                      = HiiNewPack;\r
+  HiiData->Hii.RemovePack                   = HiiRemovePack;\r
+  HiiData->Hii.FindHandles                  = HiiFindHandles;\r
+  HiiData->Hii.ExportDatabase               = HiiExportDatabase;\r
+  HiiData->Hii.GetGlyph                     = HiiGetGlyph;\r
+  HiiData->Hii.GetPrimaryLanguages          = HiiGetPrimaryLanguages;\r
+  HiiData->Hii.GetSecondaryLanguages        = HiiGetSecondaryLanguages;\r
+  HiiData->Hii.NewString                    = HiiNewString;\r
+  HiiData->Hii.GetString                    = HiiGetString;\r
+  HiiData->Hii.ResetStrings                 = HiiResetStrings;\r
+  HiiData->Hii.TestString                   = HiiTestString;\r
+  HiiData->Hii.GetLine                      = HiiGetLine;\r
+  HiiData->Hii.GetForms                     = HiiGetForms;\r
+  HiiData->Hii.GetDefaultImage              = HiiGetDefaultImage;\r
+  HiiData->Hii.UpdateForm                   = HiiUpdateForm;\r
+  HiiData->Hii.GetKeyboardLayout            = HiiGetKeyboardLayout;\r
+  HiiData->Hii.GlyphToBlt                   = HiiGlyphToBlt;\r
+\r
+  //\r
+  // Install protocol interface\r
+  //\r
+  Handle = NULL;\r
+  Status = gBS->InstallProtocolInterface (\r
+                  &Handle,\r
+                  &gEfiHiiProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  &HiiData->Hii\r
+                  );\r
+\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiFindHandles (\r
+  IN     EFI_HII_PROTOCOL *This,\r
+  IN OUT UINT16           *HandleBufferLength,\r
+  OUT    EFI_HII_HANDLE   Handle[1]\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Determines the handles that are currently active in the database.\r
+  \r
+Arguments:\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  EFI_HII_HANDLE_DATABASE *Database;\r
+  EFI_HII_DATA            *HiiData;\r
+  UINTN                   HandleCount;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  HiiData     = EFI_HII_DATA_FROM_THIS (This);\r
+\r
+  Database    = HiiData->DatabaseHead;\r
+\r
+  if (Database == NULL) {\r
+    *HandleBufferLength = 0;\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  for (HandleCount = 0; Database != NULL; HandleCount++) {\r
+    Database = Database->NextHandleDatabase;\r
+  }\r
+  //\r
+  // Is there a sufficient buffer for the data being passed back?\r
+  //\r
+  if (*HandleBufferLength >= (sizeof (EFI_HII_HANDLE) * HandleCount)) {\r
+    Database = HiiData->DatabaseHead;\r
+\r
+    //\r
+    // Copy the Head information\r
+    //\r
+    if (Database->Handle != 0) {\r
+      CopyMem (&Handle[0], &Database->Handle, sizeof (EFI_HII_HANDLE));\r
+      Database = Database->NextHandleDatabase;\r
+    }\r
+    //\r
+    // Copy more data if appropriate\r
+    //\r
+    for (HandleCount = 1; Database != NULL; HandleCount++) {\r
+      CopyMem (&Handle[HandleCount], &Database->Handle, sizeof (EFI_HII_HANDLE));\r
+      Database = Database->NextHandleDatabase;\r
+    }\r
+\r
+    *HandleBufferLength = (UINT16) (sizeof (EFI_HII_HANDLE) * HandleCount);\r
+    return EFI_SUCCESS;\r
+  } else {\r
+    //\r
+    // Insufficient buffer length\r
+    //\r
+    *HandleBufferLength = (UINT16) (sizeof (EFI_HII_HANDLE) * HandleCount);\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetPrimaryLanguages (\r
+  IN  EFI_HII_PROTOCOL      *This,\r
+  IN  EFI_HII_HANDLE        Handle,\r
+  OUT EFI_STRING            *LanguageString\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  This function allows a program to determine what the primary languages that are supported on a given handle.\r
+\r
+Arguments:\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  UINTN                     Count;\r
+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;\r
+  EFI_HII_PACKAGE_INSTANCE  *StringPackageInstance;\r
+  EFI_HII_DATA              *HiiData;\r
+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;\r
+  EFI_HII_STRING_PACK       *StringPack;\r
+  EFI_HII_STRING_PACK       *Location;\r
+  UINT32                    Length;\r
+  RELOFST                   Token;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  HiiData         = EFI_HII_DATA_FROM_THIS (This);\r
+\r
+  PackageInstance = NULL;\r
+  //\r
+  // Find matching handle in the handle database. Then get the package instance.\r
+  //\r
+  for (HandleDatabase = HiiData->DatabaseHead;\r
+       HandleDatabase != NULL;\r
+       HandleDatabase = HandleDatabase->NextHandleDatabase\r
+      ) {\r
+    if (Handle == HandleDatabase->Handle) {\r
+      PackageInstance = HandleDatabase->Buffer;\r
+    }\r
+  }\r
+  //\r
+  // No handle was found - error condition\r
+  //\r
+  if (PackageInstance == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);\r
+\r
+  //\r
+  // Based on if there is IFR data in this package instance, determine\r
+  // what the location is of the beginning of the string data.\r
+  //\r
+  if (StringPackageInstance->IfrSize > 0) {\r
+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);\r
+  } else {\r
+    StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);\r
+  }\r
+\r
+  Location = StringPack;\r
+  //\r
+  // Remember that the string packages are formed into contiguous blocks of language data.\r
+  //\r
+  CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+  for (Count = 0; Length != 0; Count = Count + 3) {\r
+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);\r
+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+  }\r
+\r
+  *LanguageString = AllocateZeroPool (2 * (Count + 1));\r
+\r
+  ASSERT (*LanguageString);\r
+\r
+  StringPack = (EFI_HII_STRING_PACK *) Location;\r
+\r
+  //\r
+  // Copy the 6 bytes to LanguageString - keep concatenating it.  Shouldn't we just store uint8's since the ISO\r
+  // standard defines the lettering as all US English characters anyway?  Save a few bytes.\r
+  //\r
+  CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+  for (Count = 0; Length != 0; Count = Count + 3) {\r
+    CopyMem (&Token, &StringPack->LanguageNameString, sizeof (RELOFST));\r
+    CopyMem (*LanguageString + Count, (VOID *) ((CHAR8 *) (StringPack) + Token), 6);\r
+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);\r
+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetSecondaryLanguages (\r
+  IN  EFI_HII_PROTOCOL      *This,\r
+  IN  EFI_HII_HANDLE        Handle,\r
+  IN  CHAR16                *PrimaryLanguage,\r
+  OUT EFI_STRING            *LanguageString\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  This function allows a program to determine which secondary languages are supported \r
+  on a given handle for a given primary language.\r
+\r
+  Arguments:\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  UINTN                     Count;\r
+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;\r
+  EFI_HII_PACKAGE_INSTANCE  *StringPackageInstance;\r
+  EFI_HII_DATA              *HiiData;\r
+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;\r
+  EFI_HII_STRING_PACK       *StringPack;\r
+  RELOFST                   Token;\r
+  UINT32                    Length;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  HiiData = EFI_HII_DATA_FROM_THIS (This);\r
+  //\r
+  // Check numeric value against the head of the database\r
+  //\r
+  PackageInstance = NULL;\r
+  for (HandleDatabase = HiiData->DatabaseHead;\r
+       HandleDatabase != NULL;\r
+       HandleDatabase = HandleDatabase->NextHandleDatabase\r
+      ) {\r
+    //\r
+    // Match the numeric value with the database entry - if matched, extract PackageInstance\r
+    //\r
+    if (Handle == HandleDatabase->Handle) {\r
+      PackageInstance = HandleDatabase->Buffer;\r
+    }\r
+  }\r
+  //\r
+  // No handle was found - error condition\r
+  //\r
+  if (PackageInstance == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);\r
+\r
+  //\r
+  // Based on if there is IFR data in this package instance, determine\r
+  // what the location is of the beginning of the string data.\r
+  //\r
+  if (StringPackageInstance->IfrSize > 0) {\r
+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);\r
+  } else {\r
+    StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);\r
+  }\r
+\r
+  //\r
+  // Remember that the string packages are formed into contiguous blocks of language data.\r
+  //\r
+  for (; StringPack->Header.Length != 0;) {\r
+    //\r
+    // Find the PrimaryLanguage being requested\r
+    //\r
+    Token = StringPack->LanguageNameString;\r
+    if (CompareMem ((VOID *) ((CHAR8 *) (StringPack) + Token), PrimaryLanguage, 3) == 0) {\r
+      //\r
+      // Now that we found the primary, the secondary languages will follow immediately\r
+      // or the next character is a NULL if there are no secondary languages.  We determine\r
+      // the number by getting the stringsize based on the StringPack origination + the LanguageNameString\r
+      // offset + 6 (which is the size of the first 3 letter ISO primary language name).  If we get 2, there\r
+      // are no secondary languages (2 = null-terminator).\r
+      //\r
+      Count           = StrSize ((VOID *) ((CHAR8 *) (StringPack) + Token + 6));\r
+\r
+      *LanguageString = AllocateZeroPool (2 * (Count + 1));\r
+\r
+      ASSERT (*LanguageString);\r
+\r
+      CopyMem (*LanguageString, (VOID *) ((CHAR8 *) (StringPack) + Token + 6), Count);\r
+      break;\r
+    }\r
+\r
+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
diff --git a/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.dxs b/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.dxs
new file mode 100644 (file)
index 0000000..3e1fa13
--- /dev/null
@@ -0,0 +1,30 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  HiiDatabase.dxs\r
+\r
+Abstract:\r
+\r
+  Dependency expression source file.\r
+  \r
+--*/\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <DxeDepex.h>\r
+\r
+DEPENDENCY_START\r
+  TRUE\r
+DEPENDENCY_END\r
diff --git a/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.h b/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.h
new file mode 100644 (file)
index 0000000..adfc31c
--- /dev/null
@@ -0,0 +1,307 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  HiiDatabase.h\r
+\r
+Abstract:\r
+\r
+  This file contains global defines and prototype definitions \r
+  for the HII database.\r
+\r
+--*/\r
+\r
+#ifndef _HIIDATABASE_H\r
+#define _HIIDATABASE_H\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+//\r
+// HII Database Global data\r
+//\r
+#define EFI_HII_DATA_SIGNATURE            EFI_SIGNATURE_32 ('H', 'i', 'i', 'P')\r
+\r
+#define MAX_GLYPH_COUNT                   65535\r
+#define NARROW_GLYPH_ARRAY_SIZE           19\r
+#define WIDE_GLYPH_ARRAY_SIZE             38\r
+\r
+#define SETUP_MAP_NAME                              L"Setup"\r
+#define HII_VARIABLE_SUFFIX_USER_DATA               L"UserSavedData"\r
+#define HII_VARIABLE_SUFFIX_DEFAULT_OVERRIDE        L"DefaultOverride"\r
+#define HII_VARIABLE_SUFFIX_MANUFACTURING_OVERRIDE  L"ManufacturingOverride"\r
+\r
+typedef struct _EFI_HII_HANDLE_DATABASE {\r
+  VOID                            *Buffer;        // Actual buffer pointer\r
+  EFI_HII_HANDLE                  Handle;         // Monotonically increasing value to signify the value returned to caller\r
+  UINT32                          NumberOfTokens; // The initial number of tokens when first registered\r
+  struct _EFI_HII_HANDLE_DATABASE *NextHandleDatabase;\r
+} EFI_HII_HANDLE_DATABASE;\r
+\r
+typedef struct {\r
+  EFI_NARROW_GLYPH    NarrowGlyphs[MAX_GLYPH_COUNT];\r
+  EFI_WIDE_GLYPH      WideGlyphs[MAX_GLYPH_COUNT];\r
+  EFI_KEY_DESCRIPTOR  SystemKeyboardLayout[106];\r
+  EFI_KEY_DESCRIPTOR  OverrideKeyboardLayout[106];\r
+  BOOLEAN             SystemKeyboardUpdate;       // Has the SystemKeyboard been updated?\r
+} EFI_HII_GLOBAL_DATA;\r
+\r
+typedef struct {\r
+  UINTN                   Signature;\r
+\r
+  EFI_HII_GLOBAL_DATA     *GlobalData;\r
+  EFI_HII_HANDLE_DATABASE *DatabaseHead;          // Head of the Null-terminated singly-linked list of handles.\r
+  EFI_HII_PROTOCOL        Hii;\r
+} EFI_HII_DATA;\r
+\r
+typedef struct {\r
+  EFI_HII_HANDLE      Handle;\r
+  EFI_GUID            Guid;\r
+  EFI_HII_HANDLE_PACK HandlePack;\r
+  UINTN               IfrSize;\r
+  UINTN               StringSize;\r
+  EFI_HII_IFR_PACK    *IfrData;                   // All the IFR data stored here\r
+  EFI_HII_STRING_PACK *StringData;                // All the String data stored at &IfrData + IfrSize (StringData is just a label - never referenced)\r
+} EFI_HII_PACKAGE_INSTANCE;\r
+\r
+typedef struct {\r
+  EFI_HII_PACK_HEADER   Header;\r
+  EFI_IFR_FORM_SET      FormSet;\r
+  EFI_IFR_END_FORM_SET  EndFormSet;\r
+} EFI_FORM_SET_STUB;\r
+\r
+#define EFI_HII_DATA_FROM_THIS(a) CR (a, EFI_HII_DATA, Hii, EFI_HII_DATA_SIGNATURE)\r
+\r
+#define NARROW_WIDTH              8\r
+#define WIDE_WIDTH                16\r
+\r
+extern UINT8  mUnknownGlyph[38];\r
+\r
+//\r
+// Prototypes\r
+//\r
+EFI_STATUS\r
+GetPackSize (\r
+  IN  VOID                *Pack,\r
+  OUT UINTN               *PackSize,\r
+  OUT UINT32              *NumberOfTokens\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+ValidatePack (\r
+  IN   EFI_HII_PROTOCOL          *This,\r
+  IN   EFI_HII_PACKAGE_INSTANCE  *PackageInstance,\r
+  OUT  EFI_HII_PACKAGE_INSTANCE  **StringPackageInstance,\r
+  OUT  UINT32                    *TotalStringCount\r
+  )\r
+;\r
+\r
+//\r
+// Public Interface Prototypes\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeHiiDatabase (\r
+  IN EFI_HANDLE             ImageHandle,\r
+  IN EFI_SYSTEM_TABLE       *SystemTable\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiNewPack (\r
+  IN  EFI_HII_PROTOCOL      *This,\r
+  IN  EFI_HII_PACKAGES      *PackageList,\r
+  OUT EFI_HII_HANDLE        *Handle\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiRemovePack (\r
+  IN EFI_HII_PROTOCOL    *This,\r
+  IN EFI_HII_HANDLE      Handle\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiFindHandles (\r
+  IN     EFI_HII_PROTOCOL    *This,\r
+  IN OUT UINT16              *HandleBufferLength,\r
+  OUT    EFI_HII_HANDLE      *Handle\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiExportDatabase (\r
+  IN     EFI_HII_PROTOCOL *This,\r
+  IN     EFI_HII_HANDLE   Handle,\r
+  IN OUT UINTN            *BufferSize,\r
+  OUT    VOID             *Buffer\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetGlyph (\r
+  IN     EFI_HII_PROTOCOL    *This,\r
+  IN     CHAR16              *Source,\r
+  IN OUT UINT16              *Index,\r
+  OUT    UINT8               **GlyphBuffer,\r
+  OUT    UINT16              *BitWidth,\r
+  IN OUT UINT32              *InternalStatus\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGlyphToBlt (\r
+  IN     EFI_HII_PROTOCOL              *This,\r
+  IN     UINT8                         *GlyphBuffer,\r
+  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,\r
+  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,\r
+  IN     UINTN                         Count,\r
+  IN     UINTN                         Width,\r
+  IN     UINTN                         Height,\r
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiNewString (\r
+  IN     EFI_HII_PROTOCOL        *This,\r
+  IN     CHAR16                  *Language,\r
+  IN     EFI_HII_HANDLE          Handle,\r
+  IN OUT STRING_REF              *Reference,\r
+  IN     CHAR16                  *NewString\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetString (\r
+  IN     EFI_HII_PROTOCOL    *This,\r
+  IN     EFI_HII_HANDLE      Handle,\r
+  IN     STRING_REF          Token,\r
+  IN     BOOLEAN             Raw,\r
+  IN     CHAR16              *LanguageString,\r
+  IN OUT UINTN               *BufferLength,\r
+  OUT    EFI_STRING          StringBuffer\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiResetStrings (\r
+  IN     EFI_HII_PROTOCOL    *This,\r
+  IN     EFI_HII_HANDLE      Handle\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiTestString (\r
+  IN     EFI_HII_PROTOCOL    *This,\r
+  IN     CHAR16              *StringToTest,\r
+  IN OUT UINT32              *FirstMissing,\r
+  OUT    UINT32              *GlyphBufferSize\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetPrimaryLanguages (\r
+  IN  EFI_HII_PROTOCOL      *This,\r
+  IN  EFI_HII_HANDLE        Handle,\r
+  OUT EFI_STRING            *LanguageString\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetSecondaryLanguages (\r
+  IN  EFI_HII_PROTOCOL      *This,\r
+  IN  EFI_HII_HANDLE        Handle,\r
+  IN  CHAR16                *PrimaryLanguage,\r
+  OUT EFI_STRING            *LanguageString\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetLine (\r
+  IN     EFI_HII_PROTOCOL    *This,\r
+  IN     EFI_HII_HANDLE      Handle,\r
+  IN     STRING_REF          Token,\r
+  IN OUT UINT16              *Index,\r
+  IN     UINT16              LineWidth,\r
+  IN     CHAR16              *LanguageString,\r
+  IN OUT UINT16              *BufferLength,\r
+  OUT    EFI_STRING          StringBuffer\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetForms (\r
+  IN     EFI_HII_PROTOCOL    *This,\r
+  IN     EFI_HII_HANDLE      Handle,\r
+  IN     EFI_FORM_ID         FormId,\r
+  IN OUT UINTN               *BufferLength,\r
+  OUT    UINT8               *Buffer\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetDefaultImage (\r
+  IN     EFI_HII_PROTOCOL           *This,\r
+  IN     EFI_HII_HANDLE             Handle,\r
+  IN     UINTN                      DefaultMask,\r
+  OUT    EFI_HII_VARIABLE_PACK_LIST **VariablePackList\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiUpdateForm (\r
+  IN EFI_HII_PROTOCOL       *This,\r
+  IN EFI_HII_HANDLE         Handle,\r
+  IN EFI_FORM_LABEL         Label,\r
+  IN BOOLEAN                AddData,\r
+  IN EFI_HII_UPDATE_DATA    *Data\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetKeyboardLayout (\r
+  IN     EFI_HII_PROTOCOL    *This,\r
+  OUT    UINT16              *DescriptorCount,\r
+  OUT    EFI_KEY_DESCRIPTOR  *Descriptor\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+HiiCompareLanguage (\r
+  IN  CHAR16                *LanguageStringLocation,\r
+  IN  CHAR16                *Language\r
+  )\r
+;\r
+\r
+#endif\r
diff --git a/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.inf b/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.inf
new file mode 100644 (file)
index 0000000..216a47a
--- /dev/null
@@ -0,0 +1,116 @@
+#/** @file\r
+# Component description file for HiiDatabase module.\r
+#\r
+# This module inits HII database and installs HII protocol.\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\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
+#  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
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = HiiDatabase\r
+  FILE_GUID                      = FCD337AB-B1D3-4EF8-957C-8048606FF670\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = InitializeHiiDatabase\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+  HiiDatabase.dxs\r
+  Keyboard.c\r
+  Fonts.c\r
+  Package.c\r
+  Strings.c\r
+  Forms.c\r
+  HiiDatabase.h\r
+  HiiDatabase.c\r
+  CommonHeader.h\r
+\r
+\r
+################################################################################\r
+#\r
+# Includes Section - list of Include locations that are required for\r
+#                    this module.\r
+#\r
+################################################################################\r
+\r
+[Includes]\r
+  $(WORKSPACE)/MdePkg/Include/Library\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  IntelFrameworkPkg/IntelFrameworkPkg.dec\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+#                         this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+  IfrSupportLibFramework\r
+  UefiRuntimeServicesTableLib\r
+  UefiBootServicesTableLib\r
+  BaseMemoryLib\r
+  MemoryAllocationLib\r
+  UefiDriverEntryPoint\r
+  DebugLib\r
+  BaseLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Guid C Name Section - list of Guids that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Guids]\r
+  gEfiGlobalVariableGuid                        # SOMETIMES_CONSUMED L"Lang"\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+#                           that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+  gEfiFormCallbackProtocolGuid                  # PROTOCOL SOMETIMES_CONSUMED\r
+  gEfiHiiProtocolGuid                           # PROTOCOL ALWAYS_PRODUCED\r
+\r
diff --git a/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.msa b/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/HiiDatabase.msa
new file mode 100644 (file)
index 0000000..f91338d
--- /dev/null
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">\r
+  <MsaHeader>\r
+    <ModuleName>HiiDatabase</ModuleName>\r
+    <ModuleType>DXE_DRIVER</ModuleType>\r
+    <GuidValue>FCD337AB-B1D3-4EF8-957C-8048606FF670</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Component description file for HiiDatabase module.</Abstract>\r
+    <Description>This module inits HII database and installs HII protocol.</Description>\r
+    <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+    <License>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
+      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.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>HiiDatabase</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED" RecommendedInstanceGuid="bda39d3a-451b-4350-8266-81ab10fa0523">\r
+      <Keyword>DebugLib</Keyword>\r
+      <HelpText>Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg.</HelpText>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverEntryPoint</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>MemoryAllocationLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiRuntimeServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>EdkIfrSupportLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>HiiDatabase.c</Filename>\r
+    <Filename>HiiDatabase.h</Filename>\r
+    <Filename>Forms.c</Filename>\r
+    <Filename>Strings.c</Filename>\r
+    <Filename>Package.c</Filename>\r
+    <Filename>Fonts.c</Filename>\r
+    <Filename>Keyboard.c</Filename>\r
+    <Filename>HiiDatabase.dxs</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+    <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="ALWAYS_PRODUCED">\r
+      <ProtocolCName>gEfiHiiProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="SOMETIMES_CONSUMED">\r
+      <ProtocolCName>gEfiFormCallbackProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Variables>\r
+    <Variable Usage="SOMETIMES_CONSUMED">\r
+      <VariableName>0x004C 0x0061 0x006E 0x0067</VariableName>\r
+      <GuidC_Name>gEfiGlobalVariableGuid</GuidC_Name>\r
+      <HelpText>L"Lang" global variable is used as system default language.</HelpText>\r
+    </Variable>\r
+  </Variables>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+    <Extern>\r
+      <ModuleEntryPoint>InitializeHiiDatabase</ModuleEntryPoint>\r
+    </Extern>\r
+  </Externs>\r
+</ModuleSurfaceArea>
\ No newline at end of file
diff --git a/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Keyboard.c b/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Keyboard.c
new file mode 100644 (file)
index 0000000..be91d40
--- /dev/null
@@ -0,0 +1,48 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+  Keyboard.c\r
+\r
+Abstract:\r
+\r
+  This file contains the keyboard processing code to the HII database.\r
+\r
+--*/\r
+\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "HiiDatabase.h"\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetKeyboardLayout (\r
+  IN     EFI_HII_PROTOCOL   *This,\r
+  OUT    UINT16             *DescriptorCount,\r
+  OUT    EFI_KEY_DESCRIPTOR *Descriptor\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+Arguments:\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Package.c b/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Package.c
new file mode 100644 (file)
index 0000000..91f5a3a
--- /dev/null
@@ -0,0 +1,678 @@
+/*++\r
+\r
+Copyright (c) 2006 - 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
+  Package.c\r
+\r
+Abstract:\r
+\r
+  This file contains the package processing code to the HII database.\r
+\r
+--*/\r
+\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "HiiDatabase.h"\r
+\r
+EFI_STATUS\r
+GetPackSize (\r
+  IN  VOID                *Pack,\r
+  OUT UINTN               *PackSize,\r
+  OUT UINT32              *NumberOfTokens\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Determines the passed in Pack's size and returns the value.\r
+  \r
+Arguments:\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  EFI_HII_STRING_PACK *StringPack;\r
+  UINT16              Type;\r
+  UINT32              Length;\r
+\r
+  *PackSize = 0;\r
+\r
+  Type      = EFI_HII_IFR;\r
+  if (!CompareMem (&((EFI_HII_PACK_HEADER *) Pack)->Type, &Type, sizeof (UINT16))) {\r
+    //\r
+    // The header contains the full IFR length\r
+    //\r
+    CopyMem (&Length, &((EFI_HII_PACK_HEADER *) Pack)->Length, sizeof (Length));\r
+    *PackSize = (UINTN) Length;\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  Type = EFI_HII_STRING;\r
+  if (!CompareMem (&((EFI_HII_PACK_HEADER *) Pack)->Type, &Type, sizeof (UINT16))) {\r
+    //\r
+    // The header contains the STRING package length\r
+    // The assumption is that the strings for all languages\r
+    // are a contiguous block of data and there is a series of\r
+    // these package instances which will terminate with a NULL package\r
+    // instance.\r
+    //\r
+    StringPack = (EFI_HII_STRING_PACK *) Pack;\r
+\r
+    //\r
+    // There may be multiple instances packed together of strings\r
+    // so we must walk the self describing structures until we encounter\r
+    // the NULL structure to determine the full size.\r
+    //\r
+    CopyMem (&Length, &StringPack->Header.Length, sizeof (Length));\r
+    if (NumberOfTokens != NULL) {\r
+      CopyMem (NumberOfTokens, &StringPack->NumStringPointers, sizeof (UINT32));\r
+    }\r
+\r
+    while (Length != 0) {\r
+      *PackSize   = *PackSize + Length;\r
+      StringPack  = (EFI_HII_STRING_PACK *) ((CHAR8 *) StringPack + Length);\r
+      CopyMem (&Length, &StringPack->Header.Length, sizeof (Length));\r
+    }\r
+    //\r
+    // Encountered a length of 0, so let's add the space for the NULL terminator\r
+    // pack's length and call it done.\r
+    //\r
+    *PackSize = *PackSize + sizeof (EFI_HII_STRING_PACK);\r
+    return EFI_SUCCESS;\r
+  }\r
+  //\r
+  // We only determine the size of the non-global Package types.\r
+  // If neither IFR or STRING data were found, return an error\r
+  //\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+EFI_STATUS\r
+ValidatePack (\r
+  IN   EFI_HII_PROTOCOL          *This,\r
+  IN   EFI_HII_PACKAGE_INSTANCE  *PackageInstance,\r
+  OUT  EFI_HII_PACKAGE_INSTANCE  **StringPackageInstance,\r
+  OUT  UINT32                    *TotalStringCount\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Verifies that the package instance is using the correct handle for string operations.\r
+  \r
+Arguments:\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  EFI_HII_DATA              *HiiData;\r
+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;\r
+  EFI_HII_PACKAGE_INSTANCE  *HandlePackageInstance;\r
+  UINT8                     *RawData;\r
+  EFI_GUID                  Guid;\r
+  EFI_HII_IFR_PACK          *FormPack;\r
+  UINTN                     Index;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  HiiData         = EFI_HII_DATA_FROM_THIS (This);\r
+\r
+  HandleDatabase  = HiiData->DatabaseHead;\r
+  ZeroMem (&Guid, sizeof (EFI_GUID));\r
+\r
+  *StringPackageInstance = PackageInstance;\r
+\r
+  //\r
+  // Based on if there is IFR data in this package instance, determine\r
+  // what the location is of the beginning of the string data.\r
+  //\r
+  if (PackageInstance->IfrSize > 0) {\r
+    FormPack = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));\r
+  } else {\r
+    //\r
+    // If there is no IFR data assume the caller knows what they are doing.\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  RawData = (UINT8 *) FormPack;\r
+\r
+  for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {\r
+    if (RawData[Index] == EFI_IFR_FORM_SET_OP) {\r
+      //\r
+      // Cache the guid for this formset\r
+      //\r
+      CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));\r
+      break;\r
+    }\r
+\r
+    Index = RawData[Index + 1] + Index;\r
+  }\r
+  //\r
+  // If there is no string package, and the PackageInstance->IfrPack.Guid and PackageInstance->Guid are\r
+  // different, we should return the correct handle for the caller to use for strings.\r
+  //\r
+  if ((PackageInstance->StringSize == 0) && (!CompareGuid (&Guid, &PackageInstance->Guid))) {\r
+    //\r
+    // Search the database for a handle that matches the PackageInstance->Guid\r
+    //\r
+    for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {\r
+      //\r
+      // Get Ifrdata and extract the Guid for it\r
+      //\r
+      HandlePackageInstance = HandleDatabase->Buffer;\r
+\r
+      ASSERT (HandlePackageInstance->IfrSize != 0);\r
+\r
+      FormPack  = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&HandlePackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));\r
+      RawData   = (UINT8 *) FormPack;\r
+\r
+      for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {\r
+        if (RawData[Index] == EFI_IFR_FORM_SET_OP) {\r
+          //\r
+          // Cache the guid for this formset\r
+          //\r
+          CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));\r
+          break;\r
+        }\r
+\r
+        Index = RawData[Index + 1] + Index;\r
+      }\r
+      //\r
+      // If the Guid from the new handle matches the original Guid referenced in the original package data\r
+      // return the appropriate package instance data to use.\r
+      //\r
+      if (CompareGuid (&Guid, &PackageInstance->Guid)) {\r
+        if (TotalStringCount != NULL) {\r
+          *TotalStringCount = HandleDatabase->NumberOfTokens;\r
+        }\r
+\r
+        *StringPackageInstance = HandlePackageInstance;\r
+      }\r
+    }\r
+    //\r
+    // end for\r
+    //\r
+  } else {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiNewPack (\r
+  IN  EFI_HII_PROTOCOL    *This,\r
+  IN  EFI_HII_PACKAGES    *Packages,\r
+  OUT EFI_HII_HANDLE      *Handle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Extracts the various packs from a package list.\r
+  \r
+Arguments:\r
+\r
+  This      - Pointer of HII protocol.\r
+  Packages  - Pointer of HII packages.\r
+  Handle    - Handle value to be returned.\r
+\r
+Returns: \r
+\r
+  EFI_SUCCESS           - Pacakges has added to HII database successfully.\r
+  EFI_INVALID_PARAMETER - Invalid parameter.\r
+\r
+--*/\r
+{\r
+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;\r
+  EFI_HII_DATA              *HiiData;\r
+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;\r
+  EFI_HII_HANDLE_DATABASE   *Database;\r
+  EFI_HII_PACK_HEADER       *PackageHeader;\r
+  EFI_HII_GLOBAL_DATA       *GlobalData;\r
+  EFI_HII_IFR_PACK          *IfrPack;\r
+  EFI_HII_STRING_PACK       *StringPack;\r
+  EFI_HII_FONT_PACK         *FontPack;\r
+  EFI_HII_KEYBOARD_PACK     *KeyboardPack;\r
+  EFI_STATUS                Status;\r
+  UINTN                     IfrSize;\r
+  UINTN                     StringSize;\r
+  UINTN                     TotalStringSize;\r
+  UINTN                     InstanceSize;\r
+  UINTN                     Count;\r
+  UINTN                     Index;\r
+  UINT16                    Member;\r
+  EFI_GUID                  Guid;\r
+  EFI_FORM_SET_STUB         FormSetStub;\r
+  UINT8                     *Location;\r
+  UINT16                    Unicode;\r
+  UINT16                    NumWideGlyphs;\r
+  UINT16                    NumNarrowGlyphs;\r
+  UINT32                    NumberOfTokens;\r
+  UINT32                    TotalTokenNumber;\r
+  UINT8                     *Local;\r
+  EFI_NARROW_GLYPH          *NarrowGlyph;\r
+\r
+  if (Packages->NumberOfPackages == 0 || This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  HiiData           = EFI_HII_DATA_FROM_THIS (This);\r
+\r
+  GlobalData        = HiiData->GlobalData;\r
+\r
+  Database          = HiiData->DatabaseHead;\r
+\r
+  PackageInstance   = NULL;\r
+  IfrPack           = NULL;\r
+  StringPack        = NULL;\r
+  InstanceSize      = 0;\r
+  IfrSize           = 0;\r
+  StringSize        = 0;\r
+  TotalStringSize   = 0;\r
+  NumberOfTokens    = 0;\r
+  TotalTokenNumber  = 0;\r
+\r
+  //\r
+  // Search through the passed in Packages for the IfrPack and any StringPack.\r
+  //\r
+  for (Index = 0; Index < Packages->NumberOfPackages; Index++) {\r
+\r
+    PackageHeader = *(EFI_HII_PACK_HEADER **) (((UINT8 *) Packages) + sizeof (EFI_HII_PACKAGES) + Index * sizeof (VOID *));\r
+\r
+    switch (PackageHeader->Type) {\r
+    case EFI_HII_IFR:\r
+      //\r
+      // There shoule be only one Ifr package.\r
+      //\r
+      ASSERT (IfrPack == NULL);\r
+      IfrPack = (EFI_HII_IFR_PACK *) PackageHeader;\r
+      break;\r
+\r
+    case EFI_HII_STRING:\r
+      StringPack = (EFI_HII_STRING_PACK *) PackageHeader;\r
+      //\r
+      // Sending me a String Package. Get its size.\r
+      //\r
+      Status = GetPackSize ((VOID *) StringPack, &StringSize, &NumberOfTokens);\r
+      ASSERT (!EFI_ERROR (Status));\r
+\r
+      //\r
+      // The size which GetPackSize() returns include the null terminator. So if multiple\r
+      // string packages are passed in, merge all these packages, and only pad one null terminator.\r
+      //\r
+      if (TotalStringSize > 0) {\r
+        TotalStringSize -= sizeof (EFI_HII_STRING_PACK);\r
+      }\r
+\r
+      TotalStringSize += StringSize;\r
+      TotalTokenNumber += NumberOfTokens;\r
+      break;\r
+    }\r
+  }\r
+  //\r
+  // If sending a StringPack without an IfrPack, you must include a GuidId\r
+  //\r
+  if ((StringPack != NULL) && (IfrPack == NULL)) {\r
+    if (Packages->GuidId == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+  //\r
+  // If passing in an IfrPack and a GuidId is provided, ensure they are the same value.\r
+  //\r
+  if ((IfrPack != NULL) && (Packages->GuidId != NULL)) {\r
+    Location  = ((UINT8 *) IfrPack);\r
+    Location  = (UINT8 *) (((UINTN) Location) + sizeof (EFI_HII_PACK_HEADER));\r
+\r
+    //\r
+    // Advance to the Form Set Op-code\r
+    //\r
+    for (Count = 0; ((EFI_IFR_OP_HEADER *) &Location[Count])->OpCode != EFI_IFR_FORM_SET_OP;) {\r
+      Count = Count + ((EFI_IFR_OP_HEADER *) &Location[Count])->Length;\r
+    }\r
+    //\r
+    // Copy to local variable\r
+    //\r
+    CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &Location[Count])->Guid, sizeof (EFI_GUID));\r
+\r
+    //\r
+    // Check to see if IfrPack->Guid != GuidId\r
+    //\r
+    if (!CompareGuid (&Guid, Packages->GuidId)) {\r
+      //\r
+      // If a string package is present, the GUIDs should have agreed.  Return an error\r
+      //\r
+      if (StringPack != NULL) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    }\r
+  }\r
+  //\r
+  // If someone is passing in a string only, create a dummy IfrPack with a Guid\r
+  // to enable future searching of this data.\r
+  //\r
+  if ((IfrPack == NULL) && (StringPack != NULL)) {\r
+    ZeroMem (&FormSetStub, sizeof (FormSetStub));\r
+\r
+    FormSetStub.Header.Type           = EFI_HII_IFR;\r
+    FormSetStub.Header.Length         = sizeof (EFI_FORM_SET_STUB);\r
+\r
+    FormSetStub.FormSet.Header.OpCode = EFI_IFR_FORM_SET_OP;\r
+    FormSetStub.FormSet.Header.Length = (UINT8) sizeof (EFI_IFR_FORM_SET);\r
+    //\r
+    // Dummy string\r
+    //\r
+    FormSetStub.FormSet.FormSetTitle  = 0x02;\r
+    CopyMem (&FormSetStub.FormSet.Guid, Packages->GuidId, sizeof (EFI_GUID));\r
+\r
+    FormSetStub.EndFormSet.Header.OpCode  = EFI_IFR_END_FORM_SET_OP;\r
+    FormSetStub.EndFormSet.Header.Length  = (UINT8) sizeof (EFI_IFR_END_FORM_SET);\r
+    IfrPack = (EFI_HII_IFR_PACK *) &FormSetStub;\r
+  }\r
+\r
+  if (IfrPack != NULL) {\r
+    //\r
+    // Sending me an IFR Package. Get its size.\r
+    //\r
+    Status = GetPackSize ((VOID *) IfrPack, &IfrSize, NULL);\r
+    ASSERT (!EFI_ERROR (Status));\r
+  }\r
+  //\r
+  // Prepare the internal package instace buffer to store package data.\r
+  //\r
+  InstanceSize = IfrSize + TotalStringSize;\r
+\r
+  if (InstanceSize != 0) {\r
+    PackageInstance = AllocateZeroPool (InstanceSize + sizeof (EFI_HII_PACKAGE_INSTANCE));\r
+\r
+    ASSERT (PackageInstance);\r
+\r
+    //\r
+    // If there is no DatabaseHead allocated - allocate one\r
+    //\r
+    if (HiiData->DatabaseHead == NULL) {\r
+      HiiData->DatabaseHead = AllocateZeroPool (sizeof (EFI_HII_HANDLE_DATABASE));\r
+      ASSERT (HiiData->DatabaseHead);\r
+    }\r
+    //\r
+    // If the head is being used (Handle is non-zero), allocate next Database and\r
+    // add it to the linked-list\r
+    //\r
+    if (HiiData->DatabaseHead->Handle != 0) {\r
+      HandleDatabase = AllocateZeroPool (sizeof (EFI_HII_HANDLE_DATABASE));\r
+\r
+      ASSERT (HandleDatabase);\r
+\r
+      for (; Database->NextHandleDatabase != NULL; Database = Database->NextHandleDatabase)\r
+        ;\r
+\r
+      //\r
+      // We are sitting on the Database entry which contains the null Next pointer.  Fix it.\r
+      //\r
+      Database->NextHandleDatabase = HandleDatabase;\r
+\r
+    }\r
+\r
+    Database = HiiData->DatabaseHead;\r
+\r
+    //\r
+    // Initialize this instance data\r
+    //\r
+    for (*Handle = 1; Database->NextHandleDatabase != NULL; Database = Database->NextHandleDatabase) {\r
+      //\r
+      // Since the first Database instance will have a passed back handle of 1, we will continue\r
+      // down the linked list of entries until we encounter the end of the linked list.  Each time\r
+      // we go down one level deeper, increment the handle value that will be passed back.\r
+      //\r
+      if (Database->Handle >= *Handle) {\r
+        *Handle = (EFI_HII_HANDLE) (Database->Handle + 1);\r
+      }\r
+    }\r
+\r
+    PackageInstance->Handle     = *Handle;\r
+    PackageInstance->IfrSize    = IfrSize;\r
+    PackageInstance->StringSize = TotalStringSize;\r
+    if (Packages->GuidId != NULL) {\r
+      CopyMem (&PackageInstance->Guid, Packages->GuidId, sizeof (EFI_GUID));\r
+    }\r
+\r
+    Database->Buffer              = PackageInstance;\r
+    Database->Handle              = PackageInstance->Handle;\r
+    Database->NumberOfTokens      = TotalTokenNumber;\r
+    Database->NextHandleDatabase  = NULL;\r
+  }\r
+  //\r
+  // Copy the Ifr package data into package instance.\r
+  //\r
+  if (IfrSize > 0) {\r
+    CopyMem (&PackageInstance->IfrData, IfrPack, IfrSize);\r
+  }\r
+  //\r
+  // Main loop to store package data into HII database.\r
+  //\r
+  StringSize      = 0;\r
+  TotalStringSize = 0;\r
+\r
+  for (Index = 0; Index < Packages->NumberOfPackages; Index++) {\r
+\r
+    PackageHeader = *(EFI_HII_PACK_HEADER **) (((UINT8 *) Packages) + sizeof (EFI_HII_PACKAGES) + Index * sizeof (VOID *));\r
+\r
+    switch (PackageHeader->Type) {\r
+    case EFI_HII_STRING:\r
+      StringPack = (EFI_HII_STRING_PACK *) PackageHeader;\r
+      //\r
+      // The size which GetPackSize() returns include the null terminator. So if multiple\r
+      // string packages are passed in, merge all these packages, and only pad one null terminator.\r
+      //\r
+      if (TotalStringSize > 0) {\r
+        TotalStringSize -= sizeof (EFI_HII_STRING_PACK);\r
+      }\r
+\r
+      GetPackSize ((VOID *) StringPack, &StringSize, &NumberOfTokens);\r
+      CopyMem ((CHAR8 *) (&PackageInstance->IfrData) + IfrSize + TotalStringSize, StringPack, StringSize);\r
+\r
+      TotalStringSize += StringSize;\r
+      break;\r
+\r
+    case EFI_HII_HANDLES:\r
+      CopyMem (&PackageInstance->HandlePack, PackageHeader, sizeof (EFI_HII_HANDLE_PACK));\r
+      break;\r
+\r
+    case EFI_HII_FONT:\r
+      FontPack = (EFI_HII_FONT_PACK *) PackageHeader;\r
+      //\r
+      // Add whatever narrow glyphs were passed to us if undefined\r
+      //\r
+      CopyMem (&NumNarrowGlyphs, &FontPack->NumberOfNarrowGlyphs, sizeof (UINT16));\r
+      for (Count = 0; Count <= NumNarrowGlyphs; Count++) {\r
+        Local       = (UINT8 *) (&FontPack->NumberOfWideGlyphs + sizeof (UINT8)) + (sizeof (EFI_NARROW_GLYPH)) * Count;\r
+        NarrowGlyph = (EFI_NARROW_GLYPH *) Local;\r
+        CopyMem (&Member, &NarrowGlyph->UnicodeWeight, sizeof (UINT16));\r
+        //\r
+        // If the glyph is already defined, do not overwrite it.  It is what it is.\r
+        //\r
+        CopyMem (&Unicode, &GlobalData->NarrowGlyphs[Member].UnicodeWeight, sizeof (UINT16));\r
+        if (Unicode == 0) {\r
+          CopyMem (&GlobalData->NarrowGlyphs[Member], Local, sizeof (EFI_NARROW_GLYPH));\r
+        }\r
+      }\r
+      //\r
+      // Add whatever wide glyphs were passed to us if undefined\r
+      //\r
+      CopyMem (&NumWideGlyphs, &FontPack->NumberOfWideGlyphs, sizeof (UINT16));\r
+      for (Count = 0; Count <= NumWideGlyphs; Count++) {\r
+        Local = (UINT8 *) (&FontPack->NumberOfWideGlyphs + sizeof (UINT8)) +\r
+          (sizeof (EFI_NARROW_GLYPH)) *\r
+          NumNarrowGlyphs;\r
+        CopyMem (\r
+          &Member,\r
+          (UINTN *) (Local + sizeof (EFI_WIDE_GLYPH) * Count),\r
+          sizeof (UINT16)\r
+          );\r
+        //\r
+        // If the glyph is already defined, do not overwrite it.  It is what it is.\r
+        //\r
+        CopyMem (&Unicode, &GlobalData->WideGlyphs[Member].UnicodeWeight, sizeof (UINT16));\r
+        if (Unicode == 0) {\r
+          Local = (UINT8*)(&FontPack->NumberOfWideGlyphs + sizeof(UINT8)) + (sizeof(EFI_NARROW_GLYPH)) * NumNarrowGlyphs;\r
+          CopyMem (\r
+            &GlobalData->WideGlyphs[Member],\r
+            (UINTN *) (Local + sizeof (EFI_WIDE_GLYPH) * Count),\r
+            sizeof (EFI_WIDE_GLYPH)\r
+            );\r
+        }\r
+      }\r
+      break;\r
+\r
+    case EFI_HII_KEYBOARD:\r
+      KeyboardPack = (EFI_HII_KEYBOARD_PACK *) PackageHeader;\r
+      //\r
+      // Sending me a Keyboard Package\r
+      //\r
+      if (KeyboardPack->DescriptorCount > 105) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+      //\r
+      // If someone updates the Descriptors with a count of 0, blow aware the overrides.\r
+      //\r
+      if (KeyboardPack->DescriptorCount == 0) {\r
+        ZeroMem (GlobalData->OverrideKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);\r
+      }\r
+\r
+      if (KeyboardPack->DescriptorCount < 106 && KeyboardPack->DescriptorCount > 0) {\r
+        //\r
+        // If SystemKeyboard was updated already, then steer changes to the override database\r
+        //\r
+        if (GlobalData->SystemKeyboardUpdate) {\r
+          ZeroMem (GlobalData->OverrideKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);\r
+          for (Count = 0; Count < KeyboardPack->DescriptorCount; Count++) {\r
+            CopyMem (&Member, &KeyboardPack->Descriptor[Count].Key, sizeof (UINT16));\r
+            CopyMem (\r
+              &GlobalData->OverrideKeyboardLayout[Member],\r
+              &KeyboardPack->Descriptor[Count],\r
+              sizeof (EFI_KEY_DESCRIPTOR)\r
+              );\r
+          }\r
+        } else {\r
+          //\r
+          // SystemKeyboard was never updated, so this is likely the keyboard driver setting the System database.\r
+          //\r
+          ZeroMem (GlobalData->SystemKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);\r
+          for (Count = 0; Count < KeyboardPack->DescriptorCount; Count++) {\r
+            CopyMem (&Member, &KeyboardPack->Descriptor->Key, sizeof (UINT16));\r
+            CopyMem (\r
+              &GlobalData->SystemKeyboardLayout[Member],\r
+              &KeyboardPack->Descriptor[Count],\r
+              sizeof (EFI_KEY_DESCRIPTOR)\r
+              );\r
+          }\r
+          //\r
+          // Just updated the system keyboard database, reflect that in the global flag.\r
+          //\r
+          GlobalData->SystemKeyboardUpdate = TRUE;\r
+        }\r
+      }\r
+      break;\r
+\r
+    default:\r
+      break;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiRemovePack (\r
+  IN EFI_HII_PROTOCOL    *This,\r
+  IN EFI_HII_HANDLE      Handle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Removes the various packs from a Handle\r
+  \r
+Arguments:\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;\r
+  EFI_HII_DATA              *HiiData;\r
+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;\r
+  EFI_HII_HANDLE_DATABASE   *PreviousHandleDatabase;\r
+\r
+  if (This == NULL || Handle == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  HiiData         = EFI_HII_DATA_FROM_THIS (This);\r
+\r
+  HandleDatabase  = HiiData->DatabaseHead;\r
+  PackageInstance = NULL;\r
+\r
+  //\r
+  // Initialize the Previous with the Head of the Database\r
+  //\r
+  PreviousHandleDatabase = HandleDatabase;\r
+\r
+  for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {\r
+    //\r
+    // Match the numeric value with the database entry - if matched,\r
+    // free the package instance and apply fix-up to database linked list\r
+    //\r
+    if (Handle == HandleDatabase->Handle) {\r
+      PackageInstance = HandleDatabase->Buffer;\r
+\r
+      //\r
+      // Free the Package Instance\r
+      //\r
+      FreePool (PackageInstance);\r
+\r
+      //\r
+      // If this was the only Handle in the database\r
+      //\r
+      if (HiiData->DatabaseHead == HandleDatabase) {\r
+        HiiData->DatabaseHead = NULL;\r
+      }\r
+      //\r
+      // Make the parent->Next point to the current->Next\r
+      //\r
+      PreviousHandleDatabase->NextHandleDatabase = HandleDatabase->NextHandleDatabase;\r
+      FreePool (HandleDatabase);\r
+      return EFI_SUCCESS;\r
+    }\r
+    //\r
+    // If this was not the HandleDatabase entry we were looking for, cache it just in case the next one is\r
+    //\r
+    PreviousHandleDatabase = HandleDatabase;\r
+  }\r
+  //\r
+  // No handle was found - error condition\r
+  //\r
+  if (PackageInstance == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Strings.c b/IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Strings.c
new file mode 100644 (file)
index 0000000..a8b04c0
--- /dev/null
@@ -0,0 +1,1276 @@
+/*++\r
+\r
+Copyright (c) 2006 - 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
+  Strings.c\r
+\r
+Abstract:\r
+\r
+  This file contains the string processing code to the HII database.\r
+\r
+--*/\r
+\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "HiiDatabase.h"\r
+\r
+STATIC\r
+VOID\r
+AsciiToUnicode (\r
+  IN    UINT8     *Lang,\r
+  IN    UINT16    *Language\r
+  )\r
+{\r
+  UINT8 Count;\r
+\r
+  //\r
+  // Convert the ASCII Lang variable to a Unicode Language variable\r
+  //\r
+  for (Count = 0; Count < 3; Count++) {\r
+    Language[Count] = (CHAR16) Lang[Count];\r
+  }\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiTestString (\r
+  IN     EFI_HII_PROTOCOL   *This,\r
+  IN     CHAR16             *StringToTest,\r
+  IN OUT UINT32             *FirstMissing,\r
+  OUT    UINT32             *GlyphBufferSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Test if all of the characters in a string have corresponding font characters.\r
+  \r
+Arguments:\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  EFI_HII_GLOBAL_DATA *GlobalData;\r
+  EFI_HII_DATA        *HiiData;\r
+  BOOLEAN             WideChar;\r
+  INT32               Location;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  HiiData     = EFI_HII_DATA_FROM_THIS (This);\r
+  GlobalData  = HiiData->GlobalData;\r
+\r
+  \r
+  //\r
+  // Rewind through the string looking for a glyph width identifier\r
+  // If no width identifier exists, we assume string has narrow width identifier\r
+  //\r
+  for (WideChar = FALSE, Location = (INT32) *FirstMissing; Location >= 0; Location--) {\r
+    if ((StringToTest[Location] == NARROW_CHAR) || (StringToTest[Location] == WIDE_CHAR)) {\r
+      //\r
+      // We found something that identifies what glyph database to look in\r
+      //\r
+      WideChar = (BOOLEAN) (StringToTest[Location] == WIDE_CHAR);\r
+      break;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Walk through the string until you hit the null terminator\r
+  //\r
+  for (*GlyphBufferSize = 0; StringToTest[*FirstMissing] != CHAR_NULL; (*FirstMissing)++) {\r
+    //\r
+    // We found something that identifies what glyph database to look in\r
+    //\r
+    if ((StringToTest[*FirstMissing] == NARROW_CHAR) || (StringToTest[*FirstMissing] == WIDE_CHAR)) {\r
+      WideChar = (BOOLEAN) (StringToTest[*FirstMissing] == WIDE_CHAR);\r
+      continue;\r
+    }\r
+\r
+    if (!WideChar) {\r
+      if (CompareMem (\r
+          GlobalData->NarrowGlyphs[StringToTest[*FirstMissing]].GlyphCol1,\r
+          &mUnknownGlyph,\r
+          NARROW_GLYPH_ARRAY_SIZE\r
+          ) == 0\r
+          ) {\r
+        //\r
+        // Break since this glyph isn't defined\r
+        //\r
+        return EFI_NOT_FOUND;\r
+      }\r
+    } else {\r
+      //\r
+      // Can compare wide glyph against only GlyphCol1 since GlyphCol1 and GlyphCol2 are contiguous - just give correct size\r
+      //\r
+      if (CompareMem (\r
+          GlobalData->WideGlyphs[StringToTest[*FirstMissing]].GlyphCol1,\r
+          &mUnknownGlyph,\r
+          WIDE_GLYPH_ARRAY_SIZE\r
+          ) == 0\r
+          ) {\r
+        //\r
+        // Break since this glyph isn't defined\r
+        //\r
+        return EFI_NOT_FOUND;\r
+      }\r
+    }\r
+\r
+    *GlyphBufferSize += (WideChar ? sizeof (EFI_WIDE_GLYPH) : sizeof (EFI_NARROW_GLYPH));\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+HiiNewString2 (\r
+  IN     EFI_HII_PROTOCOL       *This,\r
+  IN     CHAR16                 *Language,\r
+  IN     EFI_HII_HANDLE         Handle,\r
+  IN OUT STRING_REF             *Reference,\r
+  IN     CHAR16                 *NewString,\r
+  IN     BOOLEAN                ResetStrings\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function allows a new String to be added to an already existing String Package.\r
+  We will make a buffer the size of the package + EfiStrSize of the new string.  We will\r
+  copy the string package that first gets changed and the following language packages until\r
+  we encounter the NULL string package.  All this time we will ensure that the offsets have\r
+  been adjusted.  \r
+\r
+Arguments:\r
+  \r
+  This         -  Pointer to the HII protocol.\r
+  Language     -  Pointer to buffer which contains the language code of this NewString.\r
+  Handle       -  Handle of the package instance to be processed.\r
+  Reference    -  The token number for the string. If 0, new string token to be returned through this parameter.\r
+  NewString    -  Buffer pointer for the new string. \r
+  ResetStrings -  Indicate if we are resetting a string.\r
+  \r
+Returns: \r
+\r
+  EFI_SUCCESS            - The string has been added or reset to Hii database.\r
+  EFI_INVALID_PARAMETER  - Some parameter passed in is invalid.\r
+\r
+--*/\r
+{\r
+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;\r
+  EFI_HII_PACKAGE_INSTANCE  *StringPackageInstance;\r
+  EFI_HII_DATA              *HiiData;\r
+  EFI_HII_STRING_PACK       *StringPack;\r
+  EFI_HII_STRING_PACK       *NewStringPack;\r
+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;\r
+  EFI_HII_PACKAGE_INSTANCE  *NewBuffer;\r
+  UINT8                     *Location;\r
+  UINT8                     *StringLocation;\r
+  RELOFST                   *StringPointer;\r
+  UINTN                     Count;\r
+  UINTN                     Size;\r
+  UINTN                     Index;\r
+  UINTN                     SecondIndex;\r
+  BOOLEAN                   AddString;\r
+  EFI_STATUS                Status;\r
+  UINTN                     Increment;\r
+  UINTN                     StringCount;\r
+  UINT32                    TotalStringCount;\r
+  UINT32                    OriginalStringCount;\r
+  RELOFST                   StringSize;\r
+  UINT32                    Length;\r
+  RELOFST                   Offset;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  HiiData             = EFI_HII_DATA_FROM_THIS (This);\r
+\r
+  HandleDatabase      = HiiData->DatabaseHead;\r
+  PackageInstance     = NULL;\r
+  AddString           = FALSE;\r
+  Increment           = 0;\r
+  StringCount         = 0;\r
+  TotalStringCount    = 0;\r
+  OriginalStringCount = 0;\r
+\r
+  //\r
+  // Check numeric value against the head of the database\r
+  //\r
+  for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {\r
+    //\r
+    // Match the numeric value with the database entry - if matched, extract PackageInstance\r
+    //\r
+    if (Handle == HandleDatabase->Handle) {\r
+      PackageInstance = HandleDatabase->Buffer;\r
+      if (ResetStrings) {\r
+        TotalStringCount = HandleDatabase->NumberOfTokens;\r
+      }\r
+      break;\r
+    }\r
+  }\r
+  //\r
+  // No handle was found - error condition\r
+  //\r
+  if (PackageInstance == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = ValidatePack (This, PackageInstance, &StringPackageInstance, &TotalStringCount);\r
+\r
+  //\r
+  // This sets Count to 0 or the size of the IfrData.  We intend to use Count as an offset value\r
+  //\r
+  Count = StringPackageInstance->IfrSize;\r
+\r
+  //\r
+  // This is the size of the complete series of string packs\r
+  //\r
+  Size = StringPackageInstance->StringSize;\r
+\r
+  //\r
+  // Based on if there is IFR data in this package instance, determine\r
+  // what the location is of the beginning of the string data.\r
+  //\r
+  if (StringPackageInstance->IfrSize > 0) {\r
+    Location = (UINT8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize;\r
+  } else {\r
+    Location = (UINT8 *) (&StringPackageInstance->IfrData);\r
+  }\r
+  //\r
+  // We allocate a buffer which is big enough for both adding and resetting string.\r
+  // The size is slightly larger than the real size of the packages when we are resetting a string.\r
+  //\r
+  NewBuffer = AllocateZeroPool (\r
+                sizeof (EFI_HII_PACKAGE_INSTANCE) -\r
+                2 * sizeof (VOID *) +\r
+                StringPackageInstance->IfrSize +\r
+                StringPackageInstance->StringSize +\r
+                sizeof (RELOFST) +\r
+                StrSize (NewString)\r
+                );\r
+  ASSERT (NewBuffer);\r
+\r
+  //\r
+  // Copy data to new buffer\r
+  //\r
+  NewBuffer->Handle   = StringPackageInstance->Handle;\r
+  NewBuffer->IfrSize  = StringPackageInstance->IfrSize;\r
+\r
+  //\r
+  // The worst case scenario for sizing is that we are adding a new string (not replacing one) and there was not a string\r
+  // package to begin with.\r
+  //\r
+  NewBuffer->StringSize = StringPackageInstance->StringSize + StrSize (NewString) + sizeof (EFI_HII_STRING_PACK);\r
+\r
+  if (StringPackageInstance->IfrSize > 0) {\r
+    CopyMem (&NewBuffer->IfrData, &StringPackageInstance->IfrData, StringPackageInstance->IfrSize);\r
+  }\r
+\r
+  StringPack = (EFI_HII_STRING_PACK *) Location;\r
+\r
+  //\r
+  // There may be multiple instances packed together of strings\r
+  // so we must walk the self describing structures until we encounter\r
+  // what we are looking for.  In the meantime, copy everything we encounter\r
+  // to the new buffer.\r
+  //\r
+  CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+  for (; Length != 0;) {\r
+    //\r
+    // If passed in Language ISO value is in this string pack's language string\r
+    // then we are dealing with the strings we want.\r
+    //\r
+    CopyMem (&Offset, &StringPack->LanguageNameString, sizeof (RELOFST));\r
+    Status = HiiCompareLanguage ((CHAR16 *) ((CHAR8 *) (StringPack) + Offset), Language);\r
+\r
+    if (!EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+\r
+    CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), StringPack, Length);\r
+\r
+    Count       = Count + Length;\r
+    StringPack  = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);\r
+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+  }\r
+  //\r
+  // Found the language pack to update on a particular handle\r
+  // We need to Copy the Contents of this pack and adjust the offset values associated\r
+  // with adding/changing a string.  This is a particular piece of code that screams for\r
+  // it being prone to programming error.\r
+  //\r
+  //\r
+  // Copy the string package up to the string data\r
+  //\r
+  StringPointer = (RELOFST *) (StringPack + 1);\r
+  CopyMem (\r
+    ((CHAR8 *) (&NewBuffer->IfrData) + Count),\r
+    StringPack,\r
+    (UINTN) ((UINTN) (StringPointer) - (UINTN) (StringPack))\r
+    );\r
+\r
+  //\r
+  // Determine the number of StringPointers\r
+  //\r
+  if (!ResetStrings) {\r
+    CopyMem (&TotalStringCount, &StringPack->NumStringPointers, sizeof (RELOFST));\r
+  } else {\r
+    //\r
+    // If we are resetting the strings, use the original value when exported\r
+    //\r
+    CopyMem (&OriginalStringCount, &StringPack->NumStringPointers, sizeof (RELOFST));\r
+    ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->LanguageNameString -=\r
+      (\r
+        (RELOFST) (OriginalStringCount - TotalStringCount) *\r
+        sizeof (RELOFST)\r
+      );\r
+    ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->PrintableLanguageName -=\r
+      (\r
+        (RELOFST) (OriginalStringCount - TotalStringCount) *\r
+        sizeof (RELOFST)\r
+      );\r
+    ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->NumStringPointers  = TotalStringCount;\r
+    *Reference = (STRING_REF) (TotalStringCount);\r
+  }\r
+  //\r
+  // If the token value is not valid, error out\r
+  //\r
+  if ((*Reference >= TotalStringCount) && !ResetStrings) {\r
+    FreePool (NewBuffer);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // If Reference is 0, update it with what the new token reference will be and turn the AddString flag on\r
+  //\r
+  if (*Reference == 0) {\r
+    *Reference  = (STRING_REF) (TotalStringCount);\r
+    AddString   = TRUE;\r
+  }\r
+\r
+  if (AddString) {\r
+    ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->LanguageNameString += sizeof (RELOFST);\r
+    ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->PrintableLanguageName += sizeof (RELOFST);\r
+    ((EFI_HII_STRING_PACK *) ((CHAR8 *) (&NewBuffer->IfrData) + Count))->NumStringPointers++;\r
+  }\r
+  //\r
+  // Increment offset by amount of copied data\r
+  //\r
+  Count = Count + ((UINTN) (StringPointer) - (UINTN) StringPack);\r
+\r
+  for (Index = 0; Index < TotalStringCount; Index++) {\r
+    //\r
+    // If we are pointing to the size of the changing string value\r
+    // then cache the old string value so you know what the difference is\r
+    //\r
+    if (Index == *Reference) {\r
+      CopyMem (&Offset, &StringPointer[Index], sizeof (RELOFST));\r
+\r
+      StringLocation = ((UINT8 *) (StringPack) + Offset);\r
+      for (SecondIndex = 0;\r
+           (StringLocation[SecondIndex] != 0) || (StringLocation[SecondIndex + 1] != 0);\r
+           SecondIndex = SecondIndex + 2\r
+          )\r
+        ;\r
+      SecondIndex = SecondIndex + 2;\r
+\r
+      Size        = SecondIndex;\r
+\r
+      //\r
+      // NewString is a passed in local string which is assumed to be aligned\r
+      //\r
+      Size = StrSize (NewString) - Size;\r
+    }\r
+    //\r
+    // If we are about to copy the offset of the string that follows the changed string make\r
+    // sure that the offsets are adjusted accordingly\r
+    //\r
+    if ((Index > *Reference) && !ResetStrings) {\r
+      CopyMem (&Offset, &StringPointer[Index], sizeof (RELOFST));\r
+      Offset = (RELOFST) (Offset + Size);\r
+      CopyMem (&StringPointer[Index], &Offset, sizeof (RELOFST));\r
+    }\r
+    //\r
+    // If we are adding a string that means we will have an extra string pointer that will affect all string offsets\r
+    //\r
+    if (AddString) {\r
+      CopyMem (&Offset, &StringPointer[Index], sizeof (RELOFST));\r
+      Offset = (UINT32) (Offset + sizeof (RELOFST));\r
+      CopyMem (&StringPointer[Index], &Offset, sizeof (RELOFST));\r
+    }\r
+    //\r
+    // If resetting the strings, we need to reduce the offset by the difference in the strings\r
+    //\r
+    if (ResetStrings) {\r
+      CopyMem (&Length, &StringPointer[Index], sizeof (RELOFST));\r
+      Length = Length - ((RELOFST) (OriginalStringCount - TotalStringCount) * sizeof (RELOFST));\r
+      CopyMem (&StringPointer[Index], &Length, sizeof (RELOFST));\r
+    }\r
+    //\r
+    // Notice that if the string was being added as a new token, we don't have to worry about the\r
+    // offsets changing in the other indexes\r
+    //\r
+    CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), &StringPointer[Index], sizeof (RELOFST));\r
+    Count = Count + sizeof (RELOFST);\r
+    StringCount++;\r
+  }\r
+  //\r
+  // If we are adding a new string the above for loop did not copy the offset for us\r
+  //\r
+  if (AddString) {\r
+    //\r
+    // Since the Index is pointing to the beginning of the first string, we need to gather the size of the previous\r
+    // offset's string and create an offset to our new string.\r
+    //\r
+    CopyMem (&Offset, &StringPointer[Index - 1], sizeof (RELOFST));\r
+    StringLocation  = (UINT8 *) StringPack;\r
+    StringLocation  = StringLocation + Offset - sizeof (RELOFST);\r
+\r
+    //\r
+    // Since StringPack is a packed structure, we need to size it carefully (byte-wise) to avoid alignment issues\r
+    //\r
+    for (Length = 0;\r
+         (StringLocation[Length] != 0) || (StringLocation[Length + 1] != 0);\r
+         Length = (RELOFST) (Length + 2)\r
+        )\r
+      ;\r
+    Length      = (RELOFST) (Length + 2);\r
+\r
+    StringSize  = (RELOFST) (Offset + Length);\r
+\r
+    //\r
+    // Copy the new string offset\r
+    //\r
+    CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), &StringSize, sizeof (RELOFST));\r
+    Count = Count + sizeof (RELOFST);\r
+\r
+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+    Length = Length + sizeof (RELOFST);\r
+    CopyMem (&StringPack->Header.Length, &Length, sizeof (UINT32));\r
+  }\r
+  //\r
+  // Set Location to the First String\r
+  //\r
+  if (ResetStrings) {\r
+    Index = OriginalStringCount;\r
+  }\r
+  //\r
+  // Set Location to the First String\r
+  //\r
+  Location  = (UINT8 *) &StringPointer[Index];\r
+  Index     = 0;\r
+\r
+  //\r
+  // Keep copying strings until you run into two CHAR16's in a row that are NULL\r
+  //\r
+  do {\r
+    if ((*Reference == Increment) && !AddString) {\r
+      StringLocation = ((UINT8 *) (&NewBuffer->IfrData) + Count);\r
+      CopyMem (StringLocation, NewString, StrSize (NewString));\r
+\r
+      //\r
+      // Advance the destination location by Count number of bytes\r
+      //\r
+      Count = Count + StrSize (NewString);\r
+\r
+      //\r
+      // Add the difference between the new string and the old string to the length\r
+      //\r
+      CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+\r
+      //\r
+      // Since StringPack is a packed structure, we need to size it carefully (byte-wise) to avoid alignment issues\r
+      //\r
+      StringLocation = (UINT8 *) &Location[Index];\r
+      for (Offset = 0;\r
+           (StringLocation[Offset] != 0) || (StringLocation[Offset + 1] != 0);\r
+           Offset = (RELOFST) (Offset + 2)\r
+          )\r
+        ;\r
+      Offset  = (RELOFST) (Offset + 2);\r
+\r
+      Length  = Length + (UINT32) StrSize (NewString) - Offset;\r
+\r
+      CopyMem (&StringPack->Header.Length, &Length, sizeof (UINT32));\r
+    } else {\r
+      StringLocation = (UINT8 *) &Location[Index];\r
+      for (Offset = 0;\r
+           (StringLocation[Offset] != 0) || (StringLocation[Offset + 1] != 0);\r
+           Offset = (RELOFST) (Offset + 2)\r
+          )\r
+        ;\r
+      Offset = (RELOFST) (Offset + 2);\r
+\r
+      CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), StringLocation, Offset);\r
+\r
+      //\r
+      // Advance the destination location by Count number of bytes\r
+      //\r
+      Count = Count + Offset;\r
+    }\r
+    //\r
+    // Retrieve the number of characters to advance the index - should land at beginning of next string\r
+    //\r
+    Index = Index + Offset;\r
+    Increment++;\r
+    StringCount--;\r
+    Offset = 0;\r
+  } while (StringCount > 0);\r
+\r
+  //\r
+  // If we are adding a new string, then the above do/while will not suffice\r
+  //\r
+  if (AddString) {\r
+    Offset = (RELOFST) StrSize (NewString);\r
+    CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), NewString, Offset);\r
+\r
+    Count = Count + StrSize (NewString);\r
+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+    Length = Length + (UINT32) StrSize (NewString);\r
+    CopyMem (&StringPack->Header.Length, &Length, sizeof (UINT32));\r
+  }\r
+\r
+  if (ResetStrings) {\r
+    //\r
+    // Skip the remainder of strings in the string package\r
+    //\r
+    StringCount = OriginalStringCount - TotalStringCount;\r
+\r
+    while (StringCount > 0) {\r
+      StringLocation = (UINT8 *) &Location[Index];\r
+      for (Offset = 0;\r
+           (StringLocation[Offset] != 0) || (StringLocation[Offset + 1] != 0);\r
+           Offset = (RELOFST) (Offset + 2)\r
+          )\r
+        ;\r
+      Offset  = (RELOFST) (Offset + 2);\r
+      Index   = Index + Offset;\r
+      StringCount--;\r
+\r
+      //\r
+      // Adjust the size of the string pack by the string size we just skipped.\r
+      // Also reduce the length by the size of a RelativeOffset value since we\r
+      // obviously would have skipped that as well.\r
+      //\r
+      CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+      Length = Length - Offset - sizeof (RELOFST);\r
+      CopyMem (&StringPack->Header.Length, &Length, sizeof (UINT32));\r
+    }\r
+  }\r
+\r
+  StringPack = (EFI_HII_STRING_PACK *) &Location[Index];\r
+\r
+  CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+  for (; Length != 0;) {\r
+\r
+    CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), StringPack, Length);\r
+\r
+    Count       = Count + Length;\r
+    StringPack  = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);\r
+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+  }\r
+  //\r
+  // Copy the null terminator to the new buffer\r
+  //\r
+  CopyMem (((CHAR8 *) (&NewBuffer->IfrData) + Count), StringPack, sizeof (EFI_HII_STRING_PACK));\r
+\r
+  //\r
+  // Based on if there is IFR data in this package instance, determine\r
+  // what the location is of the beginning of the string data.\r
+  //\r
+  if (StringPackageInstance->IfrSize > 0) {\r
+    Location      = (UINT8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize;\r
+    StringPack    = (EFI_HII_STRING_PACK *) Location;\r
+    Location      = (UINT8 *) (&NewBuffer->IfrData) + NewBuffer->IfrSize;\r
+    NewStringPack = (EFI_HII_STRING_PACK *) Location;\r
+  } else {\r
+    StringPack    = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);\r
+    NewStringPack = (EFI_HII_STRING_PACK *) (&NewBuffer->IfrData);\r
+  }\r
+\r
+  CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+  for (; Length != 0;) {\r
+    //\r
+    // Since we updated the old version of the string data as we moved things over\r
+    // And we had a chicken-egg problem with the data we copied, let's post-fix the new\r
+    // buffer with accurate length data.\r
+    //\r
+    CopyMem (&Count, &NewStringPack->Header.Length, sizeof (UINT32));\r
+    CopyMem (&NewStringPack->Header.Length, &StringPack->Header.Length, sizeof (UINT32));\r
+    CopyMem (&StringPack->Header.Length, &Count, sizeof (UINT32));\r
+\r
+    CopyMem (&Count, &NewStringPack->Header.Length, sizeof (UINT32));\r
+    NewStringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (NewStringPack) + Count);\r
+    CopyMem (&Count, &StringPack->Header.Length, sizeof (UINT32));\r
+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Count);\r
+    CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+  }\r
+\r
+  GetPackSize ((VOID *) ((CHAR8 *) (&NewBuffer->IfrData) + NewBuffer->IfrSize), &NewBuffer->StringSize, NULL);\r
+\r
+  //\r
+  // Search through the handles until the requested handle is found.\r
+  //\r
+  for (HandleDatabase = HiiData->DatabaseHead;\r
+       HandleDatabase->Handle != 0;\r
+       HandleDatabase = HandleDatabase->NextHandleDatabase\r
+      ) {\r
+    if (HandleDatabase->Handle == StringPackageInstance->Handle) {\r
+      //\r
+      // Free the previous buffer associated with this handle, and assign the new buffer to the handle\r
+      //\r
+      FreePool (HandleDatabase->Buffer);\r
+      HandleDatabase->Buffer = NewBuffer;\r
+      break;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiNewString (\r
+  IN     EFI_HII_PROTOCOL       *This,\r
+  IN     CHAR16                 *Language,\r
+  IN     EFI_HII_HANDLE         Handle,\r
+  IN OUT STRING_REF             *Reference,\r
+  IN     CHAR16                 *NewString\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  This function allows a new String to be added to an already existing String Package.\r
+  We will make a buffer the size of the package + StrSize of the new string.  We will\r
+  copy the string package that first gets changed and the following language packages until\r
+  we encounter the NULL string package.  All this time we will ensure that the offsets have\r
+  been adjusted.  \r
+\r
+Arguments:\r
+  \r
+Returns: \r
+\r
+--*/\r
+{\r
+  UINTN       Index;\r
+  CHAR16      *LangCodes;\r
+  CHAR16      Lang[4];\r
+  STRING_REF  OriginalValue;\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // To avoid a warning 4 uninitialized variable warning\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  Status = HiiGetPrimaryLanguages (\r
+            This,\r
+            Handle,\r
+            &LangCodes\r
+            );\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    OriginalValue = *Reference;\r
+\r
+    if (Language == NULL) {\r
+      for (Index = 0; LangCodes[Index] != 0; Index += 3) {\r
+        *Reference = OriginalValue;\r
+        CopyMem (Lang, &LangCodes[Index], 6);\r
+        Lang[3] = 0;\r
+        Status = HiiNewString2 (\r
+                  This,\r
+                  Lang,\r
+                  Handle,\r
+                  Reference,\r
+                  NewString,\r
+                  FALSE\r
+                  );\r
+\r
+      }\r
+    } else {\r
+      Status = HiiNewString2 (\r
+                This,\r
+                Language,\r
+                Handle,\r
+                Reference,\r
+                NewString,\r
+                FALSE\r
+                );\r
+    }\r
+\r
+    FreePool (LangCodes);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiResetStrings (\r
+  IN     EFI_HII_PROTOCOL   *This,\r
+  IN     EFI_HII_HANDLE     Handle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+    This function removes any new strings that were added after the initial string export for this handle.\r
+\r
+Arguments:\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  UINTN       Index;\r
+  CHAR16      *LangCodes;\r
+  CHAR16      Lang[4];\r
+  STRING_REF  Reference;\r
+  CHAR16      NewString;\r
+  EFI_STATUS  Status;\r
+\r
+  Reference = 1;\r
+  NewString = 0;\r
+\r
+  HiiGetPrimaryLanguages (\r
+    This,\r
+    Handle,\r
+    &LangCodes\r
+    );\r
+\r
+  for (Index = 0; LangCodes[Index] != 0; Index += 3) {\r
+    CopyMem (Lang, &LangCodes[Index], 6);\r
+    Lang[3] = 0;\r
+    Status = HiiNewString2 (\r
+              This,\r
+              Lang,\r
+              Handle,\r
+              &Reference,\r
+              &NewString,\r
+              TRUE\r
+              );\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+  FreePool (LangCodes);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetString (\r
+  IN     EFI_HII_PROTOCOL    *This,\r
+  IN     EFI_HII_HANDLE      Handle,\r
+  IN     STRING_REF          Token,\r
+  IN     BOOLEAN             Raw,\r
+  IN     CHAR16              *LanguageString,\r
+  IN OUT UINTN               *BufferLengthTemp,\r
+  OUT    EFI_STRING          StringBuffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  This function extracts a string from a package already registered with the EFI HII database.\r
+\r
+Arguments:\r
+  This            - A pointer to the EFI_HII_PROTOCOL instance.\r
+  Handle          - The HII handle on which the string resides.\r
+  Token           - The string token assigned to the string.\r
+  Raw             - If TRUE, the string is returned unedited in the internal storage format described\r
+                    above. If false, the string returned is edited by replacing <cr> with <space> \r
+                    and by removing special characters such as the <wide> prefix.\r
+  LanguageString  - Pointer to a NULL-terminated string containing a single ISO 639-2 language\r
+                    identifier, indicating the language to print. If the LanguageString is empty (starts\r
+                    with a NULL), the default system language will be used to determine the language.\r
+  BufferLength    - Length of the StringBuffer. If the status reports that the buffer width is too\r
+                    small, this parameter is filled with the length of the buffer needed.\r
+  StringBuffer    - The buffer designed to receive the characters in the string. Type EFI_STRING is\r
+                    defined in String.\r
+\r
+Returns: \r
+  EFI_INVALID_PARAMETER - If input parameter is invalid.\r
+  EFI_BUFFER_TOO_SMALL  - If the *BufferLength is too small.\r
+  EFI_SUCCESS           - Operation is successful.\r
+  \r
+--*/\r
+{\r
+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;\r
+  EFI_HII_PACKAGE_INSTANCE  *StringPackageInstance;\r
+  EFI_HII_DATA              *HiiData;\r
+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;\r
+  EFI_HII_STRING_PACK       *StringPack;\r
+  RELOFST                   *StringPointer;\r
+  EFI_STATUS                Status;\r
+  UINTN                     DataSize;\r
+  CHAR8                     Lang[3];\r
+  CHAR16                    Language[3];\r
+  UINT32                    Length;\r
+  UINTN                     Count;\r
+  RELOFST                   Offset;\r
+  UINT16                    *Local;\r
+  UINT16                    Zero;\r
+  UINT16                    Narrow;\r
+  UINT16                    Wide;\r
+  UINT16                    NoBreak;\r
+  BOOLEAN                   LangFound;\r
+  UINT16                    *BufferLength = (UINT16 *) BufferLengthTemp;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  LangFound       = TRUE;\r
+\r
+  DataSize        = sizeof (Lang);\r
+\r
+  HiiData         = EFI_HII_DATA_FROM_THIS (This);\r
+\r
+  PackageInstance = NULL;\r
+  Zero            = 0;\r
+  Narrow          = NARROW_CHAR;\r
+  Wide            = WIDE_CHAR;\r
+  NoBreak         = NON_BREAKING_CHAR;\r
+\r
+  //\r
+  // Check numeric value against the head of the database\r
+  //\r
+  for (HandleDatabase = HiiData->DatabaseHead;\r
+       HandleDatabase != NULL;\r
+       HandleDatabase = HandleDatabase->NextHandleDatabase\r
+      ) {\r
+    //\r
+    // Match the numeric value with the database entry - if matched, extract PackageInstance\r
+    //\r
+    if (Handle == HandleDatabase->Handle) {\r
+      PackageInstance = HandleDatabase->Buffer;\r
+      break;\r
+    }\r
+  }\r
+  //\r
+  // No handle was found - error condition\r
+  //\r
+  if (PackageInstance == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);\r
+\r
+  //\r
+  // If there is no specified language, assume the system default language\r
+  //\r
+  if (LanguageString == NULL) {\r
+    //\r
+    // Get system default language\r
+    //\r
+    Status = gRT->GetVariable (\r
+                    (CHAR16 *) L"Lang",\r
+                    &gEfiGlobalVariableGuid,\r
+                    NULL,\r
+                    &DataSize,\r
+                    Lang\r
+                    );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // If Lang doesn't exist, just use the first language you find\r
+      //\r
+      LangFound = FALSE;\r
+      goto LangNotFound;\r
+    }\r
+    //\r
+    // Convert the ASCII Lang variable to a Unicode Language variable\r
+    //\r
+    AsciiToUnicode ((UINT8 *)Lang, Language);\r
+  } else {\r
+    //\r
+    // Copy input ISO value to Language variable\r
+    //\r
+    CopyMem (Language, LanguageString, 6);\r
+  }\r
+  //\r
+  // Based on if there is IFR data in this package instance, determine\r
+  // what the location is of the beginning of the string data.\r
+  //\r
+LangNotFound:\r
+  if (StringPackageInstance->IfrSize > 0) {\r
+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);\r
+  } else {\r
+    StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);\r
+  }\r
+  //\r
+  // If Token is 0, extract entire string package\r
+  //\r
+  if (Token == 0) {\r
+    //\r
+    // Compute the entire string pack length, including all languages' and the terminating pack's.\r
+    //\r
+    Length = 0;\r
+    while (0 != StringPack->Header.Length) {\r
+      Length += StringPack->Header.Length;\r
+      StringPack = (VOID*)(((UINT8*)StringPack) + StringPack->Header.Length);\r
+    }\r
+    //\r
+    // Back to the start of package.\r
+    //\r
+    StringPack = (VOID*)(((UINT8*)StringPack) - Length); \r
+    //\r
+    // Terminating zero sub-pack.\r
+    //\r
+    Length += sizeof (EFI_HII_STRING_PACK); \r
+\r
+    //\r
+    // If trying to get the entire string package and have insufficient space.  Return error.\r
+    //\r
+    if (Length > *BufferLength || StringBuffer == NULL) {\r
+      *BufferLength = (UINT16)Length;\r
+      return EFI_BUFFER_TOO_SMALL;\r
+    }\r
+    //\r
+    // Copy the Pack to the caller's buffer.\r
+    //\r
+    *BufferLength = (UINT16)Length;\r
+    CopyMem (StringBuffer, StringPack, Length);\r
+\r
+    return EFI_SUCCESS;\r
+  }\r
+  //\r
+  // There may be multiple instances packed together of strings\r
+  // so we must walk the self describing structures until we encounter\r
+  // what we are looking for, and then extract the string we are looking for\r
+  //\r
+  CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+  for (; Length != 0;) {\r
+    //\r
+    // If passed in Language ISO value is in this string pack's language string\r
+    // then we are dealing with the strings we want.\r
+    //\r
+    CopyMem (&Offset, &StringPack->LanguageNameString, sizeof (RELOFST));\r
+    Status = HiiCompareLanguage ((CHAR16 *) ((CHAR8 *) (StringPack) + Offset), Language);\r
+\r
+    //\r
+    // If we cannot find the lang variable, we skip this check and use the first language available\r
+    //\r
+    if (LangFound) {\r
+      if (EFI_ERROR (Status)) {\r
+        StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + Length);\r
+        CopyMem (&Length, &StringPack->Header.Length, sizeof (UINT32));\r
+        continue;\r
+      }\r
+    }\r
+\r
+    StringPointer = (RELOFST *) (StringPack + 1);\r
+\r
+    //\r
+    // We have the right string package - size it, and copy it to the StringBuffer\r
+    //\r
+    if (Token >= StringPack->NumStringPointers) {\r
+      return EFI_INVALID_PARAMETER;\r
+    } else {\r
+      CopyMem (&Offset, &StringPointer[Token], sizeof (RELOFST));\r
+    }\r
+    //\r
+    // Since StringPack is a packed structure, we need to determine the string's\r
+    // size safely, thus byte-wise.  Post-increment the size to include the null-terminator\r
+    //\r
+    Local = (UINT16 *) ((CHAR8 *) (StringPack) + Offset);\r
+    for (Count = 0; CompareMem (&Local[Count], &Zero, 2); Count++)\r
+      ;\r
+    Count++;\r
+\r
+    Count = Count * sizeof (CHAR16);;\r
+\r
+    if (*BufferLength >= Count && StringBuffer != NULL) {\r
+      //\r
+      // Copy the string to the user's buffer\r
+      //\r
+      if (Raw) {\r
+        CopyMem (StringBuffer, Local, Count);\r
+      } else {\r
+        for (Count = 0; CompareMem (Local, &Zero, 2); Local++) {\r
+          //\r
+          // Skip "Narraw, Wide, NoBreak"\r
+          //\r
+          if (CompareMem (Local, &Narrow,  2) &&\r
+              CompareMem (Local, &Wide,    2) && \r
+              CompareMem (Local, &NoBreak, 2)) {          \r
+            CopyMem (&StringBuffer[Count++], Local, 2);          \r
+          }        \r
+        } \r
+        //\r
+        // Add "NULL" at the end.\r
+        //\r
+        CopyMem (&StringBuffer[Count], &Zero, 2);\r
+        Count++;\r
+        Count *= sizeof (CHAR16);\r
+      }\r
+\r
+      *BufferLength = (UINT16) Count;\r
+      return EFI_SUCCESS;\r
+    } else {\r
+      *BufferLength = (UINT16) Count;\r
+      return EFI_BUFFER_TOO_SMALL;\r
+    }\r
+\r
+  }\r
+\r
+  LangFound = FALSE;\r
+  goto LangNotFound;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetLine (\r
+  IN     EFI_HII_PROTOCOL   *This,\r
+  IN     EFI_HII_HANDLE     Handle,\r
+  IN     STRING_REF         Token,\r
+  IN OUT UINT16             *Index,\r
+  IN     UINT16             LineWidth,\r
+  IN     CHAR16             *LanguageString,\r
+  IN OUT UINT16             *BufferLength,\r
+  OUT    EFI_STRING         StringBuffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function allows a program to extract a part of a string of not more than a given width.  \r
+  With repeated calls, this allows a calling program to extract "lines" of text that fit inside \r
+  columns.  The effort of measuring the fit of strings inside columns is localized to this call.\r
+\r
+Arguments:\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  UINTN                     Count;\r
+  EFI_HII_PACKAGE_INSTANCE  *PackageInstance;\r
+  EFI_HII_PACKAGE_INSTANCE  *StringPackageInstance;\r
+  EFI_HII_DATA              *HiiData;\r
+  EFI_HII_HANDLE_DATABASE   *HandleDatabase;\r
+  EFI_HII_STRING_PACK       *StringPack;\r
+  RELOFST                   *StringPointer;\r
+  CHAR16                    *Location;\r
+  EFI_STATUS                Status;\r
+  UINTN                     DataSize;\r
+  CHAR8                     Lang[3];\r
+  CHAR16                    Language[3];\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  HiiData         = EFI_HII_DATA_FROM_THIS (This);\r
+\r
+  HandleDatabase  = HiiData->DatabaseHead;\r
+\r
+  PackageInstance = NULL;\r
+  DataSize        = 4;\r
+\r
+  //\r
+  // Check numeric value against the head of the database\r
+  //\r
+  for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {\r
+    //\r
+    // Match the numeric value with the database entry - if matched, extract PackageInstance\r
+    //\r
+    if (Handle == HandleDatabase->Handle) {\r
+      PackageInstance = HandleDatabase->Buffer;\r
+    }\r
+  }\r
+  //\r
+  // No handle was found - error condition\r
+  //\r
+  if (PackageInstance == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = ValidatePack (This, PackageInstance, &StringPackageInstance, NULL);\r
+\r
+  //\r
+  // If there is no specified language, assume the system default language\r
+  //\r
+  if (LanguageString == NULL) {\r
+    //\r
+    // Get system default language\r
+    //\r
+    Status = gRT->GetVariable (\r
+                    (CHAR16 *) L"Lang",\r
+                    &gEfiGlobalVariableGuid,\r
+                    NULL,\r
+                    &DataSize,\r
+                    Lang\r
+                    );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+    //\r
+    // Convert the ASCII Lang variable to a Unicode Language variable\r
+    //\r
+    AsciiToUnicode ((UINT8 *)Lang, Language);\r
+  } else {\r
+    //\r
+    // Copy input ISO value to Language variable\r
+    //\r
+    CopyMem (Language, LanguageString, 6);\r
+  }\r
+  //\r
+  // Based on if there is IFR data in this package instance, determine\r
+  // what the location is of the beginning of the string data.\r
+  //\r
+  if (StringPackageInstance->IfrSize > 0) {\r
+    StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (&StringPackageInstance->IfrData) + StringPackageInstance->IfrSize);\r
+  } else {\r
+    StringPack = (EFI_HII_STRING_PACK *) (&StringPackageInstance->IfrData);\r
+  }\r
+\r
+  StringPointer = (RELOFST *) (StringPack + 1);\r
+\r
+  //\r
+  // There may be multiple instances packed together of strings\r
+  // so we must walk the self describing structures until we encounter\r
+  // what we are looking for, and then extract the string we are looking for\r
+  //\r
+  for (; StringPack->Header.Length != 0;) {\r
+    //\r
+    // If passed in Language ISO value is in this string pack's language string\r
+    // then we are dealing with the strings we want.\r
+    //\r
+    Status = HiiCompareLanguage ((CHAR16 *) ((CHAR8 *) (StringPack) + StringPack->LanguageNameString), Language);\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + StringPack->Header.Length);\r
+      continue;\r
+    }\r
+\r
+    Location = (CHAR16 *) ((CHAR8 *) (StringPack) + StringPointer[Token] +*Index * 2);\r
+\r
+    //\r
+    // If the size of the remaining string is less than the LineWidth\r
+    // then copy the entire thing\r
+    //\r
+    if (StrSize (Location) <= LineWidth) {\r
+      if (*BufferLength >= StrSize (Location)) {\r
+        StrCpy (StringBuffer, Location);\r
+        return EFI_SUCCESS;\r
+      } else {\r
+        *BufferLength = (UINT16) StrSize (Location);\r
+        return EFI_BUFFER_TOO_SMALL;\r
+      }\r
+    } else {\r
+      //\r
+      // Rewind the string from the maximum size until we see a space the break the line\r
+      //\r
+      for (Count = LineWidth; Location[Count] != 0x0020; Count--)\r
+        ;\r
+\r
+      //\r
+      // Put the index at the next character\r
+      //\r
+      *Index = (UINT16) (Count + 1);\r
+\r
+      if (*BufferLength >= Count) {\r
+        StrnCpy (StringBuffer, Location, Count);\r
+        return EFI_SUCCESS;\r
+      } else {\r
+        *BufferLength = (UINT16) Count;\r
+        return EFI_BUFFER_TOO_SMALL;\r
+      }\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+HiiCompareLanguage (\r
+  IN  CHAR16                *LanguageStringLocation,\r
+  IN  CHAR16                *Language\r
+  )\r
+{\r
+  UINT8   *Local;\r
+  UINTN   Index;\r
+  CHAR16  *InputString;\r
+  CHAR16  *OriginalInputString;\r
+\r
+  //\r
+  // Allocate a temporary buffer for InputString\r
+  //\r
+  InputString = AllocateZeroPool (0x100);\r
+\r
+  ASSERT (InputString);\r
+\r
+  OriginalInputString = InputString;\r
+\r
+  Local               = (UINT8 *) LanguageStringLocation;\r
+\r
+  //\r
+  // Determine the size of this packed string safely (e.g. access by byte), post-increment\r
+  // to include the null-terminator\r
+  //\r
+  for (Index = 0; Local[Index] != 0; Index = Index + 2)\r
+    ;\r
+  //\r
+  // MARMAR  Index = Index + 2;\r
+  //\r
+  // This is a packed structure that this location comes from, so let's make sure\r
+  // the value is aligned by copying it to a local variable and working on it.\r
+  //\r
+  CopyMem (InputString, LanguageStringLocation, Index);\r
+\r
+  for (Index = 0; Index < 3; Index++) {\r
+    InputString[Index]  = (CHAR16) (InputString[Index] | 0x20);\r
+    Language[Index]     = (CHAR16) (Language[Index] | 0x20);\r
+  }\r
+  //\r
+  // If the Language is the same return success\r
+  //\r
+  if (CompareMem (LanguageStringLocation, Language, 6) == 0) {\r
+    FreePool (InputString);\r
+    return EFI_SUCCESS;\r
+  }\r
+  //\r
+  // Skip the first three letters that comprised the primary language,\r
+  // see if what is being compared against is a secondary language\r
+  //\r
+  InputString = InputString + 3;\r
+\r
+  //\r
+  // If the Language is not the same as the Primary language, see if there are any\r
+  // secondary languages, and if there are see if we have a match.  If not, return an error.\r
+  //\r
+  for (Index = 0; InputString[Index] != 0; Index = Index + 3) {\r
+    //\r
+    // Getting in here means we have a secondary language\r
+    //\r
+    if (CompareMem (&InputString[Index], Language, 6) == 0) {\r
+      FreePool (InputString);\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+  //\r
+  // If nothing was found, return the error\r
+  //\r
+  FreePool (OriginalInputString);\r
+  return EFI_NOT_FOUND;\r
+\r
+}\r
diff --git a/IntelFrameworkModulePkg/Universal/SetupBrowserDxe/Boolean.c b/IntelFrameworkModulePkg/Universal/SetupBrowserDxe/Boolean.c
new file mode 100644 (file)
index 0000000..b0af07e
--- /dev/null
@@ -0,0 +1,1372 @@
+/*++\r
+\r
+Copyright (c) 2006 - 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
+  Boolean.c\r
+\r
+Abstract:\r
+\r
+  This routine will evaluate the IFR inconsistency data to determine if\r
+  something is a valid entry for a particular expression\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "Setup.h"\r
+#include "Ui.h"\r
+\r
+//\r
+// Global stack used to evaluate boolean expresions\r
+//\r
+BOOLEAN *mBooleanEvaluationStack    = (BOOLEAN) 0;\r
+BOOLEAN *mBooleanEvaluationStackEnd = (BOOLEAN) 0;\r
+\r
+STATIC\r
+VOID\r
+GrowBooleanStack (\r
+  IN OUT BOOLEAN  **Stack,\r
+  IN     UINTN    StackSizeInBoolean\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Grow size of the boolean stack\r
+\r
+Arguments:\r
+\r
+  Stack     - Old stack on the way in and new stack on the way out\r
+\r
+  StackSizeInBoolean - New size of the stack\r
+\r
+Returns:\r
+\r
+  NONE\r
+\r
+--*/\r
+{\r
+  BOOLEAN *NewStack;\r
+\r
+  NewStack = AllocatePool (StackSizeInBoolean * sizeof (BOOLEAN));\r
+  ASSERT (NewStack != NULL);\r
+\r
+  if (*Stack != NULL) {\r
+    //\r
+    // Copy to Old Stack to the New Stack\r
+    //\r
+    CopyMem (\r
+      NewStack,\r
+      mBooleanEvaluationStack,\r
+      (mBooleanEvaluationStackEnd - mBooleanEvaluationStack) * sizeof (BOOLEAN)\r
+      );\r
+\r
+    //\r
+    // Make the Stack pointer point to the old data in the new stack\r
+    //\r
+    *Stack = NewStack + (*Stack - mBooleanEvaluationStack);\r
+\r
+    //\r
+    // Free The Old Stack\r
+    //\r
+    FreePool (mBooleanEvaluationStack);\r
+  }\r
+\r
+  mBooleanEvaluationStack     = NewStack;\r
+  mBooleanEvaluationStackEnd  = NewStack + StackSizeInBoolean;\r
+}\r
+\r
+STATIC\r
+VOID\r
+InitializeBooleanEvaluator (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Allocate a global stack for boolean processing.\r
+\r
+Arguments:\r
+\r
+  NONE\r
+\r
+Returns:\r
+\r
+  NONE\r
+\r
+--*/\r
+{\r
+  BOOLEAN *NullStack;\r
+\r
+  NullStack = NULL;\r
+  GrowBooleanStack (&NullStack, 0x1000);\r
+}\r
+\r
+STATIC\r
+VOID\r
+PushBool (\r
+  IN OUT BOOLEAN  **Stack,\r
+  IN BOOLEAN      BoolResult\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Push an element onto the Boolean Stack\r
+\r
+Arguments:\r
+\r
+  Stack      - Current stack location.\r
+  BoolResult - BOOLEAN to push.\r
+\r
+Returns:\r
+\r
+  None.\r
+\r
+--*/\r
+{\r
+  CopyMem (*Stack, &BoolResult, sizeof (BOOLEAN));\r
+  *Stack += 1;\r
+\r
+  if (*Stack >= mBooleanEvaluationStackEnd) {\r
+    //\r
+    // If we run out of stack space make a new one that is 2X as big. Copy\r
+    // the old data into the new stack and update Stack to point to the old\r
+    // data in the new stack.\r
+    //\r
+    GrowBooleanStack (\r
+      Stack,\r
+      (mBooleanEvaluationStackEnd - mBooleanEvaluationStack) * sizeof (BOOLEAN) * 2\r
+      );\r
+  }\r
+}\r
+\r
+STATIC\r
+BOOLEAN\r
+PopBool (\r
+  IN OUT BOOLEAN **Stack\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Pop an element from the Boolean stack.\r
+\r
+Arguments:\r
+\r
+  Stack - Current stack location\r
+\r
+Returns:\r
+\r
+  Top of the BOOLEAN stack.\r
+\r
+--*/\r
+{\r
+  BOOLEAN ReturnValue;\r
+\r
+  *Stack -= 1;\r
+  CopyMem (&ReturnValue, *Stack, sizeof (BOOLEAN));\r
+  return ReturnValue;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+GrowBooleanExpression (\r
+  IN      EFI_INCONSISTENCY_DATA  *InconsistentTags,\r
+  OUT     VOID                    **BooleanExpression,\r
+  IN OUT  UINTN                   *BooleanExpressionLength\r
+  )\r
+{\r
+  UINT8 *NewExpression;\r
+\r
+  NewExpression = AllocatePool (*BooleanExpressionLength + sizeof (EFI_INCONSISTENCY_DATA));\r
+  ASSERT (NewExpression != NULL);\r
+\r
+  if (*BooleanExpression != NULL) {\r
+    //\r
+    // Copy Old buffer to the New buffer\r
+    //\r
+    CopyMem (NewExpression, *BooleanExpression, *BooleanExpressionLength);\r
+\r
+    CopyMem (&NewExpression[*BooleanExpressionLength], InconsistentTags, sizeof (EFI_INCONSISTENCY_DATA));\r
+\r
+    //\r
+    // Free The Old buffer\r
+    //\r
+    FreePool (*BooleanExpression);\r
+  } else {\r
+    //\r
+    // Copy data into new buffer\r
+    //\r
+    CopyMem (NewExpression, InconsistentTags, sizeof (EFI_INCONSISTENCY_DATA));\r
+  }\r
+\r
+  *BooleanExpressionLength  = *BooleanExpressionLength + sizeof (EFI_INCONSISTENCY_DATA);\r
+  *BooleanExpression        = (VOID *) NewExpression;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+VOID\r
+CreateBooleanExpression (\r
+  IN  EFI_FILE_FORM_TAGS    *FileFormTags,\r
+  IN  UINT16                Value,\r
+  IN  UINT16                Id,\r
+  IN  BOOLEAN               Complex,\r
+  OUT VOID                  **BooleanExpression,\r
+  OUT UINTN                 *BooleanExpressionLength\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  UINTN                   Count;\r
+  EFI_INCONSISTENCY_DATA  *InconsistentTags;\r
+  EFI_INCONSISTENCY_DATA  FakeInconsistentTags;\r
+\r
+  InconsistentTags = FileFormTags->InconsistentTags;\r
+\r
+  //\r
+  // Did we run into a question that contains the Id we are looking for?\r
+  //\r
+  for (Count = 0; InconsistentTags->Operand != 0xFF; Count++) {\r
+\r
+    //\r
+    // Reserve INVALID_OFFSET_VALUE - 1 for TURE and FALSE, because we need to treat them as well\r
+    // as ideqid etc. but they have no coresponding id, so we reserve this value.\r
+    //\r
+    if (InconsistentTags->QuestionId1 == Id ||\r
+        InconsistentTags->QuestionId1 == INVALID_OFFSET_VALUE - 1) {\r
+      //\r
+      // If !Complex - means evaluate a single if/endif expression\r
+      //\r
+      if (!Complex) {\r
+        //\r
+        // If the ConsistencyId does not match the expression we are looking for\r
+        // skip to the next consistency database entry\r
+        //\r
+        if (InconsistentTags->ConsistencyId != Value) {\r
+          goto NextEntry;\r
+        }\r
+      }\r
+      //\r
+      // We need to rewind to the beginning of the Inconsistent expression\r
+      //\r
+      for (;\r
+           (InconsistentTags->Operand != EFI_IFR_INCONSISTENT_IF_OP) &&\r
+             (InconsistentTags->Operand != EFI_IFR_GRAYOUT_IF_OP) &&\r
+             (InconsistentTags->Operand != EFI_IFR_SUPPRESS_IF_OP);\r
+              ) {\r
+        InconsistentTags = InconsistentTags->Previous;\r
+      }\r
+      //\r
+      // Store the consistency check expression, ensure the next for loop starts at the op-code afterwards\r
+      //\r
+      GrowBooleanExpression (InconsistentTags, BooleanExpression, BooleanExpressionLength);\r
+      InconsistentTags = InconsistentTags->Next;\r
+\r
+      //\r
+      // Keep growing until we hit the End expression op-code or we hit the beginning of another\r
+      // consistency check like grayout/suppress\r
+      //\r
+      for (;\r
+           InconsistentTags->Operand != EFI_IFR_END_IF_OP &&\r
+           InconsistentTags->Operand != EFI_IFR_GRAYOUT_IF_OP &&\r
+           InconsistentTags->Operand != EFI_IFR_SUPPRESS_IF_OP;\r
+            ) {\r
+        GrowBooleanExpression (InconsistentTags, BooleanExpression, BooleanExpressionLength);\r
+        InconsistentTags = InconsistentTags->Next;\r
+      }\r
+      //\r
+      // Store the EndExpression Op-code\r
+      //\r
+      GrowBooleanExpression (InconsistentTags, BooleanExpression, BooleanExpressionLength);\r
+    }\r
+\r
+NextEntry:\r
+    if (InconsistentTags->Next != NULL) {\r
+      //\r
+      // Skip to next entry\r
+      //\r
+      InconsistentTags = InconsistentTags->Next;\r
+    }\r
+  }\r
+\r
+  FakeInconsistentTags.Operand = 0;\r
+\r
+  //\r
+  // Add one last expression which will signify we have definitely hit the end\r
+  //\r
+  GrowBooleanExpression (&FakeInconsistentTags, BooleanExpression, BooleanExpressionLength);\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+BooleanVariableWorker (\r
+  IN     CHAR16                   *VariableName,\r
+  IN     EFI_VARIABLE_DEFINITION  *VariableDefinition,\r
+  IN     BOOLEAN                  *StackPtr,\r
+  IN OUT UINTN                    *SizeOfVariable,\r
+  IN OUT VOID                     **VariableData\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = gRT->GetVariable (\r
+                  VariableName,\r
+                  &VariableDefinition->Guid,\r
+                  NULL,\r
+                  SizeOfVariable,\r
+                  *VariableData\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+\r
+    if (Status == EFI_BUFFER_TOO_SMALL) {\r
+      *VariableData = AllocatePool (*SizeOfVariable);\r
+      ASSERT (*VariableData != NULL);\r
+\r
+      Status = gRT->GetVariable (\r
+                      VariableName,\r
+                      &VariableDefinition->Guid,\r
+                      NULL,\r
+                      SizeOfVariable,\r
+                      *VariableData\r
+                      );\r
+    }\r
+\r
+    if (Status == EFI_NOT_FOUND) {\r
+      //\r
+      // This is a serious flaw, we must have some standard result if a variable\r
+      // is not found.  Our default behavior must either be return a TRUE or FALSE\r
+      // since there is nothing else we can really do.  Therefore, my crystal ball\r
+      // says I will return a FALSE\r
+      //\r
+      PushBool (&StackPtr, FALSE);\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+STATIC\r
+UINT8\r
+PredicateIfrType (\r
+  IN  EFI_INCONSISTENCY_DATA      *Iterator\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  This routine is for the purpose of predicate whether the Ifr is generated by a VfrCompiler greater than or equal to 1.88 or\r
+  less than 1.88 which is legacy.\r
+\r
+Arguments:\r
+  Iterator    - The pointer to inconsistency tags\r
+\r
+Returns:\r
+\r
+  0x2         - If IFR is not legacy\r
+\r
+  0x1         - If IFR is legacy\r
+\r
+--*/\r
+{\r
+  //\r
+  // legacy Ifr cover the states:\r
+  // Not ...\r
+  // Operand Opcode Operand\r
+  //\r
+  // while Operand means ideqval, TRUE, or other what can be evaluated to True or False,\r
+  // and Opcode means AND or OR.\r
+  //\r
+  if (Iterator->Operand == EFI_IFR_NOT_OP   ||\r
+      Iterator->Operand == 0) {\r
+    return 0x1;\r
+  } else if (Iterator->Operand == EFI_IFR_EQ_VAR_VAL_OP ||\r
+             Iterator->Operand == EFI_IFR_EQ_ID_VAL_OP  ||\r
+             Iterator->Operand == EFI_IFR_EQ_ID_ID_OP   ||\r
+             Iterator->Operand == EFI_IFR_EQ_ID_LIST_OP) {\r
+    Iterator++;\r
+    if (Iterator->Operand == EFI_IFR_AND_OP ||\r
+        Iterator->Operand == EFI_IFR_OR_OP) {\r
+      Iterator--;\r
+      return 0x1;\r
+    }\r
+    Iterator--;\r
+  }\r
+  return 0x2;\r
+}\r
+\r
+STATIC\r
+VOID\r
+PostOrderEvaluate (\r
+  IN      EFI_FILE_FORM_TAGS          *FileFormTags,\r
+  IN      UINT16                      Width,\r
+  IN OUT  EFI_INCONSISTENCY_DATA      **PIterator,\r
+  IN OUT  BOOLEAN                     **StackPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  PostOrderEvaluate is used for Ifr generated by VfrCompiler greater than or equal to 1.88,\r
+  which generate Operand Operand Opcode type Ifr.\r
+  PostOrderEvaluete only evaluate boolean expression part, not suppressif/grayoutif. TRUE,\r
+  FALSE, >=, >, (, ) are supported.\r
+\r
+Arguments:\r
+\r
+  FileFormTags     - The pointer to the tags of the form\r
+\r
+  Width            - Width of Operand, recognized every iteration\r
+\r
+  PIterator        - The pointer to inconsistency tags\r
+\r
+  StackPtr         - The pointer to the evaluation stack\r
+\r
+Returns:\r
+\r
+  TRUE             - If value is valid\r
+\r
+  FALSE            - If value is not valid\r
+\r
+--*/\r
+{\r
+  BOOLEAN                 Operator;\r
+  BOOLEAN                 Operator2;\r
+  UINT16                  *MapBuffer;\r
+  UINT16                  *MapBuffer2;\r
+  UINT16                  MapValue;\r
+  UINT16                  MapValue2;\r
+  UINTN                   SizeOfVariable;\r
+  CHAR16                  VariableName[MAXIMUM_VALUE_CHARACTERS];\r
+  VOID                    *VariableData;\r
+  EFI_VARIABLE_DEFINITION *VariableDefinition;\r
+  EFI_STATUS              Status;\r
+  UINTN                   Index;\r
+  BOOLEAN                 PushValue;\r
+\r
+  Operator        = FALSE;\r
+  Operator2       = FALSE;\r
+  MapBuffer       = NULL;\r
+  MapBuffer2      = NULL;\r
+  MapValue        = 0;\r
+  MapValue2       = 0;\r
+  VariableData    = NULL;\r
+\r
+  while (TRUE) {\r
+    if ((*PIterator)->Operand == 0) {\r
+      return;\r
+    }\r
+\r
+    Width = (*PIterator)->Width;\r
+\r
+    //\r
+    //  Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.\r
+    //\r
+    if ((*PIterator)->QuestionId1 != INVALID_OFFSET_VALUE &&\r
+        (*PIterator)->QuestionId1 != INVALID_OFFSET_VALUE - 1) {\r
+      ExtractNvValue (FileFormTags, (*PIterator)->VariableNumber, Width, (*PIterator)->QuestionId1, (VOID **) &MapBuffer);\r
+      ExtractNvValue (FileFormTags, (*PIterator)->VariableNumber2, Width, (*PIterator)->QuestionId2, (VOID **) &MapBuffer2);\r
+      if (MapBuffer != NULL) {\r
+        if (Width == 2) {\r
+          MapValue = *MapBuffer;\r
+        } else {\r
+          MapValue = (UINT8) *MapBuffer;\r
+        }\r
+\r
+        FreePool (MapBuffer);\r
+      }\r
+\r
+      if (MapBuffer2 != NULL) {\r
+        if (Width == 2) {\r
+          MapValue2 = *MapBuffer2;\r
+        } else {\r
+          MapValue2 = (UINT8) *MapBuffer2;\r
+        }\r
+\r
+        FreePool (MapBuffer2);\r
+      }\r
+    }\r
+\r
+    switch ((*PIterator)->Operand) {\r
+    case EFI_IFR_EQ_VAR_VAL_OP:\r
+      UnicodeValueToString (\r
+        VariableName,\r
+        FALSE,\r
+        (UINTN) (*PIterator)->QuestionId1,\r
+        (sizeof (VariableName) / sizeof (VariableName[0])) - 1\r
+        );\r
+\r
+      SizeOfVariable = 0;\r
+\r
+      ExtractRequestedNvMap (FileFormTags, (*PIterator)->VariableNumber, &VariableDefinition);\r
+\r
+      Status = BooleanVariableWorker (\r
+                VariableName,\r
+                VariableDefinition,\r
+                *StackPtr,\r
+                &SizeOfVariable,\r
+                &VariableData\r
+                );\r
+\r
+      if (!EFI_ERROR (Status)) {\r
+        if (SizeOfVariable == 1) {\r
+          CopyMem (&MapValue, VariableData, 1);\r
+        } else {\r
+          CopyMem (&MapValue, VariableData, 2);\r
+        }\r
+\r
+        //\r
+        // Do operation after knowing the compare operator.\r
+        //\r
+        MapValue2 = (*PIterator)->Value;\r
+        (*PIterator)++;\r
+        if ((*PIterator)->Operand == EFI_IFR_GT_OP) {\r
+          PushValue = (BOOLEAN) (MapValue > MapValue2);\r
+        } else if ((*PIterator)->Operand == EFI_IFR_GE_OP) {\r
+          PushValue = (BOOLEAN) (MapValue >= MapValue2);\r
+        } else {\r
+          (*PIterator)--;\r
+          PushValue = (BOOLEAN) (MapValue == MapValue2);\r
+        }\r
+        PushBool (StackPtr, PushValue);\r
+      }\r
+\r
+      break;\r
+\r
+    case EFI_IFR_EQ_ID_VAL_OP:\r
+      //\r
+      // Do operation after knowing the compare operator.\r
+      //\r
+      MapValue2 = (*PIterator)->Value;\r
+      (*PIterator)++;\r
+      if ((*PIterator)->Operand == EFI_IFR_GT_OP) {\r
+        PushValue = (BOOLEAN) (MapValue > MapValue2);\r
+      } else if ((*PIterator)->Operand == EFI_IFR_GE_OP) {\r
+        PushValue = (BOOLEAN) (MapValue >= MapValue2);\r
+      } else {\r
+        (*PIterator)--;\r
+        PushValue = (BOOLEAN) (MapValue == MapValue2);\r
+      }\r
+      PushBool (StackPtr, PushValue);\r
+      break;\r
+\r
+    case EFI_IFR_EQ_ID_ID_OP:\r
+      //\r
+      // Do operation after knowing the compare operator.\r
+      //\r
+      (*PIterator)++;\r
+      if ((*PIterator)->Operand == EFI_IFR_GT_OP) {\r
+        PushValue = (BOOLEAN) (MapValue > MapValue2);\r
+      } else if ((*PIterator)->Operand == EFI_IFR_GE_OP) {\r
+        PushValue = (BOOLEAN) (MapValue >= MapValue2);\r
+      } else {\r
+        (*PIterator)--;\r
+        PushValue = (BOOLEAN) (MapValue == MapValue2);\r
+      }\r
+      PushBool (StackPtr, PushValue);\r
+      break;\r
+\r
+    case EFI_IFR_EQ_ID_LIST_OP:\r
+      for (Index = 0; Index < (*PIterator)->ListLength; Index++) {\r
+        Operator = (BOOLEAN) (MapValue == (*PIterator)->ValueList[Index]);\r
+        if (Operator) {\r
+          break;\r
+        }\r
+      }\r
+\r
+      PushBool (StackPtr, Operator);\r
+      break;\r
+\r
+    case EFI_IFR_TRUE_OP:\r
+      PushBool (StackPtr, TRUE);\r
+      break;\r
+\r
+    case EFI_IFR_FALSE_OP:\r
+      PushBool (StackPtr, FALSE);\r
+      break;\r
+\r
+    case EFI_IFR_AND_OP:\r
+      Operator  = PopBool (StackPtr);\r
+      Operator2 = PopBool (StackPtr);\r
+      PushBool (StackPtr, (BOOLEAN) (Operator && Operator2));\r
+      break;\r
+    case EFI_IFR_OR_OP:\r
+      Operator  = PopBool (StackPtr);\r
+      Operator2 = PopBool (StackPtr);\r
+      PushBool (StackPtr, (BOOLEAN) (Operator || Operator2));\r
+      break;\r
+    case EFI_IFR_NOT_OP:\r
+      Operator  = PopBool (StackPtr);\r
+      PushBool (StackPtr, (BOOLEAN) (!Operator));\r
+      break;\r
+\r
+    case EFI_IFR_SUPPRESS_IF_OP:\r
+    case EFI_IFR_GRAYOUT_IF_OP:\r
+    case EFI_IFR_INCONSISTENT_IF_OP:\r
+    default:\r
+      //\r
+      // Return to the previous tag if runs out of boolean expression.\r
+      //\r
+      (*PIterator)--;\r
+      return;\r
+    }\r
+    (*PIterator)++;\r
+  }\r
+}\r
+\r
+BOOLEAN\r
+ValueIsNotValid (\r
+  IN  BOOLEAN                     Complex,\r
+  IN  UINT16                      Value,\r
+  IN  EFI_TAG                     *Tag,\r
+  IN  EFI_FILE_FORM_TAGS          *FileFormTags,\r
+  IN  STRING_REF                  *PopUp\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  TRUE - If value is valid\r
+\r
+  FALSE - If value is not valid\r
+\r
+--*/\r
+{\r
+  BOOLEAN                 *StackPtr;\r
+  EFI_INCONSISTENCY_DATA  *Iterator;\r
+  BOOLEAN                 Operator;\r
+  BOOLEAN                 Operator2;\r
+  UINTN                   Index;\r
+  VOID                    *BooleanExpression;\r
+  UINTN                   BooleanExpressionLength;\r
+  BOOLEAN                 NotOperator;\r
+  BOOLEAN                 OrOperator;\r
+  BOOLEAN                 AndOperator;\r
+  BOOLEAN                 ArtificialEnd;\r
+  UINT16                  *MapBuffer;\r
+  UINT16                  *MapBuffer2;\r
+  UINT16                  MapValue;\r
+  UINT16                  MapValue2;\r
+  UINTN                   SizeOfVariable;\r
+  CHAR16                  VariableName[MAXIMUM_VALUE_CHARACTERS];\r
+  VOID                    *VariableData;\r
+  EFI_STATUS              Status;\r
+  UINT16                  Id;\r
+  UINT16                  Width;\r
+  EFI_VARIABLE_DEFINITION *VariableDefinition;\r
+  BOOLEAN                 CosmeticConsistency;\r
+  UINT8                   IsLegacy;\r
+\r
+  VariableData            = NULL;\r
+  BooleanExpressionLength = 0;\r
+  BooleanExpression       = NULL;\r
+  Operator                = FALSE;\r
+  ArtificialEnd           = FALSE;\r
+  CosmeticConsistency     = TRUE;\r
+  IsLegacy                = 0;\r
+\r
+  Id                      = Tag->Id;\r
+  if (Tag->StorageWidth == 1) {\r
+    Width = 1;\r
+  } else {\r
+    Width = 2;\r
+  }\r
+  CreateBooleanExpression (FileFormTags, Value, Id, Complex, &BooleanExpression, &BooleanExpressionLength);\r
+\r
+  if (mBooleanEvaluationStack == 0) {\r
+    InitializeBooleanEvaluator ();\r
+  }\r
+\r
+  if (BooleanExpression == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  StackPtr    = mBooleanEvaluationStack;\r
+  Iterator    = BooleanExpression;\r
+  MapBuffer   = NULL;\r
+  MapBuffer2  = NULL;\r
+  MapValue    = 0;\r
+  MapValue2   = 0;\r
+\r
+  while (TRUE) {\r
+    NotOperator = FALSE;\r
+    OrOperator  = FALSE;\r
+    AndOperator = FALSE;\r
+\r
+    if (Iterator->Operand == 0) {\r
+      return Operator;\r
+    }\r
+\r
+    //\r
+    //  Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.\r
+    //\r
+    if (Iterator->QuestionId1 != INVALID_OFFSET_VALUE &&\r
+        Iterator->QuestionId1 != INVALID_OFFSET_VALUE-1) {\r
+      ExtractNvValue (FileFormTags, Iterator->VariableNumber, Width, Iterator->QuestionId1, (VOID **) &MapBuffer);\r
+      ExtractNvValue (FileFormTags, Iterator->VariableNumber2, Width, Iterator->QuestionId2, (VOID **) &MapBuffer2);\r
+      if (MapBuffer != NULL) {\r
+        if (Width == 2) {\r
+          MapValue = *MapBuffer;\r
+        } else {\r
+          MapValue = (UINT8) *MapBuffer;\r
+        }\r
+\r
+        FreePool (MapBuffer);\r
+      }\r
+\r
+      if (MapBuffer2 != NULL) {\r
+        if (Width == 2) {\r
+          MapValue2 = *MapBuffer2;\r
+        } else {\r
+          MapValue2 = (UINT8) *MapBuffer2;\r
+        }\r
+\r
+        FreePool (MapBuffer2);\r
+      }\r
+    }\r
+\r
+    switch (Iterator->Operand) {\r
+    case EFI_IFR_SUPPRESS_IF_OP:\r
+      //\r
+      // Must have hit a suppress followed by a grayout or vice-versa\r
+      //\r
+      if (ArtificialEnd) {\r
+        ArtificialEnd = FALSE;\r
+        Operator      = PopBool (&StackPtr);\r
+        if (Operator) {\r
+          Tag->Suppress = TRUE;\r
+        }\r
+\r
+        return Operator;\r
+      }\r
+\r
+      ArtificialEnd = TRUE;\r
+      *PopUp        = Iterator->Popup;\r
+      break;\r
+\r
+    case EFI_IFR_GRAYOUT_IF_OP:\r
+      //\r
+      // Must have hit a suppress followed by a grayout or vice-versa\r
+      //\r
+      if (ArtificialEnd) {\r
+        ArtificialEnd = FALSE;\r
+        Operator      = PopBool (&StackPtr);\r
+        if (Operator) {\r
+          Tag->GrayOut = TRUE;\r
+        }\r
+\r
+        return Operator;\r
+      }\r
+\r
+      ArtificialEnd = TRUE;\r
+      *PopUp        = Iterator->Popup;\r
+      break;\r
+\r
+    case EFI_IFR_INCONSISTENT_IF_OP:\r
+      CosmeticConsistency = FALSE;\r
+      *PopUp              = Iterator->Popup;\r
+      break;\r
+\r
+    //\r
+    // In the case of external variable values, we must read the variable which is\r
+    // named by the human readable version of the OpCode->VariableId and the guid of the formset\r
+    //\r
+    case EFI_IFR_EQ_VAR_VAL_OP:\r
+      //\r
+      // To check whether Ifr is legacy. Once every boolean expression.\r
+      //\r
+      if (IsLegacy == 0) {\r
+        IsLegacy = PredicateIfrType (Iterator);\r
+      }\r
+      if (IsLegacy == 0x2) {\r
+        PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);\r
+        break;\r
+      }\r
+\r
+      UnicodeValueToString (\r
+        VariableName,\r
+        FALSE,\r
+        (UINTN) Iterator->QuestionId1,\r
+        (sizeof (VariableName) / sizeof (VariableName[0])) - 1\r
+        );\r
+\r
+      SizeOfVariable = 0;\r
+\r
+      ExtractRequestedNvMap (FileFormTags, Iterator->VariableNumber, &VariableDefinition);\r
+\r
+      Status = BooleanVariableWorker (\r
+                VariableName,\r
+                VariableDefinition,\r
+                StackPtr,\r
+                &SizeOfVariable,\r
+                &VariableData\r
+                );\r
+\r
+      if (!EFI_ERROR (Status)) {\r
+        if (SizeOfVariable == 1) {\r
+          CopyMem (&MapValue, VariableData, 1);\r
+        } else {\r
+          CopyMem (&MapValue, VariableData, 2);\r