diff options
Diffstat (limited to 'MdeModulePkg/Library/UefiHiiLib')
| -rw-r--r-- | MdeModulePkg/Library/UefiHiiLib/HiiLanguage.c | 176 | ||||
| -rw-r--r-- | MdeModulePkg/Library/UefiHiiLib/HiiLib.c | 9138 | ||||
| -rw-r--r-- | MdeModulePkg/Library/UefiHiiLib/HiiString.c | 790 | ||||
| -rw-r--r-- | MdeModulePkg/Library/UefiHiiLib/InternalHiiLib.h | 60 | ||||
| -rw-r--r-- | MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf | 100 | ||||
| -rw-r--r-- | MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.uni | 32 |
6 files changed, 5148 insertions, 5148 deletions
diff --git a/MdeModulePkg/Library/UefiHiiLib/HiiLanguage.c b/MdeModulePkg/Library/UefiHiiLib/HiiLanguage.c index 47f03d540d..470d2c7c15 100644 --- a/MdeModulePkg/Library/UefiHiiLib/HiiLanguage.c +++ b/MdeModulePkg/Library/UefiHiiLib/HiiLanguage.c @@ -1,88 +1,88 @@ -/** @file
- Language related HII Library implementation.
-
- Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "InternalHiiLib.h"
-
-/**
- Retrieves a pointer to the a Null-terminated ASCII string containing the list
- of languages that an HII handle in the HII Database supports. The returned
- string is allocated using AllocatePool(). The caller is responsible for freeing
- the returned string using FreePool(). The format of the returned string follows
- the language format assumed the HII Database.
-
- If HiiHandle is NULL, then ASSERT().
-
- @param[in] HiiHandle A handle that was previously registered in the HII Database.
-
- @retval NULL HiiHandle is not registered in the HII database
- @retval NULL There are not enough resources available to retrieve the supported
- languages.
- @retval NULL The list of supported languages could not be retrieved.
- @retval Other A pointer to the Null-terminated ASCII string of supported languages.
-
-**/
-CHAR8 *
-EFIAPI
-HiiGetSupportedLanguages (
- IN EFI_HII_HANDLE HiiHandle
- )
-{
- EFI_STATUS Status;
- UINTN LanguageSize;
- CHAR8 TempSupportedLanguages;
- CHAR8 *SupportedLanguages;
-
- ASSERT (HiiHandle != NULL);
-
- //
- // Retrieve the size required for the supported languages buffer.
- //
- LanguageSize = 0;
- Status = gHiiString->GetLanguages (gHiiString, HiiHandle, &TempSupportedLanguages, &LanguageSize);
-
- //
- // If GetLanguages() returns EFI_SUCCESS for a zero size,
- // then there are no supported languages registered for HiiHandle. If GetLanguages()
- // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
- // in the HII Database
- //
- if (Status != EFI_BUFFER_TOO_SMALL) {
- //
- // Return NULL if the size can not be retrieved, or if HiiHandle is not in the HII Database
- //
- return NULL;
- }
-
- //
- // Allocate the supported languages buffer.
- //
- SupportedLanguages = AllocateZeroPool (LanguageSize);
- if (SupportedLanguages == NULL) {
- //
- // Return NULL if allocation fails.
- //
- return NULL;
- }
-
- //
- // Retrieve the supported languages string
- //
- Status = gHiiString->GetLanguages (gHiiString, HiiHandle, SupportedLanguages, &LanguageSize);
- if (EFI_ERROR (Status)) {
- //
- // Free the buffer and return NULL if the supported languages can not be retrieved.
- //
- FreePool (SupportedLanguages);
- return NULL;
- }
-
- //
- // Return the Null-terminated ASCII string of supported languages
- //
- return SupportedLanguages;
-}
+/** @file + Language related HII Library implementation. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "InternalHiiLib.h" + +/** + Retrieves a pointer to the a Null-terminated ASCII string containing the list + of languages that an HII handle in the HII Database supports. The returned + string is allocated using AllocatePool(). The caller is responsible for freeing + the returned string using FreePool(). The format of the returned string follows + the language format assumed the HII Database. + + If HiiHandle is NULL, then ASSERT(). + + @param[in] HiiHandle A handle that was previously registered in the HII Database. + + @retval NULL HiiHandle is not registered in the HII database + @retval NULL There are not enough resources available to retrieve the supported + languages. + @retval NULL The list of supported languages could not be retrieved. + @retval Other A pointer to the Null-terminated ASCII string of supported languages. + +**/ +CHAR8 * +EFIAPI +HiiGetSupportedLanguages ( + IN EFI_HII_HANDLE HiiHandle + ) +{ + EFI_STATUS Status; + UINTN LanguageSize; + CHAR8 TempSupportedLanguages; + CHAR8 *SupportedLanguages; + + ASSERT (HiiHandle != NULL); + + // + // Retrieve the size required for the supported languages buffer. + // + LanguageSize = 0; + Status = gHiiString->GetLanguages (gHiiString, HiiHandle, &TempSupportedLanguages, &LanguageSize); + + // + // If GetLanguages() returns EFI_SUCCESS for a zero size, + // then there are no supported languages registered for HiiHandle. If GetLanguages() + // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present + // in the HII Database + // + if (Status != EFI_BUFFER_TOO_SMALL) { + // + // Return NULL if the size can not be retrieved, or if HiiHandle is not in the HII Database + // + return NULL; + } + + // + // Allocate the supported languages buffer. + // + SupportedLanguages = AllocateZeroPool (LanguageSize); + if (SupportedLanguages == NULL) { + // + // Return NULL if allocation fails. + // + return NULL; + } + + // + // Retrieve the supported languages string + // + Status = gHiiString->GetLanguages (gHiiString, HiiHandle, SupportedLanguages, &LanguageSize); + if (EFI_ERROR (Status)) { + // + // Free the buffer and return NULL if the supported languages can not be retrieved. + // + FreePool (SupportedLanguages); + return NULL; + } + + // + // Return the Null-terminated ASCII string of supported languages + // + return SupportedLanguages; +} diff --git a/MdeModulePkg/Library/UefiHiiLib/HiiLib.c b/MdeModulePkg/Library/UefiHiiLib/HiiLib.c index 63a37ab59a..6682eeee76 100644 --- a/MdeModulePkg/Library/UefiHiiLib/HiiLib.c +++ b/MdeModulePkg/Library/UefiHiiLib/HiiLib.c @@ -1,4569 +1,4569 @@ -/** @file
- HII Library implementation that uses DXE protocols and services.
-
- Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "InternalHiiLib.h"
-
-#define GUID_CONFIG_STRING_TYPE 0x00
-#define NAME_CONFIG_STRING_TYPE 0x01
-#define PATH_CONFIG_STRING_TYPE 0x02
-
-#define ACTION_SET_DEFAUTL_VALUE 0x01
-#define ACTION_VALIDATE_SETTING 0x02
-
-#define HII_LIB_DEFAULT_VARSTORE_SIZE 0x200
-
-typedef struct {
- LIST_ENTRY Entry; // Link to Block array
- UINT16 Offset;
- UINT16 Width;
- UINT8 OpCode;
- UINT8 Scope;
-} IFR_BLOCK_DATA;
-
-typedef struct {
- EFI_VARSTORE_ID VarStoreId;
- UINT16 Size;
-} IFR_VARSTORAGE_DATA;
-
-//
-// <ConfigHdr> Template
-//
-GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR16 mConfigHdrTemplate[] = L"GUID=00000000000000000000000000000000&NAME=0000&PATH=00";
-
-EFI_FORM_BROWSER2_PROTOCOL *mUefiFormBrowser2 = NULL;
-
-//
-// Template used to mark the end of a list of packages
-//
-GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_HII_PACKAGE_HEADER mEndOfPakageList = {
- sizeof (EFI_HII_PACKAGE_HEADER),
- EFI_HII_PACKAGE_END
-};
-
-/**
- Extract Hii package list GUID for given HII handle.
-
- If HiiHandle could not be found in the HII database, then ASSERT.
- If Guid is NULL, then ASSERT.
-
- @param Handle Hii handle
- @param Guid Package list GUID
-
- @retval EFI_SUCCESS Successfully extract GUID from Hii database.
-
-**/
-EFI_STATUS
-EFIAPI
-InternalHiiExtractGuidFromHiiHandle (
- IN EFI_HII_HANDLE Handle,
- OUT EFI_GUID *Guid
- )
-{
- EFI_STATUS Status;
- UINTN BufferSize;
- EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
-
- ASSERT (Guid != NULL);
- ASSERT (Handle != NULL);
-
- //
- // Get HII PackageList
- //
- BufferSize = 0;
- HiiPackageList = NULL;
-
- Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &BufferSize, HiiPackageList);
- ASSERT (Status != EFI_NOT_FOUND);
-
- if (Status == EFI_BUFFER_TOO_SMALL) {
- HiiPackageList = AllocatePool (BufferSize);
- ASSERT (HiiPackageList != NULL);
-
- Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &BufferSize, HiiPackageList);
- }
-
- if (EFI_ERROR (Status)) {
- FreePool (HiiPackageList);
- return Status;
- }
-
- //
- // Extract GUID
- //
- CopyGuid (Guid, &HiiPackageList->PackageListGuid);
-
- FreePool (HiiPackageList);
-
- return EFI_SUCCESS;
-}
-
-/**
- Registers a list of packages in the HII Database and returns the HII Handle
- associated with that registration. If an HII Handle has already been registered
- with the same PackageListGuid and DeviceHandle, then NULL is returned. If there
- are not enough resources to perform the registration, then NULL is returned.
- If an empty list of packages is passed in, then NULL is returned. If the size of
- the list of package is 0, then NULL is returned.
-
- The variable arguments are pointers which point to package header that defined
- by UEFI VFR compiler and StringGather tool.
-
- #pragma pack (push, 1)
- typedef struct {
- UINT32 BinaryLength;
- EFI_HII_PACKAGE_HEADER PackageHeader;
- } EDKII_AUTOGEN_PACKAGES_HEADER;
- #pragma pack (pop)
-
- @param[in] PackageListGuid The GUID of the package list.
- @param[in] DeviceHandle If not NULL, the Device Handle on which
- an instance of DEVICE_PATH_PROTOCOL is installed.
- This Device Handle uniquely defines the device that
- the added packages are associated with.
- @param[in] ... The variable argument list that contains pointers
- to packages terminated by a NULL.
-
- @retval NULL A HII Handle has already been registered in the HII Database with
- the same PackageListGuid and DeviceHandle.
- @retval NULL The HII Handle could not be created.
- @retval NULL An empty list of packages was passed in.
- @retval NULL All packages are empty.
- @retval Other The HII Handle associated with the newly registered package list.
-
-**/
-EFI_HII_HANDLE
-EFIAPI
-HiiAddPackages (
- IN CONST EFI_GUID *PackageListGuid,
- IN EFI_HANDLE DeviceHandle OPTIONAL,
- ...
- )
-{
- EFI_STATUS Status;
- VA_LIST Args;
- UINT32 *Package;
- EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;
- EFI_HII_HANDLE HiiHandle;
- UINT32 Length;
- UINT8 *Data;
-
- ASSERT (PackageListGuid != NULL);
-
- //
- // Calculate the length of all the packages in the variable argument list
- //
- for (Length = 0, VA_START (Args, DeviceHandle); (Package = VA_ARG (Args, UINT32 *)) != NULL; ) {
- Length += (ReadUnaligned32 (Package) - sizeof (UINT32));
- }
-
- VA_END (Args);
-
- //
- // If there are no packages in the variable argument list or all the packages
- // are empty, then return a NULL HII Handle
- //
- if (Length == 0) {
- return NULL;
- }
-
- //
- // Add the length of the Package List Header and the terminating Package Header
- //
- Length += sizeof (EFI_HII_PACKAGE_LIST_HEADER) + sizeof (EFI_HII_PACKAGE_HEADER);
-
- //
- // Allocate the storage for the entire Package List
- //
- PackageListHeader = AllocateZeroPool (Length);
-
- //
- // If the Package List can not be allocated, then return a NULL HII Handle
- //
- if (PackageListHeader == NULL) {
- return NULL;
- }
-
- //
- // Fill in the GUID and Length of the Package List Header
- //
- CopyGuid (&PackageListHeader->PackageListGuid, PackageListGuid);
- PackageListHeader->PackageLength = Length;
-
- //
- // Initialize a pointer to the beginning if the Package List data
- //
- Data = (UINT8 *)(PackageListHeader + 1);
-
- //
- // Copy the data from each package in the variable argument list
- //
- for (VA_START (Args, DeviceHandle); (Package = VA_ARG (Args, UINT32 *)) != NULL; ) {
- Length = ReadUnaligned32 (Package) - sizeof (UINT32);
- CopyMem (Data, Package + 1, Length);
- Data += Length;
- }
-
- VA_END (Args);
-
- //
- // Append a package of type EFI_HII_PACKAGE_END to mark the end of the package list
- //
- CopyMem (Data, &mEndOfPakageList, sizeof (mEndOfPakageList));
-
- //
- // Register the package list with the HII Database
- //
- Status = gHiiDatabase->NewPackageList (
- gHiiDatabase,
- PackageListHeader,
- DeviceHandle,
- &HiiHandle
- );
- if (EFI_ERROR (Status)) {
- HiiHandle = NULL;
- }
-
- //
- // Free the allocated package list
- //
- FreePool (PackageListHeader);
-
- //
- // Return the new HII Handle
- //
- return HiiHandle;
-}
-
-/**
- Removes a package list from the HII database.
-
- If HiiHandle is NULL, then ASSERT.
- If HiiHandle is not a valid EFI_HII_HANDLE in the HII database, then ASSERT.
-
- @param[in] HiiHandle The handle that was previously registered in the HII database
-
-**/
-VOID
-EFIAPI
-HiiRemovePackages (
- IN EFI_HII_HANDLE HiiHandle
- )
-{
- EFI_STATUS Status;
-
- ASSERT (HiiHandle != NULL);
- Status = gHiiDatabase->RemovePackageList (gHiiDatabase, HiiHandle);
- ASSERT_EFI_ERROR (Status);
-}
-
-/**
- Retrieves the array of all the HII Handles or the HII handles of a specific
- package list GUID in the HII Database.
- This array is terminated with a NULL HII Handle.
- This function allocates the returned array using AllocatePool().
- The caller is responsible for freeing the array with FreePool().
-
- @param[in] PackageListGuid An optional parameter that is used to request
- HII Handles associated with a specific
- Package List GUID. If this parameter is NULL,
- then all the HII Handles in the HII Database
- are returned. If this parameter is not NULL,
- then zero or more HII Handles associated with
- PackageListGuid are returned.
-
- @retval NULL No HII handles were found in the HII database
- @retval NULL The array of HII Handles could not be retrieved
- @retval Other A pointer to the NULL terminated array of HII Handles
-
-**/
-EFI_HII_HANDLE *
-EFIAPI
-HiiGetHiiHandles (
- IN CONST EFI_GUID *PackageListGuid OPTIONAL
- )
-{
- EFI_STATUS Status;
- UINTN HandleBufferLength;
- EFI_HII_HANDLE TempHiiHandleBuffer;
- EFI_HII_HANDLE *HiiHandleBuffer;
- EFI_GUID Guid;
- UINTN Index1;
- UINTN Index2;
-
- //
- // Retrieve the size required for the buffer of all HII handles.
- //
- HandleBufferLength = 0;
- Status = gHiiDatabase->ListPackageLists (
- gHiiDatabase,
- EFI_HII_PACKAGE_TYPE_ALL,
- NULL,
- &HandleBufferLength,
- &TempHiiHandleBuffer
- );
-
- //
- // If ListPackageLists() returns EFI_SUCCESS for a zero size,
- // then there are no HII handles in the HII database. If ListPackageLists()
- // returns an error other than EFI_BUFFER_TOO_SMALL, then there are no HII
- // handles in the HII database.
- //
- if (Status != EFI_BUFFER_TOO_SMALL) {
- //
- // Return NULL if the size can not be retrieved, or if there are no HII
- // handles in the HII Database
- //
- return NULL;
- }
-
- //
- // Allocate the array of HII handles to hold all the HII Handles and a NULL terminator
- //
- HiiHandleBuffer = AllocateZeroPool (HandleBufferLength + sizeof (EFI_HII_HANDLE));
- if (HiiHandleBuffer == NULL) {
- //
- // Return NULL if allocation fails.
- //
- return NULL;
- }
-
- //
- // Retrieve the array of HII Handles in the HII Database
- //
- Status = gHiiDatabase->ListPackageLists (
- gHiiDatabase,
- EFI_HII_PACKAGE_TYPE_ALL,
- NULL,
- &HandleBufferLength,
- HiiHandleBuffer
- );
- if (EFI_ERROR (Status)) {
- //
- // Free the buffer and return NULL if the HII handles can not be retrieved.
- //
- FreePool (HiiHandleBuffer);
- return NULL;
- }
-
- if (PackageListGuid == NULL) {
- //
- // Return the NULL terminated array of HII handles in the HII Database
- //
- return HiiHandleBuffer;
- } else {
- for (Index1 = 0, Index2 = 0; HiiHandleBuffer[Index1] != NULL; Index1++) {
- Status = InternalHiiExtractGuidFromHiiHandle (HiiHandleBuffer[Index1], &Guid);
- ASSERT_EFI_ERROR (Status);
- if (CompareGuid (&Guid, PackageListGuid)) {
- HiiHandleBuffer[Index2++] = HiiHandleBuffer[Index1];
- }
- }
-
- if (Index2 > 0) {
- HiiHandleBuffer[Index2] = NULL;
- return HiiHandleBuffer;
- } else {
- FreePool (HiiHandleBuffer);
- return NULL;
- }
- }
-}
-
-/**
- This function allows a caller to extract the form set opcode form the Hii Handle.
- The returned buffer is allocated using AllocatePool().The caller is responsible
- for freeing the allocated buffer using FreePool().
-
- @param Handle The HII handle.
- @param Buffer On return, points to a pointer which point to the buffer that contain the formset opcode.
- @param BufferSize On return, points to the length of the buffer.
-
- @retval EFI_OUT_OF_RESOURCES No enough memory resource is allocated.
- @retval EFI_NOT_FOUND Can't find the package data for the input Handle.
- @retval EFI_INVALID_PARAMETER The input parameters are not correct.
- @retval EFI_SUCCESS Get the formset opcode from the hii handle successfully.
-
-**/
-EFI_STATUS
-EFIAPI
-HiiGetFormSetFromHiiHandle (
- IN EFI_HII_HANDLE Handle,
- OUT EFI_IFR_FORM_SET **Buffer,
- OUT UINTN *BufferSize
- )
-{
- EFI_STATUS Status;
- UINTN PackageListSize;
- UINTN TempSize;
- EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
- UINT8 *Package;
- UINT8 *OpCodeData;
- UINT8 *FormSetBuffer;
- UINT8 *TempBuffer;
- UINT32 Offset;
- UINT32 Offset2;
- UINT32 PackageListLength;
- EFI_HII_PACKAGE_HEADER PackageHeader;
-
- TempSize = 0;
- FormSetBuffer = NULL;
- TempBuffer = NULL;
-
- //
- // Get HII PackageList
- //
- PackageListSize = 0;
- HiiPackageList = NULL;
- Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &PackageListSize, HiiPackageList);
- if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
- return Status;
- }
-
- HiiPackageList = AllocatePool (PackageListSize);
- if (HiiPackageList == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &PackageListSize, HiiPackageList);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Get Form package from this HII package List
- //
- Status = EFI_NOT_FOUND;
- Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
- PackageListLength = ReadUnaligned32 (&HiiPackageList->PackageLength);
-
- while (Offset < PackageListLength) {
- Package = ((UINT8 *)HiiPackageList) + Offset;
- CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
- Offset += PackageHeader.Length;
-
- if (PackageHeader.Type != EFI_HII_PACKAGE_FORMS) {
- continue;
- }
-
- //
- // Search FormSet Opcode in this Form Package
- //
- Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
- while (Offset2 < PackageHeader.Length) {
- OpCodeData = Package + Offset2;
- Offset2 += ((EFI_IFR_OP_HEADER *)OpCodeData)->Length;
-
- if (((EFI_IFR_OP_HEADER *)OpCodeData)->OpCode != EFI_IFR_FORM_SET_OP) {
- continue;
- }
-
- if (FormSetBuffer != NULL) {
- TempBuffer = ReallocatePool (
- TempSize,
- TempSize + ((EFI_IFR_OP_HEADER *)OpCodeData)->Length,
- FormSetBuffer
- );
- if (TempBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
-
- CopyMem (TempBuffer + TempSize, OpCodeData, ((EFI_IFR_OP_HEADER *)OpCodeData)->Length);
- FormSetBuffer = NULL;
- } else {
- TempBuffer = AllocatePool (TempSize + ((EFI_IFR_OP_HEADER *)OpCodeData)->Length);
- if (TempBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
-
- CopyMem (TempBuffer, OpCodeData, ((EFI_IFR_OP_HEADER *)OpCodeData)->Length);
- }
-
- TempSize += ((EFI_IFR_OP_HEADER *)OpCodeData)->Length;
- FormSetBuffer = TempBuffer;
-
- Status = EFI_SUCCESS;
- //
- // One form package has one formset, exit current form package to search other form package in the packagelist.
- //
- break;
- }
- }
-
-Done:
- FreePool (HiiPackageList);
-
- *BufferSize = TempSize;
- *Buffer = (EFI_IFR_FORM_SET *)FormSetBuffer;
-
- return Status;
-}
-
-/**
- Converts all hex dtring characters in range ['A'..'F'] to ['a'..'f'] for
- hex digits that appear between a '=' and a '&' in a config string.
-
- If ConfigString is NULL, then ASSERT().
-
- @param[in] ConfigString Pointer to a Null-terminated Unicode string.
-
- @return Pointer to the Null-terminated Unicode result string.
-
-**/
-EFI_STRING
-EFIAPI
-InternalHiiLowerConfigString (
- IN EFI_STRING ConfigString
- )
-{
- EFI_STRING String;
- BOOLEAN Lower;
-
- ASSERT (ConfigString != NULL);
-
- //
- // Convert all hex digits in range [A-F] in the configuration header to [a-f]
- //
- for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) {
- if (*String == L'=') {
- Lower = TRUE;
- } else if (*String == L'&') {
- Lower = FALSE;
- } else if (Lower && (*String >= L'A') && (*String <= L'F')) {
- *String = (CHAR16)(*String - L'A' + L'a');
- }
- }
-
- return ConfigString;
-}
-
-/**
- Uses the BlockToConfig() service of the Config Routing Protocol to
- convert <ConfigRequest> and a buffer to a <ConfigResp>
-
- If ConfigRequest is NULL, then ASSERT().
- If Block is NULL, then ASSERT().
-
- @param[in] ConfigRequest Pointer to a Null-terminated Unicode string.
- @param[in] Block Pointer to a block of data.
- @param[in] BlockSize The zie, in bytes, of Block.
-
- @retval NULL The <ConfigResp> string could not be generated.
- @retval Other Pointer to the Null-terminated Unicode <ConfigResp> string.
-
-**/
-EFI_STRING
-EFIAPI
-InternalHiiBlockToConfig (
- IN CONST EFI_STRING ConfigRequest,
- IN CONST UINT8 *Block,
- IN UINTN BlockSize
- )
-{
- EFI_STATUS Status;
- EFI_STRING ConfigResp;
- CHAR16 *Progress;
-
- ASSERT (ConfigRequest != NULL);
- ASSERT (Block != NULL);
-
- //
- // Convert <ConfigRequest> to <ConfigResp>
- //
- Status = gHiiConfigRouting->BlockToConfig (
- gHiiConfigRouting,
- ConfigRequest,
- Block,
- BlockSize,
- &ConfigResp,
- &Progress
- );
- if (EFI_ERROR (Status)) {
- return NULL;
- }
-
- return ConfigResp;
-}
-
-/**
- Uses the BrowserCallback() service of the Form Browser Protocol to retrieve
- or set uncommitted data. If sata i being retrieved, then the buffer is
- allocated using AllocatePool(). The caller is then responsible for freeing
- the buffer using FreePool().
-
- @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional
- parameter that may be NULL.
- @param[in] VariableName Pointer to a Null-terminated Unicode string. This
- is an optional parameter that may be NULL.
- @param[in] SetResultsData If not NULL, then this parameter specified the buffer
- of uncommited data to set. If this parameter is NULL,
- then the caller is requesting to get the uncommited data
- from the Form Browser.
-
- @retval NULL The uncommitted data could not be retrieved.
- @retval Other A pointer to a buffer containing the uncommitted data.
-
-**/
-EFI_STRING
-EFIAPI
-InternalHiiBrowserCallback (
- IN CONST EFI_GUID *VariableGuid OPTIONAL,
- IN CONST CHAR16 *VariableName OPTIONAL,
- IN CONST EFI_STRING SetResultsData OPTIONAL
- )
-{
- EFI_STATUS Status;
- UINTN ResultsDataSize;
- EFI_STRING ResultsData;
- CHAR16 TempResultsData;
-
- //
- // Locate protocols
- //
- if (mUefiFormBrowser2 == NULL) {
- Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **)&mUefiFormBrowser2);
- if (EFI_ERROR (Status) || (mUefiFormBrowser2 == NULL)) {
- return NULL;
- }
- }
-
- ResultsDataSize = 0;
-
- if (SetResultsData != NULL) {
- //
- // Request to to set data in the uncommitted browser state information
- //
- ResultsData = SetResultsData;
- } else {
- //
- // Retrieve the length of the buffer required ResultsData from the Browser Callback
- //
- Status = mUefiFormBrowser2->BrowserCallback (
- mUefiFormBrowser2,
- &ResultsDataSize,
- &TempResultsData,
- TRUE,
- VariableGuid,
- VariableName
- );
-
- if (!EFI_ERROR (Status)) {
- //
- // No Resluts Data, only allocate one char for '\0'
- //
- ResultsData = AllocateZeroPool (sizeof (CHAR16));
- return ResultsData;
- }
-
- if (Status != EFI_BUFFER_TOO_SMALL) {
- return NULL;
- }
-
- //
- // Allocate the ResultsData buffer
- //
- ResultsData = AllocateZeroPool (ResultsDataSize);
- if (ResultsData == NULL) {
- return NULL;
- }
- }
-
- //
- // Retrieve or set the ResultsData from the Browser Callback
- //
- Status = mUefiFormBrowser2->BrowserCallback (
- mUefiFormBrowser2,
- &ResultsDataSize,
- ResultsData,
- (BOOLEAN)(SetResultsData == NULL),
- VariableGuid,
- VariableName
- );
- if (EFI_ERROR (Status)) {
- return NULL;
- }
-
- return ResultsData;
-}
-
-/**
- Allocates and returns a Null-terminated Unicode <ConfigHdr> string using routing
- information that includes a GUID, an optional Unicode string name, and a device
- path. The string returned is allocated with AllocatePool(). The caller is
- responsible for freeing the allocated string with FreePool().
-
- The format of a <ConfigHdr> is as follows:
-
- GUID=<HexCh>32&NAME=<Char>NameLength&PATH=<HexChar>DevicePathSize<Null>
-
- @param[in] Guid Pointer to an EFI_GUID that is the routing information
- GUID. Each of the 16 bytes in Guid is converted to
- a 2 Unicode character hexadecimal string. This is
- an optional parameter that may be NULL.
- @param[in] Name Pointer to a Null-terminated Unicode string that is
- the routing information NAME. This is an optional
- parameter that may be NULL. Each 16-bit Unicode
- character in Name is converted to a 4 character Unicode
- hexadecimal string.
- @param[in] DriverHandle The driver handle which supports a Device Path Protocol
- that is the routing information PATH. Each byte of
- the Device Path associated with DriverHandle is converted
- to a 2 Unicode character hexadecimal string.
-
- @retval NULL DriverHandle does not support the Device Path Protocol.
- @retval Other A pointer to the Null-terminate Unicode <ConfigHdr> string
-
-**/
-EFI_STRING
-EFIAPI
-HiiConstructConfigHdr (
- IN CONST EFI_GUID *Guid OPTIONAL,
- IN CONST CHAR16 *Name OPTIONAL,
- IN EFI_HANDLE DriverHandle
- )
-{
- UINTN NameLength;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- UINTN DevicePathSize;
- CHAR16 *String;
- CHAR16 *ReturnString;
- UINTN Index;
- UINT8 *Buffer;
- UINTN MaxLen;
-
- //
- // Compute the length of Name in Unicode characters.
- // If Name is NULL, then the length is 0.
- //
- NameLength = 0;
- if (Name != NULL) {
- NameLength = StrLen (Name);
- }
-
- DevicePath = NULL;
- DevicePathSize = 0;
- //
- // Retrieve DevicePath Protocol associated with DriverHandle
- //
- if (DriverHandle != NULL) {
- DevicePath = DevicePathFromHandle (DriverHandle);
- if (DevicePath == NULL) {
- return NULL;
- }
-
- //
- // Compute the size of the device path in bytes
- //
- DevicePathSize = GetDevicePathSize (DevicePath);
- }
-
- //
- // GUID=<HexCh>32&NAME=<Char>NameLength&PATH=<HexChar>DevicePathSize <Null>
- // | 5 | sizeof (EFI_GUID) * 2 | 6 | NameStrLen*4 | 6 | DevicePathSize * 2 | 1 |
- //
- MaxLen = 5 + sizeof (EFI_GUID) * 2 + 6 + NameLength * 4 + 6 + DevicePathSize * 2 + 1;
- String = AllocateZeroPool (MaxLen * sizeof (CHAR16));
- if (String == NULL) {
- return NULL;
- }
-
- //
- // Start with L"GUID="
- //
- StrCpyS (String, MaxLen, L"GUID=");
- ReturnString = String;
- String += StrLen (String);
-
- if (Guid != NULL) {
- //
- // Append Guid converted to <HexCh>32
- //
- for (Index = 0, Buffer = (UINT8 *)Guid; Index < sizeof (EFI_GUID); Index++) {
- UnicodeValueToStringS (
- String,
- MaxLen * sizeof (CHAR16) - ((UINTN)String - (UINTN)ReturnString),
- PREFIX_ZERO | RADIX_HEX,
- *(Buffer++),
- 2
- );
- String += StrnLenS (String, MaxLen - ((UINTN)String - (UINTN)ReturnString) / sizeof (CHAR16));
- }
- }
-
- //
- // Append L"&NAME="
- //
- StrCatS (ReturnString, MaxLen, L"&NAME=");
- String += StrLen (String);
-
- if (Name != NULL) {
- //
- // Append Name converted to <Char>NameLength
- //
- for ( ; *Name != L'\0'; Name++) {
- UnicodeValueToStringS (
- String,
- sizeof (CHAR16) * MaxLen - ((UINTN)String - (UINTN)ReturnString),
- PREFIX_ZERO | RADIX_HEX,
- *Name,
- 4
- );
- String += StrnLenS (String, MaxLen - ((UINTN)String - (UINTN)ReturnString) / sizeof (CHAR16));
- }
- }
-
- //
- // Append L"&PATH="
- //
- StrCatS (ReturnString, MaxLen, L"&PATH=");
- String += StrLen (String);
-
- //
- // Append the device path associated with DriverHandle converted to <HexChar>DevicePathSize
- //
- for (Index = 0, Buffer = (UINT8 *)DevicePath; Index < DevicePathSize; Index++) {
- UnicodeValueToStringS (
- String,
- sizeof (CHAR16) * MaxLen - ((UINTN)String - (UINTN)ReturnString),
- PREFIX_ZERO | RADIX_HEX,
- *(Buffer++),
- 2
- );
- String += StrnLenS (String, MaxLen - ((UINTN)String - (UINTN)ReturnString) / sizeof (CHAR16));
- }
-
- //
- // Null terminate the Unicode string
- //
- *String = L'\0';
-
- //
- // Convert all hex digits in range [A-F] in the configuration header to [a-f]
- //
- return InternalHiiLowerConfigString (ReturnString);
-}
-
-/**
- Convert the hex UNICODE encoding string of UEFI GUID, NAME or device path
- to binary buffer from <ConfigHdr>.
-
- This is a internal function.
-
- @param String UEFI configuration string.
- @param Flag Flag specifies what type buffer will be retrieved.
- @param Buffer Binary of Guid, Name or Device path.
-
- @retval EFI_INVALID_PARAMETER Any incoming parameter is invalid.
- @retval EFI_OUT_OF_RESOURCES Lake of resources to store neccesary structures.
- @retval EFI_SUCCESS The buffer data is retrieved and translated to
- binary format.
-
-**/
-EFI_STATUS
-InternalHiiGetBufferFromString (
- IN EFI_STRING String,
- IN UINT8 Flag,
- OUT UINT8 **Buffer
- )
-{
- UINTN Length;
- EFI_STRING ConfigHdr;
- CHAR16 *StringPtr;
- UINT8 *DataBuffer;
- CHAR16 TemStr[5];
- UINTN Index;
- UINT8 DigitUint8;
-
- if ((String == NULL) || (Buffer == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- DataBuffer = NULL;
- StringPtr = NULL;
- ConfigHdr = String;
- //
- // The content between 'GUID', 'NAME', 'PATH' of <ConfigHdr> and '&' of next element
- // or '\0' (end of configuration string) is the UNICODE %02x bytes encoding string.
- //
- for (Length = 0; *String != 0 && *String != L'&'; String++, Length++) {
- }
-
- switch (Flag) {
- case GUID_CONFIG_STRING_TYPE:
- case PATH_CONFIG_STRING_TYPE:
- //
- // The data in <ConfigHdr> is encoded as hex UNICODE %02x bytes in the same order
- // as the device path and Guid resides in RAM memory.
- // Translate the data into binary.
- //
- DataBuffer = (UINT8 *)AllocateZeroPool ((Length + 1) / 2);
- if (DataBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Convert binary byte one by one
- //
- ZeroMem (TemStr, sizeof (TemStr));
- for (Index = 0; Index < Length; Index++) {
- TemStr[0] = ConfigHdr[Index];
- DigitUint8 = (UINT8)StrHexToUint64 (TemStr);
- if ((Index & 1) == 0) {
- DataBuffer[Index/2] = DigitUint8;
- } else {
- DataBuffer[Index/2] = (UINT8)((DataBuffer[Index/2] << 4) + DigitUint8);
- }
- }
-
- *Buffer = DataBuffer;
- break;
-
- case NAME_CONFIG_STRING_TYPE:
- //
- // Convert Config String to Unicode String, e.g. "0041004200430044" => "ABCD"
- //
-
- //
- // Add the tailling char L'\0'
- //
- DataBuffer = (UINT8 *)AllocateZeroPool ((Length/4 + 1) * sizeof (CHAR16));
- if (DataBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Convert character one by one
- //
- StringPtr = (CHAR16 *)DataBuffer;
- ZeroMem (TemStr, sizeof (TemStr));
- for (Index = 0; Index < Length; Index += 4) {
- StrnCpyS (TemStr, sizeof (TemStr) / sizeof (CHAR16), ConfigHdr + Index, 4);
- StringPtr[Index/4] = (CHAR16)StrHexToUint64 (TemStr);
- }
-
- //
- // Add tailing L'\0' character
- //
- StringPtr[Index/4] = L'\0';
-
- *Buffer = DataBuffer;
- break;
-
- default:
- return EFI_INVALID_PARAMETER;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- This function checks VarOffset and VarWidth is in the block range.
-
- @param BlockArray The block array is to be checked.
- @param VarOffset Offset of var to the structure
- @param VarWidth Width of var.
-
- @retval TRUE This Var is in the block range.
- @retval FALSE This Var is not in the block range.
-**/
-BOOLEAN
-BlockArrayCheck (
- IN IFR_BLOCK_DATA *BlockArray,
- IN UINT16 VarOffset,
- IN UINT16 VarWidth
- )
-{
- LIST_ENTRY *Link;
- IFR_BLOCK_DATA *BlockData;
-
- //
- // No Request Block array, all vars are got.
- //
- if (BlockArray == NULL) {
- return TRUE;
- }
-
- //
- // Check the input var is in the request block range.
- //
- for (Link = BlockArray->Entry.ForwardLink; Link != &BlockArray->Entry; Link = Link->ForwardLink) {
- BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
- if ((VarOffset >= BlockData->Offset) && ((VarOffset + VarWidth) <= (BlockData->Offset + BlockData->Width))) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/**
- Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET
- or WIDTH or VALUE.
- <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>
-
- @param ValueString String in <BlockConfig> format and points to the
- first character of <Number>.
- @param ValueData The output value. Caller takes the responsibility
- to free memory.
- @param ValueLength Length of the <Number>, in characters.
-
- @retval EFI_OUT_OF_RESOURCES Insufficient resources to store neccessary
- structures.
- @retval EFI_SUCCESS Value of <Number> is outputted in Number
- successfully.
-
-**/
-EFI_STATUS
-EFIAPI
-InternalHiiGetValueOfNumber (
- IN EFI_STRING ValueString,
- OUT UINT8 **ValueData,
- OUT UINTN *ValueLength
- )
-{
- EFI_STRING StringPtr;
- UINTN Length;
- UINT8 *Buf;
- UINT8 DigitUint8;
- UINTN Index;
- CHAR16 TemStr[2];
-
- ASSERT (ValueString != NULL && ValueData != NULL && ValueLength != NULL);
- ASSERT (*ValueString != L'\0');
-
- //
- // Get the length of value string
- //
- StringPtr = ValueString;
- while (*StringPtr != L'\0' && *StringPtr != L'&') {
- StringPtr++;
- }
-
- Length = StringPtr - ValueString;
-
- //
- // Allocate buffer to store the value
- //
- Buf = (UINT8 *)AllocateZeroPool ((Length + 1) / 2);
- if (Buf == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Convert character one by one to the value buffer
- //
- ZeroMem (TemStr, sizeof (TemStr));
- for (Index = 0; Index < Length; Index++) {
- TemStr[0] = ValueString[Length - Index - 1];
- DigitUint8 = (UINT8)StrHexToUint64 (TemStr);
- if ((Index & 1) == 0) {
- Buf[Index/2] = DigitUint8;
- } else {
- Buf[Index/2] = (UINT8)((DigitUint8 << 4) + Buf[Index/2]);
- }
- }
-
- //
- // Set the converted value and string length.
- //
- *ValueData = Buf;
- *ValueLength = Length;
- return EFI_SUCCESS;
-}
-
-/**
- Get value from config request resp string.
-
- @param ConfigElement ConfigResp string contains the current setting.
- @param VarName The variable name which need to get value.
- @param VarValue The return value.
-
- @retval EFI_SUCCESS Get the value for the VarName
- @retval EFI_OUT_OF_RESOURCES The memory is not enough.
-**/
-EFI_STATUS
-GetValueFromRequest (
- IN CHAR16 *ConfigElement,
- IN CHAR16 *VarName,
- OUT UINT64 *VarValue
- )
-{
- UINT8 *TmpBuffer;
- CHAR16 *StringPtr;
- UINTN Length;
- EFI_STATUS Status;
-
- //
- // Find VarName related string.
- //
- StringPtr = StrStr (ConfigElement, VarName);
- ASSERT (StringPtr != NULL);
-
- //
- // Skip the "VarName=" string
- //
- StringPtr += StrLen (VarName) + 1;
-
- //
- // Get Offset
- //
- Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- *VarValue = 0;
- CopyMem (VarValue, TmpBuffer, (((Length + 1) / 2) < sizeof (UINT64)) ? ((Length + 1) / 2) : sizeof (UINT64));
-
- FreePool (TmpBuffer);
-
- return EFI_SUCCESS;
-}
-
-/**
- This internal function parses IFR data to validate current setting.
-
- Base on the NameValueType, if it is TRUE, RequestElement and HiiHandle is valid;
- else the VarBuffer and CurrentBlockArray is valid.
-
- @param HiiPackageList Point to Hii package list.
- @param PackageListLength The length of the pacakge.
- @param VarGuid Guid of the buffer storage.
- @param VarName Name of the buffer storage.
- @param VarBuffer The data buffer for the storage.
- @param CurrentBlockArray The block array from the config Requst string.
- @param RequestElement The config string for this storage.
- @param HiiHandle The HiiHandle for this formset.
- @param NameValueType Whether current storage is name/value varstore or not.
-
- @retval EFI_SUCCESS The current setting is valid.
- @retval EFI_OUT_OF_RESOURCES The memory is not enough.
- @retval EFI_INVALID_PARAMETER The config string or the Hii package is invalid.
-**/
-EFI_STATUS
-ValidateQuestionFromVfr (
- IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList,
- IN UINTN PackageListLength,
- IN EFI_GUID *VarGuid,
- IN CHAR16 *VarName,
- IN UINT8 *VarBuffer,
- IN IFR_BLOCK_DATA *CurrentBlockArray,
- IN CHAR16 *RequestElement,
- IN EFI_HII_HANDLE HiiHandle,
- IN BOOLEAN NameValueType
- )
-{
- IFR_BLOCK_DATA VarBlockData;
- UINT16 Offset;
- UINT16 Width;
- UINT64 VarValue;
- EFI_IFR_TYPE_VALUE TmpValue;
- EFI_STATUS Status;
- EFI_HII_PACKAGE_HEADER PackageHeader;
- UINT32 PackageOffset;
- UINT8 *PackageData;
- UINTN IfrOffset;
- EFI_IFR_OP_HEADER *IfrOpHdr;
- EFI_IFR_VARSTORE *IfrVarStore;
- EFI_IFR_VARSTORE_NAME_VALUE *IfrNameValueStore;
- EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;
- IFR_VARSTORAGE_DATA VarStoreData;
- EFI_IFR_ONE_OF *IfrOneOf;
- EFI_IFR_NUMERIC *IfrNumeric;
- EFI_IFR_ONE_OF_OPTION *IfrOneOfOption;
- EFI_IFR_CHECKBOX *IfrCheckBox;
- EFI_IFR_STRING *IfrString;
- CHAR8 *VarStoreName;
- UINTN Index;
- CHAR16 *QuestionName;
- CHAR16 *StringPtr;
- UINT16 BitOffset;
- UINT16 BitWidth;
- UINT16 TotalBits;
- UINTN StartBit;
- UINTN EndBit;
- BOOLEAN QuestionReferBitField;
- UINT32 BufferValue;
-
- //
- // Initialize the local variables.
- //
- Index = 0;
- VarStoreName = NULL;
- Status = EFI_SUCCESS;
- VarValue = 0;
- IfrVarStore = NULL;
- IfrNameValueStore = NULL;
- IfrEfiVarStore = NULL;
- ZeroMem (&VarStoreData, sizeof (IFR_VARSTORAGE_DATA));
- ZeroMem (&VarBlockData, sizeof (VarBlockData));
- BitOffset = 0;
- BitWidth = 0;
- QuestionReferBitField = FALSE;
-
- //
- // Check IFR value is in block data, then Validate Value
- //
- PackageOffset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
- while (PackageOffset < PackageListLength) {
- CopyMem (&PackageHeader, (UINT8 *)HiiPackageList + PackageOffset, sizeof (PackageHeader));
-
- //
- // Parse IFR opcode from the form package.
- //
- if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
- IfrOffset = sizeof (PackageHeader);
- PackageData = (UINT8 *)HiiPackageList + PackageOffset;
- while (IfrOffset < PackageHeader.Length) {
- IfrOpHdr = (EFI_IFR_OP_HEADER *)(PackageData + IfrOffset);
- //
- // Validate current setting to the value built in IFR opcode
- //
- switch (IfrOpHdr->OpCode) {
- case EFI_IFR_VARSTORE_OP:
- //
- // VarStoreId has been found. No further found.
- //
- if (VarStoreData.VarStoreId != 0) {
- break;
- }
-
- //
- // Find the matched VarStoreId to the input VarGuid and VarName
- //
- IfrVarStore = (EFI_IFR_VARSTORE *)IfrOpHdr;
- if (CompareGuid ((EFI_GUID *)(VOID *)&IfrVarStore->Guid, VarGuid)) {
- VarStoreName = (CHAR8 *)IfrVarStore->Name;
- for (Index = 0; VarStoreName[Index] != 0; Index++) {
- if ((CHAR16)VarStoreName[Index] != VarName[Index]) {
- break;
- }
- }
-
- //
- // The matched VarStore is found.
- //
- if ((VarStoreName[Index] != 0) || (VarName[Index] != 0)) {
- IfrVarStore = NULL;
- }
- } else {
- IfrVarStore = NULL;
- }
-
- if (IfrVarStore != NULL) {
- VarStoreData.VarStoreId = IfrVarStore->VarStoreId;
- VarStoreData.Size = IfrVarStore->Size;
- }
-
- break;
- case EFI_IFR_VARSTORE_NAME_VALUE_OP:
- //
- // VarStoreId has been found. No further found.
- //
- if (VarStoreData.VarStoreId != 0) {
- break;
- }
-
- //
- // Find the matched VarStoreId to the input VarGuid
- //
- IfrNameValueStore = (EFI_IFR_VARSTORE_NAME_VALUE *)IfrOpHdr;
- if (!CompareGuid ((EFI_GUID *)(VOID *)&IfrNameValueStore->Guid, VarGuid)) {
- IfrNameValueStore = NULL;
- }
-
- if (IfrNameValueStore != NULL) {
- VarStoreData.VarStoreId = IfrNameValueStore->VarStoreId;
- }
-
- break;
- case EFI_IFR_VARSTORE_EFI_OP:
- //
- // VarStore is found. Don't need to search any more.
- //
- if (VarStoreData.VarStoreId != 0) {
- break;
- }
-
- IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpHdr;
-
- //
- // If the length is small than the structure, this is from old efi
- // varstore definition. Old efi varstore get config directly from
- // GetVariable function.
- //
- if (IfrOpHdr->Length < sizeof (EFI_IFR_VARSTORE_EFI)) {
- break;
- }
-
- if (CompareGuid ((EFI_GUID *)(VOID *)&IfrEfiVarStore->Guid, VarGuid)) {
- VarStoreName = (CHAR8 *)IfrEfiVarStore->Name;
- for (Index = 0; VarStoreName[Index] != 0; Index++) {
- if ((CHAR16)VarStoreName[Index] != VarName[Index]) {
- break;
- }
- }
-
- //
- // The matched VarStore is found.
- //
- if ((VarStoreName[Index] != 0) || (VarName[Index] != 0)) {
- IfrEfiVarStore = NULL;
- }
- } else {
- IfrEfiVarStore = NULL;
- }
-
- if (IfrEfiVarStore != NULL) {
- //
- // Find the matched VarStore
- //
- VarStoreData.VarStoreId = IfrEfiVarStore->VarStoreId;
- VarStoreData.Size = IfrEfiVarStore->Size;
- }
-
- break;
- case EFI_IFR_FORM_OP:
- case EFI_IFR_FORM_MAP_OP:
- //
- // Check the matched VarStoreId is found.
- //
- if (VarStoreData.VarStoreId == 0) {
- return EFI_SUCCESS;
- }
-
- break;
- case EFI_IFR_ONE_OF_OP:
- //
- // Check whether current value is the one of option.
- //
-
- //
- // OneOf question is not in IFR Form. This IFR form is not valid.
- //
- if (VarStoreData.VarStoreId == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check whether this question is for the requested varstore.
- //
- IfrOneOf = (EFI_IFR_ONE_OF *)IfrOpHdr;
- if (IfrOneOf->Question.VarStoreId != VarStoreData.VarStoreId) {
- break;
- }
-
- if (NameValueType) {
- QuestionName = HiiGetString (HiiHandle, IfrOneOf->Question.VarStoreInfo.VarName, NULL);
- ASSERT (QuestionName != NULL);
-
- if (StrStr (RequestElement, QuestionName) == NULL) {
- //
- // This question is not in the current configuration string. Skip it.
- //
- break;
- }
-
- Status = GetValueFromRequest (RequestElement, QuestionName, &VarValue);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- } else {
- //
- // Get Offset by Question header and Width by DataType Flags
- //
- if (QuestionReferBitField) {
- //
- // Get the byte offset/width for bit field.
- //
- BitOffset = IfrOneOf->Question.VarStoreInfo.VarOffset;
- BitWidth = IfrOneOf->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;
- Offset = BitOffset / 8;
- TotalBits = BitOffset % 8 + BitWidth;
- Width = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1);
- } else {
- Offset = IfrOneOf->Question.VarStoreInfo.VarOffset;
- Width = (UINT16)(1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));
- }
-
- //
- // Check whether this question is in current block array.
- //
- if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {
- //
- // This question is not in the current configuration string. Skip it.
- //
- break;
- }
-
- //
- // Check this var question is in the var storage
- //
- if ((Offset + Width) > VarStoreData.Size) {
- //
- // This question exceeds the var store size.
- //
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Get the current value for oneof opcode
- //
- VarValue = 0;
- if (QuestionReferBitField) {
- //
- // Get the value in bit fields.
- //
- StartBit = BitOffset % 8;
- EndBit = StartBit + BitWidth - 1;
- CopyMem ((UINT8 *)&BufferValue, VarBuffer + Offset, Width);
- VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit);
- } else {
- CopyMem (&VarValue, VarBuffer + Offset, Width);
- }
- }
-
- //
- // Set Block Data, to be checked in the following Oneof option opcode.
- //
- VarBlockData.OpCode = IfrOpHdr->OpCode;
- VarBlockData.Scope = IfrOpHdr->Scope;
- break;
- case EFI_IFR_NUMERIC_OP:
- //
- // Check the current value is in the numeric range.
- //
-
- //
- // Numeric question is not in IFR Form. This IFR form is not valid.
- //
- if (VarStoreData.VarStoreId == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check whether this question is for the requested varstore.
- //
- IfrNumeric = (EFI_IFR_NUMERIC *)IfrOpHdr;
- if (IfrNumeric->Question.VarStoreId != VarStoreData.VarStoreId) {
- break;
- }
-
- if (NameValueType) {
- QuestionName = HiiGetString (HiiHandle, IfrNumeric->Question.VarStoreInfo.VarName, NULL);
- ASSERT (QuestionName != NULL);
-
- if (StrStr (RequestElement, QuestionName) == NULL) {
- //
- // This question is not in the current configuration string. Skip it.
- //
- break;
- }
-
- Status = GetValueFromRequest (RequestElement, QuestionName, &VarValue);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- } else {
- //
- // Get Offset by Question header and Width by DataType Flags
- //
- if (QuestionReferBitField) {
- //
- // Get the byte offset/width for bit field.
- //
- BitOffset = IfrNumeric->Question.VarStoreInfo.VarOffset;
- BitWidth = IfrNumeric->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;
- Offset = BitOffset / 8;
- TotalBits = BitOffset % 8 + BitWidth;
- Width = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1);
- } else {
- Offset = IfrNumeric->Question.VarStoreInfo.VarOffset;
- Width = (UINT16)(1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE));
- }
-
- //
- // Check whether this question is in current block array.
- //
- if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {
- //
- // This question is not in the current configuration string. Skip it.
- //
- break;
- }
-
- //
- // Check this var question is in the var storage
- //
- if ((Offset + Width) > VarStoreData.Size) {
- //
- // This question exceeds the var store size.
- //
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check the current value is in the numeric range.
- //
- VarValue = 0;
- if (QuestionReferBitField) {
- //
- // Get the value in the bit fields.
- //
- StartBit = BitOffset % 8;
- EndBit = StartBit + BitWidth - 1;
- CopyMem ((UINT8 *)&BufferValue, VarBuffer + Offset, Width);
- VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit);
- } else {
- CopyMem (&VarValue, VarBuffer + Offset, Width);
- }
- }
-
- if ( QuestionReferBitField) {
- //
- // Value in bit fields was stored as UINt32 type.
- //
- if ((IfrNumeric->Flags & EDKII_IFR_DISPLAY_BIT) == 0) {
- if (((INT32)VarValue < (INT32)IfrNumeric->data.u32.MinValue) || ((INT32)VarValue > (INT32)IfrNumeric->data.u32.MaxValue)) {
- //
- // Not in the valid range.
- //
- return EFI_INVALID_PARAMETER;
- }
- } else {
- if ((VarValue < IfrNumeric->data.u32.MinValue) || (VarValue > IfrNumeric->data.u32.MaxValue)) {
- //
- // Not in the valid range.
- //
- return EFI_INVALID_PARAMETER;
- }
- }
- } else {
- if ((IfrNumeric->Flags & EFI_IFR_DISPLAY) == 0) {
- switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {
- case EFI_IFR_NUMERIC_SIZE_1:
- if (((INT8)VarValue < (INT8)IfrNumeric->data.u8.MinValue) || ((INT8)VarValue > (INT8)IfrNumeric->data.u8.MaxValue)) {
- //
- // Not in the valid range.
- //
- return EFI_INVALID_PARAMETER;
- }
-
- break;
- case EFI_IFR_NUMERIC_SIZE_2:
- if (((INT16)VarValue < (INT16)IfrNumeric->data.u16.MinValue) || ((INT16)VarValue > (INT16)IfrNumeric->data.u16.MaxValue)) {
- //
- // Not in the valid range.
- //
- return EFI_INVALID_PARAMETER;
- }
-
- break;
- case EFI_IFR_NUMERIC_SIZE_4:
- if (((INT32)VarValue < (INT32)IfrNumeric->data.u32.MinValue) || ((INT32)VarValue > (INT32)IfrNumeric->data.u32.MaxValue)) {
- //
- // Not in the valid range.
- //
- return EFI_INVALID_PARAMETER;
- }
-
- break;
- case EFI_IFR_NUMERIC_SIZE_8:
- if (((INT64)VarValue < (INT64)IfrNumeric->data.u64.MinValue) || ((INT64)VarValue > (INT64)IfrNumeric->data.u64.MaxValue)) {
- //
- // Not in the valid range.
- //
- return EFI_INVALID_PARAMETER;
- }
-
- break;
- }
- } else {
- switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {
- case EFI_IFR_NUMERIC_SIZE_1:
- if (((UINT8)VarValue < IfrNumeric->data.u8.MinValue) || ((UINT8)VarValue > IfrNumeric->data.u8.MaxValue)) {
- //
- // Not in the valid range.
- //
- return EFI_INVALID_PARAMETER;
- }
-
- break;
- case EFI_IFR_NUMERIC_SIZE_2:
- if (((UINT16)VarValue < IfrNumeric->data.u16.MinValue) || ((UINT16)VarValue > IfrNumeric->data.u16.MaxValue)) {
- //
- // Not in the valid range.
- //
- return EFI_INVALID_PARAMETER;
- }
-
- break;
- case EFI_IFR_NUMERIC_SIZE_4:
- if (((UINT32)VarValue < IfrNumeric->data.u32.MinValue) || ((UINT32)VarValue > IfrNumeric->data.u32.MaxValue)) {
- //
- // Not in the valid range.
- //
- return EFI_INVALID_PARAMETER;
- }
-
- break;
- case EFI_IFR_NUMERIC_SIZE_8:
- if (((UINT64)VarValue < IfrNumeric->data.u64.MinValue) || ((UINT64)VarValue > IfrNumeric->data.u64.MaxValue)) {
- //
- // Not in the valid range.
- //
- return EFI_INVALID_PARAMETER;
- }
-
- break;
- }
- }
- }
-
- break;
- case EFI_IFR_CHECKBOX_OP:
- //
- // Check value is BOOLEAN type, only 0 and 1 is valid.
- //
-
- //
- // CheckBox question is not in IFR Form. This IFR form is not valid.
- //
- if (VarStoreData.VarStoreId == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check whether this question is for the requested varstore.
- //
- IfrCheckBox = (EFI_IFR_CHECKBOX *)IfrOpHdr;
- if (IfrCheckBox->Question.VarStoreId != VarStoreData.VarStoreId) {
- break;
- }
-
- if (NameValueType) {
- QuestionName = HiiGetString (HiiHandle, IfrCheckBox->Question.VarStoreInfo.VarName, NULL);
- ASSERT (QuestionName != NULL);
-
- if (StrStr (RequestElement, QuestionName) == NULL) {
- //
- // This question is not in the current configuration string. Skip it.
- //
- break;
- }
-
- Status = GetValueFromRequest (RequestElement, QuestionName, &VarValue);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- } else {
- //
- // Get Offset by Question header
- //
- if (QuestionReferBitField) {
- //
- // Get the byte offset/width for bit field.
- //
- BitOffset = IfrCheckBox->Question.VarStoreInfo.VarOffset;
- BitWidth = 1;
- Offset = BitOffset / 8;
- TotalBits = BitOffset % 8 + BitWidth;
- Width = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1);
- } else {
- Offset = IfrCheckBox->Question.VarStoreInfo.VarOffset;
- Width = (UINT16)sizeof (BOOLEAN);
- }
-
- //
- // Check whether this question is in current block array.
- //
- if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {
- //
- // This question is not in the current configuration string. Skip it.
- //
- break;
- }
-
- //
- // Check this var question is in the var storage
- //
- if ((Offset + Width) > VarStoreData.Size) {
- //
- // This question exceeds the var store size.
- //
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check the current value is in the numeric range.
- //
- VarValue = 0;
- if (QuestionReferBitField) {
- //
- // Get the value in bit fields.
- //
- StartBit = BitOffset % 8;
- EndBit = StartBit + BitWidth - 1;
- CopyMem ((UINT8 *)&BufferValue, VarBuffer + Offset, Width);
- VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit);
- } else {
- CopyMem (&VarValue, VarBuffer + Offset, Width);
- }
- }
-
- //
- // Boolean type, only 1 and 0 is valid.
- //
- if (VarValue > 1) {
- return EFI_INVALID_PARAMETER;
- }
-
- break;
- case EFI_IFR_STRING_OP:
- //
- // Check current string length is less than maxsize
- //
-
- //
- // CheckBox question is not in IFR Form. This IFR form is not valid.
- //
- if (VarStoreData.VarStoreId == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check whether this question is for the requested varstore.
- //
- IfrString = (EFI_IFR_STRING *)IfrOpHdr;
- if (IfrString->Question.VarStoreId != VarStoreData.VarStoreId) {
- break;
- }
-
- //
- // Get the Max size of the string.
- //
- Width = (UINT16)(IfrString->MaxSize * sizeof (UINT16));
- if (NameValueType) {
- QuestionName = HiiGetString (HiiHandle, IfrString->Question.VarStoreInfo.VarName, NULL);
- ASSERT (QuestionName != NULL);
-
- StringPtr = StrStr (RequestElement, QuestionName);
- if (StringPtr == NULL) {
- //
- // This question is not in the current configuration string. Skip it.
- //
- break;
- }
-
- //
- // Skip the VarName.
- //
- StringPtr += StrLen (QuestionName);
-
- //
- // Skip the "=".
- //
- StringPtr += 1;
-
- //
- // Check current string length is less than maxsize
- // e.g Config String: "0041004200430044", Unicode String: "ABCD". Unicode String length = Config String length / 4.
- // Config string format in UEFI spec.
- // <NvConfig> ::= <Label>'='<String>
- // <String> ::= [<Char>]+
- // <Char> ::= <HexCh>4
- //
- if (StrLen (StringPtr) / 4 > IfrString->MaxSize) {
- return EFI_INVALID_PARAMETER;
- }
- } else {
- //
- // Get Offset/Width by Question header and OneOf Flags
- //
- Offset = IfrString->Question.VarStoreInfo.VarOffset;
- //
- // Check whether this question is in current block array.
- //
- if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {
- //
- // This question is not in the current configuration string. Skip it.
- //
- break;
- }
-
- //
- // Check this var question is in the var storage
- //
- if ((Offset + Width) > VarStoreData.Size) {
- //
- // This question exceeds the var store size.
- //
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check current string length is less than maxsize
- //
- if (StrLen ((CHAR16 *)(VarBuffer + Offset)) > IfrString->MaxSize) {
- return EFI_INVALID_PARAMETER;
- }
- }
-
- break;
- case EFI_IFR_ONE_OF_OPTION_OP:
- //
- // Opcode Scope is zero. This one of option is not to be checked.
- //
- if (VarBlockData.Scope == 0) {
- break;
- }
-
- //
- // Only check for OneOf and OrderList opcode
- //
- IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *)IfrOpHdr;
- if (VarBlockData.OpCode == EFI_IFR_ONE_OF_OP) {
- //
- // Check current value is the value of one of option.
- //
- ASSERT (IfrOneOfOption->Type <= EFI_IFR_TYPE_NUM_SIZE_64);
- ZeroMem (&TmpValue, sizeof (EFI_IFR_TYPE_VALUE));
- CopyMem (&TmpValue, &IfrOneOfOption->Value, IfrOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
- if (VarValue == TmpValue.u64) {
- //
- // The value is one of option value.
- // Set OpCode to Zero, don't need check again.
- //
- VarBlockData.OpCode = 0;
- }
- }
-
- break;
- case EFI_IFR_END_OP:
- QuestionReferBitField = FALSE;
- //
- // Decrease opcode scope for the validated opcode
- //
- if (VarBlockData.Scope > 0) {
- VarBlockData.Scope--;
- }
-
- //
- // OneOf value doesn't belong to one of option value.
- //
- if ((VarBlockData.Scope == 0) && (VarBlockData.OpCode == EFI_IFR_ONE_OF_OP)) {
- return EFI_INVALID_PARAMETER;
- }
-
- break;
- case EFI_IFR_GUID_OP:
- if (CompareGuid ((EFI_GUID *)((UINT8 *)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {
- QuestionReferBitField = TRUE;
- }
-
- break;
- default:
- //
- // Increase Scope for the validated opcode
- //
- if (VarBlockData.Scope > 0) {
- VarBlockData.Scope = (UINT8)(VarBlockData.Scope + IfrOpHdr->Scope);
- }
-
- break;
- }
-
- //
- // Go to the next opcode
- //
- IfrOffset += IfrOpHdr->Length;
- }
-
- //
- // Only one form is in a package list.
- //
- break;
- }
-
- //
- // Go to next package.
- //
- PackageOffset += PackageHeader.Length;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- This internal function parses IFR data to validate current setting.
-
- @param ConfigElement ConfigResp element string contains the current setting.
- @param CurrentBlockArray Current block array.
- @param VarBuffer Data buffer for this varstore.
-
- @retval EFI_SUCCESS The current setting is valid.
- @retval EFI_OUT_OF_RESOURCES The memory is not enough.
- @retval EFI_INVALID_PARAMETER The config string or the Hii package is invalid.
-**/
-EFI_STATUS
-GetBlockDataInfo (
- IN CHAR16 *ConfigElement,
- OUT IFR_BLOCK_DATA **CurrentBlockArray,
- OUT UINT8 **VarBuffer
- )
-{
- IFR_BLOCK_DATA *BlockData;
- IFR_BLOCK_DATA *NewBlockData;
- EFI_STRING StringPtr;
- UINTN Length;
- UINT8 *TmpBuffer;
- UINT16 Offset;
- UINT16 Width;
- LIST_ENTRY *Link;
- UINTN MaxBufferSize;
- EFI_STATUS Status;
- IFR_BLOCK_DATA *BlockArray;
- UINT8 *DataBuffer;
-
- //
- // Initialize the local variables.
- //
- Status = EFI_SUCCESS;
- BlockData = NULL;
- NewBlockData = NULL;
- TmpBuffer = NULL;
- BlockArray = NULL;
- MaxBufferSize = HII_LIB_DEFAULT_VARSTORE_SIZE;
- DataBuffer = AllocateZeroPool (MaxBufferSize);
- if (DataBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Init BlockArray
- //
- BlockArray = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));
- if (BlockArray == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
-
- InitializeListHead (&BlockArray->Entry);
-
- StringPtr = StrStr (ConfigElement, L"&OFFSET=");
- ASSERT (StringPtr != NULL);
-
- //
- // Parse each <RequestElement> if exists
- // Only <BlockName> format is supported by this help function.
- // <BlockName> ::= &'OFFSET='<Number>&'WIDTH='<Number>
- //
- while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {
- //
- // Skip the &OFFSET= string
- //
- StringPtr += StrLen (L"&OFFSET=");
-
- //
- // Get Offset
- //
- Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
-
- Offset = 0;
- CopyMem (
- &Offset,
- TmpBuffer,
- (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)
- );
- FreePool (TmpBuffer);
- TmpBuffer = NULL;
-
- StringPtr += Length;
- if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
-
- StringPtr += StrLen (L"&WIDTH=");
-
- //
- // Get Width
- //
- Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
-
- Width = 0;
- CopyMem (
- &Width,
- TmpBuffer,
- (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)
- );
- FreePool (TmpBuffer);
- TmpBuffer = NULL;
-
- StringPtr += Length;
- if ((*StringPtr != 0) && (*StringPtr != L'&')) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
-
- if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
-
- StringPtr += StrLen (L"&VALUE=");
-
- //
- // Get Value
- //
- Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
-
- StringPtr += Length;
- if ((*StringPtr != 0) && (*StringPtr != L'&')) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
-
- //
- // Check whether VarBuffer is enough
- //
- if ((UINT32)Offset + Width > MaxBufferSize) {
- DataBuffer = ReallocatePool (
- MaxBufferSize,
- Offset + Width + HII_LIB_DEFAULT_VARSTORE_SIZE,
- DataBuffer
- );
- if (DataBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
-
- MaxBufferSize = Offset + Width + HII_LIB_DEFAULT_VARSTORE_SIZE;
- }
-
- //
- // Update the Block with configuration info
- //
- CopyMem (DataBuffer + Offset, TmpBuffer, Width);
- FreePool (TmpBuffer);
- TmpBuffer = NULL;
-
- //
- // Set new Block Data
- //
- NewBlockData = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));
- if (NewBlockData == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
-
- NewBlockData->Offset = Offset;
- NewBlockData->Width = Width;
-
- //
- // Insert the new block data into the block data array.
- //
- for (Link = BlockArray->Entry.ForwardLink; Link != &BlockArray->Entry; Link = Link->ForwardLink) {
- BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
- if (NewBlockData->Offset == BlockData->Offset) {
- if (NewBlockData->Width > BlockData->Width) {
- BlockData->Width = NewBlockData->Width;
- }
-
- FreePool (NewBlockData);
- break;
- } else if (NewBlockData->Offset < BlockData->Offset) {
- //
- // Insert new block data as the previous one of this link.
- //
- InsertTailList (Link, &NewBlockData->Entry);
- break;
- }
- }
-
- //
- // Insert new block data into the array tail.
- //
- if (Link == &BlockArray->Entry) {
- InsertTailList (Link, &NewBlockData->Entry);
- }
-
- //
- // If '\0', parsing is finished.
- //
- if (*StringPtr == 0) {
- break;
- }
-
- //
- // Go to next ConfigBlock
- //
- }
-
- //
- // Merge the aligned block data into the single block data.
- //
- Link = BlockArray->Entry.ForwardLink;
- while ((Link != &BlockArray->Entry) && (Link->ForwardLink != &BlockArray->Entry)) {
- BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
- NewBlockData = BASE_CR (Link->ForwardLink, IFR_BLOCK_DATA, Entry);
- if ((NewBlockData->Offset >= BlockData->Offset) && (NewBlockData->Offset <= (BlockData->Offset + BlockData->Width))) {
- if ((NewBlockData->Offset + NewBlockData->Width) > (BlockData->Offset + BlockData->Width)) {
- BlockData->Width = (UINT16)(NewBlockData->Offset + NewBlockData->Width - BlockData->Offset);
- }
-
- RemoveEntryList (Link->ForwardLink);
- FreePool (NewBlockData);
- continue;
- }
-
- Link = Link->ForwardLink;
- }
-
- *VarBuffer = DataBuffer;
- *CurrentBlockArray = BlockArray;
- return EFI_SUCCESS;
-
-Done:
- if (DataBuffer != NULL) {
- FreePool (DataBuffer);
- }
-
- if (BlockArray != NULL) {
- //
- // Free Link Array CurrentBlockArray
- //
- while (!IsListEmpty (&BlockArray->Entry)) {
- BlockData = BASE_CR (BlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);
- RemoveEntryList (&BlockData->Entry);
- FreePool (BlockData);
- }
-
- FreePool (BlockArray);
- }
-
- return Status;
-}
-
-/**
- This internal function parses IFR data to validate current setting.
-
- @param ConfigResp ConfigResp string contains the current setting.
- @param HiiPackageList Point to Hii package list.
- @param PackageListLength The length of the pacakge.
- @param VarGuid Guid of the buffer storage.
- @param VarName Name of the buffer storage.
- @param HiiHandle The HiiHandle for this package.
-
- @retval EFI_SUCCESS The current setting is valid.
- @retval EFI_OUT_OF_RESOURCES The memory is not enough.
- @retval EFI_INVALID_PARAMETER The config string or the Hii package is invalid.
-**/
-EFI_STATUS
-EFIAPI
-InternalHiiValidateCurrentSetting (
- IN EFI_STRING ConfigResp,
- IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList,
- IN UINTN PackageListLength,
- IN EFI_GUID *VarGuid,
- IN CHAR16 *VarName,
- IN EFI_HII_HANDLE HiiHandle
- )
-{
- CHAR16 *StringPtr;
- EFI_STATUS Status;
- IFR_BLOCK_DATA *CurrentBlockArray;
- IFR_BLOCK_DATA *BlockData;
- UINT8 *VarBuffer;
- BOOLEAN NameValueType;
-
- CurrentBlockArray = NULL;
- VarBuffer = NULL;
- StringPtr = NULL;
- Status = EFI_SUCCESS;
-
- //
- // If StringPtr != NULL, get the request elements.
- //
- if (StrStr (ConfigResp, L"&OFFSET=") != NULL) {
- Status = GetBlockDataInfo (ConfigResp, &CurrentBlockArray, &VarBuffer);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- NameValueType = FALSE;
- } else {
- //
- // Skip header part.
- //
- StringPtr = StrStr (ConfigResp, L"PATH=");
- ASSERT (StringPtr != NULL);
-
- if (StrStr (StringPtr, L"&") != NULL) {
- NameValueType = TRUE;
- } else {
- //
- // Not found Request element, return success.
- //
- return EFI_SUCCESS;
- }
- }
-
- Status = ValidateQuestionFromVfr (
- HiiPackageList,
- PackageListLength,
- VarGuid,
- VarName,
- VarBuffer,
- CurrentBlockArray,
- ConfigResp,
- HiiHandle,
- NameValueType
- );
-
- if (VarBuffer != NULL) {
- FreePool (VarBuffer);
- }
-
- if (CurrentBlockArray != NULL) {
- //
- // Free Link Array CurrentBlockArray
- //
- while (!IsListEmpty (&CurrentBlockArray->Entry)) {
- BlockData = BASE_CR (CurrentBlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);
- RemoveEntryList (&BlockData->Entry);
- FreePool (BlockData);
- }
-
- FreePool (CurrentBlockArray);
- }
-
- return Status;
-}
-
-/**
- Check whether the ConfigRequest string has the request elements.
- For EFI_HII_VARSTORE_BUFFER type, the request has "&OFFSET=****&WIDTH=****..." format.
- For EFI_HII_VARSTORE_NAME_VALUE type, the request has "&NAME1**&NAME2..." format.
-
- @param ConfigRequest The input config request string.
-
- @retval TRUE The input include config request elements.
- @retval FALSE The input string not includes.
-
-**/
-BOOLEAN
-GetElementsFromRequest (
- IN EFI_STRING ConfigRequest
- )
-{
- EFI_STRING TmpRequest;
-
- TmpRequest = StrStr (ConfigRequest, L"PATH=");
- ASSERT (TmpRequest != NULL);
-
- if ((StrStr (TmpRequest, L"&OFFSET=") != NULL) || (StrStr (TmpRequest, L"&") != NULL)) {
- return TRUE;
- }
-
- return FALSE;
-}
-
-/**
- This function parses the input ConfigRequest string and its matched IFR code
- string for setting default value and validating current setting.
-
- 1. For setting default action, Reset the default value specified by DefaultId
- to the driver configuration got by Request string.
- 2. For validating current setting, Validate the current configuration
- by parsing HII form IFR opcode.
-
- NULL request string support depends on the ExportConfig interface of
- HiiConfigRouting protocol in UEFI specification.
-
- @param Request A null-terminated Unicode string in
- <MultiConfigRequest> format. It can be NULL.
- If it is NULL, all current configuration for the
- entirety of the current HII database will be validated.
- If it is NULL, all configuration for the
- entirety of the current HII database will be reset.
- @param DefaultId Specifies the type of defaults to retrieve only for setting default action.
- @param ActionType Action supports setting defaults and validate current setting.
-
- @retval TRUE Action runs successfully.
- @retval FALSE Action is not valid or Action can't be executed successfully..
-**/
-BOOLEAN
-EFIAPI
-InternalHiiIfrValueAction (
- IN CONST EFI_STRING Request OPTIONAL,
- IN UINT16 DefaultId,
- IN UINT8 ActionType
- )
-{
- EFI_STRING ConfigAltResp;
- EFI_STRING ConfigAltHdr;
- EFI_STRING ConfigResp;
- EFI_STRING Progress;
- EFI_STRING StringPtr;
- EFI_STRING StringHdr;
- EFI_STATUS Status;
- EFI_HANDLE DriverHandle;
- EFI_HANDLE TempDriverHandle;
- EFI_HII_HANDLE *HiiHandleBuffer;
- EFI_HII_HANDLE HiiHandle;
- UINT32 Index;
- EFI_GUID *VarGuid;
- EFI_STRING VarName;
-
- EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
- UINTN PackageListLength;
- UINTN MaxLen;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
-
- ConfigAltResp = NULL;
- ConfigResp = NULL;
- VarGuid = NULL;
- VarName = NULL;
- DevicePath = NULL;
- ConfigAltHdr = NULL;
- HiiHandleBuffer = NULL;
- Index = 0;
- TempDriverHandle = NULL;
- HiiHandle = NULL;
- HiiPackageList = NULL;
-
- //
- // Only support set default and validate setting action.
- //
- if ((ActionType != ACTION_SET_DEFAUTL_VALUE) && (ActionType != ACTION_VALIDATE_SETTING)) {
- return FALSE;
- }
-
- //
- // Get the full requested value and deault value string.
- //
- if (Request != NULL) {
- Status = gHiiConfigRouting->ExtractConfig (
- gHiiConfigRouting,
- Request,
- &Progress,
- &ConfigAltResp
- );
- } else {
- Status = gHiiConfigRouting->ExportConfig (
- gHiiConfigRouting,
- &ConfigAltResp
- );
- }
-
- if (EFI_ERROR (Status)) {
- return FALSE;
- }
-
- StringPtr = ConfigAltResp;
- ASSERT (StringPtr != NULL);
-
- while (*StringPtr != L'\0') {
- //
- // 1. Find <ConfigHdr> GUID=...&NAME=...&PATH=...
- //
- StringHdr = StringPtr;
-
- //
- // Get Guid value
- //
- if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
-
- StringPtr += StrLen (L"GUID=");
- Status = InternalHiiGetBufferFromString (StringPtr, GUID_CONFIG_STRING_TYPE, (UINT8 **)&VarGuid);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
-
- //
- // Get Name value VarName
- //
- while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&NAME=", StrLen (L"&NAME=")) != 0) {
- StringPtr++;
- }
-
- if (*StringPtr == L'\0') {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
-
- StringPtr += StrLen (L"&NAME=");
- Status = InternalHiiGetBufferFromString (StringPtr, NAME_CONFIG_STRING_TYPE, (UINT8 **)&VarName);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
-
- //
- // Get Path value DevicePath
- //
- while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) {
- StringPtr++;
- }
-
- if (*StringPtr == L'\0') {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
-
- StringPtr += StrLen (L"&PATH=");
- Status = InternalHiiGetBufferFromString (StringPtr, PATH_CONFIG_STRING_TYPE, (UINT8 **)&DevicePath);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
-
- //
- // Get the Driver handle by the got device path.
- //
- TempDevicePath = DevicePath;
- Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &TempDevicePath, &DriverHandle);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
-
- //
- // Find the matched Hii Handle for the found Driver handle
- //
- HiiHandleBuffer = HiiGetHiiHandles (NULL);
- if (HiiHandleBuffer == NULL) {
- Status = EFI_NOT_FOUND;
- goto Done;
- }
-
- for (Index = 0; HiiHandleBuffer[Index] != NULL; Index++) {
- gHiiDatabase->GetPackageListHandle (gHiiDatabase, HiiHandleBuffer[Index], &TempDriverHandle);
- if (TempDriverHandle == DriverHandle) {
- break;
- }
- }
-
- HiiHandle = HiiHandleBuffer[Index];
- FreePool (HiiHandleBuffer);
-
- 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 HiiPackage by HiiHandle
- //
- PackageListLength = 0;
- HiiPackageList = NULL;
- Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, 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 = AllocatePool (PackageListLength);
- if (HiiPackageList == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
-
- //
- // Get PackageList on HiiHandle
- //
- Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, HiiHandle, &PackageListLength, HiiPackageList);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
-
- //
- // 3. Call ConfigRouting GetAltCfg(ConfigRoute, <ConfigResponse>, Guid, Name, DevicePath, AltCfgId, AltCfgResp)
- // Get the default configuration string according to the default ID.
- //
- Status = gHiiConfigRouting->GetAltConfig (
- gHiiConfigRouting,
- ConfigAltResp,
- VarGuid,
- VarName,
- DevicePath,
- (ActionType == ACTION_SET_DEFAUTL_VALUE) ? &DefaultId : NULL, // 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 (!GetElementsFromRequest (ConfigResp)) {
- 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.
- //
- if (ActionType == ACTION_SET_DEFAUTL_VALUE) {
- //
- // Set the default configuration information.
- //
- Status = gHiiConfigRouting->RouteConfig (gHiiConfigRouting, ConfigResp, &Progress);
- } else {
- //
- // Current Setting is in ConfigResp, will be set into buffer, then check it again.
- //
- Status = InternalHiiValidateCurrentSetting (ConfigResp, HiiPackageList, PackageListLength, VarGuid, VarName, HiiHandle);
- }
-
- if (EFI_ERROR (Status)) {
- goto Done;
- }
-
-NextConfigAltResp:
- //
- // Free the allocated pacakge buffer and the got ConfigResp string.
- //
- if (HiiPackageList != NULL) {
- FreePool (HiiPackageList);
- HiiPackageList = NULL;
- }
-
- if (ConfigResp != NULL) {
- FreePool (ConfigResp);
- ConfigResp = NULL;
- }
-
- //
- // Free the allocated buffer.
- //
- FreePool (VarGuid);
- VarGuid = NULL;
-
- FreePool (VarName);
- VarName = NULL;
-
- 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 | StrLen (ConfigHdr) | 8 | 1 |
- //
- MaxLen = 1 + StringPtr - StringHdr + 8 + 1;
- ConfigAltHdr = AllocateZeroPool (MaxLen * sizeof (CHAR16));
- if (ConfigAltHdr == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
-
- StrCpyS (ConfigAltHdr, MaxLen, L"&");
- StrnCatS (ConfigAltHdr, MaxLen, StringHdr, StringPtr - StringHdr);
- StrCatS (ConfigAltHdr, MaxLen, L"&ALTCFG=");
-
- //
- // Skip all AltResp (AltConfigHdr ConfigBody) for the same ConfigHdr
- //
- while ((StringHdr = StrStr (StringPtr, ConfigAltHdr)) != NULL) {
- StringPtr = StringHdr + StrLen (ConfigAltHdr);
- if (*StringPtr == L'\0') {
- break;
- }
- }
-
- //
- // Free the allocated ConfigAltHdr string
- //
- FreePool (ConfigAltHdr);
- if (*StringPtr == L'\0') {
- break;
- }
-
- //
- // Find &GUID as the next ConfigHdr
- //
- StringPtr = StrStr (StringPtr, L"&GUID");
- if (StringPtr == NULL) {
- break;
- }
-
- //
- // Skip char '&'
- //
- StringPtr++;
- }
-
-Done:
- if (VarGuid != NULL) {
- FreePool (VarGuid);
- }
-
- if (VarName != NULL) {
- FreePool (VarName);
- }
-
- if (DevicePath != NULL) {
- FreePool (DevicePath);
- }
-
- if (ConfigResp != NULL) {
- FreePool (ConfigResp);
- }
-
- if (ConfigAltResp != NULL) {
- FreePool (ConfigAltResp);
- }
-
- if (HiiPackageList != NULL) {
- FreePool (HiiPackageList);
- }
-
- if (EFI_ERROR (Status)) {
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- Validate the current configuration by parsing HII form IFR opcode.
-
- NULL request string support depends on the ExportConfig interface of
- HiiConfigRouting protocol in UEFI specification.
-
- @param Request A null-terminated Unicode string in
- <MultiConfigRequest> format. It can be NULL.
- If it is NULL, all current configuration for the
- entirety of the current HII database will be validated.
-
- @retval TRUE Current configuration is valid.
- @retval FALSE Current configuration is invalid.
-**/
-BOOLEAN
-EFIAPI
-HiiValidateSettings (
- IN CONST EFI_STRING Request OPTIONAL
- )
-{
- return InternalHiiIfrValueAction (Request, 0, ACTION_VALIDATE_SETTING);
-}
-
-/**
- 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.
-
- @param 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.
- @param DefaultId Specifies the type of defaults to retrieve.
-
- @retval TRUE The default value is set successfully.
- @retval FALSE The default value can't be found and set.
-**/
-BOOLEAN
-EFIAPI
-HiiSetToDefaults (
- IN CONST EFI_STRING Request OPTIONAL,
- IN UINT16 DefaultId
- )
-{
- return InternalHiiIfrValueAction (Request, DefaultId, ACTION_SET_DEFAUTL_VALUE);
-}
-
-/**
- Determines if two values in config strings match.
-
- Compares the substring between StartSearchString and StopSearchString in
- FirstString to the substring between StartSearchString and StopSearchString
- in SecondString. If the two substrings match, then TRUE is returned. If the
- two substrings do not match, then FALSE is returned.
-
- If FirstString is NULL, then ASSERT().
- If SecondString is NULL, then ASSERT().
- If StartSearchString is NULL, then ASSERT().
- If StopSearchString is NULL, then ASSERT().
-
- @param FirstString Pointer to the first Null-terminated Unicode string.
- @param SecondString Pointer to the second Null-terminated Unicode string.
- @param StartSearchString Pointer to the Null-terminated Unicode string that
- marks the start of the value string to compare.
- @param StopSearchString Pointer to the Null-terminated Unicode string that
- marks the end of the value string to compare.
-
- @retval FALSE StartSearchString is not present in FirstString.
- @retval FALSE StartSearchString is not present in SecondString.
- @retval FALSE StopSearchString is not present in FirstString.
- @retval FALSE StopSearchString is not present in SecondString.
- @retval FALSE The length of the substring in FirstString is not the
- same length as the substring in SecondString.
- @retval FALSE The value string in FirstString does not matche the
- value string in SecondString.
- @retval TRUE The value string in FirstString matches the value
- string in SecondString.
-
-**/
-BOOLEAN
-EFIAPI
-InternalHiiCompareSubString (
- IN CHAR16 *FirstString,
- IN CHAR16 *SecondString,
- IN CHAR16 *StartSearchString,
- IN CHAR16 *StopSearchString
- )
-{
- CHAR16 *EndFirstString;
- CHAR16 *EndSecondString;
-
- ASSERT (FirstString != NULL);
- ASSERT (SecondString != NULL);
- ASSERT (StartSearchString != NULL);
- ASSERT (StopSearchString != NULL);
-
- FirstString = StrStr (FirstString, StartSearchString);
- if (FirstString == NULL) {
- return FALSE;
- }
-
- SecondString = StrStr (SecondString, StartSearchString);
- if (SecondString == NULL) {
- return FALSE;
- }
-
- EndFirstString = StrStr (FirstString, StopSearchString);
- if (EndFirstString == NULL) {
- return FALSE;
- }
-
- EndSecondString = StrStr (SecondString, StopSearchString);
- if (EndSecondString == NULL) {
- return FALSE;
- }
-
- if ((EndFirstString - FirstString) != (EndSecondString - SecondString)) {
- return FALSE;
- }
-
- return (BOOLEAN)(StrnCmp (FirstString, SecondString, EndFirstString - FirstString) == 0);
-}
-
-/**
- Determines if the routing data specified by GUID and NAME match a <ConfigHdr>.
-
- If ConfigHdr is NULL, then ASSERT().
-
- @param[in] ConfigHdr Either <ConfigRequest> or <ConfigResp>.
- @param[in] Guid GUID of the storage.
- @param[in] Name NAME of the storage.
-
- @retval TRUE Routing information matches <ConfigHdr>.
- @retval FALSE Routing information does not match <ConfigHdr>.
-
-**/
-BOOLEAN
-EFIAPI
-HiiIsConfigHdrMatch (
- IN CONST EFI_STRING ConfigHdr,
- IN CONST EFI_GUID *Guid OPTIONAL,
- IN CONST CHAR16 *Name OPTIONAL
- )
-{
- EFI_STRING CompareConfigHdr;
- BOOLEAN Result;
-
- ASSERT (ConfigHdr != NULL);
-
- //
- // Use Guid and Name to generate a <ConfigHdr> string
- //
- CompareConfigHdr = HiiConstructConfigHdr (Guid, Name, NULL);
- if (CompareConfigHdr == NULL) {
- return FALSE;
- }
-
- Result = TRUE;
- if (Guid != NULL) {
- //
- // Compare GUID value strings
- //
- Result = InternalHiiCompareSubString (ConfigHdr, CompareConfigHdr, L"GUID=", L"&NAME=");
- }
-
- if (Result && (Name != NULL)) {
- //
- // Compare NAME value strings
- //
- Result = InternalHiiCompareSubString (ConfigHdr, CompareConfigHdr, L"&NAME=", L"&PATH=");
- }
-
- //
- // Free the <ConfigHdr> string
- //
- FreePool (CompareConfigHdr);
-
- return Result;
-}
-
-/**
- Retrieves uncommitted data from the Form Browser and converts it to a binary
- buffer.
-
- @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional
- parameter that may be NULL.
- @param[in] VariableName Pointer to a Null-terminated Unicode string. This
- is an optional parameter that may be NULL.
- @param[in] BufferSize Length in bytes of buffer to hold retrieved data.
- @param[out] Buffer Buffer of data to be updated.
-
- @retval FALSE The uncommitted data could not be retrieved.
- @retval TRUE The uncommitted data was retrieved.
-
-**/
-BOOLEAN
-EFIAPI
-HiiGetBrowserData (
- IN CONST EFI_GUID *VariableGuid OPTIONAL,
- IN CONST CHAR16 *VariableName OPTIONAL,
- IN UINTN BufferSize,
- OUT UINT8 *Buffer
- )
-{
- EFI_STRING ResultsData;
- UINTN Size;
- EFI_STRING ConfigResp;
- EFI_STATUS Status;
- CHAR16 *Progress;
-
- //
- // Retrieve the results data from the Browser Callback
- //
- ResultsData = InternalHiiBrowserCallback (VariableGuid, VariableName, NULL);
- if (ResultsData == NULL) {
- return FALSE;
- }
-
- //
- // Construct <ConfigResp> mConfigHdrTemplate L'&' ResultsData L'\0'
- //
- Size = (StrLen (mConfigHdrTemplate) + 1) * sizeof (CHAR16);
- Size = Size + (StrLen (ResultsData) + 1) * sizeof (CHAR16);
- ConfigResp = AllocateZeroPool (Size);
- UnicodeSPrint (ConfigResp, Size, L"%s&%s", mConfigHdrTemplate, ResultsData);
-
- //
- // Free the allocated buffer
- //
- FreePool (ResultsData);
- if (ConfigResp == NULL) {
- return FALSE;
- }
-
- //
- // Convert <ConfigResp> to a buffer
- //
- Status = gHiiConfigRouting->ConfigToBlock (
- gHiiConfigRouting,
- ConfigResp,
- Buffer,
- &BufferSize,
- &Progress
- );
- //
- // Free the allocated buffer
- //
- FreePool (ConfigResp);
-
- if (EFI_ERROR (Status)) {
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- Updates uncommitted data in the Form Browser.
-
- If Buffer is NULL, then ASSERT().
-
- @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional
- parameter that may be NULL.
- @param[in] VariableName Pointer to a Null-terminated Unicode string. This
- is an optional parameter that may be NULL.
- @param[in] BufferSize Length, in bytes, of Buffer.
- @param[in] Buffer Buffer of data to commit.
- @param[in] 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>*
-
- @retval FALSE The uncommitted data could not be updated.
- @retval TRUE The uncommitted data was updated.
-
-**/
-BOOLEAN
-EFIAPI
-HiiSetBrowserData (
- IN CONST EFI_GUID *VariableGuid OPTIONAL,
- IN CONST CHAR16 *VariableName OPTIONAL,
- IN UINTN BufferSize,
- IN CONST UINT8 *Buffer,
- IN CONST CHAR16 *RequestElement OPTIONAL
- )
-{
- UINTN Size;
- EFI_STRING ConfigRequest;
- EFI_STRING ConfigResp;
- EFI_STRING ResultsData;
-
- ASSERT (Buffer != NULL);
-
- //
- // Construct <ConfigRequest>
- //
- if (RequestElement == NULL) {
- //
- // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
- // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
- //
- Size = (StrLen (mConfigHdrTemplate) + 32 + 1) * sizeof (CHAR16);
- ConfigRequest = AllocateZeroPool (Size);
- UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", mConfigHdrTemplate, (UINT64)BufferSize);
- } else {
- //
- // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
- // followed by <RequestElement> followed by a Null-terminator
- //
- Size = StrLen (mConfigHdrTemplate) * sizeof (CHAR16);
- Size = Size + (StrLen (RequestElement) + 1) * sizeof (CHAR16);
- ConfigRequest = AllocateZeroPool (Size);
- UnicodeSPrint (ConfigRequest, Size, L"%s%s", mConfigHdrTemplate, RequestElement);
- }
-
- if (ConfigRequest == NULL) {
- return FALSE;
- }
-
- //
- // Convert <ConfigRequest> to <ConfigResp>
- //
- ConfigResp = InternalHiiBlockToConfig (ConfigRequest, Buffer, BufferSize);
- FreePool (ConfigRequest);
- if (ConfigResp == NULL) {
- return FALSE;
- }
-
- //
- // Set data in the uncommitted browser state information
- //
- ResultsData = InternalHiiBrowserCallback (VariableGuid, VariableName, ConfigResp + StrLen (mConfigHdrTemplate) + 1);
- FreePool (ConfigResp);
-
- return (BOOLEAN)(ResultsData != NULL);
-}
-
-/////////////////////////////////////////
-/////////////////////////////////////////
-/// IFR Functions
-/////////////////////////////////////////
-/////////////////////////////////////////
-
-#define HII_LIB_OPCODE_ALLOCATION_SIZE 0x200
-
-typedef struct {
- UINT8 *Buffer;
- UINTN BufferSize;
- UINTN Position;
-} HII_LIB_OPCODE_BUFFER;
-
-///
-/// Lookup table that converts EFI_IFR_TYPE_X enum values to a width in bytes
-///
-GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 mHiiDefaultTypeToWidth[] = {
- 1, // EFI_IFR_TYPE_NUM_SIZE_8
- 2, // EFI_IFR_TYPE_NUM_SIZE_16
- 4, // EFI_IFR_TYPE_NUM_SIZE_32
- 8, // EFI_IFR_TYPE_NUM_SIZE_64
- 1, // EFI_IFR_TYPE_BOOLEAN
- 3, // EFI_IFR_TYPE_TIME
- 4, // EFI_IFR_TYPE_DATE
- 2 // EFI_IFR_TYPE_STRING
-};
-
-/**
- Allocates and returns a new OpCode Handle. OpCode Handles must be freed with
- HiiFreeOpCodeHandle().
-
- @retval NULL There are not enough resources to allocate a new OpCode Handle.
- @retval Other A new OpCode handle.
-
-**/
-VOID *
-EFIAPI
-HiiAllocateOpCodeHandle (
- VOID
- )
-{
- HII_LIB_OPCODE_BUFFER *OpCodeBuffer;
-
- OpCodeBuffer = (HII_LIB_OPCODE_BUFFER *)AllocatePool (sizeof (HII_LIB_OPCODE_BUFFER));
- if (OpCodeBuffer == NULL) {
- return NULL;
- }
-
- OpCodeBuffer->Buffer = (UINT8 *)AllocatePool (HII_LIB_OPCODE_ALLOCATION_SIZE);
- if (OpCodeBuffer->Buffer == NULL) {
- FreePool (OpCodeBuffer);
- return NULL;
- }
-
- OpCodeBuffer->BufferSize = HII_LIB_OPCODE_ALLOCATION_SIZE;
- OpCodeBuffer->Position = 0;
- return (VOID *)OpCodeBuffer;
-}
-
-/**
- Frees an OpCode Handle that was previously allocated with HiiAllocateOpCodeHandle().
- When an OpCode Handle is freed, all of the opcodes associated with the OpCode
- Handle are also freed.
-
- If OpCodeHandle is NULL, then ASSERT().
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
-
-**/
-VOID
-EFIAPI
-HiiFreeOpCodeHandle (
- VOID *OpCodeHandle
- )
-{
- HII_LIB_OPCODE_BUFFER *OpCodeBuffer;
-
- ASSERT (OpCodeHandle != NULL);
-
- OpCodeBuffer = (HII_LIB_OPCODE_BUFFER *)OpCodeHandle;
- if (OpCodeBuffer->Buffer != NULL) {
- FreePool (OpCodeBuffer->Buffer);
- }
-
- FreePool (OpCodeBuffer);
-}
-
-/**
- Internal function gets the current position of opcode buffer.
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
-
- @return Current position of opcode buffer.
-**/
-UINTN
-EFIAPI
-InternalHiiOpCodeHandlePosition (
- IN VOID *OpCodeHandle
- )
-{
- return ((HII_LIB_OPCODE_BUFFER *)OpCodeHandle)->Position;
-}
-
-/**
- Internal function gets the start pointer of opcode buffer.
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
-
- @return Pointer to the opcode buffer base.
-**/
-UINT8 *
-EFIAPI
-InternalHiiOpCodeHandleBuffer (
- IN VOID *OpCodeHandle
- )
-{
- return ((HII_LIB_OPCODE_BUFFER *)OpCodeHandle)->Buffer;
-}
-
-/**
- Internal function reserves the enough buffer for current opcode.
- When the buffer is not enough, Opcode buffer will be extended.
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] Size Size of current opcode.
-
- @return Pointer to the current opcode.
-**/
-UINT8 *
-EFIAPI
-InternalHiiGrowOpCodeHandle (
- IN VOID *OpCodeHandle,
- IN UINTN Size
- )
-{
- HII_LIB_OPCODE_BUFFER *OpCodeBuffer;
- UINT8 *Buffer;
-
- ASSERT (OpCodeHandle != NULL);
-
- OpCodeBuffer = (HII_LIB_OPCODE_BUFFER *)OpCodeHandle;
- if (OpCodeBuffer->Position + Size > OpCodeBuffer->BufferSize) {
- Buffer = ReallocatePool (
- OpCodeBuffer->BufferSize,
- OpCodeBuffer->BufferSize + (Size + HII_LIB_OPCODE_ALLOCATION_SIZE),
- OpCodeBuffer->Buffer
- );
- ASSERT (Buffer != NULL);
- OpCodeBuffer->Buffer = Buffer;
- OpCodeBuffer->BufferSize += (Size + HII_LIB_OPCODE_ALLOCATION_SIZE);
- }
-
- Buffer = OpCodeBuffer->Buffer + OpCodeBuffer->Position;
- OpCodeBuffer->Position += Size;
- return Buffer;
-}
-
-/**
- Internal function creates opcode based on the template opcode.
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] OpCodeTemplate Pointer to the template buffer of opcode.
- @param[in] OpCode OpCode IFR value.
- @param[in] OpCodeSize Size of opcode.
- @param[in] ExtensionSize Size of extended opcode.
- @param[in] Scope Scope bit of opcode.
-
- @return Pointer to the current opcode with opcode data.
-**/
-UINT8 *
-EFIAPI
-InternalHiiCreateOpCodeExtended (
- IN VOID *OpCodeHandle,
- IN VOID *OpCodeTemplate,
- IN UINT8 OpCode,
- IN UINTN OpCodeSize,
- IN UINTN ExtensionSize,
- IN UINT8 Scope
- )
-{
- EFI_IFR_OP_HEADER *Header;
- UINT8 *Buffer;
-
- ASSERT (OpCodeTemplate != NULL);
- ASSERT ((OpCodeSize + ExtensionSize) <= 0x7F);
-
- Header = (EFI_IFR_OP_HEADER *)OpCodeTemplate;
- Header->OpCode = OpCode;
- Header->Scope = Scope;
- Header->Length = (UINT8)(OpCodeSize + ExtensionSize);
- Buffer = InternalHiiGrowOpCodeHandle (OpCodeHandle, Header->Length);
- return (UINT8 *)CopyMem (Buffer, Header, OpCodeSize);
-}
-
-/**
- Internal function creates opcode based on the template opcode for the normal opcode.
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] OpCodeTemplate Pointer to the template buffer of opcode.
- @param[in] OpCode OpCode IFR value.
- @param[in] OpCodeSize Size of opcode.
-
- @return Pointer to the current opcode with opcode data.
-**/
-UINT8 *
-EFIAPI
-InternalHiiCreateOpCode (
- IN VOID *OpCodeHandle,
- IN VOID *OpCodeTemplate,
- IN UINT8 OpCode,
- IN UINTN OpCodeSize
- )
-{
- return InternalHiiCreateOpCodeExtended (OpCodeHandle, OpCodeTemplate, OpCode, OpCodeSize, 0, 0);
-}
-
-/**
- Append raw opcodes to an OpCodeHandle.
-
- If OpCodeHandle is NULL, then ASSERT().
- If RawBuffer is NULL, then ASSERT();
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] RawBuffer Buffer of opcodes to append.
- @param[in] RawBufferSize The size, in bytes, of Buffer.
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the appended opcodes.
-
-**/
-UINT8 *
-EFIAPI
-HiiCreateRawOpCodes (
- IN VOID *OpCodeHandle,
- IN UINT8 *RawBuffer,
- IN UINTN RawBufferSize
- )
-{
- UINT8 *Buffer;
-
- ASSERT (RawBuffer != NULL);
-
- Buffer = InternalHiiGrowOpCodeHandle (OpCodeHandle, RawBufferSize);
- return (UINT8 *)CopyMem (Buffer, RawBuffer, RawBufferSize);
-}
-
-/**
- Append opcodes from one OpCode Handle to another OpCode handle.
-
- If OpCodeHandle is NULL, then ASSERT().
- If RawOpCodeHandle is NULL, then ASSERT();
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] RawOpCodeHandle Handle to the buffer of opcodes.
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the appended opcodes.
-
-**/
-UINT8 *
-EFIAPI
-InternalHiiAppendOpCodes (
- IN VOID *OpCodeHandle,
- IN VOID *RawOpCodeHandle
- )
-{
- HII_LIB_OPCODE_BUFFER *RawOpCodeBuffer;
-
- ASSERT (RawOpCodeHandle != NULL);
-
- RawOpCodeBuffer = (HII_LIB_OPCODE_BUFFER *)RawOpCodeHandle;
- return HiiCreateRawOpCodes (OpCodeHandle, RawOpCodeBuffer->Buffer, RawOpCodeBuffer->Position);
-}
-
-/**
- Create EFI_IFR_END_OP opcode.
-
- If OpCodeHandle is NULL, then ASSERT().
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the created opcode.
-
-**/
-UINT8 *
-EFIAPI
-HiiCreateEndOpCode (
- IN VOID *OpCodeHandle
- )
-{
- EFI_IFR_END OpCode;
-
- return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_END_OP, sizeof (OpCode));
-}
-
-/**
- Create EFI_IFR_ONE_OF_OPTION_OP opcode.
-
- If OpCodeHandle is NULL, then ASSERT().
- If Type is invalid, then ASSERT().
- If Flags is invalid, then ASSERT().
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] StringId StringId for the option
- @param[in] Flags Flags for the option
- @param[in] Type Type for the option
- @param[in] Value Value for the option
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the created opcode.
-
-**/
-UINT8 *
-EFIAPI
-HiiCreateOneOfOptionOpCode (
- IN VOID *OpCodeHandle,
- IN UINT16 StringId,
- IN UINT8 Flags,
- IN UINT8 Type,
- IN UINT64 Value
- )
-{
- EFI_IFR_ONE_OF_OPTION OpCode;
-
- ASSERT (Type < EFI_IFR_TYPE_OTHER);
-
- ZeroMem (&OpCode, sizeof (OpCode));
- OpCode.Option = StringId;
- OpCode.Flags = (UINT8)(Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG));
- OpCode.Type = Type;
- CopyMem (&OpCode.Value, &Value, mHiiDefaultTypeToWidth[Type]);
-
- return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_ONE_OF_OPTION_OP, OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value) + mHiiDefaultTypeToWidth[Type]);
-}
-
-/**
- Create EFI_IFR_DEFAULT_OP opcode.
-
- If OpCodeHandle is NULL, then ASSERT().
- If Type is invalid, then ASSERT().
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] DefaultId DefaultId for the default
- @param[in] Type Type for the default
- @param[in] Value Value for the default
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the created opcode.
-
-**/
-UINT8 *
-EFIAPI
-HiiCreateDefaultOpCode (
- IN VOID *OpCodeHandle,
- IN UINT16 DefaultId,
- IN UINT8 Type,
- IN UINT64 Value
- )
-{
- EFI_IFR_DEFAULT OpCode;
-
- ASSERT (Type < EFI_IFR_TYPE_OTHER);
-
- ZeroMem (&OpCode, sizeof (OpCode));
- OpCode.Type = Type;
- OpCode.DefaultId = DefaultId;
- CopyMem (&OpCode.Value, &Value, mHiiDefaultTypeToWidth[Type]);
-
- return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_DEFAULT_OP, OFFSET_OF (EFI_IFR_DEFAULT, Value) + mHiiDefaultTypeToWidth[Type]);
-}
-
-/**
- Create EFI_IFR_GUID opcode.
-
- If OpCodeHandle is NULL, then ASSERT().
- If Guid is NULL, then ASSERT().
- If OpCodeSize < sizeof (EFI_IFR_GUID), then ASSERT().
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] Guid Pointer to EFI_GUID of this guided opcode.
- @param[in] GuidOpCode Pointer to an EFI_IFR_GUID opcode. This is an
- optional parameter that may be NULL. If this
- parameter is NULL, then the GUID extension
- region of the created opcode is filled with zeros.
- If this parameter is not NULL, then the GUID
- extension region of GuidData will be copied to
- the GUID extension region of the created opcode.
- @param[in] OpCodeSize The size, in bytes, of created opcode. This value
- must be >= sizeof(EFI_IFR_GUID).
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the created opcode.
-
-**/
-UINT8 *
-EFIAPI
-HiiCreateGuidOpCode (
- IN VOID *OpCodeHandle,
- IN CONST EFI_GUID *Guid,
- IN CONST VOID *GuidOpCode OPTIONAL,
- IN UINTN OpCodeSize
- )
-{
- EFI_IFR_GUID OpCode;
- EFI_IFR_GUID *OpCodePointer;
-
- ASSERT (Guid != NULL);
- ASSERT (OpCodeSize >= sizeof (OpCode));
-
- ZeroMem (&OpCode, sizeof (OpCode));
- CopyGuid ((EFI_GUID *)(VOID *)&OpCode.Guid, Guid);
-
- OpCodePointer = (EFI_IFR_GUID *)InternalHiiCreateOpCodeExtended (
- OpCodeHandle,
- &OpCode,
- EFI_IFR_GUID_OP,
- sizeof (OpCode),
- OpCodeSize - sizeof (OpCode),
- 0
- );
- if ((OpCodePointer != NULL) && (GuidOpCode != NULL)) {
- CopyMem (OpCodePointer + 1, (EFI_IFR_GUID *)GuidOpCode + 1, OpCodeSize - sizeof (OpCode));
- }
-
- return (UINT8 *)OpCodePointer;
-}
-
-/**
- Create EFI_IFR_ACTION_OP opcode.
-
- If OpCodeHandle is NULL, then ASSERT().
- If any reserved bits are set in QuestionFlags, then ASSERT().
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] QuestionId Question ID
- @param[in] Prompt String ID for Prompt
- @param[in] Help String ID for Help
- @param[in] QuestionFlags Flags in Question Header
- @param[in] QuestionConfig String ID for configuration
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the created opcode.
-
-**/
-UINT8 *
-EFIAPI
-HiiCreateActionOpCode (
- IN VOID *OpCodeHandle,
- IN EFI_QUESTION_ID QuestionId,
- IN EFI_STRING_ID Prompt,
- IN EFI_STRING_ID Help,
- IN UINT8 QuestionFlags,
- IN EFI_STRING_ID QuestionConfig
- )
-{
- EFI_IFR_ACTION OpCode;
-
- ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED))) == 0);
-
- ZeroMem (&OpCode, sizeof (OpCode));
- OpCode.Question.QuestionId = QuestionId;
- OpCode.Question.Header.Prompt = Prompt;
- OpCode.Question.Header.Help = Help;
- OpCode.Question.Flags = QuestionFlags;
- OpCode.QuestionConfig = QuestionConfig;
-
- return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_ACTION_OP, sizeof (OpCode));
-}
-
-/**
- Create EFI_IFR_SUBTITLE_OP opcode.
-
- If OpCodeHandle is NULL, then ASSERT().
- If any reserved bits are set in Flags, then ASSERT().
- If Scope > 1, then ASSERT().
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] Prompt String ID for Prompt
- @param[in] Help String ID for Help
- @param[in] Flags Subtitle opcode flags
- @param[in] Scope 1 if this opcpde is the beginning of a new scope.
- 0 if this opcode is within the current scope.
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the created opcode.
-
-**/
-UINT8 *
-EFIAPI
-HiiCreateSubTitleOpCode (
- IN VOID *OpCodeHandle,
- IN EFI_STRING_ID Prompt,
- IN EFI_STRING_ID Help,
- IN UINT8 Flags,
- IN UINT8 Scope
- )
-{
- EFI_IFR_SUBTITLE OpCode;
-
- ASSERT (Scope <= 1);
- ASSERT ((Flags & (~(EFI_IFR_FLAGS_HORIZONTAL))) == 0);
-
- ZeroMem (&OpCode, sizeof (OpCode));
- OpCode.Statement.Prompt = Prompt;
- OpCode.Statement.Help = Help;
- OpCode.Flags = Flags;
-
- return InternalHiiCreateOpCodeExtended (
- OpCodeHandle,
- &OpCode,
- EFI_IFR_SUBTITLE_OP,
- sizeof (OpCode),
- 0,
- Scope
- );
-}
-
-/**
- Create EFI_IFR_REF_OP opcode.
-
- If OpCodeHandle is NULL, then ASSERT().
- If any reserved bits are set in QuestionFlags, then ASSERT().
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] FormId Destination Form ID
- @param[in] Prompt String ID for Prompt
- @param[in] Help String ID for Help
- @param[in] QuestionFlags Flags in Question Header
- @param[in] QuestionId Question ID
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the created opcode.
-
-**/
-UINT8 *
-EFIAPI
-HiiCreateGotoOpCode (
- IN VOID *OpCodeHandle,
- IN EFI_FORM_ID FormId,
- IN EFI_STRING_ID Prompt,
- IN EFI_STRING_ID Help,
- IN UINT8 QuestionFlags,
- IN EFI_QUESTION_ID QuestionId
- )
-{
- EFI_IFR_REF OpCode;
-
- ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED))) == 0);
-
- ZeroMem (&OpCode, sizeof (OpCode));
- OpCode.Question.Header.Prompt = Prompt;
- OpCode.Question.Header.Help = Help;
- OpCode.Question.QuestionId = QuestionId;
- OpCode.Question.Flags = QuestionFlags;
- OpCode.FormId = FormId;
-
- return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_REF_OP, sizeof (OpCode));
-}
-
-/**
- Create EFI_IFR_REF_OP, EFI_IFR_REF2_OP, EFI_IFR_REF3_OP and EFI_IFR_REF4_OP opcode.
-
- When RefDevicePath is not zero, EFI_IFR_REF4 opcode will be created.
- When RefDevicePath is zero and RefFormSetId is not NULL, EFI_IFR_REF3 opcode will be created.
- When RefDevicePath is zero, RefFormSetId is NULL and RefQuestionId is not zero, EFI_IFR_REF2 opcode will be created.
- When RefDevicePath is zero, RefFormSetId is NULL and RefQuestionId is zero, EFI_IFR_REF opcode will be created.
-
- If OpCodeHandle is NULL, then ASSERT().
- If any reserved bits are set in QuestionFlags, then ASSERT().
-
- @param[in] OpCodeHandle The handle to the buffer of opcodes.
- @param[in] RefFormId The Destination Form ID.
- @param[in] Prompt The string ID for Prompt.
- @param[in] Help The string ID for Help.
- @param[in] QuestionFlags The flags in Question Header
- @param[in] QuestionId Question ID.
- @param[in] RefQuestionId The question on the form to which this link is referring.
- If its value is zero, then the link refers to the top of the form.
- @param[in] RefFormSetId The form set to which this link is referring. If its value is NULL, and RefDevicePath is
- zero, then the link is to the current form set.
- @param[in] RefDevicePath The string identifier that specifies the string containing the text representation of
- the device path to which the form set containing the form specified by FormId.
- If its value is zero, then the link refers to the current page.
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the created opcode.
-
-**/
-UINT8 *
-EFIAPI
-HiiCreateGotoExOpCode (
- IN VOID *OpCodeHandle,
- IN EFI_FORM_ID RefFormId,
- IN EFI_STRING_ID Prompt,
- IN EFI_STRING_ID Help,
- IN UINT8 QuestionFlags,
- IN EFI_QUESTION_ID QuestionId,
- IN EFI_QUESTION_ID RefQuestionId,
- IN EFI_GUID *RefFormSetId OPTIONAL,
- IN EFI_STRING_ID RefDevicePath
- )
-{
- EFI_IFR_REF4 OpCode;
- UINTN OpCodeSize;
-
- ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED))) == 0);
-
- ZeroMem (&OpCode, sizeof (OpCode));
- OpCode.Question.Header.Prompt = Prompt;
- OpCode.Question.Header.Help = Help;
- OpCode.Question.QuestionId = QuestionId;
- OpCode.Question.Flags = QuestionFlags;
- OpCode.FormId = RefFormId;
- OpCode.QuestionId = RefQuestionId;
- OpCode.DevicePath = RefDevicePath;
- if (RefFormSetId != NULL) {
- CopyMem (&OpCode.FormSetId, RefFormSetId, sizeof (OpCode.FormSetId));
- }
-
- //
- // Cacluate OpCodeSize based on the input Ref value.
- // Try to use the small OpCode to save size.
- //
- OpCodeSize = sizeof (EFI_IFR_REF);
- if (RefDevicePath != 0) {
- OpCodeSize = sizeof (EFI_IFR_REF4);
- } else if (RefFormSetId != NULL) {
- OpCodeSize = sizeof (EFI_IFR_REF3);
- } else if (RefQuestionId != 0) {
- OpCodeSize = sizeof (EFI_IFR_REF2);
- }
-
- return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_REF_OP, OpCodeSize);
-}
-
-/**
- Create EFI_IFR_CHECKBOX_OP opcode.
-
- If OpCodeHandle is NULL, then ASSERT().
- If any reserved bits are set in QuestionFlags, then ASSERT().
- If any reserved bits are set in CheckBoxFlags, then ASSERT().
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] QuestionId Question ID
- @param[in] VarStoreId Storage ID
- @param[in] VarOffset Offset in Storage or String ID of the name (VarName)
- for this name/value pair.
- @param[in] Prompt String ID for Prompt
- @param[in] Help String ID for Help
- @param[in] QuestionFlags Flags in Question Header
- @param[in] CheckBoxFlags Flags for checkbox opcode
- @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
- is an optional parameter that may be NULL.
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the created opcode.
-
-**/
-UINT8 *
-EFIAPI
-HiiCreateCheckBoxOpCode (
- IN VOID *OpCodeHandle,
- 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 VOID *DefaultsOpCodeHandle OPTIONAL
- )
-{
- EFI_IFR_CHECKBOX OpCode;
- UINTN Position;
-
- ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_REST_STYLE))) == 0);
-
- ZeroMem (&OpCode, sizeof (OpCode));
- OpCode.Question.QuestionId = QuestionId;
- OpCode.Question.VarStoreId = VarStoreId;
- OpCode.Question.VarStoreInfo.VarOffset = VarOffset;
- OpCode.Question.Header.Prompt = Prompt;
- OpCode.Question.Header.Help = Help;
- OpCode.Question.Flags = QuestionFlags;
- OpCode.Flags = CheckBoxFlags;
-
- if (DefaultsOpCodeHandle == NULL) {
- return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_CHECKBOX_OP, sizeof (OpCode));
- }
-
- Position = InternalHiiOpCodeHandlePosition (OpCodeHandle);
- InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_CHECKBOX_OP, sizeof (OpCode), 0, 1);
- InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle);
- HiiCreateEndOpCode (OpCodeHandle);
- return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position;
-}
-
-/**
- Create EFI_IFR_NUMERIC_OP opcode.
-
- If OpCodeHandle is NULL, then ASSERT().
- If any reserved bits are set in QuestionFlags, then ASSERT().
- If any reserved bits are set in NumericFlags, then ASSERT().
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] QuestionId Question ID
- @param[in] VarStoreId Storage ID
- @param[in] VarOffset Offset in Storage or String ID of the name (VarName)
- for this name/value pair.
- @param[in] Prompt String ID for Prompt
- @param[in] Help String ID for Help
- @param[in] QuestionFlags Flags in Question Header
- @param[in] NumericFlags Flags for numeric opcode
- @param[in] Minimum Numeric minimum value
- @param[in] Maximum Numeric maximum value
- @param[in] Step Numeric step for edit
- @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
- is an optional parameter that may be NULL.
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the created opcode.
-
-**/
-UINT8 *
-EFIAPI
-HiiCreateNumericOpCode (
- IN VOID *OpCodeHandle,
- 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 VOID *DefaultsOpCodeHandle OPTIONAL
- )
-{
- EFI_IFR_NUMERIC OpCode;
- UINTN Position;
- UINTN Length;
-
- ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_REST_STYLE))) == 0);
-
- Length = 0;
- ZeroMem (&OpCode, sizeof (OpCode));
- OpCode.Question.QuestionId = QuestionId;
- OpCode.Question.VarStoreId = VarStoreId;
- OpCode.Question.VarStoreInfo.VarOffset = VarOffset;
- OpCode.Question.Header.Prompt = Prompt;
- OpCode.Question.Header.Help = Help;
- OpCode.Question.Flags = QuestionFlags;
- OpCode.Flags = NumericFlags;
-
- switch (NumericFlags & EFI_IFR_NUMERIC_SIZE) {
- case EFI_IFR_NUMERIC_SIZE_1:
- OpCode.data.u8.MinValue = (UINT8)Minimum;
- OpCode.data.u8.MaxValue = (UINT8)Maximum;
- OpCode.data.u8.Step = (UINT8)Step;
- Length = 3;
- break;
-
- case EFI_IFR_NUMERIC_SIZE_2:
- OpCode.data.u16.MinValue = (UINT16)Minimum;
- OpCode.data.u16.MaxValue = (UINT16)Maximum;
- OpCode.data.u16.Step = (UINT16)Step;
- Length = 6;
- break;
-
- case EFI_IFR_NUMERIC_SIZE_4:
- OpCode.data.u32.MinValue = (UINT32)Minimum;
- OpCode.data.u32.MaxValue = (UINT32)Maximum;
- OpCode.data.u32.Step = (UINT32)Step;
- Length = 12;
- break;
-
- case EFI_IFR_NUMERIC_SIZE_8:
- OpCode.data.u64.MinValue = Minimum;
- OpCode.data.u64.MaxValue = Maximum;
- OpCode.data.u64.Step = Step;
- Length = 24;
- break;
- }
-
- Length += OFFSET_OF (EFI_IFR_NUMERIC, data);
-
- if (DefaultsOpCodeHandle == NULL) {
- return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_NUMERIC_OP, Length);
- }
-
- Position = InternalHiiOpCodeHandlePosition (OpCodeHandle);
- InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_NUMERIC_OP, Length, 0, 1);
- InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle);
- HiiCreateEndOpCode (OpCodeHandle);
- return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position;
-}
-
-/**
- Create EFI_IFR_STRING_OP opcode.
-
- If OpCodeHandle is NULL, then ASSERT().
- If any reserved bits are set in QuestionFlags, then ASSERT().
- If any reserved bits are set in StringFlags, then ASSERT().
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] QuestionId Question ID
- @param[in] VarStoreId Storage ID
- @param[in] VarOffset Offset in Storage or String ID of the name (VarName)
- for this name/value pair.
- @param[in] Prompt String ID for Prompt
- @param[in] Help String ID for Help
- @param[in] QuestionFlags Flags in Question Header
- @param[in] StringFlags Flags for string opcode
- @param[in] MinSize String minimum length
- @param[in] MaxSize String maximum length
- @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
- is an optional parameter that may be NULL.
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the created opcode.
-
-**/
-UINT8 *
-EFIAPI
-HiiCreateStringOpCode (
- IN VOID *OpCodeHandle,
- 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 VOID *DefaultsOpCodeHandle OPTIONAL
- )
-{
- EFI_IFR_STRING OpCode;
- UINTN Position;
-
- ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_REST_STYLE))) == 0);
-
- ZeroMem (&OpCode, sizeof (OpCode));
- OpCode.Question.Header.Prompt = Prompt;
- OpCode.Question.Header.Help = Help;
- OpCode.Question.QuestionId = QuestionId;
- OpCode.Question.VarStoreId = VarStoreId;
- OpCode.Question.VarStoreInfo.VarOffset = VarOffset;
- OpCode.Question.Flags = QuestionFlags;
- OpCode.MinSize = MinSize;
- OpCode.MaxSize = MaxSize;
- OpCode.Flags = (UINT8)(StringFlags & EFI_IFR_STRING_MULTI_LINE);
-
- if (DefaultsOpCodeHandle == NULL) {
- return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_STRING_OP, sizeof (OpCode));
- }
-
- Position = InternalHiiOpCodeHandlePosition (OpCodeHandle);
- InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_STRING_OP, sizeof (OpCode), 0, 1);
- InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle);
- HiiCreateEndOpCode (OpCodeHandle);
- return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position;
-}
-
-/**
- Create EFI_IFR_ONE_OF_OP opcode.
-
- If OpCodeHandle is NULL, then ASSERT().
- If any reserved bits are set in QuestionFlags, then ASSERT().
- If any reserved bits are set in OneOfFlags, then ASSERT().
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] QuestionId Question ID
- @param[in] VarStoreId Storage ID
- @param[in] VarOffset Offset in Storage or String ID of the name (VarName)
- for this name/value pair.
- @param[in] Prompt String ID for Prompt
- @param[in] Help String ID for Help
- @param[in] QuestionFlags Flags in Question Header
- @param[in] OneOfFlags Flags for oneof opcode
- @param[in] OptionsOpCodeHandle Handle for a buffer of ONE_OF_OPTION opcodes.
- @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
- is an optional parameter that may be NULL.
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the created opcode.
-
-**/
-UINT8 *
-EFIAPI
-HiiCreateOneOfOpCode (
- IN VOID *OpCodeHandle,
- 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 VOID *OptionsOpCodeHandle,
- IN VOID *DefaultsOpCodeHandle OPTIONAL
- )
-{
- EFI_IFR_ONE_OF OpCode;
- UINTN Position;
- UINTN Length;
-
- ASSERT (OptionsOpCodeHandle != NULL);
- ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_REST_STYLE | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0);
-
- ZeroMem (&OpCode, sizeof (OpCode));
- OpCode.Question.Header.Prompt = Prompt;
- OpCode.Question.Header.Help = Help;
- OpCode.Question.QuestionId = QuestionId;
- OpCode.Question.VarStoreId = VarStoreId;
- OpCode.Question.VarStoreInfo.VarOffset = VarOffset;
- OpCode.Question.Flags = QuestionFlags;
- OpCode.Flags = OneOfFlags;
-
- Length = OFFSET_OF (EFI_IFR_ONE_OF, data);
- Length += (1 << (OneOfFlags & EFI_IFR_NUMERIC_SIZE)) * 3;
-
- Position = InternalHiiOpCodeHandlePosition (OpCodeHandle);
- InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_ONE_OF_OP, Length, 0, 1);
- InternalHiiAppendOpCodes (OpCodeHandle, OptionsOpCodeHandle);
- if (DefaultsOpCodeHandle != NULL) {
- InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle);
- }
-
- HiiCreateEndOpCode (OpCodeHandle);
- return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position;
-}
-
-/**
- Create EFI_IFR_ORDERED_LIST_OP opcode.
-
- If OpCodeHandle is NULL, then ASSERT().
- If any reserved bits are set in QuestionFlags, then ASSERT().
- If any reserved bits are set in OrderedListFlags, then ASSERT().
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] QuestionId Question ID
- @param[in] VarStoreId Storage ID
- @param[in] VarOffset Offset in Storage or String ID of the name (VarName)
- for this name/value pair.
- @param[in] Prompt String ID for Prompt
- @param[in] Help String ID for Help
- @param[in] QuestionFlags Flags in Question Header
- @param[in] OrderedListFlags Flags for ordered list opcode
- @param[in] DataType Type for option value
- @param[in] MaxContainers Maximum count for options in this ordered list
- @param[in] OptionsOpCodeHandle Handle for a buffer of ONE_OF_OPTION opcodes.
- @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
- is an optional parameter that may be NULL.
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the created opcode.
-
-**/
-UINT8 *
-EFIAPI
-HiiCreateOrderedListOpCode (
- IN VOID *OpCodeHandle,
- 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 VOID *OptionsOpCodeHandle,
- IN VOID *DefaultsOpCodeHandle OPTIONAL
- )
-{
- EFI_IFR_ORDERED_LIST OpCode;
- UINTN Position;
-
- ASSERT (OptionsOpCodeHandle != NULL);
- ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_REST_STYLE | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0);
-
- ZeroMem (&OpCode, sizeof (OpCode));
- OpCode.Question.Header.Prompt = Prompt;
- OpCode.Question.Header.Help = Help;
- OpCode.Question.QuestionId = QuestionId;
- OpCode.Question.VarStoreId = VarStoreId;
- OpCode.Question.VarStoreInfo.VarOffset = VarOffset;
- OpCode.Question.Flags = QuestionFlags;
- OpCode.MaxContainers = MaxContainers;
- OpCode.Flags = OrderedListFlags;
-
- Position = InternalHiiOpCodeHandlePosition (OpCodeHandle);
- InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_ORDERED_LIST_OP, sizeof (OpCode), 0, 1);
- InternalHiiAppendOpCodes (OpCodeHandle, OptionsOpCodeHandle);
- if (DefaultsOpCodeHandle != NULL) {
- InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle);
- }
-
- HiiCreateEndOpCode (OpCodeHandle);
- return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position;
-}
-
-/**
- Create EFI_IFR_TEXT_OP opcode.
-
- If OpCodeHandle is NULL, then ASSERT().
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] Prompt String ID for Prompt.
- @param[in] Help String ID for Help.
- @param[in] TextTwo String ID for TextTwo.
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the created opcode.
-
-**/
-UINT8 *
-EFIAPI
-HiiCreateTextOpCode (
- IN VOID *OpCodeHandle,
- IN EFI_STRING_ID Prompt,
- IN EFI_STRING_ID Help,
- IN EFI_STRING_ID TextTwo
- )
-{
- EFI_IFR_TEXT OpCode;
-
- ZeroMem (&OpCode, sizeof (OpCode));
- OpCode.Statement.Prompt = Prompt;
- OpCode.Statement.Help = Help;
- OpCode.TextTwo = TextTwo;
-
- return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_TEXT_OP, sizeof (OpCode));
-}
-
-/**
- Create EFI_IFR_DATE_OP opcode.
-
- If OpCodeHandle is NULL, then ASSERT().
- If any reserved bits are set in QuestionFlags, then ASSERT().
- If any reserved bits are set in DateFlags, then ASSERT().
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] QuestionId Question ID
- @param[in] VarStoreId Storage ID, optional. If DateFlags is not
- QF_DATE_STORAGE_NORMAL, this parameter is ignored.
- @param[in] VarOffset Offset in Storage or String ID of the name (VarName)
- for this name/value pair, optional. If DateFlags is not
- QF_DATE_STORAGE_NORMAL, this parameter is ignored.
- @param[in] Prompt String ID for Prompt
- @param[in] Help String ID for Help
- @param[in] QuestionFlags Flags in Question Header
- @param[in] DateFlags Flags for date opcode
- @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
- is an optional parameter that may be NULL.
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the created opcode.
-
-**/
-UINT8 *
-EFIAPI
-HiiCreateDateOpCode (
- IN VOID *OpCodeHandle,
- IN EFI_QUESTION_ID QuestionId,
- IN EFI_VARSTORE_ID VarStoreId OPTIONAL,
- IN UINT16 VarOffset OPTIONAL,
- IN EFI_STRING_ID Prompt,
- IN EFI_STRING_ID Help,
- IN UINT8 QuestionFlags,
- IN UINT8 DateFlags,
- IN VOID *DefaultsOpCodeHandle OPTIONAL
- )
-{
- EFI_IFR_DATE OpCode;
- UINTN Position;
-
- ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_REST_STYLE))) == 0);
- ASSERT ((DateFlags & (~(EFI_QF_DATE_YEAR_SUPPRESS | EFI_QF_DATE_MONTH_SUPPRESS | EFI_QF_DATE_DAY_SUPPRESS | EFI_QF_DATE_STORAGE))) == 0);
-
- ZeroMem (&OpCode, sizeof (OpCode));
- OpCode.Question.Header.Prompt = Prompt;
- OpCode.Question.Header.Help = Help;
- OpCode.Question.QuestionId = QuestionId;
- OpCode.Question.VarStoreId = VarStoreId;
- OpCode.Question.VarStoreInfo.VarOffset = VarOffset;
- OpCode.Question.Flags = QuestionFlags;
- OpCode.Flags = DateFlags;
-
- if (DefaultsOpCodeHandle == NULL) {
- return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_DATE_OP, sizeof (OpCode));
- }
-
- Position = InternalHiiOpCodeHandlePosition (OpCodeHandle);
- InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_DATE_OP, sizeof (OpCode), 0, 1);
- InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle);
- HiiCreateEndOpCode (OpCodeHandle);
- return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position;
-}
-
-/**
- Create EFI_IFR_TIME_OP opcode.
-
- If OpCodeHandle is NULL, then ASSERT().
- If any reserved bits are set in QuestionFlags, then ASSERT().
- If any reserved bits are set in TimeFlags, then ASSERT().
-
- @param[in] OpCodeHandle Handle to the buffer of opcodes.
- @param[in] QuestionId Question ID
- @param[in] VarStoreId Storage ID, optional. If TimeFlags is not
- QF_TIME_STORAGE_NORMAL, this parameter is ignored.
- @param[in] VarOffset Offset in Storage or String ID of the name (VarName)
- for this name/value pair, optional. If TimeFlags is not
- QF_TIME_STORAGE_NORMAL, this parameter is ignored.
- @param[in] Prompt String ID for Prompt
- @param[in] Help String ID for Help
- @param[in] QuestionFlags Flags in Question Header
- @param[in] TimeFlags Flags for time opcode
- @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
- is an optional parameter that may be NULL.
-
- @retval NULL There is not enough space left in Buffer to add the opcode.
- @retval Other A pointer to the created opcode.
-
-**/
-UINT8 *
-EFIAPI
-HiiCreateTimeOpCode (
- IN VOID *OpCodeHandle,
- IN EFI_QUESTION_ID QuestionId,
- IN EFI_VARSTORE_ID VarStoreId OPTIONAL,
- IN UINT16 VarOffset OPTIONAL,
- IN EFI_STRING_ID Prompt,
- IN EFI_STRING_ID Help,
- IN UINT8 QuestionFlags,
- IN UINT8 TimeFlags,
- IN VOID *DefaultsOpCodeHandle OPTIONAL
- )
-{
- EFI_IFR_TIME OpCode;
- UINTN Position;
-
- ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_REST_STYLE))) == 0);
- ASSERT ((TimeFlags & (~(QF_TIME_HOUR_SUPPRESS | QF_TIME_MINUTE_SUPPRESS | QF_TIME_SECOND_SUPPRESS | QF_TIME_STORAGE))) == 0);
-
- ZeroMem (&OpCode, sizeof (OpCode));
- OpCode.Question.Header.Prompt = Prompt;
- OpCode.Question.Header.Help = Help;
- OpCode.Question.QuestionId = QuestionId;
- OpCode.Question.VarStoreId = VarStoreId;
- OpCode.Question.VarStoreInfo.VarOffset = VarOffset;
- OpCode.Question.Flags = QuestionFlags;
- OpCode.Flags = TimeFlags;
-
- if (DefaultsOpCodeHandle == NULL) {
- return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_TIME_OP, sizeof (OpCode));
- }
-
- Position = InternalHiiOpCodeHandlePosition (OpCodeHandle);
- InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_TIME_OP, sizeof (OpCode), 0, 1);
- InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle);
- HiiCreateEndOpCode (OpCodeHandle);
- return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position;
-}
-
-/**
- This is the internal worker function to update the data in
- a form specified by FormSetGuid, FormId and Label.
-
- @param[in] FormSetGuid The optional Formset GUID.
- @param[in] FormId The Form ID.
- @param[in] Package The package header.
- @param[in] OpCodeBufferStart An OpCode buffer that contains the set of IFR
- opcodes to be inserted or replaced in the form.
- @param[in] OpCodeBufferEnd An OpCcode buffer that contains the IFR opcode
- that marks the end of a replace operation in the form.
- @param[out] TempPackage The resultant package.
-
- @retval EFI_SUCCESS The function completes successfully.
- @retval EFI_NOT_FOUND The updated opcode or endopcode is not found.
-
-**/
-EFI_STATUS
-EFIAPI
-InternalHiiUpdateFormPackageData (
- IN EFI_GUID *FormSetGuid OPTIONAL,
- IN EFI_FORM_ID FormId,
- IN EFI_HII_PACKAGE_HEADER *Package,
- IN HII_LIB_OPCODE_BUFFER *OpCodeBufferStart,
- IN HII_LIB_OPCODE_BUFFER *OpCodeBufferEnd OPTIONAL,
- OUT EFI_HII_PACKAGE_HEADER *TempPackage
- )
-{
- UINTN AddSize;
- UINT8 *BufferPos;
- EFI_HII_PACKAGE_HEADER PackageHeader;
- UINTN Offset;
- EFI_IFR_OP_HEADER *IfrOpHdr;
- EFI_IFR_OP_HEADER *UpdateIfrOpHdr;
- BOOLEAN GetFormSet;
- BOOLEAN GetForm;
- BOOLEAN Updated;
- UINTN UpdatePackageLength;
-
- CopyMem (TempPackage, Package, sizeof (EFI_HII_PACKAGE_HEADER));
- UpdatePackageLength = sizeof (EFI_HII_PACKAGE_HEADER);
- BufferPos = (UINT8 *)(TempPackage + 1);
-
- CopyMem (&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 = (BOOLEAN)((FormSetGuid == NULL) ? TRUE : FALSE);
- GetForm = FALSE;
- Updated = FALSE;
-
- while (Offset < PackageHeader.Length) {
- CopyMem (BufferPos, IfrOpHdr, IfrOpHdr->Length);
- BufferPos += IfrOpHdr->Length;
- UpdatePackageLength += IfrOpHdr->Length;
-
- //
- // Find the matched FormSet and Form
- //
- if ((IfrOpHdr->OpCode == EFI_IFR_FORM_SET_OP) && (FormSetGuid != NULL)) {
- if (CompareGuid ((GUID *)(VOID *)&((EFI_IFR_FORM_SET *)IfrOpHdr)->Guid, FormSetGuid)) {
- GetFormSet = TRUE;
- } else {
- GetFormSet = FALSE;
- }
- } else if ((IfrOpHdr->OpCode == EFI_IFR_FORM_OP) || (IfrOpHdr->OpCode == EFI_IFR_FORM_MAP_OP)) {
- if (CompareMem (&((EFI_IFR_FORM *)IfrOpHdr)->FormId, &FormId, sizeof (EFI_FORM_ID)) == 0) {
- GetForm = TRUE;
- } else {
- GetForm = FALSE;
- }
- }
-
- //
- // The matched Form is found, and Update data in this form
- //
- if (GetFormSet && GetForm) {
- UpdateIfrOpHdr = (EFI_IFR_OP_HEADER *)OpCodeBufferStart->Buffer;
- if ((UpdateIfrOpHdr->Length == IfrOpHdr->Length) && \
- (CompareMem (IfrOpHdr, UpdateIfrOpHdr, UpdateIfrOpHdr->Length) == 0))
- {
- //
- // Remove the original data when End OpCode buffer exist.
- //
- if (OpCodeBufferEnd != NULL) {
- Offset += IfrOpHdr->Length;
- IfrOpHdr = (EFI_IFR_OP_HEADER *)((UINT8 *)(IfrOpHdr) + IfrOpHdr->Length);
- UpdateIfrOpHdr = (EFI_IFR_OP_HEADER *)OpCodeBufferEnd->Buffer;
- while (Offset < PackageHeader.Length) {
- //
- // Search the matched end opcode
- //
- if ((UpdateIfrOpHdr->Length == IfrOpHdr->Length) && \
- (CompareMem (IfrOpHdr, UpdateIfrOpHdr, UpdateIfrOpHdr->Length) == 0))
- {
- break;
- }
-
- //
- // Go to the next Op-Code
- //
- Offset += IfrOpHdr->Length;
- IfrOpHdr = (EFI_IFR_OP_HEADER *)((UINT8 *)(IfrOpHdr) + IfrOpHdr->Length);
- }
-
- if (Offset >= PackageHeader.Length) {
- //
- // The end opcode is not found.
- //
- return EFI_NOT_FOUND;
- }
- }
-
- //
- // Insert the updated data
- //
- AddSize = ((EFI_IFR_OP_HEADER *)OpCodeBufferStart->Buffer)->Length;
- CopyMem (BufferPos, OpCodeBufferStart->Buffer + AddSize, OpCodeBufferStart->Position - AddSize);
- BufferPos += OpCodeBufferStart->Position - AddSize;
- UpdatePackageLength += OpCodeBufferStart->Position - AddSize;
-
- if (OpCodeBufferEnd != NULL) {
- //
- // Add the end opcode
- //
- CopyMem (BufferPos, IfrOpHdr, IfrOpHdr->Length);
- BufferPos += IfrOpHdr->Length;
- UpdatePackageLength += IfrOpHdr->Length;
- }
-
- //
- // Copy the left package data.
- //
- Offset += IfrOpHdr->Length;
- CopyMem (BufferPos, (UINT8 *)Package + Offset, PackageHeader.Length - Offset);
- UpdatePackageLength += PackageHeader.Length - Offset;
-
- //
- // Set update flag
- //
- Updated = TRUE;
- break;
- }
- }
-
- //
- // Go to the next Op-Code
- //
- Offset += IfrOpHdr->Length;
- IfrOpHdr = (EFI_IFR_OP_HEADER *)((CHAR8 *)(IfrOpHdr) + IfrOpHdr->Length);
- }
-
- if (!Updated) {
- //
- // The updated opcode buffer is not found.
- //
- return EFI_NOT_FOUND;
- }
-
- //
- // Update the package length.
- //
- PackageHeader.Length = (UINT32)UpdatePackageLength;
- CopyMem (TempPackage, &PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));
-
- return EFI_SUCCESS;
-}
-
-/**
- This function updates a form that has previously been registered with the HII
- Database. This function will perform at most one update operation.
-
- The form to update is specified by Handle, FormSetGuid, and FormId. Binary
- comparisons of IFR opcodes are performed from the beginning of the form being
- updated until an IFR opcode is found that exactly matches the first IFR opcode
- specified by StartOpCodeHandle. The following rules are used to determine if
- an insert, replace, or delete operation is performed.
-
- 1) If no matches are found, then NULL is returned.
- 2) If a match is found, and EndOpCodeHandle is NULL, then all of the IFR opcodes
- from StartOpCodeHandle except the first opcode are inserted immediately after
- the matching IFR opcode in the form to be updated.
- 3) If a match is found, and EndOpCodeHandle is not NULL, then a search is made
- from the matching IFR opcode until an IFR opcode exactly matches the first
- IFR opcode specified by EndOpCodeHandle. If no match is found for the first
- IFR opcode specified by EndOpCodeHandle, then NULL is returned. If a match
- is found, then all of the IFR opcodes between the start match and the end
- match are deleted from the form being updated and all of the IFR opcodes
- from StartOpCodeHandle except the first opcode are inserted immediately after
- the matching start IFR opcode. If StartOpCcodeHandle only contains one
- IFR instruction, then the result of this operation will delete all of the IFR
- opcodes between the start end matches.
-
- If HiiHandle is NULL, then ASSERT().
- If StartOpCodeHandle is NULL, then ASSERT().
-
- @param[in] HiiHandle The HII Handle of the form to update.
- @param[in] FormSetGuid The Formset GUID of the form to update. This
- is an optional parameter that may be NULL.
- If it is NULL, all FormSet will be updated.
- @param[in] FormId The ID of the form to update.
- @param[in] StartOpCodeHandle An OpCode Handle that contains the set of IFR
- opcodes to be inserted or replaced in the form.
- The first IFR instruction in StartOpCodeHandle
- is used to find matching IFR opcode in the
- form.
- @param[in] EndOpCodeHandle An OpCcode Handle that contains the IFR opcode
- that marks the end of a replace operation in
- the form. This is an optional parameter that
- may be NULL. If it is NULL, then an the IFR
- opcodes specified by StartOpCodeHandle are
- inserted into the form.
-
- @retval EFI_OUT_OF_RESOURCES No enough memory resource is allocated.
- @retval EFI_NOT_FOUND The following cases will return EFI_NOT_FOUND.
- 1) The form specified by HiiHandle, FormSetGuid,
- and FormId could not be found in the HII Database.
- 2) No IFR opcodes in the target form match the first
- IFR opcode in StartOpCodeHandle.
- 3) EndOpCOde is not NULL, and no IFR opcodes in the
- target form following a matching start opcode match
- the first IFR opcode in EndOpCodeHandle.
- @retval EFI_SUCCESS The matched form is updated by StartOpcode.
-
-**/
-EFI_STATUS
-EFIAPI
-HiiUpdateForm (
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_GUID *FormSetGuid OPTIONAL,
- IN EFI_FORM_ID FormId,
- IN VOID *StartOpCodeHandle,
- IN VOID *EndOpCodeHandle OPTIONAL
- )
-{
- EFI_STATUS Status;
- EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
- UINT32 PackageListLength;
- UINT32 Offset;
- EFI_HII_PACKAGE_LIST_HEADER *UpdatePackageList;
- UINTN BufferSize;
- UINT8 *UpdateBufferPos;
- EFI_HII_PACKAGE_HEADER *Package;
- EFI_HII_PACKAGE_HEADER *TempPackage;
- EFI_HII_PACKAGE_HEADER PackageHeader;
- BOOLEAN Updated;
- HII_LIB_OPCODE_BUFFER *OpCodeBufferStart;
- HII_LIB_OPCODE_BUFFER *OpCodeBufferEnd;
-
- //
- // Input update data can't be NULL.
- //
- ASSERT (HiiHandle != NULL);
- ASSERT (StartOpCodeHandle != NULL);
- UpdatePackageList = NULL;
- TempPackage = NULL;
- HiiPackageList = NULL;
-
- //
- // Retrieve buffer data from Opcode Handle
- //
- OpCodeBufferStart = (HII_LIB_OPCODE_BUFFER *)StartOpCodeHandle;
- OpCodeBufferEnd = (HII_LIB_OPCODE_BUFFER *)EndOpCodeHandle;
-
- //
- // Get the original package list
- //
- BufferSize = 0;
- HiiPackageList = NULL;
- Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);
- //
- // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0.
- //
- if (Status != EFI_BUFFER_TOO_SMALL) {
- return Status;
- }
-
- HiiPackageList = AllocatePool (BufferSize);
- if (HiiPackageList == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Finish;
- }
-
- Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);
- if (EFI_ERROR (Status)) {
- goto Finish;
- }
-
- //
- // Calculate and allocate space for retrieval of IFR data
- //
- BufferSize += OpCodeBufferStart->Position;
- UpdatePackageList = AllocateZeroPool (BufferSize);
- if (UpdatePackageList == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Finish;
- }
-
- //
- // Allocate temp buffer to store the temp updated package buffer
- //
- TempPackage = AllocateZeroPool (BufferSize);
- if (TempPackage == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Finish;
- }
-
- UpdateBufferPos = (UINT8 *)UpdatePackageList;
-
- //
- // Copy the package list header
- //
- CopyMem (UpdateBufferPos, HiiPackageList, sizeof (EFI_HII_PACKAGE_LIST_HEADER));
- UpdateBufferPos += sizeof (EFI_HII_PACKAGE_LIST_HEADER);
-
- //
- // Go through each package to find the matched package and update one by one
- //
- Updated = FALSE;
- Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
- PackageListLength = ReadUnaligned32 (&HiiPackageList->PackageLength);
- while (Offset < PackageListLength) {
- Package = (EFI_HII_PACKAGE_HEADER *)(((UINT8 *)HiiPackageList) + Offset);
- CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
- Offset += Package->Length;
-
- if (Package->Type == EFI_HII_PACKAGE_FORMS) {
- //
- // Check this package is the matched package.
- //
- Status = InternalHiiUpdateFormPackageData (FormSetGuid, FormId, Package, OpCodeBufferStart, OpCodeBufferEnd, TempPackage);
- //
- // The matched package is found. Its package buffer will be updated by the input new data.
- //
- if (!EFI_ERROR (Status)) {
- //
- // Set Update Flag
- //
- Updated = TRUE;
- //
- // Add updated package buffer
- //
- Package = TempPackage;
- }
- }
-
- //
- // Add pacakge buffer
- //
- CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
- CopyMem (UpdateBufferPos, Package, PackageHeader.Length);
- UpdateBufferPos += PackageHeader.Length;
- }
-
- if (Updated) {
- //
- // Update package list length
- //
- BufferSize = UpdateBufferPos - (UINT8 *)UpdatePackageList;
- WriteUnaligned32 (&UpdatePackageList->PackageLength, (UINT32)BufferSize);
-
- //
- // Update Package to show form
- //
- Status = gHiiDatabase->UpdatePackageList (gHiiDatabase, HiiHandle, UpdatePackageList);
- } else {
- //
- // Not matched form is found and updated.
- //
- Status = EFI_NOT_FOUND;
- }
-
-Finish:
- if (HiiPackageList != NULL) {
- FreePool (HiiPackageList);
- }
-
- if (UpdatePackageList != NULL) {
- FreePool (UpdatePackageList);
- }
-
- if (TempPackage != NULL) {
- FreePool (TempPackage);
- }
-
- return Status;
-}
+/** @file + HII Library implementation that uses DXE protocols and services. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "InternalHiiLib.h" + +#define GUID_CONFIG_STRING_TYPE 0x00 +#define NAME_CONFIG_STRING_TYPE 0x01 +#define PATH_CONFIG_STRING_TYPE 0x02 + +#define ACTION_SET_DEFAUTL_VALUE 0x01 +#define ACTION_VALIDATE_SETTING 0x02 + +#define HII_LIB_DEFAULT_VARSTORE_SIZE 0x200 + +typedef struct { + LIST_ENTRY Entry; // Link to Block array + UINT16 Offset; + UINT16 Width; + UINT8 OpCode; + UINT8 Scope; +} IFR_BLOCK_DATA; + +typedef struct { + EFI_VARSTORE_ID VarStoreId; + UINT16 Size; +} IFR_VARSTORAGE_DATA; + +// +// <ConfigHdr> Template +// +GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR16 mConfigHdrTemplate[] = L"GUID=00000000000000000000000000000000&NAME=0000&PATH=00"; + +EFI_FORM_BROWSER2_PROTOCOL *mUefiFormBrowser2 = NULL; + +// +// Template used to mark the end of a list of packages +// +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_HII_PACKAGE_HEADER mEndOfPakageList = { + sizeof (EFI_HII_PACKAGE_HEADER), + EFI_HII_PACKAGE_END +}; + +/** + Extract Hii package list GUID for given HII handle. + + If HiiHandle could not be found in the HII database, then ASSERT. + If Guid is NULL, then ASSERT. + + @param Handle Hii handle + @param Guid Package list GUID + + @retval EFI_SUCCESS Successfully extract GUID from Hii database. + +**/ +EFI_STATUS +EFIAPI +InternalHiiExtractGuidFromHiiHandle ( + IN EFI_HII_HANDLE Handle, + OUT EFI_GUID *Guid + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList; + + ASSERT (Guid != NULL); + ASSERT (Handle != NULL); + + // + // Get HII PackageList + // + BufferSize = 0; + HiiPackageList = NULL; + + Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &BufferSize, HiiPackageList); + ASSERT (Status != EFI_NOT_FOUND); + + if (Status == EFI_BUFFER_TOO_SMALL) { + HiiPackageList = AllocatePool (BufferSize); + ASSERT (HiiPackageList != NULL); + + Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &BufferSize, HiiPackageList); + } + + if (EFI_ERROR (Status)) { + FreePool (HiiPackageList); + return Status; + } + + // + // Extract GUID + // + CopyGuid (Guid, &HiiPackageList->PackageListGuid); + + FreePool (HiiPackageList); + + return EFI_SUCCESS; +} + +/** + Registers a list of packages in the HII Database and returns the HII Handle + associated with that registration. If an HII Handle has already been registered + with the same PackageListGuid and DeviceHandle, then NULL is returned. If there + are not enough resources to perform the registration, then NULL is returned. + If an empty list of packages is passed in, then NULL is returned. If the size of + the list of package is 0, then NULL is returned. + + The variable arguments are pointers which point to package header that defined + by UEFI VFR compiler and StringGather tool. + + #pragma pack (push, 1) + typedef struct { + UINT32 BinaryLength; + EFI_HII_PACKAGE_HEADER PackageHeader; + } EDKII_AUTOGEN_PACKAGES_HEADER; + #pragma pack (pop) + + @param[in] PackageListGuid The GUID of the package list. + @param[in] DeviceHandle If not NULL, the Device Handle on which + an instance of DEVICE_PATH_PROTOCOL is installed. + This Device Handle uniquely defines the device that + the added packages are associated with. + @param[in] ... The variable argument list that contains pointers + to packages terminated by a NULL. + + @retval NULL A HII Handle has already been registered in the HII Database with + the same PackageListGuid and DeviceHandle. + @retval NULL The HII Handle could not be created. + @retval NULL An empty list of packages was passed in. + @retval NULL All packages are empty. + @retval Other The HII Handle associated with the newly registered package list. + +**/ +EFI_HII_HANDLE +EFIAPI +HiiAddPackages ( + IN CONST EFI_GUID *PackageListGuid, + IN EFI_HANDLE DeviceHandle OPTIONAL, + ... + ) +{ + EFI_STATUS Status; + VA_LIST Args; + UINT32 *Package; + EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader; + EFI_HII_HANDLE HiiHandle; + UINT32 Length; + UINT8 *Data; + + ASSERT (PackageListGuid != NULL); + + // + // Calculate the length of all the packages in the variable argument list + // + for (Length = 0, VA_START (Args, DeviceHandle); (Package = VA_ARG (Args, UINT32 *)) != NULL; ) { + Length += (ReadUnaligned32 (Package) - sizeof (UINT32)); + } + + VA_END (Args); + + // + // If there are no packages in the variable argument list or all the packages + // are empty, then return a NULL HII Handle + // + if (Length == 0) { + return NULL; + } + + // + // Add the length of the Package List Header and the terminating Package Header + // + Length += sizeof (EFI_HII_PACKAGE_LIST_HEADER) + sizeof (EFI_HII_PACKAGE_HEADER); + + // + // Allocate the storage for the entire Package List + // + PackageListHeader = AllocateZeroPool (Length); + + // + // If the Package List can not be allocated, then return a NULL HII Handle + // + if (PackageListHeader == NULL) { + return NULL; + } + + // + // Fill in the GUID and Length of the Package List Header + // + CopyGuid (&PackageListHeader->PackageListGuid, PackageListGuid); + PackageListHeader->PackageLength = Length; + + // + // Initialize a pointer to the beginning if the Package List data + // + Data = (UINT8 *)(PackageListHeader + 1); + + // + // Copy the data from each package in the variable argument list + // + for (VA_START (Args, DeviceHandle); (Package = VA_ARG (Args, UINT32 *)) != NULL; ) { + Length = ReadUnaligned32 (Package) - sizeof (UINT32); + CopyMem (Data, Package + 1, Length); + Data += Length; + } + + VA_END (Args); + + // + // Append a package of type EFI_HII_PACKAGE_END to mark the end of the package list + // + CopyMem (Data, &mEndOfPakageList, sizeof (mEndOfPakageList)); + + // + // Register the package list with the HII Database + // + Status = gHiiDatabase->NewPackageList ( + gHiiDatabase, + PackageListHeader, + DeviceHandle, + &HiiHandle + ); + if (EFI_ERROR (Status)) { + HiiHandle = NULL; + } + + // + // Free the allocated package list + // + FreePool (PackageListHeader); + + // + // Return the new HII Handle + // + return HiiHandle; +} + +/** + Removes a package list from the HII database. + + If HiiHandle is NULL, then ASSERT. + If HiiHandle is not a valid EFI_HII_HANDLE in the HII database, then ASSERT. + + @param[in] HiiHandle The handle that was previously registered in the HII database + +**/ +VOID +EFIAPI +HiiRemovePackages ( + IN EFI_HII_HANDLE HiiHandle + ) +{ + EFI_STATUS Status; + + ASSERT (HiiHandle != NULL); + Status = gHiiDatabase->RemovePackageList (gHiiDatabase, HiiHandle); + ASSERT_EFI_ERROR (Status); +} + +/** + Retrieves the array of all the HII Handles or the HII handles of a specific + package list GUID in the HII Database. + This array is terminated with a NULL HII Handle. + This function allocates the returned array using AllocatePool(). + The caller is responsible for freeing the array with FreePool(). + + @param[in] PackageListGuid An optional parameter that is used to request + HII Handles associated with a specific + Package List GUID. If this parameter is NULL, + then all the HII Handles in the HII Database + are returned. If this parameter is not NULL, + then zero or more HII Handles associated with + PackageListGuid are returned. + + @retval NULL No HII handles were found in the HII database + @retval NULL The array of HII Handles could not be retrieved + @retval Other A pointer to the NULL terminated array of HII Handles + +**/ +EFI_HII_HANDLE * +EFIAPI +HiiGetHiiHandles ( + IN CONST EFI_GUID *PackageListGuid OPTIONAL + ) +{ + EFI_STATUS Status; + UINTN HandleBufferLength; + EFI_HII_HANDLE TempHiiHandleBuffer; + EFI_HII_HANDLE *HiiHandleBuffer; + EFI_GUID Guid; + UINTN Index1; + UINTN Index2; + + // + // Retrieve the size required for the buffer of all HII handles. + // + HandleBufferLength = 0; + Status = gHiiDatabase->ListPackageLists ( + gHiiDatabase, + EFI_HII_PACKAGE_TYPE_ALL, + NULL, + &HandleBufferLength, + &TempHiiHandleBuffer + ); + + // + // If ListPackageLists() returns EFI_SUCCESS for a zero size, + // then there are no HII handles in the HII database. If ListPackageLists() + // returns an error other than EFI_BUFFER_TOO_SMALL, then there are no HII + // handles in the HII database. + // + if (Status != EFI_BUFFER_TOO_SMALL) { + // + // Return NULL if the size can not be retrieved, or if there are no HII + // handles in the HII Database + // + return NULL; + } + + // + // Allocate the array of HII handles to hold all the HII Handles and a NULL terminator + // + HiiHandleBuffer = AllocateZeroPool (HandleBufferLength + sizeof (EFI_HII_HANDLE)); + if (HiiHandleBuffer == NULL) { + // + // Return NULL if allocation fails. + // + return NULL; + } + + // + // Retrieve the array of HII Handles in the HII Database + // + Status = gHiiDatabase->ListPackageLists ( + gHiiDatabase, + EFI_HII_PACKAGE_TYPE_ALL, + NULL, + &HandleBufferLength, + HiiHandleBuffer + ); + if (EFI_ERROR (Status)) { + // + // Free the buffer and return NULL if the HII handles can not be retrieved. + // + FreePool (HiiHandleBuffer); + return NULL; + } + + if (PackageListGuid == NULL) { + // + // Return the NULL terminated array of HII handles in the HII Database + // + return HiiHandleBuffer; + } else { + for (Index1 = 0, Index2 = 0; HiiHandleBuffer[Index1] != NULL; Index1++) { + Status = InternalHiiExtractGuidFromHiiHandle (HiiHandleBuffer[Index1], &Guid); + ASSERT_EFI_ERROR (Status); + if (CompareGuid (&Guid, PackageListGuid)) { + HiiHandleBuffer[Index2++] = HiiHandleBuffer[Index1]; + } + } + + if (Index2 > 0) { + HiiHandleBuffer[Index2] = NULL; + return HiiHandleBuffer; + } else { + FreePool (HiiHandleBuffer); + return NULL; + } + } +} + +/** + This function allows a caller to extract the form set opcode form the Hii Handle. + The returned buffer is allocated using AllocatePool().The caller is responsible + for freeing the allocated buffer using FreePool(). + + @param Handle The HII handle. + @param Buffer On return, points to a pointer which point to the buffer that contain the formset opcode. + @param BufferSize On return, points to the length of the buffer. + + @retval EFI_OUT_OF_RESOURCES No enough memory resource is allocated. + @retval EFI_NOT_FOUND Can't find the package data for the input Handle. + @retval EFI_INVALID_PARAMETER The input parameters are not correct. + @retval EFI_SUCCESS Get the formset opcode from the hii handle successfully. + +**/ +EFI_STATUS +EFIAPI +HiiGetFormSetFromHiiHandle ( + IN EFI_HII_HANDLE Handle, + OUT EFI_IFR_FORM_SET **Buffer, + OUT UINTN *BufferSize + ) +{ + EFI_STATUS Status; + UINTN PackageListSize; + UINTN TempSize; + EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList; + UINT8 *Package; + UINT8 *OpCodeData; + UINT8 *FormSetBuffer; + UINT8 *TempBuffer; + UINT32 Offset; + UINT32 Offset2; + UINT32 PackageListLength; + EFI_HII_PACKAGE_HEADER PackageHeader; + + TempSize = 0; + FormSetBuffer = NULL; + TempBuffer = NULL; + + // + // Get HII PackageList + // + PackageListSize = 0; + HiiPackageList = NULL; + Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &PackageListSize, HiiPackageList); + if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) { + return Status; + } + + HiiPackageList = AllocatePool (PackageListSize); + if (HiiPackageList == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &PackageListSize, HiiPackageList); + ASSERT_EFI_ERROR (Status); + + // + // Get Form package from this HII package List + // + Status = EFI_NOT_FOUND; + Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER); + PackageListLength = ReadUnaligned32 (&HiiPackageList->PackageLength); + + while (Offset < PackageListLength) { + Package = ((UINT8 *)HiiPackageList) + Offset; + CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER)); + Offset += PackageHeader.Length; + + if (PackageHeader.Type != EFI_HII_PACKAGE_FORMS) { + continue; + } + + // + // Search FormSet Opcode in this Form Package + // + Offset2 = sizeof (EFI_HII_PACKAGE_HEADER); + while (Offset2 < PackageHeader.Length) { + OpCodeData = Package + Offset2; + Offset2 += ((EFI_IFR_OP_HEADER *)OpCodeData)->Length; + + if (((EFI_IFR_OP_HEADER *)OpCodeData)->OpCode != EFI_IFR_FORM_SET_OP) { + continue; + } + + if (FormSetBuffer != NULL) { + TempBuffer = ReallocatePool ( + TempSize, + TempSize + ((EFI_IFR_OP_HEADER *)OpCodeData)->Length, + FormSetBuffer + ); + if (TempBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + CopyMem (TempBuffer + TempSize, OpCodeData, ((EFI_IFR_OP_HEADER *)OpCodeData)->Length); + FormSetBuffer = NULL; + } else { + TempBuffer = AllocatePool (TempSize + ((EFI_IFR_OP_HEADER *)OpCodeData)->Length); + if (TempBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + CopyMem (TempBuffer, OpCodeData, ((EFI_IFR_OP_HEADER *)OpCodeData)->Length); + } + + TempSize += ((EFI_IFR_OP_HEADER *)OpCodeData)->Length; + FormSetBuffer = TempBuffer; + + Status = EFI_SUCCESS; + // + // One form package has one formset, exit current form package to search other form package in the packagelist. + // + break; + } + } + +Done: + FreePool (HiiPackageList); + + *BufferSize = TempSize; + *Buffer = (EFI_IFR_FORM_SET *)FormSetBuffer; + + return Status; +} + +/** + Converts all hex dtring characters in range ['A'..'F'] to ['a'..'f'] for + hex digits that appear between a '=' and a '&' in a config string. + + If ConfigString is NULL, then ASSERT(). + + @param[in] ConfigString Pointer to a Null-terminated Unicode string. + + @return Pointer to the Null-terminated Unicode result string. + +**/ +EFI_STRING +EFIAPI +InternalHiiLowerConfigString ( + IN EFI_STRING ConfigString + ) +{ + EFI_STRING String; + BOOLEAN Lower; + + ASSERT (ConfigString != NULL); + + // + // Convert all hex digits in range [A-F] in the configuration header to [a-f] + // + for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) { + if (*String == L'=') { + Lower = TRUE; + } else if (*String == L'&') { + Lower = FALSE; + } else if (Lower && (*String >= L'A') && (*String <= L'F')) { + *String = (CHAR16)(*String - L'A' + L'a'); + } + } + + return ConfigString; +} + +/** + Uses the BlockToConfig() service of the Config Routing Protocol to + convert <ConfigRequest> and a buffer to a <ConfigResp> + + If ConfigRequest is NULL, then ASSERT(). + If Block is NULL, then ASSERT(). + + @param[in] ConfigRequest Pointer to a Null-terminated Unicode string. + @param[in] Block Pointer to a block of data. + @param[in] BlockSize The zie, in bytes, of Block. + + @retval NULL The <ConfigResp> string could not be generated. + @retval Other Pointer to the Null-terminated Unicode <ConfigResp> string. + +**/ +EFI_STRING +EFIAPI +InternalHiiBlockToConfig ( + IN CONST EFI_STRING ConfigRequest, + IN CONST UINT8 *Block, + IN UINTN BlockSize + ) +{ + EFI_STATUS Status; + EFI_STRING ConfigResp; + CHAR16 *Progress; + + ASSERT (ConfigRequest != NULL); + ASSERT (Block != NULL); + + // + // Convert <ConfigRequest> to <ConfigResp> + // + Status = gHiiConfigRouting->BlockToConfig ( + gHiiConfigRouting, + ConfigRequest, + Block, + BlockSize, + &ConfigResp, + &Progress + ); + if (EFI_ERROR (Status)) { + return NULL; + } + + return ConfigResp; +} + +/** + Uses the BrowserCallback() service of the Form Browser Protocol to retrieve + or set uncommitted data. If sata i being retrieved, then the buffer is + allocated using AllocatePool(). The caller is then responsible for freeing + the buffer using FreePool(). + + @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional + parameter that may be NULL. + @param[in] VariableName Pointer to a Null-terminated Unicode string. This + is an optional parameter that may be NULL. + @param[in] SetResultsData If not NULL, then this parameter specified the buffer + of uncommited data to set. If this parameter is NULL, + then the caller is requesting to get the uncommited data + from the Form Browser. + + @retval NULL The uncommitted data could not be retrieved. + @retval Other A pointer to a buffer containing the uncommitted data. + +**/ +EFI_STRING +EFIAPI +InternalHiiBrowserCallback ( + IN CONST EFI_GUID *VariableGuid OPTIONAL, + IN CONST CHAR16 *VariableName OPTIONAL, + IN CONST EFI_STRING SetResultsData OPTIONAL + ) +{ + EFI_STATUS Status; + UINTN ResultsDataSize; + EFI_STRING ResultsData; + CHAR16 TempResultsData; + + // + // Locate protocols + // + if (mUefiFormBrowser2 == NULL) { + Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **)&mUefiFormBrowser2); + if (EFI_ERROR (Status) || (mUefiFormBrowser2 == NULL)) { + return NULL; + } + } + + ResultsDataSize = 0; + + if (SetResultsData != NULL) { + // + // Request to to set data in the uncommitted browser state information + // + ResultsData = SetResultsData; + } else { + // + // Retrieve the length of the buffer required ResultsData from the Browser Callback + // + Status = mUefiFormBrowser2->BrowserCallback ( + mUefiFormBrowser2, + &ResultsDataSize, + &TempResultsData, + TRUE, + VariableGuid, + VariableName + ); + + if (!EFI_ERROR (Status)) { + // + // No Resluts Data, only allocate one char for '\0' + // + ResultsData = AllocateZeroPool (sizeof (CHAR16)); + return ResultsData; + } + + if (Status != EFI_BUFFER_TOO_SMALL) { + return NULL; + } + + // + // Allocate the ResultsData buffer + // + ResultsData = AllocateZeroPool (ResultsDataSize); + if (ResultsData == NULL) { + return NULL; + } + } + + // + // Retrieve or set the ResultsData from the Browser Callback + // + Status = mUefiFormBrowser2->BrowserCallback ( + mUefiFormBrowser2, + &ResultsDataSize, + ResultsData, + (BOOLEAN)(SetResultsData == NULL), + VariableGuid, + VariableName + ); + if (EFI_ERROR (Status)) { + return NULL; + } + + return ResultsData; +} + +/** + Allocates and returns a Null-terminated Unicode <ConfigHdr> string using routing + information that includes a GUID, an optional Unicode string name, and a device + path. The string returned is allocated with AllocatePool(). The caller is + responsible for freeing the allocated string with FreePool(). + + The format of a <ConfigHdr> is as follows: + + GUID=<HexCh>32&NAME=<Char>NameLength&PATH=<HexChar>DevicePathSize<Null> + + @param[in] Guid Pointer to an EFI_GUID that is the routing information + GUID. Each of the 16 bytes in Guid is converted to + a 2 Unicode character hexadecimal string. This is + an optional parameter that may be NULL. + @param[in] Name Pointer to a Null-terminated Unicode string that is + the routing information NAME. This is an optional + parameter that may be NULL. Each 16-bit Unicode + character in Name is converted to a 4 character Unicode + hexadecimal string. + @param[in] DriverHandle The driver handle which supports a Device Path Protocol + that is the routing information PATH. Each byte of + the Device Path associated with DriverHandle is converted + to a 2 Unicode character hexadecimal string. + + @retval NULL DriverHandle does not support the Device Path Protocol. + @retval Other A pointer to the Null-terminate Unicode <ConfigHdr> string + +**/ +EFI_STRING +EFIAPI +HiiConstructConfigHdr ( + IN CONST EFI_GUID *Guid OPTIONAL, + IN CONST CHAR16 *Name OPTIONAL, + IN EFI_HANDLE DriverHandle + ) +{ + UINTN NameLength; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINTN DevicePathSize; + CHAR16 *String; + CHAR16 *ReturnString; + UINTN Index; + UINT8 *Buffer; + UINTN MaxLen; + + // + // Compute the length of Name in Unicode characters. + // If Name is NULL, then the length is 0. + // + NameLength = 0; + if (Name != NULL) { + NameLength = StrLen (Name); + } + + DevicePath = NULL; + DevicePathSize = 0; + // + // Retrieve DevicePath Protocol associated with DriverHandle + // + if (DriverHandle != NULL) { + DevicePath = DevicePathFromHandle (DriverHandle); + if (DevicePath == NULL) { + return NULL; + } + + // + // Compute the size of the device path in bytes + // + DevicePathSize = GetDevicePathSize (DevicePath); + } + + // + // GUID=<HexCh>32&NAME=<Char>NameLength&PATH=<HexChar>DevicePathSize <Null> + // | 5 | sizeof (EFI_GUID) * 2 | 6 | NameStrLen*4 | 6 | DevicePathSize * 2 | 1 | + // + MaxLen = 5 + sizeof (EFI_GUID) * 2 + 6 + NameLength * 4 + 6 + DevicePathSize * 2 + 1; + String = AllocateZeroPool (MaxLen * sizeof (CHAR16)); + if (String == NULL) { + return NULL; + } + + // + // Start with L"GUID=" + // + StrCpyS (String, MaxLen, L"GUID="); + ReturnString = String; + String += StrLen (String); + + if (Guid != NULL) { + // + // Append Guid converted to <HexCh>32 + // + for (Index = 0, Buffer = (UINT8 *)Guid; Index < sizeof (EFI_GUID); Index++) { + UnicodeValueToStringS ( + String, + MaxLen * sizeof (CHAR16) - ((UINTN)String - (UINTN)ReturnString), + PREFIX_ZERO | RADIX_HEX, + *(Buffer++), + 2 + ); + String += StrnLenS (String, MaxLen - ((UINTN)String - (UINTN)ReturnString) / sizeof (CHAR16)); + } + } + + // + // Append L"&NAME=" + // + StrCatS (ReturnString, MaxLen, L"&NAME="); + String += StrLen (String); + + if (Name != NULL) { + // + // Append Name converted to <Char>NameLength + // + for ( ; *Name != L'\0'; Name++) { + UnicodeValueToStringS ( + String, + sizeof (CHAR16) * MaxLen - ((UINTN)String - (UINTN)ReturnString), + PREFIX_ZERO | RADIX_HEX, + *Name, + 4 + ); + String += StrnLenS (String, MaxLen - ((UINTN)String - (UINTN)ReturnString) / sizeof (CHAR16)); + } + } + + // + // Append L"&PATH=" + // + StrCatS (ReturnString, MaxLen, L"&PATH="); + String += StrLen (String); + + // + // Append the device path associated with DriverHandle converted to <HexChar>DevicePathSize + // + for (Index = 0, Buffer = (UINT8 *)DevicePath; Index < DevicePathSize; Index++) { + UnicodeValueToStringS ( + String, + sizeof (CHAR16) * MaxLen - ((UINTN)String - (UINTN)ReturnString), + PREFIX_ZERO | RADIX_HEX, + *(Buffer++), + 2 + ); + String += StrnLenS (String, MaxLen - ((UINTN)String - (UINTN)ReturnString) / sizeof (CHAR16)); + } + + // + // Null terminate the Unicode string + // + *String = L'\0'; + + // + // Convert all hex digits in range [A-F] in the configuration header to [a-f] + // + return InternalHiiLowerConfigString (ReturnString); +} + +/** + Convert the hex UNICODE encoding string of UEFI GUID, NAME or device path + to binary buffer from <ConfigHdr>. + + This is a internal function. + + @param String UEFI configuration string. + @param Flag Flag specifies what type buffer will be retrieved. + @param Buffer Binary of Guid, Name or Device path. + + @retval EFI_INVALID_PARAMETER Any incoming parameter is invalid. + @retval EFI_OUT_OF_RESOURCES Lake of resources to store neccesary structures. + @retval EFI_SUCCESS The buffer data is retrieved and translated to + binary format. + +**/ +EFI_STATUS +InternalHiiGetBufferFromString ( + IN EFI_STRING String, + IN UINT8 Flag, + OUT UINT8 **Buffer + ) +{ + UINTN Length; + EFI_STRING ConfigHdr; + CHAR16 *StringPtr; + UINT8 *DataBuffer; + CHAR16 TemStr[5]; + UINTN Index; + UINT8 DigitUint8; + + if ((String == NULL) || (Buffer == NULL)) { + return EFI_INVALID_PARAMETER; + } + + DataBuffer = NULL; + StringPtr = NULL; + ConfigHdr = String; + // + // The content between 'GUID', 'NAME', 'PATH' of <ConfigHdr> and '&' of next element + // or '\0' (end of configuration string) is the UNICODE %02x bytes encoding string. + // + for (Length = 0; *String != 0 && *String != L'&'; String++, Length++) { + } + + switch (Flag) { + case GUID_CONFIG_STRING_TYPE: + case PATH_CONFIG_STRING_TYPE: + // + // The data in <ConfigHdr> is encoded as hex UNICODE %02x bytes in the same order + // as the device path and Guid resides in RAM memory. + // Translate the data into binary. + // + DataBuffer = (UINT8 *)AllocateZeroPool ((Length + 1) / 2); + if (DataBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Convert binary byte one by one + // + ZeroMem (TemStr, sizeof (TemStr)); + for (Index = 0; Index < Length; Index++) { + TemStr[0] = ConfigHdr[Index]; + DigitUint8 = (UINT8)StrHexToUint64 (TemStr); + if ((Index & 1) == 0) { + DataBuffer[Index/2] = DigitUint8; + } else { + DataBuffer[Index/2] = (UINT8)((DataBuffer[Index/2] << 4) + DigitUint8); + } + } + + *Buffer = DataBuffer; + break; + + case NAME_CONFIG_STRING_TYPE: + // + // Convert Config String to Unicode String, e.g. "0041004200430044" => "ABCD" + // + + // + // Add the tailling char L'\0' + // + DataBuffer = (UINT8 *)AllocateZeroPool ((Length/4 + 1) * sizeof (CHAR16)); + if (DataBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Convert character one by one + // + StringPtr = (CHAR16 *)DataBuffer; + ZeroMem (TemStr, sizeof (TemStr)); + for (Index = 0; Index < Length; Index += 4) { + StrnCpyS (TemStr, sizeof (TemStr) / sizeof (CHAR16), ConfigHdr + Index, 4); + StringPtr[Index/4] = (CHAR16)StrHexToUint64 (TemStr); + } + + // + // Add tailing L'\0' character + // + StringPtr[Index/4] = L'\0'; + + *Buffer = DataBuffer; + break; + + default: + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + +/** + This function checks VarOffset and VarWidth is in the block range. + + @param BlockArray The block array is to be checked. + @param VarOffset Offset of var to the structure + @param VarWidth Width of var. + + @retval TRUE This Var is in the block range. + @retval FALSE This Var is not in the block range. +**/ +BOOLEAN +BlockArrayCheck ( + IN IFR_BLOCK_DATA *BlockArray, + IN UINT16 VarOffset, + IN UINT16 VarWidth + ) +{ + LIST_ENTRY *Link; + IFR_BLOCK_DATA *BlockData; + + // + // No Request Block array, all vars are got. + // + if (BlockArray == NULL) { + return TRUE; + } + + // + // Check the input var is in the request block range. + // + for (Link = BlockArray->Entry.ForwardLink; Link != &BlockArray->Entry; Link = Link->ForwardLink) { + BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry); + if ((VarOffset >= BlockData->Offset) && ((VarOffset + VarWidth) <= (BlockData->Offset + BlockData->Width))) { + return TRUE; + } + } + + return FALSE; +} + +/** + Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET + or WIDTH or VALUE. + <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number> + + @param ValueString String in <BlockConfig> format and points to the + first character of <Number>. + @param ValueData The output value. Caller takes the responsibility + to free memory. + @param ValueLength Length of the <Number>, in characters. + + @retval EFI_OUT_OF_RESOURCES Insufficient resources to store neccessary + structures. + @retval EFI_SUCCESS Value of <Number> is outputted in Number + successfully. + +**/ +EFI_STATUS +EFIAPI +InternalHiiGetValueOfNumber ( + IN EFI_STRING ValueString, + OUT UINT8 **ValueData, + OUT UINTN *ValueLength + ) +{ + EFI_STRING StringPtr; + UINTN Length; + UINT8 *Buf; + UINT8 DigitUint8; + UINTN Index; + CHAR16 TemStr[2]; + + ASSERT (ValueString != NULL && ValueData != NULL && ValueLength != NULL); + ASSERT (*ValueString != L'\0'); + + // + // Get the length of value string + // + StringPtr = ValueString; + while (*StringPtr != L'\0' && *StringPtr != L'&') { + StringPtr++; + } + + Length = StringPtr - ValueString; + + // + // Allocate buffer to store the value + // + Buf = (UINT8 *)AllocateZeroPool ((Length + 1) / 2); + if (Buf == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Convert character one by one to the value buffer + // + ZeroMem (TemStr, sizeof (TemStr)); + for (Index = 0; Index < Length; Index++) { + TemStr[0] = ValueString[Length - Index - 1]; + DigitUint8 = (UINT8)StrHexToUint64 (TemStr); + if ((Index & 1) == 0) { + Buf[Index/2] = DigitUint8; + } else { + Buf[Index/2] = (UINT8)((DigitUint8 << 4) + Buf[Index/2]); + } + } + + // + // Set the converted value and string length. + // + *ValueData = Buf; + *ValueLength = Length; + return EFI_SUCCESS; +} + +/** + Get value from config request resp string. + + @param ConfigElement ConfigResp string contains the current setting. + @param VarName The variable name which need to get value. + @param VarValue The return value. + + @retval EFI_SUCCESS Get the value for the VarName + @retval EFI_OUT_OF_RESOURCES The memory is not enough. +**/ +EFI_STATUS +GetValueFromRequest ( + IN CHAR16 *ConfigElement, + IN CHAR16 *VarName, + OUT UINT64 *VarValue + ) +{ + UINT8 *TmpBuffer; + CHAR16 *StringPtr; + UINTN Length; + EFI_STATUS Status; + + // + // Find VarName related string. + // + StringPtr = StrStr (ConfigElement, VarName); + ASSERT (StringPtr != NULL); + + // + // Skip the "VarName=" string + // + StringPtr += StrLen (VarName) + 1; + + // + // Get Offset + // + Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length); + if (EFI_ERROR (Status)) { + return Status; + } + + *VarValue = 0; + CopyMem (VarValue, TmpBuffer, (((Length + 1) / 2) < sizeof (UINT64)) ? ((Length + 1) / 2) : sizeof (UINT64)); + + FreePool (TmpBuffer); + + return EFI_SUCCESS; +} + +/** + This internal function parses IFR data to validate current setting. + + Base on the NameValueType, if it is TRUE, RequestElement and HiiHandle is valid; + else the VarBuffer and CurrentBlockArray is valid. + + @param HiiPackageList Point to Hii package list. + @param PackageListLength The length of the pacakge. + @param VarGuid Guid of the buffer storage. + @param VarName Name of the buffer storage. + @param VarBuffer The data buffer for the storage. + @param CurrentBlockArray The block array from the config Requst string. + @param RequestElement The config string for this storage. + @param HiiHandle The HiiHandle for this formset. + @param NameValueType Whether current storage is name/value varstore or not. + + @retval EFI_SUCCESS The current setting is valid. + @retval EFI_OUT_OF_RESOURCES The memory is not enough. + @retval EFI_INVALID_PARAMETER The config string or the Hii package is invalid. +**/ +EFI_STATUS +ValidateQuestionFromVfr ( + IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList, + IN UINTN PackageListLength, + IN EFI_GUID *VarGuid, + IN CHAR16 *VarName, + IN UINT8 *VarBuffer, + IN IFR_BLOCK_DATA *CurrentBlockArray, + IN CHAR16 *RequestElement, + IN EFI_HII_HANDLE HiiHandle, + IN BOOLEAN NameValueType + ) +{ + IFR_BLOCK_DATA VarBlockData; + UINT16 Offset; + UINT16 Width; + UINT64 VarValue; + EFI_IFR_TYPE_VALUE TmpValue; + EFI_STATUS Status; + EFI_HII_PACKAGE_HEADER PackageHeader; + UINT32 PackageOffset; + UINT8 *PackageData; + UINTN IfrOffset; + EFI_IFR_OP_HEADER *IfrOpHdr; + EFI_IFR_VARSTORE *IfrVarStore; + EFI_IFR_VARSTORE_NAME_VALUE *IfrNameValueStore; + EFI_IFR_VARSTORE_EFI *IfrEfiVarStore; + IFR_VARSTORAGE_DATA VarStoreData; + EFI_IFR_ONE_OF *IfrOneOf; + EFI_IFR_NUMERIC *IfrNumeric; + EFI_IFR_ONE_OF_OPTION *IfrOneOfOption; + EFI_IFR_CHECKBOX *IfrCheckBox; + EFI_IFR_STRING *IfrString; + CHAR8 *VarStoreName; + UINTN Index; + CHAR16 *QuestionName; + CHAR16 *StringPtr; + UINT16 BitOffset; + UINT16 BitWidth; + UINT16 TotalBits; + UINTN StartBit; + UINTN EndBit; + BOOLEAN QuestionReferBitField; + UINT32 BufferValue; + + // + // Initialize the local variables. + // + Index = 0; + VarStoreName = NULL; + Status = EFI_SUCCESS; + VarValue = 0; + IfrVarStore = NULL; + IfrNameValueStore = NULL; + IfrEfiVarStore = NULL; + ZeroMem (&VarStoreData, sizeof (IFR_VARSTORAGE_DATA)); + ZeroMem (&VarBlockData, sizeof (VarBlockData)); + BitOffset = 0; + BitWidth = 0; + QuestionReferBitField = FALSE; + + // + // Check IFR value is in block data, then Validate Value + // + PackageOffset = sizeof (EFI_HII_PACKAGE_LIST_HEADER); + while (PackageOffset < PackageListLength) { + CopyMem (&PackageHeader, (UINT8 *)HiiPackageList + PackageOffset, sizeof (PackageHeader)); + + // + // Parse IFR opcode from the form package. + // + if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) { + IfrOffset = sizeof (PackageHeader); + PackageData = (UINT8 *)HiiPackageList + PackageOffset; + while (IfrOffset < PackageHeader.Length) { + IfrOpHdr = (EFI_IFR_OP_HEADER *)(PackageData + IfrOffset); + // + // Validate current setting to the value built in IFR opcode + // + switch (IfrOpHdr->OpCode) { + case EFI_IFR_VARSTORE_OP: + // + // VarStoreId has been found. No further found. + // + if (VarStoreData.VarStoreId != 0) { + break; + } + + // + // Find the matched VarStoreId to the input VarGuid and VarName + // + IfrVarStore = (EFI_IFR_VARSTORE *)IfrOpHdr; + if (CompareGuid ((EFI_GUID *)(VOID *)&IfrVarStore->Guid, VarGuid)) { + VarStoreName = (CHAR8 *)IfrVarStore->Name; + for (Index = 0; VarStoreName[Index] != 0; Index++) { + if ((CHAR16)VarStoreName[Index] != VarName[Index]) { + break; + } + } + + // + // The matched VarStore is found. + // + if ((VarStoreName[Index] != 0) || (VarName[Index] != 0)) { + IfrVarStore = NULL; + } + } else { + IfrVarStore = NULL; + } + + if (IfrVarStore != NULL) { + VarStoreData.VarStoreId = IfrVarStore->VarStoreId; + VarStoreData.Size = IfrVarStore->Size; + } + + break; + case EFI_IFR_VARSTORE_NAME_VALUE_OP: + // + // VarStoreId has been found. No further found. + // + if (VarStoreData.VarStoreId != 0) { + break; + } + + // + // Find the matched VarStoreId to the input VarGuid + // + IfrNameValueStore = (EFI_IFR_VARSTORE_NAME_VALUE *)IfrOpHdr; + if (!CompareGuid ((EFI_GUID *)(VOID *)&IfrNameValueStore->Guid, VarGuid)) { + IfrNameValueStore = NULL; + } + + if (IfrNameValueStore != NULL) { + VarStoreData.VarStoreId = IfrNameValueStore->VarStoreId; + } + + break; + case EFI_IFR_VARSTORE_EFI_OP: + // + // VarStore is found. Don't need to search any more. + // + if (VarStoreData.VarStoreId != 0) { + break; + } + + IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpHdr; + + // + // If the length is small than the structure, this is from old efi + // varstore definition. Old efi varstore get config directly from + // GetVariable function. + // + if (IfrOpHdr->Length < sizeof (EFI_IFR_VARSTORE_EFI)) { + break; + } + + if (CompareGuid ((EFI_GUID *)(VOID *)&IfrEfiVarStore->Guid, VarGuid)) { + VarStoreName = (CHAR8 *)IfrEfiVarStore->Name; + for (Index = 0; VarStoreName[Index] != 0; Index++) { + if ((CHAR16)VarStoreName[Index] != VarName[Index]) { + break; + } + } + + // + // The matched VarStore is found. + // + if ((VarStoreName[Index] != 0) || (VarName[Index] != 0)) { + IfrEfiVarStore = NULL; + } + } else { + IfrEfiVarStore = NULL; + } + + if (IfrEfiVarStore != NULL) { + // + // Find the matched VarStore + // + VarStoreData.VarStoreId = IfrEfiVarStore->VarStoreId; + VarStoreData.Size = IfrEfiVarStore->Size; + } + + break; + case EFI_IFR_FORM_OP: + case EFI_IFR_FORM_MAP_OP: + // + // Check the matched VarStoreId is found. + // + if (VarStoreData.VarStoreId == 0) { + return EFI_SUCCESS; + } + + break; + case EFI_IFR_ONE_OF_OP: + // + // Check whether current value is the one of option. + // + + // + // OneOf question is not in IFR Form. This IFR form is not valid. + // + if (VarStoreData.VarStoreId == 0) { + return EFI_INVALID_PARAMETER; + } + + // + // Check whether this question is for the requested varstore. + // + IfrOneOf = (EFI_IFR_ONE_OF *)IfrOpHdr; + if (IfrOneOf->Question.VarStoreId != VarStoreData.VarStoreId) { + break; + } + + if (NameValueType) { + QuestionName = HiiGetString (HiiHandle, IfrOneOf->Question.VarStoreInfo.VarName, NULL); + ASSERT (QuestionName != NULL); + + if (StrStr (RequestElement, QuestionName) == NULL) { + // + // This question is not in the current configuration string. Skip it. + // + break; + } + + Status = GetValueFromRequest (RequestElement, QuestionName, &VarValue); + if (EFI_ERROR (Status)) { + return Status; + } + } else { + // + // Get Offset by Question header and Width by DataType Flags + // + if (QuestionReferBitField) { + // + // Get the byte offset/width for bit field. + // + BitOffset = IfrOneOf->Question.VarStoreInfo.VarOffset; + BitWidth = IfrOneOf->Flags & EDKII_IFR_NUMERIC_SIZE_BIT; + Offset = BitOffset / 8; + TotalBits = BitOffset % 8 + BitWidth; + Width = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1); + } else { + Offset = IfrOneOf->Question.VarStoreInfo.VarOffset; + Width = (UINT16)(1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE)); + } + + // + // Check whether this question is in current block array. + // + if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) { + // + // This question is not in the current configuration string. Skip it. + // + break; + } + + // + // Check this var question is in the var storage + // + if ((Offset + Width) > VarStoreData.Size) { + // + // This question exceeds the var store size. + // + return EFI_INVALID_PARAMETER; + } + + // + // Get the current value for oneof opcode + // + VarValue = 0; + if (QuestionReferBitField) { + // + // Get the value in bit fields. + // + StartBit = BitOffset % 8; + EndBit = StartBit + BitWidth - 1; + CopyMem ((UINT8 *)&BufferValue, VarBuffer + Offset, Width); + VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit); + } else { + CopyMem (&VarValue, VarBuffer + Offset, Width); + } + } + + // + // Set Block Data, to be checked in the following Oneof option opcode. + // + VarBlockData.OpCode = IfrOpHdr->OpCode; + VarBlockData.Scope = IfrOpHdr->Scope; + break; + case EFI_IFR_NUMERIC_OP: + // + // Check the current value is in the numeric range. + // + + // + // Numeric question is not in IFR Form. This IFR form is not valid. + // + if (VarStoreData.VarStoreId == 0) { + return EFI_INVALID_PARAMETER; + } + + // + // Check whether this question is for the requested varstore. + // + IfrNumeric = (EFI_IFR_NUMERIC *)IfrOpHdr; + if (IfrNumeric->Question.VarStoreId != VarStoreData.VarStoreId) { + break; + } + + if (NameValueType) { + QuestionName = HiiGetString (HiiHandle, IfrNumeric->Question.VarStoreInfo.VarName, NULL); + ASSERT (QuestionName != NULL); + + if (StrStr (RequestElement, QuestionName) == NULL) { + // + // This question is not in the current configuration string. Skip it. + // + break; + } + + Status = GetValueFromRequest (RequestElement, QuestionName, &VarValue); + if (EFI_ERROR (Status)) { + return Status; + } + } else { + // + // Get Offset by Question header and Width by DataType Flags + // + if (QuestionReferBitField) { + // + // Get the byte offset/width for bit field. + // + BitOffset = IfrNumeric->Question.VarStoreInfo.VarOffset; + BitWidth = IfrNumeric->Flags & EDKII_IFR_NUMERIC_SIZE_BIT; + Offset = BitOffset / 8; + TotalBits = BitOffset % 8 + BitWidth; + Width = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1); + } else { + Offset = IfrNumeric->Question.VarStoreInfo.VarOffset; + Width = (UINT16)(1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE)); + } + + // + // Check whether this question is in current block array. + // + if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) { + // + // This question is not in the current configuration string. Skip it. + // + break; + } + + // + // Check this var question is in the var storage + // + if ((Offset + Width) > VarStoreData.Size) { + // + // This question exceeds the var store size. + // + return EFI_INVALID_PARAMETER; + } + + // + // Check the current value is in the numeric range. + // + VarValue = 0; + if (QuestionReferBitField) { + // + // Get the value in the bit fields. + // + StartBit = BitOffset % 8; + EndBit = StartBit + BitWidth - 1; + CopyMem ((UINT8 *)&BufferValue, VarBuffer + Offset, Width); + VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit); + } else { + CopyMem (&VarValue, VarBuffer + Offset, Width); + } + } + + if ( QuestionReferBitField) { + // + // Value in bit fields was stored as UINt32 type. + // + if ((IfrNumeric->Flags & EDKII_IFR_DISPLAY_BIT) == 0) { + if (((INT32)VarValue < (INT32)IfrNumeric->data.u32.MinValue) || ((INT32)VarValue > (INT32)IfrNumeric->data.u32.MaxValue)) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + } else { + if ((VarValue < IfrNumeric->data.u32.MinValue) || (VarValue > IfrNumeric->data.u32.MaxValue)) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + } + } else { + if ((IfrNumeric->Flags & EFI_IFR_DISPLAY) == 0) { + switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) { + case EFI_IFR_NUMERIC_SIZE_1: + if (((INT8)VarValue < (INT8)IfrNumeric->data.u8.MinValue) || ((INT8)VarValue > (INT8)IfrNumeric->data.u8.MaxValue)) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + + break; + case EFI_IFR_NUMERIC_SIZE_2: + if (((INT16)VarValue < (INT16)IfrNumeric->data.u16.MinValue) || ((INT16)VarValue > (INT16)IfrNumeric->data.u16.MaxValue)) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + + break; + case EFI_IFR_NUMERIC_SIZE_4: + if (((INT32)VarValue < (INT32)IfrNumeric->data.u32.MinValue) || ((INT32)VarValue > (INT32)IfrNumeric->data.u32.MaxValue)) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + + break; + case EFI_IFR_NUMERIC_SIZE_8: + if (((INT64)VarValue < (INT64)IfrNumeric->data.u64.MinValue) || ((INT64)VarValue > (INT64)IfrNumeric->data.u64.MaxValue)) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + + break; + } + } else { + switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) { + case EFI_IFR_NUMERIC_SIZE_1: + if (((UINT8)VarValue < IfrNumeric->data.u8.MinValue) || ((UINT8)VarValue > IfrNumeric->data.u8.MaxValue)) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + + break; + case EFI_IFR_NUMERIC_SIZE_2: + if (((UINT16)VarValue < IfrNumeric->data.u16.MinValue) || ((UINT16)VarValue > IfrNumeric->data.u16.MaxValue)) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + + break; + case EFI_IFR_NUMERIC_SIZE_4: + if (((UINT32)VarValue < IfrNumeric->data.u32.MinValue) || ((UINT32)VarValue > IfrNumeric->data.u32.MaxValue)) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + + break; + case EFI_IFR_NUMERIC_SIZE_8: + if (((UINT64)VarValue < IfrNumeric->data.u64.MinValue) || ((UINT64)VarValue > IfrNumeric->data.u64.MaxValue)) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + + break; + } + } + } + + break; + case EFI_IFR_CHECKBOX_OP: + // + // Check value is BOOLEAN type, only 0 and 1 is valid. + // + + // + // CheckBox question is not in IFR Form. This IFR form is not valid. + // + if (VarStoreData.VarStoreId == 0) { + return EFI_INVALID_PARAMETER; + } + + // + // Check whether this question is for the requested varstore. + // + IfrCheckBox = (EFI_IFR_CHECKBOX *)IfrOpHdr; + if (IfrCheckBox->Question.VarStoreId != VarStoreData.VarStoreId) { + break; + } + + if (NameValueType) { + QuestionName = HiiGetString (HiiHandle, IfrCheckBox->Question.VarStoreInfo.VarName, NULL); + ASSERT (QuestionName != NULL); + + if (StrStr (RequestElement, QuestionName) == NULL) { + // + // This question is not in the current configuration string. Skip it. + // + break; + } + + Status = GetValueFromRequest (RequestElement, QuestionName, &VarValue); + if (EFI_ERROR (Status)) { + return Status; + } + } else { + // + // Get Offset by Question header + // + if (QuestionReferBitField) { + // + // Get the byte offset/width for bit field. + // + BitOffset = IfrCheckBox->Question.VarStoreInfo.VarOffset; + BitWidth = 1; + Offset = BitOffset / 8; + TotalBits = BitOffset % 8 + BitWidth; + Width = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1); + } else { + Offset = IfrCheckBox->Question.VarStoreInfo.VarOffset; + Width = (UINT16)sizeof (BOOLEAN); + } + + // + // Check whether this question is in current block array. + // + if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) { + // + // This question is not in the current configuration string. Skip it. + // + break; + } + + // + // Check this var question is in the var storage + // + if ((Offset + Width) > VarStoreData.Size) { + // + // This question exceeds the var store size. + // + return EFI_INVALID_PARAMETER; + } + + // + // Check the current value is in the numeric range. + // + VarValue = 0; + if (QuestionReferBitField) { + // + // Get the value in bit fields. + // + StartBit = BitOffset % 8; + EndBit = StartBit + BitWidth - 1; + CopyMem ((UINT8 *)&BufferValue, VarBuffer + Offset, Width); + VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit); + } else { + CopyMem (&VarValue, VarBuffer + Offset, Width); + } + } + + // + // Boolean type, only 1 and 0 is valid. + // + if (VarValue > 1) { + return EFI_INVALID_PARAMETER; + } + + break; + case EFI_IFR_STRING_OP: + // + // Check current string length is less than maxsize + // + + // + // CheckBox question is not in IFR Form. This IFR form is not valid. + // + if (VarStoreData.VarStoreId == 0) { + return EFI_INVALID_PARAMETER; + } + + // + // Check whether this question is for the requested varstore. + // + IfrString = (EFI_IFR_STRING *)IfrOpHdr; + if (IfrString->Question.VarStoreId != VarStoreData.VarStoreId) { + break; + } + + // + // Get the Max size of the string. + // + Width = (UINT16)(IfrString->MaxSize * sizeof (UINT16)); + if (NameValueType) { + QuestionName = HiiGetString (HiiHandle, IfrString->Question.VarStoreInfo.VarName, NULL); + ASSERT (QuestionName != NULL); + + StringPtr = StrStr (RequestElement, QuestionName); + if (StringPtr == NULL) { + // + // This question is not in the current configuration string. Skip it. + // + break; + } + + // + // Skip the VarName. + // + StringPtr += StrLen (QuestionName); + + // + // Skip the "=". + // + StringPtr += 1; + + // + // Check current string length is less than maxsize + // e.g Config String: "0041004200430044", Unicode String: "ABCD". Unicode String length = Config String length / 4. + // Config string format in UEFI spec. + // <NvConfig> ::= <Label>'='<String> + // <String> ::= [<Char>]+ + // <Char> ::= <HexCh>4 + // + if (StrLen (StringPtr) / 4 > IfrString->MaxSize) { + return EFI_INVALID_PARAMETER; + } + } else { + // + // Get Offset/Width by Question header and OneOf Flags + // + Offset = IfrString->Question.VarStoreInfo.VarOffset; + // + // Check whether this question is in current block array. + // + if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) { + // + // This question is not in the current configuration string. Skip it. + // + break; + } + + // + // Check this var question is in the var storage + // + if ((Offset + Width) > VarStoreData.Size) { + // + // This question exceeds the var store size. + // + return EFI_INVALID_PARAMETER; + } + + // + // Check current string length is less than maxsize + // + if (StrLen ((CHAR16 *)(VarBuffer + Offset)) > IfrString->MaxSize) { + return EFI_INVALID_PARAMETER; + } + } + + break; + case EFI_IFR_ONE_OF_OPTION_OP: + // + // Opcode Scope is zero. This one of option is not to be checked. + // + if (VarBlockData.Scope == 0) { + break; + } + + // + // Only check for OneOf and OrderList opcode + // + IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *)IfrOpHdr; + if (VarBlockData.OpCode == EFI_IFR_ONE_OF_OP) { + // + // Check current value is the value of one of option. + // + ASSERT (IfrOneOfOption->Type <= EFI_IFR_TYPE_NUM_SIZE_64); + ZeroMem (&TmpValue, sizeof (EFI_IFR_TYPE_VALUE)); + CopyMem (&TmpValue, &IfrOneOfOption->Value, IfrOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value)); + if (VarValue == TmpValue.u64) { + // + // The value is one of option value. + // Set OpCode to Zero, don't need check again. + // + VarBlockData.OpCode = 0; + } + } + + break; + case EFI_IFR_END_OP: + QuestionReferBitField = FALSE; + // + // Decrease opcode scope for the validated opcode + // + if (VarBlockData.Scope > 0) { + VarBlockData.Scope--; + } + + // + // OneOf value doesn't belong to one of option value. + // + if ((VarBlockData.Scope == 0) && (VarBlockData.OpCode == EFI_IFR_ONE_OF_OP)) { + return EFI_INVALID_PARAMETER; + } + + break; + case EFI_IFR_GUID_OP: + if (CompareGuid ((EFI_GUID *)((UINT8 *)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) { + QuestionReferBitField = TRUE; + } + + break; + default: + // + // Increase Scope for the validated opcode + // + if (VarBlockData.Scope > 0) { + VarBlockData.Scope = (UINT8)(VarBlockData.Scope + IfrOpHdr->Scope); + } + + break; + } + + // + // Go to the next opcode + // + IfrOffset += IfrOpHdr->Length; + } + + // + // Only one form is in a package list. + // + break; + } + + // + // Go to next package. + // + PackageOffset += PackageHeader.Length; + } + + return EFI_SUCCESS; +} + +/** + This internal function parses IFR data to validate current setting. + + @param ConfigElement ConfigResp element string contains the current setting. + @param CurrentBlockArray Current block array. + @param VarBuffer Data buffer for this varstore. + + @retval EFI_SUCCESS The current setting is valid. + @retval EFI_OUT_OF_RESOURCES The memory is not enough. + @retval EFI_INVALID_PARAMETER The config string or the Hii package is invalid. +**/ +EFI_STATUS +GetBlockDataInfo ( + IN CHAR16 *ConfigElement, + OUT IFR_BLOCK_DATA **CurrentBlockArray, + OUT UINT8 **VarBuffer + ) +{ + IFR_BLOCK_DATA *BlockData; + IFR_BLOCK_DATA *NewBlockData; + EFI_STRING StringPtr; + UINTN Length; + UINT8 *TmpBuffer; + UINT16 Offset; + UINT16 Width; + LIST_ENTRY *Link; + UINTN MaxBufferSize; + EFI_STATUS Status; + IFR_BLOCK_DATA *BlockArray; + UINT8 *DataBuffer; + + // + // Initialize the local variables. + // + Status = EFI_SUCCESS; + BlockData = NULL; + NewBlockData = NULL; + TmpBuffer = NULL; + BlockArray = NULL; + MaxBufferSize = HII_LIB_DEFAULT_VARSTORE_SIZE; + DataBuffer = AllocateZeroPool (MaxBufferSize); + if (DataBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Init BlockArray + // + BlockArray = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA)); + if (BlockArray == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + InitializeListHead (&BlockArray->Entry); + + StringPtr = StrStr (ConfigElement, L"&OFFSET="); + ASSERT (StringPtr != NULL); + + // + // Parse each <RequestElement> if exists + // Only <BlockName> format is supported by this help function. + // <BlockName> ::= &'OFFSET='<Number>&'WIDTH='<Number> + // + while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) { + // + // Skip the &OFFSET= string + // + StringPtr += StrLen (L"&OFFSET="); + + // + // Get Offset + // + Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length); + if (EFI_ERROR (Status)) { + goto Done; + } + + Offset = 0; + CopyMem ( + &Offset, + TmpBuffer, + (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16) + ); + FreePool (TmpBuffer); + TmpBuffer = NULL; + + StringPtr += Length; + if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + StringPtr += StrLen (L"&WIDTH="); + + // + // Get Width + // + Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length); + if (EFI_ERROR (Status)) { + goto Done; + } + + Width = 0; + CopyMem ( + &Width, + TmpBuffer, + (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16) + ); + FreePool (TmpBuffer); + TmpBuffer = NULL; + + StringPtr += Length; + if ((*StringPtr != 0) && (*StringPtr != L'&')) { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + StringPtr += StrLen (L"&VALUE="); + + // + // Get Value + // + Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length); + if (EFI_ERROR (Status)) { + goto Done; + } + + StringPtr += Length; + if ((*StringPtr != 0) && (*StringPtr != L'&')) { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + // + // Check whether VarBuffer is enough + // + if ((UINT32)Offset + Width > MaxBufferSize) { + DataBuffer = ReallocatePool ( + MaxBufferSize, + Offset + Width + HII_LIB_DEFAULT_VARSTORE_SIZE, + DataBuffer + ); + if (DataBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + MaxBufferSize = Offset + Width + HII_LIB_DEFAULT_VARSTORE_SIZE; + } + + // + // Update the Block with configuration info + // + CopyMem (DataBuffer + Offset, TmpBuffer, Width); + FreePool (TmpBuffer); + TmpBuffer = NULL; + + // + // Set new Block Data + // + NewBlockData = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA)); + if (NewBlockData == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + NewBlockData->Offset = Offset; + NewBlockData->Width = Width; + + // + // Insert the new block data into the block data array. + // + for (Link = BlockArray->Entry.ForwardLink; Link != &BlockArray->Entry; Link = Link->ForwardLink) { + BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry); + if (NewBlockData->Offset == BlockData->Offset) { + if (NewBlockData->Width > BlockData->Width) { + BlockData->Width = NewBlockData->Width; + } + + FreePool (NewBlockData); + break; + } else if (NewBlockData->Offset < BlockData->Offset) { + // + // Insert new block data as the previous one of this link. + // + InsertTailList (Link, &NewBlockData->Entry); + break; + } + } + + // + // Insert new block data into the array tail. + // + if (Link == &BlockArray->Entry) { + InsertTailList (Link, &NewBlockData->Entry); + } + + // + // If '\0', parsing is finished. + // + if (*StringPtr == 0) { + break; + } + + // + // Go to next ConfigBlock + // + } + + // + // Merge the aligned block data into the single block data. + // + Link = BlockArray->Entry.ForwardLink; + while ((Link != &BlockArray->Entry) && (Link->ForwardLink != &BlockArray->Entry)) { + BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry); + NewBlockData = BASE_CR (Link->ForwardLink, IFR_BLOCK_DATA, Entry); + if ((NewBlockData->Offset >= BlockData->Offset) && (NewBlockData->Offset <= (BlockData->Offset + BlockData->Width))) { + if ((NewBlockData->Offset + NewBlockData->Width) > (BlockData->Offset + BlockData->Width)) { + BlockData->Width = (UINT16)(NewBlockData->Offset + NewBlockData->Width - BlockData->Offset); + } + + RemoveEntryList (Link->ForwardLink); + FreePool (NewBlockData); + continue; + } + + Link = Link->ForwardLink; + } + + *VarBuffer = DataBuffer; + *CurrentBlockArray = BlockArray; + return EFI_SUCCESS; + +Done: + if (DataBuffer != NULL) { + FreePool (DataBuffer); + } + + if (BlockArray != NULL) { + // + // Free Link Array CurrentBlockArray + // + while (!IsListEmpty (&BlockArray->Entry)) { + BlockData = BASE_CR (BlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry); + RemoveEntryList (&BlockData->Entry); + FreePool (BlockData); + } + + FreePool (BlockArray); + } + + return Status; +} + +/** + This internal function parses IFR data to validate current setting. + + @param ConfigResp ConfigResp string contains the current setting. + @param HiiPackageList Point to Hii package list. + @param PackageListLength The length of the pacakge. + @param VarGuid Guid of the buffer storage. + @param VarName Name of the buffer storage. + @param HiiHandle The HiiHandle for this package. + + @retval EFI_SUCCESS The current setting is valid. + @retval EFI_OUT_OF_RESOURCES The memory is not enough. + @retval EFI_INVALID_PARAMETER The config string or the Hii package is invalid. +**/ +EFI_STATUS +EFIAPI +InternalHiiValidateCurrentSetting ( + IN EFI_STRING ConfigResp, + IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList, + IN UINTN PackageListLength, + IN EFI_GUID *VarGuid, + IN CHAR16 *VarName, + IN EFI_HII_HANDLE HiiHandle + ) +{ + CHAR16 *StringPtr; + EFI_STATUS Status; + IFR_BLOCK_DATA *CurrentBlockArray; + IFR_BLOCK_DATA *BlockData; + UINT8 *VarBuffer; + BOOLEAN NameValueType; + + CurrentBlockArray = NULL; + VarBuffer = NULL; + StringPtr = NULL; + Status = EFI_SUCCESS; + + // + // If StringPtr != NULL, get the request elements. + // + if (StrStr (ConfigResp, L"&OFFSET=") != NULL) { + Status = GetBlockDataInfo (ConfigResp, &CurrentBlockArray, &VarBuffer); + if (EFI_ERROR (Status)) { + return Status; + } + + NameValueType = FALSE; + } else { + // + // Skip header part. + // + StringPtr = StrStr (ConfigResp, L"PATH="); + ASSERT (StringPtr != NULL); + + if (StrStr (StringPtr, L"&") != NULL) { + NameValueType = TRUE; + } else { + // + // Not found Request element, return success. + // + return EFI_SUCCESS; + } + } + + Status = ValidateQuestionFromVfr ( + HiiPackageList, + PackageListLength, + VarGuid, + VarName, + VarBuffer, + CurrentBlockArray, + ConfigResp, + HiiHandle, + NameValueType + ); + + if (VarBuffer != NULL) { + FreePool (VarBuffer); + } + + if (CurrentBlockArray != NULL) { + // + // Free Link Array CurrentBlockArray + // + while (!IsListEmpty (&CurrentBlockArray->Entry)) { + BlockData = BASE_CR (CurrentBlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry); + RemoveEntryList (&BlockData->Entry); + FreePool (BlockData); + } + + FreePool (CurrentBlockArray); + } + + return Status; +} + +/** + Check whether the ConfigRequest string has the request elements. + For EFI_HII_VARSTORE_BUFFER type, the request has "&OFFSET=****&WIDTH=****..." format. + For EFI_HII_VARSTORE_NAME_VALUE type, the request has "&NAME1**&NAME2..." format. + + @param ConfigRequest The input config request string. + + @retval TRUE The input include config request elements. + @retval FALSE The input string not includes. + +**/ +BOOLEAN +GetElementsFromRequest ( + IN EFI_STRING ConfigRequest + ) +{ + EFI_STRING TmpRequest; + + TmpRequest = StrStr (ConfigRequest, L"PATH="); + ASSERT (TmpRequest != NULL); + + if ((StrStr (TmpRequest, L"&OFFSET=") != NULL) || (StrStr (TmpRequest, L"&") != NULL)) { + return TRUE; + } + + return FALSE; +} + +/** + This function parses the input ConfigRequest string and its matched IFR code + string for setting default value and validating current setting. + + 1. For setting default action, Reset the default value specified by DefaultId + to the driver configuration got by Request string. + 2. For validating current setting, Validate the current configuration + by parsing HII form IFR opcode. + + NULL request string support depends on the ExportConfig interface of + HiiConfigRouting protocol in UEFI specification. + + @param Request A null-terminated Unicode string in + <MultiConfigRequest> format. It can be NULL. + If it is NULL, all current configuration for the + entirety of the current HII database will be validated. + If it is NULL, all configuration for the + entirety of the current HII database will be reset. + @param DefaultId Specifies the type of defaults to retrieve only for setting default action. + @param ActionType Action supports setting defaults and validate current setting. + + @retval TRUE Action runs successfully. + @retval FALSE Action is not valid or Action can't be executed successfully.. +**/ +BOOLEAN +EFIAPI +InternalHiiIfrValueAction ( + IN CONST EFI_STRING Request OPTIONAL, + IN UINT16 DefaultId, + IN UINT8 ActionType + ) +{ + EFI_STRING ConfigAltResp; + EFI_STRING ConfigAltHdr; + EFI_STRING ConfigResp; + EFI_STRING Progress; + EFI_STRING StringPtr; + EFI_STRING StringHdr; + EFI_STATUS Status; + EFI_HANDLE DriverHandle; + EFI_HANDLE TempDriverHandle; + EFI_HII_HANDLE *HiiHandleBuffer; + EFI_HII_HANDLE HiiHandle; + UINT32 Index; + EFI_GUID *VarGuid; + EFI_STRING VarName; + + EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList; + UINTN PackageListLength; + UINTN MaxLen; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + + ConfigAltResp = NULL; + ConfigResp = NULL; + VarGuid = NULL; + VarName = NULL; + DevicePath = NULL; + ConfigAltHdr = NULL; + HiiHandleBuffer = NULL; + Index = 0; + TempDriverHandle = NULL; + HiiHandle = NULL; + HiiPackageList = NULL; + + // + // Only support set default and validate setting action. + // + if ((ActionType != ACTION_SET_DEFAUTL_VALUE) && (ActionType != ACTION_VALIDATE_SETTING)) { + return FALSE; + } + + // + // Get the full requested value and deault value string. + // + if (Request != NULL) { + Status = gHiiConfigRouting->ExtractConfig ( + gHiiConfigRouting, + Request, + &Progress, + &ConfigAltResp + ); + } else { + Status = gHiiConfigRouting->ExportConfig ( + gHiiConfigRouting, + &ConfigAltResp + ); + } + + if (EFI_ERROR (Status)) { + return FALSE; + } + + StringPtr = ConfigAltResp; + ASSERT (StringPtr != NULL); + + while (*StringPtr != L'\0') { + // + // 1. Find <ConfigHdr> GUID=...&NAME=...&PATH=... + // + StringHdr = StringPtr; + + // + // Get Guid value + // + if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + StringPtr += StrLen (L"GUID="); + Status = InternalHiiGetBufferFromString (StringPtr, GUID_CONFIG_STRING_TYPE, (UINT8 **)&VarGuid); + if (EFI_ERROR (Status)) { + goto Done; + } + + // + // Get Name value VarName + // + while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&NAME=", StrLen (L"&NAME=")) != 0) { + StringPtr++; + } + + if (*StringPtr == L'\0') { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + StringPtr += StrLen (L"&NAME="); + Status = InternalHiiGetBufferFromString (StringPtr, NAME_CONFIG_STRING_TYPE, (UINT8 **)&VarName); + if (EFI_ERROR (Status)) { + goto Done; + } + + // + // Get Path value DevicePath + // + while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) { + StringPtr++; + } + + if (*StringPtr == L'\0') { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + StringPtr += StrLen (L"&PATH="); + Status = InternalHiiGetBufferFromString (StringPtr, PATH_CONFIG_STRING_TYPE, (UINT8 **)&DevicePath); + if (EFI_ERROR (Status)) { + goto Done; + } + + // + // Get the Driver handle by the got device path. + // + TempDevicePath = DevicePath; + Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &TempDevicePath, &DriverHandle); + if (EFI_ERROR (Status)) { + goto Done; + } + + // + // Find the matched Hii Handle for the found Driver handle + // + HiiHandleBuffer = HiiGetHiiHandles (NULL); + if (HiiHandleBuffer == NULL) { + Status = EFI_NOT_FOUND; + goto Done; + } + + for (Index = 0; HiiHandleBuffer[Index] != NULL; Index++) { + gHiiDatabase->GetPackageListHandle (gHiiDatabase, HiiHandleBuffer[Index], &TempDriverHandle); + if (TempDriverHandle == DriverHandle) { + break; + } + } + + HiiHandle = HiiHandleBuffer[Index]; + FreePool (HiiHandleBuffer); + + 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 HiiPackage by HiiHandle + // + PackageListLength = 0; + HiiPackageList = NULL; + Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, 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 = AllocatePool (PackageListLength); + if (HiiPackageList == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + // + // Get PackageList on HiiHandle + // + Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, HiiHandle, &PackageListLength, HiiPackageList); + if (EFI_ERROR (Status)) { + goto Done; + } + + // + // 3. Call ConfigRouting GetAltCfg(ConfigRoute, <ConfigResponse>, Guid, Name, DevicePath, AltCfgId, AltCfgResp) + // Get the default configuration string according to the default ID. + // + Status = gHiiConfigRouting->GetAltConfig ( + gHiiConfigRouting, + ConfigAltResp, + VarGuid, + VarName, + DevicePath, + (ActionType == ACTION_SET_DEFAUTL_VALUE) ? &DefaultId : NULL, // 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 (!GetElementsFromRequest (ConfigResp)) { + 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. + // + if (ActionType == ACTION_SET_DEFAUTL_VALUE) { + // + // Set the default configuration information. + // + Status = gHiiConfigRouting->RouteConfig (gHiiConfigRouting, ConfigResp, &Progress); + } else { + // + // Current Setting is in ConfigResp, will be set into buffer, then check it again. + // + Status = InternalHiiValidateCurrentSetting (ConfigResp, HiiPackageList, PackageListLength, VarGuid, VarName, HiiHandle); + } + + if (EFI_ERROR (Status)) { + goto Done; + } + +NextConfigAltResp: + // + // Free the allocated pacakge buffer and the got ConfigResp string. + // + if (HiiPackageList != NULL) { + FreePool (HiiPackageList); + HiiPackageList = NULL; + } + + if (ConfigResp != NULL) { + FreePool (ConfigResp); + ConfigResp = NULL; + } + + // + // Free the allocated buffer. + // + FreePool (VarGuid); + VarGuid = NULL; + + FreePool (VarName); + VarName = NULL; + + 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 | StrLen (ConfigHdr) | 8 | 1 | + // + MaxLen = 1 + StringPtr - StringHdr + 8 + 1; + ConfigAltHdr = AllocateZeroPool (MaxLen * sizeof (CHAR16)); + if (ConfigAltHdr == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpyS (ConfigAltHdr, MaxLen, L"&"); + StrnCatS (ConfigAltHdr, MaxLen, StringHdr, StringPtr - StringHdr); + StrCatS (ConfigAltHdr, MaxLen, L"&ALTCFG="); + + // + // Skip all AltResp (AltConfigHdr ConfigBody) for the same ConfigHdr + // + while ((StringHdr = StrStr (StringPtr, ConfigAltHdr)) != NULL) { + StringPtr = StringHdr + StrLen (ConfigAltHdr); + if (*StringPtr == L'\0') { + break; + } + } + + // + // Free the allocated ConfigAltHdr string + // + FreePool (ConfigAltHdr); + if (*StringPtr == L'\0') { + break; + } + + // + // Find &GUID as the next ConfigHdr + // + StringPtr = StrStr (StringPtr, L"&GUID"); + if (StringPtr == NULL) { + break; + } + + // + // Skip char '&' + // + StringPtr++; + } + +Done: + if (VarGuid != NULL) { + FreePool (VarGuid); + } + + if (VarName != NULL) { + FreePool (VarName); + } + + if (DevicePath != NULL) { + FreePool (DevicePath); + } + + if (ConfigResp != NULL) { + FreePool (ConfigResp); + } + + if (ConfigAltResp != NULL) { + FreePool (ConfigAltResp); + } + + if (HiiPackageList != NULL) { + FreePool (HiiPackageList); + } + + if (EFI_ERROR (Status)) { + return FALSE; + } + + return TRUE; +} + +/** + Validate the current configuration by parsing HII form IFR opcode. + + NULL request string support depends on the ExportConfig interface of + HiiConfigRouting protocol in UEFI specification. + + @param Request A null-terminated Unicode string in + <MultiConfigRequest> format. It can be NULL. + If it is NULL, all current configuration for the + entirety of the current HII database will be validated. + + @retval TRUE Current configuration is valid. + @retval FALSE Current configuration is invalid. +**/ +BOOLEAN +EFIAPI +HiiValidateSettings ( + IN CONST EFI_STRING Request OPTIONAL + ) +{ + return InternalHiiIfrValueAction (Request, 0, ACTION_VALIDATE_SETTING); +} + +/** + 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. + + @param 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. + @param DefaultId Specifies the type of defaults to retrieve. + + @retval TRUE The default value is set successfully. + @retval FALSE The default value can't be found and set. +**/ +BOOLEAN +EFIAPI +HiiSetToDefaults ( + IN CONST EFI_STRING Request OPTIONAL, + IN UINT16 DefaultId + ) +{ + return InternalHiiIfrValueAction (Request, DefaultId, ACTION_SET_DEFAUTL_VALUE); +} + +/** + Determines if two values in config strings match. + + Compares the substring between StartSearchString and StopSearchString in + FirstString to the substring between StartSearchString and StopSearchString + in SecondString. If the two substrings match, then TRUE is returned. If the + two substrings do not match, then FALSE is returned. + + If FirstString is NULL, then ASSERT(). + If SecondString is NULL, then ASSERT(). + If StartSearchString is NULL, then ASSERT(). + If StopSearchString is NULL, then ASSERT(). + + @param FirstString Pointer to the first Null-terminated Unicode string. + @param SecondString Pointer to the second Null-terminated Unicode string. + @param StartSearchString Pointer to the Null-terminated Unicode string that + marks the start of the value string to compare. + @param StopSearchString Pointer to the Null-terminated Unicode string that + marks the end of the value string to compare. + + @retval FALSE StartSearchString is not present in FirstString. + @retval FALSE StartSearchString is not present in SecondString. + @retval FALSE StopSearchString is not present in FirstString. + @retval FALSE StopSearchString is not present in SecondString. + @retval FALSE The length of the substring in FirstString is not the + same length as the substring in SecondString. + @retval FALSE The value string in FirstString does not matche the + value string in SecondString. + @retval TRUE The value string in FirstString matches the value + string in SecondString. + +**/ +BOOLEAN +EFIAPI +InternalHiiCompareSubString ( + IN CHAR16 *FirstString, + IN CHAR16 *SecondString, + IN CHAR16 *StartSearchString, + IN CHAR16 *StopSearchString + ) +{ + CHAR16 *EndFirstString; + CHAR16 *EndSecondString; + + ASSERT (FirstString != NULL); + ASSERT (SecondString != NULL); + ASSERT (StartSearchString != NULL); + ASSERT (StopSearchString != NULL); + + FirstString = StrStr (FirstString, StartSearchString); + if (FirstString == NULL) { + return FALSE; + } + + SecondString = StrStr (SecondString, StartSearchString); + if (SecondString == NULL) { + return FALSE; + } + + EndFirstString = StrStr (FirstString, StopSearchString); + if (EndFirstString == NULL) { + return FALSE; + } + + EndSecondString = StrStr (SecondString, StopSearchString); + if (EndSecondString == NULL) { + return FALSE; + } + + if ((EndFirstString - FirstString) != (EndSecondString - SecondString)) { + return FALSE; + } + + return (BOOLEAN)(StrnCmp (FirstString, SecondString, EndFirstString - FirstString) == 0); +} + +/** + Determines if the routing data specified by GUID and NAME match a <ConfigHdr>. + + If ConfigHdr is NULL, then ASSERT(). + + @param[in] ConfigHdr Either <ConfigRequest> or <ConfigResp>. + @param[in] Guid GUID of the storage. + @param[in] Name NAME of the storage. + + @retval TRUE Routing information matches <ConfigHdr>. + @retval FALSE Routing information does not match <ConfigHdr>. + +**/ +BOOLEAN +EFIAPI +HiiIsConfigHdrMatch ( + IN CONST EFI_STRING ConfigHdr, + IN CONST EFI_GUID *Guid OPTIONAL, + IN CONST CHAR16 *Name OPTIONAL + ) +{ + EFI_STRING CompareConfigHdr; + BOOLEAN Result; + + ASSERT (ConfigHdr != NULL); + + // + // Use Guid and Name to generate a <ConfigHdr> string + // + CompareConfigHdr = HiiConstructConfigHdr (Guid, Name, NULL); + if (CompareConfigHdr == NULL) { + return FALSE; + } + + Result = TRUE; + if (Guid != NULL) { + // + // Compare GUID value strings + // + Result = InternalHiiCompareSubString (ConfigHdr, CompareConfigHdr, L"GUID=", L"&NAME="); + } + + if (Result && (Name != NULL)) { + // + // Compare NAME value strings + // + Result = InternalHiiCompareSubString (ConfigHdr, CompareConfigHdr, L"&NAME=", L"&PATH="); + } + + // + // Free the <ConfigHdr> string + // + FreePool (CompareConfigHdr); + + return Result; +} + +/** + Retrieves uncommitted data from the Form Browser and converts it to a binary + buffer. + + @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional + parameter that may be NULL. + @param[in] VariableName Pointer to a Null-terminated Unicode string. This + is an optional parameter that may be NULL. + @param[in] BufferSize Length in bytes of buffer to hold retrieved data. + @param[out] Buffer Buffer of data to be updated. + + @retval FALSE The uncommitted data could not be retrieved. + @retval TRUE The uncommitted data was retrieved. + +**/ +BOOLEAN +EFIAPI +HiiGetBrowserData ( + IN CONST EFI_GUID *VariableGuid OPTIONAL, + IN CONST CHAR16 *VariableName OPTIONAL, + IN UINTN BufferSize, + OUT UINT8 *Buffer + ) +{ + EFI_STRING ResultsData; + UINTN Size; + EFI_STRING ConfigResp; + EFI_STATUS Status; + CHAR16 *Progress; + + // + // Retrieve the results data from the Browser Callback + // + ResultsData = InternalHiiBrowserCallback (VariableGuid, VariableName, NULL); + if (ResultsData == NULL) { + return FALSE; + } + + // + // Construct <ConfigResp> mConfigHdrTemplate L'&' ResultsData L'\0' + // + Size = (StrLen (mConfigHdrTemplate) + 1) * sizeof (CHAR16); + Size = Size + (StrLen (ResultsData) + 1) * sizeof (CHAR16); + ConfigResp = AllocateZeroPool (Size); + UnicodeSPrint (ConfigResp, Size, L"%s&%s", mConfigHdrTemplate, ResultsData); + + // + // Free the allocated buffer + // + FreePool (ResultsData); + if (ConfigResp == NULL) { + return FALSE; + } + + // + // Convert <ConfigResp> to a buffer + // + Status = gHiiConfigRouting->ConfigToBlock ( + gHiiConfigRouting, + ConfigResp, + Buffer, + &BufferSize, + &Progress + ); + // + // Free the allocated buffer + // + FreePool (ConfigResp); + + if (EFI_ERROR (Status)) { + return FALSE; + } + + return TRUE; +} + +/** + Updates uncommitted data in the Form Browser. + + If Buffer is NULL, then ASSERT(). + + @param[in] VariableGuid Pointer to an EFI_GUID structure. This is an optional + parameter that may be NULL. + @param[in] VariableName Pointer to a Null-terminated Unicode string. This + is an optional parameter that may be NULL. + @param[in] BufferSize Length, in bytes, of Buffer. + @param[in] Buffer Buffer of data to commit. + @param[in] 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>* + + @retval FALSE The uncommitted data could not be updated. + @retval TRUE The uncommitted data was updated. + +**/ +BOOLEAN +EFIAPI +HiiSetBrowserData ( + IN CONST EFI_GUID *VariableGuid OPTIONAL, + IN CONST CHAR16 *VariableName OPTIONAL, + IN UINTN BufferSize, + IN CONST UINT8 *Buffer, + IN CONST CHAR16 *RequestElement OPTIONAL + ) +{ + UINTN Size; + EFI_STRING ConfigRequest; + EFI_STRING ConfigResp; + EFI_STRING ResultsData; + + ASSERT (Buffer != NULL); + + // + // Construct <ConfigRequest> + // + if (RequestElement == NULL) { + // + // Allocate and fill a buffer large enough to hold the <ConfigHdr> template + // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator + // + Size = (StrLen (mConfigHdrTemplate) + 32 + 1) * sizeof (CHAR16); + ConfigRequest = AllocateZeroPool (Size); + UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", mConfigHdrTemplate, (UINT64)BufferSize); + } else { + // + // Allocate and fill a buffer large enough to hold the <ConfigHdr> template + // followed by <RequestElement> followed by a Null-terminator + // + Size = StrLen (mConfigHdrTemplate) * sizeof (CHAR16); + Size = Size + (StrLen (RequestElement) + 1) * sizeof (CHAR16); + ConfigRequest = AllocateZeroPool (Size); + UnicodeSPrint (ConfigRequest, Size, L"%s%s", mConfigHdrTemplate, RequestElement); + } + + if (ConfigRequest == NULL) { + return FALSE; + } + + // + // Convert <ConfigRequest> to <ConfigResp> + // + ConfigResp = InternalHiiBlockToConfig (ConfigRequest, Buffer, BufferSize); + FreePool (ConfigRequest); + if (ConfigResp == NULL) { + return FALSE; + } + + // + // Set data in the uncommitted browser state information + // + ResultsData = InternalHiiBrowserCallback (VariableGuid, VariableName, ConfigResp + StrLen (mConfigHdrTemplate) + 1); + FreePool (ConfigResp); + + return (BOOLEAN)(ResultsData != NULL); +} + +///////////////////////////////////////// +///////////////////////////////////////// +/// IFR Functions +///////////////////////////////////////// +///////////////////////////////////////// + +#define HII_LIB_OPCODE_ALLOCATION_SIZE 0x200 + +typedef struct { + UINT8 *Buffer; + UINTN BufferSize; + UINTN Position; +} HII_LIB_OPCODE_BUFFER; + +/// +/// Lookup table that converts EFI_IFR_TYPE_X enum values to a width in bytes +/// +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 mHiiDefaultTypeToWidth[] = { + 1, // EFI_IFR_TYPE_NUM_SIZE_8 + 2, // EFI_IFR_TYPE_NUM_SIZE_16 + 4, // EFI_IFR_TYPE_NUM_SIZE_32 + 8, // EFI_IFR_TYPE_NUM_SIZE_64 + 1, // EFI_IFR_TYPE_BOOLEAN + 3, // EFI_IFR_TYPE_TIME + 4, // EFI_IFR_TYPE_DATE + 2 // EFI_IFR_TYPE_STRING +}; + +/** + Allocates and returns a new OpCode Handle. OpCode Handles must be freed with + HiiFreeOpCodeHandle(). + + @retval NULL There are not enough resources to allocate a new OpCode Handle. + @retval Other A new OpCode handle. + +**/ +VOID * +EFIAPI +HiiAllocateOpCodeHandle ( + VOID + ) +{ + HII_LIB_OPCODE_BUFFER *OpCodeBuffer; + + OpCodeBuffer = (HII_LIB_OPCODE_BUFFER *)AllocatePool (sizeof (HII_LIB_OPCODE_BUFFER)); + if (OpCodeBuffer == NULL) { + return NULL; + } + + OpCodeBuffer->Buffer = (UINT8 *)AllocatePool (HII_LIB_OPCODE_ALLOCATION_SIZE); + if (OpCodeBuffer->Buffer == NULL) { + FreePool (OpCodeBuffer); + return NULL; + } + + OpCodeBuffer->BufferSize = HII_LIB_OPCODE_ALLOCATION_SIZE; + OpCodeBuffer->Position = 0; + return (VOID *)OpCodeBuffer; +} + +/** + Frees an OpCode Handle that was previously allocated with HiiAllocateOpCodeHandle(). + When an OpCode Handle is freed, all of the opcodes associated with the OpCode + Handle are also freed. + + If OpCodeHandle is NULL, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + +**/ +VOID +EFIAPI +HiiFreeOpCodeHandle ( + VOID *OpCodeHandle + ) +{ + HII_LIB_OPCODE_BUFFER *OpCodeBuffer; + + ASSERT (OpCodeHandle != NULL); + + OpCodeBuffer = (HII_LIB_OPCODE_BUFFER *)OpCodeHandle; + if (OpCodeBuffer->Buffer != NULL) { + FreePool (OpCodeBuffer->Buffer); + } + + FreePool (OpCodeBuffer); +} + +/** + Internal function gets the current position of opcode buffer. + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + + @return Current position of opcode buffer. +**/ +UINTN +EFIAPI +InternalHiiOpCodeHandlePosition ( + IN VOID *OpCodeHandle + ) +{ + return ((HII_LIB_OPCODE_BUFFER *)OpCodeHandle)->Position; +} + +/** + Internal function gets the start pointer of opcode buffer. + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + + @return Pointer to the opcode buffer base. +**/ +UINT8 * +EFIAPI +InternalHiiOpCodeHandleBuffer ( + IN VOID *OpCodeHandle + ) +{ + return ((HII_LIB_OPCODE_BUFFER *)OpCodeHandle)->Buffer; +} + +/** + Internal function reserves the enough buffer for current opcode. + When the buffer is not enough, Opcode buffer will be extended. + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] Size Size of current opcode. + + @return Pointer to the current opcode. +**/ +UINT8 * +EFIAPI +InternalHiiGrowOpCodeHandle ( + IN VOID *OpCodeHandle, + IN UINTN Size + ) +{ + HII_LIB_OPCODE_BUFFER *OpCodeBuffer; + UINT8 *Buffer; + + ASSERT (OpCodeHandle != NULL); + + OpCodeBuffer = (HII_LIB_OPCODE_BUFFER *)OpCodeHandle; + if (OpCodeBuffer->Position + Size > OpCodeBuffer->BufferSize) { + Buffer = ReallocatePool ( + OpCodeBuffer->BufferSize, + OpCodeBuffer->BufferSize + (Size + HII_LIB_OPCODE_ALLOCATION_SIZE), + OpCodeBuffer->Buffer + ); + ASSERT (Buffer != NULL); + OpCodeBuffer->Buffer = Buffer; + OpCodeBuffer->BufferSize += (Size + HII_LIB_OPCODE_ALLOCATION_SIZE); + } + + Buffer = OpCodeBuffer->Buffer + OpCodeBuffer->Position; + OpCodeBuffer->Position += Size; + return Buffer; +} + +/** + Internal function creates opcode based on the template opcode. + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] OpCodeTemplate Pointer to the template buffer of opcode. + @param[in] OpCode OpCode IFR value. + @param[in] OpCodeSize Size of opcode. + @param[in] ExtensionSize Size of extended opcode. + @param[in] Scope Scope bit of opcode. + + @return Pointer to the current opcode with opcode data. +**/ +UINT8 * +EFIAPI +InternalHiiCreateOpCodeExtended ( + IN VOID *OpCodeHandle, + IN VOID *OpCodeTemplate, + IN UINT8 OpCode, + IN UINTN OpCodeSize, + IN UINTN ExtensionSize, + IN UINT8 Scope + ) +{ + EFI_IFR_OP_HEADER *Header; + UINT8 *Buffer; + + ASSERT (OpCodeTemplate != NULL); + ASSERT ((OpCodeSize + ExtensionSize) <= 0x7F); + + Header = (EFI_IFR_OP_HEADER *)OpCodeTemplate; + Header->OpCode = OpCode; + Header->Scope = Scope; + Header->Length = (UINT8)(OpCodeSize + ExtensionSize); + Buffer = InternalHiiGrowOpCodeHandle (OpCodeHandle, Header->Length); + return (UINT8 *)CopyMem (Buffer, Header, OpCodeSize); +} + +/** + Internal function creates opcode based on the template opcode for the normal opcode. + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] OpCodeTemplate Pointer to the template buffer of opcode. + @param[in] OpCode OpCode IFR value. + @param[in] OpCodeSize Size of opcode. + + @return Pointer to the current opcode with opcode data. +**/ +UINT8 * +EFIAPI +InternalHiiCreateOpCode ( + IN VOID *OpCodeHandle, + IN VOID *OpCodeTemplate, + IN UINT8 OpCode, + IN UINTN OpCodeSize + ) +{ + return InternalHiiCreateOpCodeExtended (OpCodeHandle, OpCodeTemplate, OpCode, OpCodeSize, 0, 0); +} + +/** + Append raw opcodes to an OpCodeHandle. + + If OpCodeHandle is NULL, then ASSERT(). + If RawBuffer is NULL, then ASSERT(); + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] RawBuffer Buffer of opcodes to append. + @param[in] RawBufferSize The size, in bytes, of Buffer. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the appended opcodes. + +**/ +UINT8 * +EFIAPI +HiiCreateRawOpCodes ( + IN VOID *OpCodeHandle, + IN UINT8 *RawBuffer, + IN UINTN RawBufferSize + ) +{ + UINT8 *Buffer; + + ASSERT (RawBuffer != NULL); + + Buffer = InternalHiiGrowOpCodeHandle (OpCodeHandle, RawBufferSize); + return (UINT8 *)CopyMem (Buffer, RawBuffer, RawBufferSize); +} + +/** + Append opcodes from one OpCode Handle to another OpCode handle. + + If OpCodeHandle is NULL, then ASSERT(). + If RawOpCodeHandle is NULL, then ASSERT(); + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] RawOpCodeHandle Handle to the buffer of opcodes. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the appended opcodes. + +**/ +UINT8 * +EFIAPI +InternalHiiAppendOpCodes ( + IN VOID *OpCodeHandle, + IN VOID *RawOpCodeHandle + ) +{ + HII_LIB_OPCODE_BUFFER *RawOpCodeBuffer; + + ASSERT (RawOpCodeHandle != NULL); + + RawOpCodeBuffer = (HII_LIB_OPCODE_BUFFER *)RawOpCodeHandle; + return HiiCreateRawOpCodes (OpCodeHandle, RawOpCodeBuffer->Buffer, RawOpCodeBuffer->Position); +} + +/** + Create EFI_IFR_END_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateEndOpCode ( + IN VOID *OpCodeHandle + ) +{ + EFI_IFR_END OpCode; + + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_END_OP, sizeof (OpCode)); +} + +/** + Create EFI_IFR_ONE_OF_OPTION_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If Type is invalid, then ASSERT(). + If Flags is invalid, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] StringId StringId for the option + @param[in] Flags Flags for the option + @param[in] Type Type for the option + @param[in] Value Value for the option + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateOneOfOptionOpCode ( + IN VOID *OpCodeHandle, + IN UINT16 StringId, + IN UINT8 Flags, + IN UINT8 Type, + IN UINT64 Value + ) +{ + EFI_IFR_ONE_OF_OPTION OpCode; + + ASSERT (Type < EFI_IFR_TYPE_OTHER); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Option = StringId; + OpCode.Flags = (UINT8)(Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG)); + OpCode.Type = Type; + CopyMem (&OpCode.Value, &Value, mHiiDefaultTypeToWidth[Type]); + + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_ONE_OF_OPTION_OP, OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value) + mHiiDefaultTypeToWidth[Type]); +} + +/** + Create EFI_IFR_DEFAULT_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If Type is invalid, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] DefaultId DefaultId for the default + @param[in] Type Type for the default + @param[in] Value Value for the default + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateDefaultOpCode ( + IN VOID *OpCodeHandle, + IN UINT16 DefaultId, + IN UINT8 Type, + IN UINT64 Value + ) +{ + EFI_IFR_DEFAULT OpCode; + + ASSERT (Type < EFI_IFR_TYPE_OTHER); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Type = Type; + OpCode.DefaultId = DefaultId; + CopyMem (&OpCode.Value, &Value, mHiiDefaultTypeToWidth[Type]); + + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_DEFAULT_OP, OFFSET_OF (EFI_IFR_DEFAULT, Value) + mHiiDefaultTypeToWidth[Type]); +} + +/** + Create EFI_IFR_GUID opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If Guid is NULL, then ASSERT(). + If OpCodeSize < sizeof (EFI_IFR_GUID), then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] Guid Pointer to EFI_GUID of this guided opcode. + @param[in] GuidOpCode Pointer to an EFI_IFR_GUID opcode. This is an + optional parameter that may be NULL. If this + parameter is NULL, then the GUID extension + region of the created opcode is filled with zeros. + If this parameter is not NULL, then the GUID + extension region of GuidData will be copied to + the GUID extension region of the created opcode. + @param[in] OpCodeSize The size, in bytes, of created opcode. This value + must be >= sizeof(EFI_IFR_GUID). + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateGuidOpCode ( + IN VOID *OpCodeHandle, + IN CONST EFI_GUID *Guid, + IN CONST VOID *GuidOpCode OPTIONAL, + IN UINTN OpCodeSize + ) +{ + EFI_IFR_GUID OpCode; + EFI_IFR_GUID *OpCodePointer; + + ASSERT (Guid != NULL); + ASSERT (OpCodeSize >= sizeof (OpCode)); + + ZeroMem (&OpCode, sizeof (OpCode)); + CopyGuid ((EFI_GUID *)(VOID *)&OpCode.Guid, Guid); + + OpCodePointer = (EFI_IFR_GUID *)InternalHiiCreateOpCodeExtended ( + OpCodeHandle, + &OpCode, + EFI_IFR_GUID_OP, + sizeof (OpCode), + OpCodeSize - sizeof (OpCode), + 0 + ); + if ((OpCodePointer != NULL) && (GuidOpCode != NULL)) { + CopyMem (OpCodePointer + 1, (EFI_IFR_GUID *)GuidOpCode + 1, OpCodeSize - sizeof (OpCode)); + } + + return (UINT8 *)OpCodePointer; +} + +/** + Create EFI_IFR_ACTION_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] QuestionConfig String ID for configuration + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateActionOpCode ( + IN VOID *OpCodeHandle, + IN EFI_QUESTION_ID QuestionId, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN EFI_STRING_ID QuestionConfig + ) +{ + EFI_IFR_ACTION OpCode; + + ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Question.QuestionId = QuestionId; + OpCode.Question.Header.Prompt = Prompt; + OpCode.Question.Header.Help = Help; + OpCode.Question.Flags = QuestionFlags; + OpCode.QuestionConfig = QuestionConfig; + + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_ACTION_OP, sizeof (OpCode)); +} + +/** + Create EFI_IFR_SUBTITLE_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in Flags, then ASSERT(). + If Scope > 1, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] Flags Subtitle opcode flags + @param[in] Scope 1 if this opcpde is the beginning of a new scope. + 0 if this opcode is within the current scope. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateSubTitleOpCode ( + IN VOID *OpCodeHandle, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 Flags, + IN UINT8 Scope + ) +{ + EFI_IFR_SUBTITLE OpCode; + + ASSERT (Scope <= 1); + ASSERT ((Flags & (~(EFI_IFR_FLAGS_HORIZONTAL))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Statement.Prompt = Prompt; + OpCode.Statement.Help = Help; + OpCode.Flags = Flags; + + return InternalHiiCreateOpCodeExtended ( + OpCodeHandle, + &OpCode, + EFI_IFR_SUBTITLE_OP, + sizeof (OpCode), + 0, + Scope + ); +} + +/** + Create EFI_IFR_REF_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] FormId Destination Form ID + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] QuestionId Question ID + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateGotoOpCode ( + IN VOID *OpCodeHandle, + IN EFI_FORM_ID FormId, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN EFI_QUESTION_ID QuestionId + ) +{ + EFI_IFR_REF OpCode; + + ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Question.Header.Prompt = Prompt; + OpCode.Question.Header.Help = Help; + OpCode.Question.QuestionId = QuestionId; + OpCode.Question.Flags = QuestionFlags; + OpCode.FormId = FormId; + + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_REF_OP, sizeof (OpCode)); +} + +/** + Create EFI_IFR_REF_OP, EFI_IFR_REF2_OP, EFI_IFR_REF3_OP and EFI_IFR_REF4_OP opcode. + + When RefDevicePath is not zero, EFI_IFR_REF4 opcode will be created. + When RefDevicePath is zero and RefFormSetId is not NULL, EFI_IFR_REF3 opcode will be created. + When RefDevicePath is zero, RefFormSetId is NULL and RefQuestionId is not zero, EFI_IFR_REF2 opcode will be created. + When RefDevicePath is zero, RefFormSetId is NULL and RefQuestionId is zero, EFI_IFR_REF opcode will be created. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + + @param[in] OpCodeHandle The handle to the buffer of opcodes. + @param[in] RefFormId The Destination Form ID. + @param[in] Prompt The string ID for Prompt. + @param[in] Help The string ID for Help. + @param[in] QuestionFlags The flags in Question Header + @param[in] QuestionId Question ID. + @param[in] RefQuestionId The question on the form to which this link is referring. + If its value is zero, then the link refers to the top of the form. + @param[in] RefFormSetId The form set to which this link is referring. If its value is NULL, and RefDevicePath is + zero, then the link is to the current form set. + @param[in] RefDevicePath The string identifier that specifies the string containing the text representation of + the device path to which the form set containing the form specified by FormId. + If its value is zero, then the link refers to the current page. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateGotoExOpCode ( + IN VOID *OpCodeHandle, + IN EFI_FORM_ID RefFormId, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN EFI_QUESTION_ID QuestionId, + IN EFI_QUESTION_ID RefQuestionId, + IN EFI_GUID *RefFormSetId OPTIONAL, + IN EFI_STRING_ID RefDevicePath + ) +{ + EFI_IFR_REF4 OpCode; + UINTN OpCodeSize; + + ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Question.Header.Prompt = Prompt; + OpCode.Question.Header.Help = Help; + OpCode.Question.QuestionId = QuestionId; + OpCode.Question.Flags = QuestionFlags; + OpCode.FormId = RefFormId; + OpCode.QuestionId = RefQuestionId; + OpCode.DevicePath = RefDevicePath; + if (RefFormSetId != NULL) { + CopyMem (&OpCode.FormSetId, RefFormSetId, sizeof (OpCode.FormSetId)); + } + + // + // Cacluate OpCodeSize based on the input Ref value. + // Try to use the small OpCode to save size. + // + OpCodeSize = sizeof (EFI_IFR_REF); + if (RefDevicePath != 0) { + OpCodeSize = sizeof (EFI_IFR_REF4); + } else if (RefFormSetId != NULL) { + OpCodeSize = sizeof (EFI_IFR_REF3); + } else if (RefQuestionId != 0) { + OpCodeSize = sizeof (EFI_IFR_REF2); + } + + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_REF_OP, OpCodeSize); +} + +/** + Create EFI_IFR_CHECKBOX_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + If any reserved bits are set in CheckBoxFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] VarStoreId Storage ID + @param[in] VarOffset Offset in Storage or String ID of the name (VarName) + for this name/value pair. + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] CheckBoxFlags Flags for checkbox opcode + @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This + is an optional parameter that may be NULL. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateCheckBoxOpCode ( + IN VOID *OpCodeHandle, + 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 VOID *DefaultsOpCodeHandle OPTIONAL + ) +{ + EFI_IFR_CHECKBOX OpCode; + UINTN Position; + + ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_REST_STYLE))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Question.QuestionId = QuestionId; + OpCode.Question.VarStoreId = VarStoreId; + OpCode.Question.VarStoreInfo.VarOffset = VarOffset; + OpCode.Question.Header.Prompt = Prompt; + OpCode.Question.Header.Help = Help; + OpCode.Question.Flags = QuestionFlags; + OpCode.Flags = CheckBoxFlags; + + if (DefaultsOpCodeHandle == NULL) { + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_CHECKBOX_OP, sizeof (OpCode)); + } + + Position = InternalHiiOpCodeHandlePosition (OpCodeHandle); + InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_CHECKBOX_OP, sizeof (OpCode), 0, 1); + InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle); + HiiCreateEndOpCode (OpCodeHandle); + return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position; +} + +/** + Create EFI_IFR_NUMERIC_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + If any reserved bits are set in NumericFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] VarStoreId Storage ID + @param[in] VarOffset Offset in Storage or String ID of the name (VarName) + for this name/value pair. + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] NumericFlags Flags for numeric opcode + @param[in] Minimum Numeric minimum value + @param[in] Maximum Numeric maximum value + @param[in] Step Numeric step for edit + @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This + is an optional parameter that may be NULL. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateNumericOpCode ( + IN VOID *OpCodeHandle, + 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 VOID *DefaultsOpCodeHandle OPTIONAL + ) +{ + EFI_IFR_NUMERIC OpCode; + UINTN Position; + UINTN Length; + + ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_REST_STYLE))) == 0); + + Length = 0; + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Question.QuestionId = QuestionId; + OpCode.Question.VarStoreId = VarStoreId; + OpCode.Question.VarStoreInfo.VarOffset = VarOffset; + OpCode.Question.Header.Prompt = Prompt; + OpCode.Question.Header.Help = Help; + OpCode.Question.Flags = QuestionFlags; + OpCode.Flags = NumericFlags; + + switch (NumericFlags & EFI_IFR_NUMERIC_SIZE) { + case EFI_IFR_NUMERIC_SIZE_1: + OpCode.data.u8.MinValue = (UINT8)Minimum; + OpCode.data.u8.MaxValue = (UINT8)Maximum; + OpCode.data.u8.Step = (UINT8)Step; + Length = 3; + break; + + case EFI_IFR_NUMERIC_SIZE_2: + OpCode.data.u16.MinValue = (UINT16)Minimum; + OpCode.data.u16.MaxValue = (UINT16)Maximum; + OpCode.data.u16.Step = (UINT16)Step; + Length = 6; + break; + + case EFI_IFR_NUMERIC_SIZE_4: + OpCode.data.u32.MinValue = (UINT32)Minimum; + OpCode.data.u32.MaxValue = (UINT32)Maximum; + OpCode.data.u32.Step = (UINT32)Step; + Length = 12; + break; + + case EFI_IFR_NUMERIC_SIZE_8: + OpCode.data.u64.MinValue = Minimum; + OpCode.data.u64.MaxValue = Maximum; + OpCode.data.u64.Step = Step; + Length = 24; + break; + } + + Length += OFFSET_OF (EFI_IFR_NUMERIC, data); + + if (DefaultsOpCodeHandle == NULL) { + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_NUMERIC_OP, Length); + } + + Position = InternalHiiOpCodeHandlePosition (OpCodeHandle); + InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_NUMERIC_OP, Length, 0, 1); + InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle); + HiiCreateEndOpCode (OpCodeHandle); + return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position; +} + +/** + Create EFI_IFR_STRING_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + If any reserved bits are set in StringFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] VarStoreId Storage ID + @param[in] VarOffset Offset in Storage or String ID of the name (VarName) + for this name/value pair. + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] StringFlags Flags for string opcode + @param[in] MinSize String minimum length + @param[in] MaxSize String maximum length + @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This + is an optional parameter that may be NULL. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateStringOpCode ( + IN VOID *OpCodeHandle, + 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 VOID *DefaultsOpCodeHandle OPTIONAL + ) +{ + EFI_IFR_STRING OpCode; + UINTN Position; + + ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_REST_STYLE))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Question.Header.Prompt = Prompt; + OpCode.Question.Header.Help = Help; + OpCode.Question.QuestionId = QuestionId; + OpCode.Question.VarStoreId = VarStoreId; + OpCode.Question.VarStoreInfo.VarOffset = VarOffset; + OpCode.Question.Flags = QuestionFlags; + OpCode.MinSize = MinSize; + OpCode.MaxSize = MaxSize; + OpCode.Flags = (UINT8)(StringFlags & EFI_IFR_STRING_MULTI_LINE); + + if (DefaultsOpCodeHandle == NULL) { + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_STRING_OP, sizeof (OpCode)); + } + + Position = InternalHiiOpCodeHandlePosition (OpCodeHandle); + InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_STRING_OP, sizeof (OpCode), 0, 1); + InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle); + HiiCreateEndOpCode (OpCodeHandle); + return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position; +} + +/** + Create EFI_IFR_ONE_OF_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + If any reserved bits are set in OneOfFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] VarStoreId Storage ID + @param[in] VarOffset Offset in Storage or String ID of the name (VarName) + for this name/value pair. + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] OneOfFlags Flags for oneof opcode + @param[in] OptionsOpCodeHandle Handle for a buffer of ONE_OF_OPTION opcodes. + @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This + is an optional parameter that may be NULL. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateOneOfOpCode ( + IN VOID *OpCodeHandle, + 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 VOID *OptionsOpCodeHandle, + IN VOID *DefaultsOpCodeHandle OPTIONAL + ) +{ + EFI_IFR_ONE_OF OpCode; + UINTN Position; + UINTN Length; + + ASSERT (OptionsOpCodeHandle != NULL); + ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_REST_STYLE | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Question.Header.Prompt = Prompt; + OpCode.Question.Header.Help = Help; + OpCode.Question.QuestionId = QuestionId; + OpCode.Question.VarStoreId = VarStoreId; + OpCode.Question.VarStoreInfo.VarOffset = VarOffset; + OpCode.Question.Flags = QuestionFlags; + OpCode.Flags = OneOfFlags; + + Length = OFFSET_OF (EFI_IFR_ONE_OF, data); + Length += (1 << (OneOfFlags & EFI_IFR_NUMERIC_SIZE)) * 3; + + Position = InternalHiiOpCodeHandlePosition (OpCodeHandle); + InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_ONE_OF_OP, Length, 0, 1); + InternalHiiAppendOpCodes (OpCodeHandle, OptionsOpCodeHandle); + if (DefaultsOpCodeHandle != NULL) { + InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle); + } + + HiiCreateEndOpCode (OpCodeHandle); + return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position; +} + +/** + Create EFI_IFR_ORDERED_LIST_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + If any reserved bits are set in OrderedListFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] VarStoreId Storage ID + @param[in] VarOffset Offset in Storage or String ID of the name (VarName) + for this name/value pair. + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] OrderedListFlags Flags for ordered list opcode + @param[in] DataType Type for option value + @param[in] MaxContainers Maximum count for options in this ordered list + @param[in] OptionsOpCodeHandle Handle for a buffer of ONE_OF_OPTION opcodes. + @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This + is an optional parameter that may be NULL. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateOrderedListOpCode ( + IN VOID *OpCodeHandle, + 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 VOID *OptionsOpCodeHandle, + IN VOID *DefaultsOpCodeHandle OPTIONAL + ) +{ + EFI_IFR_ORDERED_LIST OpCode; + UINTN Position; + + ASSERT (OptionsOpCodeHandle != NULL); + ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_REST_STYLE | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Question.Header.Prompt = Prompt; + OpCode.Question.Header.Help = Help; + OpCode.Question.QuestionId = QuestionId; + OpCode.Question.VarStoreId = VarStoreId; + OpCode.Question.VarStoreInfo.VarOffset = VarOffset; + OpCode.Question.Flags = QuestionFlags; + OpCode.MaxContainers = MaxContainers; + OpCode.Flags = OrderedListFlags; + + Position = InternalHiiOpCodeHandlePosition (OpCodeHandle); + InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_ORDERED_LIST_OP, sizeof (OpCode), 0, 1); + InternalHiiAppendOpCodes (OpCodeHandle, OptionsOpCodeHandle); + if (DefaultsOpCodeHandle != NULL) { + InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle); + } + + HiiCreateEndOpCode (OpCodeHandle); + return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position; +} + +/** + Create EFI_IFR_TEXT_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] Prompt String ID for Prompt. + @param[in] Help String ID for Help. + @param[in] TextTwo String ID for TextTwo. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateTextOpCode ( + IN VOID *OpCodeHandle, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN EFI_STRING_ID TextTwo + ) +{ + EFI_IFR_TEXT OpCode; + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Statement.Prompt = Prompt; + OpCode.Statement.Help = Help; + OpCode.TextTwo = TextTwo; + + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_TEXT_OP, sizeof (OpCode)); +} + +/** + Create EFI_IFR_DATE_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + If any reserved bits are set in DateFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] VarStoreId Storage ID, optional. If DateFlags is not + QF_DATE_STORAGE_NORMAL, this parameter is ignored. + @param[in] VarOffset Offset in Storage or String ID of the name (VarName) + for this name/value pair, optional. If DateFlags is not + QF_DATE_STORAGE_NORMAL, this parameter is ignored. + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] DateFlags Flags for date opcode + @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This + is an optional parameter that may be NULL. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateDateOpCode ( + IN VOID *OpCodeHandle, + IN EFI_QUESTION_ID QuestionId, + IN EFI_VARSTORE_ID VarStoreId OPTIONAL, + IN UINT16 VarOffset OPTIONAL, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN UINT8 DateFlags, + IN VOID *DefaultsOpCodeHandle OPTIONAL + ) +{ + EFI_IFR_DATE OpCode; + UINTN Position; + + ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_REST_STYLE))) == 0); + ASSERT ((DateFlags & (~(EFI_QF_DATE_YEAR_SUPPRESS | EFI_QF_DATE_MONTH_SUPPRESS | EFI_QF_DATE_DAY_SUPPRESS | EFI_QF_DATE_STORAGE))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Question.Header.Prompt = Prompt; + OpCode.Question.Header.Help = Help; + OpCode.Question.QuestionId = QuestionId; + OpCode.Question.VarStoreId = VarStoreId; + OpCode.Question.VarStoreInfo.VarOffset = VarOffset; + OpCode.Question.Flags = QuestionFlags; + OpCode.Flags = DateFlags; + + if (DefaultsOpCodeHandle == NULL) { + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_DATE_OP, sizeof (OpCode)); + } + + Position = InternalHiiOpCodeHandlePosition (OpCodeHandle); + InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_DATE_OP, sizeof (OpCode), 0, 1); + InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle); + HiiCreateEndOpCode (OpCodeHandle); + return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position; +} + +/** + Create EFI_IFR_TIME_OP opcode. + + If OpCodeHandle is NULL, then ASSERT(). + If any reserved bits are set in QuestionFlags, then ASSERT(). + If any reserved bits are set in TimeFlags, then ASSERT(). + + @param[in] OpCodeHandle Handle to the buffer of opcodes. + @param[in] QuestionId Question ID + @param[in] VarStoreId Storage ID, optional. If TimeFlags is not + QF_TIME_STORAGE_NORMAL, this parameter is ignored. + @param[in] VarOffset Offset in Storage or String ID of the name (VarName) + for this name/value pair, optional. If TimeFlags is not + QF_TIME_STORAGE_NORMAL, this parameter is ignored. + @param[in] Prompt String ID for Prompt + @param[in] Help String ID for Help + @param[in] QuestionFlags Flags in Question Header + @param[in] TimeFlags Flags for time opcode + @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This + is an optional parameter that may be NULL. + + @retval NULL There is not enough space left in Buffer to add the opcode. + @retval Other A pointer to the created opcode. + +**/ +UINT8 * +EFIAPI +HiiCreateTimeOpCode ( + IN VOID *OpCodeHandle, + IN EFI_QUESTION_ID QuestionId, + IN EFI_VARSTORE_ID VarStoreId OPTIONAL, + IN UINT16 VarOffset OPTIONAL, + IN EFI_STRING_ID Prompt, + IN EFI_STRING_ID Help, + IN UINT8 QuestionFlags, + IN UINT8 TimeFlags, + IN VOID *DefaultsOpCodeHandle OPTIONAL + ) +{ + EFI_IFR_TIME OpCode; + UINTN Position; + + ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_REST_STYLE))) == 0); + ASSERT ((TimeFlags & (~(QF_TIME_HOUR_SUPPRESS | QF_TIME_MINUTE_SUPPRESS | QF_TIME_SECOND_SUPPRESS | QF_TIME_STORAGE))) == 0); + + ZeroMem (&OpCode, sizeof (OpCode)); + OpCode.Question.Header.Prompt = Prompt; + OpCode.Question.Header.Help = Help; + OpCode.Question.QuestionId = QuestionId; + OpCode.Question.VarStoreId = VarStoreId; + OpCode.Question.VarStoreInfo.VarOffset = VarOffset; + OpCode.Question.Flags = QuestionFlags; + OpCode.Flags = TimeFlags; + + if (DefaultsOpCodeHandle == NULL) { + return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_TIME_OP, sizeof (OpCode)); + } + + Position = InternalHiiOpCodeHandlePosition (OpCodeHandle); + InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_TIME_OP, sizeof (OpCode), 0, 1); + InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle); + HiiCreateEndOpCode (OpCodeHandle); + return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position; +} + +/** + This is the internal worker function to update the data in + a form specified by FormSetGuid, FormId and Label. + + @param[in] FormSetGuid The optional Formset GUID. + @param[in] FormId The Form ID. + @param[in] Package The package header. + @param[in] OpCodeBufferStart An OpCode buffer that contains the set of IFR + opcodes to be inserted or replaced in the form. + @param[in] OpCodeBufferEnd An OpCcode buffer that contains the IFR opcode + that marks the end of a replace operation in the form. + @param[out] TempPackage The resultant package. + + @retval EFI_SUCCESS The function completes successfully. + @retval EFI_NOT_FOUND The updated opcode or endopcode is not found. + +**/ +EFI_STATUS +EFIAPI +InternalHiiUpdateFormPackageData ( + IN EFI_GUID *FormSetGuid OPTIONAL, + IN EFI_FORM_ID FormId, + IN EFI_HII_PACKAGE_HEADER *Package, + IN HII_LIB_OPCODE_BUFFER *OpCodeBufferStart, + IN HII_LIB_OPCODE_BUFFER *OpCodeBufferEnd OPTIONAL, + OUT EFI_HII_PACKAGE_HEADER *TempPackage + ) +{ + UINTN AddSize; + UINT8 *BufferPos; + EFI_HII_PACKAGE_HEADER PackageHeader; + UINTN Offset; + EFI_IFR_OP_HEADER *IfrOpHdr; + EFI_IFR_OP_HEADER *UpdateIfrOpHdr; + BOOLEAN GetFormSet; + BOOLEAN GetForm; + BOOLEAN Updated; + UINTN UpdatePackageLength; + + CopyMem (TempPackage, Package, sizeof (EFI_HII_PACKAGE_HEADER)); + UpdatePackageLength = sizeof (EFI_HII_PACKAGE_HEADER); + BufferPos = (UINT8 *)(TempPackage + 1); + + CopyMem (&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 = (BOOLEAN)((FormSetGuid == NULL) ? TRUE : FALSE); + GetForm = FALSE; + Updated = FALSE; + + while (Offset < PackageHeader.Length) { + CopyMem (BufferPos, IfrOpHdr, IfrOpHdr->Length); + BufferPos += IfrOpHdr->Length; + UpdatePackageLength += IfrOpHdr->Length; + + // + // Find the matched FormSet and Form + // + if ((IfrOpHdr->OpCode == EFI_IFR_FORM_SET_OP) && (FormSetGuid != NULL)) { + if (CompareGuid ((GUID *)(VOID *)&((EFI_IFR_FORM_SET *)IfrOpHdr)->Guid, FormSetGuid)) { + GetFormSet = TRUE; + } else { + GetFormSet = FALSE; + } + } else if ((IfrOpHdr->OpCode == EFI_IFR_FORM_OP) || (IfrOpHdr->OpCode == EFI_IFR_FORM_MAP_OP)) { + if (CompareMem (&((EFI_IFR_FORM *)IfrOpHdr)->FormId, &FormId, sizeof (EFI_FORM_ID)) == 0) { + GetForm = TRUE; + } else { + GetForm = FALSE; + } + } + + // + // The matched Form is found, and Update data in this form + // + if (GetFormSet && GetForm) { + UpdateIfrOpHdr = (EFI_IFR_OP_HEADER *)OpCodeBufferStart->Buffer; + if ((UpdateIfrOpHdr->Length == IfrOpHdr->Length) && \ + (CompareMem (IfrOpHdr, UpdateIfrOpHdr, UpdateIfrOpHdr->Length) == 0)) + { + // + // Remove the original data when End OpCode buffer exist. + // + if (OpCodeBufferEnd != NULL) { + Offset += IfrOpHdr->Length; + IfrOpHdr = (EFI_IFR_OP_HEADER *)((UINT8 *)(IfrOpHdr) + IfrOpHdr->Length); + UpdateIfrOpHdr = (EFI_IFR_OP_HEADER *)OpCodeBufferEnd->Buffer; + while (Offset < PackageHeader.Length) { + // + // Search the matched end opcode + // + if ((UpdateIfrOpHdr->Length == IfrOpHdr->Length) && \ + (CompareMem (IfrOpHdr, UpdateIfrOpHdr, UpdateIfrOpHdr->Length) == 0)) + { + break; + } + + // + // Go to the next Op-Code + // + Offset += IfrOpHdr->Length; + IfrOpHdr = (EFI_IFR_OP_HEADER *)((UINT8 *)(IfrOpHdr) + IfrOpHdr->Length); + } + + if (Offset >= PackageHeader.Length) { + // + // The end opcode is not found. + // + return EFI_NOT_FOUND; + } + } + + // + // Insert the updated data + // + AddSize = ((EFI_IFR_OP_HEADER *)OpCodeBufferStart->Buffer)->Length; + CopyMem (BufferPos, OpCodeBufferStart->Buffer + AddSize, OpCodeBufferStart->Position - AddSize); + BufferPos += OpCodeBufferStart->Position - AddSize; + UpdatePackageLength += OpCodeBufferStart->Position - AddSize; + + if (OpCodeBufferEnd != NULL) { + // + // Add the end opcode + // + CopyMem (BufferPos, IfrOpHdr, IfrOpHdr->Length); + BufferPos += IfrOpHdr->Length; + UpdatePackageLength += IfrOpHdr->Length; + } + + // + // Copy the left package data. + // + Offset += IfrOpHdr->Length; + CopyMem (BufferPos, (UINT8 *)Package + Offset, PackageHeader.Length - Offset); + UpdatePackageLength += PackageHeader.Length - Offset; + + // + // Set update flag + // + Updated = TRUE; + break; + } + } + + // + // Go to the next Op-Code + // + Offset += IfrOpHdr->Length; + IfrOpHdr = (EFI_IFR_OP_HEADER *)((CHAR8 *)(IfrOpHdr) + IfrOpHdr->Length); + } + + if (!Updated) { + // + // The updated opcode buffer is not found. + // + return EFI_NOT_FOUND; + } + + // + // Update the package length. + // + PackageHeader.Length = (UINT32)UpdatePackageLength; + CopyMem (TempPackage, &PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER)); + + return EFI_SUCCESS; +} + +/** + This function updates a form that has previously been registered with the HII + Database. This function will perform at most one update operation. + + The form to update is specified by Handle, FormSetGuid, and FormId. Binary + comparisons of IFR opcodes are performed from the beginning of the form being + updated until an IFR opcode is found that exactly matches the first IFR opcode + specified by StartOpCodeHandle. The following rules are used to determine if + an insert, replace, or delete operation is performed. + + 1) If no matches are found, then NULL is returned. + 2) If a match is found, and EndOpCodeHandle is NULL, then all of the IFR opcodes + from StartOpCodeHandle except the first opcode are inserted immediately after + the matching IFR opcode in the form to be updated. + 3) If a match is found, and EndOpCodeHandle is not NULL, then a search is made + from the matching IFR opcode until an IFR opcode exactly matches the first + IFR opcode specified by EndOpCodeHandle. If no match is found for the first + IFR opcode specified by EndOpCodeHandle, then NULL is returned. If a match + is found, then all of the IFR opcodes between the start match and the end + match are deleted from the form being updated and all of the IFR opcodes + from StartOpCodeHandle except the first opcode are inserted immediately after + the matching start IFR opcode. If StartOpCcodeHandle only contains one + IFR instruction, then the result of this operation will delete all of the IFR + opcodes between the start end matches. + + If HiiHandle is NULL, then ASSERT(). + If StartOpCodeHandle is NULL, then ASSERT(). + + @param[in] HiiHandle The HII Handle of the form to update. + @param[in] FormSetGuid The Formset GUID of the form to update. This + is an optional parameter that may be NULL. + If it is NULL, all FormSet will be updated. + @param[in] FormId The ID of the form to update. + @param[in] StartOpCodeHandle An OpCode Handle that contains the set of IFR + opcodes to be inserted or replaced in the form. + The first IFR instruction in StartOpCodeHandle + is used to find matching IFR opcode in the + form. + @param[in] EndOpCodeHandle An OpCcode Handle that contains the IFR opcode + that marks the end of a replace operation in + the form. This is an optional parameter that + may be NULL. If it is NULL, then an the IFR + opcodes specified by StartOpCodeHandle are + inserted into the form. + + @retval EFI_OUT_OF_RESOURCES No enough memory resource is allocated. + @retval EFI_NOT_FOUND The following cases will return EFI_NOT_FOUND. + 1) The form specified by HiiHandle, FormSetGuid, + and FormId could not be found in the HII Database. + 2) No IFR opcodes in the target form match the first + IFR opcode in StartOpCodeHandle. + 3) EndOpCOde is not NULL, and no IFR opcodes in the + target form following a matching start opcode match + the first IFR opcode in EndOpCodeHandle. + @retval EFI_SUCCESS The matched form is updated by StartOpcode. + +**/ +EFI_STATUS +EFIAPI +HiiUpdateForm ( + IN EFI_HII_HANDLE HiiHandle, + IN EFI_GUID *FormSetGuid OPTIONAL, + IN EFI_FORM_ID FormId, + IN VOID *StartOpCodeHandle, + IN VOID *EndOpCodeHandle OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList; + UINT32 PackageListLength; + UINT32 Offset; + EFI_HII_PACKAGE_LIST_HEADER *UpdatePackageList; + UINTN BufferSize; + UINT8 *UpdateBufferPos; + EFI_HII_PACKAGE_HEADER *Package; + EFI_HII_PACKAGE_HEADER *TempPackage; + EFI_HII_PACKAGE_HEADER PackageHeader; + BOOLEAN Updated; + HII_LIB_OPCODE_BUFFER *OpCodeBufferStart; + HII_LIB_OPCODE_BUFFER *OpCodeBufferEnd; + + // + // Input update data can't be NULL. + // + ASSERT (HiiHandle != NULL); + ASSERT (StartOpCodeHandle != NULL); + UpdatePackageList = NULL; + TempPackage = NULL; + HiiPackageList = NULL; + + // + // Retrieve buffer data from Opcode Handle + // + OpCodeBufferStart = (HII_LIB_OPCODE_BUFFER *)StartOpCodeHandle; + OpCodeBufferEnd = (HII_LIB_OPCODE_BUFFER *)EndOpCodeHandle; + + // + // Get the original package list + // + BufferSize = 0; + HiiPackageList = NULL; + Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, HiiHandle, &BufferSize, HiiPackageList); + // + // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0. + // + if (Status != EFI_BUFFER_TOO_SMALL) { + return Status; + } + + HiiPackageList = AllocatePool (BufferSize); + if (HiiPackageList == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Finish; + } + + Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, HiiHandle, &BufferSize, HiiPackageList); + if (EFI_ERROR (Status)) { + goto Finish; + } + + // + // Calculate and allocate space for retrieval of IFR data + // + BufferSize += OpCodeBufferStart->Position; + UpdatePackageList = AllocateZeroPool (BufferSize); + if (UpdatePackageList == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Finish; + } + + // + // Allocate temp buffer to store the temp updated package buffer + // + TempPackage = AllocateZeroPool (BufferSize); + if (TempPackage == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Finish; + } + + UpdateBufferPos = (UINT8 *)UpdatePackageList; + + // + // Copy the package list header + // + CopyMem (UpdateBufferPos, HiiPackageList, sizeof (EFI_HII_PACKAGE_LIST_HEADER)); + UpdateBufferPos += sizeof (EFI_HII_PACKAGE_LIST_HEADER); + + // + // Go through each package to find the matched package and update one by one + // + Updated = FALSE; + Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER); + PackageListLength = ReadUnaligned32 (&HiiPackageList->PackageLength); + while (Offset < PackageListLength) { + Package = (EFI_HII_PACKAGE_HEADER *)(((UINT8 *)HiiPackageList) + Offset); + CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER)); + Offset += Package->Length; + + if (Package->Type == EFI_HII_PACKAGE_FORMS) { + // + // Check this package is the matched package. + // + Status = InternalHiiUpdateFormPackageData (FormSetGuid, FormId, Package, OpCodeBufferStart, OpCodeBufferEnd, TempPackage); + // + // The matched package is found. Its package buffer will be updated by the input new data. + // + if (!EFI_ERROR (Status)) { + // + // Set Update Flag + // + Updated = TRUE; + // + // Add updated package buffer + // + Package = TempPackage; + } + } + + // + // Add pacakge buffer + // + CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER)); + CopyMem (UpdateBufferPos, Package, PackageHeader.Length); + UpdateBufferPos += PackageHeader.Length; + } + + if (Updated) { + // + // Update package list length + // + BufferSize = UpdateBufferPos - (UINT8 *)UpdatePackageList; + WriteUnaligned32 (&UpdatePackageList->PackageLength, (UINT32)BufferSize); + + // + // Update Package to show form + // + Status = gHiiDatabase->UpdatePackageList (gHiiDatabase, HiiHandle, UpdatePackageList); + } else { + // + // Not matched form is found and updated. + // + Status = EFI_NOT_FOUND; + } + +Finish: + if (HiiPackageList != NULL) { + FreePool (HiiPackageList); + } + + if (UpdatePackageList != NULL) { + FreePool (UpdatePackageList); + } + + if (TempPackage != NULL) { + FreePool (TempPackage); + } + + return Status; +} diff --git a/MdeModulePkg/Library/UefiHiiLib/HiiString.c b/MdeModulePkg/Library/UefiHiiLib/HiiString.c index 2c586ef64d..9ced10d4bf 100644 --- a/MdeModulePkg/Library/UefiHiiLib/HiiString.c +++ b/MdeModulePkg/Library/UefiHiiLib/HiiString.c @@ -1,395 +1,395 @@ -/** @file
- HII Library implementation that uses DXE protocols and services.
-
- Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>
- (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "InternalHiiLib.h"
-
-/**
- This function create a new string in String Package or updates an existing
- string in a String Package. If StringId is 0, then a new string is added to
- a String Package. If StringId is not zero, then a string in String Package is
- updated. If SupportedLanguages is NULL, then the string is added or updated
- for all the languages that the String Package supports. If SupportedLanguages
- is not NULL, then the string is added or updated for the set of languages
- specified by SupportedLanguages.
-
- If HiiHandle is NULL, then ASSERT().
- If String is NULL, then ASSERT().
-
- @param[in] HiiHandle A handle that was previously registered in the
- HII Database.
- @param[in] StringId If zero, then a new string is created in the
- String Package associated with HiiHandle. If
- non-zero, then the string specified by StringId
- is updated in the String Package associated
- with HiiHandle.
- @param[in] String A pointer to the Null-terminated Unicode string
- to add or update in the String Package associated
- with HiiHandle.
- @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string of
- language codes. If this parameter is NULL, then
- String is added or updated in the String Package
- associated with HiiHandle for all the languages
- that the String Package supports. If this
- parameter is not NULL, then then String is added
- or updated in the String Package associated with
- HiiHandle for the set oflanguages specified by
- SupportedLanguages. The format of
- SupportedLanguages must follow the language
- format assumed the HII Database.
-
- @retval 0 The string could not be added or updated in the String Package.
- @retval Other The EFI_STRING_ID of the newly added or updated string.
-
-**/
-EFI_STRING_ID
-EFIAPI
-HiiSetString (
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_STRING_ID StringId OPTIONAL,
- IN CONST EFI_STRING String,
- IN CONST CHAR8 *SupportedLanguages OPTIONAL
- )
-{
- EFI_STATUS Status;
- CHAR8 *AllocatedLanguages;
- CHAR8 *Supported;
- CHAR8 *Language;
-
- ASSERT (HiiHandle != NULL);
- ASSERT (String != NULL);
-
- if (SupportedLanguages == NULL) {
- //
- // Retrieve the languages that the package specified by HiiHandle supports
- //
- AllocatedLanguages = HiiGetSupportedLanguages (HiiHandle);
- } else {
- //
- // Allocate a copy of the SupportLanguages string that passed in
- //
- AllocatedLanguages = AllocateCopyPool (AsciiStrSize (SupportedLanguages), SupportedLanguages);
- }
-
- //
- // If there are not enough resources for the supported languages string, then return a StringId of 0
- //
- if (AllocatedLanguages == NULL) {
- return (EFI_STRING_ID)(0);
- }
-
- Status = EFI_INVALID_PARAMETER;
- //
- // Loop through each language that the string supports
- //
- for (Supported = AllocatedLanguages; *Supported != '\0'; ) {
- //
- // Cache a pointer to the beginning of the current language in the list of languages
- //
- Language = Supported;
-
- //
- // Search for the next language separator and replace it with a Null-terminator
- //
- for ( ; *Supported != 0 && *Supported != ';'; Supported++) {
- }
-
- if (*Supported != 0) {
- *(Supported++) = '\0';
- }
-
- if ((SupportedLanguages == NULL) && (AsciiStrnCmp (Language, UEFI_CONFIG_LANG, AsciiStrLen (UEFI_CONFIG_LANG)) == 0)) {
- //
- // Skip string package used for keyword protocol.
- //
- continue;
- }
-
- //
- // If StringId is 0, then call NewString(). Otherwise, call SetString()
- //
- if (StringId == (EFI_STRING_ID)(0)) {
- Status = gHiiString->NewString (gHiiString, HiiHandle, &StringId, Language, NULL, String, NULL);
- } else {
- Status = gHiiString->SetString (gHiiString, HiiHandle, StringId, Language, String, NULL);
- }
-
- //
- // If there was an error, then break out of the loop and return a StringId of 0
- //
- if (EFI_ERROR (Status)) {
- break;
- }
- }
-
- //
- // Free the buffer of supported languages
- //
- FreePool (AllocatedLanguages);
-
- if (EFI_ERROR (Status)) {
- return (EFI_STRING_ID)(0);
- } else {
- return StringId;
- }
-}
-
-/**
- Retrieves a string from a string package names by GUID in a specific language.
- If the language is not specified, then a string from a string package in the
- current platform language is retrieved. If the string can not be retrieved
- using the specified language or the current platform language, then the string
- is retrieved from the string package in the first language the string package
- supports. The returned string is allocated using AllocatePool(). The caller
- is responsible for freeing the allocated buffer using FreePool().
-
- If PackageListGuid is NULL, then ASSERT().
- If StringId is 0, then ASSERT.
-
- @param[in] PackageListGuid The GUID of a package list that was previously
- registered in the HII Database.
- @param[in] StringId The identifier of the string to retrieved from the
- string package associated with PackageListGuid.
- @param[in] Language The language of the string to retrieve. If this
- parameter is NULL, then the current platform
- language is used. The format of Language must
- follow the language format assumed the HII Database.
-
- @retval NULL The package list specified by PackageListGuid is not present in the
- HII Database.
- @retval NULL The string specified by StringId is not present in the string package.
- @retval Other The string was returned.
-
-**/
-EFI_STRING
-EFIAPI
-HiiGetPackageString (
- IN CONST EFI_GUID *PackageListGuid,
- IN EFI_STRING_ID StringId,
- IN CONST CHAR8 *Language OPTIONAL
- )
-{
- EFI_HII_HANDLE *HiiHandleBuffer;
- EFI_HII_HANDLE HiiHandle;
-
- ASSERT (PackageListGuid != NULL);
-
- HiiHandleBuffer = HiiGetHiiHandles (PackageListGuid);
- if (HiiHandleBuffer == NULL) {
- return NULL;
- }
-
- HiiHandle = HiiHandleBuffer[0];
- FreePool (HiiHandleBuffer);
-
- return HiiGetString (HiiHandle, StringId, Language);
-}
-
-/**
- Retrieves a string from a string package in a specific language specified in Language
- or in the best lanaguage. See HiiGetStringEx () for the details.
-
- @param[in] HiiHandle A handle that was previously registered in the HII Database.
- @param[in] StringId The identifier of the string to retrieved from the string
- package associated with HiiHandle.
- @param[in] Language The language of the string to retrieve. If this parameter
- is NULL, then the current platform language is used. The
- format of Language must follow the language format assumed
- the HII Database.
-
- @retval NULL The string specified by StringId is not present in the string package.
- @retval Other The string was returned.
-
-**/
-EFI_STRING
-EFIAPI
-HiiGetString (
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_STRING_ID StringId,
- IN CONST CHAR8 *Language OPTIONAL
- )
-{
- return HiiGetStringEx (HiiHandle, StringId, Language, TRUE);
-}
-
-/**
- Retrieves a string from a string package in a specific language or in the best
- language at discretion of this function according to the priority of languages.
- TryBestLanguage is used to get the string in the best language or in the language
- specified in Language parameter. The behavior is,
- If TryBestLanguage is TRUE, this function looks for the best language for the string.
- - If the string can not be retrieved using the specified language or the current
- platform language, then the string is retrieved from the string package in the
- first language the string package supports.
- If TryBestLanguage is FALSE, Language must be specified for retrieving the string.
-
- The returned string is allocated using AllocatePool(). The caller is responsible
- for freeing the allocated buffer using FreePool().
-
- If HiiHandle is NULL, then ASSERT().
- If StringId is 0, then ASSET.
- If TryBestLanguage is FALE and Language is NULL, then ASSERT().
-
- @param[in] HiiHandle A handle that was previously registered in the HII Database.
- @param[in] StringId The identifier of the string to retrieved from the string
- package associated with HiiHandle.
- @param[in] Language The language of the string to retrieve. If this parameter
- is NULL, then the current platform language is used. The
- format of Language must follow the language format assumed
- the HII Database.
- @param[in] TryBestLanguage If TRUE, try to get the best matching language from all
- supported languages.If FALSE, the Language must be assigned
- for the StringID.
-
- @retval NULL The string specified by StringId is not present in the string package.
- @retval Other The string was returned.
-
-**/
-EFI_STRING
-EFIAPI
-HiiGetStringEx (
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_STRING_ID StringId,
- IN CONST CHAR8 *Language OPTIONAL,
- IN BOOLEAN TryBestLanguage
- )
-{
- EFI_STATUS Status;
- UINTN StringSize;
- CHAR16 TempString;
- EFI_STRING String;
- CHAR8 *SupportedLanguages;
- CHAR8 *PlatformLanguage;
- CHAR8 *BestLanguage;
-
- ASSERT (HiiHandle != NULL);
- ASSERT (StringId != 0);
- //
- // Language must be specified if TryBestLanguage = FALSE.
- //
- ASSERT (!(!TryBestLanguage && Language == NULL));
- //
- // Initialize all allocated buffers to NULL
- //
- SupportedLanguages = NULL;
- PlatformLanguage = NULL;
- BestLanguage = NULL;
- String = NULL;
-
- //
- // Get the languages that the package specified by HiiHandle supports
- //
- SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
- if (SupportedLanguages == NULL) {
- goto Error;
- }
-
- //
- // Get the current platform language setting
- //
- GetEfiGlobalVariable2 (L"PlatformLang", (VOID **)&PlatformLanguage, NULL);
-
- //
- // If Languag is NULL, then set it to an empty string, so it will be
- // skipped by GetBestLanguage()
- //
- if (Language == NULL) {
- Language = "";
- }
-
- if (TryBestLanguage) {
- //
- // Get the best matching language from SupportedLanguages
- //
- BestLanguage = GetBestLanguage (
- SupportedLanguages,
- FALSE, // RFC 4646 mode
- Language, // Highest priority
- PlatformLanguage != NULL ? PlatformLanguage : "", // Next highest priority
- SupportedLanguages, // Lowest priority
- NULL
- );
- if (BestLanguage == NULL) {
- goto Error;
- }
- } else {
- BestLanguage = (CHAR8 *)Language;
- }
-
- //
- // Retrieve the size of the string in the string package for the BestLanguage
- //
- StringSize = 0;
- Status = gHiiString->GetString (
- gHiiString,
- BestLanguage,
- HiiHandle,
- StringId,
- &TempString,
- &StringSize,
- NULL
- );
- //
- // If GetString() returns EFI_SUCCESS for a zero size,
- // then there are no supported languages registered for HiiHandle. If GetString()
- // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
- // in the HII Database
- //
- if (Status != EFI_BUFFER_TOO_SMALL) {
- goto Error;
- }
-
- //
- // Allocate a buffer for the return string
- //
- String = AllocateZeroPool (StringSize);
- if (String == NULL) {
- goto Error;
- }
-
- //
- // Retrieve the string from the string package
- //
- Status = gHiiString->GetString (
- gHiiString,
- BestLanguage,
- HiiHandle,
- StringId,
- String,
- &StringSize,
- NULL
- );
- if (EFI_ERROR (Status)) {
- //
- // Free the buffer and return NULL if the supported languages can not be retrieved.
- //
- FreePool (String);
- String = NULL;
- }
-
-Error:
- //
- // Free allocated buffers
- //
- if (SupportedLanguages != NULL) {
- FreePool (SupportedLanguages);
- }
-
- if (PlatformLanguage != NULL) {
- FreePool (PlatformLanguage);
- }
-
- if (TryBestLanguage && (BestLanguage != NULL)) {
- FreePool (BestLanguage);
- }
-
- //
- // Return the Null-terminated Unicode string
- //
- return String;
-}
+/** @file + HII Library implementation that uses DXE protocols and services. + + Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR> + (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "InternalHiiLib.h" + +/** + This function create a new string in String Package or updates an existing + string in a String Package. If StringId is 0, then a new string is added to + a String Package. If StringId is not zero, then a string in String Package is + updated. If SupportedLanguages is NULL, then the string is added or updated + for all the languages that the String Package supports. If SupportedLanguages + is not NULL, then the string is added or updated for the set of languages + specified by SupportedLanguages. + + If HiiHandle is NULL, then ASSERT(). + If String is NULL, then ASSERT(). + + @param[in] HiiHandle A handle that was previously registered in the + HII Database. + @param[in] StringId If zero, then a new string is created in the + String Package associated with HiiHandle. If + non-zero, then the string specified by StringId + is updated in the String Package associated + with HiiHandle. + @param[in] String A pointer to the Null-terminated Unicode string + to add or update in the String Package associated + with HiiHandle. + @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string of + language codes. If this parameter is NULL, then + String is added or updated in the String Package + associated with HiiHandle for all the languages + that the String Package supports. If this + parameter is not NULL, then then String is added + or updated in the String Package associated with + HiiHandle for the set oflanguages specified by + SupportedLanguages. The format of + SupportedLanguages must follow the language + format assumed the HII Database. + + @retval 0 The string could not be added or updated in the String Package. + @retval Other The EFI_STRING_ID of the newly added or updated string. + +**/ +EFI_STRING_ID +EFIAPI +HiiSetString ( + IN EFI_HII_HANDLE HiiHandle, + IN EFI_STRING_ID StringId OPTIONAL, + IN CONST EFI_STRING String, + IN CONST CHAR8 *SupportedLanguages OPTIONAL + ) +{ + EFI_STATUS Status; + CHAR8 *AllocatedLanguages; + CHAR8 *Supported; + CHAR8 *Language; + + ASSERT (HiiHandle != NULL); + ASSERT (String != NULL); + + if (SupportedLanguages == NULL) { + // + // Retrieve the languages that the package specified by HiiHandle supports + // + AllocatedLanguages = HiiGetSupportedLanguages (HiiHandle); + } else { + // + // Allocate a copy of the SupportLanguages string that passed in + // + AllocatedLanguages = AllocateCopyPool (AsciiStrSize (SupportedLanguages), SupportedLanguages); + } + + // + // If there are not enough resources for the supported languages string, then return a StringId of 0 + // + if (AllocatedLanguages == NULL) { + return (EFI_STRING_ID)(0); + } + + Status = EFI_INVALID_PARAMETER; + // + // Loop through each language that the string supports + // + for (Supported = AllocatedLanguages; *Supported != '\0'; ) { + // + // Cache a pointer to the beginning of the current language in the list of languages + // + Language = Supported; + + // + // Search for the next language separator and replace it with a Null-terminator + // + for ( ; *Supported != 0 && *Supported != ';'; Supported++) { + } + + if (*Supported != 0) { + *(Supported++) = '\0'; + } + + if ((SupportedLanguages == NULL) && (AsciiStrnCmp (Language, UEFI_CONFIG_LANG, AsciiStrLen (UEFI_CONFIG_LANG)) == 0)) { + // + // Skip string package used for keyword protocol. + // + continue; + } + + // + // If StringId is 0, then call NewString(). Otherwise, call SetString() + // + if (StringId == (EFI_STRING_ID)(0)) { + Status = gHiiString->NewString (gHiiString, HiiHandle, &StringId, Language, NULL, String, NULL); + } else { + Status = gHiiString->SetString (gHiiString, HiiHandle, StringId, Language, String, NULL); + } + + // + // If there was an error, then break out of the loop and return a StringId of 0 + // + if (EFI_ERROR (Status)) { + break; + } + } + + // + // Free the buffer of supported languages + // + FreePool (AllocatedLanguages); + + if (EFI_ERROR (Status)) { + return (EFI_STRING_ID)(0); + } else { + return StringId; + } +} + +/** + Retrieves a string from a string package names by GUID in a specific language. + If the language is not specified, then a string from a string package in the + current platform language is retrieved. If the string can not be retrieved + using the specified language or the current platform language, then the string + is retrieved from the string package in the first language the string package + supports. The returned string is allocated using AllocatePool(). The caller + is responsible for freeing the allocated buffer using FreePool(). + + If PackageListGuid is NULL, then ASSERT(). + If StringId is 0, then ASSERT. + + @param[in] PackageListGuid The GUID of a package list that was previously + registered in the HII Database. + @param[in] StringId The identifier of the string to retrieved from the + string package associated with PackageListGuid. + @param[in] Language The language of the string to retrieve. If this + parameter is NULL, then the current platform + language is used. The format of Language must + follow the language format assumed the HII Database. + + @retval NULL The package list specified by PackageListGuid is not present in the + HII Database. + @retval NULL The string specified by StringId is not present in the string package. + @retval Other The string was returned. + +**/ +EFI_STRING +EFIAPI +HiiGetPackageString ( + IN CONST EFI_GUID *PackageListGuid, + IN EFI_STRING_ID StringId, + IN CONST CHAR8 *Language OPTIONAL + ) +{ + EFI_HII_HANDLE *HiiHandleBuffer; + EFI_HII_HANDLE HiiHandle; + + ASSERT (PackageListGuid != NULL); + + HiiHandleBuffer = HiiGetHiiHandles (PackageListGuid); + if (HiiHandleBuffer == NULL) { + return NULL; + } + + HiiHandle = HiiHandleBuffer[0]; + FreePool (HiiHandleBuffer); + + return HiiGetString (HiiHandle, StringId, Language); +} + +/** + Retrieves a string from a string package in a specific language specified in Language + or in the best lanaguage. See HiiGetStringEx () for the details. + + @param[in] HiiHandle A handle that was previously registered in the HII Database. + @param[in] StringId The identifier of the string to retrieved from the string + package associated with HiiHandle. + @param[in] Language The language of the string to retrieve. If this parameter + is NULL, then the current platform language is used. The + format of Language must follow the language format assumed + the HII Database. + + @retval NULL The string specified by StringId is not present in the string package. + @retval Other The string was returned. + +**/ +EFI_STRING +EFIAPI +HiiGetString ( + IN EFI_HII_HANDLE HiiHandle, + IN EFI_STRING_ID StringId, + IN CONST CHAR8 *Language OPTIONAL + ) +{ + return HiiGetStringEx (HiiHandle, StringId, Language, TRUE); +} + +/** + Retrieves a string from a string package in a specific language or in the best + language at discretion of this function according to the priority of languages. + TryBestLanguage is used to get the string in the best language or in the language + specified in Language parameter. The behavior is, + If TryBestLanguage is TRUE, this function looks for the best language for the string. + - If the string can not be retrieved using the specified language or the current + platform language, then the string is retrieved from the string package in the + first language the string package supports. + If TryBestLanguage is FALSE, Language must be specified for retrieving the string. + + The returned string is allocated using AllocatePool(). The caller is responsible + for freeing the allocated buffer using FreePool(). + + If HiiHandle is NULL, then ASSERT(). + If StringId is 0, then ASSET. + If TryBestLanguage is FALE and Language is NULL, then ASSERT(). + + @param[in] HiiHandle A handle that was previously registered in the HII Database. + @param[in] StringId The identifier of the string to retrieved from the string + package associated with HiiHandle. + @param[in] Language The language of the string to retrieve. If this parameter + is NULL, then the current platform language is used. The + format of Language must follow the language format assumed + the HII Database. + @param[in] TryBestLanguage If TRUE, try to get the best matching language from all + supported languages.If FALSE, the Language must be assigned + for the StringID. + + @retval NULL The string specified by StringId is not present in the string package. + @retval Other The string was returned. + +**/ +EFI_STRING +EFIAPI +HiiGetStringEx ( + IN EFI_HII_HANDLE HiiHandle, + IN EFI_STRING_ID StringId, + IN CONST CHAR8 *Language OPTIONAL, + IN BOOLEAN TryBestLanguage + ) +{ + EFI_STATUS Status; + UINTN StringSize; + CHAR16 TempString; + EFI_STRING String; + CHAR8 *SupportedLanguages; + CHAR8 *PlatformLanguage; + CHAR8 *BestLanguage; + + ASSERT (HiiHandle != NULL); + ASSERT (StringId != 0); + // + // Language must be specified if TryBestLanguage = FALSE. + // + ASSERT (!(!TryBestLanguage && Language == NULL)); + // + // Initialize all allocated buffers to NULL + // + SupportedLanguages = NULL; + PlatformLanguage = NULL; + BestLanguage = NULL; + String = NULL; + + // + // Get the languages that the package specified by HiiHandle supports + // + SupportedLanguages = HiiGetSupportedLanguages (HiiHandle); + if (SupportedLanguages == NULL) { + goto Error; + } + + // + // Get the current platform language setting + // + GetEfiGlobalVariable2 (L"PlatformLang", (VOID **)&PlatformLanguage, NULL); + + // + // If Languag is NULL, then set it to an empty string, so it will be + // skipped by GetBestLanguage() + // + if (Language == NULL) { + Language = ""; + } + + if (TryBestLanguage) { + // + // Get the best matching language from SupportedLanguages + // + BestLanguage = GetBestLanguage ( + SupportedLanguages, + FALSE, // RFC 4646 mode + Language, // Highest priority + PlatformLanguage != NULL ? PlatformLanguage : "", // Next highest priority + SupportedLanguages, // Lowest priority + NULL + ); + if (BestLanguage == NULL) { + goto Error; + } + } else { + BestLanguage = (CHAR8 *)Language; + } + + // + // Retrieve the size of the string in the string package for the BestLanguage + // + StringSize = 0; + Status = gHiiString->GetString ( + gHiiString, + BestLanguage, + HiiHandle, + StringId, + &TempString, + &StringSize, + NULL + ); + // + // If GetString() returns EFI_SUCCESS for a zero size, + // then there are no supported languages registered for HiiHandle. If GetString() + // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present + // in the HII Database + // + if (Status != EFI_BUFFER_TOO_SMALL) { + goto Error; + } + + // + // Allocate a buffer for the return string + // + String = AllocateZeroPool (StringSize); + if (String == NULL) { + goto Error; + } + + // + // Retrieve the string from the string package + // + Status = gHiiString->GetString ( + gHiiString, + BestLanguage, + HiiHandle, + StringId, + String, + &StringSize, + NULL + ); + if (EFI_ERROR (Status)) { + // + // Free the buffer and return NULL if the supported languages can not be retrieved. + // + FreePool (String); + String = NULL; + } + +Error: + // + // Free allocated buffers + // + if (SupportedLanguages != NULL) { + FreePool (SupportedLanguages); + } + + if (PlatformLanguage != NULL) { + FreePool (PlatformLanguage); + } + + if (TryBestLanguage && (BestLanguage != NULL)) { + FreePool (BestLanguage); + } + + // + // Return the Null-terminated Unicode string + // + return String; +} diff --git a/MdeModulePkg/Library/UefiHiiLib/InternalHiiLib.h b/MdeModulePkg/Library/UefiHiiLib/InternalHiiLib.h index 9378f9d6ef..c74efc2c59 100644 --- a/MdeModulePkg/Library/UefiHiiLib/InternalHiiLib.h +++ b/MdeModulePkg/Library/UefiHiiLib/InternalHiiLib.h @@ -1,30 +1,30 @@ -/** @file
- Internal include file for the HII Library instance.
-
- Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef __INTERNAL_HII_LIB_H__
-#define __INTERNAL_HII_LIB_H__
-
-#include <Uefi.h>
-
-#include <Protocol/DevicePath.h>
-#include <Protocol/FormBrowser2.h>
-
-#include <Guid/MdeModuleHii.h>
-
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/HiiLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/UefiHiiServicesLib.h>
-#include <Library/PrintLib.h>
-#include <Library/UefiLib.h>
-
-#endif
+/** @file + Internal include file for the HII Library instance. + + Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __INTERNAL_HII_LIB_H__ +#define __INTERNAL_HII_LIB_H__ + +#include <Uefi.h> + +#include <Protocol/DevicePath.h> +#include <Protocol/FormBrowser2.h> + +#include <Guid/MdeModuleHii.h> + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/HiiLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/DevicePathLib.h> +#include <Library/UefiHiiServicesLib.h> +#include <Library/PrintLib.h> +#include <Library/UefiLib.h> + +#endif diff --git a/MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf b/MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf index d432b439bc..cc9b5bd127 100644 --- a/MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf +++ b/MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf @@ -1,50 +1,50 @@ -## @file
-# HII Library implementation using UEFI HII protocols and services.
-#
-# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = UefiHiiLib
- MODULE_UNI_FILE = UefiHiiLib.uni
- FILE_GUID = 3143687A-7C80-404e-B5FE-2D88980E1B1C
- MODULE_TYPE = UEFI_DRIVER
- VERSION_STRING = 1.0
- LIBRARY_CLASS = HiiLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
-
-#
-# VALID_ARCHITECTURES = IA32 X64 EBC
-#
-
-[Sources]
- HiiLib.c
- HiiString.c
- HiiLanguage.c
- InternalHiiLib.h
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
-
-[LibraryClasses]
- MemoryAllocationLib
- BaseMemoryLib
- BaseLib
- DebugLib
- UefiBootServicesTableLib
- DevicePathLib
- UefiLib
- UefiHiiServicesLib
- PrintLib
-
-[Protocols]
- gEfiFormBrowser2ProtocolGuid ## SOMETIMES_CONSUMES
- gEfiDevicePathProtocolGuid ## SOMETIMES_CONSUMES
-
-[Guids]
- gEdkiiIfrBitVarstoreGuid ## SOMETIMES_CONSUMES ## GUID
+## @file +# HII Library implementation using UEFI HII protocols and services. +# +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UefiHiiLib + MODULE_UNI_FILE = UefiHiiLib.uni + FILE_GUID = 3143687A-7C80-404e-B5FE-2D88980E1B1C + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = HiiLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER + +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + HiiLib.c + HiiString.c + HiiLanguage.c + InternalHiiLib.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + MemoryAllocationLib + BaseMemoryLib + BaseLib + DebugLib + UefiBootServicesTableLib + DevicePathLib + UefiLib + UefiHiiServicesLib + PrintLib + +[Protocols] + gEfiFormBrowser2ProtocolGuid ## SOMETIMES_CONSUMES + gEfiDevicePathProtocolGuid ## SOMETIMES_CONSUMES + +[Guids] + gEdkiiIfrBitVarstoreGuid ## SOMETIMES_CONSUMES ## GUID diff --git a/MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.uni b/MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.uni index 76ee892320..b53a5cd6a7 100644 --- a/MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.uni +++ b/MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.uni @@ -1,16 +1,16 @@ -// /** @file
-// HII Library implementation using UEFI HII protocols and services.
-//
-// HII Library implementation using UEFI HII protocols and services.
-//
-// Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-
-#string STR_MODULE_ABSTRACT #language en-US "HII Library implementation using UEFI HII protocols and services"
-
-#string STR_MODULE_DESCRIPTION #language en-US "HII Library implementation using UEFI HII protocols and services."
-
+// /** @file +// HII Library implementation using UEFI HII protocols and services. +// +// HII Library implementation using UEFI HII protocols and services. +// +// Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "HII Library implementation using UEFI HII protocols and services" + +#string STR_MODULE_DESCRIPTION #language en-US "HII Library implementation using UEFI HII protocols and services." + |
