summaryrefslogtreecommitdiff
path: root/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib
diff options
context:
space:
mode:
Diffstat (limited to 'EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib')
-rw-r--r--EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.cif15
-rw-r--r--EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.inf49
-rw-r--r--EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.mak70
-rw-r--r--EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.sdl26
-rw-r--r--EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrCommon.c762
-rw-r--r--EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrForm.c2249
-rw-r--r--EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrLibrary.h1370
-rw-r--r--EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrOpCodeCreation.c638
-rw-r--r--EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrString.c729
9 files changed, 5908 insertions, 0 deletions
diff --git a/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.cif b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.cif
new file mode 100644
index 0000000..7a843fc
--- /dev/null
+++ b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "UefiEfiIfrSupportLib"
+ category = ModulePart
+ LocalRoot = "EDK\Foundation\Library\Dxe\UefiEfiIfrSupportLib\"
+ RefName = "UefiEfiIfrSupportLib"
+[files]
+"UefiEfiIfrSupportLib.sdl"
+"UefiEfiIfrSupportLib.mak"
+"UefiIfrCommon.c"
+"UefiIfrForm.c"
+"UefiIfrLibrary.h"
+"UefiIfrOpCodeCreation.c"
+"UefiIfrString.c"
+"UefiEfiIfrSupportLib.inf"
+<endComponent>
diff --git a/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.inf b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.inf
new file mode 100644
index 0000000..cc26951
--- /dev/null
+++ b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.inf
@@ -0,0 +1,49 @@
+#/*++
+#
+# 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
+
+[libraries.common]
+ EfiGuidLib
+ EdkFrameworkProtocolLib
+
+[nmake.common]
diff --git a/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.mak b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.mak
new file mode 100644
index 0000000..991cd72
--- /dev/null
+++ b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.mak
@@ -0,0 +1,70 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/IntelEDK/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.mak 1 1/20/12 4:13a Jeffch $
+#
+# $Revision: 1 $
+#
+# $Date: 1/20/12 4:13a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/IntelEDK/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.mak $
+#
+# 1 1/20/12 4:13a Jeffch
+# Create Intel EDK 1117 Patch 7.
+#
+# 1 9/27/11 6:35a Wesleychen
+# Intel EDK initially releases.
+#
+# 2 9/02/09 3:55a Iminglin
+# EIP24919
+#
+#**********************************************************************
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: UefiEfiIfrSupportLib.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+$(UEFIEFIIFRSUPPORTLIB) : UefiEfiIfrSupportLib
+
+$(BUILD_DIR)\UefiEfiIfrSupportLib.lib : UefiEfiIfrSupportLib
+
+UefiEfiIfrSupportLib : $(BUILD_DIR)\UefiEfiIfrSupportLib.mak UefiEfiIfrSupportLibBin
+
+$(BUILD_DIR)\UefiEfiIfrSupportLib.mak : $(UefiEfiIfrSupportLib_DIR)\$(@B).cif $(UefiEfiIfrSupportLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(UefiEfiIfrSupportLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+UefiEfiIfrSupportLibBin : $(EFIGUIDLIB) $(EDKFRAMEWORKPROTOCOLLIB)
+ $(MAKE) /$(MAKEFLAGS) $(EDK_DEFAULTS)\
+ /f $(BUILD_DIR)\UefiEfiIfrSupportLib.mak all\
+ TYPE=LIBRARY \
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.sdl b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.sdl
new file mode 100644
index 0000000..f7135b8
--- /dev/null
+++ b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiEfiIfrSupportLib.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "UefiEfiIfrSupportLib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable UefiEfiIfrSupportLib support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "UEFIEFIIFRSUPPORTLIB"
+ Value = "$(BUILD_DIR)\UefiEfiIfrSupportLib.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "UefiEfiIfrSupportLib_DIR"
+End
+
+MODULE
+ Help = "Includes UefiEfiIfrSupportLib.mak to Project"
+ File = "UefiEfiIfrSupportLib.mak"
+End
+
diff --git a/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrCommon.c b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrCommon.c
new file mode 100644
index 0000000..d2a66e0
--- /dev/null
+++ b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrCommon.c
@@ -0,0 +1,762 @@
+/*++
+
+Copyright (c) 2007 - 2011, 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,
+ 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;
+
+ VendorDevicePath = EfiLibAllocateCopyPool (sizeof (HII_VENDOR_DEVICE_PATH), &mHiiVendorDevicePathTemplate);
+ if (VendorDevicePath == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Use memory address as unique ID to distinguish from different device paths
+ //
+ VendorDevicePath->UniqueId = (UINT64) ((UINTN) VendorDevicePath);
+
+ *DriverHandle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ VendorDevicePath,
+ NULL
+ );
+ 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
+ );
+ gBS->FreePool (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_NOT_FOUND - Class not found.
+
+--*/
+{
+ 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;
+ BOOLEAN ClassFound;
+
+ *Class = EFI_NON_DEVICE_CLASS;
+ *FormSetTitle = 0;
+ *FormSetHelp = 0;
+ ClassFound = FALSE;
+
+ //
+ // 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_FORMS) {
+ //
+ // Search Class Opcode in this Form Package
+ //
+ Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
+ while (Offset2 < PackageHeader.Length) {
+ OpCodeData = Package + Offset2;
+ if (OpCodeData == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ 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
+ //
+ ClassFound = TRUE;
+ break;
+ }
+
+ Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
+ }
+
+ if (Offset2 < PackageHeader.Length) {
+ //
+ // Target formset found
+ //
+ break;
+ }
+ }
+
+ Offset += PackageHeader.Length;
+ }
+
+ gBS->FreePool (HiiPackageList);
+
+ return ClassFound ? EFI_SUCCESS : EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+ExtractClassGuidFromHiiHandle (
+ IN EFI_HII_HANDLE Handle,
+ OUT UINT8 *NumberOfClassGuid,
+ OUT EFI_GUID **ClassGuid,
+ OUT EFI_STRING_ID *FormSetTitle,
+ OUT EFI_STRING_ID *FormSetHelp
+ )
+/*++
+
+Routine Description:
+ Extract formset ClassGuid for given HII handle.
+
+Arguments:
+ HiiHandle - Hii handle
+ NumberOfClassGuid - Number of ClassGuid
+ ClassGuid - Pointer to callee allocated buffer, an array of ClassGuid
+ 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;
+
+ if (NumberOfClassGuid == NULL || ClassGuid == NULL || FormSetTitle == NULL || FormSetHelp == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *NumberOfClassGuid = 0;
+ *ClassGuid = NULL;
+ *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_FORMS) {
+ //
+ // Search Class Opcode in this Form Package
+ //
+ Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
+ while (Offset2 < PackageHeader.Length) {
+ OpCodeData = Package + Offset2;
+ if (OpCodeData == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ 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)->Length > ((UINTN) &((EFI_IFR_FORM_SET *) 0)->Flags)) {
+ //
+ // New version of formset OpCode
+ //
+ *NumberOfClassGuid = ((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3;
+ *ClassGuid = EfiLibAllocateCopyPool (
+ *NumberOfClassGuid * sizeof (EFI_GUID),
+ ((EFI_IFR_FORM_SET *) OpCodeData)->ClassGuid
+ );
+ }
+ 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/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrForm.c b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrForm.c
new file mode 100644
index 0000000..0fe6582
--- /dev/null
+++ b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrForm.c
@@ -0,0 +1,2249 @@
+/*++
+
+Copyright (c) 2007 - 2008, 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
+ )
+{
+ UINT8 *BufferPos;
+ EFI_HII_PACKAGE_HEADER PackageHeader;
+ UINT32 Offset;
+ EFI_IFR_OP_HEADER *IfrOpHdr;
+ BOOLEAN GetFormSet;
+ BOOLEAN GetForm;
+ UINT8 ExtendOpCode;
+ UINT16 LabelNumber;
+ BOOLEAN Updated;
+
+ 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 (!Updated && 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;
+ } else {
+ GetFormSet = FALSE;
+ }
+ }
+ break;
+
+ case EFI_IFR_FORM_OP:
+ if (EfiCompareMem (&((EFI_IFR_FORM *) IfrOpHdr)->FormId, &FormId, sizeof (EFI_FORM_ID)) == 0) {
+ GetForm = TRUE;
+ } else {
+ GetForm = FALSE;
+ }
+ break;
+
+ case EFI_IFR_GUID_OP :
+ if (!GetFormSet || !GetForm) {
+ //
+ // Go to the next Op-Code
+ //
+ break;
+ }
+
+ if (!EfiCompareGuid (&((EFI_IFR_GUID *) IfrOpHdr)->Guid, &mIfrVendorGuid)) {
+ //
+ // GUID mismatch, skip this op-code
+ //
+ break;
+ }
+
+ 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
+ //
+ break;
+ }
+
+ if (Insert) {
+ //
+ // Insert data after current Label, skip myself
+ //
+ Offset += IfrOpHdr->Length;
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);
+ } else {
+ //
+ // Replace data between two paired Label, try to find 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 (EfiCompareGuid (&((EFI_IFR_GUID *) IfrOpHdr)->Guid, &mIfrVendorGuid) && ExtendOpCode == EFI_IFR_EXTEND_OP_LABEL) {
+ break;
+ }
+ }
+ }
+ }
+
+ //
+ // Fill in the update data
+ //
+ if (Data != NULL) {
+ EfiCopyMem (BufferPos, Data->Data, Data->Offset);
+ BufferPos += Data->Offset;
+ *TempBufferSize += Data->Offset;
+ }
+
+ //
+ // Copy the reset data
+ //
+ EfiCopyMem (BufferPos, IfrOpHdr, PackageHeader.Length - Offset);
+ *TempBufferSize += PackageHeader.Length - Offset;
+
+ 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
+IfrLibInitUpdateData (
+ IN OUT EFI_HII_UPDATE_DATA *UpdateData,
+ IN UINT32 BufferSize
+ )
+/*++
+
+Routine Description:
+ This function initialize the data structure for dynamic opcode.
+
+Arguments:
+ UpdateData - The adding data;
+ BufferSize - Length of the buffer to fill dynamic opcodes.
+
+Returns:
+ EFI_SUCCESS - Update data is initialized.
+ EFI_INVALID_PARAMETER - UpdateData is NULL.
+ EFI_OUT_OF_RESOURCES - No enough memory to allocate.
+
+--*/
+{
+ if (UpdateData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ UpdateData->BufferSize = BufferSize;
+ UpdateData->Offset = 0;
+ UpdateData->Data = EfiLibAllocatePool (BufferSize);
+
+ return (UpdateData->Data != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
+}
+
+EFI_STATUS
+IfrLibFreeUpdateData (
+ IN EFI_HII_UPDATE_DATA *UpdateData
+ )
+/*++
+
+Routine Description:
+ This function free the resource of update data.
+
+Arguments:
+ UpdateData - The adding data;
+
+Returns:
+ EFI_SUCCESS - Resource in UpdateData is released.
+ EFI_INVALID_PARAMETER - UpdateData is NULL.
+
+--*/
+{
+ EFI_STATUS Status;
+
+ if (UpdateData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = gBS->FreePool (UpdateData->Data);
+ UpdateData->Data = NULL;
+
+ return Status;
+}
+
+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_FORMS) && !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;
+}
+
+EFI_STATUS
+ExtractBlockName (
+ IN UINT8 *Buffer,
+ OUT CHAR16 **BlockName
+ )
+/*++
+
+ Routine Description:
+
+ Extract block name from the array generated by VFR compiler. The name of
+ this array is "Vfr + <StorageName> + BlockName", e.g. "VfrMyIfrNVDataBlockName".
+ Format of this array is:
+ Array length | 4-bytes
+ Offset | 2-bytes
+ Width | 2-bytes
+ Offset | 2-bytes
+ Width | 2-bytes
+ ... ...
+
+ Arguments:
+ Buffer - Array generated by VFR compiler.
+ BlockName - The returned <BlockName>
+
+ Returns:
+ EFI_OUT_OF_RESOURCES - Run out of memory resource.
+ EFI_INVALID_PARAMETER - Buffer is NULL or BlockName is NULL.
+ EFI_SUCCESS - Operation successful.
+
+--*/
+{
+ UINTN Index;
+ UINT32 Length;
+ UINT32 BlockNameNumber;
+ UINTN HexStringBufferLen;
+ CHAR16 *StringPtr;
+
+ if ((Buffer == NULL) || (BlockName == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Calculate number of Offset/Width pair
+ //
+ EfiCopyMem (&Length, Buffer, sizeof (UINT32));
+ BlockNameNumber = (Length - sizeof (UINT32)) / (sizeof (UINT16) * 2);
+
+ //
+ // <BlockName> ::= &OFFSET=1234&WIDTH=1234
+ // | 8 | 4 | 7 | 4 |
+ //
+ StringPtr = EfiLibAllocateZeroPool ((BlockNameNumber * (8 + 4 + 7 + 4) + 1) * sizeof (CHAR16));
+ *BlockName = StringPtr;
+ if (StringPtr == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Buffer += sizeof (UINT32);
+ for (Index = 0; Index < BlockNameNumber; Index++) {
+ EfiStrCpy (StringPtr, L"&OFFSET=");
+ StringPtr += 8;
+
+ HexStringBufferLen = 5;
+ BufToHexString (StringPtr, &HexStringBufferLen, Buffer, sizeof (UINT16));
+ Buffer += sizeof (UINT16);
+ StringPtr += 4;
+
+ EfiStrCpy (StringPtr, L"&WIDTH=");
+ StringPtr += 7;
+
+ HexStringBufferLen = 5;
+ BufToHexString (StringPtr, &HexStringBufferLen, Buffer, sizeof (UINT16));
+ Buffer += sizeof (UINT16);
+ StringPtr += 4;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ExtractBlockConfig (
+ IN UINT8 *Buffer,
+ OUT CHAR16 **BlockConfig
+ )
+/*++
+
+ Routine Description:
+
+ Extract block config from the array generated by VFR compiler. The name of
+ this array is "Vfr + <StorageName> + Default<HexCh>4", e.g. "VfrMyIfrNVDataDefault0000".
+
+ Arguments:
+ Buffer - Array generated by VFR compiler.
+ BlockConfig - The returned <BlockConfig>
+
+ Returns:
+ EFI_OUT_OF_RESOURCES - Run out of memory resource.
+ EFI_INVALID_PARAMETER - Buffer is NULL or BlockConfig is NULL.
+ EFI_SUCCESS - Operation successful.
+
+--*/
+{
+ UINT32 Length;
+ UINT16 Width;
+ UINTN HexStringBufferLen;
+ CHAR16 *StringPtr;
+ UINT8 *BufferEnd;
+ CHAR16 *StringEnd;
+ EFI_STATUS Status;
+
+ if ((Buffer == NULL) || (BlockConfig == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Calculate length of AltResp string
+ // Format of Default value array is:
+ // Array length | 4-bytes
+ // Offset | 2-bytes
+ // Width | 2-bytes
+ // Value | Variable length
+ // Offset | 2-bytes
+ // Width | 2-bytes
+ // Value | Variable length
+ // ... ...
+ // When value is 1 byte in length, overhead of AltResp string will be maximum,
+ // BlockConfig ::= <&OFFSET=1234&WIDTH=1234&VALUE=12>+
+ // | 8 | 4 | 7 | 4 | 7 |2|
+ // so the maximum length of BlockConfig could be calculated as:
+ // (ArrayLength / 5) * (8 + 4 + 7 + 4 + 7 + 2) = ArrayLength * 6.4 < ArrayLength * 7
+ //
+ EfiCopyMem (&Length, Buffer, sizeof (UINT32));
+ BufferEnd = Buffer + Length;
+ StringPtr = EfiLibAllocatePool (Length * 7 * sizeof (CHAR16));
+ *BlockConfig = StringPtr;
+ if (StringPtr == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ StringEnd = StringPtr + (Length * 7);
+
+ Buffer += sizeof (UINT32);
+ while (Buffer < BufferEnd) {
+ EfiStrCpy (StringPtr, L"&OFFSET=");
+ StringPtr += 8;
+
+ HexStringBufferLen = 5;
+ BufToHexString (StringPtr, &HexStringBufferLen, Buffer, sizeof (UINT16));
+ Buffer += sizeof (UINT16);
+ StringPtr += 4;
+
+ EfiStrCpy (StringPtr, L"&WIDTH=");
+ StringPtr += 7;
+
+ HexStringBufferLen = 5;
+ BufToHexString (StringPtr, &HexStringBufferLen, Buffer, sizeof (UINT16));
+ EfiCopyMem (&Width, Buffer, sizeof (UINT16));
+ Buffer += sizeof (UINT16);
+ StringPtr += 4;
+
+ EfiStrCpy (StringPtr, L"&VALUE=");
+ StringPtr += 7;
+
+ HexStringBufferLen = StringEnd - StringPtr;
+ Status = BufToHexString (StringPtr, &HexStringBufferLen, Buffer, Width);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Buffer += Width;
+ StringPtr += (Width * 2);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ConstructConfigAltResp (
+ IN EFI_STRING ConfigRequest, OPTIONAL
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *ConfigAltResp,
+ IN EFI_GUID *Guid,
+ IN CHAR16 *Name,
+ IN EFI_HANDLE *DriverHandle,
+ IN VOID *BufferStorage,
+ IN UINTN BufferStorageSize,
+ IN VOID *BlockNameArray, OPTIONAL
+ IN UINTN NumberAltCfg,
+ ...
+//IN UINT16 AltCfgId,
+//IN VOID *DefaultValueArray,
+ )
+/*++
+
+ Routine Description:
+
+ Construct <ConfigAltResp> for a buffer storage.
+
+ Arguments:
+ ConfigRequest - The Config request string. If set to NULL, all the
+ configurable elements will be extracted from BlockNameArray.
+ ConfigAltResp - The returned <ConfigAltResp>.
+ Progress - On return, points to a character in the Request.
+ Guid - GUID of the buffer storage.
+ Name - Name of the buffer storage.
+ DriverHandle - The DriverHandle which is used to invoke HiiDatabase
+ protocol interface NewPackageList().
+ BufferStorage - Content of the buffer storage.
+ BufferStorageSize - Length in bytes of the buffer storage.
+ BlockNameArray - Array generated by VFR compiler.
+ NumberAltCfg - Number of Default value array generated by VFR compiler.
+ The sequential input parameters will be number of
+ AltCfgId and DefaultValueArray pairs. When set to 0,
+ there will be no <AltResp>.
+
+ Returns:
+ EFI_OUT_OF_RESOURCES - Run out of memory resource.
+ EFI_INVALID_PARAMETER - ConfigAltResp is NULL.
+ EFI_SUCCESS - Operation successful.
+
+--*/
+{
+ EFI_STATUS Status;
+ CHAR16 *ConfigHdr;
+ CHAR16 *BlockName;
+ CHAR16 *DescHdr;
+ CHAR16 *StringPtr;
+ CHAR16 **AltCfg;
+ UINT16 AltCfgId;
+ VOID *DefaultValueArray;
+ UINTN StrBufferLen;
+ EFI_STRING ConfigResp;
+ EFI_STRING TempStr;
+ VA_LIST Args;
+ UINTN AltRespLen;
+ UINTN Index;
+ BOOLEAN NeedFreeConfigRequest;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+ if (ConfigAltResp == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Construct <ConfigHdr> : "GUID=...&NAME=...&PATH=..."
+ //
+ ConfigHdr = NULL;
+ StrBufferLen = 0;
+ Status = ConstructConfigHdr (
+ ConfigHdr,
+ &StrBufferLen,
+ Guid,
+ Name,
+ DriverHandle
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ ConfigHdr = EfiLibAllocateZeroPool (StrBufferLen);
+ Status = ConstructConfigHdr (
+ ConfigHdr,
+ &StrBufferLen,
+ Guid,
+ Name,
+ DriverHandle
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Construct <ConfigResp>
+ //
+ NeedFreeConfigRequest = FALSE;
+ if (ConfigRequest == NULL) {
+ //
+ // If ConfigRequest is set to NULL, export all configurable elements in BlockNameArray
+ //
+ Status = ExtractBlockName (BlockNameArray, &BlockName);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ConfigRequest = EfiLibAllocateZeroPool (EfiStrSize (ConfigHdr) + EfiStrSize (BlockName) - sizeof (CHAR16));
+ EfiStrCpy (ConfigRequest, ConfigHdr);
+ EfiStrCat (ConfigRequest, BlockName);
+ NeedFreeConfigRequest = TRUE;
+ }
+
+ Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, &HiiConfigRouting);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = HiiConfigRouting->BlockToConfig (
+ HiiConfigRouting,
+ ConfigRequest,
+ BufferStorage,
+ BufferStorageSize,
+ &ConfigResp,
+ (Progress == NULL) ? &TempStr : Progress
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Construct <AltResp>
+ //
+ DescHdr = EfiLibAllocateZeroPool (NumberAltCfg * 16 * sizeof (CHAR16));
+ StringPtr = DescHdr;
+ AltCfg = EfiLibAllocateZeroPool (NumberAltCfg * sizeof (CHAR16 *));
+ AltRespLen = 0;
+ VA_START (Args, NumberAltCfg);
+ for (Index = 0; Index < NumberAltCfg; Index++) {
+ AltCfgId = (UINT16) VA_ARG (Args, UINT16);
+ DefaultValueArray = (UINT8 *) VA_ARG (Args, VOID *);
+
+ //
+ // '&' <ConfigHdr>
+ //
+ AltRespLen += (EfiStrLen (ConfigHdr) + 1);
+
+ StringPtr = DescHdr + Index * 16;
+ EfiStrCpy (StringPtr, L"&ALTCFG=");
+ AltRespLen += (8 + sizeof (UINT16) * 2);
+
+ StrBufferLen = 5;
+ BufToHexString (StringPtr + 8, &StrBufferLen, (UINT8 *) &AltCfgId, sizeof (UINT16));
+ Status = ExtractBlockConfig (DefaultValueArray, &AltCfg[Index]);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ AltRespLen += EfiStrLen (AltCfg[Index]);
+ }
+ VA_END (Args);
+
+ //
+ // Generate the final <ConfigAltResp>
+ //
+ StrBufferLen = (EfiStrLen ((CHAR16 *) ConfigResp) + AltRespLen + 1) * sizeof (CHAR16);
+ TempStr = EfiLibAllocateZeroPool (StrBufferLen);
+ *ConfigAltResp = TempStr;
+ if (TempStr == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // <ConfigAltResp> ::= <ConfigResp> ['&' <AltResp>]*
+ //
+ EfiStrCpy (TempStr, ConfigResp);
+ for (Index = 0; Index < NumberAltCfg; Index++) {
+ EfiStrCat (TempStr, L"&");
+ EfiStrCat (TempStr, ConfigHdr);
+ EfiStrCat (TempStr, DescHdr + Index * 16);
+ EfiStrCat (TempStr, AltCfg[Index]);
+
+ gBS->FreePool (AltCfg[Index]);
+ }
+
+ if (NeedFreeConfigRequest) {
+ gBS->FreePool (ConfigRequest);
+ }
+ gBS->FreePool (ConfigHdr);
+ gBS->FreePool (ConfigResp);
+ gBS->FreePool (DescHdr);
+ gBS->FreePool (AltCfg);
+
+ 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 / 2;
+ for (Index = 0; Index < SwapCount; Index++) {
+ Temp = Buffer[Index];
+ Buffer[Index] = Buffer[BufferSize - 1 - Index];
+ Buffer[BufferSize - 1 - Index] = Temp;
+ }
+}
+
+VOID
+ToLower (
+ IN OUT CHAR16 *Str
+ )
+/*++
+
+Routine Description:
+ Converts the unicode character of the string from uppercase to lowercase.
+
+Arguments:
+ Str - String to be converted
+
+Returns:
+
+--*/
+{
+ CHAR16 *Ptr;
+
+ for (Ptr = Str; *Ptr != L'\0'; Ptr++) {
+ if (*Ptr >= L'A' && *Ptr <= L'Z') {
+ *Ptr = (CHAR16) (*Ptr - L'A' + L'a');
+ }
+ }
+}
+
+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 * 2 + 1;
+ Status = BufToHexString (Str, &StrBufferLen, NewBuffer, BufferSize);
+
+ gBS->FreePool (NewBuffer);
+ //
+ // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.
+ //
+ ToLower (Str);
+
+ 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 + 1) / 2);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+ConfigStringToUnicode (
+ IN OUT CHAR16 *UnicodeString,
+ IN OUT UINTN *StrBufferLen,
+ IN CHAR16 *ConfigString
+ )
+/*++
+
+Routine Description:
+ Convert binary representation Config string (e.g. "0041004200430044") to the
+ original string (e.g. "ABCD"). Config string appears in <ConfigHdr> (i.e.
+ "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>").
+
+Arguments:
+ UnicodeString - Original Unicode string.
+ StrBufferLen - On input: Length in bytes of buffer to hold the Unicode string.
+ Includes tailing '\0' character.
+ On output:
+ If return EFI_SUCCESS, containing length of Unicode string buffer.
+ If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
+ ConfigString - Binary representation of Unicode String, <string> := (<HexCh>4)+
+
+Returns:
+ EFI_SUCCESS - Routine success.
+ EFI_BUFFER_TOO_SMALL - The string buffer is too small.
+
+--*/
+{
+ UINTN Index;
+ UINTN Len;
+ UINTN BufferSize;
+ CHAR16 BackupChar;
+
+ Len = EfiStrLen (ConfigString) / 4;
+ BufferSize = (Len + 1) * sizeof (CHAR16);
+
+ if (*StrBufferLen < BufferSize) {
+ *StrBufferLen = BufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *StrBufferLen = BufferSize;
+
+ for (Index = 0; Index < Len; Index++) {
+ BackupChar = ConfigString[4];
+ ConfigString[4] = L'\0';
+
+ HexStringToBuf ((UINT8 *) UnicodeString, &BufferSize, ConfigString, NULL);
+
+ ConfigString[4] = BackupChar;
+
+ ConfigString += 4;
+ UnicodeString += 1;
+ }
+
+ //
+ // Add tailing '\0' character
+ //
+ *UnicodeString = L'\0';
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+UnicodeToConfigString (
+ IN OUT CHAR16 *ConfigString,
+ IN OUT UINTN *StrBufferLen,
+ IN CHAR16 *UnicodeString
+ )
+/*++
+
+Routine Description:
+ Convert Unicode string to binary representation Config string, e.g.
+ "ABCD" => "0041004200430044". Config string appears in <ConfigHdr> (i.e.
+ "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>").
+
+Arguments:
+ ConfigString - Binary representation of Unicode String, <string> := (<HexCh>4)+
+ StrBufferLen - On input: Length in bytes of buffer to hold the Unicode string.
+ Includes tailing '\0' character.
+ On output:
+ If return EFI_SUCCESS, containing length of Unicode string buffer.
+ If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
+ UnicodeString - Original Unicode string.
+
+Returns:
+ EFI_SUCCESS - Routine success.
+ EFI_BUFFER_TOO_SMALL - The string buffer is too small.
+
+--*/
+{
+ UINTN Index;
+ UINTN Len;
+ UINTN BufferSize;
+ CHAR16 *String;
+
+ Len = EfiStrLen (UnicodeString);
+ BufferSize = (Len * 4 + 1) * sizeof (CHAR16);
+
+ if (*StrBufferLen < BufferSize) {
+ *StrBufferLen = BufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *StrBufferLen = BufferSize;
+ String = ConfigString;
+
+ for (Index = 0; Index < Len; Index++) {
+ BufToHexString (ConfigString, &BufferSize, (UINT8 *) UnicodeString, 2);
+
+ ConfigString += 4;
+ UnicodeString += 1;
+ }
+
+ //
+ // Add tailing '\0' character
+ //
+ *ConfigString = L'\0';
+
+ //
+ // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.
+ //
+ ToLower (String);
+ return EFI_SUCCESS;
+}
+
+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=<Char>NameStrLen&PATH=<HexChar>DevicePathStrLen <NULL>
+ // | 5 | 32 | 6 | NameStrLen*4 | 6 | DevicePathStrLen | 1 |
+ //
+ BufferSize = (5 + 32 + 6 + NameStrLen * 4 + 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;
+
+ //
+ // Convert name string, e.g. name "ABCD" => "&NAME=0041004200430044"
+ //
+ EfiStrCpy (StrPtr, L"&NAME=");
+ StrPtr += 6;
+ if (Name != NULL) {
+ BufferSize = (NameStrLen * 4 + 1) * sizeof (CHAR16);
+ UnicodeToConfigString (StrPtr, &BufferSize, Name);
+ StrPtr += (NameStrLen * 4);
+ }
+
+ EfiStrCpy (StrPtr, L"&PATH=");
+ StrPtr += 6;
+ BufferToHexString (StrPtr, (UINT8 *) DevicePath, DevicePathSize);
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+IsConfigHdrMatch (
+ IN EFI_STRING ConfigString,
+ IN EFI_GUID *StorageGuid, OPTIONAL
+ IN CHAR16 *StorageName OPTIONAL
+ )
+/*++
+
+Routine Description:
+ Determines if the Routing data (Guid and Name) is correct in <ConfigHdr>.
+
+Arguments:
+ ConfigString - Either <ConfigRequest> or <ConfigResp>.
+ StorageGuid - GUID of the storage.
+ StorageName - Name of the stoarge.
+
+Returns:
+ TRUE - Routing information is correct in ConfigString.
+ FALSE - Routing information is incorrect in ConfigString.
+
+--*/
+{
+ EFI_STATUS Status;
+ BOOLEAN Match;
+ EFI_GUID Guid;
+ CHAR16 *Name;
+ CHAR16 *StrPtr;
+ UINTN BufferSize;
+
+ //
+ // <ConfigHdr> ::=
+ // GUID=<HexCh>32&NAME=<Char>NameStrLen&PATH=<HexChar>DevicePathStrLen <NULL>
+ // | 5 | 32 | 6 | NameStrLen*4 | 6 | DevicePathStrLen | 1 |
+ //
+ if (EfiStrLen (ConfigString) <= (5 + 32 + 6)) {
+ return FALSE;
+ }
+
+ //
+ // Compare GUID
+ //
+ if (StorageGuid != NULL) {
+
+ StrPtr = ConfigString + 5 + 32;
+ if (*StrPtr != L'&') {
+ return FALSE;
+ }
+ *StrPtr = L'\0';
+
+ BufferSize = sizeof (EFI_GUID);
+ Status = HexStringToBuffer (
+ (UINT8 *) &Guid,
+ &BufferSize,
+ ConfigString + 5
+ );
+ *StrPtr = L'&';
+
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ if (!EfiCompareGuid (&Guid, StorageGuid)) {
+ return FALSE;
+ }
+ }
+
+ //
+ // Compare Name
+ //
+ Match = TRUE;
+ if (StorageName != NULL) {
+ StrPtr = ConfigString + 5 + 32 + 6;
+ while (*StrPtr != L'\0' && *StrPtr != L'&') {
+ StrPtr++;
+ }
+ if (*StrPtr != L'&') {
+ return FALSE;
+ }
+
+ *StrPtr = L'\0';
+ BufferSize = (((UINTN) StrPtr) - ((UINTN) &ConfigString[5 + 32 + 6])) / 4 + sizeof (CHAR16);
+ Name = EfiLibAllocatePool (BufferSize);
+ ASSERT (Name != NULL);
+ Status = ConfigStringToUnicode (
+ Name,
+ &BufferSize,
+ ConfigString + 5 + 32 + 6
+ );
+ *StrPtr = L'&';
+
+ if (EFI_ERROR (Status) || (EfiStrCmp (Name, StorageName) != 0)) {
+ Match = FALSE;
+ }
+ gBS->FreePool (Name);
+ }
+
+ return Match;
+}
+
+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 + 1) * sizeof (CHAR16));
+
+ 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 + 1) * sizeof (CHAR16));
+
+ 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 (ConfigRequest);
+ return Status;
+ }
+
+ //
+ // Skip <ConfigHdr> and '&'
+ //
+ StringPtr = ConfigResp + HeaderLen + 1;
+
+ //
+ // Change uncommitted data in Browser
+ //
+ Status = FormBrowser2->BrowserCallback (
+ FormBrowser2,
+ &BufferSize,
+ StringPtr,
+ FALSE,
+ VariableGuid,
+ VariableName
+ );
+ gBS->FreePool (ConfigResp);
+ gBS->FreePool (ConfigRequest);
+ return Status;
+}
+
+BOOLEAN
+HiiSetToDefaults (
+ IN CONST EFI_STRING Request, OPTIONAL
+ IN UINT16 DefaultId
+ )
+/*++
+
+Routine Description:
+ Reset the default value specified by DefaultId to the driver
+ configuration got by Request string.
+
+ NULL request string support depends on the ExportConfig interface of
+ HiiConfigRouting protocol in UEFI specification.
+
+Arguments:
+ Request - A null-terminated Unicode string in
+ <MultiConfigRequest> format. It can be NULL.
+ If it is NULL, all configuration for the
+ entirety of the current HII database will be reset.
+ DefaultId - Specifies the type of defaults to retrieve.
+
+Returns:
+ TURE - The default value is set successfully.
+ FALSE - The default value can't be found and set.
+
+--*/
+{
+ EFI_STRING ConfigAltResp;
+ EFI_STRING ConfigAltHdr;
+ EFI_STRING ConfigResp;
+ EFI_STRING Progress;
+ EFI_STRING StringPtr;
+ EFI_STRING StringHdr;
+ EFI_STRING CurString;
+ EFI_STATUS Status;
+ EFI_HII_HANDLE HiiHandle;
+ CHAR16 OrigChar;
+ UINT32 Index;
+ EFI_GUID *VarGuid;
+ EFI_STRING VarName;
+ EFI_STRING_ID DefaultName;
+ UINTN BufferSize;
+ UINT8 *PackageData;
+ UINTN IfrOffset;
+ EFI_IFR_OP_HEADER *IfrOpHdr;
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
+ UINT32 PackageOffset;
+ UINTN PackageListLength;
+ EFI_HII_PACKAGE_HEADER PacakgeHeader;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+ DEBUG ((EFI_D_ERROR, "HiiSetToDefaults - enter\n"));
+
+ Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ LocateHiiProtocols ();
+
+ ConfigAltResp = NULL;
+ ConfigResp = NULL;
+ VarGuid = NULL;
+ VarName = NULL;
+ DevicePath = NULL;
+ ConfigAltHdr = NULL;
+ CurString = NULL;
+ Index = 0;
+ BufferSize = 0;
+ OrigChar = 0;
+ HiiHandle = NULL;
+ PackageData = NULL;
+ HiiPackageList = NULL;
+
+ //
+ // Get the full requested value and deault value string.
+ //
+ if (Request != NULL) {
+ Status = HiiConfigRouting->ExtractConfig (
+ HiiConfigRouting,
+ Request,
+ &Progress,
+ &ConfigAltResp
+ );
+ } else {
+ Status = HiiConfigRouting->ExportConfig (
+ HiiConfigRouting,
+ &ConfigAltResp
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ DEBUG ((EFI_D_ERROR, "HiiSetToDefaults - start\n"));
+ StringPtr = ConfigAltResp;
+
+ while (StringPtr != L'\0') {
+ //
+ // 1. Find <ConfigHdr> GUID=...&NAME=...&PATH=...
+ //
+ StringHdr = StringPtr;
+
+ if (EfiStrnCmp (StringPtr, L"GUID=", (sizeof(L"GUID=")/sizeof(CHAR16)) - 1) != 0) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+ StringPtr += (sizeof(L"GUID=")/sizeof(CHAR16)) - 1;
+ CurString = StringPtr;
+ while (*StringPtr != L'\0' && EfiStrnCmp (StringPtr, L"&NAME=", (sizeof(L"&NAME=")/sizeof(CHAR16)) - 1) != 0) {
+ StringPtr++;
+ }
+ if (*StringPtr == L'\0') {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ //
+ // Get Guid value
+ //
+ BufferSize = sizeof (EFI_GUID);
+ VarGuid = EfiLibAllocatePool (BufferSize);
+ OrigChar = *StringPtr;
+ *StringPtr = L'\0';
+ Status = HexStringToBuffer ((UINT8 *) VarGuid, &BufferSize, CurString);
+ *StringPtr = OrigChar;
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Get Name value VarName
+ //
+ StringPtr += (sizeof(L"&NAME=")/sizeof(CHAR16)) - 1;
+ CurString = StringPtr;
+ while (*StringPtr != L'\0' && EfiStrnCmp (StringPtr, L"&PATH=", (sizeof(L"&PATH=")/sizeof(CHAR16)) - 1) != 0) {
+ StringPtr++;
+ }
+ if (*StringPtr == L'\0') {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+ OrigChar = *StringPtr;
+ *StringPtr = L'\0';
+ BufferSize = 0;
+ Status = ConfigStringToUnicode (VarName, &BufferSize, CurString);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ VarName = EfiLibAllocatePool (BufferSize);
+ Status = ConfigStringToUnicode (VarName, &BufferSize, CurString);
+ }
+ *StringPtr = OrigChar;
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Get Path value DevicePath
+ //
+ StringPtr += (sizeof(L"&PATH=")/sizeof(CHAR16)) - 1;
+ CurString = StringPtr;
+ for (; *StringPtr != L'\0' && *StringPtr != L'&'; StringPtr++);
+ OrigChar = *StringPtr;
+ *StringPtr = L'\0';
+ Status = HexStringToBuffer ((UINT8 *) DevicePath, &BufferSize, CurString);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ DevicePath = EfiLibAllocatePool (BufferSize);
+ Status = HexStringToBuffer ((UINT8 *) DevicePath, &BufferSize, CurString);
+ }
+ *StringPtr = OrigChar;
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Get the Driver handle by the got device path.
+ //
+ HiiHandle = DevicePathToHiiHandle (gIfrLibHiiDatabase, DevicePath);
+ if (HiiHandle == NULL) {
+ //
+ // This request string has no its Hii package.
+ // Its default value and validating can't execute by parsing IFR data.
+ // Directly jump into the next ConfigAltResp string for another pair Guid, Name, and Path.
+ //
+ Status = EFI_SUCCESS;
+ goto NextConfigAltResp;
+ }
+
+ //
+ // 2. Get DefaultName string ID by parsing the PacakgeList
+ //
+
+ //
+ // Get HiiPackage by HiiHandle
+ //
+ PackageListLength = 0;
+ HiiPackageList = NULL;
+ Status = gIfrLibHiiDatabase->ExportPackageLists (gIfrLibHiiDatabase, HiiHandle, &PackageListLength, HiiPackageList);
+
+ //
+ // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0.
+ //
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ HiiPackageList = EfiLibAllocatePool (PackageListLength);
+ if (HiiPackageList == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ //
+ // Get PackageList on HiiHandle
+ //
+ Status = gIfrLibHiiDatabase->ExportPackageLists (gIfrLibHiiDatabase, HiiHandle, &PackageListLength, HiiPackageList);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Parse the form package and get the default name string ID.
+ //
+ PackageOffset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
+ Status = EFI_NOT_FOUND;
+ while (PackageOffset < PackageListLength) {
+ EfiCopyMem (&PacakgeHeader, (UINT8 *) HiiPackageList + PackageOffset, sizeof (PacakgeHeader));
+
+ //
+ // Parse IFR opcode to get default store opcode
+ //
+ if (PacakgeHeader.Type == EFI_HII_PACKAGE_FORMS) {
+ IfrOffset = sizeof (PacakgeHeader);
+ PackageData = (UINT8 *) HiiPackageList + PackageOffset;
+ while (IfrOffset < PacakgeHeader.Length) {
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) (PackageData + IfrOffset);
+ //
+ // Match DefaultId to find its DefaultName
+ //
+ if (IfrOpHdr->OpCode == EFI_IFR_DEFAULTSTORE_OP) {
+ if (((EFI_IFR_DEFAULTSTORE *) IfrOpHdr)->DefaultId == DefaultId) {
+ DefaultName = ((EFI_IFR_DEFAULTSTORE *) IfrOpHdr)->DefaultName;
+ Status = EFI_SUCCESS;
+ break;
+ }
+ }
+ IfrOffset += IfrOpHdr->Length;
+ }
+ //
+ // Only one form is in a package list.
+ //
+ break;
+ }
+
+ //
+ // Go to next package.
+ //
+ PackageOffset += PacakgeHeader.Length;
+ }
+
+ //
+ // Not found the matched default string ID
+ //
+ if (EFI_ERROR (Status)) {
+ Status = EFI_SUCCESS;
+ goto NextConfigAltResp;
+ }
+
+ //
+ // 3. Call ConfigRouting GetAltCfg(ConfigRoute, <ConfigResponse>, Guid, Name, DevicePath, AltCfgId, AltCfgResp)
+ // Get the default configuration string according to the found default name string ID.
+ //
+ Status = HiiConfigRouting->GetAltConfig (
+ HiiConfigRouting,
+ ConfigAltResp,
+ VarGuid,
+ VarName,
+ DevicePath,
+ &DefaultName, // it can be NULL to get the current setting.
+ &ConfigResp
+ );
+
+ //
+ // The required setting can't be found. So, it is not required to be validated and set.
+ //
+ if (EFI_ERROR (Status)) {
+ Status = EFI_SUCCESS;
+ goto NextConfigAltResp;
+ }
+ //
+ // Only the ConfigHdr is found. Not any block data is found. No data is required to be validated and set.
+ //
+ if (EfiStrStr (ConfigResp, L"&OFFSET=") == NULL) {
+ goto NextConfigAltResp;
+ }
+
+ //
+ // 4. Set the default configuration information or Validate current setting by parse IFR code.
+ // Current Setting is in ConfigResp, will be set into buffer, then check it again.
+ //
+ //
+ // Set the default configuration information.
+ //
+ Status = HiiConfigRouting->RouteConfig (HiiConfigRouting, ConfigResp, &Progress);
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+NextConfigAltResp:
+ //
+ // Free the allocated pacakge buffer and the got ConfigResp string.
+ //
+ if (HiiPackageList != NULL) {
+ gBS->FreePool (HiiPackageList);
+ HiiPackageList = NULL;
+ }
+
+ if (ConfigResp != NULL) {
+ gBS->FreePool (ConfigResp);
+ ConfigResp = NULL;
+ }
+
+ //
+ // Free the allocated buffer.
+ //
+ gBS->FreePool (VarGuid);
+ VarGuid = NULL;
+
+ gBS->FreePool (VarName);
+ VarName = NULL;
+
+ gBS->FreePool (DevicePath);
+ DevicePath = NULL;
+
+ //
+ // 5. Jump to next ConfigAltResp for another Guid, Name, Path.
+ //
+
+ //
+ // Get and Skip ConfigHdr
+ //
+ while (*StringPtr != L'\0' && *StringPtr != L'&') {
+ StringPtr++;
+ }
+ if (*StringPtr == L'\0') {
+ break;
+ }
+
+ //
+ // Construct ConfigAltHdr string "&<ConfigHdr>&ALTCFG=\0"
+ // | 1 | EfiStrLen (ConfigHdr) | 8 | 1 |
+ //
+ ConfigAltHdr = EfiLibAllocateZeroPool ((1 + StringPtr - StringHdr + 8 + 1) * sizeof (CHAR16));
+ if (ConfigAltHdr == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ EfiStrCpy (ConfigAltHdr, L"&");
+ EfiStrnCat (ConfigAltHdr, StringHdr, StringPtr - StringHdr);
+ EfiStrCat (ConfigAltHdr, L"&ALTCFG=");
+
+ //
+ // Skip all AltResp (AltConfigHdr ConfigBody) for the same ConfigHdr
+ //
+ while ((StringHdr = EfiStrStr (StringPtr, ConfigAltHdr)) != NULL) {
+ StringPtr = StringHdr + EfiStrLen (ConfigAltHdr);
+ if (*StringPtr == L'\0') {
+ break;
+ }
+ }
+
+ //
+ // Free the allocated ConfigAltHdr string
+ //
+ gBS->FreePool (ConfigAltHdr);
+ if (*StringPtr == L'\0') {
+ break;
+ }
+
+ //
+ // Find &GUID as the next ConfigHdr
+ //
+ StringPtr = EfiStrStr (StringPtr, L"&GUID");
+ if (StringPtr == NULL) {
+ break;
+ }
+
+ //
+ // Skip char '&'
+ //
+ StringPtr ++;
+ }
+ DEBUG ((EFI_D_ERROR, "HiiSetToDefaults - end\n"));
+
+Done:
+ if (VarGuid != NULL) {
+ gBS->FreePool (VarGuid);
+ }
+
+ if (VarName != NULL) {
+ gBS->FreePool (VarName);
+ }
+
+ if (DevicePath != NULL) {
+ gBS->FreePool (DevicePath);
+ }
+
+ if (ConfigResp != NULL) {
+ gBS->FreePool (ConfigResp);
+ }
+
+ if (ConfigAltResp != NULL) {
+ gBS->FreePool (ConfigAltResp);
+ }
+
+ if (HiiPackageList != NULL) {
+ gBS->FreePool (HiiPackageList);
+ }
+
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrLibrary.h b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrLibrary.h
new file mode 100644
index 0000000..3baf851
--- /dev/null
+++ b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrLibrary.h
@@ -0,0 +1,1370 @@
+/*++
+
+Copyright (c) 2007 - 2008, 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()
+
+#pragma pack(1)
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ UINT32 Reserved;
+ UINT64 UniqueId;
+} HII_VENDOR_DEVICE_PATH_NODE;
+#pragma pack()
+
+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
+ConstructConfigAltResp (
+ IN EFI_STRING ConfigRequest, OPTIONAL
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *ConfigAltResp,
+ IN EFI_GUID *Guid,
+ IN CHAR16 *Name,
+ IN EFI_HANDLE *DriverHandle,
+ IN VOID *BufferStorage,
+ IN UINTN BufferStorageSize,
+ IN VOID *BlockNameArray, OPTIONAL
+ IN UINTN NumberAltCfg,
+ ...
+//IN UINT16 AltCfgId,
+//IN VOID *DefaultValueArray,
+ )
+/*++
+
+ Routine Description:
+
+ Construct <ConfigAltResp> for a buffer storage.
+
+ Arguments:
+ ConfigRequest - The Config request string. If set to NULL, all the
+ configurable elements will be extracted from BlockNameArray.
+ ConfigAltResp - The returned <ConfigAltResp>.
+ Progress - On return, points to a character in the Request.
+ Guid - GUID of the buffer storage.
+ Name - Name of the buffer storage.
+ DriverHandle - The DriverHandle which is used to invoke HiiDatabase
+ protocol interface NewPackageList().
+ BufferStorage - Content of the buffer storage.
+ BufferStorageSize - Length in bytes of the buffer storage.
+ BlockNameArray - Array generated by VFR compiler.
+ NumberAltCfg - Number of Default value array generated by VFR compiler.
+ The sequential input parameters will be number of
+ AltCfgId and DefaultValueArray pairs. When set to 0,
+ there will be no <AltResp>.
+
+ Returns:
+ EFI_OUT_OF_RESOURCES - Run out of memory resource.
+ EFI_INVALID_PARAMETER - ConfigAltResp is NULL.
+ 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
+ExtractClassGuidFromHiiHandle (
+ IN EFI_HII_HANDLE Handle,
+ OUT UINT8 *NumberOfClassGuid,
+ OUT EFI_GUID **ClassGuid,
+ OUT EFI_STRING_ID *FormSetTitle,
+ OUT EFI_STRING_ID *FormSetHelp
+ )
+/*++
+
+Routine Description:
+ Extract formset ClassGuid for given HII handle.
+
+Arguments:
+ HiiHandle - Hii handle
+ NumberOfClassGuid - Number of ClassGuid
+ ClassGuid - Pointer to callee allocated buffer, an array of ClassGuid
+ FormSetTitle - Formset title string
+ FormSetHelp - Formset help string
+
+Returns:
+ EFI_SUCCESS - Successfully extract Class for specified Hii handle.
+
+--*/
+;
+
+VOID
+ToLower (
+ IN OUT CHAR16 *Str
+ )
+/*++
+
+Routine Description:
+ Converts the unicode character from uppercase to lowercase.
+
+Arguments:
+ Str - String to be converted
+
+Returns:
+
+--*/
+;
+
+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
+ConfigStringToUnicode (
+ IN OUT CHAR16 *UnicodeString,
+ IN OUT UINTN *StrBufferLen,
+ IN CHAR16 *ConfigString
+ )
+/*++
+
+Routine Description:
+ Convert binary representation Config string (e.g. "0041004200430044") to the
+ original string (e.g. "ABCD"). Config string appears in <ConfigHdr> (i.e.
+ "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>").
+
+Arguments:
+ UnicodeString - Original Unicode string.
+ StrBufferLen - On input: Length in bytes of buffer to hold the Unicode string.
+ Includes tailing '\0' character.
+ On output:
+ If return EFI_SUCCESS, containing length of Unicode string buffer.
+ If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
+ ConfigString - Binary representation of Unicode String, <string> := (<HexCh>4)+
+
+Returns:
+ EFI_SUCCESS - Routine success.
+ EFI_BUFFER_TOO_SMALL - The string buffer is too small.
+
+--*/
+;
+
+EFI_STATUS
+UnicodeToConfigString (
+ IN OUT CHAR16 *ConfigString,
+ IN OUT UINTN *StrBufferLen,
+ IN CHAR16 *UnicodeString
+ )
+/*++
+
+Routine Description:
+ Convert Unicode string to binary representation Config string, e.g.
+ "ABCD" => "0041004200430044". Config string appears in <ConfigHdr> (i.e.
+ "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>").
+
+Arguments:
+ ConfigString - Binary representation of Unicode String, <string> := (<HexCh>4)+
+ StrBufferLen - On input: Length in bytes of buffer to hold the Unicode string.
+ Includes tailing '\0' character.
+ On output:
+ If return EFI_SUCCESS, containing length of Unicode string buffer.
+ If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
+ UnicodeString - Original Unicode string.
+
+Returns:
+ EFI_SUCCESS - Routine success.
+ EFI_BUFFER_TOO_SMALL - The string buffer is too small.
+
+--*/
+;
+
+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
+IsConfigHdrMatch (
+ IN EFI_STRING ConfigString,
+ IN EFI_GUID *StorageGuid, OPTIONAL
+ IN CHAR16 *StorageName OPTIONAL
+ )
+/*++
+
+Routine Description:
+ Determines if the Routing data (Guid and Name) is correct in <ConfigHdr>.
+
+Arguments:
+ ConfigString - Either <ConfigRequest> or <ConfigResp>.
+ StorageGuid - GUID of the storage.
+ StorageName - Name of the stoarge.
+
+Returns:
+ TRUE - Routing information is correct in ConfigString.
+ FALSE - Routing information is incorrect in ConfigString.
+
+--*/
+;
+
+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
+IfrLibInitUpdateData (
+ IN OUT EFI_HII_UPDATE_DATA *UpdateData,
+ IN UINT32 BufferSize
+ )
+/*++
+
+Routine Description:
+ This function initialize the data structure for dynamic opcode.
+
+Arguments:
+ UpdateData - The adding data;
+ BufferSize - Length of the buffer to fill dynamic opcodes.
+
+Returns:
+ EFI_SUCCESS - Update data is initialized.
+ EFI_INVALID_PARAMETER - UpdateData is NULL.
+ EFI_OUT_OF_RESOURCES - No enough memory to allocate.
+
+--*/
+;
+
+EFI_STATUS
+IfrLibFreeUpdateData (
+ IN EFI_HII_UPDATE_DATA *UpdateData
+ )
+/*++
+
+Routine Description:
+ This function free the resource of update data.
+
+Arguments:
+ UpdateData - The adding data;
+
+Returns:
+ EFI_SUCCESS - Resource in UpdateData is released.
+ EFI_INVALID_PARAMETER - UpdateData is NULL.
+
+--*/
+;
+
+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.
+
+--*/
+;
+
+BOOLEAN
+HiiSetToDefaults (
+ IN CONST EFI_STRING Request, OPTIONAL
+ IN UINT16 DefaultId
+ )
+/*++
+
+Routine Description:
+ Reset the default value specified by DefaultId to the driver
+ configuration got by Request string.
+
+ NULL request string support depends on the ExportConfig interface of
+ HiiConfigRouting protocol in UEFI specification.
+
+Arguments:
+ Request - A null-terminated Unicode string in
+ <MultiConfigRequest> format. It can be NULL.
+ If it is NULL, all configuration for the
+ entirety of the current HII database will be reset.
+ DefaultId - Specifies the type of defaults to retrieve.
+
+Returns:
+ TURE - The default value is set successfully.
+ FALSE - The default value can't be found and set.
+
+--*/
+;
+#endif
diff --git a/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrOpCodeCreation.c b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrOpCodeCreation.c
new file mode 100644
index 0000000..e6b37b8
--- /dev/null
+++ b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrOpCodeCreation.c
@@ -0,0 +1,638 @@
+/*++
+
+Copyright (c) 2007 - 2009, 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 & (~(EFI_IFR_UNIQUE_SET | EFI_IFR_NO_EMPTY_SET))) != 0) {
+ 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/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrString.c b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrString.c
new file mode 100644
index 0000000..5341941
--- /dev/null
+++ b/EDK/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrString.c
@@ -0,0 +1,729 @@
+/*++
+
+Copyright (c) 2007 - 2011, 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 (HiiHandleBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ 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);
+ if (Languages == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+
+ if (StringId == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *StringId = 0;
+
+ LangStrings = Languages;
+ while (*LangStrings != 0) {
+ GetNextLanguage (&LangStrings, Lang);
+
+ if (*StringId == 0) {
+ Status = gIfrLibHiiString->NewString (
+ gIfrLibHiiString,
+ PackageList,
+ StringId,
+ Lang,
+ NULL,
+ String,
+ NULL
+ );
+ } else {
+ Status = gIfrLibHiiString->SetString (
+ gIfrLibHiiString,
+ PackageList,
+ *StringId,
+ Lang,
+ 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);
+ if (Languages == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ 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;
+}
+