From 45cf57ce798860b02fbeca8c8f4d5e971c476e0e Mon Sep 17 00:00:00 2001 From: xieyuanh Date: Mon, 24 Jun 2024 23:39:27 +0800 Subject: [PATCH] MdeModulePkg: Relocate VarCheckHiiInternalDumpHex, VarCheckHiiQuestion Move VarCheckHiiInternalDumpHex and VarCheckHiiQuestion to the common file. Cc: Liming Gao Cc: Rahul Kumar Cc: Gerd Hoffmann Cc: Star Zeng Cc: Hongbin1 Zhang Cc: Wei6 Xu Cc: Dun Tan Cc: Dandan Bi Signed-off-by: Yuanhao Xie --- .../Library/VarCheckHiiLib/VarCheckHiiLib.c | 249 ------------------ .../VarCheckHiiLib/VarCheckHiiLibCommon.c | 246 ++++++++++++++++- 2 files changed, 245 insertions(+), 250 deletions(-) diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c index c6bd8cc887..d6d68bbb7b 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c @@ -9,255 +9,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "VarCheckHii.h" #include "VarCheckHiiGen.h" #include "VarCheckHiiLibCommon.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; -} /** Sets the variable check handler for HII. diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.c index b8fbbf31f5..00a37df017 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.c @@ -8,7 +8,251 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "VarCheckHii.h" #include "VarCheckHiiLibCommon.h" -EFI_HANDLE mEfiVariableCheckHiiHandle = NULL; +EFI_HANDLE mEfiVariableCheckHiiHandle = NULL; +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; +} /** SetVariable check handler HII.