X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FHiiDatabaseDxe%2FConfigRouting.c;h=a97e28b8dd6090a49a8f888a677794a4f8cbfe59;hb=4a4297160fda8ff9646a7ae0cad7989a8aaeb619;hp=08e564343d6c925fed1ff11761be2da29503d639;hpb=bc166db3114c8bebb73807d58fbd042c1b79e928;p=mirror_edk2.git diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c index 08e564343d..a97e28b8dd 100644 --- a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c +++ b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c @@ -1,8 +1,8 @@ /** @file Implementation of interfaces function for EFI_HII_CONFIG_ROUTING_PROTOCOL. -Copyright (c) 2007 - 2008, Intel Corporation -All rights reserved. This program and the accompanying materials +Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php @@ -14,6 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "HiiDatabase.h" +extern HII_DATABASE_PRIVATE_DATA mPrivate; /** Calculate the number of Unicode characters of the incoming Configuration string, @@ -32,7 +33,7 @@ CalculateConfigStringLen ( IN EFI_STRING String ) { - UINTN Length; + EFI_STRING TmpPtr; // // "GUID=" should be the first element of incoming string. @@ -40,19 +41,16 @@ CalculateConfigStringLen ( ASSERT (String != NULL); ASSERT (StrnCmp (String, L"GUID=", StrLen (L"GUID=")) == 0); - Length = StrLen (L"GUID="); - String += Length; - // // The beginning of next / should be "&GUID=". // Will meet '\0' if there is only one /. - // - while (*String != 0 && StrnCmp (String, L"&GUID=", StrLen (L"&GUID=")) != 0) { - Length++; - String++; + // + TmpPtr = StrStr (String, L"&GUID="); + if (TmpPtr == NULL) { + return StrLen (String); } - return Length; + return (TmpPtr - String); } @@ -63,10 +61,11 @@ CalculateConfigStringLen ( This is a internal function. @param String UEFI configuration string - @param DevicePath binary of a UEFI device path. + @param DevicePathData Binary of a UEFI device path. + @retval EFI_NOT_FOUND The device path is not invalid. @retval EFI_INVALID_PARAMETER Any incoming parameter is invalid. - @retval EFI_OUT_OF_RESOURCES Lake of resources to store neccesary structures. + @retval EFI_OUT_OF_RESOURCES Lake of resources to store necessary structures. @retval EFI_SUCCESS The device path is retrieved and translated to binary format. @@ -74,14 +73,19 @@ CalculateConfigStringLen ( EFI_STATUS GetDevicePath ( IN EFI_STRING String, - OUT UINT8 **DevicePath + OUT UINT8 **DevicePathData ) { - UINTN Length; - EFI_STRING PathHdr; - EFI_STRING DevicePathString; + UINTN Length; + EFI_STRING PathHdr; + UINT8 *DevicePathBuffer; + CHAR16 TemStr[2]; + UINTN Index; + UINT8 DigitUint8; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + - if (String == NULL || DevicePath == NULL) { + if (String == NULL || DevicePathData == NULL) { return EFI_INVALID_PARAMETER; } @@ -92,8 +96,13 @@ GetDevicePath ( if (*String == 0) { return EFI_INVALID_PARAMETER; } - + // + // Check whether path data does exist. + // String += StrLen (L"PATH="); + if (*String == 0) { + return EFI_INVALID_PARAMETER; + } PathHdr = String; // @@ -102,33 +111,92 @@ GetDevicePath ( // of UEFI device path. // for (Length = 0; *String != 0 && *String != L'&'; String++, Length++); - DevicePathString = (EFI_STRING) AllocateZeroPool ((Length + 1) * sizeof (CHAR16)); - if (DevicePathString == NULL) { - return EFI_OUT_OF_RESOURCES; + // + // Check DevicePath Length + // + if (((Length + 1) / 2) < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { + return EFI_NOT_FOUND; } - StrnCpy (DevicePathString, PathHdr, Length); - *(DevicePathString + Length) = 0; - + // // The data in is encoded as hex UNICODE %02x bytes in the same order // as the device path resides in RAM memory. // Translate the data into binary. // - Length /= 2; - *DevicePath = (UINT8 *) AllocateZeroPool (Length); - if (*DevicePath == NULL) { - FreePool (DevicePathString); + DevicePathBuffer = (UINT8 *) AllocateZeroPool ((Length + 1) / 2); + if (DevicePathBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } + + // + // Convert DevicePath + // + ZeroMem (TemStr, sizeof (TemStr)); + for (Index = 0; Index < Length; Index ++) { + TemStr[0] = PathHdr[Index]; + DigitUint8 = (UINT8) StrHexToUint64 (TemStr); + if ((Index & 1) == 0) { + DevicePathBuffer [Index/2] = DigitUint8; + } else { + DevicePathBuffer [Index/2] = (UINT8) ((DevicePathBuffer [Index/2] << 4) + DigitUint8); + } + } + + // + // Validate DevicePath + // + DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) DevicePathBuffer; + while (!IsDevicePathEnd (DevicePath)) { + if ((DevicePath->Type == 0) || (DevicePath->SubType == 0) || (DevicePathNodeLength (DevicePath) < sizeof (EFI_DEVICE_PATH_PROTOCOL))) { + // + // Invalid device path + // + FreePool (DevicePathBuffer); + return EFI_NOT_FOUND; + } + DevicePath = NextDevicePathNode (DevicePath); + } + + // + // return the device path + // + *DevicePathData = DevicePathBuffer; + return EFI_SUCCESS; +} - HexStringToBufInReverseOrder (*DevicePath, &Length, DevicePathString); +/** + Converts the unicode character of the string from uppercase to lowercase. + This is a internal function. - FreePool (DevicePathString); + @param ConfigString String to be converted - return EFI_SUCCESS; +**/ +VOID +EFIAPI +HiiToLower ( + IN EFI_STRING ConfigString + ) +{ + EFI_STRING String; + BOOLEAN Lower; -} + ASSERT (ConfigString != NULL); + + // + // Convert all hex digits in range [A-F] in the configuration header to [a-f] + // + for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) { + if (*String == L'=') { + Lower = TRUE; + } else if (*String == L'&') { + Lower = FALSE; + } else if (Lower && *String >= L'A' && *String <= L'F') { + *String = (CHAR16) (*String - L'A' + L'a'); + } + } + return; +} /** Generate a sub string then output it. @@ -137,12 +205,16 @@ GetDevicePath ( @param String A constant string which is the prefix of the to be generated string, e.g. GUID= + @param BufferLen The length of the Buffer in bytes. + @param Buffer Points to a buffer which will be converted to be the - content of the generated string. - @param Flag If 1, the buffer contains data for the value of GUID or PATH stored in - UINT8 *; if 2, the buffer contains unicode string for the value of NAME; - if 3, the buffer contains other data. + content of the generated string. + + @param Flag If 1, the buffer contains data for the value of GUID or PATH stored in + UINT8 *; if 2, the buffer contains unicode string for the value of NAME; + if 3, the buffer contains other data. + @param SubStr Points to the output string. It's caller's responsibility to free this buffer. @@ -159,47 +231,73 @@ GenerateSubStr ( { UINTN Length; EFI_STRING Str; - EFI_STATUS Status; EFI_STRING StringHeader; + CHAR16 *TemString; + CHAR16 *TemName; + UINT8 *TemBuffer; + UINTN Index; ASSERT (String != NULL && SubStr != NULL); if (Buffer == NULL) { *SubStr = AllocateCopyPool (StrSize (String), String); ASSERT (*SubStr != NULL); - return ; + return; } - + + // + // Header + Data + '&' + '\0' + // Length = StrLen (String) + BufferLen * 2 + 1 + 1; - Str = AllocateZeroPool (Length * sizeof (CHAR16)); + Str = AllocateZeroPool (Length * sizeof (CHAR16)); ASSERT (Str != NULL); - StrCpy (Str, String); - Length = (BufferLen * 2 + 1) * sizeof (CHAR16); + StrCpyS (Str, Length, String); - Status = EFI_SUCCESS; StringHeader = Str + StrLen (String); + TemString = (CHAR16 *) StringHeader; switch (Flag) { case 1: - Status = BufInReverseOrderToHexString (StringHeader, (UINT8 *) Buffer, BufferLen); + // + // Convert Buffer to Hex String in reverse order + // + TemBuffer = ((UINT8 *) Buffer); + for (Index = 0; Index < BufferLen; Index ++, TemBuffer ++) { + TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2); + } break; case 2: - Status = UnicodeToConfigString (StringHeader, &Length, (CHAR16 *) Buffer); + // + // Check buffer is enough + // + TemName = (CHAR16 *) Buffer; + ASSERT ((BufferLen * 2 + 1) >= (StrLen (TemName) * 4 + 1)); + // + // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044" + // + for (; *TemName != L'\0'; TemName++) { + TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4); + } break; case 3: - Status = BufToHexString (StringHeader, &Length, (UINT8 *) Buffer, BufferLen); // - // Convert the uppercase to lowercase since is defined in lowercase format. + // Convert Buffer to Hex String // - ToLower (StringHeader); + TemBuffer = ((UINT8 *) Buffer) + BufferLen - 1; + for (Index = 0; Index < BufferLen; Index ++, TemBuffer --) { + TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2); + } break; default: break; } - ASSERT_EFI_ERROR (Status); - StrCat (Str, L"&"); + // + // Convert the uppercase to lowercase since is defined in lowercase format. + // + StrCatS (Str, Length, L"&"); + HiiToLower (Str); *SubStr = Str; } @@ -233,6 +331,13 @@ OutputConfigBody ( if (String == NULL || ConfigBody == NULL) { return EFI_INVALID_PARAMETER; } + + // + // The setting information should start OFFSET, not ALTCFG. + // + if (StrnCmp (String, L"&ALTCFG=", StrLen (L"&ALTCFG=")) == 0) { + return EFI_INVALID_PARAMETER; + } TmpPtr = StrStr (String, L"GUID="); if (TmpPtr == NULL) { @@ -249,6 +354,9 @@ OutputConfigBody ( } Length = TmpPtr - String; + if (Length == 0) { + return EFI_NOT_FOUND; + } Result = AllocateCopyPool (Length * sizeof (CHAR16), String); if (Result == NULL) { return EFI_OUT_OF_RESOURCES; @@ -257,7 +365,6 @@ OutputConfigBody ( *(Result + Length - 1) = 0; *ConfigBody = Result; return EFI_SUCCESS; - } /** @@ -284,6 +391,7 @@ AppendToMultiString ( { UINTN AppendStringSize; UINTN MultiStringSize; + UINTN MaxLen; if (MultiString == NULL || *MultiString == NULL || AppendString == NULL) { return EFI_INVALID_PARAMETER; @@ -291,6 +399,7 @@ AppendToMultiString ( AppendStringSize = StrSize (AppendString); MultiStringSize = StrSize (*MultiString); + MaxLen = MAX_STRING_LENGTH / sizeof (CHAR16); // // Enlarge the buffer each time when length exceeds MAX_STRING_LENGTH. @@ -302,12 +411,13 @@ AppendToMultiString ( MultiStringSize + AppendStringSize, (VOID *) (*MultiString) ); + MaxLen = (MultiStringSize + AppendStringSize) / sizeof (CHAR16); ASSERT (*MultiString != NULL); } // // Append the incoming string // - StrCat (*MultiString, AppendString); + StrCatS (*MultiString, MaxLen, AppendString); return EFI_SUCCESS; } @@ -326,7 +436,7 @@ AppendToMultiString ( to free memory. @param Len Length of the , in characters. - @retval EFI_OUT_OF_RESOURCES Insufficient resources to store neccessary + @retval EFI_OUT_OF_RESOURCES Insufficient resources to store necessary structures. @retval EFI_SUCCESS Value of is outputted in Number successfully. @@ -344,50 +454,3893 @@ GetValueOfNumber ( EFI_STRING Str; UINT8 *Buf; EFI_STATUS Status; + UINT8 DigitUint8; + UINTN Index; + CHAR16 TemStr[2]; - ASSERT (StringPtr != NULL && Number != NULL && Len != NULL); - ASSERT (*StringPtr != 0); + if (StringPtr == NULL || *StringPtr == L'\0' || Number == NULL || Len == NULL) { + return EFI_INVALID_PARAMETER; + } Buf = NULL; TmpPtr = StringPtr; - while (*StringPtr != 0 && *StringPtr != L'&') { + while (*StringPtr != L'\0' && *StringPtr != L'&') { + StringPtr++; + } + *Len = StringPtr - TmpPtr; + Length = *Len + 1; + + Str = (EFI_STRING) AllocateZeroPool (Length * sizeof (CHAR16)); + if (Str == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + CopyMem (Str, TmpPtr, *Len * sizeof (CHAR16)); + *(Str + *Len) = L'\0'; + + Length = (Length + 1) / 2; + Buf = (UINT8 *) AllocateZeroPool (Length); + if (Buf == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + Length = *Len; + ZeroMem (TemStr, sizeof (TemStr)); + for (Index = 0; Index < Length; Index ++) { + TemStr[0] = Str[Length - Index - 1]; + DigitUint8 = (UINT8) StrHexToUint64 (TemStr); + if ((Index & 1) == 0) { + Buf [Index/2] = DigitUint8; + } else { + Buf [Index/2] = (UINT8) ((DigitUint8 << 4) + Buf [Index/2]); + } + } + + *Number = Buf; + Status = EFI_SUCCESS; + +Exit: + if (Str != NULL) { + FreePool (Str); + } + + return Status; +} + +/** + To find the BlockName in the string with same value. + + @param String Pointer to a Null-terminated Unicode string. + @param BlockName Pointer to a Null-terminated Unicode string to search for. + @param Buffer Pointer to the value correspond to the BlockName. + @param Found The Block whether has been found. + @param BufferLen The length of the buffer. + + @retval EFI_OUT_OF_RESOURCES Insufficient resources to store necessary structures. + @retval EFI_SUCCESS The function finishes successfully. + +**/ +EFI_STATUS +FindSameBlockElement( + IN EFI_STRING String, + IN EFI_STRING BlockName, + IN UINT8 *Buffer, + OUT BOOLEAN *Found, + IN UINTN BufferLen + ) +{ + EFI_STRING BlockPtr; + UINTN Length; + UINT8 *TempBuffer; + EFI_STATUS Status; + + TempBuffer = NULL; + *Found = FALSE; + BlockPtr = StrStr (String, BlockName); + + while (BlockPtr != NULL) { + BlockPtr += StrLen (BlockName); + Status = GetValueOfNumber (BlockPtr, &TempBuffer, &Length); + if (EFI_ERROR (Status)) { + return Status; + } + ASSERT (TempBuffer != NULL); + if ((BufferLen == Length) && (0 == CompareMem (Buffer, TempBuffer, Length))) { + *Found = TRUE; + FreePool (TempBuffer); + TempBuffer = NULL; + return EFI_SUCCESS; + } else { + FreePool (TempBuffer); + TempBuffer = NULL; + BlockPtr = StrStr (BlockPtr + 1, BlockName); + } + } + return EFI_SUCCESS; +} + +/** + Compare the in ConfigAltResp and DefaultAltCfgResp, if the + in DefaultAltCfgResp but not in ConfigAltResp,add it to the ConfigAltResp. + + @param DefaultAltCfgResp Pointer to a null-terminated Unicode string in + format. The default value + string may contain more than one ConfigAltResp + string for the different varstore buffer. + @param ConfigAltResp Pointer to a null-terminated Unicode string in + format. + @param AltConfigHdr Pointer to a Unicode string in format. + @param ConfigAltRespChanged Whether the ConfigAltResp has been changed. + + @retval EFI_OUT_OF_RESOURCES Insufficient resources to store necessary structures. + @retval EFI_SUCCESS The function finishes successfully. + +**/ +EFI_STATUS +CompareBlockElementDefault ( + IN EFI_STRING DefaultAltCfgResp, + IN OUT EFI_STRING *ConfigAltResp, + IN EFI_STRING AltConfigHdr, + IN OUT BOOLEAN *ConfigAltRespChanged +) +{ + EFI_STATUS Status; + EFI_STRING BlockPtr; + EFI_STRING BlockPtrStart; + EFI_STRING StringPtr; + EFI_STRING AppendString; + EFI_STRING AltConfigHdrPtr; + UINT8 *TempBuffer; + UINTN OffsetLength; + UINTN AppendSize; + UINTN TotalSize; + BOOLEAN FoundOffset; + + AppendString = NULL; + TempBuffer = NULL; + // + // Make BlockPtr point to the first with AltConfigHdr in DefaultAltCfgResp. + // + AltConfigHdrPtr = StrStr (DefaultAltCfgResp, AltConfigHdr); + ASSERT (AltConfigHdrPtr != NULL); + BlockPtr = StrStr (AltConfigHdrPtr, L"&OFFSET="); + // + // Make StringPtr point to the AltConfigHdr in ConfigAltResp. + // + StringPtr = StrStr (*ConfigAltResp, AltConfigHdr); + ASSERT (StringPtr != NULL); + + while (BlockPtr != NULL) { + // + // Find the "&OFFSET=" block and get the value of the Number with AltConfigHdr in DefaultAltCfgResp. + // + BlockPtrStart = BlockPtr; + BlockPtr += StrLen (L"&OFFSET="); + Status = GetValueOfNumber (BlockPtr, &TempBuffer, &OffsetLength); + if (EFI_ERROR (Status)) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + // + // To find the same "&OFFSET=" block in ConfigAltResp. + // + Status = FindSameBlockElement (StringPtr, L"&OFFSET=", TempBuffer, &FoundOffset, OffsetLength); + if (TempBuffer != NULL) { + FreePool (TempBuffer); + TempBuffer = NULL; + } + if (EFI_ERROR (Status)) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + if (!FoundOffset) { + // + // Don't find the same "&OFFSET=" block in ConfigAltResp. + // Calculate the size of . + // ::='OFFSET=''&WIDTH=''&VALUE='. + // + BlockPtr = StrStr (BlockPtr + 1, L"&OFFSET="); + if (BlockPtr != NULL) { + AppendSize = (BlockPtr - BlockPtrStart) * sizeof (CHAR16); + } else { + AppendSize = StrSize (BlockPtrStart); + } + // + // Copy the to AppendString. + // + if (AppendString == NULL) { + AppendString = (EFI_STRING) AllocateZeroPool (AppendSize + sizeof (CHAR16)); + StrnCatS (AppendString, AppendSize / sizeof (CHAR16) + 1, BlockPtrStart, AppendSize / sizeof (CHAR16)); + } else { + TotalSize = StrSize (AppendString) + AppendSize + sizeof (CHAR16); + AppendString = (EFI_STRING) ReallocatePool ( + StrSize (AppendString), + TotalSize, + AppendString + ); + if (AppendString == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + StrnCatS (AppendString, TotalSize / sizeof (CHAR16), BlockPtrStart, AppendSize / sizeof (CHAR16)); + } + } else { + // + // To find next "&OFFSET=" block with AltConfigHdr in DefaultAltCfgResp. + // + BlockPtr = StrStr (BlockPtr + 1, L"&OFFSET="); + } + } + + if (AppendString != NULL) { + // + // Reallocate ConfigAltResp to copy the AppendString. + // + TotalSize = StrSize (*ConfigAltResp) + StrSize (AppendString) + sizeof (CHAR16); + *ConfigAltResp = (EFI_STRING) ReallocatePool ( + StrSize (*ConfigAltResp), + TotalSize, + *ConfigAltResp + ); + if (*ConfigAltResp == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + StrCatS (*ConfigAltResp, TotalSize / sizeof (CHAR16), AppendString); + *ConfigAltRespChanged = TRUE; + } + + Status = EFI_SUCCESS; + +Exit: + if (AppendString != NULL) { + FreePool (AppendString); + } + + return Status; +} + +/** + Compare the in ConfigAltResp and DefaultAltCfgResp, if the + in DefaultAltCfgResp but not in ConfigAltResp,add it to the ConfigAltResp. + + @param DefaultAltCfgResp Pointer to a null-terminated Unicode string in + format. The default value + string may contain more than one ConfigAltResp + string for the different varstore buffer. + @param ConfigAltResp Pointer to a null-terminated Unicode string in + format. + @param AltConfigHdr Pointer to a Unicode string in format. + @param ConfigAltRespChanged Whether the ConfigAltResp has been changed. + + @retval EFI_OUT_OF_RESOURCES Insufficient resources to store necessary structures. + @retval EFI_SUCCESS The function finishes successfully. + +**/ +EFI_STATUS +CompareNameElementDefault ( + IN EFI_STRING DefaultAltCfgResp, + IN OUT EFI_STRING *ConfigAltResp, + IN EFI_STRING AltConfigHdr, + IN OUT BOOLEAN *ConfigAltRespChanged +) +{ + EFI_STATUS Status; + EFI_STRING NvConfigPtr; + EFI_STRING NvConfigStart; + EFI_STRING NvConfigValuePtr; + EFI_STRING StringPtr; + EFI_STRING NvConfigExist; + EFI_STRING AppendString; + CHAR16 TempChar; + UINTN AppendSize; + UINTN TotalSize; + + AppendString = NULL; + NvConfigExist = NULL; + // + // Make NvConfigPtr point to the first with AltConfigHdr in DefaultAltCfgResp. + // + NvConfigPtr = StrStr (DefaultAltCfgResp, AltConfigHdr); + ASSERT (NvConfigPtr != NULL); + NvConfigPtr = StrStr (NvConfigPtr + StrLen(AltConfigHdr),L"&"); + // + // Make StringPtr point to the first with AltConfigHdr in ConfigAltResp. + // + StringPtr = StrStr (*ConfigAltResp, AltConfigHdr); + ASSERT (StringPtr != NULL); + StringPtr = StrStr (StringPtr + StrLen (AltConfigHdr), L"&"); + ASSERT (StringPtr != NULL); + + while (NvConfigPtr != NULL) { + // + // ::=