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
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
--- /dev/null
+/**@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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+#/** @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
--- /dev/null
+<?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
--- /dev/null
+//\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
--- /dev/null
+/*++\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
--- /dev/null
+//\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
--- /dev/null
+/**@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
--- /dev/null
+/*++\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
--- /dev/null
+/**@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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+#/** @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
--- /dev/null
+<?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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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