summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Library/VarCheckHiiLib
diff options
context:
space:
mode:
authorkx <kx@radix.pro>2024-06-04 06:43:08 +0300
committerkx <kx@radix.pro>2024-06-04 06:43:08 +0300
commit7e2ccccace24636f29ddc210b94606abd4c7e42b (patch)
tree545d43ea12671048956cafeb12303e84d601e571 /MdeModulePkg/Library/VarCheckHiiLib
parent27b044605cd5f6b33a3d231576003850b3fe305b (diff)
downloadedk2-trunk.tar.xz
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'MdeModulePkg/Library/VarCheckHiiLib')
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/InternalVarCheckStructure.h162
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h114
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c3274
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.h260
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c880
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromHii.c134
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf102
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.uni32
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c1260
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;
+}