diff options
| author | kx <kx@radix.pro> | 2024-06-04 06:43:08 +0300 |
|---|---|---|
| committer | kx <kx@radix.pro> | 2024-06-04 06:43:08 +0300 |
| commit | 7e2ccccace24636f29ddc210b94606abd4c7e42b (patch) | |
| tree | 545d43ea12671048956cafeb12303e84d601e571 /MdeModulePkg/Library/VarCheckHiiLib | |
| parent | 27b044605cd5f6b33a3d231576003850b3fe305b (diff) | |
| download | edk2-trunk.tar.xz | |
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'MdeModulePkg/Library/VarCheckHiiLib')
| -rw-r--r-- | MdeModulePkg/Library/VarCheckHiiLib/InternalVarCheckStructure.h | 162 | ||||
| -rw-r--r-- | MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h | 114 | ||||
| -rw-r--r-- | MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c | 3274 | ||||
| -rw-r--r-- | MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.h | 260 | ||||
| -rw-r--r-- | MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c | 880 | ||||
| -rw-r--r-- | MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromHii.c | 134 | ||||
| -rw-r--r-- | MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf | 102 | ||||
| -rw-r--r-- | MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.uni | 32 | ||||
| -rw-r--r-- | MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c | 1260 |
9 files changed, 3109 insertions, 3109 deletions
diff --git a/MdeModulePkg/Library/VarCheckHiiLib/InternalVarCheckStructure.h b/MdeModulePkg/Library/VarCheckHiiLib/InternalVarCheckStructure.h index c7da537eb4..eef2650971 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/InternalVarCheckStructure.h +++ b/MdeModulePkg/Library/VarCheckHiiLib/InternalVarCheckStructure.h @@ -1,81 +1,81 @@ -/** @file
- Internal structure for Var Check Hii.
-
-Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _VAR_CHECK_STRUCTURE_H_
-#define _VAR_CHECK_STRUCTURE_H_
-
-//
-// Alignment for Hii Variable and Question header.
-//
-#define HEADER_ALIGNMENT 4
-#define HEADER_ALIGN(Header) (((UINTN) (Header) + HEADER_ALIGNMENT - 1) & (~(HEADER_ALIGNMENT - 1)))
-
-#pragma pack (1)
-
-#define VAR_CHECK_HII_REVISION 0x0002
-
-typedef struct {
- UINT16 Revision;
- UINT16 HeaderLength;
- UINT32 Length; // Length include this header
- UINT8 OpCode;
- UINT8 Reserved;
- UINT16 Size;
- UINT32 Attributes;
- EFI_GUID Guid;
- // CHAR16 Name[];
-} VAR_CHECK_HII_VARIABLE_HEADER;
-
-typedef struct {
- UINT8 OpCode;
- UINT8 Length; // Length include this header
- UINT16 VarOffset;
- UINT8 StorageWidth;
- BOOLEAN BitFieldStore; // Whether the Question is stored in bit field, if TRUE, the VarOffset/StorageWidth will be saved as bit level, otherwise in byte level.
-} VAR_CHECK_HII_QUESTION_HEADER;
-
-typedef struct {
- UINT8 OpCode;
- UINT8 Length; // Length include this header
- UINT16 VarOffset;
- UINT8 StorageWidth;
- BOOLEAN BitFieldStore; // Whether the Question is stored in bit field, if TRUE, the VarOffset/StorageWidth will be saved as bit level, otherwise in byte level.
- // UINTx Data[]; // x = UINT8/UINT16/UINT32/UINT64;
-} VAR_CHECK_HII_QUESTION_ONEOF;
-
-typedef struct {
- UINT8 OpCode;
- UINT8 Length; // Length include this header
- UINT16 VarOffset;
- UINT8 StorageWidth;
- BOOLEAN BitFieldStore; // Whether the Question is stored in bit field, if TRUE, the VarOffset/StorageWidth will be saved as bit level, otherwise in byte level.
-} VAR_CHECK_HII_QUESTION_CHECKBOX;
-
-typedef struct {
- UINT8 OpCode;
- UINT8 Length; // Length include this header
- UINT16 VarOffset;
- UINT8 StorageWidth;
- BOOLEAN BitFieldStore; // Whether the Question is stored in bit field, if TRUE, the VarOffset/StorageWidth will be saved as bit level, otherwise in byte level.
- // UINTx Minimum; // x = UINT8/UINT16/UINT32/UINT64;
- // UINTx Maximum; // x = UINT8/UINT16/UINT32/UINT64;
-} VAR_CHECK_HII_QUESTION_NUMERIC;
-
-typedef struct {
- UINT8 OpCode;
- UINT8 Length; // Length include this header
- UINT16 VarOffset;
- UINT8 StorageWidth;
- BOOLEAN BitFieldStore; // Whether the Question is stored in bit field, if TRUE, the VarOffset/StorageWidth will be saved as bit level, otherwise in byte level.
- UINT8 MaxContainers;
- // UINTx Data[]; // x = UINT8/UINT16/UINT32/UINT64;
-} VAR_CHECK_HII_QUESTION_ORDEREDLIST;
-
-#pragma pack ()
-
-#endif
+/** @file + Internal structure for Var Check Hii. + +Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _VAR_CHECK_STRUCTURE_H_ +#define _VAR_CHECK_STRUCTURE_H_ + +// +// Alignment for Hii Variable and Question header. +// +#define HEADER_ALIGNMENT 4 +#define HEADER_ALIGN(Header) (((UINTN) (Header) + HEADER_ALIGNMENT - 1) & (~(HEADER_ALIGNMENT - 1))) + +#pragma pack (1) + +#define VAR_CHECK_HII_REVISION 0x0002 + +typedef struct { + UINT16 Revision; + UINT16 HeaderLength; + UINT32 Length; // Length include this header + UINT8 OpCode; + UINT8 Reserved; + UINT16 Size; + UINT32 Attributes; + EFI_GUID Guid; + // CHAR16 Name[]; +} VAR_CHECK_HII_VARIABLE_HEADER; + +typedef struct { + UINT8 OpCode; + UINT8 Length; // Length include this header + UINT16 VarOffset; + UINT8 StorageWidth; + BOOLEAN BitFieldStore; // Whether the Question is stored in bit field, if TRUE, the VarOffset/StorageWidth will be saved as bit level, otherwise in byte level. +} VAR_CHECK_HII_QUESTION_HEADER; + +typedef struct { + UINT8 OpCode; + UINT8 Length; // Length include this header + UINT16 VarOffset; + UINT8 StorageWidth; + BOOLEAN BitFieldStore; // Whether the Question is stored in bit field, if TRUE, the VarOffset/StorageWidth will be saved as bit level, otherwise in byte level. + // UINTx Data[]; // x = UINT8/UINT16/UINT32/UINT64; +} VAR_CHECK_HII_QUESTION_ONEOF; + +typedef struct { + UINT8 OpCode; + UINT8 Length; // Length include this header + UINT16 VarOffset; + UINT8 StorageWidth; + BOOLEAN BitFieldStore; // Whether the Question is stored in bit field, if TRUE, the VarOffset/StorageWidth will be saved as bit level, otherwise in byte level. +} VAR_CHECK_HII_QUESTION_CHECKBOX; + +typedef struct { + UINT8 OpCode; + UINT8 Length; // Length include this header + UINT16 VarOffset; + UINT8 StorageWidth; + BOOLEAN BitFieldStore; // Whether the Question is stored in bit field, if TRUE, the VarOffset/StorageWidth will be saved as bit level, otherwise in byte level. + // UINTx Minimum; // x = UINT8/UINT16/UINT32/UINT64; + // UINTx Maximum; // x = UINT8/UINT16/UINT32/UINT64; +} VAR_CHECK_HII_QUESTION_NUMERIC; + +typedef struct { + UINT8 OpCode; + UINT8 Length; // Length include this header + UINT16 VarOffset; + UINT8 StorageWidth; + BOOLEAN BitFieldStore; // Whether the Question is stored in bit field, if TRUE, the VarOffset/StorageWidth will be saved as bit level, otherwise in byte level. + UINT8 MaxContainers; + // UINTx Data[]; // x = UINT8/UINT16/UINT32/UINT64; +} VAR_CHECK_HII_QUESTION_ORDEREDLIST; + +#pragma pack () + +#endif diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h index 89de54ddf4..0f8332c435 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h @@ -1,57 +1,57 @@ -/** @file
- Include file for Var Check Hii handler and bin.
-
-Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _VAR_CHECK_HII_H_
-#define _VAR_CHECK_HII_H_
-
-#include <Library/VarCheckLib.h>
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/MemoryAllocationLib.h>
-
-#include <Guid/MdeModuleHii.h>
-
-#include <Protocol/HiiDatabase.h>
-#include <Protocol/FirmwareVolume2.h>
-#include <Protocol/FirmwareVolumeBlock.h>
-
-#include "InternalVarCheckStructure.h"
-#include "VarCheckHiiGen.h"
-
-// #define DUMP_VAR_CHECK_HII
-// #define DUMP_HII_DATA
-
-typedef struct {
- UINT8 HiiOpCode;
- CHAR8 *HiiOpCodeStr;
-} VAR_CHECK_HII_OPCODE_STRING;
-
-typedef struct {
- UINT8 PackageType;
- CHAR8 *PackageTypeStr;
-} VAR_CHECK_HII_PACKAGE_TYPE_STRING;
-
-/**
- Dump Var Check HII.
-
- @param[in] VarCheckHiiBin Pointer to VarCheckHiiBin.
- @param[in] VarCheckHiiBinSize VarCheckHiiBin size.
-
-**/
-VOID
-DumpVarCheckHii (
- IN VOID *VarCheckHiiBin,
- IN UINTN VarCheckHiiBinSize
- );
-
-extern VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin;
-extern UINTN mVarCheckHiiBinSize;
-
-#endif
+/** @file + Include file for Var Check Hii handler and bin. + +Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _VAR_CHECK_HII_H_ +#define _VAR_CHECK_HII_H_ + +#include <Library/VarCheckLib.h> +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/MemoryAllocationLib.h> + +#include <Guid/MdeModuleHii.h> + +#include <Protocol/HiiDatabase.h> +#include <Protocol/FirmwareVolume2.h> +#include <Protocol/FirmwareVolumeBlock.h> + +#include "InternalVarCheckStructure.h" +#include "VarCheckHiiGen.h" + +// #define DUMP_VAR_CHECK_HII +// #define DUMP_HII_DATA + +typedef struct { + UINT8 HiiOpCode; + CHAR8 *HiiOpCodeStr; +} VAR_CHECK_HII_OPCODE_STRING; + +typedef struct { + UINT8 PackageType; + CHAR8 *PackageTypeStr; +} VAR_CHECK_HII_PACKAGE_TYPE_STRING; + +/** + Dump Var Check HII. + + @param[in] VarCheckHiiBin Pointer to VarCheckHiiBin. + @param[in] VarCheckHiiBinSize VarCheckHiiBin size. + +**/ +VOID +DumpVarCheckHii ( + IN VOID *VarCheckHiiBin, + IN UINTN VarCheckHiiBinSize + ); + +extern VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin; +extern UINTN mVarCheckHiiBinSize; + +#endif diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c index ca8227df6b..20c3852e3d 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c @@ -1,1637 +1,1637 @@ -/** @file
- Var Check Hii bin generation.
-
-Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "VarCheckHiiGen.h"
-
-LIST_ENTRY mVarCheckHiiList = INITIALIZE_LIST_HEAD_VARIABLE (mVarCheckHiiList);
-
-#define VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE SIGNATURE_32 ('V', 'C', 'H', 'V')
-
-typedef struct {
- UINTN Signature;
- LIST_ENTRY Link;
- VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;
- EFI_VARSTORE_ID VarStoreId;
-
- VAR_CHECK_HII_QUESTION_HEADER **HiiQuestionArray;
-} VAR_CHECK_HII_VARIABLE_NODE;
-
-#define VAR_CHECK_HII_VARIABLE_FROM_LINK(a) CR (a, VAR_CHECK_HII_VARIABLE_NODE, Link, VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE)
-
-CHAR16 *mVarName = NULL;
-UINTN mMaxVarNameSize = 0;
-
-#ifdef DUMP_HII_DATA
-GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_OPCODE_STRING mIfrOpCodeStringTable[] = {
- { EFI_IFR_VARSTORE_OP, "EFI_IFR_VARSTORE_OP" },
- { EFI_IFR_VARSTORE_EFI_OP, "EFI_IFR_VARSTORE_EFI_OP" },
- { EFI_IFR_ONE_OF_OP, "EFI_IFR_ONE_OF_OP" },
- { EFI_IFR_CHECKBOX_OP, "EFI_IFR_CHECKBOX_OP" },
- { EFI_IFR_NUMERIC_OP, "EFI_IFR_NUMERIC_OP" },
- { EFI_IFR_ORDERED_LIST_OP, "EFI_IFR_ORDERED_LIST_OP" },
- { EFI_IFR_ONE_OF_OPTION_OP, "EFI_IFR_ONE_OF_OPTION_OP" },
-};
-
-/**
- Ifr opcode to string.
-
- @param[in] IfrOpCode Ifr OpCode.
-
- @return Pointer to string.
-
-**/
-CHAR8 *
-IfrOpCodeToStr (
- IN UINT8 IfrOpCode
- )
-{
- UINTN Index;
-
- for (Index = 0; Index < ARRAY_SIZE (mIfrOpCodeStringTable); Index++) {
- if (mIfrOpCodeStringTable[Index].HiiOpCode == IfrOpCode) {
- return mIfrOpCodeStringTable[Index].HiiOpCodeStr;
- }
- }
-
- return "<UnknownIfrOpCode>";
-}
-
-GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_PACKAGE_TYPE_STRING mPackageTypeStringTable[] = {
- { EFI_HII_PACKAGE_TYPE_ALL, "EFI_HII_PACKAGE_TYPE_ALL" },
- { EFI_HII_PACKAGE_TYPE_GUID, "EFI_HII_PACKAGE_TYPE_GUID" },
- { EFI_HII_PACKAGE_FORMS, "EFI_HII_PACKAGE_FORMS" },
- { EFI_HII_PACKAGE_STRINGS, "EFI_HII_PACKAGE_STRINGS" },
- { EFI_HII_PACKAGE_FONTS, "EFI_HII_PACKAGE_FONTS" },
- { EFI_HII_PACKAGE_IMAGES, "EFI_HII_PACKAGE_IMAGES" },
- { EFI_HII_PACKAGE_SIMPLE_FONTS, "EFI_HII_PACKAGE_SIMPLE_FONTS" },
- { EFI_HII_PACKAGE_DEVICE_PATH, "EFI_HII_PACKAGE_DEVICE_PATH" },
- { EFI_HII_PACKAGE_KEYBOARD_LAYOUT, "EFI_HII_PACKAGE_KEYBOARD_LAYOUT" },
- { EFI_HII_PACKAGE_ANIMATIONS, "EFI_HII_PACKAGE_ANIMATIONS" },
- { EFI_HII_PACKAGE_END, "EFI_HII_PACKAGE_END" },
- { EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN, "EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN" },
- { EFI_HII_PACKAGE_TYPE_SYSTEM_END, "EFI_HII_PACKAGE_TYPE_SYSTEM_END" },
-};
-
-/**
- Hii Package type to string.
-
- @param[in] PackageType Package Type
-
- @return Pointer to string.
-
-**/
-CHAR8 *
-HiiPackageTypeToStr (
- IN UINT8 PackageType
- )
-{
- UINTN Index;
-
- for (Index = 0; Index < ARRAY_SIZE (mPackageTypeStringTable); Index++) {
- if (mPackageTypeStringTable[Index].PackageType == PackageType) {
- return mPackageTypeStringTable[Index].PackageTypeStr;
- }
- }
-
- return "<UnknownPackageType>";
-}
-
-/**
- Dump Hii Package.
-
- @param[in] HiiPackage Pointer to Hii Package.
-
-**/
-VOID
-DumpHiiPackage (
- IN VOID *HiiPackage
- )
-{
- EFI_HII_PACKAGE_HEADER *HiiPackageHeader;
- EFI_IFR_OP_HEADER *IfrOpCodeHeader;
- EFI_IFR_VARSTORE *IfrVarStore;
- EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;
- BOOLEAN QuestionStoredInBitField;
-
- HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiPackage;
- QuestionStoredInBitField = FALSE;
-
- DEBUG ((DEBUG_INFO, " HiiPackageHeader->Type - 0x%02x (%a)\n", HiiPackageHeader->Type, HiiPackageTypeToStr ((UINT8)HiiPackageHeader->Type)));
- DEBUG ((DEBUG_INFO, " HiiPackageHeader->Length - 0x%06x\n", HiiPackageHeader->Length));
-
- switch (HiiPackageHeader->Type) {
- case EFI_HII_PACKAGE_FORMS:
- IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)(HiiPackageHeader + 1);
-
- while ((UINTN)IfrOpCodeHeader < ((UINTN)HiiPackageHeader + HiiPackageHeader->Length)) {
- switch (IfrOpCodeHeader->OpCode) {
- case EFI_IFR_VARSTORE_OP:
- IfrVarStore = (EFI_IFR_VARSTORE *)IfrOpCodeHeader;
- DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", IfrOpCodeHeader->OpCode, IfrOpCodeToStr (IfrOpCodeHeader->OpCode)));
- DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader->Length));
- DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader->Scope));
- DEBUG ((DEBUG_INFO, " Guid - %g\n", &IfrVarStore->Guid));
- DEBUG ((DEBUG_INFO, " VarStoreId - 0x%04x\n", IfrVarStore->VarStoreId));
- DEBUG ((DEBUG_INFO, " Size - 0x%04x\n", IfrVarStore->Size));
- DEBUG ((DEBUG_INFO, " Name - %a\n", IfrVarStore->Name));
- break;
-
- case EFI_IFR_VARSTORE_EFI_OP:
- IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpCodeHeader;
- if (IfrEfiVarStore->Header.Length >= sizeof (EFI_IFR_VARSTORE_EFI)) {
- DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", IfrOpCodeHeader->OpCode, IfrOpCodeToStr (IfrOpCodeHeader->OpCode)));
- DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader->Length));
- DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader->Scope));
- DEBUG ((DEBUG_INFO, " Guid - %g\n", &IfrEfiVarStore->Guid));
- DEBUG ((DEBUG_INFO, " VarStoreId - 0x%04x\n", IfrEfiVarStore->VarStoreId));
- DEBUG ((DEBUG_INFO, " Size - 0x%04x\n", IfrEfiVarStore->Size));
- DEBUG ((DEBUG_INFO, " Attributes - 0x%08x\n", IfrEfiVarStore->Attributes));
- DEBUG ((DEBUG_INFO, " Name - %a\n", IfrEfiVarStore->Name));
- }
-
- break;
-
- case EFI_IFR_GUID_OP:
- if (CompareGuid ((EFI_GUID *)((UINTN)IfrOpCodeHeader + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {
- QuestionStoredInBitField = TRUE;
- }
-
- break;
-
- case EFI_IFR_ONE_OF_OP:
- case EFI_IFR_CHECKBOX_OP:
- case EFI_IFR_NUMERIC_OP:
- case EFI_IFR_ORDERED_LIST_OP:
- DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->OpCode - 0x%02x (%a) (%a)\n", IfrOpCodeHeader->OpCode, IfrOpCodeToStr (IfrOpCodeHeader->OpCode), (QuestionStoredInBitField ? "bit level" : "byte level")));
- DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader->Length));
- DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader->Scope));
- DEBUG ((DEBUG_INFO, " Prompt - 0x%04x\n", ((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.Header.Prompt));
- DEBUG ((DEBUG_INFO, " Help - 0x%04x\n", ((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.Header.Help));
- DEBUG ((DEBUG_INFO, " QuestionId - 0x%04x\n", ((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.QuestionId));
- DEBUG ((DEBUG_INFO, " VarStoreId - 0x%04x\n", ((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.VarStoreId));
- DEBUG ((DEBUG_INFO, " VarStoreInfo - 0x%04x (%a)\n", ((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.VarStoreInfo.VarOffset, (QuestionStoredInBitField ? "bit level" : "byte level")));
- {
- EFI_IFR_ONE_OF *IfrOneOf;
- EFI_IFR_CHECKBOX *IfrCheckBox;
- EFI_IFR_NUMERIC *IfrNumeric;
- EFI_IFR_ORDERED_LIST *IfrOrderedList;
-
- switch (IfrOpCodeHeader->OpCode) {
- case EFI_IFR_ONE_OF_OP:
- IfrOneOf = (EFI_IFR_ONE_OF *)IfrOpCodeHeader;
- DEBUG ((DEBUG_INFO, " Flags - 0x%02x\n", IfrOneOf->Flags));
- if (QuestionStoredInBitField) {
- //
- // For OneOf stored in bit field, the option value are saved as UINT32 type.
- //
- DEBUG ((DEBUG_INFO, " MinValue - 0x%08x\n", IfrOneOf->data.u32.MinValue));
- DEBUG ((DEBUG_INFO, " MaxValue - 0x%08x\n", IfrOneOf->data.u32.MaxValue));
- DEBUG ((DEBUG_INFO, " Step - 0x%08x\n", IfrOneOf->data.u32.Step));
- } else {
- switch (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE) {
- case EFI_IFR_NUMERIC_SIZE_1:
- DEBUG ((DEBUG_INFO, " MinValue - 0x%02x\n", IfrOneOf->data.u8.MinValue));
- DEBUG ((DEBUG_INFO, " MaxValue - 0x%02x\n", IfrOneOf->data.u8.MaxValue));
- DEBUG ((DEBUG_INFO, " Step - 0x%02x\n", IfrOneOf->data.u8.Step));
- break;
- case EFI_IFR_NUMERIC_SIZE_2:
- DEBUG ((DEBUG_INFO, " MinValue - 0x%04x\n", IfrOneOf->data.u16.MinValue));
- DEBUG ((DEBUG_INFO, " MaxValue - 0x%04x\n", IfrOneOf->data.u16.MaxValue));
- DEBUG ((DEBUG_INFO, " Step - 0x%04x\n", IfrOneOf->data.u16.Step));
- break;
- case EFI_IFR_NUMERIC_SIZE_4:
- DEBUG ((DEBUG_INFO, " MinValue - 0x%08x\n", IfrOneOf->data.u32.MinValue));
- DEBUG ((DEBUG_INFO, " MaxValue - 0x%08x\n", IfrOneOf->data.u32.MaxValue));
- DEBUG ((DEBUG_INFO, " Step - 0x%08x\n", IfrOneOf->data.u32.Step));
- break;
- case EFI_IFR_NUMERIC_SIZE_8:
- DEBUG ((DEBUG_INFO, " MinValue - 0x%016lx\n", IfrOneOf->data.u64.MinValue));
- DEBUG ((DEBUG_INFO, " MaxValue - 0x%016lx\n", IfrOneOf->data.u64.MaxValue));
- DEBUG ((DEBUG_INFO, " Step - 0x%016lx\n", IfrOneOf->data.u64.Step));
- break;
- }
- }
-
- break;
- case EFI_IFR_CHECKBOX_OP:
- IfrCheckBox = (EFI_IFR_CHECKBOX *)IfrOpCodeHeader;
- DEBUG ((DEBUG_INFO, " Flags - 0x%02x\n", IfrCheckBox->Flags));
- break;
- case EFI_IFR_NUMERIC_OP:
- IfrNumeric = (EFI_IFR_NUMERIC *)IfrOpCodeHeader;
- DEBUG ((DEBUG_INFO, " Flags - 0x%02x\n", IfrNumeric->Flags));
- if (QuestionStoredInBitField) {
- //
- // For Numeric stored in bit field, the MinValue,MaxValue and Step are saved as UINT32 type.
- //
- DEBUG ((DEBUG_INFO, " MinValue - 0x%08x\n", IfrNumeric->data.u32.MinValue));
- DEBUG ((DEBUG_INFO, " MaxValue - 0x%08x\n", IfrNumeric->data.u32.MaxValue));
- DEBUG ((DEBUG_INFO, " Step - 0x%08x\n", IfrNumeric->data.u32.Step));
- } else {
- switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {
- case EFI_IFR_NUMERIC_SIZE_1:
- DEBUG ((DEBUG_INFO, " MinValue - 0x%02x\n", IfrNumeric->data.u8.MinValue));
- DEBUG ((DEBUG_INFO, " MaxValue - 0x%02x\n", IfrNumeric->data.u8.MaxValue));
- DEBUG ((DEBUG_INFO, " Step - 0x%02x\n", IfrNumeric->data.u8.Step));
- break;
- case EFI_IFR_NUMERIC_SIZE_2:
- DEBUG ((DEBUG_INFO, " MinValue - 0x%04x\n", IfrNumeric->data.u16.MinValue));
- DEBUG ((DEBUG_INFO, " MaxValue - 0x%04x\n", IfrNumeric->data.u16.MaxValue));
- DEBUG ((DEBUG_INFO, " Step - 0x%04x\n", IfrNumeric->data.u16.Step));
- break;
- case EFI_IFR_NUMERIC_SIZE_4:
- DEBUG ((DEBUG_INFO, " MinValue - 0x%08x\n", IfrNumeric->data.u32.MinValue));
- DEBUG ((DEBUG_INFO, " MaxValue - 0x%08x\n", IfrNumeric->data.u32.MaxValue));
- DEBUG ((DEBUG_INFO, " Step - 0x%08x\n", IfrNumeric->data.u32.Step));
- break;
- case EFI_IFR_NUMERIC_SIZE_8:
- DEBUG ((DEBUG_INFO, " MinValue - 0x%016lx\n", IfrNumeric->data.u64.MinValue));
- DEBUG ((DEBUG_INFO, " MaxValue - 0x%016lx\n", IfrNumeric->data.u64.MaxValue));
- DEBUG ((DEBUG_INFO, " Step - 0x%016lx\n", IfrNumeric->data.u64.Step));
- break;
- }
- }
-
- break;
- case EFI_IFR_ORDERED_LIST_OP:
- IfrOrderedList = (EFI_IFR_ORDERED_LIST *)IfrOpCodeHeader;
- DEBUG ((DEBUG_INFO, " MaxContainers - 0x%02x\n", IfrOrderedList->MaxContainers));
- DEBUG ((DEBUG_INFO, " Flags - 0x%02x\n", IfrOrderedList->Flags));
- break;
- default:
- break;
- }
-
- if (IfrOpCodeHeader->Scope != 0) {
- UINTN Scope;
- EFI_IFR_ONE_OF_OPTION *IfrOneOfOption;
-
- IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length);
- Scope = 1;
- while (Scope != 0) {
- switch (IfrOpCodeHeader->OpCode) {
- case EFI_IFR_ONE_OF_OPTION_OP:
- IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *)IfrOpCodeHeader;
- DEBUG ((DEBUG_INFO, "!!!! IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", (UINTN)IfrOpCodeHeader->OpCode, IfrOpCodeToStr (IfrOpCodeHeader->OpCode)));
- DEBUG ((DEBUG_INFO, "!!!! IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader->Scope));
- DEBUG ((DEBUG_INFO, "!!!! Option - 0x%04x\n", IfrOneOfOption->Option));
- DEBUG ((DEBUG_INFO, "!!!! Flags - 0x%02x\n", IfrOneOfOption->Flags));
- DEBUG ((DEBUG_INFO, "!!!! Type - 0x%02x\n", IfrOneOfOption->Type));
- switch (IfrOneOfOption->Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- DEBUG ((DEBUG_INFO, "!!!! Value - 0x%02x\n", IfrOneOfOption->Value.u8));
- break;
- case EFI_IFR_TYPE_NUM_SIZE_16:
- DEBUG ((DEBUG_INFO, "!!!! Value - 0x%04x\n", IfrOneOfOption->Value.u16));
- break;
- case EFI_IFR_TYPE_NUM_SIZE_32:
- DEBUG ((DEBUG_INFO, "!!!! Value - 0x%08x\n", IfrOneOfOption->Value.u32));
- break;
- case EFI_IFR_TYPE_NUM_SIZE_64:
- DEBUG ((DEBUG_INFO, "!!!! Value - 0x%016lx\n", IfrOneOfOption->Value.u64));
- break;
- case EFI_IFR_TYPE_BOOLEAN:
- DEBUG ((DEBUG_INFO, "!!!! Value - 0x%02x\n", IfrOneOfOption->Value.b));
- break;
- default:
- break;
- }
-
- break;
- }
-
- if (IfrOpCodeHeader->OpCode == EFI_IFR_END_OP) {
- QuestionStoredInBitField = FALSE;
- ASSERT (Scope > 0);
- Scope--;
- if (Scope == 0) {
- break;
- }
- } else if (IfrOpCodeHeader->Scope != 0) {
- Scope++;
- }
-
- IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length);
- }
- }
- }
- default:
- break;
- }
-
- IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length);
- }
-
- break;
- default:
- break;
- }
-}
-
-/**
- Dump Hii Database.
-
- @param[in] HiiDatabase Pointer to Hii Database.
- @param[in] HiiDatabaseSize Hii Database size.
-
-**/
-VOID
-DumpHiiDatabase (
- IN VOID *HiiDatabase,
- IN UINTN HiiDatabaseSize
- )
-{
- EFI_HII_PACKAGE_LIST_HEADER *HiiPackageListHeader;
- EFI_HII_PACKAGE_HEADER *HiiPackageHeader;
-
- DEBUG ((DEBUG_INFO, "HiiDatabaseSize - 0x%x\n", HiiDatabaseSize));
- HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)HiiDatabase;
-
- while ((UINTN)HiiPackageListHeader < ((UINTN)HiiDatabase + HiiDatabaseSize)) {
- DEBUG ((DEBUG_INFO, "HiiPackageListHeader->PackageListGuid - %g\n", &HiiPackageListHeader->PackageListGuid));
- DEBUG ((DEBUG_INFO, "HiiPackageListHeader->PackageLength - 0x%x\n", (UINTN)HiiPackageListHeader->PackageLength));
- HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)(HiiPackageListHeader + 1);
-
- while ((UINTN)HiiPackageHeader < (UINTN)HiiPackageListHeader + HiiPackageListHeader->PackageLength) {
- DumpHiiPackage (HiiPackageHeader);
-
- HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)((UINTN)HiiPackageHeader + HiiPackageHeader->Length);
- }
-
- HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)((UINTN)HiiPackageListHeader + HiiPackageListHeader->PackageLength);
- }
-
- return;
-}
-
-#endif
-
-/**
- Allocates a buffer of a certain pool type.
-
- Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
- pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
- returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
-
- @param MemoryType The type of memory to allocate.
- @param AllocationSize The number of bytes to allocate.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-InternalVarCheckAllocatePool (
- IN EFI_MEMORY_TYPE MemoryType,
- IN UINTN AllocationSize
- )
-{
- EFI_STATUS Status;
- VOID *Memory;
-
- Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);
- if (EFI_ERROR (Status)) {
- Memory = NULL;
- }
-
- return Memory;
-}
-
-/**
- Allocates and zeros a buffer of type EfiBootServicesData.
-
- Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
- buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
- valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
- request, then NULL is returned.
-
- @param AllocationSize The number of bytes to allocate and zero.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-InternalVarCheckAllocateZeroPool (
- IN UINTN AllocationSize
- )
-{
- VOID *Memory;
-
- Memory = InternalVarCheckAllocatePool (EfiBootServicesData, AllocationSize);
- if (Memory != NULL) {
- Memory = ZeroMem (Memory, AllocationSize);
- }
-
- return Memory;
-}
-
-/**
- Frees a buffer that was previously allocated with one of the pool allocation functions in the
- Memory Allocation Library.
-
- Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
- pool allocation services of the Memory Allocation Library. If it is not possible to free pool
- resources, then this function will perform no actions.
-
- If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
- then ASSERT().
-
- @param Buffer The pointer to the buffer to free.
-
-**/
-VOID
-EFIAPI
-InternalVarCheckFreePool (
- IN VOID *Buffer
- )
-{
- EFI_STATUS Status;
-
- Status = gBS->FreePool (Buffer);
- ASSERT_EFI_ERROR (Status);
-}
-
-/**
- Reallocates a buffer of type EfiBootServicesData.
-
- Allocates and zeros the number bytes specified by NewSize from memory of type
- EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
- NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
- OldBuffer is freed. A pointer to the newly allocated buffer is returned.
- If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
- enough memory remaining to satisfy the request, then NULL is returned.
-
- If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
- is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
-
- @param OldSize The size, in bytes, of OldBuffer.
- @param NewSize The size, in bytes, of the buffer to reallocate.
- @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
- parameter that may be NULL.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-InternalVarCheckReallocatePool (
- IN UINTN OldSize,
- IN UINTN NewSize,
- IN VOID *OldBuffer OPTIONAL
- )
-{
- VOID *NewBuffer;
-
- NewBuffer = InternalVarCheckAllocateZeroPool (NewSize);
- if ((NewBuffer != NULL) && (OldBuffer != NULL)) {
- CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
- InternalVarCheckFreePool (OldBuffer);
- }
-
- return NewBuffer;
-}
-
-/**
- Merge Hii Question.
-
- @param[in, out] HiiVariableNode Pointer to Hii Variable node.
- @param[in] HiiQuestion Pointer to Hii Question.
- @param[in] FromFv Hii Question from FV.
-
-**/
-VOID
-MergeHiiQuestion (
- IN OUT VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode,
- IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion,
- IN BOOLEAN FromFv
- )
-{
- VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion1;
- VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion2;
- VAR_CHECK_HII_QUESTION_HEADER *NewHiiQuestion;
- UINT8 NewLength;
- UINT64 Minimum1;
- UINT64 Maximum1;
- UINT64 OneValue1;
- UINT64 Minimum2;
- UINT64 Maximum2;
- UINT64 OneValue2;
- UINT8 *Ptr;
- UINT8 *Ptr1;
- UINT8 *Ptr2;
- UINTN ArrayIndex;
-
- //
- // Hii Question from Hii Database has high priority.
- // Do not to merge Hii Question from Fv to Hii Question from Hii Database.
- //
- if (FromFv) {
- InternalVarCheckFreePool (HiiQuestion);
- return;
- }
-
- if (HiiQuestion->BitFieldStore) {
- ArrayIndex = HiiQuestion->VarOffset;
- } else {
- ArrayIndex = HiiQuestion->VarOffset * 8;
- }
-
- HiiQuestion1 = HiiVariableNode->HiiQuestionArray[ArrayIndex];
- HiiQuestion2 = HiiQuestion;
-
- ASSERT ((HiiQuestion1->OpCode == HiiQuestion2->OpCode) && (HiiQuestion1->StorageWidth == HiiQuestion2->StorageWidth));
-
- switch (HiiQuestion1->OpCode) {
- case EFI_IFR_ONE_OF_OP:
- DEBUG ((DEBUG_INFO, "MergeHiiQuestion - EFI_IFR_ONE_OF_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1->VarOffset, (HiiQuestion1->BitFieldStore ? "bit level" : "byte level")));
- //
- // Get the length of Hii Question 1.
- //
- NewLength = HiiQuestion1->Length;
-
- //
- // Check if the one of options in Hii Question 2 have been in Hii Question 1.
- //
- Ptr2 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion2 + 1);
- while ((UINTN)Ptr2 < (UINTN)HiiQuestion2 + HiiQuestion2->Length) {
- OneValue2 = 0;
- CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth);
-
- Ptr1 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion1 + 1);
- while ((UINTN)Ptr1 < (UINTN)HiiQuestion1 + HiiQuestion1->Length) {
- OneValue1 = 0;
- CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth);
- if (OneValue2 == OneValue1) {
- //
- // Match
- //
- break;
- }
-
- Ptr1 += HiiQuestion1->StorageWidth;
- }
-
- if ((UINTN)Ptr1 >= ((UINTN)HiiQuestion1 + HiiQuestion1->Length)) {
- //
- // No match
- //
- NewLength = (UINT8)(NewLength + HiiQuestion1->StorageWidth);
- }
-
- Ptr2 += HiiQuestion2->StorageWidth;
- }
-
- if (NewLength > HiiQuestion1->Length) {
- //
- // Merge the one of options of Hii Question 2 and Hii Question 1.
- //
- NewHiiQuestion = InternalVarCheckAllocateZeroPool (NewLength);
- ASSERT (NewHiiQuestion != NULL);
- CopyMem (NewHiiQuestion, HiiQuestion1, HiiQuestion1->Length);
- //
- // Use the new length.
- //
- NewHiiQuestion->Length = NewLength;
- Ptr = (UINT8 *)NewHiiQuestion + HiiQuestion1->Length;
-
- Ptr2 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion2 + 1);
- while ((UINTN)Ptr2 < (UINTN)HiiQuestion2 + HiiQuestion2->Length) {
- OneValue2 = 0;
- CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth);
-
- Ptr1 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion1 + 1);
- while ((UINTN)Ptr1 < (UINTN)HiiQuestion1 + HiiQuestion1->Length) {
- OneValue1 = 0;
- CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth);
- if (OneValue2 == OneValue1) {
- //
- // Match
- //
- break;
- }
-
- Ptr1 += HiiQuestion1->StorageWidth;
- }
-
- if ((UINTN)Ptr1 >= ((UINTN)HiiQuestion1 + HiiQuestion1->Length)) {
- //
- // No match
- //
- CopyMem (Ptr, &OneValue2, HiiQuestion1->StorageWidth);
- Ptr += HiiQuestion1->StorageWidth;
- }
-
- Ptr2 += HiiQuestion2->StorageWidth;
- }
-
- HiiVariableNode->HiiQuestionArray[ArrayIndex] = NewHiiQuestion;
- InternalVarCheckFreePool (HiiQuestion1);
- }
-
- break;
-
- case EFI_IFR_CHECKBOX_OP:
- DEBUG ((DEBUG_INFO, "MergeHiiQuestion - EFI_IFR_CHECKBOX_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1->VarOffset, (HiiQuestion1->BitFieldStore ? "bit level" : "byte level")));
- break;
-
- case EFI_IFR_NUMERIC_OP:
- DEBUG ((DEBUG_INFO, "MergeHiiQuestion - EFI_IFR_NUMERIC_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1->VarOffset, (HiiQuestion1->BitFieldStore ? "bit level" : "byte level")));
- //
- // Get minimum and maximum of Hii Question 1.
- //
- Minimum1 = 0;
- Maximum1 = 0;
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion1 + 1);
- CopyMem (&Minimum1, Ptr, HiiQuestion1->StorageWidth);
- Ptr += HiiQuestion1->StorageWidth;
- CopyMem (&Maximum1, Ptr, HiiQuestion1->StorageWidth);
-
- //
- // Get minimum and maximum of Hii Question 2.
- //
- Minimum2 = 0;
- Maximum2 = 0;
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion2 + 1);
- CopyMem (&Minimum2, Ptr, HiiQuestion2->StorageWidth);
- Ptr += HiiQuestion2->StorageWidth;
- CopyMem (&Maximum2, Ptr, HiiQuestion2->StorageWidth);
-
- //
- // Update minimum.
- //
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion1 + 1);
- if (Minimum2 < Minimum1) {
- Minimum1 = Minimum2;
- CopyMem (Ptr, &Minimum1, HiiQuestion1->StorageWidth);
- }
-
- //
- // Update maximum.
- //
- Ptr += HiiQuestion1->StorageWidth;
- if (Maximum2 > Maximum1) {
- Maximum1 = Maximum2;
- CopyMem (Ptr, &Maximum1, HiiQuestion1->StorageWidth);
- }
-
- break;
-
- case EFI_IFR_ORDERED_LIST_OP:
- DEBUG ((DEBUG_INFO, "MergeHiiQuestion - EFI_IFR_ORDERED_LIST_OP VarOffset = 0x%04x\n", HiiQuestion1->VarOffset));
- //
- // Get the length of Hii Question 1.
- //
- NewLength = HiiQuestion1->Length;
-
- //
- // Check if the one of options in Hii Question 2 have been in Hii Question 1.
- //
- Ptr2 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion2 + 1);
- while ((UINTN)Ptr2 < (UINTN)HiiQuestion2 + HiiQuestion2->Length) {
- OneValue2 = 0;
- CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth);
-
- Ptr1 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion1 + 1);
- while ((UINTN)Ptr1 < (UINTN)HiiQuestion1 + HiiQuestion1->Length) {
- OneValue1 = 0;
- CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth);
- if (OneValue2 == OneValue1) {
- //
- // Match
- //
- break;
- }
-
- Ptr1 += HiiQuestion1->StorageWidth;
- }
-
- if ((UINTN)Ptr1 >= ((UINTN)HiiQuestion1 + HiiQuestion1->Length)) {
- //
- // No match
- //
- NewLength = (UINT8)(NewLength + HiiQuestion1->StorageWidth);
- }
-
- Ptr2 += HiiQuestion2->StorageWidth;
- }
-
- if (NewLength > HiiQuestion1->Length) {
- //
- // Merge the one of options of Hii Question 2 and Hii Question 1.
- //
- NewHiiQuestion = InternalVarCheckAllocateZeroPool (NewLength);
- ASSERT (NewHiiQuestion != NULL);
- CopyMem (NewHiiQuestion, HiiQuestion1, HiiQuestion1->Length);
- //
- // Use the new length.
- //
- NewHiiQuestion->Length = NewLength;
- Ptr = (UINT8 *)NewHiiQuestion + HiiQuestion1->Length;
-
- Ptr2 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion2 + 1);
- while ((UINTN)Ptr2 < (UINTN)HiiQuestion2 + HiiQuestion2->Length) {
- OneValue2 = 0;
- CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth);
-
- Ptr1 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion1 + 1);
- while ((UINTN)Ptr1 < (UINTN)HiiQuestion1 + HiiQuestion1->Length) {
- OneValue1 = 0;
- CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth);
- if (OneValue2 == OneValue1) {
- //
- // Match
- //
- break;
- }
-
- Ptr1 += HiiQuestion1->StorageWidth;
- }
-
- if ((UINTN)Ptr1 >= ((UINTN)HiiQuestion1 + HiiQuestion1->Length)) {
- //
- // No match
- //
- CopyMem (Ptr, &OneValue2, HiiQuestion1->StorageWidth);
- Ptr += HiiQuestion1->StorageWidth;
- }
-
- Ptr2 += HiiQuestion2->StorageWidth;
- }
-
- HiiVariableNode->HiiQuestionArray[ArrayIndex] = NewHiiQuestion;
- InternalVarCheckFreePool (HiiQuestion1);
- }
-
- break;
-
- default:
- ASSERT (FALSE);
- return;
- break;
- }
-
- //
- //
- // Hii Question 2 has been merged with Hii Question 1.
- //
- InternalVarCheckFreePool (HiiQuestion2);
-}
-
-/**
- Get OneOf option data.
-
- @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
- @param[out] Count Pointer to option count.
- @param[out] Width Pointer to option width.
- @param[out] OptionBuffer Pointer to option buffer.
-
-**/
-VOID
-GetOneOfOption (
- IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,
- OUT UINTN *Count,
- OUT UINT8 *Width,
- OUT VOID *OptionBuffer OPTIONAL
- )
-{
- UINTN Scope;
- EFI_IFR_ONE_OF_OPTION *IfrOneOfOption;
-
- //
- // Assume all OPTION has same Width.
- //
- *Count = 0;
-
- if (IfrOpCodeHeader->Scope != 0) {
- //
- // Nested OpCode.
- //
- Scope = 1;
- IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length);
- while (Scope != 0) {
- switch (IfrOpCodeHeader->OpCode) {
- case EFI_IFR_ONE_OF_OPTION_OP:
- IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *)IfrOpCodeHeader;
- switch (IfrOneOfOption->Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- *Count = *Count + 1;
- *Width = sizeof (UINT8);
- if (OptionBuffer != NULL) {
- CopyMem (OptionBuffer, &IfrOneOfOption->Value.u8, sizeof (UINT8));
- OptionBuffer = (UINT8 *)OptionBuffer + 1;
- }
-
- break;
- case EFI_IFR_TYPE_NUM_SIZE_16:
- *Count = *Count + 1;
- *Width = sizeof (UINT16);
- if (OptionBuffer != NULL) {
- CopyMem (OptionBuffer, &IfrOneOfOption->Value.u16, sizeof (UINT16));
- OptionBuffer = (UINT16 *)OptionBuffer + 1;
- }
-
- break;
- case EFI_IFR_TYPE_NUM_SIZE_32:
- *Count = *Count + 1;
- *Width = sizeof (UINT32);
- if (OptionBuffer != NULL) {
- CopyMem (OptionBuffer, &IfrOneOfOption->Value.u32, sizeof (UINT32));
- OptionBuffer = (UINT32 *)OptionBuffer + 1;
- }
-
- break;
- case EFI_IFR_TYPE_NUM_SIZE_64:
- *Count = *Count + 1;
- *Width = sizeof (UINT64);
- if (OptionBuffer != NULL) {
- CopyMem (OptionBuffer, &IfrOneOfOption->Value.u64, sizeof (UINT64));
- OptionBuffer = (UINT64 *)OptionBuffer + 1;
- }
-
- break;
- case EFI_IFR_TYPE_BOOLEAN:
- *Count = *Count + 1;
- *Width = sizeof (BOOLEAN);
- if (OptionBuffer != NULL) {
- CopyMem (OptionBuffer, &IfrOneOfOption->Value.b, sizeof (BOOLEAN));
- OptionBuffer = (BOOLEAN *)OptionBuffer + 1;
- }
-
- break;
- default:
- break;
- }
-
- break;
- }
-
- //
- // Until End OpCode.
- //
- if (IfrOpCodeHeader->OpCode == EFI_IFR_END_OP) {
- ASSERT (Scope > 0);
- Scope--;
- if (Scope == 0) {
- break;
- }
- } else if (IfrOpCodeHeader->Scope != 0) {
- //
- // Nested OpCode.
- //
- Scope++;
- }
-
- IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length);
- }
- }
-
- return;
-}
-
-/**
- Parse Hii Question Oneof.
-
- @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
- @param[in] StoredInBitField Whether the OneOf is stored in bit field Storage.
-
- return Pointer to Hii Question.
-
-**/
-VAR_CHECK_HII_QUESTION_HEADER *
-ParseHiiQuestionOneOf (
- IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,
- IN BOOLEAN StoredInBitField
- )
-{
- EFI_IFR_ONE_OF *IfrOneOf;
- VAR_CHECK_HII_QUESTION_ONEOF *OneOf;
- UINTN Length;
- UINT8 Width;
- UINTN OptionCount;
- UINT8 OptionWidth;
- UINT8 BitWidth;
-
- IfrOneOf = (EFI_IFR_ONE_OF *)IfrOpCodeHeader;
- BitWidth = 0;
-
- if (StoredInBitField) {
- //
- // When OneOf stored in bit field, the bit width is saved in the lower six bits of the flag.
- // And the options in the OneOf is saved as UINT32 type.
- //
- BitWidth = IfrOneOf->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;
- Width = sizeof (UINT32);
- } else {
- Width = (UINT8)(1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));
- }
-
- GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, NULL);
- ASSERT (Width == OptionWidth);
-
- Length = sizeof (*OneOf) + OptionCount * Width;
-
- OneOf = InternalVarCheckAllocateZeroPool (Length);
- ASSERT (OneOf != NULL);
- OneOf->OpCode = EFI_IFR_ONE_OF_OP;
- OneOf->Length = (UINT8)Length;
- OneOf->VarOffset = IfrOneOf->Question.VarStoreInfo.VarOffset;
- OneOf->BitFieldStore = StoredInBitField;
- if (StoredInBitField) {
- OneOf->StorageWidth = BitWidth;
- } else {
- OneOf->StorageWidth = Width;
- }
-
- GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, OneOf + 1);
-
- return (VAR_CHECK_HII_QUESTION_HEADER *)OneOf;
-}
-
-/**
- Parse Hii Question CheckBox.
-
- @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
- @param[in] StoredInBitField Whether the CheckBox is stored in bit field Storage.
-
- return Pointer to Hii Question.
-
-**/
-VAR_CHECK_HII_QUESTION_HEADER *
-ParseHiiQuestionCheckBox (
- IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,
- IN BOOLEAN StoredInBitField
- )
-{
- EFI_IFR_CHECKBOX *IfrCheckBox;
- VAR_CHECK_HII_QUESTION_CHECKBOX *CheckBox;
-
- IfrCheckBox = (EFI_IFR_CHECKBOX *)IfrOpCodeHeader;
-
- CheckBox = InternalVarCheckAllocateZeroPool (sizeof (*CheckBox));
- ASSERT (CheckBox != NULL);
- CheckBox->OpCode = EFI_IFR_CHECKBOX_OP;
- CheckBox->Length = (UINT8)sizeof (*CheckBox);
- CheckBox->VarOffset = IfrCheckBox->Question.VarStoreInfo.VarOffset;
- CheckBox->BitFieldStore = StoredInBitField;
- if (StoredInBitField) {
- CheckBox->StorageWidth = 1;
- } else {
- CheckBox->StorageWidth = (UINT8)sizeof (BOOLEAN);
- }
-
- return (VAR_CHECK_HII_QUESTION_HEADER *)CheckBox;
-}
-
-/**
- Parse Hii Question Numeric.
-
- @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
- @param[in] StoredInBitField Whether the Numeric is stored in bit field Storage.
-
- return Pointer to Hii Question.
-
-**/
-VAR_CHECK_HII_QUESTION_HEADER *
-ParseHiiQuestionNumeric (
- IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,
- IN BOOLEAN StoredInBitField
- )
-{
- EFI_IFR_NUMERIC *IfrNumeric;
- VAR_CHECK_HII_QUESTION_NUMERIC *Numeric;
- UINT8 Width;
- UINT8 BitWidth;
-
- IfrNumeric = (EFI_IFR_NUMERIC *)IfrOpCodeHeader;
- BitWidth = 0;
-
- Numeric = InternalVarCheckAllocateZeroPool (sizeof (VAR_CHECK_HII_QUESTION_NUMERIC) + 2 * sizeof (UINT64));
- ASSERT (Numeric != NULL);
-
- if (StoredInBitField) {
- //
- // When Numeric stored in bit field, the bit field width is saved in the lower six bits of the flag.
- // And the Minimum Maximum of Numeric is saved as UINT32 type.
- //
- BitWidth = IfrNumeric->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;
- Width = sizeof (UINT32);
- } else {
- Width = (UINT8)(1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE));
- }
-
- Numeric->OpCode = EFI_IFR_NUMERIC_OP;
- Numeric->Length = (UINT8)(sizeof (VAR_CHECK_HII_QUESTION_NUMERIC) + 2 * Width);
- Numeric->VarOffset = IfrNumeric->Question.VarStoreInfo.VarOffset;
- Numeric->BitFieldStore = StoredInBitField;
- if (StoredInBitField) {
- Numeric->StorageWidth = BitWidth;
- } else {
- Numeric->StorageWidth = Width;
- }
-
- CopyMem (Numeric + 1, &IfrNumeric->data, Width * 2);
-
- return (VAR_CHECK_HII_QUESTION_HEADER *)Numeric;
-}
-
-/**
- Parse Hii Question OrderedList.
-
- @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
-
- return Pointer to Hii Question.
-
-**/
-VAR_CHECK_HII_QUESTION_HEADER *
-ParseHiiQuestionOrderedList (
- IN EFI_IFR_OP_HEADER *IfrOpCodeHeader
- )
-{
- EFI_IFR_ORDERED_LIST *IfrOrderedList;
- VAR_CHECK_HII_QUESTION_ORDEREDLIST *OrderedList;
- UINTN Length;
- UINTN OptionCount;
- UINT8 OptionWidth;
-
- IfrOrderedList = (EFI_IFR_ORDERED_LIST *)IfrOpCodeHeader;
-
- GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, NULL);
-
- Length = sizeof (*OrderedList) + OptionCount * OptionWidth;
-
- OrderedList = InternalVarCheckAllocateZeroPool (Length);
- ASSERT (OrderedList != NULL);
- OrderedList->OpCode = EFI_IFR_ORDERED_LIST_OP;
- OrderedList->Length = (UINT8)Length;
- OrderedList->VarOffset = IfrOrderedList->Question.VarStoreInfo.VarOffset;
- OrderedList->StorageWidth = OptionWidth;
- OrderedList->MaxContainers = IfrOrderedList->MaxContainers;
- OrderedList->BitFieldStore = FALSE;
-
- GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, OrderedList + 1);
-
- return (VAR_CHECK_HII_QUESTION_HEADER *)OrderedList;
-}
-
-/**
- Parse and create Hii Question node.
-
- @param[in] HiiVariableNode Pointer to Hii Variable node.
- @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
- @param[in] FromFv Hii Question from FV.
- @param[in] StoredInBitField Whether the Question is stored in bit field Storage.
-
-**/
-VOID
-ParseHiiQuestion (
- IN VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode,
- IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,
- IN BOOLEAN FromFv,
- IN BOOLEAN StoredInBitField
- )
-{
- VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;
- UINTN ArrayIndex;
-
- //
- // Currently only OneOf, CheckBox and Numeric can be stored in bit field.
- //
- switch (IfrOpCodeHeader->OpCode) {
- case EFI_IFR_ONE_OF_OP:
- HiiQuestion = ParseHiiQuestionOneOf (IfrOpCodeHeader, StoredInBitField);
- break;
-
- case EFI_IFR_CHECKBOX_OP:
- HiiQuestion = ParseHiiQuestionCheckBox (IfrOpCodeHeader, StoredInBitField);
- break;
-
- case EFI_IFR_NUMERIC_OP:
- HiiQuestion = ParseHiiQuestionNumeric (IfrOpCodeHeader, StoredInBitField);
- break;
-
- case EFI_IFR_ORDERED_LIST_OP:
- HiiQuestion = ParseHiiQuestionOrderedList (IfrOpCodeHeader);
- break;
-
- default:
- ASSERT (FALSE);
- return;
- break;
- }
-
- if (StoredInBitField) {
- ArrayIndex = HiiQuestion->VarOffset;
- } else {
- ArrayIndex = HiiQuestion->VarOffset * 8;
- }
-
- if (HiiVariableNode->HiiQuestionArray[ArrayIndex] != NULL) {
- MergeHiiQuestion (HiiVariableNode, HiiQuestion, FromFv);
- } else {
- HiiVariableNode->HiiQuestionArray[ArrayIndex] = HiiQuestion;
- }
-}
-
-/**
- Find Hii variable node by name and GUID.
-
- @param[in] Name Pointer to variable name.
- @param[in] Guid Pointer to vendor GUID.
-
- @return Pointer to Hii Variable node.
-
-**/
-VAR_CHECK_HII_VARIABLE_NODE *
-FindHiiVariableNode (
- IN CHAR16 *Name,
- IN EFI_GUID *Guid
- )
-{
- VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
- LIST_ENTRY *Link;
-
- for (Link = mVarCheckHiiList.ForwardLink
- ; Link != &mVarCheckHiiList
- ; Link = Link->ForwardLink)
- {
- HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (Link);
-
- if ((StrCmp (Name, (CHAR16 *)(HiiVariableNode->HiiVariable + 1)) == 0) &&
- CompareGuid (Guid, &HiiVariableNode->HiiVariable->Guid))
- {
- return HiiVariableNode;
- }
- }
-
- return NULL;
-}
-
-/**
- Find Hii variable node by var store id.
-
- @param[in] VarStoreId Var store id.
-
- @return Pointer to Hii Variable node.
-
-**/
-VAR_CHECK_HII_VARIABLE_NODE *
-FindHiiVariableNodeByVarStoreId (
- IN EFI_VARSTORE_ID VarStoreId
- )
-{
- VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
- LIST_ENTRY *Link;
-
- if (VarStoreId == 0) {
- //
- // The variable store identifier, which is unique within the current form set.
- // A value of zero is invalid.
- //
- return NULL;
- }
-
- for (Link = mVarCheckHiiList.ForwardLink
- ; Link != &mVarCheckHiiList
- ; Link = Link->ForwardLink)
- {
- HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (Link);
- //
- // The variable store identifier, which is unique within the current form set.
- //
- if (VarStoreId == HiiVariableNode->VarStoreId) {
- return HiiVariableNode;
- }
- }
-
- return NULL;
-}
-
-/**
- Destroy var store id in the Hii Variable node after parsing one Hii Package.
-
-**/
-VOID
-DestroyVarStoreId (
- VOID
- )
-{
- VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
- LIST_ENTRY *Link;
-
- for (Link = mVarCheckHiiList.ForwardLink
- ; Link != &mVarCheckHiiList
- ; Link = Link->ForwardLink)
- {
- HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (Link);
- //
- // The variable store identifier, which is unique within the current form set.
- // A value of zero is invalid.
- //
- HiiVariableNode->VarStoreId = 0;
- }
-}
-
-/**
- Create Hii Variable node.
-
- @param[in] IfrEfiVarStore Pointer to EFI VARSTORE.
-
-**/
-VOID
-CreateHiiVariableNode (
- IN EFI_IFR_VARSTORE_EFI *IfrEfiVarStore
- )
-{
- VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
- VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;
- UINTN HeaderLength;
- CHAR16 *VarName;
- UINTN VarNameSize;
-
- //
- // Get variable name.
- //
- VarNameSize = AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16);
- if (VarNameSize > mMaxVarNameSize) {
- mVarName = InternalVarCheckReallocatePool (mMaxVarNameSize, VarNameSize, mVarName);
- ASSERT (mVarName != NULL);
- mMaxVarNameSize = VarNameSize;
- }
-
- AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, mVarName, mMaxVarNameSize / sizeof (CHAR16));
- VarName = mVarName;
-
- HiiVariableNode = FindHiiVariableNode (
- VarName,
- &IfrEfiVarStore->Guid
- );
- if (HiiVariableNode == NULL) {
- //
- // Not found, then create new.
- //
- HeaderLength = sizeof (*HiiVariable) + VarNameSize;
- HiiVariable = InternalVarCheckAllocateZeroPool (HeaderLength);
- ASSERT (HiiVariable != NULL);
- HiiVariable->Revision = VAR_CHECK_HII_REVISION;
- HiiVariable->OpCode = EFI_IFR_VARSTORE_EFI_OP;
- HiiVariable->HeaderLength = (UINT16)HeaderLength;
- HiiVariable->Size = IfrEfiVarStore->Size;
- HiiVariable->Attributes = IfrEfiVarStore->Attributes;
- CopyGuid (&HiiVariable->Guid, &IfrEfiVarStore->Guid);
- StrCpyS ((CHAR16 *)(HiiVariable + 1), VarNameSize / sizeof (CHAR16), VarName);
-
- HiiVariableNode = InternalVarCheckAllocateZeroPool (sizeof (*HiiVariableNode));
- ASSERT (HiiVariableNode != NULL);
- HiiVariableNode->Signature = VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE;
- HiiVariableNode->HiiVariable = HiiVariable;
- //
- // The variable store identifier, which is unique within the current form set.
- //
- HiiVariableNode->VarStoreId = IfrEfiVarStore->VarStoreId;
- HiiVariableNode->HiiQuestionArray = InternalVarCheckAllocateZeroPool (IfrEfiVarStore->Size * 8 * sizeof (VAR_CHECK_HII_QUESTION_HEADER *));
-
- InsertTailList (&mVarCheckHiiList, &HiiVariableNode->Link);
- } else {
- HiiVariableNode->VarStoreId = IfrEfiVarStore->VarStoreId;
- }
-}
-
-/**
- Parse and create Hii Variable node list.
-
- @param[in] HiiPackage Pointer to Hii Package.
-
-**/
-VOID
-ParseHiiVariable (
- IN VOID *HiiPackage
- )
-{
- EFI_HII_PACKAGE_HEADER *HiiPackageHeader;
- EFI_IFR_OP_HEADER *IfrOpCodeHeader;
- EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;
-
- HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiPackage;
-
- switch (HiiPackageHeader->Type) {
- case EFI_HII_PACKAGE_FORMS:
- IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)(HiiPackageHeader + 1);
-
- while ((UINTN)IfrOpCodeHeader < (UINTN)HiiPackageHeader + HiiPackageHeader->Length) {
- switch (IfrOpCodeHeader->OpCode) {
- case EFI_IFR_VARSTORE_EFI_OP:
- //
- // Come to EFI VARSTORE in Form Package.
- //
- IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpCodeHeader;
- if ((IfrEfiVarStore->Header.Length >= sizeof (EFI_IFR_VARSTORE_EFI)) &&
- ((IfrEfiVarStore->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0))
- {
- //
- // Only create node list for Hii Variable with NV attribute.
- //
- CreateHiiVariableNode (IfrEfiVarStore);
- }
-
- break;
-
- default:
- break;
- }
-
- IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length);
- }
-
- break;
-
- default:
- break;
- }
-}
-
-/**
- Var Check Parse Hii Package.
-
- @param[in] HiiPackage Pointer to Hii Package.
- @param[in] FromFv Hii Package from FV.
-
-**/
-VOID
-VarCheckParseHiiPackage (
- IN VOID *HiiPackage,
- IN BOOLEAN FromFv
- )
-{
- EFI_HII_PACKAGE_HEADER *HiiPackageHeader;
- EFI_IFR_OP_HEADER *IfrOpCodeHeader;
- VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
- BOOLEAN QuestionStoredInBitField;
-
- //
- // Parse and create Hii Variable node list for this Hii Package.
- //
- ParseHiiVariable (HiiPackage);
-
- HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiPackage;
-
- QuestionStoredInBitField = FALSE;
-
- switch (HiiPackageHeader->Type) {
- case EFI_HII_PACKAGE_FORMS:
- IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)(HiiPackageHeader + 1);
-
- while ((UINTN)IfrOpCodeHeader < (UINTN)HiiPackageHeader + HiiPackageHeader->Length) {
- switch (IfrOpCodeHeader->OpCode) {
- case EFI_IFR_GUID_OP:
- if (CompareGuid ((EFI_GUID *)((UINTN)IfrOpCodeHeader + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {
- QuestionStoredInBitField = TRUE;
- }
-
- break;
-
- case EFI_IFR_END_OP:
- QuestionStoredInBitField = FALSE;
- break;
-
- case EFI_IFR_ONE_OF_OP:
- case EFI_IFR_CHECKBOX_OP:
- case EFI_IFR_NUMERIC_OP:
- case EFI_IFR_ORDERED_LIST_OP:
- HiiVariableNode = FindHiiVariableNodeByVarStoreId (((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.VarStoreId);
- if ((HiiVariableNode == NULL) ||
- //
- // No related Hii Variable node found.
- //
- ((((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.Header.Prompt == 0) && (((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.Header.Help == 0)))
- {
- //
- // meanless IFR item introduced by ECP.
- //
- } else {
- //
- // Normal IFR
- //
- ParseHiiQuestion (HiiVariableNode, IfrOpCodeHeader, FromFv, QuestionStoredInBitField);
- }
-
- default:
- break;
- }
-
- IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length);
- }
-
- break;
-
- default:
- break;
- }
-
- DestroyVarStoreId ();
-}
-
-/**
- Var Check Parse Hii Database.
-
- @param[in] HiiDatabase Pointer to Hii Database.
- @param[in] HiiDatabaseSize Hii Database size.
-
-**/
-VOID
-VarCheckParseHiiDatabase (
- IN VOID *HiiDatabase,
- IN UINTN HiiDatabaseSize
- )
-{
- EFI_HII_PACKAGE_LIST_HEADER *HiiPackageListHeader;
- EFI_HII_PACKAGE_HEADER *HiiPackageHeader;
-
- HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)HiiDatabase;
-
- while ((UINTN)HiiPackageListHeader < ((UINTN)HiiDatabase + HiiDatabaseSize)) {
- HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)(HiiPackageListHeader + 1);
-
- while ((UINTN)HiiPackageHeader < ((UINTN)HiiPackageListHeader + HiiPackageListHeader->PackageLength)) {
- //
- // Parse Hii Package.
- //
- VarCheckParseHiiPackage (HiiPackageHeader, FALSE);
-
- HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)((UINTN)HiiPackageHeader + HiiPackageHeader->Length);
- }
-
- HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)((UINTN)HiiPackageListHeader + HiiPackageListHeader->PackageLength);
- }
-}
-
-/**
- Destroy Hii Variable node.
-
-**/
-VOID
-DestroyHiiVariableNode (
- VOID
- )
-{
- VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
- LIST_ENTRY *HiiVariableLink;
- UINTN Index;
-
- while (mVarCheckHiiList.ForwardLink != &mVarCheckHiiList) {
- HiiVariableLink = mVarCheckHiiList.ForwardLink;
- HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink);
-
- RemoveEntryList (&HiiVariableNode->Link);
-
- //
- // Free the allocated buffer.
- //
- for (Index = 0; Index < HiiVariableNode->HiiVariable->Size * (UINTN)8; Index++) {
- if (HiiVariableNode->HiiQuestionArray[Index] != NULL) {
- InternalVarCheckFreePool (HiiVariableNode->HiiQuestionArray[Index]);
- }
- }
-
- InternalVarCheckFreePool (HiiVariableNode->HiiQuestionArray);
- InternalVarCheckFreePool (HiiVariableNode->HiiVariable);
- InternalVarCheckFreePool (HiiVariableNode);
- }
-}
-
-/**
- Build VarCheckHiiBin.
-
- @param[out] Size Pointer to VarCheckHii size.
-
- @return Pointer to VarCheckHiiBin.
-
-**/
-VOID *
-BuildVarCheckHiiBin (
- OUT UINTN *Size
- )
-{
- VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
- LIST_ENTRY *HiiVariableLink;
- UINTN Index;
- VOID *Data;
- UINT8 *Ptr;
- UINT32 BinSize;
- UINT32 HiiVariableLength;
-
- //
- // Get Size
- //
- BinSize = 0;
-
- for (HiiVariableLink = mVarCheckHiiList.ForwardLink
- ; HiiVariableLink != &mVarCheckHiiList
- ; HiiVariableLink = HiiVariableLink->ForwardLink)
- {
- //
- // For Hii Variable header align.
- //
- BinSize = (UINT32)HEADER_ALIGN (BinSize);
-
- HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink);
- HiiVariableLength = HiiVariableNode->HiiVariable->HeaderLength;
-
- for (Index = 0; Index < HiiVariableNode->HiiVariable->Size * (UINTN)8; Index++) {
- if (HiiVariableNode->HiiQuestionArray[Index] != NULL) {
- //
- // For Hii Question header align.
- //
- HiiVariableLength = (UINT32)HEADER_ALIGN (HiiVariableLength);
- HiiVariableLength += HiiVariableNode->HiiQuestionArray[Index]->Length;
- }
- }
-
- HiiVariableNode->HiiVariable->Length = HiiVariableLength;
- BinSize += HiiVariableLength;
- }
-
- DEBUG ((DEBUG_INFO, "VarCheckHiiBin - size = 0x%x\n", BinSize));
- if (BinSize == 0) {
- *Size = BinSize;
- return NULL;
- }
-
- //
- // AllocatePages () and AllocatePool () from gBS are used for the process of VarCheckHiiBin generation.
- // Only here AllocateRuntimeZeroPool () from MemoryAllocateLib is used for runtime access
- // in SetVariable check handler.
- //
- Data = AllocateRuntimeZeroPool (BinSize);
- ASSERT (Data != NULL);
- //
- // Make sure the allocated buffer for VarCheckHiiBin at required alignment.
- //
- ASSERT ((((UINTN)Data) & (HEADER_ALIGNMENT - 1)) == 0);
- DEBUG ((DEBUG_INFO, "VarCheckHiiBin - built at 0x%x\n", Data));
-
- //
- // Gen Data
- //
- Ptr = Data;
- for (HiiVariableLink = mVarCheckHiiList.ForwardLink
- ; HiiVariableLink != &mVarCheckHiiList
- ; HiiVariableLink = HiiVariableLink->ForwardLink)
- {
- //
- // For Hii Variable header align.
- //
- Ptr = (UINT8 *)HEADER_ALIGN (Ptr);
-
- HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink);
- CopyMem (Ptr, HiiVariableNode->HiiVariable, HiiVariableNode->HiiVariable->HeaderLength);
- Ptr += HiiVariableNode->HiiVariable->HeaderLength;
-
- for (Index = 0; Index < HiiVariableNode->HiiVariable->Size * (UINTN)8; Index++) {
- if (HiiVariableNode->HiiQuestionArray[Index] != NULL) {
- //
- // For Hii Question header align.
- //
- Ptr = (UINT8 *)HEADER_ALIGN (Ptr);
- CopyMem (Ptr, HiiVariableNode->HiiQuestionArray[Index], HiiVariableNode->HiiQuestionArray[Index]->Length);
- Ptr += HiiVariableNode->HiiQuestionArray[Index]->Length;
- }
- }
- }
-
- *Size = BinSize;
- return Data;
-}
-
-/**
- Generate VarCheckHiiBin from Hii Database and FV.
-
-**/
-VOID
-EFIAPI
-VarCheckHiiGen (
- VOID
- )
-{
- VarCheckHiiGenFromHiiDatabase ();
- VarCheckHiiGenFromFv ();
-
- mVarCheckHiiBin = BuildVarCheckHiiBin (&mVarCheckHiiBinSize);
- if (mVarCheckHiiBin == NULL) {
- DEBUG ((DEBUG_INFO, "[VarCheckHii] This driver could be removed from *.dsc and *.fdf\n"));
- return;
- }
-
- DestroyHiiVariableNode ();
- if (mVarName != NULL) {
- InternalVarCheckFreePool (mVarName);
- }
-
- #ifdef DUMP_VAR_CHECK_HII
- DEBUG_CODE (
- DumpVarCheckHii (mVarCheckHiiBin, mVarCheckHiiBinSize);
- );
- #endif
-}
+/** @file + Var Check Hii bin generation. + +Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "VarCheckHiiGen.h" + +LIST_ENTRY mVarCheckHiiList = INITIALIZE_LIST_HEAD_VARIABLE (mVarCheckHiiList); + +#define VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE SIGNATURE_32 ('V', 'C', 'H', 'V') + +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable; + EFI_VARSTORE_ID VarStoreId; + + VAR_CHECK_HII_QUESTION_HEADER **HiiQuestionArray; +} VAR_CHECK_HII_VARIABLE_NODE; + +#define VAR_CHECK_HII_VARIABLE_FROM_LINK(a) CR (a, VAR_CHECK_HII_VARIABLE_NODE, Link, VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE) + +CHAR16 *mVarName = NULL; +UINTN mMaxVarNameSize = 0; + +#ifdef DUMP_HII_DATA +GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_OPCODE_STRING mIfrOpCodeStringTable[] = { + { EFI_IFR_VARSTORE_OP, "EFI_IFR_VARSTORE_OP" }, + { EFI_IFR_VARSTORE_EFI_OP, "EFI_IFR_VARSTORE_EFI_OP" }, + { EFI_IFR_ONE_OF_OP, "EFI_IFR_ONE_OF_OP" }, + { EFI_IFR_CHECKBOX_OP, "EFI_IFR_CHECKBOX_OP" }, + { EFI_IFR_NUMERIC_OP, "EFI_IFR_NUMERIC_OP" }, + { EFI_IFR_ORDERED_LIST_OP, "EFI_IFR_ORDERED_LIST_OP" }, + { EFI_IFR_ONE_OF_OPTION_OP, "EFI_IFR_ONE_OF_OPTION_OP" }, +}; + +/** + Ifr opcode to string. + + @param[in] IfrOpCode Ifr OpCode. + + @return Pointer to string. + +**/ +CHAR8 * +IfrOpCodeToStr ( + IN UINT8 IfrOpCode + ) +{ + UINTN Index; + + for (Index = 0; Index < ARRAY_SIZE (mIfrOpCodeStringTable); Index++) { + if (mIfrOpCodeStringTable[Index].HiiOpCode == IfrOpCode) { + return mIfrOpCodeStringTable[Index].HiiOpCodeStr; + } + } + + return "<UnknownIfrOpCode>"; +} + +GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_PACKAGE_TYPE_STRING mPackageTypeStringTable[] = { + { EFI_HII_PACKAGE_TYPE_ALL, "EFI_HII_PACKAGE_TYPE_ALL" }, + { EFI_HII_PACKAGE_TYPE_GUID, "EFI_HII_PACKAGE_TYPE_GUID" }, + { EFI_HII_PACKAGE_FORMS, "EFI_HII_PACKAGE_FORMS" }, + { EFI_HII_PACKAGE_STRINGS, "EFI_HII_PACKAGE_STRINGS" }, + { EFI_HII_PACKAGE_FONTS, "EFI_HII_PACKAGE_FONTS" }, + { EFI_HII_PACKAGE_IMAGES, "EFI_HII_PACKAGE_IMAGES" }, + { EFI_HII_PACKAGE_SIMPLE_FONTS, "EFI_HII_PACKAGE_SIMPLE_FONTS" }, + { EFI_HII_PACKAGE_DEVICE_PATH, "EFI_HII_PACKAGE_DEVICE_PATH" }, + { EFI_HII_PACKAGE_KEYBOARD_LAYOUT, "EFI_HII_PACKAGE_KEYBOARD_LAYOUT" }, + { EFI_HII_PACKAGE_ANIMATIONS, "EFI_HII_PACKAGE_ANIMATIONS" }, + { EFI_HII_PACKAGE_END, "EFI_HII_PACKAGE_END" }, + { EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN, "EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN" }, + { EFI_HII_PACKAGE_TYPE_SYSTEM_END, "EFI_HII_PACKAGE_TYPE_SYSTEM_END" }, +}; + +/** + Hii Package type to string. + + @param[in] PackageType Package Type + + @return Pointer to string. + +**/ +CHAR8 * +HiiPackageTypeToStr ( + IN UINT8 PackageType + ) +{ + UINTN Index; + + for (Index = 0; Index < ARRAY_SIZE (mPackageTypeStringTable); Index++) { + if (mPackageTypeStringTable[Index].PackageType == PackageType) { + return mPackageTypeStringTable[Index].PackageTypeStr; + } + } + + return "<UnknownPackageType>"; +} + +/** + Dump Hii Package. + + @param[in] HiiPackage Pointer to Hii Package. + +**/ +VOID +DumpHiiPackage ( + IN VOID *HiiPackage + ) +{ + EFI_HII_PACKAGE_HEADER *HiiPackageHeader; + EFI_IFR_OP_HEADER *IfrOpCodeHeader; + EFI_IFR_VARSTORE *IfrVarStore; + EFI_IFR_VARSTORE_EFI *IfrEfiVarStore; + BOOLEAN QuestionStoredInBitField; + + HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiPackage; + QuestionStoredInBitField = FALSE; + + DEBUG ((DEBUG_INFO, " HiiPackageHeader->Type - 0x%02x (%a)\n", HiiPackageHeader->Type, HiiPackageTypeToStr ((UINT8)HiiPackageHeader->Type))); + DEBUG ((DEBUG_INFO, " HiiPackageHeader->Length - 0x%06x\n", HiiPackageHeader->Length)); + + switch (HiiPackageHeader->Type) { + case EFI_HII_PACKAGE_FORMS: + IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)(HiiPackageHeader + 1); + + while ((UINTN)IfrOpCodeHeader < ((UINTN)HiiPackageHeader + HiiPackageHeader->Length)) { + switch (IfrOpCodeHeader->OpCode) { + case EFI_IFR_VARSTORE_OP: + IfrVarStore = (EFI_IFR_VARSTORE *)IfrOpCodeHeader; + DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", IfrOpCodeHeader->OpCode, IfrOpCodeToStr (IfrOpCodeHeader->OpCode))); + DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader->Length)); + DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader->Scope)); + DEBUG ((DEBUG_INFO, " Guid - %g\n", &IfrVarStore->Guid)); + DEBUG ((DEBUG_INFO, " VarStoreId - 0x%04x\n", IfrVarStore->VarStoreId)); + DEBUG ((DEBUG_INFO, " Size - 0x%04x\n", IfrVarStore->Size)); + DEBUG ((DEBUG_INFO, " Name - %a\n", IfrVarStore->Name)); + break; + + case EFI_IFR_VARSTORE_EFI_OP: + IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpCodeHeader; + if (IfrEfiVarStore->Header.Length >= sizeof (EFI_IFR_VARSTORE_EFI)) { + DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", IfrOpCodeHeader->OpCode, IfrOpCodeToStr (IfrOpCodeHeader->OpCode))); + DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader->Length)); + DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader->Scope)); + DEBUG ((DEBUG_INFO, " Guid - %g\n", &IfrEfiVarStore->Guid)); + DEBUG ((DEBUG_INFO, " VarStoreId - 0x%04x\n", IfrEfiVarStore->VarStoreId)); + DEBUG ((DEBUG_INFO, " Size - 0x%04x\n", IfrEfiVarStore->Size)); + DEBUG ((DEBUG_INFO, " Attributes - 0x%08x\n", IfrEfiVarStore->Attributes)); + DEBUG ((DEBUG_INFO, " Name - %a\n", IfrEfiVarStore->Name)); + } + + break; + + case EFI_IFR_GUID_OP: + if (CompareGuid ((EFI_GUID *)((UINTN)IfrOpCodeHeader + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) { + QuestionStoredInBitField = TRUE; + } + + break; + + case EFI_IFR_ONE_OF_OP: + case EFI_IFR_CHECKBOX_OP: + case EFI_IFR_NUMERIC_OP: + case EFI_IFR_ORDERED_LIST_OP: + DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->OpCode - 0x%02x (%a) (%a)\n", IfrOpCodeHeader->OpCode, IfrOpCodeToStr (IfrOpCodeHeader->OpCode), (QuestionStoredInBitField ? "bit level" : "byte level"))); + DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader->Length)); + DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader->Scope)); + DEBUG ((DEBUG_INFO, " Prompt - 0x%04x\n", ((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.Header.Prompt)); + DEBUG ((DEBUG_INFO, " Help - 0x%04x\n", ((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.Header.Help)); + DEBUG ((DEBUG_INFO, " QuestionId - 0x%04x\n", ((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.QuestionId)); + DEBUG ((DEBUG_INFO, " VarStoreId - 0x%04x\n", ((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.VarStoreId)); + DEBUG ((DEBUG_INFO, " VarStoreInfo - 0x%04x (%a)\n", ((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.VarStoreInfo.VarOffset, (QuestionStoredInBitField ? "bit level" : "byte level"))); + { + EFI_IFR_ONE_OF *IfrOneOf; + EFI_IFR_CHECKBOX *IfrCheckBox; + EFI_IFR_NUMERIC *IfrNumeric; + EFI_IFR_ORDERED_LIST *IfrOrderedList; + + switch (IfrOpCodeHeader->OpCode) { + case EFI_IFR_ONE_OF_OP: + IfrOneOf = (EFI_IFR_ONE_OF *)IfrOpCodeHeader; + DEBUG ((DEBUG_INFO, " Flags - 0x%02x\n", IfrOneOf->Flags)); + if (QuestionStoredInBitField) { + // + // For OneOf stored in bit field, the option value are saved as UINT32 type. + // + DEBUG ((DEBUG_INFO, " MinValue - 0x%08x\n", IfrOneOf->data.u32.MinValue)); + DEBUG ((DEBUG_INFO, " MaxValue - 0x%08x\n", IfrOneOf->data.u32.MaxValue)); + DEBUG ((DEBUG_INFO, " Step - 0x%08x\n", IfrOneOf->data.u32.Step)); + } else { + switch (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE) { + case EFI_IFR_NUMERIC_SIZE_1: + DEBUG ((DEBUG_INFO, " MinValue - 0x%02x\n", IfrOneOf->data.u8.MinValue)); + DEBUG ((DEBUG_INFO, " MaxValue - 0x%02x\n", IfrOneOf->data.u8.MaxValue)); + DEBUG ((DEBUG_INFO, " Step - 0x%02x\n", IfrOneOf->data.u8.Step)); + break; + case EFI_IFR_NUMERIC_SIZE_2: + DEBUG ((DEBUG_INFO, " MinValue - 0x%04x\n", IfrOneOf->data.u16.MinValue)); + DEBUG ((DEBUG_INFO, " MaxValue - 0x%04x\n", IfrOneOf->data.u16.MaxValue)); + DEBUG ((DEBUG_INFO, " Step - 0x%04x\n", IfrOneOf->data.u16.Step)); + break; + case EFI_IFR_NUMERIC_SIZE_4: + DEBUG ((DEBUG_INFO, " MinValue - 0x%08x\n", IfrOneOf->data.u32.MinValue)); + DEBUG ((DEBUG_INFO, " MaxValue - 0x%08x\n", IfrOneOf->data.u32.MaxValue)); + DEBUG ((DEBUG_INFO, " Step - 0x%08x\n", IfrOneOf->data.u32.Step)); + break; + case EFI_IFR_NUMERIC_SIZE_8: + DEBUG ((DEBUG_INFO, " MinValue - 0x%016lx\n", IfrOneOf->data.u64.MinValue)); + DEBUG ((DEBUG_INFO, " MaxValue - 0x%016lx\n", IfrOneOf->data.u64.MaxValue)); + DEBUG ((DEBUG_INFO, " Step - 0x%016lx\n", IfrOneOf->data.u64.Step)); + break; + } + } + + break; + case EFI_IFR_CHECKBOX_OP: + IfrCheckBox = (EFI_IFR_CHECKBOX *)IfrOpCodeHeader; + DEBUG ((DEBUG_INFO, " Flags - 0x%02x\n", IfrCheckBox->Flags)); + break; + case EFI_IFR_NUMERIC_OP: + IfrNumeric = (EFI_IFR_NUMERIC *)IfrOpCodeHeader; + DEBUG ((DEBUG_INFO, " Flags - 0x%02x\n", IfrNumeric->Flags)); + if (QuestionStoredInBitField) { + // + // For Numeric stored in bit field, the MinValue,MaxValue and Step are saved as UINT32 type. + // + DEBUG ((DEBUG_INFO, " MinValue - 0x%08x\n", IfrNumeric->data.u32.MinValue)); + DEBUG ((DEBUG_INFO, " MaxValue - 0x%08x\n", IfrNumeric->data.u32.MaxValue)); + DEBUG ((DEBUG_INFO, " Step - 0x%08x\n", IfrNumeric->data.u32.Step)); + } else { + switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) { + case EFI_IFR_NUMERIC_SIZE_1: + DEBUG ((DEBUG_INFO, " MinValue - 0x%02x\n", IfrNumeric->data.u8.MinValue)); + DEBUG ((DEBUG_INFO, " MaxValue - 0x%02x\n", IfrNumeric->data.u8.MaxValue)); + DEBUG ((DEBUG_INFO, " Step - 0x%02x\n", IfrNumeric->data.u8.Step)); + break; + case EFI_IFR_NUMERIC_SIZE_2: + DEBUG ((DEBUG_INFO, " MinValue - 0x%04x\n", IfrNumeric->data.u16.MinValue)); + DEBUG ((DEBUG_INFO, " MaxValue - 0x%04x\n", IfrNumeric->data.u16.MaxValue)); + DEBUG ((DEBUG_INFO, " Step - 0x%04x\n", IfrNumeric->data.u16.Step)); + break; + case EFI_IFR_NUMERIC_SIZE_4: + DEBUG ((DEBUG_INFO, " MinValue - 0x%08x\n", IfrNumeric->data.u32.MinValue)); + DEBUG ((DEBUG_INFO, " MaxValue - 0x%08x\n", IfrNumeric->data.u32.MaxValue)); + DEBUG ((DEBUG_INFO, " Step - 0x%08x\n", IfrNumeric->data.u32.Step)); + break; + case EFI_IFR_NUMERIC_SIZE_8: + DEBUG ((DEBUG_INFO, " MinValue - 0x%016lx\n", IfrNumeric->data.u64.MinValue)); + DEBUG ((DEBUG_INFO, " MaxValue - 0x%016lx\n", IfrNumeric->data.u64.MaxValue)); + DEBUG ((DEBUG_INFO, " Step - 0x%016lx\n", IfrNumeric->data.u64.Step)); + break; + } + } + + break; + case EFI_IFR_ORDERED_LIST_OP: + IfrOrderedList = (EFI_IFR_ORDERED_LIST *)IfrOpCodeHeader; + DEBUG ((DEBUG_INFO, " MaxContainers - 0x%02x\n", IfrOrderedList->MaxContainers)); + DEBUG ((DEBUG_INFO, " Flags - 0x%02x\n", IfrOrderedList->Flags)); + break; + default: + break; + } + + if (IfrOpCodeHeader->Scope != 0) { + UINTN Scope; + EFI_IFR_ONE_OF_OPTION *IfrOneOfOption; + + IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length); + Scope = 1; + while (Scope != 0) { + switch (IfrOpCodeHeader->OpCode) { + case EFI_IFR_ONE_OF_OPTION_OP: + IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *)IfrOpCodeHeader; + DEBUG ((DEBUG_INFO, "!!!! IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", (UINTN)IfrOpCodeHeader->OpCode, IfrOpCodeToStr (IfrOpCodeHeader->OpCode))); + DEBUG ((DEBUG_INFO, "!!!! IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader->Scope)); + DEBUG ((DEBUG_INFO, "!!!! Option - 0x%04x\n", IfrOneOfOption->Option)); + DEBUG ((DEBUG_INFO, "!!!! Flags - 0x%02x\n", IfrOneOfOption->Flags)); + DEBUG ((DEBUG_INFO, "!!!! Type - 0x%02x\n", IfrOneOfOption->Type)); + switch (IfrOneOfOption->Type) { + case EFI_IFR_TYPE_NUM_SIZE_8: + DEBUG ((DEBUG_INFO, "!!!! Value - 0x%02x\n", IfrOneOfOption->Value.u8)); + break; + case EFI_IFR_TYPE_NUM_SIZE_16: + DEBUG ((DEBUG_INFO, "!!!! Value - 0x%04x\n", IfrOneOfOption->Value.u16)); + break; + case EFI_IFR_TYPE_NUM_SIZE_32: + DEBUG ((DEBUG_INFO, "!!!! Value - 0x%08x\n", IfrOneOfOption->Value.u32)); + break; + case EFI_IFR_TYPE_NUM_SIZE_64: + DEBUG ((DEBUG_INFO, "!!!! Value - 0x%016lx\n", IfrOneOfOption->Value.u64)); + break; + case EFI_IFR_TYPE_BOOLEAN: + DEBUG ((DEBUG_INFO, "!!!! Value - 0x%02x\n", IfrOneOfOption->Value.b)); + break; + default: + break; + } + + break; + } + + if (IfrOpCodeHeader->OpCode == EFI_IFR_END_OP) { + QuestionStoredInBitField = FALSE; + ASSERT (Scope > 0); + Scope--; + if (Scope == 0) { + break; + } + } else if (IfrOpCodeHeader->Scope != 0) { + Scope++; + } + + IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length); + } + } + } + default: + break; + } + + IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length); + } + + break; + default: + break; + } +} + +/** + Dump Hii Database. + + @param[in] HiiDatabase Pointer to Hii Database. + @param[in] HiiDatabaseSize Hii Database size. + +**/ +VOID +DumpHiiDatabase ( + IN VOID *HiiDatabase, + IN UINTN HiiDatabaseSize + ) +{ + EFI_HII_PACKAGE_LIST_HEADER *HiiPackageListHeader; + EFI_HII_PACKAGE_HEADER *HiiPackageHeader; + + DEBUG ((DEBUG_INFO, "HiiDatabaseSize - 0x%x\n", HiiDatabaseSize)); + HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)HiiDatabase; + + while ((UINTN)HiiPackageListHeader < ((UINTN)HiiDatabase + HiiDatabaseSize)) { + DEBUG ((DEBUG_INFO, "HiiPackageListHeader->PackageListGuid - %g\n", &HiiPackageListHeader->PackageListGuid)); + DEBUG ((DEBUG_INFO, "HiiPackageListHeader->PackageLength - 0x%x\n", (UINTN)HiiPackageListHeader->PackageLength)); + HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)(HiiPackageListHeader + 1); + + while ((UINTN)HiiPackageHeader < (UINTN)HiiPackageListHeader + HiiPackageListHeader->PackageLength) { + DumpHiiPackage (HiiPackageHeader); + + HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)((UINTN)HiiPackageHeader + HiiPackageHeader->Length); + } + + HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)((UINTN)HiiPackageListHeader + HiiPackageListHeader->PackageLength); + } + + return; +} + +#endif + +/** + Allocates a buffer of a certain pool type. + + Allocates the number bytes specified by AllocationSize of a certain pool type and returns a + pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param MemoryType The type of memory to allocate. + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +InternalVarCheckAllocatePool ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN AllocationSize + ) +{ + EFI_STATUS Status; + VOID *Memory; + + Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory); + if (EFI_ERROR (Status)) { + Memory = NULL; + } + + return Memory; +} + +/** + Allocates and zeros a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +InternalVarCheckAllocateZeroPool ( + IN UINTN AllocationSize + ) +{ + VOID *Memory; + + Memory = InternalVarCheckAllocatePool (EfiBootServicesData, AllocationSize); + if (Memory != NULL) { + Memory = ZeroMem (Memory, AllocationSize); + } + + return Memory; +} + +/** + Frees a buffer that was previously allocated with one of the pool allocation functions in the + Memory Allocation Library. + + Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the + pool allocation services of the Memory Allocation Library. If it is not possible to free pool + resources, then this function will perform no actions. + + If Buffer was not allocated with a pool allocation function in the Memory Allocation Library, + then ASSERT(). + + @param Buffer The pointer to the buffer to free. + +**/ +VOID +EFIAPI +InternalVarCheckFreePool ( + IN VOID *Buffer + ) +{ + EFI_STATUS Status; + + Status = gBS->FreePool (Buffer); + ASSERT_EFI_ERROR (Status); +} + +/** + Reallocates a buffer of type EfiBootServicesData. + + Allocates and zeros the number bytes specified by NewSize from memory of type + EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +InternalVarCheckReallocatePool ( + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + VOID *NewBuffer; + + NewBuffer = InternalVarCheckAllocateZeroPool (NewSize); + if ((NewBuffer != NULL) && (OldBuffer != NULL)) { + CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); + InternalVarCheckFreePool (OldBuffer); + } + + return NewBuffer; +} + +/** + Merge Hii Question. + + @param[in, out] HiiVariableNode Pointer to Hii Variable node. + @param[in] HiiQuestion Pointer to Hii Question. + @param[in] FromFv Hii Question from FV. + +**/ +VOID +MergeHiiQuestion ( + IN OUT VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode, + IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion, + IN BOOLEAN FromFv + ) +{ + VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion1; + VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion2; + VAR_CHECK_HII_QUESTION_HEADER *NewHiiQuestion; + UINT8 NewLength; + UINT64 Minimum1; + UINT64 Maximum1; + UINT64 OneValue1; + UINT64 Minimum2; + UINT64 Maximum2; + UINT64 OneValue2; + UINT8 *Ptr; + UINT8 *Ptr1; + UINT8 *Ptr2; + UINTN ArrayIndex; + + // + // Hii Question from Hii Database has high priority. + // Do not to merge Hii Question from Fv to Hii Question from Hii Database. + // + if (FromFv) { + InternalVarCheckFreePool (HiiQuestion); + return; + } + + if (HiiQuestion->BitFieldStore) { + ArrayIndex = HiiQuestion->VarOffset; + } else { + ArrayIndex = HiiQuestion->VarOffset * 8; + } + + HiiQuestion1 = HiiVariableNode->HiiQuestionArray[ArrayIndex]; + HiiQuestion2 = HiiQuestion; + + ASSERT ((HiiQuestion1->OpCode == HiiQuestion2->OpCode) && (HiiQuestion1->StorageWidth == HiiQuestion2->StorageWidth)); + + switch (HiiQuestion1->OpCode) { + case EFI_IFR_ONE_OF_OP: + DEBUG ((DEBUG_INFO, "MergeHiiQuestion - EFI_IFR_ONE_OF_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1->VarOffset, (HiiQuestion1->BitFieldStore ? "bit level" : "byte level"))); + // + // Get the length of Hii Question 1. + // + NewLength = HiiQuestion1->Length; + + // + // Check if the one of options in Hii Question 2 have been in Hii Question 1. + // + Ptr2 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion2 + 1); + while ((UINTN)Ptr2 < (UINTN)HiiQuestion2 + HiiQuestion2->Length) { + OneValue2 = 0; + CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth); + + Ptr1 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion1 + 1); + while ((UINTN)Ptr1 < (UINTN)HiiQuestion1 + HiiQuestion1->Length) { + OneValue1 = 0; + CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth); + if (OneValue2 == OneValue1) { + // + // Match + // + break; + } + + Ptr1 += HiiQuestion1->StorageWidth; + } + + if ((UINTN)Ptr1 >= ((UINTN)HiiQuestion1 + HiiQuestion1->Length)) { + // + // No match + // + NewLength = (UINT8)(NewLength + HiiQuestion1->StorageWidth); + } + + Ptr2 += HiiQuestion2->StorageWidth; + } + + if (NewLength > HiiQuestion1->Length) { + // + // Merge the one of options of Hii Question 2 and Hii Question 1. + // + NewHiiQuestion = InternalVarCheckAllocateZeroPool (NewLength); + ASSERT (NewHiiQuestion != NULL); + CopyMem (NewHiiQuestion, HiiQuestion1, HiiQuestion1->Length); + // + // Use the new length. + // + NewHiiQuestion->Length = NewLength; + Ptr = (UINT8 *)NewHiiQuestion + HiiQuestion1->Length; + + Ptr2 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion2 + 1); + while ((UINTN)Ptr2 < (UINTN)HiiQuestion2 + HiiQuestion2->Length) { + OneValue2 = 0; + CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth); + + Ptr1 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion1 + 1); + while ((UINTN)Ptr1 < (UINTN)HiiQuestion1 + HiiQuestion1->Length) { + OneValue1 = 0; + CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth); + if (OneValue2 == OneValue1) { + // + // Match + // + break; + } + + Ptr1 += HiiQuestion1->StorageWidth; + } + + if ((UINTN)Ptr1 >= ((UINTN)HiiQuestion1 + HiiQuestion1->Length)) { + // + // No match + // + CopyMem (Ptr, &OneValue2, HiiQuestion1->StorageWidth); + Ptr += HiiQuestion1->StorageWidth; + } + + Ptr2 += HiiQuestion2->StorageWidth; + } + + HiiVariableNode->HiiQuestionArray[ArrayIndex] = NewHiiQuestion; + InternalVarCheckFreePool (HiiQuestion1); + } + + break; + + case EFI_IFR_CHECKBOX_OP: + DEBUG ((DEBUG_INFO, "MergeHiiQuestion - EFI_IFR_CHECKBOX_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1->VarOffset, (HiiQuestion1->BitFieldStore ? "bit level" : "byte level"))); + break; + + case EFI_IFR_NUMERIC_OP: + DEBUG ((DEBUG_INFO, "MergeHiiQuestion - EFI_IFR_NUMERIC_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1->VarOffset, (HiiQuestion1->BitFieldStore ? "bit level" : "byte level"))); + // + // Get minimum and maximum of Hii Question 1. + // + Minimum1 = 0; + Maximum1 = 0; + Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion1 + 1); + CopyMem (&Minimum1, Ptr, HiiQuestion1->StorageWidth); + Ptr += HiiQuestion1->StorageWidth; + CopyMem (&Maximum1, Ptr, HiiQuestion1->StorageWidth); + + // + // Get minimum and maximum of Hii Question 2. + // + Minimum2 = 0; + Maximum2 = 0; + Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion2 + 1); + CopyMem (&Minimum2, Ptr, HiiQuestion2->StorageWidth); + Ptr += HiiQuestion2->StorageWidth; + CopyMem (&Maximum2, Ptr, HiiQuestion2->StorageWidth); + + // + // Update minimum. + // + Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion1 + 1); + if (Minimum2 < Minimum1) { + Minimum1 = Minimum2; + CopyMem (Ptr, &Minimum1, HiiQuestion1->StorageWidth); + } + + // + // Update maximum. + // + Ptr += HiiQuestion1->StorageWidth; + if (Maximum2 > Maximum1) { + Maximum1 = Maximum2; + CopyMem (Ptr, &Maximum1, HiiQuestion1->StorageWidth); + } + + break; + + case EFI_IFR_ORDERED_LIST_OP: + DEBUG ((DEBUG_INFO, "MergeHiiQuestion - EFI_IFR_ORDERED_LIST_OP VarOffset = 0x%04x\n", HiiQuestion1->VarOffset)); + // + // Get the length of Hii Question 1. + // + NewLength = HiiQuestion1->Length; + + // + // Check if the one of options in Hii Question 2 have been in Hii Question 1. + // + Ptr2 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion2 + 1); + while ((UINTN)Ptr2 < (UINTN)HiiQuestion2 + HiiQuestion2->Length) { + OneValue2 = 0; + CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth); + + Ptr1 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion1 + 1); + while ((UINTN)Ptr1 < (UINTN)HiiQuestion1 + HiiQuestion1->Length) { + OneValue1 = 0; + CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth); + if (OneValue2 == OneValue1) { + // + // Match + // + break; + } + + Ptr1 += HiiQuestion1->StorageWidth; + } + + if ((UINTN)Ptr1 >= ((UINTN)HiiQuestion1 + HiiQuestion1->Length)) { + // + // No match + // + NewLength = (UINT8)(NewLength + HiiQuestion1->StorageWidth); + } + + Ptr2 += HiiQuestion2->StorageWidth; + } + + if (NewLength > HiiQuestion1->Length) { + // + // Merge the one of options of Hii Question 2 and Hii Question 1. + // + NewHiiQuestion = InternalVarCheckAllocateZeroPool (NewLength); + ASSERT (NewHiiQuestion != NULL); + CopyMem (NewHiiQuestion, HiiQuestion1, HiiQuestion1->Length); + // + // Use the new length. + // + NewHiiQuestion->Length = NewLength; + Ptr = (UINT8 *)NewHiiQuestion + HiiQuestion1->Length; + + Ptr2 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion2 + 1); + while ((UINTN)Ptr2 < (UINTN)HiiQuestion2 + HiiQuestion2->Length) { + OneValue2 = 0; + CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth); + + Ptr1 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion1 + 1); + while ((UINTN)Ptr1 < (UINTN)HiiQuestion1 + HiiQuestion1->Length) { + OneValue1 = 0; + CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth); + if (OneValue2 == OneValue1) { + // + // Match + // + break; + } + + Ptr1 += HiiQuestion1->StorageWidth; + } + + if ((UINTN)Ptr1 >= ((UINTN)HiiQuestion1 + HiiQuestion1->Length)) { + // + // No match + // + CopyMem (Ptr, &OneValue2, HiiQuestion1->StorageWidth); + Ptr += HiiQuestion1->StorageWidth; + } + + Ptr2 += HiiQuestion2->StorageWidth; + } + + HiiVariableNode->HiiQuestionArray[ArrayIndex] = NewHiiQuestion; + InternalVarCheckFreePool (HiiQuestion1); + } + + break; + + default: + ASSERT (FALSE); + return; + break; + } + + // + // + // Hii Question 2 has been merged with Hii Question 1. + // + InternalVarCheckFreePool (HiiQuestion2); +} + +/** + Get OneOf option data. + + @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header. + @param[out] Count Pointer to option count. + @param[out] Width Pointer to option width. + @param[out] OptionBuffer Pointer to option buffer. + +**/ +VOID +GetOneOfOption ( + IN EFI_IFR_OP_HEADER *IfrOpCodeHeader, + OUT UINTN *Count, + OUT UINT8 *Width, + OUT VOID *OptionBuffer OPTIONAL + ) +{ + UINTN Scope; + EFI_IFR_ONE_OF_OPTION *IfrOneOfOption; + + // + // Assume all OPTION has same Width. + // + *Count = 0; + + if (IfrOpCodeHeader->Scope != 0) { + // + // Nested OpCode. + // + Scope = 1; + IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length); + while (Scope != 0) { + switch (IfrOpCodeHeader->OpCode) { + case EFI_IFR_ONE_OF_OPTION_OP: + IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *)IfrOpCodeHeader; + switch (IfrOneOfOption->Type) { + case EFI_IFR_TYPE_NUM_SIZE_8: + *Count = *Count + 1; + *Width = sizeof (UINT8); + if (OptionBuffer != NULL) { + CopyMem (OptionBuffer, &IfrOneOfOption->Value.u8, sizeof (UINT8)); + OptionBuffer = (UINT8 *)OptionBuffer + 1; + } + + break; + case EFI_IFR_TYPE_NUM_SIZE_16: + *Count = *Count + 1; + *Width = sizeof (UINT16); + if (OptionBuffer != NULL) { + CopyMem (OptionBuffer, &IfrOneOfOption->Value.u16, sizeof (UINT16)); + OptionBuffer = (UINT16 *)OptionBuffer + 1; + } + + break; + case EFI_IFR_TYPE_NUM_SIZE_32: + *Count = *Count + 1; + *Width = sizeof (UINT32); + if (OptionBuffer != NULL) { + CopyMem (OptionBuffer, &IfrOneOfOption->Value.u32, sizeof (UINT32)); + OptionBuffer = (UINT32 *)OptionBuffer + 1; + } + + break; + case EFI_IFR_TYPE_NUM_SIZE_64: + *Count = *Count + 1; + *Width = sizeof (UINT64); + if (OptionBuffer != NULL) { + CopyMem (OptionBuffer, &IfrOneOfOption->Value.u64, sizeof (UINT64)); + OptionBuffer = (UINT64 *)OptionBuffer + 1; + } + + break; + case EFI_IFR_TYPE_BOOLEAN: + *Count = *Count + 1; + *Width = sizeof (BOOLEAN); + if (OptionBuffer != NULL) { + CopyMem (OptionBuffer, &IfrOneOfOption->Value.b, sizeof (BOOLEAN)); + OptionBuffer = (BOOLEAN *)OptionBuffer + 1; + } + + break; + default: + break; + } + + break; + } + + // + // Until End OpCode. + // + if (IfrOpCodeHeader->OpCode == EFI_IFR_END_OP) { + ASSERT (Scope > 0); + Scope--; + if (Scope == 0) { + break; + } + } else if (IfrOpCodeHeader->Scope != 0) { + // + // Nested OpCode. + // + Scope++; + } + + IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length); + } + } + + return; +} + +/** + Parse Hii Question Oneof. + + @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header. + @param[in] StoredInBitField Whether the OneOf is stored in bit field Storage. + + return Pointer to Hii Question. + +**/ +VAR_CHECK_HII_QUESTION_HEADER * +ParseHiiQuestionOneOf ( + IN EFI_IFR_OP_HEADER *IfrOpCodeHeader, + IN BOOLEAN StoredInBitField + ) +{ + EFI_IFR_ONE_OF *IfrOneOf; + VAR_CHECK_HII_QUESTION_ONEOF *OneOf; + UINTN Length; + UINT8 Width; + UINTN OptionCount; + UINT8 OptionWidth; + UINT8 BitWidth; + + IfrOneOf = (EFI_IFR_ONE_OF *)IfrOpCodeHeader; + BitWidth = 0; + + if (StoredInBitField) { + // + // When OneOf stored in bit field, the bit width is saved in the lower six bits of the flag. + // And the options in the OneOf is saved as UINT32 type. + // + BitWidth = IfrOneOf->Flags & EDKII_IFR_NUMERIC_SIZE_BIT; + Width = sizeof (UINT32); + } else { + Width = (UINT8)(1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE)); + } + + GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, NULL); + ASSERT (Width == OptionWidth); + + Length = sizeof (*OneOf) + OptionCount * Width; + + OneOf = InternalVarCheckAllocateZeroPool (Length); + ASSERT (OneOf != NULL); + OneOf->OpCode = EFI_IFR_ONE_OF_OP; + OneOf->Length = (UINT8)Length; + OneOf->VarOffset = IfrOneOf->Question.VarStoreInfo.VarOffset; + OneOf->BitFieldStore = StoredInBitField; + if (StoredInBitField) { + OneOf->StorageWidth = BitWidth; + } else { + OneOf->StorageWidth = Width; + } + + GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, OneOf + 1); + + return (VAR_CHECK_HII_QUESTION_HEADER *)OneOf; +} + +/** + Parse Hii Question CheckBox. + + @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header. + @param[in] StoredInBitField Whether the CheckBox is stored in bit field Storage. + + return Pointer to Hii Question. + +**/ +VAR_CHECK_HII_QUESTION_HEADER * +ParseHiiQuestionCheckBox ( + IN EFI_IFR_OP_HEADER *IfrOpCodeHeader, + IN BOOLEAN StoredInBitField + ) +{ + EFI_IFR_CHECKBOX *IfrCheckBox; + VAR_CHECK_HII_QUESTION_CHECKBOX *CheckBox; + + IfrCheckBox = (EFI_IFR_CHECKBOX *)IfrOpCodeHeader; + + CheckBox = InternalVarCheckAllocateZeroPool (sizeof (*CheckBox)); + ASSERT (CheckBox != NULL); + CheckBox->OpCode = EFI_IFR_CHECKBOX_OP; + CheckBox->Length = (UINT8)sizeof (*CheckBox); + CheckBox->VarOffset = IfrCheckBox->Question.VarStoreInfo.VarOffset; + CheckBox->BitFieldStore = StoredInBitField; + if (StoredInBitField) { + CheckBox->StorageWidth = 1; + } else { + CheckBox->StorageWidth = (UINT8)sizeof (BOOLEAN); + } + + return (VAR_CHECK_HII_QUESTION_HEADER *)CheckBox; +} + +/** + Parse Hii Question Numeric. + + @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header. + @param[in] StoredInBitField Whether the Numeric is stored in bit field Storage. + + return Pointer to Hii Question. + +**/ +VAR_CHECK_HII_QUESTION_HEADER * +ParseHiiQuestionNumeric ( + IN EFI_IFR_OP_HEADER *IfrOpCodeHeader, + IN BOOLEAN StoredInBitField + ) +{ + EFI_IFR_NUMERIC *IfrNumeric; + VAR_CHECK_HII_QUESTION_NUMERIC *Numeric; + UINT8 Width; + UINT8 BitWidth; + + IfrNumeric = (EFI_IFR_NUMERIC *)IfrOpCodeHeader; + BitWidth = 0; + + Numeric = InternalVarCheckAllocateZeroPool (sizeof (VAR_CHECK_HII_QUESTION_NUMERIC) + 2 * sizeof (UINT64)); + ASSERT (Numeric != NULL); + + if (StoredInBitField) { + // + // When Numeric stored in bit field, the bit field width is saved in the lower six bits of the flag. + // And the Minimum Maximum of Numeric is saved as UINT32 type. + // + BitWidth = IfrNumeric->Flags & EDKII_IFR_NUMERIC_SIZE_BIT; + Width = sizeof (UINT32); + } else { + Width = (UINT8)(1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE)); + } + + Numeric->OpCode = EFI_IFR_NUMERIC_OP; + Numeric->Length = (UINT8)(sizeof (VAR_CHECK_HII_QUESTION_NUMERIC) + 2 * Width); + Numeric->VarOffset = IfrNumeric->Question.VarStoreInfo.VarOffset; + Numeric->BitFieldStore = StoredInBitField; + if (StoredInBitField) { + Numeric->StorageWidth = BitWidth; + } else { + Numeric->StorageWidth = Width; + } + + CopyMem (Numeric + 1, &IfrNumeric->data, Width * 2); + + return (VAR_CHECK_HII_QUESTION_HEADER *)Numeric; +} + +/** + Parse Hii Question OrderedList. + + @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header. + + return Pointer to Hii Question. + +**/ +VAR_CHECK_HII_QUESTION_HEADER * +ParseHiiQuestionOrderedList ( + IN EFI_IFR_OP_HEADER *IfrOpCodeHeader + ) +{ + EFI_IFR_ORDERED_LIST *IfrOrderedList; + VAR_CHECK_HII_QUESTION_ORDEREDLIST *OrderedList; + UINTN Length; + UINTN OptionCount; + UINT8 OptionWidth; + + IfrOrderedList = (EFI_IFR_ORDERED_LIST *)IfrOpCodeHeader; + + GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, NULL); + + Length = sizeof (*OrderedList) + OptionCount * OptionWidth; + + OrderedList = InternalVarCheckAllocateZeroPool (Length); + ASSERT (OrderedList != NULL); + OrderedList->OpCode = EFI_IFR_ORDERED_LIST_OP; + OrderedList->Length = (UINT8)Length; + OrderedList->VarOffset = IfrOrderedList->Question.VarStoreInfo.VarOffset; + OrderedList->StorageWidth = OptionWidth; + OrderedList->MaxContainers = IfrOrderedList->MaxContainers; + OrderedList->BitFieldStore = FALSE; + + GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, OrderedList + 1); + + return (VAR_CHECK_HII_QUESTION_HEADER *)OrderedList; +} + +/** + Parse and create Hii Question node. + + @param[in] HiiVariableNode Pointer to Hii Variable node. + @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header. + @param[in] FromFv Hii Question from FV. + @param[in] StoredInBitField Whether the Question is stored in bit field Storage. + +**/ +VOID +ParseHiiQuestion ( + IN VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode, + IN EFI_IFR_OP_HEADER *IfrOpCodeHeader, + IN BOOLEAN FromFv, + IN BOOLEAN StoredInBitField + ) +{ + VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion; + UINTN ArrayIndex; + + // + // Currently only OneOf, CheckBox and Numeric can be stored in bit field. + // + switch (IfrOpCodeHeader->OpCode) { + case EFI_IFR_ONE_OF_OP: + HiiQuestion = ParseHiiQuestionOneOf (IfrOpCodeHeader, StoredInBitField); + break; + + case EFI_IFR_CHECKBOX_OP: + HiiQuestion = ParseHiiQuestionCheckBox (IfrOpCodeHeader, StoredInBitField); + break; + + case EFI_IFR_NUMERIC_OP: + HiiQuestion = ParseHiiQuestionNumeric (IfrOpCodeHeader, StoredInBitField); + break; + + case EFI_IFR_ORDERED_LIST_OP: + HiiQuestion = ParseHiiQuestionOrderedList (IfrOpCodeHeader); + break; + + default: + ASSERT (FALSE); + return; + break; + } + + if (StoredInBitField) { + ArrayIndex = HiiQuestion->VarOffset; + } else { + ArrayIndex = HiiQuestion->VarOffset * 8; + } + + if (HiiVariableNode->HiiQuestionArray[ArrayIndex] != NULL) { + MergeHiiQuestion (HiiVariableNode, HiiQuestion, FromFv); + } else { + HiiVariableNode->HiiQuestionArray[ArrayIndex] = HiiQuestion; + } +} + +/** + Find Hii variable node by name and GUID. + + @param[in] Name Pointer to variable name. + @param[in] Guid Pointer to vendor GUID. + + @return Pointer to Hii Variable node. + +**/ +VAR_CHECK_HII_VARIABLE_NODE * +FindHiiVariableNode ( + IN CHAR16 *Name, + IN EFI_GUID *Guid + ) +{ + VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode; + LIST_ENTRY *Link; + + for (Link = mVarCheckHiiList.ForwardLink + ; Link != &mVarCheckHiiList + ; Link = Link->ForwardLink) + { + HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (Link); + + if ((StrCmp (Name, (CHAR16 *)(HiiVariableNode->HiiVariable + 1)) == 0) && + CompareGuid (Guid, &HiiVariableNode->HiiVariable->Guid)) + { + return HiiVariableNode; + } + } + + return NULL; +} + +/** + Find Hii variable node by var store id. + + @param[in] VarStoreId Var store id. + + @return Pointer to Hii Variable node. + +**/ +VAR_CHECK_HII_VARIABLE_NODE * +FindHiiVariableNodeByVarStoreId ( + IN EFI_VARSTORE_ID VarStoreId + ) +{ + VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode; + LIST_ENTRY *Link; + + if (VarStoreId == 0) { + // + // The variable store identifier, which is unique within the current form set. + // A value of zero is invalid. + // + return NULL; + } + + for (Link = mVarCheckHiiList.ForwardLink + ; Link != &mVarCheckHiiList + ; Link = Link->ForwardLink) + { + HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (Link); + // + // The variable store identifier, which is unique within the current form set. + // + if (VarStoreId == HiiVariableNode->VarStoreId) { + return HiiVariableNode; + } + } + + return NULL; +} + +/** + Destroy var store id in the Hii Variable node after parsing one Hii Package. + +**/ +VOID +DestroyVarStoreId ( + VOID + ) +{ + VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode; + LIST_ENTRY *Link; + + for (Link = mVarCheckHiiList.ForwardLink + ; Link != &mVarCheckHiiList + ; Link = Link->ForwardLink) + { + HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (Link); + // + // The variable store identifier, which is unique within the current form set. + // A value of zero is invalid. + // + HiiVariableNode->VarStoreId = 0; + } +} + +/** + Create Hii Variable node. + + @param[in] IfrEfiVarStore Pointer to EFI VARSTORE. + +**/ +VOID +CreateHiiVariableNode ( + IN EFI_IFR_VARSTORE_EFI *IfrEfiVarStore + ) +{ + VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode; + VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable; + UINTN HeaderLength; + CHAR16 *VarName; + UINTN VarNameSize; + + // + // Get variable name. + // + VarNameSize = AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16); + if (VarNameSize > mMaxVarNameSize) { + mVarName = InternalVarCheckReallocatePool (mMaxVarNameSize, VarNameSize, mVarName); + ASSERT (mVarName != NULL); + mMaxVarNameSize = VarNameSize; + } + + AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, mVarName, mMaxVarNameSize / sizeof (CHAR16)); + VarName = mVarName; + + HiiVariableNode = FindHiiVariableNode ( + VarName, + &IfrEfiVarStore->Guid + ); + if (HiiVariableNode == NULL) { + // + // Not found, then create new. + // + HeaderLength = sizeof (*HiiVariable) + VarNameSize; + HiiVariable = InternalVarCheckAllocateZeroPool (HeaderLength); + ASSERT (HiiVariable != NULL); + HiiVariable->Revision = VAR_CHECK_HII_REVISION; + HiiVariable->OpCode = EFI_IFR_VARSTORE_EFI_OP; + HiiVariable->HeaderLength = (UINT16)HeaderLength; + HiiVariable->Size = IfrEfiVarStore->Size; + HiiVariable->Attributes = IfrEfiVarStore->Attributes; + CopyGuid (&HiiVariable->Guid, &IfrEfiVarStore->Guid); + StrCpyS ((CHAR16 *)(HiiVariable + 1), VarNameSize / sizeof (CHAR16), VarName); + + HiiVariableNode = InternalVarCheckAllocateZeroPool (sizeof (*HiiVariableNode)); + ASSERT (HiiVariableNode != NULL); + HiiVariableNode->Signature = VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE; + HiiVariableNode->HiiVariable = HiiVariable; + // + // The variable store identifier, which is unique within the current form set. + // + HiiVariableNode->VarStoreId = IfrEfiVarStore->VarStoreId; + HiiVariableNode->HiiQuestionArray = InternalVarCheckAllocateZeroPool (IfrEfiVarStore->Size * 8 * sizeof (VAR_CHECK_HII_QUESTION_HEADER *)); + + InsertTailList (&mVarCheckHiiList, &HiiVariableNode->Link); + } else { + HiiVariableNode->VarStoreId = IfrEfiVarStore->VarStoreId; + } +} + +/** + Parse and create Hii Variable node list. + + @param[in] HiiPackage Pointer to Hii Package. + +**/ +VOID +ParseHiiVariable ( + IN VOID *HiiPackage + ) +{ + EFI_HII_PACKAGE_HEADER *HiiPackageHeader; + EFI_IFR_OP_HEADER *IfrOpCodeHeader; + EFI_IFR_VARSTORE_EFI *IfrEfiVarStore; + + HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiPackage; + + switch (HiiPackageHeader->Type) { + case EFI_HII_PACKAGE_FORMS: + IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)(HiiPackageHeader + 1); + + while ((UINTN)IfrOpCodeHeader < (UINTN)HiiPackageHeader + HiiPackageHeader->Length) { + switch (IfrOpCodeHeader->OpCode) { + case EFI_IFR_VARSTORE_EFI_OP: + // + // Come to EFI VARSTORE in Form Package. + // + IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpCodeHeader; + if ((IfrEfiVarStore->Header.Length >= sizeof (EFI_IFR_VARSTORE_EFI)) && + ((IfrEfiVarStore->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0)) + { + // + // Only create node list for Hii Variable with NV attribute. + // + CreateHiiVariableNode (IfrEfiVarStore); + } + + break; + + default: + break; + } + + IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length); + } + + break; + + default: + break; + } +} + +/** + Var Check Parse Hii Package. + + @param[in] HiiPackage Pointer to Hii Package. + @param[in] FromFv Hii Package from FV. + +**/ +VOID +VarCheckParseHiiPackage ( + IN VOID *HiiPackage, + IN BOOLEAN FromFv + ) +{ + EFI_HII_PACKAGE_HEADER *HiiPackageHeader; + EFI_IFR_OP_HEADER *IfrOpCodeHeader; + VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode; + BOOLEAN QuestionStoredInBitField; + + // + // Parse and create Hii Variable node list for this Hii Package. + // + ParseHiiVariable (HiiPackage); + + HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiPackage; + + QuestionStoredInBitField = FALSE; + + switch (HiiPackageHeader->Type) { + case EFI_HII_PACKAGE_FORMS: + IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)(HiiPackageHeader + 1); + + while ((UINTN)IfrOpCodeHeader < (UINTN)HiiPackageHeader + HiiPackageHeader->Length) { + switch (IfrOpCodeHeader->OpCode) { + case EFI_IFR_GUID_OP: + if (CompareGuid ((EFI_GUID *)((UINTN)IfrOpCodeHeader + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) { + QuestionStoredInBitField = TRUE; + } + + break; + + case EFI_IFR_END_OP: + QuestionStoredInBitField = FALSE; + break; + + case EFI_IFR_ONE_OF_OP: + case EFI_IFR_CHECKBOX_OP: + case EFI_IFR_NUMERIC_OP: + case EFI_IFR_ORDERED_LIST_OP: + HiiVariableNode = FindHiiVariableNodeByVarStoreId (((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.VarStoreId); + if ((HiiVariableNode == NULL) || + // + // No related Hii Variable node found. + // + ((((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.Header.Prompt == 0) && (((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.Header.Help == 0))) + { + // + // meanless IFR item introduced by ECP. + // + } else { + // + // Normal IFR + // + ParseHiiQuestion (HiiVariableNode, IfrOpCodeHeader, FromFv, QuestionStoredInBitField); + } + + default: + break; + } + + IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length); + } + + break; + + default: + break; + } + + DestroyVarStoreId (); +} + +/** + Var Check Parse Hii Database. + + @param[in] HiiDatabase Pointer to Hii Database. + @param[in] HiiDatabaseSize Hii Database size. + +**/ +VOID +VarCheckParseHiiDatabase ( + IN VOID *HiiDatabase, + IN UINTN HiiDatabaseSize + ) +{ + EFI_HII_PACKAGE_LIST_HEADER *HiiPackageListHeader; + EFI_HII_PACKAGE_HEADER *HiiPackageHeader; + + HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)HiiDatabase; + + while ((UINTN)HiiPackageListHeader < ((UINTN)HiiDatabase + HiiDatabaseSize)) { + HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)(HiiPackageListHeader + 1); + + while ((UINTN)HiiPackageHeader < ((UINTN)HiiPackageListHeader + HiiPackageListHeader->PackageLength)) { + // + // Parse Hii Package. + // + VarCheckParseHiiPackage (HiiPackageHeader, FALSE); + + HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)((UINTN)HiiPackageHeader + HiiPackageHeader->Length); + } + + HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)((UINTN)HiiPackageListHeader + HiiPackageListHeader->PackageLength); + } +} + +/** + Destroy Hii Variable node. + +**/ +VOID +DestroyHiiVariableNode ( + VOID + ) +{ + VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode; + LIST_ENTRY *HiiVariableLink; + UINTN Index; + + while (mVarCheckHiiList.ForwardLink != &mVarCheckHiiList) { + HiiVariableLink = mVarCheckHiiList.ForwardLink; + HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink); + + RemoveEntryList (&HiiVariableNode->Link); + + // + // Free the allocated buffer. + // + for (Index = 0; Index < HiiVariableNode->HiiVariable->Size * (UINTN)8; Index++) { + if (HiiVariableNode->HiiQuestionArray[Index] != NULL) { + InternalVarCheckFreePool (HiiVariableNode->HiiQuestionArray[Index]); + } + } + + InternalVarCheckFreePool (HiiVariableNode->HiiQuestionArray); + InternalVarCheckFreePool (HiiVariableNode->HiiVariable); + InternalVarCheckFreePool (HiiVariableNode); + } +} + +/** + Build VarCheckHiiBin. + + @param[out] Size Pointer to VarCheckHii size. + + @return Pointer to VarCheckHiiBin. + +**/ +VOID * +BuildVarCheckHiiBin ( + OUT UINTN *Size + ) +{ + VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode; + LIST_ENTRY *HiiVariableLink; + UINTN Index; + VOID *Data; + UINT8 *Ptr; + UINT32 BinSize; + UINT32 HiiVariableLength; + + // + // Get Size + // + BinSize = 0; + + for (HiiVariableLink = mVarCheckHiiList.ForwardLink + ; HiiVariableLink != &mVarCheckHiiList + ; HiiVariableLink = HiiVariableLink->ForwardLink) + { + // + // For Hii Variable header align. + // + BinSize = (UINT32)HEADER_ALIGN (BinSize); + + HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink); + HiiVariableLength = HiiVariableNode->HiiVariable->HeaderLength; + + for (Index = 0; Index < HiiVariableNode->HiiVariable->Size * (UINTN)8; Index++) { + if (HiiVariableNode->HiiQuestionArray[Index] != NULL) { + // + // For Hii Question header align. + // + HiiVariableLength = (UINT32)HEADER_ALIGN (HiiVariableLength); + HiiVariableLength += HiiVariableNode->HiiQuestionArray[Index]->Length; + } + } + + HiiVariableNode->HiiVariable->Length = HiiVariableLength; + BinSize += HiiVariableLength; + } + + DEBUG ((DEBUG_INFO, "VarCheckHiiBin - size = 0x%x\n", BinSize)); + if (BinSize == 0) { + *Size = BinSize; + return NULL; + } + + // + // AllocatePages () and AllocatePool () from gBS are used for the process of VarCheckHiiBin generation. + // Only here AllocateRuntimeZeroPool () from MemoryAllocateLib is used for runtime access + // in SetVariable check handler. + // + Data = AllocateRuntimeZeroPool (BinSize); + ASSERT (Data != NULL); + // + // Make sure the allocated buffer for VarCheckHiiBin at required alignment. + // + ASSERT ((((UINTN)Data) & (HEADER_ALIGNMENT - 1)) == 0); + DEBUG ((DEBUG_INFO, "VarCheckHiiBin - built at 0x%x\n", Data)); + + // + // Gen Data + // + Ptr = Data; + for (HiiVariableLink = mVarCheckHiiList.ForwardLink + ; HiiVariableLink != &mVarCheckHiiList + ; HiiVariableLink = HiiVariableLink->ForwardLink) + { + // + // For Hii Variable header align. + // + Ptr = (UINT8 *)HEADER_ALIGN (Ptr); + + HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink); + CopyMem (Ptr, HiiVariableNode->HiiVariable, HiiVariableNode->HiiVariable->HeaderLength); + Ptr += HiiVariableNode->HiiVariable->HeaderLength; + + for (Index = 0; Index < HiiVariableNode->HiiVariable->Size * (UINTN)8; Index++) { + if (HiiVariableNode->HiiQuestionArray[Index] != NULL) { + // + // For Hii Question header align. + // + Ptr = (UINT8 *)HEADER_ALIGN (Ptr); + CopyMem (Ptr, HiiVariableNode->HiiQuestionArray[Index], HiiVariableNode->HiiQuestionArray[Index]->Length); + Ptr += HiiVariableNode->HiiQuestionArray[Index]->Length; + } + } + } + + *Size = BinSize; + return Data; +} + +/** + Generate VarCheckHiiBin from Hii Database and FV. + +**/ +VOID +EFIAPI +VarCheckHiiGen ( + VOID + ) +{ + VarCheckHiiGenFromHiiDatabase (); + VarCheckHiiGenFromFv (); + + mVarCheckHiiBin = BuildVarCheckHiiBin (&mVarCheckHiiBinSize); + if (mVarCheckHiiBin == NULL) { + DEBUG ((DEBUG_INFO, "[VarCheckHii] This driver could be removed from *.dsc and *.fdf\n")); + return; + } + + DestroyHiiVariableNode (); + if (mVarName != NULL) { + InternalVarCheckFreePool (mVarName); + } + + #ifdef DUMP_VAR_CHECK_HII + DEBUG_CODE ( + DumpVarCheckHii (mVarCheckHiiBin, mVarCheckHiiBinSize); + ); + #endif +} diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.h b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.h index c70bf726cd..18b7532413 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.h +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.h @@ -1,130 +1,130 @@ -/** @file
- Include file for Var Check Hii bin generation.
-
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _VAR_CHECK_HII_GEN_H_
-#define _VAR_CHECK_HII_GEN_H_
-
-#include "VarCheckHii.h"
-
-/**
- Dump Hii Package.
-
- @param[in] HiiPackage Pointer to Hii Package.
-
-**/
-VOID
-DumpHiiPackage (
- IN VOID *HiiPackage
- );
-
-/**
- Dump Hii Database.
-
- @param[in] HiiDatabase Pointer to Hii Database.
- @param[in] HiiDatabaseSize Hii Database size.
-
-**/
-VOID
-DumpHiiDatabase (
- IN VOID *HiiDatabase,
- IN UINTN HiiDatabaseSize
- );
-
-/**
- Allocates and zeros a buffer of type EfiBootServicesData.
-
- Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
- buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
- valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
- request, then NULL is returned.
-
- @param AllocationSize The number of bytes to allocate and zero.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-InternalVarCheckAllocateZeroPool (
- IN UINTN AllocationSize
- );
-
-/**
- Frees a buffer that was previously allocated with one of the pool allocation functions in the
- Memory Allocation Library.
-
- Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
- pool allocation services of the Memory Allocation Library. If it is not possible to free pool
- resources, then this function will perform no actions.
-
- If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
- then ASSERT().
-
- @param Buffer The pointer to the buffer to free.
-
-**/
-VOID
-EFIAPI
-InternalVarCheckFreePool (
- IN VOID *Buffer
- );
-
-/**
- Var Check Parse Hii Package.
-
- @param[in] HiiPackage Pointer to Hii Package.
- @param[in] FromFv Hii Package from FV.
-
-**/
-VOID
-VarCheckParseHiiPackage (
- IN VOID *HiiPackage,
- IN BOOLEAN FromFv
- );
-
-/**
- Var Check Parse Hii Database.
-
- @param[in] HiiDatabase Pointer to Hii Database.
- @param[in] HiiDatabaseSize Hii Database size.
-
-**/
-VOID
-VarCheckParseHiiDatabase (
- IN VOID *HiiDatabase,
- IN UINTN HiiDatabaseSize
- );
-
-/**
- Generate from FV.
-
-**/
-VOID
-VarCheckHiiGenFromFv (
- VOID
- );
-
-/**
- Generate from Hii Database.
-
-**/
-VOID
-VarCheckHiiGenFromHiiDatabase (
- VOID
- );
-
-/**
- Generate VarCheckHiiBin from Hii Database and FV.
-
-**/
-VOID
-EFIAPI
-VarCheckHiiGen (
- VOID
- );
-
-#endif
+/** @file + Include file for Var Check Hii bin generation. + +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _VAR_CHECK_HII_GEN_H_ +#define _VAR_CHECK_HII_GEN_H_ + +#include "VarCheckHii.h" + +/** + Dump Hii Package. + + @param[in] HiiPackage Pointer to Hii Package. + +**/ +VOID +DumpHiiPackage ( + IN VOID *HiiPackage + ); + +/** + Dump Hii Database. + + @param[in] HiiDatabase Pointer to Hii Database. + @param[in] HiiDatabaseSize Hii Database size. + +**/ +VOID +DumpHiiDatabase ( + IN VOID *HiiDatabase, + IN UINTN HiiDatabaseSize + ); + +/** + Allocates and zeros a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +InternalVarCheckAllocateZeroPool ( + IN UINTN AllocationSize + ); + +/** + Frees a buffer that was previously allocated with one of the pool allocation functions in the + Memory Allocation Library. + + Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the + pool allocation services of the Memory Allocation Library. If it is not possible to free pool + resources, then this function will perform no actions. + + If Buffer was not allocated with a pool allocation function in the Memory Allocation Library, + then ASSERT(). + + @param Buffer The pointer to the buffer to free. + +**/ +VOID +EFIAPI +InternalVarCheckFreePool ( + IN VOID *Buffer + ); + +/** + Var Check Parse Hii Package. + + @param[in] HiiPackage Pointer to Hii Package. + @param[in] FromFv Hii Package from FV. + +**/ +VOID +VarCheckParseHiiPackage ( + IN VOID *HiiPackage, + IN BOOLEAN FromFv + ); + +/** + Var Check Parse Hii Database. + + @param[in] HiiDatabase Pointer to Hii Database. + @param[in] HiiDatabaseSize Hii Database size. + +**/ +VOID +VarCheckParseHiiDatabase ( + IN VOID *HiiDatabase, + IN UINTN HiiDatabaseSize + ); + +/** + Generate from FV. + +**/ +VOID +VarCheckHiiGenFromFv ( + VOID + ); + +/** + Generate from Hii Database. + +**/ +VOID +VarCheckHiiGenFromHiiDatabase ( + VOID + ); + +/** + Generate VarCheckHiiBin from Hii Database and FV. + +**/ +VOID +EFIAPI +VarCheckHiiGen ( + VOID + ); + +#endif diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c index 562f5a02f6..5c6cc54916 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c @@ -1,440 +1,440 @@ -/** @file
- Var Check Hii generation from FV.
-
-Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "VarCheckHiiGen.h"
-
-// {d0bc7cb4-6a47-495f-aa11-710746da06a2}
-#define EFI_VFR_ATTRACT_GUID \
-{ 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } }
-
-EFI_GUID gVfrArrayAttractGuid = EFI_VFR_ATTRACT_GUID;
-
-#define ALL_FF_GUID \
-{ 0xFFFFFFFF, 0xFFFF, 0xFFFF, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } }
-
-EFI_GUID mAllFfGuid = ALL_FF_GUID;
-
-#define VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE SIGNATURE_32 ('V', 'D', 'R', 'I')
-
-typedef struct {
- UINTN Signature;
- LIST_ENTRY Link;
- EFI_GUID *DriverGuid;
-} VAR_CHECK_VFR_DRIVER_INFO;
-
-LIST_ENTRY mVfrDriverList = INITIALIZE_LIST_HEAD_VARIABLE (mVfrDriverList);
-
-#define VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK(a) CR (a, VAR_CHECK_VFR_DRIVER_INFO, Link, VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE)
-
-#define MAX_MATCH_GUID_NUM 100
-
-/**
- Get the address by Guid.
-
- Parse the FFS and find the GUID address.
- There may be multiple Guids matching the searched Guid.
-
- @param Ffs Pointer to the FFS.
- @param Guid Guid to find.
- @param Length The length of FFS.
- @param Offset Pointer to pointer to the offset.
- @param NumOfMatchingGuid The number of matching Guid.
-
- @retval EFI_SUCCESS One or multiple Guids matching the searched Guid.
- @retval EFI_NOT_FOUND No Guid matching the searched Guid.
-
-**/
-EFI_STATUS
-GetAddressByGuid (
- IN VOID *Ffs,
- IN EFI_GUID *Guid,
- IN UINTN Length,
- OUT UINTN **Offset,
- OUT UINT8 *NumOfMatchingGuid
- )
-{
- UINTN LoopControl;
- BOOLEAN Found;
-
- if ((Ffs == NULL) || (Guid == NULL) || (Length == 0)) {
- return EFI_NOT_FOUND;
- }
-
- if (NumOfMatchingGuid != NULL) {
- *NumOfMatchingGuid = 0;
- }
-
- Found = FALSE;
- for (LoopControl = 0; LoopControl < Length; LoopControl++) {
- if (CompareGuid (Guid, (EFI_GUID *)((UINT8 *)Ffs + LoopControl))) {
- Found = TRUE;
- //
- // If NumOfMatchGuid or Offset are NULL, means user only want
- // to check whether current FFS includes this Guid or not.
- //
- if ((NumOfMatchingGuid != NULL) && (Offset != NULL)) {
- if (*NumOfMatchingGuid == 0) {
- *Offset = InternalVarCheckAllocateZeroPool (sizeof (UINTN) * MAX_MATCH_GUID_NUM);
- ASSERT (*Offset != NULL);
- }
-
- *(*Offset + *NumOfMatchingGuid) = LoopControl + sizeof (EFI_GUID);
- (*NumOfMatchingGuid)++;
- } else {
- break;
- }
- }
- }
-
- return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);
-}
-
-/**
- Search the VfrBin Base address.
-
- According to the known GUID gVfrArrayAttractGuid to get the base address from FFS.
-
- @param Ffs Pointer to the FFS.
- @param EfiAddr Pointer to the EFI in FFS
- @param Length The length of FFS.
- @param Offset Pointer to pointer to the Addr (Offset).
- @param NumOfMatchingOffset The number of Addr (Offset).
-
- @retval EFI_SUCCESS Get the address successfully.
- @retval EFI_NOT_FOUND No VfrBin found.
-
-**/
-EFI_STATUS
-SearchVfrBinInFfs (
- IN VOID *Ffs,
- IN VOID *EfiAddr,
- IN UINTN Length,
- OUT UINTN **Offset,
- OUT UINT8 *NumOfMatchingOffset
- )
-{
- UINTN Index;
- EFI_STATUS Status;
- UINTN VirOffValue;
-
- if ((Ffs == NULL) || (Offset == NULL)) {
- return EFI_NOT_FOUND;
- }
-
- Status = GetAddressByGuid (
- Ffs,
- &gVfrArrayAttractGuid,
- Length,
- Offset,
- NumOfMatchingOffset
- );
- if (Status != EFI_SUCCESS) {
- return Status;
- }
-
- for (Index = 0; Index < *NumOfMatchingOffset; Index++) {
- //
- // Got the virOffset after the GUID
- //
- VirOffValue = *(UINTN *)((UINTN)Ffs + *(*Offset + Index));
- //
- // Transfer the offset to the VA address. One modules may own multiple VfrBin address.
- //
- *(*Offset + Index) = (UINTN)EfiAddr + VirOffValue;
- }
-
- return Status;
-}
-
-/**
- Parse FFS.
-
- @param[in] Fv2 Pointer to Fv2 protocol.
- @param[in] DriverGuid Pointer to driver GUID.
-
- @return Found the driver in the FV or not.
-
-**/
-BOOLEAN
-ParseFfs (
- IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv2,
- IN EFI_GUID *DriverGuid
- )
-{
- EFI_STATUS Status;
- EFI_FV_FILETYPE FoundType;
- EFI_FV_FILE_ATTRIBUTES FileAttributes;
- UINT32 AuthenticationStatus;
- UINTN Size;
- VOID *Buffer;
- UINTN SectionSize;
- VOID *SectionBuffer;
- UINTN VfrBinIndex;
- UINT8 NumberofMatchingVfrBin;
- UINTN *VfrBinBaseAddress;
-
- Status = Fv2->ReadFile (
- Fv2,
- DriverGuid,
- NULL,
- &Size,
- &FoundType,
- &FileAttributes,
- &AuthenticationStatus
- );
- if (EFI_ERROR (Status)) {
- return FALSE;
- }
-
- Buffer = NULL;
- Status = Fv2->ReadSection (
- Fv2,
- DriverGuid,
- EFI_SECTION_RAW,
- 0, // Instance
- &Buffer,
- &Size,
- &AuthenticationStatus
- );
- if (!EFI_ERROR (Status)) {
- Status = SearchVfrBinInFfs (Buffer, 0, Size, &VfrBinBaseAddress, &NumberofMatchingVfrBin);
- if (!EFI_ERROR (Status)) {
- SectionBuffer = NULL;
- Status = Fv2->ReadSection (
- Fv2,
- DriverGuid,
- EFI_SECTION_PE32,
- 0, // Instance
- &SectionBuffer,
- &SectionSize,
- &AuthenticationStatus
- );
- if (!EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, "FfsNameGuid - %g\n", DriverGuid));
- DEBUG ((DEBUG_INFO, "NumberofMatchingVfrBin - 0x%02x\n", NumberofMatchingVfrBin));
-
- for (VfrBinIndex = 0; VfrBinIndex < NumberofMatchingVfrBin; VfrBinIndex++) {
- #ifdef DUMP_HII_DATA
- DEBUG_CODE (
- DumpHiiPackage ((UINT8 *)(UINTN)SectionBuffer + VfrBinBaseAddress[VfrBinIndex] + sizeof (UINT32));
- );
- #endif
- VarCheckParseHiiPackage ((UINT8 *)(UINTN)SectionBuffer + VfrBinBaseAddress[VfrBinIndex] + sizeof (UINT32), TRUE);
- }
-
- FreePool (SectionBuffer);
- }
-
- InternalVarCheckFreePool (VfrBinBaseAddress);
- }
-
- FreePool (Buffer);
- }
-
- return TRUE;
-}
-
-/**
- Parse FVs.
-
- @param[in] ScanAll Scan all modules in all FVs or not.
-
-**/
-VOID
-ParseFv (
- IN BOOLEAN ScanAll
- )
-{
- EFI_STATUS Status;
- EFI_HANDLE *HandleBuffer;
- UINTN HandleCount;
- UINTN Index;
- EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv2;
- VOID *Key;
- EFI_FV_FILETYPE FileType;
- EFI_GUID NameGuid;
- EFI_FV_FILE_ATTRIBUTES FileAttributes;
- UINTN Size;
- UINTN FfsIndex;
- VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo;
- LIST_ENTRY *VfrDriverLink;
-
- HandleBuffer = NULL;
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiFirmwareVolume2ProtocolGuid,
- NULL,
- &HandleCount,
- &HandleBuffer
- );
- if (EFI_ERROR (Status)) {
- return;
- }
-
- //
- // Search all FVs
- //
- for (Index = 0; Index < HandleCount; Index++) {
- DEBUG ((DEBUG_INFO, "FvIndex - %x\n", Index));
- Status = gBS->HandleProtocol (
- HandleBuffer[Index],
- &gEfiFirmwareVolume2ProtocolGuid,
- (VOID **)&Fv2
- );
- ASSERT_EFI_ERROR (Status);
-
- DEBUG_CODE_BEGIN ();
- EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *Fvb2;
- EFI_PHYSICAL_ADDRESS FvAddress;
- UINT64 FvSize;
-
- Status = gBS->HandleProtocol (
- HandleBuffer[Index],
- &gEfiFirmwareVolumeBlock2ProtocolGuid,
- (VOID **)&Fvb2
- );
- ASSERT_EFI_ERROR (Status);
- Status = Fvb2->GetPhysicalAddress (Fvb2, &FvAddress);
- if (!EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, "FvAddress - 0x%08x\n", FvAddress));
- FvSize = ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvAddress)->FvLength;
- DEBUG ((DEBUG_INFO, "FvSize - 0x%08x\n", FvSize));
- }
-
- DEBUG_CODE_END ();
-
- if (ScanAll) {
- //
- // Need to parse all modules in all FVs.
- //
- Key = InternalVarCheckAllocateZeroPool (Fv2->KeySize);
- ASSERT (Key != NULL);
-
- for (FfsIndex = 0; ; FfsIndex++) {
- FileType = EFI_FV_FILETYPE_ALL;
- Status = Fv2->GetNextFile (
- Fv2,
- Key,
- &FileType,
- &NameGuid,
- &FileAttributes,
- &Size
- );
- if (EFI_ERROR (Status)) {
- break;
- }
-
- ParseFfs (Fv2, &NameGuid);
- }
-
- InternalVarCheckFreePool (Key);
- } else {
- //
- // Only parse drivers in the VFR drivers list.
- //
- VfrDriverLink = mVfrDriverList.ForwardLink;
- while (VfrDriverLink != &mVfrDriverList) {
- VfrDriverInfo = VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK (VfrDriverLink);
- VfrDriverLink = VfrDriverLink->ForwardLink;
- if (ParseFfs (Fv2, VfrDriverInfo->DriverGuid)) {
- //
- // Found the driver in the FV.
- //
- RemoveEntryList (&VfrDriverInfo->Link);
- InternalVarCheckFreePool (VfrDriverInfo);
- }
- }
- }
- }
-
- FreePool (HandleBuffer);
-}
-
-/**
- Create Vfr Driver List.
-
- @param[in] DriverGuidArray Driver Guid Array
-
-**/
-VOID
-CreateVfrDriverList (
- IN EFI_GUID *DriverGuidArray
- )
-{
- UINTN Index;
- VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo;
-
- for (Index = 0; !IsZeroGuid (&DriverGuidArray[Index]); Index++) {
- DEBUG ((DEBUG_INFO, "CreateVfrDriverList: %g\n", &DriverGuidArray[Index]));
- VfrDriverInfo = InternalVarCheckAllocateZeroPool (sizeof (*VfrDriverInfo));
- ASSERT (VfrDriverInfo != NULL);
- VfrDriverInfo->Signature = VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE;
- VfrDriverInfo->DriverGuid = &DriverGuidArray[Index];
- InsertTailList (&mVfrDriverList, &VfrDriverInfo->Link);
- }
-}
-
-/**
- Destroy Vfr Driver List.
-
-**/
-VOID
-DestroyVfrDriverList (
- VOID
- )
-{
- VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo;
- LIST_ENTRY *VfrDriverLink;
-
- while (mVfrDriverList.ForwardLink != &mVfrDriverList) {
- VfrDriverLink = mVfrDriverList.ForwardLink;
- VfrDriverInfo = VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK (VfrDriverLink);
- RemoveEntryList (&VfrDriverInfo->Link);
- InternalVarCheckFreePool (VfrDriverInfo);
- }
-}
-
-/**
- Generate from FV.
-
-**/
-VOID
-VarCheckHiiGenFromFv (
- VOID
- )
-{
- EFI_GUID *DriverGuidArray;
- BOOLEAN ScanAll;
-
- DEBUG ((DEBUG_INFO, "VarCheckHiiGenDxeFromFv\n"));
-
- //
- // Get vfr driver guid array from PCD.
- //
- DriverGuidArray = (EFI_GUID *)PcdGetPtr (PcdVarCheckVfrDriverGuidArray);
-
- if (IsZeroGuid (&DriverGuidArray[0])) {
- //
- // No VFR driver will be parsed from FVs.
- //
- return;
- }
-
- if (CompareGuid (&DriverGuidArray[0], &mAllFfGuid)) {
- ScanAll = TRUE;
- } else {
- ScanAll = FALSE;
- CreateVfrDriverList (DriverGuidArray);
- }
-
- ParseFv (ScanAll);
-
- if (!ScanAll) {
- DestroyVfrDriverList ();
- }
-}
+/** @file + Var Check Hii generation from FV. + +Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "VarCheckHiiGen.h" + +// {d0bc7cb4-6a47-495f-aa11-710746da06a2} +#define EFI_VFR_ATTRACT_GUID \ +{ 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } } + +EFI_GUID gVfrArrayAttractGuid = EFI_VFR_ATTRACT_GUID; + +#define ALL_FF_GUID \ +{ 0xFFFFFFFF, 0xFFFF, 0xFFFF, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } } + +EFI_GUID mAllFfGuid = ALL_FF_GUID; + +#define VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE SIGNATURE_32 ('V', 'D', 'R', 'I') + +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + EFI_GUID *DriverGuid; +} VAR_CHECK_VFR_DRIVER_INFO; + +LIST_ENTRY mVfrDriverList = INITIALIZE_LIST_HEAD_VARIABLE (mVfrDriverList); + +#define VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK(a) CR (a, VAR_CHECK_VFR_DRIVER_INFO, Link, VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE) + +#define MAX_MATCH_GUID_NUM 100 + +/** + Get the address by Guid. + + Parse the FFS and find the GUID address. + There may be multiple Guids matching the searched Guid. + + @param Ffs Pointer to the FFS. + @param Guid Guid to find. + @param Length The length of FFS. + @param Offset Pointer to pointer to the offset. + @param NumOfMatchingGuid The number of matching Guid. + + @retval EFI_SUCCESS One or multiple Guids matching the searched Guid. + @retval EFI_NOT_FOUND No Guid matching the searched Guid. + +**/ +EFI_STATUS +GetAddressByGuid ( + IN VOID *Ffs, + IN EFI_GUID *Guid, + IN UINTN Length, + OUT UINTN **Offset, + OUT UINT8 *NumOfMatchingGuid + ) +{ + UINTN LoopControl; + BOOLEAN Found; + + if ((Ffs == NULL) || (Guid == NULL) || (Length == 0)) { + return EFI_NOT_FOUND; + } + + if (NumOfMatchingGuid != NULL) { + *NumOfMatchingGuid = 0; + } + + Found = FALSE; + for (LoopControl = 0; LoopControl < Length; LoopControl++) { + if (CompareGuid (Guid, (EFI_GUID *)((UINT8 *)Ffs + LoopControl))) { + Found = TRUE; + // + // If NumOfMatchGuid or Offset are NULL, means user only want + // to check whether current FFS includes this Guid or not. + // + if ((NumOfMatchingGuid != NULL) && (Offset != NULL)) { + if (*NumOfMatchingGuid == 0) { + *Offset = InternalVarCheckAllocateZeroPool (sizeof (UINTN) * MAX_MATCH_GUID_NUM); + ASSERT (*Offset != NULL); + } + + *(*Offset + *NumOfMatchingGuid) = LoopControl + sizeof (EFI_GUID); + (*NumOfMatchingGuid)++; + } else { + break; + } + } + } + + return (Found ? EFI_SUCCESS : EFI_NOT_FOUND); +} + +/** + Search the VfrBin Base address. + + According to the known GUID gVfrArrayAttractGuid to get the base address from FFS. + + @param Ffs Pointer to the FFS. + @param EfiAddr Pointer to the EFI in FFS + @param Length The length of FFS. + @param Offset Pointer to pointer to the Addr (Offset). + @param NumOfMatchingOffset The number of Addr (Offset). + + @retval EFI_SUCCESS Get the address successfully. + @retval EFI_NOT_FOUND No VfrBin found. + +**/ +EFI_STATUS +SearchVfrBinInFfs ( + IN VOID *Ffs, + IN VOID *EfiAddr, + IN UINTN Length, + OUT UINTN **Offset, + OUT UINT8 *NumOfMatchingOffset + ) +{ + UINTN Index; + EFI_STATUS Status; + UINTN VirOffValue; + + if ((Ffs == NULL) || (Offset == NULL)) { + return EFI_NOT_FOUND; + } + + Status = GetAddressByGuid ( + Ffs, + &gVfrArrayAttractGuid, + Length, + Offset, + NumOfMatchingOffset + ); + if (Status != EFI_SUCCESS) { + return Status; + } + + for (Index = 0; Index < *NumOfMatchingOffset; Index++) { + // + // Got the virOffset after the GUID + // + VirOffValue = *(UINTN *)((UINTN)Ffs + *(*Offset + Index)); + // + // Transfer the offset to the VA address. One modules may own multiple VfrBin address. + // + *(*Offset + Index) = (UINTN)EfiAddr + VirOffValue; + } + + return Status; +} + +/** + Parse FFS. + + @param[in] Fv2 Pointer to Fv2 protocol. + @param[in] DriverGuid Pointer to driver GUID. + + @return Found the driver in the FV or not. + +**/ +BOOLEAN +ParseFfs ( + IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv2, + IN EFI_GUID *DriverGuid + ) +{ + EFI_STATUS Status; + EFI_FV_FILETYPE FoundType; + EFI_FV_FILE_ATTRIBUTES FileAttributes; + UINT32 AuthenticationStatus; + UINTN Size; + VOID *Buffer; + UINTN SectionSize; + VOID *SectionBuffer; + UINTN VfrBinIndex; + UINT8 NumberofMatchingVfrBin; + UINTN *VfrBinBaseAddress; + + Status = Fv2->ReadFile ( + Fv2, + DriverGuid, + NULL, + &Size, + &FoundType, + &FileAttributes, + &AuthenticationStatus + ); + if (EFI_ERROR (Status)) { + return FALSE; + } + + Buffer = NULL; + Status = Fv2->ReadSection ( + Fv2, + DriverGuid, + EFI_SECTION_RAW, + 0, // Instance + &Buffer, + &Size, + &AuthenticationStatus + ); + if (!EFI_ERROR (Status)) { + Status = SearchVfrBinInFfs (Buffer, 0, Size, &VfrBinBaseAddress, &NumberofMatchingVfrBin); + if (!EFI_ERROR (Status)) { + SectionBuffer = NULL; + Status = Fv2->ReadSection ( + Fv2, + DriverGuid, + EFI_SECTION_PE32, + 0, // Instance + &SectionBuffer, + &SectionSize, + &AuthenticationStatus + ); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "FfsNameGuid - %g\n", DriverGuid)); + DEBUG ((DEBUG_INFO, "NumberofMatchingVfrBin - 0x%02x\n", NumberofMatchingVfrBin)); + + for (VfrBinIndex = 0; VfrBinIndex < NumberofMatchingVfrBin; VfrBinIndex++) { + #ifdef DUMP_HII_DATA + DEBUG_CODE ( + DumpHiiPackage ((UINT8 *)(UINTN)SectionBuffer + VfrBinBaseAddress[VfrBinIndex] + sizeof (UINT32)); + ); + #endif + VarCheckParseHiiPackage ((UINT8 *)(UINTN)SectionBuffer + VfrBinBaseAddress[VfrBinIndex] + sizeof (UINT32), TRUE); + } + + FreePool (SectionBuffer); + } + + InternalVarCheckFreePool (VfrBinBaseAddress); + } + + FreePool (Buffer); + } + + return TRUE; +} + +/** + Parse FVs. + + @param[in] ScanAll Scan all modules in all FVs or not. + +**/ +VOID +ParseFv ( + IN BOOLEAN ScanAll + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN HandleCount; + UINTN Index; + EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv2; + VOID *Key; + EFI_FV_FILETYPE FileType; + EFI_GUID NameGuid; + EFI_FV_FILE_ATTRIBUTES FileAttributes; + UINTN Size; + UINTN FfsIndex; + VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo; + LIST_ENTRY *VfrDriverLink; + + HandleBuffer = NULL; + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolume2ProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return; + } + + // + // Search all FVs + // + for (Index = 0; Index < HandleCount; Index++) { + DEBUG ((DEBUG_INFO, "FvIndex - %x\n", Index)); + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiFirmwareVolume2ProtocolGuid, + (VOID **)&Fv2 + ); + ASSERT_EFI_ERROR (Status); + + DEBUG_CODE_BEGIN (); + EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *Fvb2; + EFI_PHYSICAL_ADDRESS FvAddress; + UINT64 FvSize; + + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiFirmwareVolumeBlock2ProtocolGuid, + (VOID **)&Fvb2 + ); + ASSERT_EFI_ERROR (Status); + Status = Fvb2->GetPhysicalAddress (Fvb2, &FvAddress); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "FvAddress - 0x%08x\n", FvAddress)); + FvSize = ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvAddress)->FvLength; + DEBUG ((DEBUG_INFO, "FvSize - 0x%08x\n", FvSize)); + } + + DEBUG_CODE_END (); + + if (ScanAll) { + // + // Need to parse all modules in all FVs. + // + Key = InternalVarCheckAllocateZeroPool (Fv2->KeySize); + ASSERT (Key != NULL); + + for (FfsIndex = 0; ; FfsIndex++) { + FileType = EFI_FV_FILETYPE_ALL; + Status = Fv2->GetNextFile ( + Fv2, + Key, + &FileType, + &NameGuid, + &FileAttributes, + &Size + ); + if (EFI_ERROR (Status)) { + break; + } + + ParseFfs (Fv2, &NameGuid); + } + + InternalVarCheckFreePool (Key); + } else { + // + // Only parse drivers in the VFR drivers list. + // + VfrDriverLink = mVfrDriverList.ForwardLink; + while (VfrDriverLink != &mVfrDriverList) { + VfrDriverInfo = VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK (VfrDriverLink); + VfrDriverLink = VfrDriverLink->ForwardLink; + if (ParseFfs (Fv2, VfrDriverInfo->DriverGuid)) { + // + // Found the driver in the FV. + // + RemoveEntryList (&VfrDriverInfo->Link); + InternalVarCheckFreePool (VfrDriverInfo); + } + } + } + } + + FreePool (HandleBuffer); +} + +/** + Create Vfr Driver List. + + @param[in] DriverGuidArray Driver Guid Array + +**/ +VOID +CreateVfrDriverList ( + IN EFI_GUID *DriverGuidArray + ) +{ + UINTN Index; + VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo; + + for (Index = 0; !IsZeroGuid (&DriverGuidArray[Index]); Index++) { + DEBUG ((DEBUG_INFO, "CreateVfrDriverList: %g\n", &DriverGuidArray[Index])); + VfrDriverInfo = InternalVarCheckAllocateZeroPool (sizeof (*VfrDriverInfo)); + ASSERT (VfrDriverInfo != NULL); + VfrDriverInfo->Signature = VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE; + VfrDriverInfo->DriverGuid = &DriverGuidArray[Index]; + InsertTailList (&mVfrDriverList, &VfrDriverInfo->Link); + } +} + +/** + Destroy Vfr Driver List. + +**/ +VOID +DestroyVfrDriverList ( + VOID + ) +{ + VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo; + LIST_ENTRY *VfrDriverLink; + + while (mVfrDriverList.ForwardLink != &mVfrDriverList) { + VfrDriverLink = mVfrDriverList.ForwardLink; + VfrDriverInfo = VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK (VfrDriverLink); + RemoveEntryList (&VfrDriverInfo->Link); + InternalVarCheckFreePool (VfrDriverInfo); + } +} + +/** + Generate from FV. + +**/ +VOID +VarCheckHiiGenFromFv ( + VOID + ) +{ + EFI_GUID *DriverGuidArray; + BOOLEAN ScanAll; + + DEBUG ((DEBUG_INFO, "VarCheckHiiGenDxeFromFv\n")); + + // + // Get vfr driver guid array from PCD. + // + DriverGuidArray = (EFI_GUID *)PcdGetPtr (PcdVarCheckVfrDriverGuidArray); + + if (IsZeroGuid (&DriverGuidArray[0])) { + // + // No VFR driver will be parsed from FVs. + // + return; + } + + if (CompareGuid (&DriverGuidArray[0], &mAllFfGuid)) { + ScanAll = TRUE; + } else { + ScanAll = FALSE; + CreateVfrDriverList (DriverGuidArray); + } + + ParseFv (ScanAll); + + if (!ScanAll) { + DestroyVfrDriverList (); + } +} diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromHii.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromHii.c index 27d10f8bc6..7de1f8b82e 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromHii.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromHii.c @@ -1,67 +1,67 @@ -/** @file
- Var Check Hii generation from Hii Database.
-
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "VarCheckHiiGen.h"
-
-/**
- Generate from Hii Database.
-
-**/
-VOID
-VarCheckHiiGenFromHiiDatabase (
- VOID
- )
-{
- EFI_STATUS Status;
- UINTN BufferSize;
- VOID *Buffer;
- EFI_PHYSICAL_ADDRESS BufferAddress;
- EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
-
- //
- // Locate HII Database protocol
- //
- Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **)&HiiDatabase);
- if (EFI_ERROR (Status)) {
- return;
- }
-
- //
- // Call first time with zero buffer length.
- // Should fail with EFI_BUFFER_TOO_SMALL.
- //
- BufferSize = 0;
- Buffer = NULL;
- Status = HiiDatabase->ExportPackageLists (HiiDatabase, 0, &BufferSize, Buffer);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- //
- // Allocate buffer to hold the HII Database.
- //
- Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES (BufferSize), &BufferAddress);
- ASSERT_EFI_ERROR (Status);
- Buffer = (VOID *)(UINTN)BufferAddress;
-
- //
- // Export HII Database into the buffer.
- //
- Status = HiiDatabase->ExportPackageLists (HiiDatabase, 0, &BufferSize, Buffer);
- ASSERT_EFI_ERROR (Status);
-
- DEBUG ((DEBUG_INFO, "VarCheckHiiGenDxeFromHii - HII Database exported at 0x%x, size = 0x%x\n", Buffer, BufferSize));
-
- #ifdef DUMP_HII_DATA
- DEBUG_CODE (
- DumpHiiDatabase (Buffer, BufferSize);
- );
- #endif
-
- VarCheckParseHiiDatabase (Buffer, BufferSize);
-
- gBS->FreePages (BufferAddress, EFI_SIZE_TO_PAGES (BufferSize));
- }
-}
+/** @file + Var Check Hii generation from Hii Database. + +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "VarCheckHiiGen.h" + +/** + Generate from Hii Database. + +**/ +VOID +VarCheckHiiGenFromHiiDatabase ( + VOID + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + VOID *Buffer; + EFI_PHYSICAL_ADDRESS BufferAddress; + EFI_HII_DATABASE_PROTOCOL *HiiDatabase; + + // + // Locate HII Database protocol + // + Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **)&HiiDatabase); + if (EFI_ERROR (Status)) { + return; + } + + // + // Call first time with zero buffer length. + // Should fail with EFI_BUFFER_TOO_SMALL. + // + BufferSize = 0; + Buffer = NULL; + Status = HiiDatabase->ExportPackageLists (HiiDatabase, 0, &BufferSize, Buffer); + if (Status == EFI_BUFFER_TOO_SMALL) { + // + // Allocate buffer to hold the HII Database. + // + Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES (BufferSize), &BufferAddress); + ASSERT_EFI_ERROR (Status); + Buffer = (VOID *)(UINTN)BufferAddress; + + // + // Export HII Database into the buffer. + // + Status = HiiDatabase->ExportPackageLists (HiiDatabase, 0, &BufferSize, Buffer); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, "VarCheckHiiGenDxeFromHii - HII Database exported at 0x%x, size = 0x%x\n", Buffer, BufferSize)); + + #ifdef DUMP_HII_DATA + DEBUG_CODE ( + DumpHiiDatabase (Buffer, BufferSize); + ); + #endif + + VarCheckParseHiiDatabase (Buffer, BufferSize); + + gBS->FreePages (BufferAddress, EFI_SIZE_TO_PAGES (BufferSize)); + } +} diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf index 9e55d20f28..86d7880449 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf @@ -1,51 +1,51 @@ -## @file
-# NULL class library to register var check HII handler.
-#
-# Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = VarCheckHiiLib
- MODULE_UNI_FILE = VarCheckHiiLib.uni
- FILE_GUID = A34FBDD0-05D3-4AF7-A720-560E91AC8CDF
- MODULE_TYPE = DXE_RUNTIME_DRIVER
- VERSION_STRING = 1.0
- LIBRARY_CLASS = NULL|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
- CONSTRUCTOR = VarCheckHiiLibNullClassConstructor
-
-[Sources]
- VarCheckHiiLibNullClass.c
- VarCheckHii.h
- VarCheckHiiGenFromFv.c
- VarCheckHiiGenFromHii.c
- VarCheckHiiGen.c
- VarCheckHiiGen.h
- InternalVarCheckStructure.h
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
-
-[LibraryClasses]
- BaseLib
- DebugLib
- BaseMemoryLib
- UefiBootServicesTableLib
- MemoryAllocationLib
- PcdLib
- VarCheckLib
-
-[Guids]
- gEdkiiIfrBitVarstoreGuid ## SOMETIMES_CONSUMES ## GUID
-
-[Protocols]
- gEfiFirmwareVolume2ProtocolGuid ## SOMETIMES_CONSUMES
- gEfiFirmwareVolumeBlock2ProtocolGuid ## SOMETIMES_CONSUMES
- gEfiHiiDatabaseProtocolGuid ## SOMETIMES_CONSUMES
-
-[Pcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdVarCheckVfrDriverGuidArray ## SOMETIMES_CONSUMES
+## @file +# NULL class library to register var check HII handler. +# +# Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = VarCheckHiiLib + MODULE_UNI_FILE = VarCheckHiiLib.uni + FILE_GUID = A34FBDD0-05D3-4AF7-A720-560E91AC8CDF + MODULE_TYPE = DXE_RUNTIME_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = NULL|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER + CONSTRUCTOR = VarCheckHiiLibNullClassConstructor + +[Sources] + VarCheckHiiLibNullClass.c + VarCheckHii.h + VarCheckHiiGenFromFv.c + VarCheckHiiGenFromHii.c + VarCheckHiiGen.c + VarCheckHiiGen.h + InternalVarCheckStructure.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + BaseMemoryLib + UefiBootServicesTableLib + MemoryAllocationLib + PcdLib + VarCheckLib + +[Guids] + gEdkiiIfrBitVarstoreGuid ## SOMETIMES_CONSUMES ## GUID + +[Protocols] + gEfiFirmwareVolume2ProtocolGuid ## SOMETIMES_CONSUMES + gEfiFirmwareVolumeBlock2ProtocolGuid ## SOMETIMES_CONSUMES + gEfiHiiDatabaseProtocolGuid ## SOMETIMES_CONSUMES + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdVarCheckVfrDriverGuidArray ## SOMETIMES_CONSUMES diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.uni b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.uni index a7563e9b0b..a46aac3af7 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.uni +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.uni @@ -1,16 +1,16 @@ -// /** @file
-// NULL class library to register var check HII handler.
-//
-// NULL class library to register var check HII handler.
-//
-// Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-
-#string STR_MODULE_ABSTRACT #language en-US "NULL class library to register var check HII handler"
-
-#string STR_MODULE_DESCRIPTION #language en-US "NULL class library to register var check HII handler."
-
+// /** @file +// NULL class library to register var check HII handler. +// +// NULL class library to register var check HII handler. +// +// Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "NULL class library to register var check HII handler" + +#string STR_MODULE_DESCRIPTION #language en-US "NULL class library to register var check HII handler." + diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c index ee2d98c7d1..ef93347dae 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c @@ -1,630 +1,630 @@ -/** @file
- Var Check Hii handler.
-
-Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "VarCheckHii.h"
-
-GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckHiiHex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
-
-/**
- Dump some hexadecimal data.
-
- @param[in] Indent How many spaces to indent the output.
- @param[in] Offset The offset of the dump.
- @param[in] DataSize The size in bytes of UserData.
- @param[in] UserData The data to dump.
-
-**/
-VOID
-VarCheckHiiInternalDumpHex (
- IN UINTN Indent,
- IN UINTN Offset,
- IN UINTN DataSize,
- IN VOID *UserData
- )
-{
- UINT8 *Data;
-
- CHAR8 Val[50];
-
- CHAR8 Str[20];
-
- UINT8 TempByte;
- UINTN Size;
- UINTN Index;
-
- Data = UserData;
- while (DataSize != 0) {
- Size = 16;
- if (Size > DataSize) {
- Size = DataSize;
- }
-
- for (Index = 0; Index < Size; Index += 1) {
- TempByte = Data[Index];
- Val[Index * 3 + 0] = mVarCheckHiiHex[TempByte >> 4];
- Val[Index * 3 + 1] = mVarCheckHiiHex[TempByte & 0xF];
- Val[Index * 3 + 2] = (CHAR8)((Index == 7) ? '-' : ' ');
- Str[Index] = (CHAR8)((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);
- }
-
- Val[Index * 3] = 0;
- Str[Index] = 0;
- DEBUG ((DEBUG_INFO, "%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str));
-
- Data += Size;
- Offset += Size;
- DataSize -= Size;
- }
-}
-
-/**
- Var Check Hii Question.
-
- @param[in] HiiQuestion Pointer to Hii Question
- @param[in] Data Data pointer.
- @param[in] DataSize Size of Data to set.
-
- @retval TRUE Check pass
- @retval FALSE Check fail.
-
-**/
-BOOLEAN
-VarCheckHiiQuestion (
- IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion,
- IN VOID *Data,
- IN UINTN DataSize
- )
-{
- UINT64 OneData;
- UINT64 Minimum;
- UINT64 Maximum;
- UINT64 OneValue;
- UINT8 *Ptr;
- UINT8 Index;
- UINT8 MaxContainers;
- UINT8 StartBit;
- UINT8 EndBit;
- UINT8 TotalBits;
- UINT16 VarOffsetByteLevel;
- UINT8 StorageWidthByteLevel;
-
- if (HiiQuestion->BitFieldStore) {
- VarOffsetByteLevel = HiiQuestion->VarOffset / 8;
- TotalBits = HiiQuestion->VarOffset % 8 + HiiQuestion->StorageWidth;
- StorageWidthByteLevel = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1);
- } else {
- VarOffsetByteLevel = HiiQuestion->VarOffset;
- StorageWidthByteLevel = HiiQuestion->StorageWidth;
- }
-
- if (((UINT32)VarOffsetByteLevel + StorageWidthByteLevel) > DataSize) {
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x)) > Size(0x%x)\n", VarOffsetByteLevel, StorageWidthByteLevel, DataSize));
- return FALSE;
- }
-
- OneData = 0;
- CopyMem (&OneData, (UINT8 *)Data + VarOffsetByteLevel, StorageWidthByteLevel);
- if (HiiQuestion->BitFieldStore) {
- //
- // Get the value from the bit field.
- //
- StartBit = HiiQuestion->VarOffset % 8;
- EndBit = StartBit + HiiQuestion->StorageWidth - 1;
- OneData = BitFieldRead64 (OneData, StartBit, EndBit);
- }
-
- switch (HiiQuestion->OpCode) {
- case EFI_IFR_ONE_OF_OP:
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1);
- while ((UINTN)Ptr < (UINTN)HiiQuestion + HiiQuestion->Length) {
- OneValue = 0;
- if (HiiQuestion->BitFieldStore) {
- //
- // For OneOf stored in bit field, the value of options are saved as UINT32 type.
- //
- CopyMem (&OneValue, Ptr, sizeof (UINT32));
- } else {
- CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
- }
-
- if (OneData == OneValue) {
- //
- // Match
- //
- break;
- }
-
- if (HiiQuestion->BitFieldStore) {
- Ptr += sizeof (UINT32);
- } else {
- Ptr += HiiQuestion->StorageWidth;
- }
- }
-
- if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) {
- //
- // No match
- //
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OneOf mismatch (0x%lx)\n", OneData));
- DEBUG_CODE (
- VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);
- );
- return FALSE;
- }
-
- break;
-
- case EFI_IFR_CHECKBOX_OP:
- if ((OneData != 0) && (OneData != 1)) {
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: CheckBox mismatch (0x%lx)\n", OneData));
- DEBUG_CODE (
- VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);
- );
- return FALSE;
- }
-
- break;
-
- case EFI_IFR_NUMERIC_OP:
- Minimum = 0;
- Maximum = 0;
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1);
- if (HiiQuestion->BitFieldStore) {
- //
- // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type.
- //
- CopyMem (&Minimum, Ptr, sizeof (UINT32));
- Ptr += sizeof (UINT32);
- CopyMem (&Maximum, Ptr, sizeof (UINT32));
- Ptr += sizeof (UINT32);
- } else {
- CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth);
- Ptr += HiiQuestion->StorageWidth;
- CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth);
- Ptr += HiiQuestion->StorageWidth;
- }
-
- //
- // No need to check Step, because it is ONLY for UI.
- //
- if ((OneData < Minimum) || (OneData > Maximum)) {
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: Numeric mismatch (0x%lx)\n", OneData));
- DEBUG_CODE (
- VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);
- );
- return FALSE;
- }
-
- break;
-
- case EFI_IFR_ORDERED_LIST_OP:
- MaxContainers = ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers;
- if (((UINT32)HiiQuestion->VarOffset + HiiQuestion->StorageWidth * MaxContainers) > DataSize) {
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x) * MaxContainers(0x%02x)) > Size(0x%x)\n", HiiQuestion->VarOffset, HiiQuestion->StorageWidth, MaxContainers, DataSize));
- return FALSE;
- }
-
- for (Index = 0; Index < MaxContainers; Index++) {
- OneData = 0;
- CopyMem (&OneData, (UINT8 *)Data + HiiQuestion->VarOffset + HiiQuestion->StorageWidth * Index, HiiQuestion->StorageWidth);
- if (OneData == 0) {
- //
- // The value of 0 is used to determine if a particular "slot" in the array is empty.
- //
- continue;
- }
-
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1);
- while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) {
- OneValue = 0;
- CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
- if (OneData == OneValue) {
- //
- // Match
- //
- break;
- }
-
- Ptr += HiiQuestion->StorageWidth;
- }
-
- if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) {
- //
- // No match
- //
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OrderedList mismatch\n"));
- DEBUG_CODE (
- VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->StorageWidth * MaxContainers, (UINT8 *)Data + HiiQuestion->VarOffset);
- );
- DEBUG_CODE (
- VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);
- );
- return FALSE;
- }
- }
-
- break;
-
- default:
- ASSERT (FALSE);
- break;
- }
-
- return TRUE;
-}
-
-VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin = NULL;
-UINTN mVarCheckHiiBinSize = 0;
-
-/**
- SetVariable check handler HII.
-
- @param[in] VariableName Name of Variable to set.
- @param[in] VendorGuid Variable vendor GUID.
- @param[in] Attributes Attribute value of the variable.
- @param[in] DataSize Size of Data to set.
- @param[in] Data Data pointer.
-
- @retval EFI_SUCCESS The SetVariable check result was success.
- @retval EFI_SECURITY_VIOLATION Check fail.
-
-**/
-EFI_STATUS
-EFIAPI
-SetVariableCheckHandlerHii (
- IN CHAR16 *VariableName,
- IN EFI_GUID *VendorGuid,
- IN UINT32 Attributes,
- IN UINTN DataSize,
- IN VOID *Data
- )
-{
- VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;
- VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;
-
- if (mVarCheckHiiBin == NULL) {
- return EFI_SUCCESS;
- }
-
- if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {
- //
- // Do not check delete variable.
- //
- return EFI_SUCCESS;
- }
-
- //
- // For Hii Variable header align.
- //
- HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (mVarCheckHiiBin);
- while ((UINTN)HiiVariable < ((UINTN)mVarCheckHiiBin + mVarCheckHiiBinSize)) {
- if ((StrCmp ((CHAR16 *)(HiiVariable + 1), VariableName) == 0) &&
- (CompareGuid (&HiiVariable->Guid, VendorGuid)))
- {
- //
- // Found the Hii Variable that could be used to do check.
- //
- DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - %s:%g with Attributes = 0x%08x Size = 0x%x\n", VariableName, VendorGuid, Attributes, DataSize));
- if (HiiVariable->Attributes != Attributes) {
- DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Attributes - 0x%08x\n", HiiVariable->Attributes));
- return EFI_SECURITY_VIOLATION;
- }
-
- if (DataSize == 0) {
- DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - CHECK PASS with DataSize == 0 !\n"));
- return EFI_SUCCESS;
- }
-
- if (HiiVariable->Size != DataSize) {
- DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Size - 0x%x\n", HiiVariable->Size));
- return EFI_SECURITY_VIOLATION;
- }
-
- //
- // Do the check.
- // For Hii Question header align.
- //
- HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength));
- while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) {
- if (!VarCheckHiiQuestion (HiiQuestion, Data, DataSize)) {
- return EFI_SECURITY_VIOLATION;
- }
-
- //
- // For Hii Question header align.
- //
- HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length));
- }
-
- DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - ALL CHECK PASS!\n"));
- return EFI_SUCCESS;
- }
-
- //
- // For Hii Variable header align.
- //
- HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length));
- }
-
- // Not found, so pass.
- return EFI_SUCCESS;
-}
-
-#ifdef DUMP_VAR_CHECK_HII
-GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_OPCODE_STRING mHiiOpCodeStringTable[] = {
- { EFI_IFR_VARSTORE_EFI_OP, "EfiVarStore" },
- { EFI_IFR_ONE_OF_OP, "OneOf" },
- { EFI_IFR_CHECKBOX_OP, "CheckBox" },
- { EFI_IFR_NUMERIC_OP, "Numeric" },
- { EFI_IFR_ORDERED_LIST_OP, "OrderedList" },
-};
-
-/**
- HII opcode to string.
-
- @param[in] HiiOpCode Hii OpCode.
-
- @return Pointer to string.
-
-**/
-CHAR8 *
-HiiOpCodeToStr (
- IN UINT8 HiiOpCode
- )
-{
- UINTN Index;
-
- for (Index = 0; Index < ARRAY_SIZE (mHiiOpCodeStringTable); Index++) {
- if (mHiiOpCodeStringTable[Index].HiiOpCode == HiiOpCode) {
- return mHiiOpCodeStringTable[Index].HiiOpCodeStr;
- }
- }
-
- return "<UnknownHiiOpCode>";
-}
-
-/**
- Dump Hii Question.
-
- @param[in] HiiQuestion Pointer to Hii Question.
-
-**/
-VOID
-DumpHiiQuestion (
- IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion
- )
-{
- UINT64 Minimum;
- UINT64 Maximum;
- UINT64 OneValue;
- UINT8 *Ptr;
-
- DEBUG ((DEBUG_INFO, " VAR_CHECK_HII_QUESTION_HEADER\n"));
- DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a) (%a)\n", HiiQuestion->OpCode, HiiOpCodeToStr (HiiQuestion->OpCode), (HiiQuestion->BitFieldStore ? "bit level" : "byte level")));
- DEBUG ((DEBUG_INFO, " Length - 0x%02x\n", HiiQuestion->Length));
- DEBUG ((DEBUG_INFO, " VarOffset - 0x%04x (%a)\n", HiiQuestion->VarOffset, (HiiQuestion->BitFieldStore ? "bit level" : "byte level")));
- DEBUG ((DEBUG_INFO, " StorageWidth - 0x%02x (%a)\n", HiiQuestion->StorageWidth, (HiiQuestion->BitFieldStore ? "bit level" : "byte level")));
-
- switch (HiiQuestion->OpCode) {
- case EFI_IFR_ONE_OF_OP:
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1);
- while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) {
- OneValue = 0;
- if (HiiQuestion->BitFieldStore) {
- //
- // For OneOf stored in bit field, the value of options are saved as UINT32 type.
- //
- CopyMem (&OneValue, Ptr, sizeof (UINT32));
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue));
- } else {
- CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
- switch (HiiQuestion->StorageWidth) {
- case sizeof (UINT8):
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue));
- break;
- case sizeof (UINT16):
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue));
- break;
- case sizeof (UINT32):
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue));
- break;
- case sizeof (UINT64):
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue));
- break;
- default:
- ASSERT (FALSE);
- break;
- }
- }
-
- if (HiiQuestion->BitFieldStore) {
- Ptr += sizeof (UINT32);
- } else {
- Ptr += HiiQuestion->StorageWidth;
- }
- }
-
- break;
-
- case EFI_IFR_CHECKBOX_OP:
- break;
-
- case EFI_IFR_NUMERIC_OP:
- Minimum = 0;
- Maximum = 0;
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1);
- if (HiiQuestion->BitFieldStore) {
- //
- // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type.
- //
- CopyMem (&Minimum, Ptr, sizeof (UINT32));
- Ptr += sizeof (UINT32);
- CopyMem (&Maximum, Ptr, sizeof (UINT32));
- Ptr += sizeof (UINT32);
-
- DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum));
- DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum));
- } else {
- CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth);
- Ptr += HiiQuestion->StorageWidth;
- CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth);
- Ptr += HiiQuestion->StorageWidth;
-
- switch (HiiQuestion->StorageWidth) {
- case sizeof (UINT8):
- DEBUG ((DEBUG_INFO, " Minimum - 0x%02x\n", Minimum));
- DEBUG ((DEBUG_INFO, " Maximum - 0x%02x\n", Maximum));
- break;
- case sizeof (UINT16):
- DEBUG ((DEBUG_INFO, " Minimum - 0x%04x\n", Minimum));
- DEBUG ((DEBUG_INFO, " Maximum - 0x%04x\n", Maximum));
- break;
- case sizeof (UINT32):
- DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum));
- DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum));
- break;
- case sizeof (UINT64):
- DEBUG ((DEBUG_INFO, " Minimum - 0x%016lx\n", Minimum));
- DEBUG ((DEBUG_INFO, " Maximum - 0x%016lx\n", Maximum));
- break;
- default:
- ASSERT (FALSE);
- break;
- }
- }
-
- break;
-
- case EFI_IFR_ORDERED_LIST_OP:
- DEBUG ((DEBUG_INFO, " MaxContainers - 0x%02x\n", ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers));
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1);
- while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) {
- OneValue = 0;
- CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
- switch (HiiQuestion->StorageWidth) {
- case sizeof (UINT8):
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue));
- break;
- case sizeof (UINT16):
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue));
- break;
- case sizeof (UINT32):
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue));
- break;
- case sizeof (UINT64):
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue));
- break;
- default:
- ASSERT (FALSE);
- break;
- }
-
- Ptr += HiiQuestion->StorageWidth;
- }
-
- break;
-
- default:
- ASSERT (FALSE);
- break;
- }
-}
-
-/**
- Dump Hii Variable.
-
- @param[in] HiiVariable Pointer to Hii Variable.
-
-**/
-VOID
-DumpHiiVariable (
- IN VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable
- )
-{
- VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;
-
- DEBUG ((DEBUG_INFO, "VAR_CHECK_HII_VARIABLE_HEADER\n"));
- DEBUG ((DEBUG_INFO, " Revision - 0x%04x\n", HiiVariable->Revision));
- DEBUG ((DEBUG_INFO, " HeaderLength - 0x%04x\n", HiiVariable->HeaderLength));
- DEBUG ((DEBUG_INFO, " Length - 0x%08x\n", HiiVariable->Length));
- DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a)\n", HiiVariable->OpCode, HiiOpCodeToStr (HiiVariable->OpCode)));
- DEBUG ((DEBUG_INFO, " Size - 0x%04x\n", HiiVariable->Size));
- DEBUG ((DEBUG_INFO, " Attributes - 0x%08x\n", HiiVariable->Attributes));
- DEBUG ((DEBUG_INFO, " Guid - %g\n", &HiiVariable->Guid));
- DEBUG ((DEBUG_INFO, " Name - %s\n", HiiVariable + 1));
-
- //
- // For Hii Question header align.
- //
- HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength));
- while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) {
- //
- // Dump Hii Question related to the Hii Variable.
- //
- DumpHiiQuestion (HiiQuestion);
- //
- // For Hii Question header align.
- //
- HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length));
- }
-}
-
-/**
- Dump Var Check HII.
-
- @param[in] VarCheckHiiBin Pointer to VarCheckHiiBin.
- @param[in] VarCheckHiiBinSize VarCheckHiiBin size.
-
-**/
-VOID
-DumpVarCheckHii (
- IN VOID *VarCheckHiiBin,
- IN UINTN VarCheckHiiBinSize
- )
-{
- VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;
-
- DEBUG ((DEBUG_INFO, "DumpVarCheckHii\n"));
-
- //
- // For Hii Variable header align.
- //
- HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (VarCheckHiiBin);
- while ((UINTN)HiiVariable < ((UINTN)VarCheckHiiBin + VarCheckHiiBinSize)) {
- DumpHiiVariable (HiiVariable);
- //
- // For Hii Variable header align.
- //
- HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length));
- }
-}
-
-#endif
-
-/**
- Constructor function of VarCheckHiiLib to register var check HII handler.
-
- @param[in] ImageHandle The firmware allocated handle for the EFI image.
- @param[in] SystemTable A pointer to the EFI System Table.
-
- @retval EFI_SUCCESS The constructor executed correctly.
-
-**/
-EFI_STATUS
-EFIAPI
-VarCheckHiiLibNullClassConstructor (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- VarCheckLibRegisterEndOfDxeCallback (VarCheckHiiGen);
- VarCheckLibRegisterAddressPointer ((VOID **)&mVarCheckHiiBin);
- VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerHii);
-
- return EFI_SUCCESS;
-}
+/** @file + Var Check Hii handler. + +Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "VarCheckHii.h" + +GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckHiiHex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + +/** + Dump some hexadecimal data. + + @param[in] Indent How many spaces to indent the output. + @param[in] Offset The offset of the dump. + @param[in] DataSize The size in bytes of UserData. + @param[in] UserData The data to dump. + +**/ +VOID +VarCheckHiiInternalDumpHex ( + IN UINTN Indent, + IN UINTN Offset, + IN UINTN DataSize, + IN VOID *UserData + ) +{ + UINT8 *Data; + + CHAR8 Val[50]; + + CHAR8 Str[20]; + + UINT8 TempByte; + UINTN Size; + UINTN Index; + + Data = UserData; + while (DataSize != 0) { + Size = 16; + if (Size > DataSize) { + Size = DataSize; + } + + for (Index = 0; Index < Size; Index += 1) { + TempByte = Data[Index]; + Val[Index * 3 + 0] = mVarCheckHiiHex[TempByte >> 4]; + Val[Index * 3 + 1] = mVarCheckHiiHex[TempByte & 0xF]; + Val[Index * 3 + 2] = (CHAR8)((Index == 7) ? '-' : ' '); + Str[Index] = (CHAR8)((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte); + } + + Val[Index * 3] = 0; + Str[Index] = 0; + DEBUG ((DEBUG_INFO, "%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str)); + + Data += Size; + Offset += Size; + DataSize -= Size; + } +} + +/** + Var Check Hii Question. + + @param[in] HiiQuestion Pointer to Hii Question + @param[in] Data Data pointer. + @param[in] DataSize Size of Data to set. + + @retval TRUE Check pass + @retval FALSE Check fail. + +**/ +BOOLEAN +VarCheckHiiQuestion ( + IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion, + IN VOID *Data, + IN UINTN DataSize + ) +{ + UINT64 OneData; + UINT64 Minimum; + UINT64 Maximum; + UINT64 OneValue; + UINT8 *Ptr; + UINT8 Index; + UINT8 MaxContainers; + UINT8 StartBit; + UINT8 EndBit; + UINT8 TotalBits; + UINT16 VarOffsetByteLevel; + UINT8 StorageWidthByteLevel; + + if (HiiQuestion->BitFieldStore) { + VarOffsetByteLevel = HiiQuestion->VarOffset / 8; + TotalBits = HiiQuestion->VarOffset % 8 + HiiQuestion->StorageWidth; + StorageWidthByteLevel = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1); + } else { + VarOffsetByteLevel = HiiQuestion->VarOffset; + StorageWidthByteLevel = HiiQuestion->StorageWidth; + } + + if (((UINT32)VarOffsetByteLevel + StorageWidthByteLevel) > DataSize) { + DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x)) > Size(0x%x)\n", VarOffsetByteLevel, StorageWidthByteLevel, DataSize)); + return FALSE; + } + + OneData = 0; + CopyMem (&OneData, (UINT8 *)Data + VarOffsetByteLevel, StorageWidthByteLevel); + if (HiiQuestion->BitFieldStore) { + // + // Get the value from the bit field. + // + StartBit = HiiQuestion->VarOffset % 8; + EndBit = StartBit + HiiQuestion->StorageWidth - 1; + OneData = BitFieldRead64 (OneData, StartBit, EndBit); + } + + switch (HiiQuestion->OpCode) { + case EFI_IFR_ONE_OF_OP: + Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1); + while ((UINTN)Ptr < (UINTN)HiiQuestion + HiiQuestion->Length) { + OneValue = 0; + if (HiiQuestion->BitFieldStore) { + // + // For OneOf stored in bit field, the value of options are saved as UINT32 type. + // + CopyMem (&OneValue, Ptr, sizeof (UINT32)); + } else { + CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth); + } + + if (OneData == OneValue) { + // + // Match + // + break; + } + + if (HiiQuestion->BitFieldStore) { + Ptr += sizeof (UINT32); + } else { + Ptr += HiiQuestion->StorageWidth; + } + } + + if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) { + // + // No match + // + DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OneOf mismatch (0x%lx)\n", OneData)); + DEBUG_CODE ( + VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion); + ); + return FALSE; + } + + break; + + case EFI_IFR_CHECKBOX_OP: + if ((OneData != 0) && (OneData != 1)) { + DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: CheckBox mismatch (0x%lx)\n", OneData)); + DEBUG_CODE ( + VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion); + ); + return FALSE; + } + + break; + + case EFI_IFR_NUMERIC_OP: + Minimum = 0; + Maximum = 0; + Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1); + if (HiiQuestion->BitFieldStore) { + // + // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type. + // + CopyMem (&Minimum, Ptr, sizeof (UINT32)); + Ptr += sizeof (UINT32); + CopyMem (&Maximum, Ptr, sizeof (UINT32)); + Ptr += sizeof (UINT32); + } else { + CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth); + Ptr += HiiQuestion->StorageWidth; + CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth); + Ptr += HiiQuestion->StorageWidth; + } + + // + // No need to check Step, because it is ONLY for UI. + // + if ((OneData < Minimum) || (OneData > Maximum)) { + DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: Numeric mismatch (0x%lx)\n", OneData)); + DEBUG_CODE ( + VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion); + ); + return FALSE; + } + + break; + + case EFI_IFR_ORDERED_LIST_OP: + MaxContainers = ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers; + if (((UINT32)HiiQuestion->VarOffset + HiiQuestion->StorageWidth * MaxContainers) > DataSize) { + DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x) * MaxContainers(0x%02x)) > Size(0x%x)\n", HiiQuestion->VarOffset, HiiQuestion->StorageWidth, MaxContainers, DataSize)); + return FALSE; + } + + for (Index = 0; Index < MaxContainers; Index++) { + OneData = 0; + CopyMem (&OneData, (UINT8 *)Data + HiiQuestion->VarOffset + HiiQuestion->StorageWidth * Index, HiiQuestion->StorageWidth); + if (OneData == 0) { + // + // The value of 0 is used to determine if a particular "slot" in the array is empty. + // + continue; + } + + Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1); + while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) { + OneValue = 0; + CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth); + if (OneData == OneValue) { + // + // Match + // + break; + } + + Ptr += HiiQuestion->StorageWidth; + } + + if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) { + // + // No match + // + DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OrderedList mismatch\n")); + DEBUG_CODE ( + VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->StorageWidth * MaxContainers, (UINT8 *)Data + HiiQuestion->VarOffset); + ); + DEBUG_CODE ( + VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion); + ); + return FALSE; + } + } + + break; + + default: + ASSERT (FALSE); + break; + } + + return TRUE; +} + +VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin = NULL; +UINTN mVarCheckHiiBinSize = 0; + +/** + SetVariable check handler HII. + + @param[in] VariableName Name of Variable to set. + @param[in] VendorGuid Variable vendor GUID. + @param[in] Attributes Attribute value of the variable. + @param[in] DataSize Size of Data to set. + @param[in] Data Data pointer. + + @retval EFI_SUCCESS The SetVariable check result was success. + @retval EFI_SECURITY_VIOLATION Check fail. + +**/ +EFI_STATUS +EFIAPI +SetVariableCheckHandlerHii ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable; + VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion; + + if (mVarCheckHiiBin == NULL) { + return EFI_SUCCESS; + } + + if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) { + // + // Do not check delete variable. + // + return EFI_SUCCESS; + } + + // + // For Hii Variable header align. + // + HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (mVarCheckHiiBin); + while ((UINTN)HiiVariable < ((UINTN)mVarCheckHiiBin + mVarCheckHiiBinSize)) { + if ((StrCmp ((CHAR16 *)(HiiVariable + 1), VariableName) == 0) && + (CompareGuid (&HiiVariable->Guid, VendorGuid))) + { + // + // Found the Hii Variable that could be used to do check. + // + DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - %s:%g with Attributes = 0x%08x Size = 0x%x\n", VariableName, VendorGuid, Attributes, DataSize)); + if (HiiVariable->Attributes != Attributes) { + DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Attributes - 0x%08x\n", HiiVariable->Attributes)); + return EFI_SECURITY_VIOLATION; + } + + if (DataSize == 0) { + DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - CHECK PASS with DataSize == 0 !\n")); + return EFI_SUCCESS; + } + + if (HiiVariable->Size != DataSize) { + DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Size - 0x%x\n", HiiVariable->Size)); + return EFI_SECURITY_VIOLATION; + } + + // + // Do the check. + // For Hii Question header align. + // + HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength)); + while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) { + if (!VarCheckHiiQuestion (HiiQuestion, Data, DataSize)) { + return EFI_SECURITY_VIOLATION; + } + + // + // For Hii Question header align. + // + HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length)); + } + + DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - ALL CHECK PASS!\n")); + return EFI_SUCCESS; + } + + // + // For Hii Variable header align. + // + HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length)); + } + + // Not found, so pass. + return EFI_SUCCESS; +} + +#ifdef DUMP_VAR_CHECK_HII +GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_OPCODE_STRING mHiiOpCodeStringTable[] = { + { EFI_IFR_VARSTORE_EFI_OP, "EfiVarStore" }, + { EFI_IFR_ONE_OF_OP, "OneOf" }, + { EFI_IFR_CHECKBOX_OP, "CheckBox" }, + { EFI_IFR_NUMERIC_OP, "Numeric" }, + { EFI_IFR_ORDERED_LIST_OP, "OrderedList" }, +}; + +/** + HII opcode to string. + + @param[in] HiiOpCode Hii OpCode. + + @return Pointer to string. + +**/ +CHAR8 * +HiiOpCodeToStr ( + IN UINT8 HiiOpCode + ) +{ + UINTN Index; + + for (Index = 0; Index < ARRAY_SIZE (mHiiOpCodeStringTable); Index++) { + if (mHiiOpCodeStringTable[Index].HiiOpCode == HiiOpCode) { + return mHiiOpCodeStringTable[Index].HiiOpCodeStr; + } + } + + return "<UnknownHiiOpCode>"; +} + +/** + Dump Hii Question. + + @param[in] HiiQuestion Pointer to Hii Question. + +**/ +VOID +DumpHiiQuestion ( + IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion + ) +{ + UINT64 Minimum; + UINT64 Maximum; + UINT64 OneValue; + UINT8 *Ptr; + + DEBUG ((DEBUG_INFO, " VAR_CHECK_HII_QUESTION_HEADER\n")); + DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a) (%a)\n", HiiQuestion->OpCode, HiiOpCodeToStr (HiiQuestion->OpCode), (HiiQuestion->BitFieldStore ? "bit level" : "byte level"))); + DEBUG ((DEBUG_INFO, " Length - 0x%02x\n", HiiQuestion->Length)); + DEBUG ((DEBUG_INFO, " VarOffset - 0x%04x (%a)\n", HiiQuestion->VarOffset, (HiiQuestion->BitFieldStore ? "bit level" : "byte level"))); + DEBUG ((DEBUG_INFO, " StorageWidth - 0x%02x (%a)\n", HiiQuestion->StorageWidth, (HiiQuestion->BitFieldStore ? "bit level" : "byte level"))); + + switch (HiiQuestion->OpCode) { + case EFI_IFR_ONE_OF_OP: + Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1); + while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) { + OneValue = 0; + if (HiiQuestion->BitFieldStore) { + // + // For OneOf stored in bit field, the value of options are saved as UINT32 type. + // + CopyMem (&OneValue, Ptr, sizeof (UINT32)); + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue)); + } else { + CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth); + switch (HiiQuestion->StorageWidth) { + case sizeof (UINT8): + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue)); + break; + case sizeof (UINT16): + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue)); + break; + case sizeof (UINT32): + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue)); + break; + case sizeof (UINT64): + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue)); + break; + default: + ASSERT (FALSE); + break; + } + } + + if (HiiQuestion->BitFieldStore) { + Ptr += sizeof (UINT32); + } else { + Ptr += HiiQuestion->StorageWidth; + } + } + + break; + + case EFI_IFR_CHECKBOX_OP: + break; + + case EFI_IFR_NUMERIC_OP: + Minimum = 0; + Maximum = 0; + Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1); + if (HiiQuestion->BitFieldStore) { + // + // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type. + // + CopyMem (&Minimum, Ptr, sizeof (UINT32)); + Ptr += sizeof (UINT32); + CopyMem (&Maximum, Ptr, sizeof (UINT32)); + Ptr += sizeof (UINT32); + + DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum)); + DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum)); + } else { + CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth); + Ptr += HiiQuestion->StorageWidth; + CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth); + Ptr += HiiQuestion->StorageWidth; + + switch (HiiQuestion->StorageWidth) { + case sizeof (UINT8): + DEBUG ((DEBUG_INFO, " Minimum - 0x%02x\n", Minimum)); + DEBUG ((DEBUG_INFO, " Maximum - 0x%02x\n", Maximum)); + break; + case sizeof (UINT16): + DEBUG ((DEBUG_INFO, " Minimum - 0x%04x\n", Minimum)); + DEBUG ((DEBUG_INFO, " Maximum - 0x%04x\n", Maximum)); + break; + case sizeof (UINT32): + DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum)); + DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum)); + break; + case sizeof (UINT64): + DEBUG ((DEBUG_INFO, " Minimum - 0x%016lx\n", Minimum)); + DEBUG ((DEBUG_INFO, " Maximum - 0x%016lx\n", Maximum)); + break; + default: + ASSERT (FALSE); + break; + } + } + + break; + + case EFI_IFR_ORDERED_LIST_OP: + DEBUG ((DEBUG_INFO, " MaxContainers - 0x%02x\n", ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers)); + Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1); + while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) { + OneValue = 0; + CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth); + switch (HiiQuestion->StorageWidth) { + case sizeof (UINT8): + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue)); + break; + case sizeof (UINT16): + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue)); + break; + case sizeof (UINT32): + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue)); + break; + case sizeof (UINT64): + DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue)); + break; + default: + ASSERT (FALSE); + break; + } + + Ptr += HiiQuestion->StorageWidth; + } + + break; + + default: + ASSERT (FALSE); + break; + } +} + +/** + Dump Hii Variable. + + @param[in] HiiVariable Pointer to Hii Variable. + +**/ +VOID +DumpHiiVariable ( + IN VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable + ) +{ + VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion; + + DEBUG ((DEBUG_INFO, "VAR_CHECK_HII_VARIABLE_HEADER\n")); + DEBUG ((DEBUG_INFO, " Revision - 0x%04x\n", HiiVariable->Revision)); + DEBUG ((DEBUG_INFO, " HeaderLength - 0x%04x\n", HiiVariable->HeaderLength)); + DEBUG ((DEBUG_INFO, " Length - 0x%08x\n", HiiVariable->Length)); + DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a)\n", HiiVariable->OpCode, HiiOpCodeToStr (HiiVariable->OpCode))); + DEBUG ((DEBUG_INFO, " Size - 0x%04x\n", HiiVariable->Size)); + DEBUG ((DEBUG_INFO, " Attributes - 0x%08x\n", HiiVariable->Attributes)); + DEBUG ((DEBUG_INFO, " Guid - %g\n", &HiiVariable->Guid)); + DEBUG ((DEBUG_INFO, " Name - %s\n", HiiVariable + 1)); + + // + // For Hii Question header align. + // + HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength)); + while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) { + // + // Dump Hii Question related to the Hii Variable. + // + DumpHiiQuestion (HiiQuestion); + // + // For Hii Question header align. + // + HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length)); + } +} + +/** + Dump Var Check HII. + + @param[in] VarCheckHiiBin Pointer to VarCheckHiiBin. + @param[in] VarCheckHiiBinSize VarCheckHiiBin size. + +**/ +VOID +DumpVarCheckHii ( + IN VOID *VarCheckHiiBin, + IN UINTN VarCheckHiiBinSize + ) +{ + VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable; + + DEBUG ((DEBUG_INFO, "DumpVarCheckHii\n")); + + // + // For Hii Variable header align. + // + HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (VarCheckHiiBin); + while ((UINTN)HiiVariable < ((UINTN)VarCheckHiiBin + VarCheckHiiBinSize)) { + DumpHiiVariable (HiiVariable); + // + // For Hii Variable header align. + // + HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length)); + } +} + +#endif + +/** + Constructor function of VarCheckHiiLib to register var check HII handler. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor executed correctly. + +**/ +EFI_STATUS +EFIAPI +VarCheckHiiLibNullClassConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + VarCheckLibRegisterEndOfDxeCallback (VarCheckHiiGen); + VarCheckLibRegisterAddressPointer ((VOID **)&mVarCheckHiiBin); + VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerHii); + + return EFI_SUCCESS; +} |
