No functional changes.
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Hongbin1 Zhang <hongbin1.zhang@intel.com>
Cc: Wei6 Xu <wei6.xu@intel.com>
Cc: Dun Tan <dun.tan@intel.com>
Cc: Dandan Bi <dandan.bi@intel.com>
Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
--- /dev/null
+/** @file\r
+ Var Check Hii handler.\r
+\r
+Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "VarCheckHii.h"\r
+#include "VarCheckHiiGen.h"\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckHiiHex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };\r
+\r
+/**\r
+ Dump some hexadecimal data.\r
+\r
+ @param[in] Indent How many spaces to indent the output.\r
+ @param[in] Offset The offset of the dump.\r
+ @param[in] DataSize The size in bytes of UserData.\r
+ @param[in] UserData The data to dump.\r
+\r
+**/\r
+VOID\r
+VarCheckHiiInternalDumpHex (\r
+ IN UINTN Indent,\r
+ IN UINTN Offset,\r
+ IN UINTN DataSize,\r
+ IN VOID *UserData\r
+ )\r
+{\r
+ UINT8 *Data;\r
+\r
+ CHAR8 Val[50];\r
+\r
+ CHAR8 Str[20];\r
+\r
+ UINT8 TempByte;\r
+ UINTN Size;\r
+ UINTN Index;\r
+\r
+ Data = UserData;\r
+ while (DataSize != 0) {\r
+ Size = 16;\r
+ if (Size > DataSize) {\r
+ Size = DataSize;\r
+ }\r
+\r
+ for (Index = 0; Index < Size; Index += 1) {\r
+ TempByte = Data[Index];\r
+ Val[Index * 3 + 0] = mVarCheckHiiHex[TempByte >> 4];\r
+ Val[Index * 3 + 1] = mVarCheckHiiHex[TempByte & 0xF];\r
+ Val[Index * 3 + 2] = (CHAR8)((Index == 7) ? '-' : ' ');\r
+ Str[Index] = (CHAR8)((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);\r
+ }\r
+\r
+ Val[Index * 3] = 0;\r
+ Str[Index] = 0;\r
+ DEBUG ((DEBUG_INFO, "%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str));\r
+\r
+ Data += Size;\r
+ Offset += Size;\r
+ DataSize -= Size;\r
+ }\r
+}\r
+\r
+/**\r
+ Var Check Hii Question.\r
+\r
+ @param[in] HiiQuestion Pointer to Hii Question\r
+ @param[in] Data Data pointer.\r
+ @param[in] DataSize Size of Data to set.\r
+\r
+ @retval TRUE Check pass\r
+ @retval FALSE Check fail.\r
+\r
+**/\r
+BOOLEAN\r
+VarCheckHiiQuestion (\r
+ IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion,\r
+ IN VOID *Data,\r
+ IN UINTN DataSize\r
+ )\r
+{\r
+ UINT64 OneData;\r
+ UINT64 Minimum;\r
+ UINT64 Maximum;\r
+ UINT64 OneValue;\r
+ UINT8 *Ptr;\r
+ UINT8 Index;\r
+ UINT8 MaxContainers;\r
+ UINT8 StartBit;\r
+ UINT8 EndBit;\r
+ UINT8 TotalBits;\r
+ UINT16 VarOffsetByteLevel;\r
+ UINT8 StorageWidthByteLevel;\r
+\r
+ if (HiiQuestion->BitFieldStore) {\r
+ VarOffsetByteLevel = HiiQuestion->VarOffset / 8;\r
+ TotalBits = HiiQuestion->VarOffset % 8 + HiiQuestion->StorageWidth;\r
+ StorageWidthByteLevel = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1);\r
+ } else {\r
+ VarOffsetByteLevel = HiiQuestion->VarOffset;\r
+ StorageWidthByteLevel = HiiQuestion->StorageWidth;\r
+ }\r
+\r
+ if (((UINT32)VarOffsetByteLevel + StorageWidthByteLevel) > DataSize) {\r
+ DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x)) > Size(0x%x)\n", VarOffsetByteLevel, StorageWidthByteLevel, DataSize));\r
+ return FALSE;\r
+ }\r
+\r
+ OneData = 0;\r
+ CopyMem (&OneData, (UINT8 *)Data + VarOffsetByteLevel, StorageWidthByteLevel);\r
+ if (HiiQuestion->BitFieldStore) {\r
+ //\r
+ // Get the value from the bit field.\r
+ //\r
+ StartBit = HiiQuestion->VarOffset % 8;\r
+ EndBit = StartBit + HiiQuestion->StorageWidth - 1;\r
+ OneData = BitFieldRead64 (OneData, StartBit, EndBit);\r
+ }\r
+\r
+ switch (HiiQuestion->OpCode) {\r
+ case EFI_IFR_ONE_OF_OP:\r
+ Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1);\r
+ while ((UINTN)Ptr < (UINTN)HiiQuestion + HiiQuestion->Length) {\r
+ OneValue = 0;\r
+ if (HiiQuestion->BitFieldStore) {\r
+ //\r
+ // For OneOf stored in bit field, the value of options are saved as UINT32 type.\r
+ //\r
+ CopyMem (&OneValue, Ptr, sizeof (UINT32));\r
+ } else {\r
+ CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);\r
+ }\r
+\r
+ if (OneData == OneValue) {\r
+ //\r
+ // Match\r
+ //\r
+ break;\r
+ }\r
+\r
+ if (HiiQuestion->BitFieldStore) {\r
+ Ptr += sizeof (UINT32);\r
+ } else {\r
+ Ptr += HiiQuestion->StorageWidth;\r
+ }\r
+ }\r
+\r
+ if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) {\r
+ //\r
+ // No match\r
+ //\r
+ DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OneOf mismatch (0x%lx)\n", OneData));\r
+ DEBUG_CODE (\r
+ VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);\r
+ );\r
+ return FALSE;\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_CHECKBOX_OP:\r
+ if ((OneData != 0) && (OneData != 1)) {\r
+ DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: CheckBox mismatch (0x%lx)\n", OneData));\r
+ DEBUG_CODE (\r
+ VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);\r
+ );\r
+ return FALSE;\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_OP:\r
+ Minimum = 0;\r
+ Maximum = 0;\r
+ Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1);\r
+ if (HiiQuestion->BitFieldStore) {\r
+ //\r
+ // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type.\r
+ //\r
+ CopyMem (&Minimum, Ptr, sizeof (UINT32));\r
+ Ptr += sizeof (UINT32);\r
+ CopyMem (&Maximum, Ptr, sizeof (UINT32));\r
+ Ptr += sizeof (UINT32);\r
+ } else {\r
+ CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth);\r
+ Ptr += HiiQuestion->StorageWidth;\r
+ CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth);\r
+ Ptr += HiiQuestion->StorageWidth;\r
+ }\r
+\r
+ //\r
+ // No need to check Step, because it is ONLY for UI.\r
+ //\r
+ if ((OneData < Minimum) || (OneData > Maximum)) {\r
+ DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: Numeric mismatch (0x%lx)\n", OneData));\r
+ DEBUG_CODE (\r
+ VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);\r
+ );\r
+ return FALSE;\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_ORDERED_LIST_OP:\r
+ MaxContainers = ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers;\r
+ if (((UINT32)HiiQuestion->VarOffset + HiiQuestion->StorageWidth * MaxContainers) > DataSize) {\r
+ DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x) * MaxContainers(0x%02x)) > Size(0x%x)\n", HiiQuestion->VarOffset, HiiQuestion->StorageWidth, MaxContainers, DataSize));\r
+ return FALSE;\r
+ }\r
+\r
+ for (Index = 0; Index < MaxContainers; Index++) {\r
+ OneData = 0;\r
+ CopyMem (&OneData, (UINT8 *)Data + HiiQuestion->VarOffset + HiiQuestion->StorageWidth * Index, HiiQuestion->StorageWidth);\r
+ if (OneData == 0) {\r
+ //\r
+ // The value of 0 is used to determine if a particular "slot" in the array is empty.\r
+ //\r
+ continue;\r
+ }\r
+\r
+ Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1);\r
+ while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) {\r
+ OneValue = 0;\r
+ CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);\r
+ if (OneData == OneValue) {\r
+ //\r
+ // Match\r
+ //\r
+ break;\r
+ }\r
+\r
+ Ptr += HiiQuestion->StorageWidth;\r
+ }\r
+\r
+ if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) {\r
+ //\r
+ // No match\r
+ //\r
+ DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OrderedList mismatch\n"));\r
+ DEBUG_CODE (\r
+ VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->StorageWidth * MaxContainers, (UINT8 *)Data + HiiQuestion->VarOffset);\r
+ );\r
+ DEBUG_CODE (\r
+ VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);\r
+ );\r
+ return FALSE;\r
+ }\r
+ }\r
+\r
+ break;\r
+\r
+ default:\r
+ ASSERT (FALSE);\r
+ break;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+/**\r
+ SetVariable check handler HII.\r
+\r
+ @param[in] VariableName Name of Variable to set.\r
+ @param[in] VendorGuid Variable vendor GUID.\r
+ @param[in] Attributes Attribute value of the variable.\r
+ @param[in] DataSize Size of Data to set.\r
+ @param[in] Data Data pointer.\r
+\r
+ @retval EFI_SUCCESS The SetVariable check result was success.\r
+ @retval EFI_SECURITY_VIOLATION Check fail.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SetVariableCheckHandlerHii (\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN UINT32 Attributes,\r
+ IN UINTN DataSize,\r
+ IN VOID *Data\r
+ )\r
+{\r
+ VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;\r
+ VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;\r
+\r
+ if (mVarCheckHiiBin == NULL) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {\r
+ //\r
+ // Do not check delete variable.\r
+ //\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // For Hii Variable header align.\r
+ //\r
+ HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (mVarCheckHiiBin);\r
+ while ((UINTN)HiiVariable < ((UINTN)mVarCheckHiiBin + mVarCheckHiiBinSize)) {\r
+ if ((StrCmp ((CHAR16 *)(HiiVariable + 1), VariableName) == 0) &&\r
+ (CompareGuid (&HiiVariable->Guid, VendorGuid)))\r
+ {\r
+ //\r
+ // Found the Hii Variable that could be used to do check.\r
+ //\r
+ DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - %s:%g with Attributes = 0x%08x Size = 0x%x\n", VariableName, VendorGuid, Attributes, DataSize));\r
+ if (HiiVariable->Attributes != Attributes) {\r
+ DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Attributes - 0x%08x\n", HiiVariable->Attributes));\r
+ return EFI_SECURITY_VIOLATION;\r
+ }\r
+\r
+ if (DataSize == 0) {\r
+ DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - CHECK PASS with DataSize == 0 !\n"));\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if (HiiVariable->Size != DataSize) {\r
+ DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Size - 0x%x\n", HiiVariable->Size));\r
+ return EFI_SECURITY_VIOLATION;\r
+ }\r
+\r
+ //\r
+ // Do the check.\r
+ // For Hii Question header align.\r
+ //\r
+ HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength));\r
+ while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) {\r
+ if (!VarCheckHiiQuestion (HiiQuestion, Data, DataSize)) {\r
+ return EFI_SECURITY_VIOLATION;\r
+ }\r
+\r
+ //\r
+ // For Hii Question header align.\r
+ //\r
+ HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length));\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - ALL CHECK PASS!\n"));\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // For Hii Variable header align.\r
+ //\r
+ HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length));\r
+ }\r
+\r
+ // Not found, so pass.\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+#ifdef DUMP_VAR_CHECK_HII\r
+GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_OPCODE_STRING mHiiOpCodeStringTable[] = {\r
+ { EFI_IFR_VARSTORE_EFI_OP, "EfiVarStore" },\r
+ { EFI_IFR_ONE_OF_OP, "OneOf" },\r
+ { EFI_IFR_CHECKBOX_OP, "CheckBox" },\r
+ { EFI_IFR_NUMERIC_OP, "Numeric" },\r
+ { EFI_IFR_ORDERED_LIST_OP, "OrderedList" },\r
+};\r
+\r
+/**\r
+ HII opcode to string.\r
+\r
+ @param[in] HiiOpCode Hii OpCode.\r
+\r
+ @return Pointer to string.\r
+\r
+**/\r
+CHAR8 *\r
+HiiOpCodeToStr (\r
+ IN UINT8 HiiOpCode\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ for (Index = 0; Index < ARRAY_SIZE (mHiiOpCodeStringTable); Index++) {\r
+ if (mHiiOpCodeStringTable[Index].HiiOpCode == HiiOpCode) {\r
+ return mHiiOpCodeStringTable[Index].HiiOpCodeStr;\r
+ }\r
+ }\r
+\r
+ return "<UnknownHiiOpCode>";\r
+}\r
+\r
+/**\r
+ Dump Hii Question.\r
+\r
+ @param[in] HiiQuestion Pointer to Hii Question.\r
+\r
+**/\r
+VOID\r
+DumpHiiQuestion (\r
+ IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion\r
+ )\r
+{\r
+ UINT64 Minimum;\r
+ UINT64 Maximum;\r
+ UINT64 OneValue;\r
+ UINT8 *Ptr;\r
+\r
+ DEBUG ((DEBUG_INFO, " VAR_CHECK_HII_QUESTION_HEADER\n"));\r
+ DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a) (%a)\n", HiiQuestion->OpCode, HiiOpCodeToStr (HiiQuestion->OpCode), (HiiQuestion->BitFieldStore ? "bit level" : "byte level")));\r
+ DEBUG ((DEBUG_INFO, " Length - 0x%02x\n", HiiQuestion->Length));\r
+ DEBUG ((DEBUG_INFO, " VarOffset - 0x%04x (%a)\n", HiiQuestion->VarOffset, (HiiQuestion->BitFieldStore ? "bit level" : "byte level")));\r
+ DEBUG ((DEBUG_INFO, " StorageWidth - 0x%02x (%a)\n", HiiQuestion->StorageWidth, (HiiQuestion->BitFieldStore ? "bit level" : "byte level")));\r
+\r
+ switch (HiiQuestion->OpCode) {\r
+ case EFI_IFR_ONE_OF_OP:\r
+ Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1);\r
+ while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) {\r
+ OneValue = 0;\r
+ if (HiiQuestion->BitFieldStore) {\r
+ //\r
+ // For OneOf stored in bit field, the value of options are saved as UINT32 type.\r
+ //\r
+ CopyMem (&OneValue, Ptr, sizeof (UINT32));\r
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue));\r
+ } else {\r
+ CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);\r
+ switch (HiiQuestion->StorageWidth) {\r
+ case sizeof (UINT8):\r
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue));\r
+ break;\r
+ case sizeof (UINT16):\r
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue));\r
+ break;\r
+ case sizeof (UINT32):\r
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue));\r
+ break;\r
+ case sizeof (UINT64):\r
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue));\r
+ break;\r
+ default:\r
+ ASSERT (FALSE);\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (HiiQuestion->BitFieldStore) {\r
+ Ptr += sizeof (UINT32);\r
+ } else {\r
+ Ptr += HiiQuestion->StorageWidth;\r
+ }\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_CHECKBOX_OP:\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_OP:\r
+ Minimum = 0;\r
+ Maximum = 0;\r
+ Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1);\r
+ if (HiiQuestion->BitFieldStore) {\r
+ //\r
+ // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type.\r
+ //\r
+ CopyMem (&Minimum, Ptr, sizeof (UINT32));\r
+ Ptr += sizeof (UINT32);\r
+ CopyMem (&Maximum, Ptr, sizeof (UINT32));\r
+ Ptr += sizeof (UINT32);\r
+\r
+ DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum));\r
+ DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum));\r
+ } else {\r
+ CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth);\r
+ Ptr += HiiQuestion->StorageWidth;\r
+ CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth);\r
+ Ptr += HiiQuestion->StorageWidth;\r
+\r
+ switch (HiiQuestion->StorageWidth) {\r
+ case sizeof (UINT8):\r
+ DEBUG ((DEBUG_INFO, " Minimum - 0x%02x\n", Minimum));\r
+ DEBUG ((DEBUG_INFO, " Maximum - 0x%02x\n", Maximum));\r
+ break;\r
+ case sizeof (UINT16):\r
+ DEBUG ((DEBUG_INFO, " Minimum - 0x%04x\n", Minimum));\r
+ DEBUG ((DEBUG_INFO, " Maximum - 0x%04x\n", Maximum));\r
+ break;\r
+ case sizeof (UINT32):\r
+ DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum));\r
+ DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum));\r
+ break;\r
+ case sizeof (UINT64):\r
+ DEBUG ((DEBUG_INFO, " Minimum - 0x%016lx\n", Minimum));\r
+ DEBUG ((DEBUG_INFO, " Maximum - 0x%016lx\n", Maximum));\r
+ break;\r
+ default:\r
+ ASSERT (FALSE);\r
+ break;\r
+ }\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_ORDERED_LIST_OP:\r
+ DEBUG ((DEBUG_INFO, " MaxContainers - 0x%02x\n", ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers));\r
+ Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1);\r
+ while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) {\r
+ OneValue = 0;\r
+ CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);\r
+ switch (HiiQuestion->StorageWidth) {\r
+ case sizeof (UINT8):\r
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue));\r
+ break;\r
+ case sizeof (UINT16):\r
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue));\r
+ break;\r
+ case sizeof (UINT32):\r
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue));\r
+ break;\r
+ case sizeof (UINT64):\r
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue));\r
+ break;\r
+ default:\r
+ ASSERT (FALSE);\r
+ break;\r
+ }\r
+\r
+ Ptr += HiiQuestion->StorageWidth;\r
+ }\r
+\r
+ break;\r
+\r
+ default:\r
+ ASSERT (FALSE);\r
+ break;\r
+ }\r
+}\r
+\r
+/**\r
+ Dump Hii Variable.\r
+\r
+ @param[in] HiiVariable Pointer to Hii Variable.\r
+\r
+**/\r
+VOID\r
+DumpHiiVariable (\r
+ IN VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable\r
+ )\r
+{\r
+ VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;\r
+\r
+ DEBUG ((DEBUG_INFO, "VAR_CHECK_HII_VARIABLE_HEADER\n"));\r
+ DEBUG ((DEBUG_INFO, " Revision - 0x%04x\n", HiiVariable->Revision));\r
+ DEBUG ((DEBUG_INFO, " HeaderLength - 0x%04x\n", HiiVariable->HeaderLength));\r
+ DEBUG ((DEBUG_INFO, " Length - 0x%08x\n", HiiVariable->Length));\r
+ DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a)\n", HiiVariable->OpCode, HiiOpCodeToStr (HiiVariable->OpCode)));\r
+ DEBUG ((DEBUG_INFO, " Size - 0x%04x\n", HiiVariable->Size));\r
+ DEBUG ((DEBUG_INFO, " Attributes - 0x%08x\n", HiiVariable->Attributes));\r
+ DEBUG ((DEBUG_INFO, " Guid - %g\n", &HiiVariable->Guid));\r
+ DEBUG ((DEBUG_INFO, " Name - %s\n", HiiVariable + 1));\r
+\r
+ //\r
+ // For Hii Question header align.\r
+ //\r
+ HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength));\r
+ while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) {\r
+ //\r
+ // Dump Hii Question related to the Hii Variable.\r
+ //\r
+ DumpHiiQuestion (HiiQuestion);\r
+ //\r
+ // For Hii Question header align.\r
+ //\r
+ HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length));\r
+ }\r
+}\r
+\r
+/**\r
+ Dump Var Check HII.\r
+\r
+ @param[in] VarCheckHiiBin Pointer to VarCheckHiiBin.\r
+ @param[in] VarCheckHiiBinSize VarCheckHiiBin size.\r
+\r
+**/\r
+VOID\r
+DumpVarCheckHii (\r
+ IN VOID *VarCheckHiiBin,\r
+ IN UINTN VarCheckHiiBinSize\r
+ )\r
+{\r
+ VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;\r
+\r
+ DEBUG ((DEBUG_INFO, "DumpVarCheckHii\n"));\r
+\r
+ //\r
+ // For Hii Variable header align.\r
+ //\r
+ HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (VarCheckHiiBin);\r
+ while ((UINTN)HiiVariable < ((UINTN)VarCheckHiiBin + VarCheckHiiBinSize)) {\r
+ DumpHiiVariable (HiiVariable);\r
+ //\r
+ // For Hii Variable header align.\r
+ //\r
+ HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length));\r
+ }\r
+}\r
+\r
+#endif\r
+\r
+/**\r
+ Constructor function of VarCheckHiiLib to register var check HII handler.\r
+\r
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
+ @param[in] SystemTable A pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCCESS The constructor executed correctly.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VarCheckHiiLibConstructor (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ VarCheckLibRegisterEndOfDxeCallback (VarCheckHiiGen);\r
+ VarCheckLibRegisterAddressPointer ((VOID **)&mVarCheckHiiBin);\r
+ VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerHii);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
## @file\r
-# NULL class library to register var check HII handler.\r
+# VarCheckHiiLib library to register var check HII handler.\r
#\r
# Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
#\r
MODULE_TYPE = DXE_RUNTIME_DRIVER\r
VERSION_STRING = 1.0\r
LIBRARY_CLASS = NULL|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER\r
- CONSTRUCTOR = VarCheckHiiLibNullClassConstructor\r
+ CONSTRUCTOR = VarCheckHiiLibConstructor\r
\r
[Sources]\r
- VarCheckHiiLibNullClass.c\r
+ VarCheckHiiLib.c\r
VarCheckHii.h\r
VarCheckHiiGenFromFv.c\r
VarCheckHiiGenFromHii.c\r
+++ /dev/null
-/** @file\r
- Var Check Hii handler.\r
-\r
-Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "VarCheckHii.h"\r
-#include "VarCheckHiiGen.h"\r
-GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckHiiHex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };\r
-\r
-/**\r
- Dump some hexadecimal data.\r
-\r
- @param[in] Indent How many spaces to indent the output.\r
- @param[in] Offset The offset of the dump.\r
- @param[in] DataSize The size in bytes of UserData.\r
- @param[in] UserData The data to dump.\r
-\r
-**/\r
-VOID\r
-VarCheckHiiInternalDumpHex (\r
- IN UINTN Indent,\r
- IN UINTN Offset,\r
- IN UINTN DataSize,\r
- IN VOID *UserData\r
- )\r
-{\r
- UINT8 *Data;\r
-\r
- CHAR8 Val[50];\r
-\r
- CHAR8 Str[20];\r
-\r
- UINT8 TempByte;\r
- UINTN Size;\r
- UINTN Index;\r
-\r
- Data = UserData;\r
- while (DataSize != 0) {\r
- Size = 16;\r
- if (Size > DataSize) {\r
- Size = DataSize;\r
- }\r
-\r
- for (Index = 0; Index < Size; Index += 1) {\r
- TempByte = Data[Index];\r
- Val[Index * 3 + 0] = mVarCheckHiiHex[TempByte >> 4];\r
- Val[Index * 3 + 1] = mVarCheckHiiHex[TempByte & 0xF];\r
- Val[Index * 3 + 2] = (CHAR8)((Index == 7) ? '-' : ' ');\r
- Str[Index] = (CHAR8)((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);\r
- }\r
-\r
- Val[Index * 3] = 0;\r
- Str[Index] = 0;\r
- DEBUG ((DEBUG_INFO, "%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str));\r
-\r
- Data += Size;\r
- Offset += Size;\r
- DataSize -= Size;\r
- }\r
-}\r
-\r
-/**\r
- Var Check Hii Question.\r
-\r
- @param[in] HiiQuestion Pointer to Hii Question\r
- @param[in] Data Data pointer.\r
- @param[in] DataSize Size of Data to set.\r
-\r
- @retval TRUE Check pass\r
- @retval FALSE Check fail.\r
-\r
-**/\r
-BOOLEAN\r
-VarCheckHiiQuestion (\r
- IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion,\r
- IN VOID *Data,\r
- IN UINTN DataSize\r
- )\r
-{\r
- UINT64 OneData;\r
- UINT64 Minimum;\r
- UINT64 Maximum;\r
- UINT64 OneValue;\r
- UINT8 *Ptr;\r
- UINT8 Index;\r
- UINT8 MaxContainers;\r
- UINT8 StartBit;\r
- UINT8 EndBit;\r
- UINT8 TotalBits;\r
- UINT16 VarOffsetByteLevel;\r
- UINT8 StorageWidthByteLevel;\r
-\r
- if (HiiQuestion->BitFieldStore) {\r
- VarOffsetByteLevel = HiiQuestion->VarOffset / 8;\r
- TotalBits = HiiQuestion->VarOffset % 8 + HiiQuestion->StorageWidth;\r
- StorageWidthByteLevel = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1);\r
- } else {\r
- VarOffsetByteLevel = HiiQuestion->VarOffset;\r
- StorageWidthByteLevel = HiiQuestion->StorageWidth;\r
- }\r
-\r
- if (((UINT32)VarOffsetByteLevel + StorageWidthByteLevel) > DataSize) {\r
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x)) > Size(0x%x)\n", VarOffsetByteLevel, StorageWidthByteLevel, DataSize));\r
- return FALSE;\r
- }\r
-\r
- OneData = 0;\r
- CopyMem (&OneData, (UINT8 *)Data + VarOffsetByteLevel, StorageWidthByteLevel);\r
- if (HiiQuestion->BitFieldStore) {\r
- //\r
- // Get the value from the bit field.\r
- //\r
- StartBit = HiiQuestion->VarOffset % 8;\r
- EndBit = StartBit + HiiQuestion->StorageWidth - 1;\r
- OneData = BitFieldRead64 (OneData, StartBit, EndBit);\r
- }\r
-\r
- switch (HiiQuestion->OpCode) {\r
- case EFI_IFR_ONE_OF_OP:\r
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1);\r
- while ((UINTN)Ptr < (UINTN)HiiQuestion + HiiQuestion->Length) {\r
- OneValue = 0;\r
- if (HiiQuestion->BitFieldStore) {\r
- //\r
- // For OneOf stored in bit field, the value of options are saved as UINT32 type.\r
- //\r
- CopyMem (&OneValue, Ptr, sizeof (UINT32));\r
- } else {\r
- CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);\r
- }\r
-\r
- if (OneData == OneValue) {\r
- //\r
- // Match\r
- //\r
- break;\r
- }\r
-\r
- if (HiiQuestion->BitFieldStore) {\r
- Ptr += sizeof (UINT32);\r
- } else {\r
- Ptr += HiiQuestion->StorageWidth;\r
- }\r
- }\r
-\r
- if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) {\r
- //\r
- // No match\r
- //\r
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OneOf mismatch (0x%lx)\n", OneData));\r
- DEBUG_CODE (\r
- VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);\r
- );\r
- return FALSE;\r
- }\r
-\r
- break;\r
-\r
- case EFI_IFR_CHECKBOX_OP:\r
- if ((OneData != 0) && (OneData != 1)) {\r
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: CheckBox mismatch (0x%lx)\n", OneData));\r
- DEBUG_CODE (\r
- VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);\r
- );\r
- return FALSE;\r
- }\r
-\r
- break;\r
-\r
- case EFI_IFR_NUMERIC_OP:\r
- Minimum = 0;\r
- Maximum = 0;\r
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1);\r
- if (HiiQuestion->BitFieldStore) {\r
- //\r
- // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type.\r
- //\r
- CopyMem (&Minimum, Ptr, sizeof (UINT32));\r
- Ptr += sizeof (UINT32);\r
- CopyMem (&Maximum, Ptr, sizeof (UINT32));\r
- Ptr += sizeof (UINT32);\r
- } else {\r
- CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth);\r
- Ptr += HiiQuestion->StorageWidth;\r
- CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth);\r
- Ptr += HiiQuestion->StorageWidth;\r
- }\r
-\r
- //\r
- // No need to check Step, because it is ONLY for UI.\r
- //\r
- if ((OneData < Minimum) || (OneData > Maximum)) {\r
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: Numeric mismatch (0x%lx)\n", OneData));\r
- DEBUG_CODE (\r
- VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);\r
- );\r
- return FALSE;\r
- }\r
-\r
- break;\r
-\r
- case EFI_IFR_ORDERED_LIST_OP:\r
- MaxContainers = ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers;\r
- if (((UINT32)HiiQuestion->VarOffset + HiiQuestion->StorageWidth * MaxContainers) > DataSize) {\r
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x) * MaxContainers(0x%02x)) > Size(0x%x)\n", HiiQuestion->VarOffset, HiiQuestion->StorageWidth, MaxContainers, DataSize));\r
- return FALSE;\r
- }\r
-\r
- for (Index = 0; Index < MaxContainers; Index++) {\r
- OneData = 0;\r
- CopyMem (&OneData, (UINT8 *)Data + HiiQuestion->VarOffset + HiiQuestion->StorageWidth * Index, HiiQuestion->StorageWidth);\r
- if (OneData == 0) {\r
- //\r
- // The value of 0 is used to determine if a particular "slot" in the array is empty.\r
- //\r
- continue;\r
- }\r
-\r
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1);\r
- while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) {\r
- OneValue = 0;\r
- CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);\r
- if (OneData == OneValue) {\r
- //\r
- // Match\r
- //\r
- break;\r
- }\r
-\r
- Ptr += HiiQuestion->StorageWidth;\r
- }\r
-\r
- if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) {\r
- //\r
- // No match\r
- //\r
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OrderedList mismatch\n"));\r
- DEBUG_CODE (\r
- VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->StorageWidth * MaxContainers, (UINT8 *)Data + HiiQuestion->VarOffset);\r
- );\r
- DEBUG_CODE (\r
- VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);\r
- );\r
- return FALSE;\r
- }\r
- }\r
-\r
- break;\r
-\r
- default:\r
- ASSERT (FALSE);\r
- break;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
- SetVariable check handler HII.\r
-\r
- @param[in] VariableName Name of Variable to set.\r
- @param[in] VendorGuid Variable vendor GUID.\r
- @param[in] Attributes Attribute value of the variable.\r
- @param[in] DataSize Size of Data to set.\r
- @param[in] Data Data pointer.\r
-\r
- @retval EFI_SUCCESS The SetVariable check result was success.\r
- @retval EFI_SECURITY_VIOLATION Check fail.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SetVariableCheckHandlerHii (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN UINT32 Attributes,\r
- IN UINTN DataSize,\r
- IN VOID *Data\r
- )\r
-{\r
- VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;\r
- VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;\r
-\r
- if (mVarCheckHiiBin == NULL) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {\r
- //\r
- // Do not check delete variable.\r
- //\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // For Hii Variable header align.\r
- //\r
- HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (mVarCheckHiiBin);\r
- while ((UINTN)HiiVariable < ((UINTN)mVarCheckHiiBin + mVarCheckHiiBinSize)) {\r
- if ((StrCmp ((CHAR16 *)(HiiVariable + 1), VariableName) == 0) &&\r
- (CompareGuid (&HiiVariable->Guid, VendorGuid)))\r
- {\r
- //\r
- // Found the Hii Variable that could be used to do check.\r
- //\r
- DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - %s:%g with Attributes = 0x%08x Size = 0x%x\n", VariableName, VendorGuid, Attributes, DataSize));\r
- if (HiiVariable->Attributes != Attributes) {\r
- DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Attributes - 0x%08x\n", HiiVariable->Attributes));\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
-\r
- if (DataSize == 0) {\r
- DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - CHECK PASS with DataSize == 0 !\n"));\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (HiiVariable->Size != DataSize) {\r
- DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Size - 0x%x\n", HiiVariable->Size));\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
-\r
- //\r
- // Do the check.\r
- // For Hii Question header align.\r
- //\r
- HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength));\r
- while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) {\r
- if (!VarCheckHiiQuestion (HiiQuestion, Data, DataSize)) {\r
- return EFI_SECURITY_VIOLATION;\r
- }\r
-\r
- //\r
- // For Hii Question header align.\r
- //\r
- HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length));\r
- }\r
-\r
- DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - ALL CHECK PASS!\n"));\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // For Hii Variable header align.\r
- //\r
- HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length));\r
- }\r
-\r
- // Not found, so pass.\r
- return EFI_SUCCESS;\r
-}\r
-\r
-#ifdef DUMP_VAR_CHECK_HII\r
-GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_OPCODE_STRING mHiiOpCodeStringTable[] = {\r
- { EFI_IFR_VARSTORE_EFI_OP, "EfiVarStore" },\r
- { EFI_IFR_ONE_OF_OP, "OneOf" },\r
- { EFI_IFR_CHECKBOX_OP, "CheckBox" },\r
- { EFI_IFR_NUMERIC_OP, "Numeric" },\r
- { EFI_IFR_ORDERED_LIST_OP, "OrderedList" },\r
-};\r
-\r
-/**\r
- HII opcode to string.\r
-\r
- @param[in] HiiOpCode Hii OpCode.\r
-\r
- @return Pointer to string.\r
-\r
-**/\r
-CHAR8 *\r
-HiiOpCodeToStr (\r
- IN UINT8 HiiOpCode\r
- )\r
-{\r
- UINTN Index;\r
-\r
- for (Index = 0; Index < ARRAY_SIZE (mHiiOpCodeStringTable); Index++) {\r
- if (mHiiOpCodeStringTable[Index].HiiOpCode == HiiOpCode) {\r
- return mHiiOpCodeStringTable[Index].HiiOpCodeStr;\r
- }\r
- }\r
-\r
- return "<UnknownHiiOpCode>";\r
-}\r
-\r
-/**\r
- Dump Hii Question.\r
-\r
- @param[in] HiiQuestion Pointer to Hii Question.\r
-\r
-**/\r
-VOID\r
-DumpHiiQuestion (\r
- IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion\r
- )\r
-{\r
- UINT64 Minimum;\r
- UINT64 Maximum;\r
- UINT64 OneValue;\r
- UINT8 *Ptr;\r
-\r
- DEBUG ((DEBUG_INFO, " VAR_CHECK_HII_QUESTION_HEADER\n"));\r
- DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a) (%a)\n", HiiQuestion->OpCode, HiiOpCodeToStr (HiiQuestion->OpCode), (HiiQuestion->BitFieldStore ? "bit level" : "byte level")));\r
- DEBUG ((DEBUG_INFO, " Length - 0x%02x\n", HiiQuestion->Length));\r
- DEBUG ((DEBUG_INFO, " VarOffset - 0x%04x (%a)\n", HiiQuestion->VarOffset, (HiiQuestion->BitFieldStore ? "bit level" : "byte level")));\r
- DEBUG ((DEBUG_INFO, " StorageWidth - 0x%02x (%a)\n", HiiQuestion->StorageWidth, (HiiQuestion->BitFieldStore ? "bit level" : "byte level")));\r
-\r
- switch (HiiQuestion->OpCode) {\r
- case EFI_IFR_ONE_OF_OP:\r
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1);\r
- while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) {\r
- OneValue = 0;\r
- if (HiiQuestion->BitFieldStore) {\r
- //\r
- // For OneOf stored in bit field, the value of options are saved as UINT32 type.\r
- //\r
- CopyMem (&OneValue, Ptr, sizeof (UINT32));\r
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue));\r
- } else {\r
- CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);\r
- switch (HiiQuestion->StorageWidth) {\r
- case sizeof (UINT8):\r
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue));\r
- break;\r
- case sizeof (UINT16):\r
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue));\r
- break;\r
- case sizeof (UINT32):\r
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue));\r
- break;\r
- case sizeof (UINT64):\r
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue));\r
- break;\r
- default:\r
- ASSERT (FALSE);\r
- break;\r
- }\r
- }\r
-\r
- if (HiiQuestion->BitFieldStore) {\r
- Ptr += sizeof (UINT32);\r
- } else {\r
- Ptr += HiiQuestion->StorageWidth;\r
- }\r
- }\r
-\r
- break;\r
-\r
- case EFI_IFR_CHECKBOX_OP:\r
- break;\r
-\r
- case EFI_IFR_NUMERIC_OP:\r
- Minimum = 0;\r
- Maximum = 0;\r
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1);\r
- if (HiiQuestion->BitFieldStore) {\r
- //\r
- // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type.\r
- //\r
- CopyMem (&Minimum, Ptr, sizeof (UINT32));\r
- Ptr += sizeof (UINT32);\r
- CopyMem (&Maximum, Ptr, sizeof (UINT32));\r
- Ptr += sizeof (UINT32);\r
-\r
- DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum));\r
- DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum));\r
- } else {\r
- CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth);\r
- Ptr += HiiQuestion->StorageWidth;\r
- CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth);\r
- Ptr += HiiQuestion->StorageWidth;\r
-\r
- switch (HiiQuestion->StorageWidth) {\r
- case sizeof (UINT8):\r
- DEBUG ((DEBUG_INFO, " Minimum - 0x%02x\n", Minimum));\r
- DEBUG ((DEBUG_INFO, " Maximum - 0x%02x\n", Maximum));\r
- break;\r
- case sizeof (UINT16):\r
- DEBUG ((DEBUG_INFO, " Minimum - 0x%04x\n", Minimum));\r
- DEBUG ((DEBUG_INFO, " Maximum - 0x%04x\n", Maximum));\r
- break;\r
- case sizeof (UINT32):\r
- DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum));\r
- DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum));\r
- break;\r
- case sizeof (UINT64):\r
- DEBUG ((DEBUG_INFO, " Minimum - 0x%016lx\n", Minimum));\r
- DEBUG ((DEBUG_INFO, " Maximum - 0x%016lx\n", Maximum));\r
- break;\r
- default:\r
- ASSERT (FALSE);\r
- break;\r
- }\r
- }\r
-\r
- break;\r
-\r
- case EFI_IFR_ORDERED_LIST_OP:\r
- DEBUG ((DEBUG_INFO, " MaxContainers - 0x%02x\n", ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers));\r
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1);\r
- while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) {\r
- OneValue = 0;\r
- CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);\r
- switch (HiiQuestion->StorageWidth) {\r
- case sizeof (UINT8):\r
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue));\r
- break;\r
- case sizeof (UINT16):\r
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue));\r
- break;\r
- case sizeof (UINT32):\r
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue));\r
- break;\r
- case sizeof (UINT64):\r
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue));\r
- break;\r
- default:\r
- ASSERT (FALSE);\r
- break;\r
- }\r
-\r
- Ptr += HiiQuestion->StorageWidth;\r
- }\r
-\r
- break;\r
-\r
- default:\r
- ASSERT (FALSE);\r
- break;\r
- }\r
-}\r
-\r
-/**\r
- Dump Hii Variable.\r
-\r
- @param[in] HiiVariable Pointer to Hii Variable.\r
-\r
-**/\r
-VOID\r
-DumpHiiVariable (\r
- IN VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable\r
- )\r
-{\r
- VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;\r
-\r
- DEBUG ((DEBUG_INFO, "VAR_CHECK_HII_VARIABLE_HEADER\n"));\r
- DEBUG ((DEBUG_INFO, " Revision - 0x%04x\n", HiiVariable->Revision));\r
- DEBUG ((DEBUG_INFO, " HeaderLength - 0x%04x\n", HiiVariable->HeaderLength));\r
- DEBUG ((DEBUG_INFO, " Length - 0x%08x\n", HiiVariable->Length));\r
- DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a)\n", HiiVariable->OpCode, HiiOpCodeToStr (HiiVariable->OpCode)));\r
- DEBUG ((DEBUG_INFO, " Size - 0x%04x\n", HiiVariable->Size));\r
- DEBUG ((DEBUG_INFO, " Attributes - 0x%08x\n", HiiVariable->Attributes));\r
- DEBUG ((DEBUG_INFO, " Guid - %g\n", &HiiVariable->Guid));\r
- DEBUG ((DEBUG_INFO, " Name - %s\n", HiiVariable + 1));\r
-\r
- //\r
- // For Hii Question header align.\r
- //\r
- HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength));\r
- while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) {\r
- //\r
- // Dump Hii Question related to the Hii Variable.\r
- //\r
- DumpHiiQuestion (HiiQuestion);\r
- //\r
- // For Hii Question header align.\r
- //\r
- HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length));\r
- }\r
-}\r
-\r
-/**\r
- Dump Var Check HII.\r
-\r
- @param[in] VarCheckHiiBin Pointer to VarCheckHiiBin.\r
- @param[in] VarCheckHiiBinSize VarCheckHiiBin size.\r
-\r
-**/\r
-VOID\r
-DumpVarCheckHii (\r
- IN VOID *VarCheckHiiBin,\r
- IN UINTN VarCheckHiiBinSize\r
- )\r
-{\r
- VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;\r
-\r
- DEBUG ((DEBUG_INFO, "DumpVarCheckHii\n"));\r
-\r
- //\r
- // For Hii Variable header align.\r
- //\r
- HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (VarCheckHiiBin);\r
- while ((UINTN)HiiVariable < ((UINTN)VarCheckHiiBin + VarCheckHiiBinSize)) {\r
- DumpHiiVariable (HiiVariable);\r
- //\r
- // For Hii Variable header align.\r
- //\r
- HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length));\r
- }\r
-}\r
-\r
-#endif\r
-\r
-/**\r
- Constructor function of VarCheckHiiLib to register var check HII handler.\r
-\r
- @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
- @param[in] SystemTable A pointer to the EFI System Table.\r
-\r
- @retval EFI_SUCCESS The constructor executed correctly.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-VarCheckHiiLibNullClassConstructor (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- VarCheckLibRegisterEndOfDxeCallback (VarCheckHiiGen);\r
- VarCheckLibRegisterAddressPointer ((VOID **)&mVarCheckHiiBin);\r
- VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerHii);\r
-\r
- return EFI_SUCCESS;\r
-}\r