summaryrefslogtreecommitdiff
path: root/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib
diff options
context:
space:
mode:
Diffstat (limited to 'EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib')
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.inf50
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrCommon.c618
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrForm.c1141
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrLibrary.h1127
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrOpCodeCreation.c640
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrString.c702
6 files changed, 4278 insertions, 0 deletions
diff --git a/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.inf b/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.inf
new file mode 100644
index 0000000000..f5e66c1511
--- /dev/null
+++ b/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.inf
@@ -0,0 +1,50 @@
+#/*++
+#
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Module Name:
+#
+# UfiIfrSupportLib.inf
+#
+# Abstract:
+#
+# Component description file.
+#
+#--*/
+
+[defines]
+BASE_NAME = UefiEfiIfrSupportLib
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ UefiIfrCommon.c
+ UefiIfrForm.c
+ UefiIfrString.c
+ UefiIfrOpCodeCreation.c
+ UefiIfrLibrary.h
+
+[includes.common]
+ $(EDK_SOURCE)\Foundation\Efi
+ $(EDK_SOURCE)\Foundation\Framework
+ $(EDK_SOURCE)\Foundation
+ .
+ $(EDK_SOURCE)\Foundation\Include
+ $(EDK_SOURCE)\Foundation\Efi\Include
+ $(EDK_SOURCE)\Foundation\Framework\Include
+ $(EDK_SOURCE)\Foundation\Include\IndustryStandard
+ $(EDK_SOURCE)\Foundation\Core\Dxe
+ $(EDK_SOURCE)\Foundation\Library\Dxe\Include
+ $(EDK_SOURCE)\Foundation\Library\Dxe\EfiDriverLib
+
+[libraries.common]
+ EfiGuidLib
+ EdkFrameworkProtocolLib
+
+[nmake.common]
diff --git a/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrCommon.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrCommon.c
new file mode 100644
index 0000000000..7e9553ffe0
--- /dev/null
+++ b/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrCommon.c
@@ -0,0 +1,618 @@
+/*++
+
+Copyright (c) 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ UefiIfrCommon.c
+
+Abstract:
+
+ Common Library Routines to assist handle HII elements.
+
+--*/
+
+#include "UefiIfrLibrary.h"
+
+//
+// Hii vendor device path template
+//
+HII_VENDOR_DEVICE_PATH mHiiVendorDevicePathTemplate = {
+ {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ (UINT8) (sizeof (HII_VENDOR_DEVICE_PATH_NODE)),
+ (UINT8) ((sizeof (HII_VENDOR_DEVICE_PATH_NODE)) >> 8)
+ },
+ EFI_IFR_TIANO_GUID,
+ },
+ 0
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+};
+
+//
+// Hii relative protocols
+//
+BOOLEAN mHiiProtocolsInitialized = FALSE;
+
+EFI_HII_DATABASE_PROTOCOL *gIfrLibHiiDatabase;
+EFI_HII_STRING_PROTOCOL *gIfrLibHiiString;
+
+VOID
+LocateHiiProtocols (
+ VOID
+ )
+/*++
+
+Routine Description:
+ This function locate Hii relative protocols for later usage.
+
+Arguments:
+ None.
+
+Returns:
+ None.
+
+--*/
+{
+ EFI_STATUS Status;
+
+ if (mHiiProtocolsInitialized) {
+ return;
+ }
+
+ Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, &gIfrLibHiiDatabase);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, &gIfrLibHiiString);
+ ASSERT_EFI_ERROR (Status);
+
+ mHiiProtocolsInitialized = TRUE;
+}
+
+EFI_HII_PACKAGE_LIST_HEADER *
+PreparePackageList (
+ IN UINTN NumberOfPackages,
+ IN EFI_GUID *GuidId,
+ ...
+ )
+/*++
+
+Routine Description:
+ Assemble EFI_HII_PACKAGE_LIST according to the passed in packages.
+
+Arguments:
+ NumberOfPackages - Number of packages.
+ GuidId - Package GUID.
+
+Returns:
+ Pointer of EFI_HII_PACKAGE_LIST_HEADER.
+
+--*/
+{
+ VA_LIST Marker;
+ EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;
+ UINT8 *PackageListData;
+ UINT32 PackageListLength;
+ UINT32 PackageLength;
+ EFI_HII_PACKAGE_HEADER PackageHeader;
+ UINT8 *PackageArray;
+ UINTN Index;
+
+ PackageListLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
+
+ VA_START (Marker, GuidId);
+ for (Index = 0; Index < NumberOfPackages; Index++) {
+ EfiCopyMem (&PackageLength, VA_ARG (Marker, VOID *), sizeof (UINT32));
+ PackageListLength += (PackageLength - sizeof (UINT32));
+ }
+ VA_END (Marker);
+
+ //
+ // Include the lenght of EFI_HII_PACKAGE_END
+ //
+ PackageListLength += sizeof (EFI_HII_PACKAGE_HEADER);
+ PackageListHeader = EfiLibAllocateZeroPool (PackageListLength);
+ ASSERT (PackageListHeader != NULL);
+ EfiCopyMem (&PackageListHeader->PackageListGuid, GuidId, sizeof (EFI_GUID));
+ PackageListHeader->PackageLength = PackageListLength;
+
+ PackageListData = ((UINT8 *) PackageListHeader) + sizeof (EFI_HII_PACKAGE_LIST_HEADER);
+
+ VA_START (Marker, GuidId);
+ for (Index = 0; Index < NumberOfPackages; Index++) {
+ PackageArray = (UINT8 *) VA_ARG (Marker, VOID *);
+ EfiCopyMem (&PackageLength, PackageArray, sizeof (UINT32));
+ PackageLength -= sizeof (UINT32);
+ PackageArray += sizeof (UINT32);
+ EfiCopyMem (PackageListData, PackageArray, PackageLength);
+ PackageListData += PackageLength;
+ }
+ VA_END (Marker);
+
+ //
+ // Append EFI_HII_PACKAGE_END
+ //
+ PackageHeader.Type = EFI_HII_PACKAGE_END;
+ PackageHeader.Length = sizeof (EFI_HII_PACKAGE_HEADER);
+ EfiCopyMem (PackageListData, &PackageHeader, PackageHeader.Length);
+
+ return PackageListHeader;
+}
+
+EFI_STATUS
+CreateHiiDriverHandle (
+ OUT EFI_HANDLE *DriverHandle
+ )
+/*++
+
+Routine Description:
+ The HII driver handle passed in for HiiDatabase.NewPackageList() requires
+ that there should be DevicePath Protocol installed on it.
+ This routine create a virtual Driver Handle by installing a vendor device
+ path on it, so as to use it to invoke HiiDatabase.NewPackageList().
+
+Arguments:
+ DriverHandle - Handle to be returned
+
+Returns:
+ EFI_SUCCESS - Handle destroy success.
+ EFI_OUT_OF_RESOURCES - Not enough memory.
+
+--*/
+{
+ EFI_STATUS Status;
+ HII_VENDOR_DEVICE_PATH_NODE *VendorDevicePath;
+ UINT64 MonotonicCount;
+
+ VendorDevicePath = EfiLibAllocateCopyPool (sizeof (HII_VENDOR_DEVICE_PATH), &mHiiVendorDevicePathTemplate);
+ if (VendorDevicePath == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ gBS->GetNextMonotonicCount (&MonotonicCount);
+ VendorDevicePath->MonotonicCount = (UINT32) MonotonicCount;
+
+ *DriverHandle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ VendorDevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DestroyHiiDriverHandle (
+ IN EFI_HANDLE DriverHandle
+ )
+/*++
+
+Routine Description:
+ Destroy the Driver Handle created by CreateHiiDriverHandle().
+
+Arguments:
+ DriverHandle - Handle returned by CreateHiiDriverHandle()
+
+Returns:
+ EFI_SUCCESS - Handle destroy success.
+ other - Handle destroy fail.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ Status = gBS->HandleProtocol (
+ DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->UninstallProtocolInterface (
+ DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ DevicePath
+ );
+
+ return Status;
+}
+
+EFI_HII_HANDLE
+DevicePathToHiiHandle (
+ IN EFI_HII_DATABASE_PROTOCOL *HiiDatabase,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+Routine Description:
+ Find HII Handle associated with given Device Path.
+
+Arguments:
+ HiiDatabase - Point to EFI_HII_DATABASE_PROTOCOL instance.
+ DevicePath - Device Path associated with the HII package list handle.
+
+Returns:
+ Handle - HII package list Handle associated with the Device Path.
+ NULL - Hii Package list handle is not found.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
+ UINTN BufferSize;
+ UINTN HandleCount;
+ UINTN Index;
+ EFI_HANDLE *Handles;
+ EFI_HANDLE Handle;
+ UINTN Size;
+ EFI_HANDLE DriverHandle;
+ EFI_HII_HANDLE *HiiHandles;
+ EFI_HII_HANDLE HiiHandle;
+
+ //
+ // Locate Device Path Protocol handle buffer
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiDevicePathProtocolGuid,
+ NULL,
+ &HandleCount,
+ &Handles
+ );
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ //
+ // Search Driver Handle by Device Path
+ //
+ DriverHandle = NULL;
+ BufferSize = EfiDevicePathSize (DevicePath);
+ for(Index = 0; Index < HandleCount; Index++) {
+ Handle = Handles[Index];
+ gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, &TmpDevicePath);
+
+ //
+ // Check whether DevicePath match
+ //
+ Size = EfiDevicePathSize (TmpDevicePath);
+ if ((Size == BufferSize) && EfiCompareMem (DevicePath, TmpDevicePath, Size) == 0) {
+ DriverHandle = Handle;
+ break;
+ }
+ }
+ gBS->FreePool (Handles);
+
+ if (DriverHandle == NULL) {
+ return NULL;
+ }
+
+ //
+ // Retrieve all Hii Handles from HII database
+ //
+ BufferSize = 0x1000;
+ HiiHandles = EfiLibAllocatePool (BufferSize);
+ ASSERT (HiiHandles != NULL);
+ Status = HiiDatabase->ListPackageLists (
+ HiiDatabase,
+ EFI_HII_PACKAGE_TYPE_ALL,
+ NULL,
+ &BufferSize,
+ HiiHandles
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ gBS->FreePool (HiiHandles);
+ HiiHandles = EfiLibAllocatePool (BufferSize);
+ ASSERT (HiiHandles != NULL);
+
+ Status = HiiDatabase->ListPackageLists (
+ HiiDatabase,
+ EFI_HII_PACKAGE_TYPE_ALL,
+ NULL,
+ &BufferSize,
+ HiiHandles
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (HiiHandles);
+ return NULL;
+ }
+
+ //
+ // Search Hii Handle by Driver Handle
+ //
+ HiiHandle = NULL;
+ HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = HiiDatabase->GetPackageListHandle (
+ HiiDatabase,
+ HiiHandles[Index],
+ &Handle
+ );
+ if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {
+ HiiHandle = HiiHandles[Index];
+ break;
+ }
+ }
+
+ gBS->FreePool (HiiHandles);
+ return HiiHandle;
+}
+
+EFI_STATUS
+GetHiiHandles (
+ IN OUT UINTN *HandleBufferLength,
+ OUT EFI_HII_HANDLE **HiiHandleBuffer
+ )
+/*++
+
+Routine Description:
+ Determines the handles that are currently active in the database.
+ It's the caller's responsibility to free handle buffer.
+
+Arguments:
+ HiiDatabase - A pointer to the EFI_HII_DATABASE_PROTOCOL instance.
+ HandleBufferLength - On input, a pointer to the length of the handle buffer. On output,
+ the length of the handle buffer that is required for the handles found.
+ HiiHandleBuffer - Pointer to an array of Hii Handles returned.
+
+Returns:
+ EFI_SUCCESS - Get an array of Hii Handles successfully.
+ EFI_INVALID_PARAMETER - Hii is NULL.
+ EFI_NOT_FOUND - Database not found.
+
+--*/
+{
+ UINTN BufferLength;
+ EFI_STATUS Status;
+
+ BufferLength = 0;
+
+ LocateHiiProtocols ();
+
+ //
+ // Try to find the actual buffer size for HiiHandle Buffer.
+ //
+ Status = gIfrLibHiiDatabase->ListPackageLists (
+ gIfrLibHiiDatabase,
+ EFI_HII_PACKAGE_TYPE_ALL,
+ NULL,
+ &BufferLength,
+ *HiiHandleBuffer
+ );
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ *HiiHandleBuffer = EfiLibAllocateZeroPool (BufferLength);
+ Status = gIfrLibHiiDatabase->ListPackageLists (
+ gIfrLibHiiDatabase,
+ EFI_HII_PACKAGE_TYPE_ALL,
+ NULL,
+ &BufferLength,
+ *HiiHandleBuffer
+ );
+ //
+ // we should not fail here.
+ //
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ *HandleBufferLength = BufferLength;
+
+ return Status;
+}
+
+EFI_STATUS
+ExtractGuidFromHiiHandle (
+ IN EFI_HII_HANDLE Handle,
+ OUT EFI_GUID *Guid
+ )
+/*++
+
+Routine Description:
+ Extract Hii package list GUID for given HII handle.
+
+Arguments:
+ HiiHandle - Hii handle
+ Guid - Package list GUID
+
+Returns:
+ EFI_SUCCESS - Successfully extract GUID from Hii database.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
+
+ //
+ // Locate HII Database protocol
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiHiiDatabaseProtocolGuid,
+ NULL,
+ &HiiDatabase
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get HII PackageList
+ //
+ BufferSize = 0;
+ HiiPackageList = NULL;
+ Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ HiiPackageList = EfiLibAllocatePool (BufferSize);
+ ASSERT (HiiPackageList != NULL);
+
+ Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Extract GUID
+ //
+ EfiCopyMem (Guid, &HiiPackageList->PackageListGuid, sizeof (EFI_GUID));
+
+ gBS->FreePool (HiiPackageList);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ExtractClassFromHiiHandle (
+ IN EFI_HII_HANDLE Handle,
+ OUT UINT16 *Class,
+ OUT EFI_STRING_ID *FormSetTitle,
+ OUT EFI_STRING_ID *FormSetHelp
+ )
+/*++
+
+Routine Description:
+ Extract formset class for given HII handle.
+
+Arguments:
+ HiiHandle - Hii handle
+ Class - Class of the formset
+ FormSetTitle - Formset title string
+ FormSetHelp - Formset help string
+
+Returns:
+ EFI_SUCCESS - Successfully extract Class for specified Hii handle.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
+ UINT8 *Package;
+ UINT8 *FormSet;
+ UINT8 *OpCodeData;
+ UINT32 Offset;
+ UINT32 Offset2;
+ UINT32 PackageListLength;
+ EFI_HII_PACKAGE_HEADER PackageHeader;
+
+ *Class = EFI_NON_DEVICE_CLASS;
+ *FormSetTitle = 0;
+ *FormSetHelp = 0;
+
+ //
+ // Locate HII Database protocol
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiHiiDatabaseProtocolGuid,
+ NULL,
+ &HiiDatabase
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get HII PackageList
+ //
+ BufferSize = 0;
+ HiiPackageList = NULL;
+ Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ HiiPackageList = EfiLibAllocatePool (BufferSize);
+ ASSERT (HiiPackageList != NULL);
+
+ Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get Form package from this HII package List
+ //
+ Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
+ Offset2 = 0;
+ FormSet = NULL;
+ EfiCopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
+
+ while (Offset < PackageListLength) {
+ Package = ((UINT8 *) HiiPackageList) + Offset;
+ EfiCopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
+
+ if (PackageHeader.Type == EFI_HII_PACKAGE_FORM) {
+ //
+ // Search Class Opcode in this Form Package
+ //
+ Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
+ while (Offset2 < PackageHeader.Length) {
+ OpCodeData = Package + Offset2;
+
+ if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
+ //
+ // Find FormSet OpCode
+ //
+ EfiCopyMem (FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
+ EfiCopyMem (FormSetHelp, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));
+ }
+
+ if ((((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_GUID_OP) &&
+ (EfiCompareGuid (&mIfrVendorGuid, &((EFI_IFR_GUID *) OpCodeData)->Guid)) &&
+ (((EFI_IFR_GUID_CLASS *) OpCodeData)->ExtendOpCode == EFI_IFR_EXTEND_OP_CLASS)
+ ) {
+ //
+ // Find GUIDed Class OpCode
+ //
+ EfiCopyMem (Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));
+
+ //
+ // Till now, we ought to have found the formset Opcode
+ //
+ break;
+ }
+
+ Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
+ }
+
+ if (Offset2 < PackageHeader.Length) {
+ //
+ // Target formset found
+ //
+ break;
+ }
+ }
+
+ Offset += PackageHeader.Length;
+ }
+
+ gBS->FreePool (HiiPackageList);
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrForm.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrForm.c
new file mode 100644
index 0000000000..381e9d21a5
--- /dev/null
+++ b/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrForm.c
@@ -0,0 +1,1141 @@
+/*++
+
+Copyright (c) 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ UefiIfrForm.c
+
+Abstract:
+
+ Common Library Routines to assist handle HII elements.
+
+--*/
+
+#include "UefiIfrLibrary.h"
+
+//
+// Fake <ConfigHdr>
+//
+UINT16 mFakeConfigHdr[] = L"GUID=00000000000000000000000000000000&NAME=0000&PATH=0";
+
+STATIC
+EFI_STATUS
+GetPackageDataFromPackageList (
+ IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList,
+ IN UINT32 PackageIndex,
+ OUT UINT32 *BufferLen,
+ OUT EFI_HII_PACKAGE_HEADER **Buffer
+ )
+{
+ UINT32 Index;
+ EFI_HII_PACKAGE_HEADER *Package;
+ UINT32 Offset;
+ UINT32 PackageListLength;
+ EFI_HII_PACKAGE_HEADER PackageHeader = {0, 0};
+
+ ASSERT(HiiPackageList != NULL);
+
+ if ((BufferLen == NULL) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Package = NULL;
+ Index = 0;
+ Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
+ EfiCopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
+ while (Offset < PackageListLength) {
+ Package = (EFI_HII_PACKAGE_HEADER *) (((UINT8 *) HiiPackageList) + Offset);
+ EfiCopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
+ if (Index == PackageIndex) {
+ break;
+ }
+ Offset += PackageHeader.Length;
+ Index++;
+ }
+ if (Offset >= PackageListLength) {
+ //
+ // no package found in this Package List
+ //
+ return EFI_NOT_FOUND;
+ }
+
+ *BufferLen = PackageHeader.Length;
+ *Buffer = Package;
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+UpdateFormPackageData (
+ IN EFI_GUID *FormSetGuid,
+ IN EFI_FORM_ID FormId,
+ IN EFI_HII_PACKAGE_HEADER *Package,
+ IN UINT32 PackageLength,
+ IN UINT16 Label,
+ IN BOOLEAN Insert,
+ IN EFI_HII_UPDATE_DATA *Data,
+ OUT UINT8 **TempBuffer,
+ OUT UINT32 *TempBufferSize
+ )
+{
+ UINTN AddSize;
+ UINT8 *BufferPos;
+ EFI_HII_PACKAGE_HEADER PackageHeader;
+ UINTN Offset;
+ EFI_IFR_OP_HEADER *IfrOpHdr;
+ BOOLEAN GetFormSet;
+ BOOLEAN GetForm;
+ UINT8 ExtendOpCode;
+ UINT16 LabelNumber;
+ BOOLEAN Updated;
+ EFI_IFR_OP_HEADER *AddOpCode;
+
+ if ((TempBuffer == NULL) || (TempBufferSize == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *TempBufferSize = PackageLength;
+ if (Data != NULL) {
+ *TempBufferSize += Data->Offset;
+ }
+ *TempBuffer = EfiLibAllocateZeroPool (*TempBufferSize);
+ if (*TempBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ EfiCopyMem (*TempBuffer, Package, sizeof (EFI_HII_PACKAGE_HEADER));
+ *TempBufferSize = sizeof (EFI_HII_PACKAGE_HEADER);
+ BufferPos = *TempBuffer + sizeof (EFI_HII_PACKAGE_HEADER);
+
+ EfiCopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
+ IfrOpHdr = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + sizeof (EFI_HII_PACKAGE_HEADER));
+ Offset = sizeof (EFI_HII_PACKAGE_HEADER);
+ GetFormSet = (FormSetGuid == NULL) ? TRUE : FALSE;
+ GetForm = FALSE;
+ Updated = FALSE;
+
+ while (Offset < PackageHeader.Length) {
+ EfiCopyMem (BufferPos, IfrOpHdr, IfrOpHdr->Length);
+ BufferPos += IfrOpHdr->Length;
+ *TempBufferSize += IfrOpHdr->Length;
+
+ switch (IfrOpHdr->OpCode) {
+ case EFI_IFR_FORM_SET_OP :
+ if (FormSetGuid != NULL) {
+ if (EfiCompareMem (&((EFI_IFR_FORM_SET *) IfrOpHdr)->Guid, FormSetGuid, sizeof (EFI_GUID)) == 0) {
+ GetFormSet = TRUE;
+ }
+ }
+ break;
+
+ case EFI_IFR_FORM_OP:
+ if (EfiCompareMem (&((EFI_IFR_FORM *) IfrOpHdr)->FormId, &FormId, sizeof (EFI_FORM_ID)) == 0) {
+ GetForm = TRUE;
+ }
+ break;
+
+ case EFI_IFR_GUID_OP :
+ if (!GetFormSet || !GetForm || Updated) {
+ //
+ // Go to the next Op-Code
+ //
+ Offset += IfrOpHdr->Length;
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);
+ continue;
+ }
+
+ ExtendOpCode = ((EFI_IFR_GUID_LABEL *) IfrOpHdr)->ExtendOpCode;
+ EfiCopyMem (&LabelNumber, &((EFI_IFR_GUID_LABEL *)IfrOpHdr)->Number, sizeof (UINT16));
+ if ((ExtendOpCode != EFI_IFR_EXTEND_OP_LABEL) || (LabelNumber != Label)) {
+ //
+ // Go to the next Op-Code
+ //
+ Offset += IfrOpHdr->Length;
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);
+ continue;
+ }
+
+ if (Insert && (Data != NULL)) {
+ //
+ // insert the DataCount amount of opcodes to TempBuffer if Data is NULL remove
+ // DataCount amount of opcodes unless runing into a label.
+ //
+ AddOpCode = (EFI_IFR_OP_HEADER *)Data->Data;
+ AddSize = 0;
+ while (AddSize < Data->Offset) {
+ EfiCopyMem (BufferPos, AddOpCode, AddOpCode->Length);
+ BufferPos += AddOpCode->Length;
+ *TempBufferSize += AddOpCode->Length;
+
+ AddSize += AddOpCode->Length;
+ AddOpCode = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (AddOpCode) + AddOpCode->Length);
+ }
+ } else {
+ //
+ // Search the next Label.
+ //
+ while (TRUE) {
+ Offset += IfrOpHdr->Length;
+ //
+ // Search the next label and Fail if not label found.
+ //
+ if (Offset >= PackageHeader.Length) {
+ goto Fail;
+ }
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);
+ if (IfrOpHdr->OpCode == EFI_IFR_GUID_OP) {
+ ExtendOpCode = ((EFI_IFR_GUID_LABEL *) IfrOpHdr)->ExtendOpCode;
+ if (ExtendOpCode == EFI_IFR_EXTEND_OP_LABEL) {
+ break;
+ }
+ }
+ }
+
+ if (Data != NULL) {
+ AddOpCode = (EFI_IFR_OP_HEADER *)Data->Data;
+ AddSize = 0;
+ while (AddSize < Data->Offset) {
+ EfiCopyMem (BufferPos, AddOpCode, AddOpCode->Length);
+ BufferPos += AddOpCode->Length;
+ *TempBufferSize += AddOpCode->Length;
+
+ AddSize += AddOpCode->Length;
+ AddOpCode = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (AddOpCode) + AddOpCode->Length);
+ }
+ }
+
+ //
+ // copy the next label
+ //
+ EfiCopyMem (BufferPos, IfrOpHdr, IfrOpHdr->Length);
+ BufferPos += IfrOpHdr->Length;
+ *TempBufferSize += IfrOpHdr->Length;
+ }
+
+ Updated = TRUE;
+ break;
+ default :
+ break;
+ }
+
+ //
+ // Go to the next Op-Code
+ //
+ Offset += IfrOpHdr->Length;
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);
+ }
+
+ //
+ // Update the package length.
+ //
+ PackageHeader.Length = *TempBufferSize;
+ EfiCopyMem (*TempBuffer, &PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));
+
+Fail:
+ if (!Updated) {
+ gBS->FreePool (*TempBuffer);
+ *TempBufferSize = 0;
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+IfrLibUpdateForm (
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_GUID *FormSetGuid, OPTIONAL
+ IN EFI_FORM_ID FormId,
+ IN UINT16 Label,
+ IN BOOLEAN Insert,
+ IN EFI_HII_UPDATE_DATA *Data
+ )
+/*++
+
+Routine Description:
+ This function allows the caller to update a form that has
+ previously been registered with the EFI HII database.
+
+Arguments:
+ Handle - Hii Handle
+ FormSetGuid - The formset should be updated.
+ FormId - The form should be updated.
+ Label - Update information starting immediately after this label in the IFR
+ Insert - If TRUE and Data is not NULL, insert data after Label.
+ If FALSE, replace opcodes between two labels with Data
+ Data - The adding data; If NULL, remove opcodes between two Label.
+
+Returns:
+ EFI_SUCCESS - Update success.
+ Other - Update fail.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
+ UINT32 Index;
+ EFI_HII_PACKAGE_LIST_HEADER *UpdateBuffer;
+ UINTN BufferSize;
+ UINT8 *UpdateBufferPos;
+ EFI_HII_PACKAGE_HEADER PackageHeader;
+ EFI_HII_PACKAGE_HEADER *Package;
+ UINT32 PackageLength;
+ EFI_HII_PACKAGE_HEADER *TempBuffer;
+ UINT32 TempBufferSize;
+ BOOLEAN Updated;
+
+ if (Data == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ LocateHiiProtocols ();
+ HiiDatabase = gIfrLibHiiDatabase;
+
+ //
+ // Get the orginal package list
+ //
+ BufferSize = 0;
+ HiiPackageList = NULL;
+ Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ HiiPackageList = EfiLibAllocatePool (BufferSize);
+ ASSERT (HiiPackageList != NULL);
+
+ Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (HiiPackageList);
+ return Status;
+ }
+ }
+
+ //
+ // Calculate and allocate space for retrieval of IFR data
+ //
+ BufferSize += Data->Offset;
+ UpdateBuffer = EfiLibAllocateZeroPool (BufferSize);
+ if (UpdateBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ UpdateBufferPos = (UINT8 *) UpdateBuffer;
+
+ //
+ // copy the package list header
+ //
+ EfiCopyMem (UpdateBufferPos, HiiPackageList, sizeof (EFI_HII_PACKAGE_LIST_HEADER));
+ UpdateBufferPos += sizeof (EFI_HII_PACKAGE_LIST_HEADER);
+
+ Updated = FALSE;
+ for (Index = 0; ; Index++) {
+ Status = GetPackageDataFromPackageList (HiiPackageList, Index, &PackageLength, &Package);
+ if (Status == EFI_SUCCESS) {
+ EfiCopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
+ if ((PackageHeader.Type == EFI_HII_PACKAGE_FORM) && !Updated) {
+ Status = UpdateFormPackageData (FormSetGuid, FormId, Package, PackageLength, Label, Insert, Data, (UINT8 **)&TempBuffer, &TempBufferSize);
+ if (!EFI_ERROR(Status)) {
+ if (FormSetGuid == NULL) {
+ Updated = TRUE;
+ }
+ EfiCopyMem (UpdateBufferPos, TempBuffer, TempBufferSize);
+ UpdateBufferPos += TempBufferSize;
+ gBS->FreePool (TempBuffer);
+ continue;
+ }
+ }
+
+ EfiCopyMem (UpdateBufferPos, Package, PackageLength);
+ UpdateBufferPos += PackageLength;
+ } else if (Status == EFI_NOT_FOUND) {
+ break;
+ } else {
+ gBS->FreePool (HiiPackageList);
+ return Status;
+ }
+ }
+
+ //
+ // Update package list length
+ //
+ BufferSize = UpdateBufferPos - (UINT8 *) UpdateBuffer;
+ EfiCopyMem (&UpdateBuffer->PackageLength, &BufferSize, sizeof (UINT32));
+
+ gBS->FreePool (HiiPackageList);
+
+ return HiiDatabase->UpdatePackageList (HiiDatabase, Handle, UpdateBuffer);
+}
+
+EFI_STATUS
+IfrLibCreatePopUp (
+ IN UINTN NumberOfLines,
+ OUT EFI_INPUT_KEY *KeyValue,
+ IN CHAR16 *String,
+ ...
+ )
+/*++
+
+Routine Description:
+ Draw a dialog and return the selected key.
+
+Arguments:
+ NumberOfLines - The number of lines for the dialog box
+ KeyValue - The EFI_KEY value returned if HotKey is TRUE..
+ String - Pointer to the first string in the list
+ ... - A series of (quantity == NumberOfLines) text strings which
+ will be used to construct the dialog box
+
+Returns:
+ EFI_SUCCESS - Displayed dialog and received user interaction
+ EFI_INVALID_PARAMETER - One of the parameters was invalid.
+
+--*/
+{
+ UINTN Index;
+ UINTN Count;
+ UINTN Start;
+ UINTN End;
+ UINTN Top;
+ UINTN Bottom;
+ CHAR16 *StringPtr;
+ UINTN LeftColumn;
+ UINTN RightColumn;
+ UINTN TopRow;
+ UINTN BottomRow;
+ UINTN DimensionsWidth;
+ UINTN DimensionsHeight;
+ VA_LIST Marker;
+ EFI_INPUT_KEY Key;
+ UINTN LargestString;
+ CHAR16 *StackString;
+ EFI_STATUS Status;
+ UINTN StringLen;
+ CHAR16 *LineBuffer;
+ CHAR16 **StringArray;
+ EFI_EVENT TimerEvent;
+ EFI_EVENT WaitList[2];
+ UINTN CurrentAttribute;
+ EFI_SIMPLE_TEXT_OUT_PROTOCOL *ConOut;
+
+ if ((KeyValue == NULL) || (String == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TopRow = 0;
+ BottomRow = 0;
+ LeftColumn = 0;
+ RightColumn = 0;
+
+ ConOut = gST->ConOut;
+ ConOut->QueryMode (ConOut, ConOut->Mode->Mode, &RightColumn, &BottomRow);
+
+ DimensionsWidth = RightColumn - LeftColumn;
+ DimensionsHeight = BottomRow - TopRow;
+
+ CurrentAttribute = ConOut->Mode->Attribute;
+
+ LineBuffer = EfiLibAllocateZeroPool (DimensionsWidth * sizeof (CHAR16));
+ ASSERT (LineBuffer != NULL);
+
+ //
+ // Determine the largest string in the dialog box
+ // Notice we are starting with 1 since String is the first string
+ //
+ StringArray = EfiLibAllocateZeroPool (NumberOfLines * sizeof (CHAR16 *));
+ LargestString = EfiStrLen (String);
+ StringArray[0] = String;
+
+ VA_START (Marker, String);
+ for (Index = 1; Index < NumberOfLines; Index++) {
+ StackString = VA_ARG (Marker, CHAR16 *);
+
+ if (StackString == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ StringArray[Index] = StackString;
+ StringLen = EfiStrLen (StackString);
+ if (StringLen > LargestString) {
+ LargestString = StringLen;
+ }
+ }
+
+ if ((LargestString + 2) > DimensionsWidth) {
+ LargestString = DimensionsWidth - 2;
+ }
+
+ //
+ // Subtract the PopUp width from total Columns, allow for one space extra on
+ // each end plus a border.
+ //
+ Start = (DimensionsWidth - LargestString - 2) / 2 + LeftColumn + 1;
+ End = Start + LargestString + 1;
+
+ Top = ((DimensionsHeight - NumberOfLines - 2) / 2) + TopRow - 1;
+ Bottom = Top + NumberOfLines + 2;
+
+ //
+ // Disable cursor
+ //
+ ConOut->EnableCursor (ConOut, FALSE);
+ ConOut->SetAttribute (ConOut, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
+
+ StringPtr = &LineBuffer[0];
+ *StringPtr++ = BOXDRAW_DOWN_RIGHT;
+ for (Index = 0; Index < LargestString; Index++) {
+ *StringPtr++ = BOXDRAW_HORIZONTAL;
+ }
+ *StringPtr++ = BOXDRAW_DOWN_LEFT;
+ *StringPtr = L'\0';
+
+ ConOut->SetCursorPosition (ConOut, Start, Top);
+ ConOut->OutputString (ConOut, LineBuffer);
+
+ for (Index = 0; Index < NumberOfLines; Index++) {
+ StringPtr = &LineBuffer[0];
+ *StringPtr++ = BOXDRAW_VERTICAL;
+
+ for (Count = 0; Count < LargestString; Count++) {
+ StringPtr[Count] = L' ';
+ }
+
+ StringLen = EfiStrLen (StringArray[Index]);
+ if (StringLen > LargestString) {
+ StringLen = LargestString;
+ }
+ EfiCopyMem (
+ StringPtr + ((LargestString - StringLen) / 2),
+ StringArray[Index],
+ StringLen * sizeof (CHAR16)
+ );
+ StringPtr += LargestString;
+
+ *StringPtr++ = BOXDRAW_VERTICAL;
+ *StringPtr = L'\0';
+
+ ConOut->SetCursorPosition (ConOut, Start, Top + 1 + Index);
+ ConOut->OutputString (ConOut, LineBuffer);
+ }
+
+ StringPtr = &LineBuffer[0];
+ *StringPtr++ = BOXDRAW_UP_RIGHT;
+ for (Index = 0; Index < LargestString; Index++) {
+ *StringPtr++ = BOXDRAW_HORIZONTAL;
+ }
+ *StringPtr++ = BOXDRAW_UP_LEFT;
+ *StringPtr = L'\0';
+
+ ConOut->SetCursorPosition (ConOut, Start, Top + NumberOfLines + 1);
+ ConOut->OutputString (ConOut, LineBuffer);
+
+ do {
+ Status = gBS->CreateEvent (EFI_EVENT_TIMER, 0, NULL, NULL, &TimerEvent);
+
+ //
+ // Set a timer event of 1 second expiration
+ //
+ gBS->SetTimer (
+ TimerEvent,
+ TimerRelative,
+ 10000000
+ );
+
+ //
+ // Wait for the keystroke event or the timer
+ //
+ WaitList[0] = gST->ConIn->WaitForKey;
+ WaitList[1] = TimerEvent;
+ Status = gBS->WaitForEvent (2, WaitList, &Index);
+
+ //
+ // Check for the timer expiration
+ //
+ if (!EFI_ERROR (Status) && Index == 1) {
+ Status = EFI_TIMEOUT;
+ }
+
+ gBS->CloseEvent (TimerEvent);
+ } while (Status == EFI_TIMEOUT);
+
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+ EfiCopyMem (KeyValue, &Key, sizeof (EFI_INPUT_KEY));
+
+ ConOut->SetAttribute (ConOut, CurrentAttribute);
+ ConOut->EnableCursor (ConOut, TRUE);
+
+ return Status;
+}
+
+EFI_STATUS
+ExtractDefault(
+ IN VOID *Buffer,
+ IN UINTN *BufferSize,
+ UINTN Number,
+ ...
+ )
+/*++
+
+ Routine Description:
+
+ Configure the buffer accrording to ConfigBody strings.
+
+ Arguments:
+ DefaultId - the ID of default.
+ Buffer - the start address of buffer.
+ BufferSize - the size of buffer.
+ Number - the number of the strings.
+
+ Returns:
+ EFI_BUFFER_TOO_SMALL - the BufferSize is too small to operate.
+ EFI_INVALID_PARAMETER - Buffer is NULL or BufferSize is 0.
+ EFI_SUCCESS - Operation successful.
+
+--*/
+{
+ VA_LIST Args;
+ UINTN Index;
+ UINT32 TotalLen;
+ UINT8 *BufCfgArray;
+ UINT8 *BufferPos;
+ UINT16 Offset;
+ UINT16 Width;
+ UINT8 *Value;
+
+ if ((Buffer == NULL) || (BufferSize == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Offset = 0;
+ Width = 0;
+ Value = NULL;
+
+ VA_START (Args, Number);
+ for (Index = 0; Index < Number; Index++) {
+ BufCfgArray = (UINT8 *) VA_ARG (Args, VOID *);
+ EfiCopyMem (&TotalLen, BufCfgArray, sizeof (UINT32));
+ BufferPos = BufCfgArray + sizeof (UINT32);
+
+ while ((UINT32)(BufferPos - BufCfgArray) < TotalLen) {
+ EfiCopyMem (&Offset, BufferPos, sizeof (UINT16));
+ BufferPos += sizeof (UINT16);
+ EfiCopyMem (&Width, BufferPos, sizeof (UINT16));
+ BufferPos += sizeof (UINT16);
+ Value = BufferPos;
+ BufferPos += Width;
+
+ if ((UINTN)(Offset + Width) > *BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ EfiCopyMem ((UINT8 *)Buffer + Offset, Value, Width);
+ }
+ }
+ VA_END (Args);
+
+ *BufferSize = (UINTN)Offset;
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+SwapBuffer (
+ IN OUT UINT8 *Buffer,
+ IN UINTN BufferSize
+ )
+/*++
+
+Routine Description:
+ Swap bytes in the buffer.
+
+Arguments:
+ Buffer - Binary buffer.
+ BufferSize - Size of the buffer in bytes.
+
+Returns:
+ None.
+
+--*/
+{
+ UINTN Index;
+ UINT8 Temp;
+ UINTN SwapCount;
+
+ SwapCount = (BufferSize - 1) / 2;
+ for (Index = 0; Index < SwapCount; Index++) {
+ Temp = Buffer[Index];
+ Buffer[Index] = Buffer[BufferSize - 1 - Index];
+ Buffer[BufferSize - 1 - Index] = Temp;
+ }
+}
+
+EFI_STATUS
+BufferToHexString (
+ IN OUT CHAR16 *Str,
+ IN UINT8 *Buffer,
+ IN UINTN BufferSize
+ )
+/*++
+
+Routine Description:
+ Converts binary buffer to Unicode string in reversed byte order from BufToHexString().
+
+Arguments:
+ Str - String for output
+ Buffer - Binary buffer.
+ BufferSize - Size of the buffer in bytes.
+
+Returns:
+ EFI_SUCCESS - The function completed successfully.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT8 *NewBuffer;
+ UINTN StrBufferLen;
+
+ NewBuffer = EfiLibAllocateCopyPool (BufferSize, Buffer);
+ SwapBuffer (NewBuffer, BufferSize);
+
+ StrBufferLen = (BufferSize + 1) * sizeof (CHAR16);
+ Status = BufToHexString (Str, &StrBufferLen, NewBuffer, BufferSize);
+
+ gBS->FreePool (NewBuffer);
+
+ return Status;
+}
+
+EFI_STATUS
+HexStringToBuffer (
+ IN OUT UINT8 *Buffer,
+ IN OUT UINTN *BufferSize,
+ IN CHAR16 *Str
+ )
+/*++
+
+Routine Description:
+ Converts Hex String to binary buffer in reversed byte order from HexStringToBuf().
+
+Arguments:
+ Buffer - Pointer to buffer that receives the data.
+ BufferSize - Length in bytes of the buffer to hold converted data.
+ If routine return with EFI_SUCCESS, containing length of converted data.
+ If routine return with EFI_BUFFER_TOO_SMALL, containg length of buffer desired.
+ Str - String to be converted from.
+
+Returns:
+ EFI_SUCCESS - The function completed successfully.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN ConvertedStrLen;
+
+ ConvertedStrLen = 0;
+ Status = HexStringToBuf (Buffer, BufferSize, Str, &ConvertedStrLen);
+ if (!EFI_ERROR (Status)) {
+ SwapBuffer (Buffer, ConvertedStrLen);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+ConstructConfigHdr (
+ IN OUT CHAR16 *ConfigHdr,
+ IN OUT UINTN *StrBufferLen,
+ IN EFI_GUID *Guid,
+ IN CHAR16 *Name, OPTIONAL
+ IN EFI_HANDLE *DriverHandle
+ )
+/*++
+
+Routine Description:
+ Construct <ConfigHdr> using routing information GUID/NAME/PATH.
+
+Arguments:
+ ConfigHdr - Pointer to the ConfigHdr string.
+ StrBufferLen - On input: Length in bytes of buffer to hold the ConfigHdr string.
+ Includes tailing '\0' character.
+ On output:
+ If return EFI_SUCCESS, containing length of ConfigHdr string buffer.
+ If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
+ Guid - Routing information: GUID.
+ Name - Routing information: NAME.
+ DriverHandle - Driver handle which contains the routing information: PATH.
+
+Returns:
+ EFI_SUCCESS - Routine success.
+ EFI_BUFFER_TOO_SMALL - The ConfigHdr string buffer is too small.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN NameStrLen;
+ UINTN DevicePathSize;
+ UINTN BufferSize;
+ CHAR16 *StrPtr;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if (Name == NULL) {
+ //
+ // There will be no "NAME" in <ConfigHdr> for Name/Value storage
+ //
+ NameStrLen = 0;
+ } else {
+ //
+ // For buffer storage
+ //
+ NameStrLen = EfiStrLen (Name);
+ }
+
+ //
+ // Retrieve DevicePath Protocol associated with this HiiPackageList
+ //
+ Status = gBS->HandleProtocol (
+ DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DevicePathSize = EfiDevicePathSize (DevicePath);
+
+ //
+ // GUID=<HexCh>32&NAME=<Alpha>NameStrLen&PATH=<HexChar>DevicePathStrLen <NULL>
+ // | 5 | 32 | 6 | NameStrLen | 6 | DevicePathStrLen |
+ //
+ BufferSize = (5 + 32 + 6 + NameStrLen + 6 + DevicePathSize * 2 + 1) * sizeof (CHAR16);
+ if (*StrBufferLen < BufferSize) {
+ *StrBufferLen = BufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *StrBufferLen = BufferSize;
+
+ StrPtr = ConfigHdr;
+
+ EfiStrCpy (StrPtr, L"GUID=");
+ StrPtr += 5;
+ BufferToHexString (StrPtr, (UINT8 *) Guid, sizeof (EFI_GUID));
+ StrPtr += 32;
+
+ EfiStrCpy (StrPtr, L"&NAME=");
+ StrPtr += 6;
+ if (Name != NULL) {
+ EfiStrCpy (StrPtr, Name);
+ StrPtr += NameStrLen;
+ }
+
+ EfiStrCpy (StrPtr, L"&PATH=");
+ StrPtr += 6;
+ BufferToHexString (StrPtr, (UINT8 *) DevicePath, DevicePathSize);
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+FindBlockName (
+ IN OUT CHAR16 *String,
+ UINTN Offset,
+ UINTN Width
+ )
+/*++
+
+Routine Description:
+ Search BlockName "&OFFSET=Offset&WIDTH=Width" in a string.
+
+Arguments:
+ String - The string to be searched in.
+ Offset - Offset in BlockName.
+ Width - Width in BlockName.
+
+Returns:
+ TRUE - Block name found.
+ FALSE - Block name not found.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Data;
+ UINTN BufferSize;
+ UINTN ConvertedStrLen;
+
+ while ((String = EfiStrStr (String, L"&OFFSET=")) != NULL) {
+ //
+ // Skip '&OFFSET='
+ //
+ String = String + 8;
+
+ Data = 0;
+ BufferSize = sizeof (UINTN);
+ Status = HexStringToBuf ((UINT8 *) &Data, &BufferSize, String, &ConvertedStrLen);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ String = String + ConvertedStrLen;
+
+ if (Data != Offset) {
+ continue;
+ }
+
+ if (EfiStrnCmp (String, L"&WIDTH=", 7) != 0) {
+ return FALSE;
+ }
+ String = String + 7;
+
+ Data = 0;
+ BufferSize = sizeof (UINTN);
+ Status = HexStringToBuf ((UINT8 *) &Data, &BufferSize, String, &ConvertedStrLen);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ if (Data == Width) {
+ return TRUE;
+ }
+
+ String = String + ConvertedStrLen;
+ }
+
+ return FALSE;
+}
+
+EFI_STATUS
+GetBrowserData (
+ EFI_GUID *VariableGuid, OPTIONAL
+ CHAR16 *VariableName, OPTIONAL
+ UINTN *BufferSize,
+ UINT8 *Buffer
+ )
+/*++
+
+Routine Description:
+ This routine is invoked by ConfigAccess.Callback() to retrived uncommitted data from Form Browser.
+
+Arguments:
+ VariableGuid - An optional field to indicate the target variable GUID name to use.
+ VariableName - An optional field to indicate the target human-readable variable name.
+ BufferSize - On input: Length in bytes of buffer to hold retrived data.
+ On output:
+ If return EFI_BUFFER_TOO_SMALL, containg length of buffer desired.
+ Buffer - Buffer to hold retrived data.
+
+Returns:
+ EFI_SUCCESS - Routine success.
+ EFI_BUFFER_TOO_SMALL - The intput buffer is too small.
+
+--*/
+{
+ EFI_STATUS Status;
+ CHAR16 *ConfigHdr;
+ CHAR16 *ConfigResp;
+ CHAR16 *StringPtr;
+ UINTN HeaderLen;
+ UINTN BufferLen;
+ CHAR16 *Progress;
+ EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+ //
+ // Locate protocols for use
+ //
+ Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, &FormBrowser2);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, &HiiConfigRouting);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrive formset storage data from Form Browser
+ //
+ ConfigHdr = mFakeConfigHdr;
+ HeaderLen = EfiStrLen (ConfigHdr);
+
+ BufferLen = 0x4000;
+ ConfigResp = EfiLibAllocateZeroPool (BufferLen + HeaderLen);
+
+ StringPtr = ConfigResp + HeaderLen;
+ *StringPtr = L'&';
+ StringPtr++;
+
+ Status = FormBrowser2->BrowserCallback (
+ FormBrowser2,
+ &BufferLen,
+ StringPtr,
+ TRUE,
+ VariableGuid,
+ VariableName
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ gBS->FreePool (ConfigResp);
+ ConfigResp = EfiLibAllocateZeroPool (BufferLen + HeaderLen);
+
+ StringPtr = ConfigResp + HeaderLen;
+ *StringPtr = L'&';
+ StringPtr++;
+
+ Status = FormBrowser2->BrowserCallback (
+ FormBrowser2,
+ &BufferLen,
+ StringPtr,
+ TRUE,
+ VariableGuid,
+ VariableName
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (ConfigResp);
+ return Status;
+ }
+ EfiCopyMem (ConfigResp, ConfigHdr, HeaderLen * sizeof (UINT16));
+
+ //
+ // Convert <ConfigResp> to buffer data
+ //
+ Status = HiiConfigRouting->ConfigToBlock (
+ HiiConfigRouting,
+ ConfigResp,
+ Buffer,
+ BufferSize,
+ &Progress
+ );
+ gBS->FreePool (ConfigResp);
+
+ return Status;
+}
+
+EFI_STATUS
+SetBrowserData (
+ EFI_GUID *VariableGuid, OPTIONAL
+ CHAR16 *VariableName, OPTIONAL
+ UINTN BufferSize,
+ UINT8 *Buffer,
+ CHAR16 *RequestElement OPTIONAL
+ )
+/*++
+
+Routine Description:
+ This routine is invoked by ConfigAccess.Callback() to update uncommitted data of Form Browser.
+
+Arguments:
+ VariableGuid - An optional field to indicate the target variable GUID name to use.
+ VariableName - An optional field to indicate the target human-readable variable name.
+ BufferSize - Length in bytes of buffer to hold retrived data.
+ Buffer - Buffer to hold retrived data.
+ RequestElement - An optional field to specify which part of the buffer data
+ will be send back to Browser. If NULL, the whole buffer of
+ data will be committed to Browser.
+ <RequestElement> ::= &OFFSET=<Number>&WIDTH=<Number>*
+
+Returns:
+ EFI_SUCCESS - Routine success.
+ Other - Updating Browser uncommitted data failed.
+
+--*/
+{
+ EFI_STATUS Status;
+ CHAR16 *ConfigHdr;
+ CHAR16 *ConfigResp;
+ CHAR16 *StringPtr;
+ UINTN HeaderLen;
+ UINTN BufferLen;
+ CHAR16 *Progress;
+ EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+ CHAR16 BlockName[33];
+ CHAR16 *ConfigRequest;
+ CHAR16 *Request;
+
+ //
+ // Locate protocols for use
+ //
+ Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, &FormBrowser2);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, &HiiConfigRouting);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Prepare <ConfigRequest>
+ //
+ ConfigHdr = mFakeConfigHdr;
+ HeaderLen = EfiStrLen (ConfigHdr);
+
+ if (RequestElement == NULL) {
+ //
+ // RequestElement not specified, use "&OFFSET=0&WIDTH=<BufferSize>" as <BlockName>
+ //
+ BlockName[0] = L'\0';
+ EfiStrCpy (BlockName, L"&OFFSET=0&WIDTH=");
+
+ //
+ // String lenghth of L"&OFFSET=0&WIDTH=" is 16
+ //
+ StringPtr = BlockName + 16;
+ BufferLen = sizeof (BlockName) - (16 * sizeof (CHAR16));
+ BufToHexString (StringPtr, &BufferLen, (UINT8 *) &BufferSize, sizeof (UINTN));
+
+ Request = BlockName;
+ } else {
+ Request = RequestElement;
+ }
+
+ BufferLen = HeaderLen * sizeof (CHAR16) + EfiStrSize (Request);
+ ConfigRequest = EfiLibAllocateZeroPool (BufferLen);
+
+ EfiCopyMem (ConfigRequest, ConfigHdr, HeaderLen * sizeof (CHAR16));
+ StringPtr = ConfigRequest + HeaderLen;
+ EfiStrCpy (StringPtr, Request);
+
+ //
+ // Convert buffer to <ConfigResp>
+ //
+ Status = HiiConfigRouting->BlockToConfig (
+ HiiConfigRouting,
+ ConfigRequest,
+ Buffer,
+ BufferSize,
+ &ConfigResp,
+ &Progress
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (ConfigResp);
+ return Status;
+ }
+
+ //
+ // Skip <ConfigHdr> and '&'
+ //
+ StringPtr = ConfigResp + HeaderLen + 1;
+
+ //
+ // Change uncommitted data in Browser
+ //
+ Status = FormBrowser2->BrowserCallback (
+ FormBrowser2,
+ &BufferSize,
+ StringPtr,
+ FALSE,
+ NULL,
+ NULL
+ );
+ gBS->FreePool (ConfigResp);
+ return Status;
+}
diff --git a/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrLibrary.h b/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrLibrary.h
new file mode 100644
index 0000000000..9c65215724
--- /dev/null
+++ b/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrLibrary.h
@@ -0,0 +1,1127 @@
+/*++
+
+Copyright (c) 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ UefiIfrLibrary.h
+
+Abstract:
+
+ The file contain all library function for Ifr Operations.
+
+--*/
+
+#ifndef _IFRLIBRARY_H
+#define _IFRLIBRARY_H
+
+#include "Tiano.h"
+#include "EfiDriverLib.h"
+#include "TianoHii.h"
+
+#include EFI_PROTOCOL_DEFINITION (HiiFont)
+#include EFI_PROTOCOL_DEFINITION (HiiImage)
+#include EFI_PROTOCOL_DEFINITION (HiiString)
+#include EFI_PROTOCOL_DEFINITION (HiiDatabase)
+#include EFI_PROTOCOL_DEFINITION (HiiConfigRouting)
+#include EFI_PROTOCOL_DEFINITION (HiiConfigAccess)
+#include EFI_PROTOCOL_DEFINITION (FormBrowser2)
+#include EFI_PROTOCOL_DEFINITION (SimpleTextOut)
+
+#include EFI_GUID_DEFINITION (GlobalVariable)
+
+#define IFR_LIB_DEFAULT_STRING_SIZE 0x200
+
+//
+// The architectural variable "Lang" and "LangCodes" are deprecated in UEFI
+// specification. While, UEFI specification also states that these deprecated
+// variables may be provided for backwards compatibility.
+// If "LANG_SUPPORT" is defined, "Lang" and "LangCodes" will be produced;
+// If "LANG_SUPPORT" is undefined, "Lang" and "LangCodes" will not be produced.
+//
+#define LANG_SUPPORT
+
+#define EFI_LANGUAGE_VARIABLE L"Lang"
+#define EFI_LANGUAGE_CODES_VARIABLE L"LangCodes"
+
+#define UEFI_LANGUAGE_VARIABLE L"PlatformLang"
+#define UEFI_LANGUAGE_CODES_VARIABLE L"PlatformLangCodes"
+
+//
+// Limited buffer size recommended by RFC4646 (4.3. Length Considerations)
+// (42 characters plus a NULL terminator)
+//
+#define RFC_3066_ENTRY_SIZE (42 + 1)
+#define ISO_639_2_ENTRY_SIZE 3
+
+#define INVALID_VARSTORE_ID 0
+
+#define QUESTION_FLAGS (EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY)
+#define QUESTION_FLAGS_MASK (~QUESTION_FLAGS)
+
+extern EFI_GUID mIfrVendorGuid;
+extern EFI_HII_DATABASE_PROTOCOL *gIfrLibHiiDatabase;
+extern EFI_HII_STRING_PROTOCOL *gIfrLibHiiString;
+
+#pragma pack(1)
+typedef struct {
+ EFI_STRING_ID StringToken;
+ EFI_IFR_TYPE_VALUE Value;
+ UINT8 Flags;
+} IFR_OPTION;
+#pragma pack()
+
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ UINT32 MonotonicCount;
+} HII_VENDOR_DEVICE_PATH_NODE;
+
+typedef struct {
+ HII_VENDOR_DEVICE_PATH_NODE Node;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+typedef struct {
+ //
+ // Buffer size allocated for Data.
+ //
+ UINT32 BufferSize;
+
+ //
+ // Offset in Data to append the newly created opcode binary.
+ // It will be adjusted automatically in Create***OpCode(), and should be
+ // initialized to 0 before invocation of a serial of Create***OpCode()
+ //
+ UINT32 Offset;
+
+ //
+ // The destination buffer for created op-codes
+ //
+ UINT8 *Data;
+} EFI_HII_UPDATE_DATA;
+
+VOID
+LocateHiiProtocols (
+ VOID
+ )
+/*++
+
+Routine Description:
+ This function locate Hii relative protocols for later usage.
+
+Arguments:
+ None.
+
+Returns:
+ None.
+
+--*/
+;
+
+//
+// Exported Library functions
+//
+EFI_STATUS
+CreateEndOpCode (
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+/*++
+
+Routine Description:
+ Create EFI_IFR_END_OP opcode.
+
+Arguments:
+ Data - Destination for the created opcode binary
+
+Returns:
+ EFI_SUCCESS - Opcode create success
+
+--*/
+;
+
+EFI_STATUS
+CreateDefaultOpCode (
+ IN EFI_IFR_TYPE_VALUE *Value,
+ IN UINT8 Type,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+/*++
+
+Routine Description:
+ Create EFI_IFR_DEFAULT_OP opcode.
+
+Arguments:
+ Value - Value for the default
+ Type - Type for the default
+ Data - Destination for the created opcode binary
+
+Returns:
+ EFI_SUCCESS - Opcode create success
+
+--*/
+;
+
+EFI_STATUS
+CreateActionOpCode (
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN EFI_STRING_ID QuestionConfig,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+/*++
+
+Routine Description:
+ Create EFI_IFR_ACTION_OP opcode.
+
+Arguments:
+ QuestionId - Question ID
+ Prompt - String ID for Prompt
+ Help - String ID for Help
+ QuestionFlags - Flags in Question Header
+ QuestionConfig - String ID for configuration
+ Data - Destination for the created opcode binary
+
+Returns:
+ EFI_SUCCESS - Opcode create success
+
+--*/
+;
+
+EFI_STATUS
+CreateSubTitleOpCode (
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 Flags,
+ IN UINT8 Scope,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+/*++
+
+Routine Description:
+ Create EFI_IFR_SUBTITLE_OP opcode.
+
+Arguments:
+ Prompt - String ID for Prompt
+ Help - String ID for Help
+ Flags - Subtitle opcode flags
+ Scope - Subtitle Scope bit
+ Data - Destination for the created opcode binary
+
+Returns:
+ EFI_SUCCESS - Opcode create success
+
+--*/
+;
+
+EFI_STATUS
+CreateTextOpCode (
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN EFI_STRING_ID TextTwo,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+/*++
+
+Routine Description:
+ Create EFI_IFR_TEXT_OP opcode.
+
+Arguments:
+ Prompt - String ID for Prompt
+ Help - String ID for Help
+ TextTwo - String ID for text two
+ Data - Destination for the created opcode binary
+
+Returns:
+ EFI_SUCCESS - Opcode create success
+
+--*/
+;
+
+EFI_STATUS
+CreateGotoOpCode (
+ IN EFI_FORM_ID FormId,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN EFI_QUESTION_ID QuestionId,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+/*++
+
+Routine Description:
+ Create EFI_IFR_REF_OP opcode.
+
+Arguments:
+ FormId - Destination Form ID
+ Prompt - String ID for Prompt
+ Help - String ID for Help
+ QuestionFlags - Flags in Question Header
+ QuestionId - Question ID
+ Data - Destination for the created opcode binary
+
+Returns:
+ EFI_SUCCESS - Opcode create success
+
+--*/
+;
+
+EFI_STATUS
+CreateOneOfOptionOpCode (
+ IN UINTN OptionCount,
+ IN IFR_OPTION *OptionsList,
+ IN UINT8 Type,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+;
+
+EFI_STATUS
+CreateOneOfOpCode (
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN UINT16 VarOffset,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN UINT8 OneOfFlags,
+ IN IFR_OPTION *OptionsList,
+ IN UINTN OptionCount,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+/*++
+
+Routine Description:
+ Create EFI_IFR_ONE_OF_OP opcode.
+
+Arguments:
+ QuestionId - Question ID
+ VarStoreId - Storage ID
+ VarOffset - Offset in Storage
+ Prompt - String ID for Prompt
+ Help - String ID for Help
+ QuestionFlags - Flags in Question Header
+ OneOfFlags - Flags for oneof opcode
+ OptionsList - List of options
+ OptionCount - Number of options in option list
+ Data - Destination for the created opcode binary
+
+Returns:
+ EFI_SUCCESS - Opcode create success
+
+--*/
+;
+
+EFI_STATUS
+CreateOrderedListOpCode (
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN UINT16 VarOffset,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN UINT8 Flags,
+ IN UINT8 DataType,
+ IN UINT8 MaxContainers,
+ IN IFR_OPTION *OptionsList,
+ IN UINTN OptionCount,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+/*++
+
+Routine Description:
+ Create EFI_IFR_ORDERED_LIST_OP opcode.
+
+Arguments:
+ QuestionId - Question ID
+ VarStoreId - Storage ID
+ VarOffset - Offset in Storage
+ Prompt - String ID for Prompt
+ Help - String ID for Help
+ QuestionFlags - Flags in Question Header
+ Flags - Flags for ordered list opcode
+ DataType - Type for option value
+ MaxContainers - Maximum count for options in this ordered list
+ OptionsList - List of options
+ OptionCount - Number of options in option list
+ Data - Destination for the created opcode binary
+
+Returns:
+ EFI_SUCCESS - Opcode create success
+
+--*/
+;
+
+EFI_STATUS
+CreateCheckBoxOpCode (
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN UINT16 VarOffset,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN UINT8 CheckBoxFlags,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+/*++
+
+Routine Description:
+ Create EFI_IFR_CHECKBOX_OP opcode.
+
+Arguments:
+ QuestionId - Question ID
+ VarStoreId - Storage ID
+ VarOffset - Offset in Storage
+ Prompt - String ID for Prompt
+ Help - String ID for Help
+ QuestionFlags - Flags in Question Header
+ CheckBoxFlags - Flags for checkbox opcode
+ Data - Destination for the created opcode binary
+
+Returns:
+ EFI_SUCCESS - Opcode create success
+
+--*/
+;
+
+EFI_STATUS
+CreateNumericOpCode (
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN UINT16 VarOffset,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN UINT8 NumericFlags,
+ IN UINT64 Minimum,
+ IN UINT64 Maximum,
+ IN UINT64 Step,
+ IN UINT64 Default,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+/*++
+
+Routine Description:
+ Create EFI_IFR_NUMERIC_OP opcode.
+
+Arguments:
+ QuestionId - Question ID
+ VarStoreId - Storage ID
+ VarOffset - Offset in Storage
+ Prompt - String ID for Prompt
+ Help - String ID for Help
+ QuestionFlags - Flags in Question Header
+ NumericFlags - Flags for numeric opcode
+ Minimum - Numeric minimum value
+ Maximum - Numeric maximum value
+ Step - Numeric step for edit
+ Default - Numeric default value
+ Data - Destination for the created opcode binary
+
+Returns:
+ EFI_SUCCESS - Opcode create success
+
+--*/
+;
+
+EFI_STATUS
+CreateStringOpCode (
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN UINT16 VarOffset,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN UINT8 StringFlags,
+ IN UINT8 MinSize,
+ IN UINT8 MaxSize,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+/*++
+
+Routine Description:
+ Create EFI_IFR_STRING_OP opcode.
+
+Arguments:
+ QuestionId - Question ID
+ VarStoreId - Storage ID
+ VarOffset - Offset in Storage
+ Prompt - String ID for Prompt
+ Help - String ID for Help
+ QuestionFlags - Flags in Question Header
+ StringFlags - Flags for string opcode
+ MinSize - String minimum length
+ MaxSize - String maximum length
+ Data - Destination for the created opcode binary
+
+Returns:
+ EFI_SUCCESS - Opcode create success
+
+--*/
+;
+
+EFI_STATUS
+CreateBannerOpCode (
+ IN EFI_STRING_ID Title,
+ IN UINT16 LineNumber,
+ IN UINT8 Alignment,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+/*++
+
+Routine Description:
+ Create GUIDed opcode for banner.
+
+Arguments:
+ Title - String ID for title
+ LineNumber - Line number for this banner
+ Alignment - Alignment for this banner, left, center or right
+ Data - Destination for the created opcode binary
+
+Returns:
+ EFI_SUCCESS - Opcode create success
+
+--*/
+;
+
+EFI_HII_PACKAGE_LIST_HEADER *
+PreparePackageList (
+ IN UINTN NumberOfPackages,
+ IN EFI_GUID *GuidId,
+ ...
+ )
+/*++
+
+Routine Description:
+ Assemble EFI_HII_PACKAGE_LIST according to the passed in packages.
+
+Arguments:
+ NumberOfPackages - Number of packages.
+ GuidId - Package GUID.
+
+Returns:
+ Pointer of EFI_HII_PACKAGE_LIST_HEADER.
+
+--*/
+;
+
+EFI_STATUS
+CreateHiiDriverHandle (
+ OUT EFI_HANDLE *DriverHandle
+ )
+/*++
+
+Routine Description:
+ The HII driver handle passed in for HiiDatabase.NewPackageList() requires
+ that there should be DevicePath Protocol installed on it.
+ This routine create a virtual Driver Handle by installing a vendor device
+ path on it, so as to use it to invoke HiiDatabase.NewPackageList().
+
+Arguments:
+ DriverHandle - Handle to be returned
+
+Returns:
+ EFI_SUCCESS - Handle destroy success.
+ EFI_OUT_OF_RESOURCES - Not enough memory.
+
+--*/
+;
+
+EFI_STATUS
+DestroyHiiDriverHandle (
+ IN EFI_HANDLE DriverHandle
+ )
+/*++
+
+Routine Description:
+ Destroy the Driver Handle created by CreateHiiDriverHandle().
+
+Arguments:
+ DriverHandle - Handle returned by CreateHiiDriverHandle()
+
+Returns:
+ EFI_SUCCESS - Handle destroy success.
+ other - Handle destroy fail.
+
+--*/
+;
+
+EFI_HII_HANDLE
+DevicePathToHiiHandle (
+ IN EFI_HII_DATABASE_PROTOCOL *HiiDatabase,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+Routine Description:
+ Find HII Handle associated with given Device Path.
+
+Arguments:
+ HiiDatabase - Point to EFI_HII_DATABASE_PROTOCOL instance.
+ DevicePath - Device Path associated with the HII package list handle.
+
+Returns:
+ Handle - HII package list Handle associated with the Device Path.
+ NULL - Hii Package list handle is not found.
+
+--*/
+;
+
+EFI_STATUS
+ExtractDefault(
+ IN VOID *Buffer,
+ IN UINTN *BufferSize,
+ UINTN Number,
+ ...
+ )
+/*++
+
+ Routine Description:
+ Configure the buffer accrording to ConfigBody strings.
+
+ Arguments:
+ DefaultId - the ID of default.
+ Buffer - the start address of buffer.
+ BufferSize - the size of buffer.
+ Number - the number of the strings.
+
+ Returns:
+ EFI_BUFFER_TOO_SMALL - the BufferSize is too small to operate.
+ EFI_INVALID_PARAMETER - Buffer is NULL or BufferSize is 0.
+ EFI_SUCCESS - Operation successful.
+
+--*/
+;
+
+EFI_STATUS
+ExtractGuidFromHiiHandle (
+ IN EFI_HII_HANDLE Handle,
+ OUT EFI_GUID *Guid
+ )
+/*++
+
+Routine Description:
+ Extract Hii package list GUID for given HII handle.
+
+Arguments:
+ HiiHandle - Hii handle
+ Guid - Package list GUID
+
+Returns:
+ EFI_SUCCESS - Successfully extract GUID from Hii database.
+
+--*/
+;
+
+EFI_STATUS
+ExtractClassFromHiiHandle (
+ IN EFI_HII_HANDLE Handle,
+ OUT UINT16 *Class,
+ OUT EFI_STRING_ID *FormSetTitle,
+ OUT EFI_STRING_ID *FormSetHelp
+ )
+/*++
+
+Routine Description:
+ Extract formset class for given HII handle.
+
+Arguments:
+ HiiHandle - Hii handle
+ Class - Class of the formset
+ FormSetTitle - Formset title string
+ FormSetHelp - Formset help string
+
+Returns:
+ EFI_SUCCESS - Successfully extract Class for specified Hii handle.
+
+--*/
+;
+
+EFI_STATUS
+BufferToHexString (
+ IN OUT CHAR16 *Str,
+ IN UINT8 *Buffer,
+ IN UINTN BufferSize
+ )
+/*++
+
+Routine Description:
+ Converts binary buffer to Unicode string in reversed byte order to BufToHexString().
+
+Arguments:
+ Str - String for output
+ Buffer - Binary buffer.
+ BufferSize - Size of the buffer in bytes.
+
+Returns:
+ EFI_SUCCESS - The function completed successfully.
+
+--*/
+;
+
+EFI_STATUS
+HexStringToBuffer (
+ IN OUT UINT8 *Buffer,
+ IN OUT UINTN *BufferSize,
+ IN CHAR16 *Str
+ )
+/*++
+
+Routine Description:
+ Converts Hex String to binary buffer in reversed byte order to HexStringToBuf().
+
+Arguments:
+ Buffer - Pointer to buffer that receives the data.
+ BufferSize - Length in bytes of the buffer to hold converted data.
+ If routine return with EFI_SUCCESS, containing length of converted data.
+ If routine return with EFI_BUFFER_TOO_SMALL, containg length of buffer desired.
+ Str - String to be converted from.
+
+Returns:
+ EFI_SUCCESS - The function completed successfully.
+
+--*/
+;
+
+EFI_STATUS
+ConstructConfigHdr (
+ IN OUT CHAR16 *ConfigHdr,
+ IN OUT UINTN *StrBufferLen,
+ IN EFI_GUID *Guid,
+ IN CHAR16 *Name, OPTIONAL
+ IN EFI_HANDLE *DriverHandle
+ )
+/*++
+
+Routine Description:
+ Construct <ConfigHdr> using routing information GUID/NAME/PATH.
+
+Arguments:
+ ConfigHdr - Pointer to the ConfigHdr string.
+ StrBufferLen - On input: Length in bytes of buffer to hold the ConfigHdr string. Includes tailing '\0' character.
+ On output:
+ If return EFI_SUCCESS, containing length of ConfigHdr string buffer.
+ If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
+ Guid - Routing information: GUID.
+ Name - Routing information: NAME.
+ DriverHandle - Driver handle which contains the routing information: PATH.
+
+Returns:
+ EFI_SUCCESS - Routine success.
+ EFI_BUFFER_TOO_SMALL - The ConfigHdr string buffer is too small.
+
+--*/
+;
+
+BOOLEAN
+FindBlockName (
+ IN OUT CHAR16 *String,
+ UINTN Offset,
+ UINTN Width
+ )
+/*++
+
+Routine Description:
+ Search BlockName "&OFFSET=Offset&WIDTH=Width" in a string.
+
+Arguments:
+ String - The string to be searched in.
+ Offset - Offset in BlockName.
+ Width - Width in BlockName.
+
+Returns:
+ TRUE - Block name found.
+ FALSE - Block name not found.
+
+--*/
+;
+
+EFI_STATUS
+GetBrowserData (
+ EFI_GUID *VariableGuid, OPTIONAL
+ CHAR16 *VariableName, OPTIONAL
+ UINTN *BufferSize,
+ UINT8 *Buffer
+ )
+/*++
+
+Routine Description:
+ This routine is invoked by ConfigAccess.Callback() to retrived uncommitted data from Form Browser.
+
+Arguments:
+ VariableGuid - An optional field to indicate the target variable GUID name to use.
+ VariableName - An optional field to indicate the target human-readable variable name.
+ BufferSize - On input: Length in bytes of buffer to hold retrived data.
+ On output:
+ If return EFI_BUFFER_TOO_SMALL, containg length of buffer desired.
+ Buffer - Buffer to hold retrived data.
+
+Returns:
+ EFI_SUCCESS - Routine success.
+ EFI_BUFFER_TOO_SMALL - The intput buffer is too small.
+
+--*/
+;
+
+EFI_STATUS
+GetHiiHandles (
+ IN OUT UINTN *HandleBufferLength,
+ OUT EFI_HII_HANDLE **HiiHandleBuffer
+ )
+/*++
+
+Routine Description:
+ Determines the handles that are currently active in the database.
+ It's the caller's responsibility to free handle buffer.
+
+Arguments:
+ HiiDatabase - A pointer to the EFI_HII_DATABASE_PROTOCOL instance.
+ HandleBufferLength - On input, a pointer to the length of the handle buffer. On output,
+ the length of the handle buffer that is required for the handles found.
+ HiiHandleBuffer - Pointer to an array of Hii Handles returned.
+
+Returns:
+ EFI_SUCCESS - Get an array of Hii Handles successfully.
+ EFI_INVALID_PARAMETER - Hii is NULL.
+ EFI_NOT_FOUND - Database not found.
+
+--*/
+;
+
+EFI_STATUS
+SetBrowserData (
+ EFI_GUID *VariableGuid, OPTIONAL
+ CHAR16 *VariableName, OPTIONAL
+ UINTN BufferSize,
+ UINT8 *Buffer,
+ CHAR16 *RequestElement OPTIONAL
+ )
+/*++
+
+Routine Description:
+ This routine is invoked by ConfigAccess.Callback() to update uncommitted data of Form Browser.
+
+Arguments:
+ VariableGuid - An optional field to indicate the target variable GUID name to use.
+ VariableName - An optional field to indicate the target human-readable variable name.
+ BufferSize - Length in bytes of buffer to hold retrived data.
+ Buffer - Buffer to hold retrived data.
+ RequestElement - An optional field to specify which part of the buffer data
+ will be send back to Browser. If NULL, the whole buffer of
+ data will be committed to Browser.
+ <RequestElement> ::= &OFFSET=<Number>&WIDTH=<Number>*
+
+Returns:
+ EFI_SUCCESS - Routine success.
+ Other - Updating Browser uncommitted data failed.
+
+--*/
+;
+
+EFI_STATUS
+ConvertRfc3066LanguageToIso639Language (
+ CHAR8 *LanguageRfc3066,
+ CHAR8 *LanguageIso639
+ )
+/*++
+
+Routine Description:
+ Convert language code from RFC3066 to ISO639-2.
+
+Arguments:
+ LanguageRfc3066 - RFC3066 language code.
+ LanguageIso639 - ISO639-2 language code.
+
+Returns:
+ EFI_SUCCESS - Language code converted.
+ EFI_NOT_FOUND - Language code not found.
+
+--*/
+;
+
+CHAR8 *
+Rfc3066ToIso639 (
+ CHAR8 *SupportedLanguages
+ )
+/*++
+
+Routine Description:
+ Convert language code list from RFC3066 to ISO639-2, e.g. "en-US;fr-FR" will
+ be converted to "engfra".
+
+Arguments:
+ SupportedLanguages - The RFC3066 language list.
+
+Returns:
+ The ISO639-2 language list.
+
+--*/
+;
+
+EFI_STATUS
+GetCurrentLanguage (
+ OUT CHAR8 *Lang
+ )
+/*++
+
+Routine Description:
+ Determine what is the current language setting
+
+Arguments:
+ Lang - Pointer of system language
+
+Returns:
+ Status code
+
+--*/
+;
+
+VOID
+GetNextLanguage (
+ IN OUT CHAR8 **LangCode,
+ OUT CHAR8 *Lang
+ )
+/*++
+
+Routine Description:
+ Get next language from language code list.
+
+Arguments:
+ LangCode - The language code.
+ Lang - Returned language.
+
+Returns:
+ None.
+
+--*/
+;
+
+CHAR8 *
+GetSupportedLanguages (
+ IN EFI_HII_HANDLE HiiHandle
+ )
+/*++
+
+Routine Description:
+ This function returns the list of supported languages, in the format specified
+ in UEFI specification Appendix M.
+
+Arguments:
+ HiiHandle - The HII package list handle.
+
+Returns:
+ The supported languages.
+
+--*/
+;
+
+UINT16
+GetSupportedLanguageNumber (
+ IN EFI_HII_HANDLE HiiHandle
+ )
+/*++
+
+Routine Description:
+ This function returns the number of supported languages
+
+Arguments:
+ HiiHandle - The HII package list handle.
+
+Returns:
+ The number of supported languages.
+
+--*/
+;
+
+EFI_STATUS
+GetStringFromHandle (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_STRING_ID StringId,
+ OUT EFI_STRING *String
+ )
+/*++
+
+Routine Description:
+ Get string specified by StringId form the HiiHandle.
+
+Arguments:
+ HiiHandle - The HII handle of package list.
+ StringId - The String ID.
+ String - The output string.
+
+Returns:
+ EFI_NOT_FOUND - String is not found.
+ EFI_SUCCESS - Operation is successful.
+ EFI_OUT_OF_RESOURCES - There is not enought memory in the system.
+ EFI_INVALID_PARAMETER - The String is NULL.
+
+--*/
+;
+
+EFI_STATUS
+GetStringFromToken (
+ IN EFI_GUID *ProducerGuid,
+ IN EFI_STRING_ID StringId,
+ OUT EFI_STRING *String
+ )
+/*++
+
+Routine Description:
+ Get the string given the StringId and String package Producer's Guid.
+
+Arguments:
+ ProducerGuid - The Guid of String package list.
+ StringId - The String ID.
+ String - The output string.
+
+Returns:
+ EFI_NOT_FOUND - String is not found.
+ EFI_SUCCESS - Operation is successful.
+ EFI_OUT_OF_RESOURCES - There is not enought memory in the system.
+
+--*/
+;
+
+EFI_STATUS
+IfrLibNewString (
+ IN EFI_HII_HANDLE PackageList,
+ OUT EFI_STRING_ID *StringId,
+ IN CONST EFI_STRING String
+ )
+/*++
+
+ Routine Description:
+ This function adds the string into String Package of each language.
+
+ Arguments:
+ PackageList - Handle of the package list where this string will be added.
+ StringId - On return, contains the new strings id, which is unique within PackageList.
+ String - Points to the new null-terminated string.
+
+ Returns:
+ EFI_SUCCESS - The new string was added successfully.
+ EFI_NOT_FOUND - The specified PackageList could not be found in database.
+ EFI_OUT_OF_RESOURCES - Could not add the string due to lack of resources.
+ EFI_INVALID_PARAMETER - String is NULL or StringId is NULL is NULL.
+
+--*/
+;
+
+EFI_STATUS
+IfrLibGetString (
+ IN EFI_HII_HANDLE PackageList,
+ IN EFI_STRING_ID StringId,
+ OUT EFI_STRING String,
+ IN OUT UINTN *StringSize
+ )
+/*++
+
+ Routine Description:
+ This function try to retrieve string from String package of current language.
+ If fail, it try to retrieve string from String package of first language it support.
+
+ Arguments:
+ PackageList - The package list in the HII database to search for the specified string.
+ StringId - The string's id, which is unique within PackageList.
+ String - Points to the new null-terminated string.
+ StringSize - On entry, points to the size of the buffer pointed to by String, in bytes. On return,
+ points to the length of the string, in bytes.
+
+ Returns:
+ EFI_SUCCESS - The string was returned successfully.
+ EFI_NOT_FOUND - The string specified by StringId is not available.
+ EFI_BUFFER_TOO_SMALL - The buffer specified by StringLength is too small to hold the string.
+ EFI_INVALID_PARAMETER - The String or StringSize was NULL.
+
+--*/
+;
+
+EFI_STATUS
+IfrLibSetString (
+ IN EFI_HII_HANDLE PackageList,
+ IN EFI_STRING_ID StringId,
+ IN CONST EFI_STRING String
+ )
+/*++
+
+ Routine Description:
+ This function updates the string in String package of current language.
+
+ Arguments:
+ PackageList - The package list containing the strings.
+ StringId - The string's id, which is unique within PackageList.
+ String - Points to the new null-terminated string.
+
+ Returns:
+ EFI_SUCCESS - The string was updated successfully.
+ EFI_NOT_FOUND - The string specified by StringId is not in the database.
+ EFI_INVALID_PARAMETER - The String was NULL.
+ EFI_OUT_OF_RESOURCES - The system is out of resources to accomplish the task.
+
+--*/
+;
+
+EFI_STATUS
+IfrLibCreatePopUp (
+ IN UINTN NumberOfLines,
+ OUT EFI_INPUT_KEY *KeyValue,
+ IN CHAR16 *String,
+ ...
+ )
+/*++
+
+Routine Description:
+ Draw a dialog and return the selected key.
+
+Arguments:
+ NumberOfLines - The number of lines for the dialog box
+ KeyValue - The EFI_KEY value returned if HotKey is TRUE..
+ String - Pointer to the first string in the list
+ ... - A series of (quantity == NumberOfLines) text strings which
+ will be used to construct the dialog box
+
+Returns:
+ EFI_SUCCESS - Displayed dialog and received user interaction
+ EFI_INVALID_PARAMETER - One of the parameters was invalid.
+
+--*/
+;
+
+EFI_STATUS
+IfrLibUpdateForm (
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_GUID *FormSetGuid, OPTIONAL
+ IN EFI_FORM_ID FormId,
+ IN UINT16 Label,
+ IN BOOLEAN Insert,
+ IN EFI_HII_UPDATE_DATA *Data
+ )
+/*++
+
+Routine Description:
+ This function allows the caller to update a form that has
+ previously been registered with the EFI HII database.
+
+Arguments:
+ Handle - Hii Handle
+ FormSetGuid - The formset should be updated.
+ FormId - The form should be updated.
+ Label - Update information starting immediately after this label in the IFR
+ Insert - If TRUE and Data is not NULL, insert data after Label.
+ If FALSE, replace opcodes between two labels with Data.
+ Data - The adding data; If NULL, remove opcodes between two Label.
+
+Returns:
+ EFI_SUCCESS - Update success.
+ Other - Update fail.
+
+--*/
+;
+#endif
diff --git a/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrOpCodeCreation.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrOpCodeCreation.c
new file mode 100644
index 0000000000..3729fa216f
--- /dev/null
+++ b/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrOpCodeCreation.c
@@ -0,0 +1,640 @@
+/*++
+
+Copyright (c) 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ UefiIfrOpCodeCreation.c
+
+Abstract:
+
+ Library Routines to create IFR independent of string data - assume tokens already exist
+ Primarily to be used for exporting op-codes at a label in pre-defined forms.
+
+Revision History:
+
+--*/
+
+#include "UefiIfrLibrary.h"
+
+EFI_GUID mIfrVendorGuid = EFI_IFR_TIANO_GUID;
+
+STATIC
+BOOLEAN
+IsValidQuestionFlags (
+ IN UINT8 Flags
+ )
+{
+ return (Flags & (~QUESTION_FLAGS)) ? FALSE : TRUE;
+}
+
+STATIC
+BOOLEAN
+IsValidValueType (
+ IN UINT8 Type
+ )
+{
+ return (Type <= EFI_IFR_TYPE_OTHER) ? TRUE : FALSE;
+}
+
+STATIC
+BOOLEAN
+IsValidNumricFlags (
+ IN UINT8 Flags
+ )
+{
+ if (Flags & ~(EFI_IFR_NUMERIC_SIZE | EFI_IFR_DISPLAY)) {
+ return FALSE;
+ }
+
+ if ((Flags & EFI_IFR_DISPLAY) > EFI_IFR_DISPLAY_UINT_HEX) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+STATIC
+BOOLEAN
+IsValidCheckboxFlags (
+ IN UINT8 Flags
+ )
+{
+ return (Flags <= EFI_IFR_CHECKBOX_DEFAULT_MFG) ? TRUE : FALSE;
+}
+
+EFI_STATUS
+CreateEndOpCode (
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+{
+ EFI_IFR_END End;
+ UINT8 *LocalBuffer;
+
+ ASSERT (Data != NULL && Data->Data != NULL);
+
+ if (Data->Offset + sizeof (EFI_IFR_END) > Data->BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ End.Header.Length = sizeof (EFI_IFR_END);
+ End.Header.OpCode = EFI_IFR_END_OP;
+ End.Header.Scope = 0;
+
+ LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
+ EfiCopyMem (LocalBuffer, &End, sizeof (EFI_IFR_END));
+ Data->Offset += sizeof (EFI_IFR_END);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CreateDefaultOpCode (
+ IN EFI_IFR_TYPE_VALUE *Value,
+ IN UINT8 Type,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+{
+ EFI_IFR_DEFAULT Default;
+ UINT8 *LocalBuffer;
+
+ ASSERT (Data != NULL && Data->Data != NULL);
+
+ if ((Value == NULL) || !IsValidValueType (Type)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Data->Offset + sizeof (EFI_IFR_DEFAULT) > Data->BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Default.Header.OpCode = EFI_IFR_DEFAULT_OP;
+ Default.Header.Length = sizeof (EFI_IFR_DEFAULT);
+ Default.Header.Scope = 0;
+ Default.Type = Type;
+ Default.DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
+ EfiCopyMem (&Default.Value, Value, sizeof(EFI_IFR_TYPE_VALUE));
+
+ LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
+ EfiCopyMem (LocalBuffer, &Default, sizeof (EFI_IFR_DEFAULT));
+ Data->Offset += sizeof (EFI_IFR_DEFAULT);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CreateActionOpCode (
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN EFI_STRING_ID QuestionConfig,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+{
+ EFI_IFR_ACTION Action;
+ UINT8 *LocalBuffer;
+
+ ASSERT (Data != NULL && Data->Data != NULL);
+
+ if (!IsValidQuestionFlags (QuestionFlags)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Data->Offset + sizeof (EFI_IFR_ACTION) > Data->BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Action.Header.OpCode = EFI_IFR_ACTION_OP;
+ Action.Header.Length = sizeof (EFI_IFR_ACTION);
+ Action.Header.Scope = 0;
+ Action.Question.QuestionId = QuestionId;
+ Action.Question.Header.Prompt = Prompt;
+ Action.Question.Header.Help = Help;
+ Action.Question.VarStoreId = INVALID_VARSTORE_ID;
+ Action.Question.Flags = QuestionFlags;
+ Action.QuestionConfig = QuestionConfig;
+
+ LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
+ EfiCopyMem (LocalBuffer, &Action, sizeof (EFI_IFR_ACTION));
+ Data->Offset += sizeof (EFI_IFR_ACTION);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CreateSubTitleOpCode (
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 Flags,
+ IN UINT8 Scope,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+{
+ EFI_IFR_SUBTITLE Subtitle;
+ UINT8 *LocalBuffer;
+
+ ASSERT (Data != NULL && Data->Data != NULL);
+
+ if (Data->Offset + sizeof (EFI_IFR_SUBTITLE) > Data->BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Subtitle.Header.OpCode = EFI_IFR_SUBTITLE_OP;
+ Subtitle.Header.Length = sizeof (EFI_IFR_SUBTITLE);
+ Subtitle.Header.Scope = Scope;
+ Subtitle.Statement.Prompt = Prompt;
+ Subtitle.Statement.Help = Help;
+ Subtitle.Flags = Flags;
+
+ LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
+ EfiCopyMem (LocalBuffer, &Subtitle, sizeof (EFI_IFR_SUBTITLE));
+ Data->Offset += sizeof (EFI_IFR_SUBTITLE);
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+CreateTextOpCode (
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN EFI_STRING_ID TextTwo,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+{
+ EFI_IFR_TEXT Text;
+ UINT8 *LocalBuffer;
+
+ ASSERT (Data != NULL && Data->Data != NULL);
+
+ if (Data->Offset + sizeof (EFI_IFR_TEXT) > Data->BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Text.Header.OpCode = EFI_IFR_TEXT_OP;
+ Text.Header.Length = sizeof (EFI_IFR_TEXT);
+ Text.Header.Scope = 0;
+ Text.Statement.Prompt = Prompt;
+ Text.Statement.Help = Help;
+ Text.TextTwo = TextTwo;
+
+ LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
+ EfiCopyMem (LocalBuffer, &Text, sizeof (EFI_IFR_TEXT));
+ Data->Offset += sizeof (EFI_IFR_TEXT);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CreateGotoOpCode (
+ IN EFI_FORM_ID FormId,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN EFI_QUESTION_ID QuestionId,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+{
+ EFI_IFR_REF Goto;
+ UINT8 *LocalBuffer;
+
+ ASSERT (Data != NULL && Data->Data != NULL);
+
+ if (!IsValidQuestionFlags (QuestionFlags)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Data->Offset + sizeof (EFI_IFR_REF) > Data->BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Goto.Header.OpCode = EFI_IFR_REF_OP;
+ Goto.Header.Length = sizeof (EFI_IFR_REF);
+ Goto.Header.Scope = 0;
+ Goto.Question.Header.Prompt = Prompt;
+ Goto.Question.Header.Help = Help;
+ Goto.Question.VarStoreId = INVALID_VARSTORE_ID;
+ Goto.Question.QuestionId = QuestionId;
+ Goto.Question.Flags = QuestionFlags;
+ Goto.FormId = FormId;
+
+ LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
+ EfiCopyMem (LocalBuffer, &Goto, sizeof (EFI_IFR_REF));
+ Data->Offset += sizeof (EFI_IFR_REF);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CreateOneOfOptionOpCode (
+ IN UINTN OptionCount,
+ IN IFR_OPTION *OptionsList,
+ IN UINT8 Type,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+{
+ UINTN Index;
+ UINT8 *LocalBuffer;
+ EFI_IFR_ONE_OF_OPTION OneOfOption;
+
+ ASSERT (Data != NULL && Data->Data != NULL);
+
+ if ((OptionCount != 0) && (OptionsList == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Data->Offset + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) > Data->BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ for (Index = 0; Index < OptionCount; Index++) {
+ OneOfOption.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP;
+ OneOfOption.Header.Length = sizeof (EFI_IFR_ONE_OF_OPTION);
+ OneOfOption.Header.Scope = 0;
+
+ OneOfOption.Option = OptionsList[Index].StringToken;
+ OneOfOption.Value = OptionsList[Index].Value;
+ OneOfOption.Flags = OptionsList[Index].Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG);
+ OneOfOption.Type = Type;
+
+ LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
+ EfiCopyMem (LocalBuffer, &OneOfOption, sizeof (EFI_IFR_ONE_OF_OPTION));
+ Data->Offset += sizeof (EFI_IFR_ONE_OF_OPTION);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CreateOneOfOpCode (
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN UINT16 VarOffset,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN UINT8 OneOfFlags,
+ IN IFR_OPTION *OptionsList,
+ IN UINTN OptionCount,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+{
+ UINTN Length;
+ EFI_IFR_ONE_OF OneOf;
+ UINT8 *LocalBuffer;
+
+ ASSERT (Data != NULL && Data->Data != NULL);
+
+ if (!IsValidNumricFlags (OneOfFlags) ||
+ !IsValidQuestionFlags (QuestionFlags) ||
+ ((OptionCount != 0) && (OptionsList == NULL))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Length = sizeof (EFI_IFR_ONE_OF) + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) + sizeof (EFI_IFR_END);
+ if (Data->Offset + Length > Data->BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ OneOf.Header.OpCode = EFI_IFR_ONE_OF_OP;
+ OneOf.Header.Length = sizeof (EFI_IFR_ONE_OF);
+ OneOf.Header.Scope = 1;
+ OneOf.Question.Header.Prompt = Prompt;
+ OneOf.Question.Header.Help = Help;
+ OneOf.Question.QuestionId = QuestionId;
+ OneOf.Question.VarStoreId = VarStoreId;
+ OneOf.Question.VarStoreInfo.VarOffset = VarOffset;
+ OneOf.Question.Flags = QuestionFlags;
+ OneOf.Flags = OneOfFlags;
+ EfiZeroMem ((VOID *) &OneOf.data, sizeof (MINMAXSTEP_DATA));
+
+ LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
+ EfiCopyMem (LocalBuffer, &OneOf, sizeof (EFI_IFR_ONE_OF));
+ Data->Offset += sizeof (EFI_IFR_ONE_OF);
+
+ CreateOneOfOptionOpCode (OptionCount, OptionsList, (OneOfFlags & EFI_IFR_NUMERIC_SIZE), Data);
+
+ CreateEndOpCode (Data);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CreateOrderedListOpCode (
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN UINT16 VarOffset,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN UINT8 OrderedListFlags,
+ IN UINT8 DataType,
+ IN UINT8 MaxContainers,
+ IN IFR_OPTION *OptionsList,
+ IN UINTN OptionCount,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+{
+ UINTN Length;
+ EFI_IFR_ORDERED_LIST OrderedList;
+ UINT8 *LocalBuffer;
+
+ ASSERT (Data != NULL && Data->Data != NULL);
+
+ if (!IsValidQuestionFlags (QuestionFlags) ||
+ ((OptionCount != 0) && (OptionsList == NULL))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((OrderedListFlags != 0) &&
+ (OrderedListFlags != EFI_IFR_UNIQUE_SET) &&
+ (OrderedListFlags != EFI_IFR_NO_EMPTY_SET)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Length = sizeof (EFI_IFR_ORDERED_LIST) + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) + sizeof (EFI_IFR_END);
+ if (Data->Offset + Length > Data->BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ OrderedList.Header.OpCode = EFI_IFR_ORDERED_LIST_OP;
+ OrderedList.Header.Length = sizeof (EFI_IFR_ORDERED_LIST);
+ OrderedList.Header.Scope = 1;
+ OrderedList.Question.Header.Prompt = Prompt;
+ OrderedList.Question.Header.Help = Help;
+ OrderedList.Question.QuestionId = QuestionId;
+ OrderedList.Question.VarStoreId = VarStoreId;
+ OrderedList.Question.VarStoreInfo.VarOffset = VarOffset;
+ OrderedList.Question.Flags = QuestionFlags;
+ OrderedList.MaxContainers = MaxContainers;
+ OrderedList.Flags = OrderedListFlags;
+
+ LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
+ EfiCopyMem (LocalBuffer, &OrderedList, sizeof (EFI_IFR_ORDERED_LIST));
+ Data->Offset += sizeof (EFI_IFR_ORDERED_LIST);
+
+ CreateOneOfOptionOpCode (OptionCount, OptionsList, DataType, Data);
+
+ CreateEndOpCode (Data);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CreateCheckBoxOpCode (
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN UINT16 VarOffset,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN UINT8 CheckBoxFlags,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+{
+ EFI_IFR_CHECKBOX CheckBox;
+ UINT8 *LocalBuffer;
+
+ ASSERT (Data != NULL && Data->Data != NULL);
+
+ if (!IsValidQuestionFlags (QuestionFlags) || !IsValidCheckboxFlags (CheckBoxFlags)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Data->Offset + sizeof (EFI_IFR_CHECKBOX) > Data->BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ CheckBox.Header.OpCode = EFI_IFR_CHECKBOX_OP;
+ CheckBox.Header.Length = sizeof (EFI_IFR_CHECKBOX);
+ CheckBox.Header.Scope = 0;
+ CheckBox.Question.QuestionId = QuestionId;
+ CheckBox.Question.VarStoreId = VarStoreId;
+ CheckBox.Question.VarStoreInfo.VarOffset = VarOffset;
+ CheckBox.Question.Header.Prompt = Prompt;
+ CheckBox.Question.Header.Help = Help;
+ CheckBox.Question.Flags = QuestionFlags;
+ CheckBox.Flags = CheckBoxFlags;
+
+ LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
+ EfiCopyMem (LocalBuffer, &CheckBox, sizeof (EFI_IFR_CHECKBOX));
+ Data->Offset += sizeof (EFI_IFR_CHECKBOX);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CreateNumericOpCode (
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN UINT16 VarOffset,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN UINT8 NumericFlags,
+ IN UINT64 Minimum,
+ IN UINT64 Maximum,
+ IN UINT64 Step,
+ IN UINT64 Default,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+{
+ UINTN Length;
+ EFI_STATUS Status;
+ EFI_IFR_NUMERIC Numeric;
+ MINMAXSTEP_DATA MinMaxStep;
+ EFI_IFR_TYPE_VALUE DefaultValue;
+ UINT8 *LocalBuffer;
+
+ ASSERT (Data != NULL && Data->Data != NULL);
+
+ if (!IsValidQuestionFlags (QuestionFlags) || !IsValidNumricFlags (NumericFlags)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Length = sizeof (EFI_IFR_NUMERIC) + sizeof (EFI_IFR_DEFAULT) + sizeof (EFI_IFR_END);
+ if (Data->Offset + sizeof (EFI_IFR_CHECKBOX) > Data->BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Numeric.Header.OpCode = EFI_IFR_NUMERIC_OP;
+ Numeric.Header.Length = sizeof (EFI_IFR_NUMERIC);
+ Numeric.Header.Scope = 1;
+ Numeric.Question.QuestionId = QuestionId;
+ Numeric.Question.VarStoreId = VarStoreId;
+ Numeric.Question.VarStoreInfo.VarOffset = VarOffset;
+ Numeric.Question.Header.Prompt = Prompt;
+ Numeric.Question.Header.Help = Help;
+ Numeric.Question.Flags = QuestionFlags;
+ Numeric.Flags = NumericFlags;
+
+ switch (NumericFlags & EFI_IFR_NUMERIC_SIZE) {
+ case EFI_IFR_NUMERIC_SIZE_1:
+ MinMaxStep.u8.MinValue = (UINT8) Minimum;
+ MinMaxStep.u8.MaxValue = (UINT8) Maximum;
+ MinMaxStep.u8.Step = (UINT8) Step;
+ break;
+
+ case EFI_IFR_NUMERIC_SIZE_2:
+ MinMaxStep.u16.MinValue = (UINT16) Minimum;
+ MinMaxStep.u16.MaxValue = (UINT16) Maximum;
+ MinMaxStep.u16.Step = (UINT16) Step;
+ break;
+
+ case EFI_IFR_NUMERIC_SIZE_4:
+ MinMaxStep.u32.MinValue = (UINT32) Minimum;
+ MinMaxStep.u32.MaxValue = (UINT32) Maximum;
+ MinMaxStep.u32.Step = (UINT32) Step;
+ break;
+
+ case EFI_IFR_NUMERIC_SIZE_8:
+ MinMaxStep.u64.MinValue = Minimum;
+ MinMaxStep.u64.MaxValue = Maximum;
+ MinMaxStep.u64.Step = Step;
+ break;
+ }
+
+ EfiCopyMem (&Numeric.data, &MinMaxStep, sizeof (MINMAXSTEP_DATA));
+
+ LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
+ EfiCopyMem (LocalBuffer, &Numeric, sizeof (EFI_IFR_NUMERIC));
+ Data->Offset += sizeof (EFI_IFR_NUMERIC);
+
+ DefaultValue.u64 = Default;
+ Status = CreateDefaultOpCode (&DefaultValue, (NumericFlags & EFI_IFR_NUMERIC_SIZE), Data);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ CreateEndOpCode (Data);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CreateStringOpCode (
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN UINT16 VarOffset,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN UINT8 StringFlags,
+ IN UINT8 MinSize,
+ IN UINT8 MaxSize,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+{
+ EFI_IFR_STRING String;
+ UINT8 *LocalBuffer;
+
+ ASSERT (Data != NULL && Data->Data != NULL);
+
+ if (!IsValidQuestionFlags (QuestionFlags) || (StringFlags & (~EFI_IFR_STRING_MULTI_LINE))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Data->Offset + sizeof (EFI_IFR_STRING) > Data->BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ String.Header.OpCode = EFI_IFR_STRING_OP;
+ String.Header.Length = sizeof (EFI_IFR_STRING);
+ String.Header.Scope = 0;
+ String.Question.Header.Prompt = Prompt;
+ String.Question.Header.Help = Help;
+ String.Question.QuestionId = QuestionId;
+ String.Question.VarStoreId = VarStoreId;
+ String.Question.VarStoreInfo.VarOffset = VarOffset;
+ String.Question.Flags = QuestionFlags;
+ String.MinSize = MinSize;
+ String.MaxSize = MaxSize;
+ String.Flags = StringFlags;
+
+ LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
+ EfiCopyMem (LocalBuffer, &String, sizeof (EFI_IFR_STRING));
+ Data->Offset += sizeof (EFI_IFR_STRING);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CreateBannerOpCode (
+ IN EFI_STRING_ID Title,
+ IN UINT16 LineNumber,
+ IN UINT8 Alignment,
+ IN OUT EFI_HII_UPDATE_DATA *Data
+ )
+{
+ EFI_IFR_GUID_BANNER Banner;
+ UINT8 *LocalBuffer;
+
+ ASSERT (Data != NULL && Data->Data != NULL);
+
+ if (Data->Offset + sizeof (EFI_IFR_GUID_BANNER) > Data->BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Banner.Header.OpCode = EFI_IFR_GUID_OP;
+ Banner.Header.Length = sizeof (EFI_IFR_GUID_BANNER);
+ Banner.Header.Scope = 0;
+ EfiCopyMem (&Banner.Guid, &mIfrVendorGuid, sizeof (EFI_IFR_GUID));
+ Banner.ExtendOpCode = EFI_IFR_EXTEND_OP_BANNER;
+ Banner.Title = Title;
+ Banner.LineNumber = LineNumber;
+ Banner.Alignment = Alignment;
+
+ LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
+ EfiCopyMem (LocalBuffer, &Banner, sizeof (EFI_IFR_GUID_BANNER));
+ Data->Offset += sizeof (EFI_IFR_GUID_BANNER);
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrString.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrString.c
new file mode 100644
index 0000000000..c2e57dd16b
--- /dev/null
+++ b/EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrString.c
@@ -0,0 +1,702 @@
+/*++
+
+Copyright (c) 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ UefiIfrString.c
+
+Abstract:
+
+ Common Library Routines to assist to handle String and Language.
+
+--*/
+
+#include "UefiIfrLibrary.h"
+
+//
+// Lookup table of ISO639-2 3 character language codes to ISO 639-1 2 character language codes
+// Each entry is 5 CHAR8 values long. The first 3 CHAR8 values are the ISO 639-2 code.
+// The last 2 CHAR8 values are the ISO 639-1 code.
+//
+CHAR8 Iso639ToRfc3066ConversionTable[] =
+"\
+aaraa\
+abkab\
+afraf\
+amham\
+araar\
+asmas\
+aymay\
+azeaz\
+bakba\
+belbe\
+benbn\
+bihbh\
+bisbi\
+bodbo\
+brebr\
+bulbg\
+catca\
+cescs\
+corkw\
+cosco\
+cymcy\
+danda\
+deude\
+dzodz\
+ellel\
+engen\
+epoeo\
+estet\
+euseu\
+faofo\
+fasfa\
+fijfj\
+finfi\
+frafr\
+fryfy\
+gaiga\
+gdhgd\
+glggl\
+grngn\
+gujgu\
+hauha\
+hebhe\
+hinhi\
+hrvhr\
+hunhu\
+hyehy\
+ikuiu\
+ileie\
+inaia\
+indid\
+ipkik\
+islis\
+itait\
+jawjw\
+jpnja\
+kalkl\
+kankn\
+kasks\
+katka\
+kazkk\
+khmkm\
+kinrw\
+kirky\
+korko\
+kurku\
+laolo\
+latla\
+lavlv\
+linln\
+litlt\
+ltzlb\
+malml\
+marmr\
+mkdmk\
+mlgmg\
+mltmt\
+molmo\
+monmn\
+mrimi\
+msams\
+myamy\
+nauna\
+nepne\
+nldnl\
+norno\
+ocioc\
+ormom\
+panpa\
+polpl\
+porpt\
+pusps\
+quequ\
+rohrm\
+ronro\
+runrn\
+rusru\
+sagsg\
+sansa\
+sinsi\
+slksk\
+slvsl\
+smise\
+smosm\
+snasn\
+sndsd\
+somso\
+sotst\
+spaes\
+sqisq\
+srpsr\
+sswss\
+sunsu\
+swasw\
+swesv\
+tamta\
+tattt\
+telte\
+tgktg\
+tgltl\
+thath\
+tsnts\
+tuktk\
+twitw\
+uigug\
+ukruk\
+urdur\
+uzbuz\
+vievi\
+volvo\
+wolwo\
+xhoxh\
+yidyi\
+zhaza\
+zhozh\
+zulzu\
+";
+
+EFI_STATUS
+ConvertRfc3066LanguageToIso639Language (
+ CHAR8 *LanguageRfc3066,
+ CHAR8 *LanguageIso639
+ )
+/*++
+
+Routine Description:
+ Convert language code from RFC3066 to ISO639-2.
+
+Arguments:
+ LanguageRfc3066 - RFC3066 language code.
+ LanguageIso639 - ISO639-2 language code.
+
+Returns:
+ EFI_SUCCESS - Language code converted.
+ EFI_NOT_FOUND - Language code not found.
+
+--*/
+{
+ UINTN Index;
+
+ if ((LanguageRfc3066[2] != '-') && (LanguageRfc3066[2] != 0)) {
+ EfiCopyMem (LanguageIso639, LanguageRfc3066, 3);
+ return EFI_SUCCESS;
+ }
+
+ for (Index = 0; Iso639ToRfc3066ConversionTable[Index] != 0; Index += 5) {
+ if (EfiCompareMem (LanguageRfc3066, &Iso639ToRfc3066ConversionTable[Index + 3], 2) == 0) {
+ EfiCopyMem (LanguageIso639, &Iso639ToRfc3066ConversionTable[Index], 3);
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+CHAR8 *
+Rfc3066ToIso639 (
+ CHAR8 *SupportedLanguages
+ )
+/*++
+
+Routine Description:
+ Convert language code list from RFC3066 to ISO639-2, e.g. "en-US;fr-FR" will
+ be converted to "engfra".
+
+Arguments:
+ SupportedLanguages - The RFC3066 language list.
+
+Returns:
+ The ISO639-2 language list.
+
+--*/
+{
+ CHAR8 *Languages;
+ CHAR8 *ReturnValue;
+ CHAR8 *LangCodes;
+ CHAR8 LangRfc3066[RFC_3066_ENTRY_SIZE];
+ CHAR8 LangIso639[ISO_639_2_ENTRY_SIZE];
+ EFI_STATUS Status;
+
+ ReturnValue = EfiLibAllocateZeroPool (EfiAsciiStrSize (SupportedLanguages));
+ if (ReturnValue == NULL) {
+ return ReturnValue;
+ }
+
+ Languages = ReturnValue;
+ LangCodes = SupportedLanguages;
+ while (*LangCodes != 0) {
+ GetNextLanguage (&LangCodes, LangRfc3066);
+
+ Status = ConvertRfc3066LanguageToIso639Language (LangRfc3066, LangIso639);
+ if (!EFI_ERROR (Status)) {
+ EfiCopyMem (Languages, LangIso639, 3);
+ Languages = Languages + 3;
+ }
+ }
+
+ return ReturnValue;
+}
+
+EFI_STATUS
+GetCurrentLanguage (
+ OUT CHAR8 *Lang
+ )
+/*++
+
+Routine Description:
+ Determine what is the current language setting
+
+Arguments:
+ Lang - Pointer of system language
+
+Returns:
+ Status code
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Size;
+
+ //
+ // Get current language setting
+ //
+ Size = RFC_3066_ENTRY_SIZE;
+ Status = gRT->GetVariable (
+ L"PlatformLang",
+ &gEfiGlobalVariableGuid,
+ NULL,
+ &Size,
+ Lang
+ );
+
+ if (EFI_ERROR (Status)) {
+ EfiAsciiStrCpy (Lang, "en-US");
+ }
+
+ return Status;
+}
+
+VOID
+GetNextLanguage (
+ IN OUT CHAR8 **LangCode,
+ OUT CHAR8 *Lang
+ )
+/*++
+
+Routine Description:
+ Get next language from language code list (with separator ';').
+
+Arguments:
+ LangCode - On input: point to first language in the list. On output: point to
+ next language in the list, or NULL if no more language in the list.
+ Lang - The first language in the list.
+
+Returns:
+ None.
+
+--*/
+{
+ UINTN Index;
+ CHAR8 *StringPtr;
+
+ if (LangCode == NULL || *LangCode == NULL) {
+ *Lang = 0;
+ return;
+ }
+
+ Index = 0;
+ StringPtr = *LangCode;
+ while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {
+ Index++;
+ }
+
+ EfiCopyMem (Lang, StringPtr, Index);
+ Lang[Index] = 0;
+
+ if (StringPtr[Index] == ';') {
+ Index++;
+ }
+ *LangCode = StringPtr + Index;
+}
+
+CHAR8 *
+GetSupportedLanguages (
+ IN EFI_HII_HANDLE HiiHandle
+ )
+/*++
+
+Routine Description:
+ This function returns the list of supported languages, in the format specified
+ in UEFI specification Appendix M.
+
+Arguments:
+ HiiHandle - The HII package list handle.
+
+Returns:
+ The supported languages.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ CHAR8 *LanguageString;
+
+ LocateHiiProtocols ();
+
+ //
+ // Collect current supported Languages for given HII handle
+ //
+ BufferSize = 0x1000;
+ LanguageString = EfiLibAllocatePool (BufferSize);
+ Status = gIfrLibHiiString->GetLanguages (gIfrLibHiiString, HiiHandle, LanguageString, &BufferSize);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ gBS->FreePool (LanguageString);
+ LanguageString = EfiLibAllocatePool (BufferSize);
+ Status = gIfrLibHiiString->GetLanguages (gIfrLibHiiString, HiiHandle, LanguageString, &BufferSize);
+ }
+
+ if (EFI_ERROR (Status)) {
+ LanguageString = NULL;
+ }
+
+ return LanguageString;
+}
+
+UINT16
+GetSupportedLanguageNumber (
+ IN EFI_HII_HANDLE HiiHandle
+ )
+/*++
+
+Routine Description:
+ This function returns the number of supported languages
+
+Arguments:
+ HiiHandle - The HII package list handle.
+
+Returns:
+ The number of supported languages.
+
+--*/
+{
+ CHAR8 *Languages;
+ CHAR8 *LanguageString;
+ UINT16 LangNumber;
+ CHAR8 Lang[RFC_3066_ENTRY_SIZE];
+
+ Languages = GetSupportedLanguages (HiiHandle);
+ if (Languages == NULL) {
+ return 0;
+ }
+
+ LangNumber = 0;
+ LanguageString = Languages;
+ while (*LanguageString != 0) {
+ GetNextLanguage (&LanguageString, Lang);
+ LangNumber++;
+ }
+ gBS->FreePool (Languages);
+
+ return LangNumber;
+}
+
+EFI_STATUS
+GetStringFromHandle (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_STRING_ID StringId,
+ OUT EFI_STRING *String
+ )
+/*++
+
+Routine Description:
+ Get string specified by StringId form the HiiHandle.
+
+Arguments:
+ HiiHandle - The HII handle of package list.
+ StringId - The String ID.
+ String - The output string.
+
+Returns:
+ EFI_NOT_FOUND - String is not found.
+ EFI_SUCCESS - Operation is successful.
+ EFI_OUT_OF_RESOURCES - There is not enought memory in the system.
+ EFI_INVALID_PARAMETER - The String is NULL.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN StringSize;
+
+ if (String == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ StringSize = IFR_LIB_DEFAULT_STRING_SIZE;
+ *String = EfiLibAllocateZeroPool (StringSize);
+ if (*String == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = IfrLibGetString (HiiHandle, StringId, *String, &StringSize);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ gBS->FreePool (*String);
+ *String = EfiLibAllocateZeroPool (StringSize);
+ if (*String == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ Status = IfrLibGetString (HiiHandle, StringId, *String, &StringSize);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+GetStringFromToken (
+ IN EFI_GUID *ProducerGuid,
+ IN EFI_STRING_ID StringId,
+ OUT EFI_STRING *String
+ )
+/*++
+
+Routine Description:
+ Get the string given the StringId and String package Producer's Guid.
+
+Arguments:
+ ProducerGuid - The Guid of String package list.
+ StringId - The String ID.
+ String - The output string.
+
+Returns:
+ EFI_NOT_FOUND - String is not found.
+ EFI_SUCCESS - Operation is successful.
+ EFI_OUT_OF_RESOURCES - There is not enought memory in the system.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN HandleBufferLen;
+ EFI_HII_HANDLE *HiiHandleBuffer;
+ EFI_GUID Guid;
+
+ Status = GetHiiHandles (&HandleBufferLen, &HiiHandleBuffer);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ for (Index = 0; Index < (HandleBufferLen / sizeof (EFI_HII_HANDLE)); Index++) {
+ Status = ExtractGuidFromHiiHandle (HiiHandleBuffer[Index], &Guid);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ if (EfiCompareGuid (&Guid, ProducerGuid) == TRUE) {
+ break;
+ }
+ }
+
+ if (Index >= (HandleBufferLen / sizeof (EFI_HII_HANDLE))) {
+ Status = EFI_NOT_FOUND;
+ goto Out;
+ }
+
+ Status = GetStringFromHandle (HiiHandleBuffer[Index], StringId, String);
+
+Out:
+ if (HiiHandleBuffer != NULL) {
+ gBS->FreePool (HiiHandleBuffer);
+ }
+ return Status;
+}
+
+EFI_STATUS
+IfrLibNewString (
+ IN EFI_HII_HANDLE PackageList,
+ OUT EFI_STRING_ID *StringId,
+ IN CONST EFI_STRING String
+ )
+/*++
+
+ Routine Description:
+ This function adds the string into String Package of each language.
+
+ Arguments:
+ PackageList - Handle of the package list where this string will be added.
+ StringId - On return, contains the new strings id, which is unique within PackageList.
+ String - Points to the new null-terminated string.
+
+ Returns:
+ EFI_SUCCESS - The new string was added successfully.
+ EFI_NOT_FOUND - The specified PackageList could not be found in database.
+ EFI_OUT_OF_RESOURCES - Could not add the string due to lack of resources.
+ EFI_INVALID_PARAMETER - String is NULL or StringId is NULL is NULL.
+
+--*/
+{
+ EFI_STATUS Status;
+ CHAR8 *Languages;
+ CHAR8 *LangStrings;
+ CHAR8 Lang[RFC_3066_ENTRY_SIZE];
+
+ Status = EFI_SUCCESS;
+
+ LocateHiiProtocols ();
+
+ Languages = GetSupportedLanguages (PackageList);
+
+ LangStrings = Languages;
+ while (*LangStrings != 0) {
+ GetNextLanguage (&LangStrings, Lang);
+
+ Status = gIfrLibHiiString->NewString (
+ gIfrLibHiiString,
+ PackageList,
+ StringId,
+ Lang,
+ NULL,
+ String,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ }
+
+ gBS->FreePool (Languages);
+
+ return Status;
+}
+
+EFI_STATUS
+IfrLibGetString (
+ IN EFI_HII_HANDLE PackageList,
+ IN EFI_STRING_ID StringId,
+ OUT EFI_STRING String,
+ IN OUT UINTN *StringSize
+ )
+/*++
+
+ Routine Description:
+ This function try to retrieve string from String package of current language.
+ If fail, it try to retrieve string from String package of first language it support.
+
+ Arguments:
+ PackageList - The package list in the HII database to search for the specified string.
+ StringId - The string's id, which is unique within PackageList.
+ String - Points to the new null-terminated string.
+ StringSize - On entry, points to the size of the buffer pointed to by String, in bytes. On return,
+ points to the length of the string, in bytes.
+
+ Returns:
+ EFI_SUCCESS - The string was returned successfully.
+ EFI_NOT_FOUND - The string specified by StringId is not available.
+ EFI_BUFFER_TOO_SMALL - The buffer specified by StringLength is too small to hold the string.
+ EFI_INVALID_PARAMETER - The String or StringSize was NULL.
+
+--*/
+{
+ EFI_STATUS Status;
+ CHAR8 *Languages;
+ CHAR8 *LangStrings;
+ CHAR8 Lang[RFC_3066_ENTRY_SIZE];
+ CHAR8 CurrentLang[RFC_3066_ENTRY_SIZE];
+
+ LocateHiiProtocols ();
+
+ GetCurrentLanguage (CurrentLang);
+
+ Status = gIfrLibHiiString->GetString (
+ gIfrLibHiiString,
+ CurrentLang,
+ PackageList,
+ StringId,
+ String,
+ StringSize,
+ NULL
+ );
+
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ Languages = GetSupportedLanguages (PackageList);
+ LangStrings = Languages;
+ GetNextLanguage (&LangStrings, Lang);
+ gBS->FreePool (Languages);
+
+ Status = gIfrLibHiiString->GetString (
+ gIfrLibHiiString,
+ Lang,
+ PackageList,
+ StringId,
+ String,
+ StringSize,
+ NULL
+ );
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+IfrLibSetString (
+ IN EFI_HII_HANDLE PackageList,
+ IN EFI_STRING_ID StringId,
+ IN CONST EFI_STRING String
+ )
+/*++
+
+ Routine Description:
+ This function updates the string in String package of each language.
+
+ Arguments:
+ PackageList - The package list containing the strings.
+ StringId - The string's id, which is unique within PackageList.
+ String - Points to the new null-terminated string.
+
+ Returns:
+ EFI_SUCCESS - The string was updated successfully.
+ EFI_NOT_FOUND - The string specified by StringId is not in the database.
+ EFI_INVALID_PARAMETER - The String was NULL.
+ EFI_OUT_OF_RESOURCES - The system is out of resources to accomplish the task.
+
+--*/
+{
+ EFI_STATUS Status;
+ CHAR8 *Languages;
+ CHAR8 *LangStrings;
+ CHAR8 Lang[RFC_3066_ENTRY_SIZE];
+
+ Status = EFI_SUCCESS;
+
+ LocateHiiProtocols ();
+
+ Languages = GetSupportedLanguages (PackageList);
+
+ LangStrings = Languages;
+ while (*LangStrings != 0) {
+ GetNextLanguage (&LangStrings, Lang);
+
+ Status = gIfrLibHiiString->SetString (
+ gIfrLibHiiString,
+ PackageList,
+ StringId,
+ Lang,
+ String,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ }
+
+ gBS->FreePool (Languages);
+
+ return Status;
+}
+