X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FHiiDatabaseDxe%2FConfigRouting.c;h=c9ff1cff627f9cf49e1ac6976d00a131d1b472c6;hp=15a55d794ae68477691f8bda74cfbcc0f62c981e;hb=9f4048f7f8cd4b6bd5eee0f0c4bfd4eb6926a536;hpb=93e3992d1ea50fb30c48f498d257d4e66252dd9b diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c index 15a55d794a..c9ff1cff62 100644 --- a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c +++ b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c @@ -1,7 +1,8 @@ /** @file +Implementation of interfaces function for EFI_HII_CONFIG_ROUTING_PROTOCOL. -Copyright (c) 2007, Intel Corporation -All rights reserved. This program and the accompanying materials +Copyright (c) 2007 - 2017, 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 @@ -9,224 +10,30 @@ http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -Module Name: - - ConfigRouting.c - -Abstract: - - Implementation for EFI_HII_CONFIG_ROUTING_PROTOCOL. - -Revision History - - **/ #include "HiiDatabase.h" - -#ifndef DISABLE_UNUSED_HII_PROTOCOLS - -STATIC -CHAR16 -NibbleToHexCharPrivate ( - IN UINT8 Nibble - ) -/*++ - - Routine Description: - Converts the low nibble of a byte to hex unicode character. - - Arguments: - Nibble - lower nibble of a byte. - - Returns: - Hex unicode character between L'0' to L'f'. - ---*/ -{ - Nibble &= 0x0F; - - if (Nibble <= 0x9) { - return (CHAR16)(Nibble + L'0'); - } - - return (CHAR16)(Nibble - 0xA + L'a'); -} - - -/** - Converts Unicode string to binary buffer. - The conversion may be partial. - The first character in the string that is not hex digit stops the conversion. - At a minimum, any blob of data could be represented as a hex string. - - @param Buf Pointer to buffer that receives the data. - @param Len Length in bytes of the buffer to hold converted - data. If routine return with EFI_SUCCESS, - containing length of converted data. If routine - return with EFI_BUFFER_TOO_SMALL, containg length - of buffer desired. - @param Str String to be converted from. - @param ConvertedStrLen Length of the Hex String consumed. - - @retval EFI_SUCCESS Routine Success. - @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold converted data. - -**/ -STATIC -EFI_STATUS -HexStringToBufPrivate ( - IN OUT UINT8 *Buf, - IN OUT UINTN *Len, - IN CHAR16 *Str, - OUT UINTN *ConvertedStrLen OPTIONAL - ) -{ - UINTN HexCnt; - UINTN Idx; - UINTN BufferLength; - UINT8 Digit; - UINT8 Byte; - - // - // Find out how many hex characters the string has. - // - for (Idx = 0, HexCnt = 0; R8_IsHexDigit (&Digit, Str[Idx]); Idx++, HexCnt++); - - if (HexCnt == 0) { - *Len = 0; - return EFI_SUCCESS; - } - // - // Two Unicode characters make up 1 buffer byte. Round up. - // - BufferLength = (HexCnt + 1) / 2; - - // - // Test if buffer is passed enough. - // - if (BufferLength > (*Len)) { - *Len = BufferLength; - return EFI_BUFFER_TOO_SMALL; - } - - *Len = BufferLength; - - for (Idx = 0; Idx < HexCnt; Idx++) { - - R8_IsHexDigit (&Digit, Str[Idx]); - - // - // For odd charaters, write the lower nibble for each buffer byte, - // and for even characters, the upper nibble. - // - if ((Idx & 1) == 0) { - Byte = (UINT8) (Digit << 4); - } else { - Byte = Buf[Idx / 2]; - Byte &= 0xF0; - Byte = (UINT8) (Byte | Digit); - } - - Buf[Idx / 2] = Byte; - } - - if (ConvertedStrLen != NULL) { - *ConvertedStrLen = HexCnt; - } - - return EFI_SUCCESS; -} - - -/** - Converts binary buffer to Unicode string. - At a minimum, any blob of data could be represented as a hex string. - - @param Str Pointer to the string. - @param HexStringBufferLength Length in bytes of buffer to hold the hex string. - Includes tailing '\0' character. If routine return - with EFI_SUCCESS, containing length of hex string - buffer. If routine return with - EFI_BUFFER_TOO_SMALL, containg length of hex - string buffer desired. - @param Buf Buffer to be converted from. - @param Len Length in bytes of the buffer to be converted. - @param Flag If TRUE, encode the data in the same order as the - it resides in the Buf. Else encode it in the - reverse direction. - - @retval EFI_SUCCESS Routine success. - @retval EFI_BUFFER_TOO_SMALL The hex string buffer is too small. - -**/ -STATIC -EFI_STATUS -BufToHexStringPrivate ( - IN OUT CHAR16 *Str, - IN OUT UINTN *HexStringBufferLength, - IN UINT8 *Buf, - IN UINTN Len, - IN BOOLEAN Flag - ) -{ - UINTN Idx; - UINT8 Byte; - UINTN StrLen; - - // - // Make sure string is either passed or allocate enough. - // It takes 2 Unicode characters (4 bytes) to represent 1 byte of the binary buffer. - // Plus the Unicode termination character. - // - StrLen = Len * 2; - if ((*HexStringBufferLength) < (StrLen + 1) * sizeof (CHAR16)) { - *HexStringBufferLength = (StrLen + 1) * sizeof (CHAR16); - return EFI_BUFFER_TOO_SMALL; - } - - *HexStringBufferLength = (StrLen + 1) * sizeof (CHAR16); - - // - // Ends the string. - // - Str[StrLen] = 0; - - for (Idx = 0; Idx < Len; Idx++) { - - Byte = Buf[Idx]; - if (Flag) { - Str[Idx * 2] = NibbleToHexCharPrivate ((UINT8)(Byte >> 4)); - Str[Idx * 2 + 1] = NibbleToHexCharPrivate (Byte); - } else { - Str[StrLen - 1 - Idx * 2] = NibbleToHexCharPrivate (Byte); - Str[StrLen - 2 - Idx * 2] = NibbleToHexCharPrivate ((UINT8)(Byte >> 4)); - } - } - - return EFI_SUCCESS; -} - - +extern HII_DATABASE_PRIVATE_DATA mPrivate; /** Calculate the number of Unicode characters of the incoming Configuration string, not including NULL terminator. + This is a internal function. + @param String String in or format. @return The number of Unicode characters. **/ -STATIC UINTN CalculateConfigStringLen ( IN EFI_STRING String ) { - UINTN Length; + EFI_STRING TmpPtr; // // "GUID=" should be the first element of incoming string. @@ -234,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); } @@ -254,27 +58,34 @@ CalculateConfigStringLen ( Convert the hex UNICODE %02x encoding of a UEFI device path to binary from of . + 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. **/ -STATIC 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; } @@ -285,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; // @@ -295,264 +111,214 @@ 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. - // Two Unicode characters make up 1 buffer byte. // - Length /= 2; - *DevicePath = (UINT8 *) AllocateZeroPool (Length); - if (*DevicePath == NULL) { - SafeFreePool (DevicePathString); + DevicePathBuffer = (UINT8 *) AllocateZeroPool ((Length + 1) / 2); + if (DevicePathBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } - - HexStringToBufPrivate (*DevicePath, &Length, DevicePathString, NULL); - - SafeFreePool (DevicePathString); - - return EFI_SUCCESS; - -} - - -/** - Extract Storage from all Form Packages in current hii database. - - @param HiiDatabase EFI_HII_DATABASE_PROTOCOL instance. - @param StorageListHead Storage link List head. - - @retval EFI_NOT_FOUND There is no form package in current hii database. - @retval EFI_INVALID_PARAMETER Any parameter is invalid. - @retval EFI_SUCCESS All existing storage is exported. - -**/ -STATIC -EFI_STATUS -ExportAllStorage ( - IN EFI_HII_DATABASE_PROTOCOL *HiiDatabase, - IN OUT LIST_ENTRY *StorageListHead -) -{ - EFI_STATUS Status; - UINTN BufferSize; - UINTN HandleCount; - EFI_HII_HANDLE *HandleBuffer; - UINTN Index; - UINTN Index2; - EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList; - EFI_HII_PACKAGE_HEADER *Package; - UINT8 *OpCodeData; - UINT8 Operand; - UINT32 Offset; - HII_FORMSET_STORAGE *Storage; - EFI_HII_HANDLE HiiHandle; - EFI_HANDLE DriverHandle; - CHAR8 *AsciiString; - UINT32 PackageListLength; - EFI_HII_PACKAGE_HEADER PackageHeader; - - // - // Find the package list which contains Form package. + // - BufferSize = 0; - HandleBuffer = NULL; - Status = HiiListPackageLists ( - HiiDatabase, - EFI_HII_PACKAGE_FORM, - NULL, - &BufferSize, - HandleBuffer - ); - if (Status == EFI_BUFFER_TOO_SMALL) { - HandleBuffer = AllocateZeroPool (BufferSize); - ASSERT (HandleBuffer != NULL); - - Status = HiiListPackageLists ( - HiiDatabase, - EFI_HII_PACKAGE_FORM, - NULL, - &BufferSize, - HandleBuffer - ); - } - if (EFI_ERROR (Status)) { - SafeFreePool (HandleBuffer); - return Status; - } - - HandleCount = BufferSize / sizeof (EFI_HII_HANDLE); - for (Index = 0; Index < HandleCount; Index++) { - HiiHandle = HandleBuffer[Index]; - - BufferSize = 0; - HiiPackageList = NULL; - Status = HiiExportPackageLists (HiiDatabase, HiiHandle, &BufferSize, HiiPackageList); - if (Status == EFI_BUFFER_TOO_SMALL) { - HiiPackageList = AllocateZeroPool (BufferSize); - ASSERT (HiiPackageList != NULL); - Status = HiiExportPackageLists (HiiDatabase, HiiHandle, &BufferSize, HiiPackageList); - } - if (EFI_ERROR (Status)) { - SafeFreePool (HandleBuffer); - SafeFreePool (HiiPackageList); - return Status; - } - - // - // Get Form package from this HII package List - // - Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER); - CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32)); - Package = NULL; - ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER)); - - while (Offset < PackageListLength) { - Package = (EFI_HII_PACKAGE_HEADER *) (((UINT8 *) HiiPackageList) + Offset); - CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER)); - if (PackageHeader.Type == EFI_HII_PACKAGE_FORM) { - break; - } - Offset += PackageHeader.Length; + // 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); } - if (Offset >= PackageListLength) { + } + + // + // 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))) { // - // Error here: No Form package found in this Package List + // Invalid device path // - ASSERT (FALSE); + FreePool (DevicePathBuffer); + return EFI_NOT_FOUND; } + DevicePath = NextDevicePathNode (DevicePath); + } - // - // Search Storage definition in this Form package - // - Offset = sizeof (EFI_HII_PACKAGE_HEADER); - while (Offset < PackageHeader.Length) { - OpCodeData = ((UINT8 *) Package) + Offset; - Offset += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length; - - Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode; - - if ((Operand == EFI_IFR_VARSTORE_OP) || - (Operand == EFI_IFR_VARSTORE_NAME_VALUE_OP) || - (Operand == EFI_IFR_VARSTORE_EFI_OP)) { - - Storage = AllocateZeroPool (sizeof (HII_FORMSET_STORAGE)); - ASSERT (Storage != NULL); - InsertTailList (StorageListHead, &Storage->Entry); - - Storage->Signature = HII_FORMSET_STORAGE_SIGNATURE; - Storage->HiiHandle = HiiHandle; - - Status = HiiGetPackageListHandle (HiiDatabase, HiiHandle, &DriverHandle); - if (EFI_ERROR (Status)) { - SafeFreePool (HandleBuffer); - SafeFreePool (HiiPackageList); - SafeFreePool (Storage); - return Status; - } - Storage->DriverHandle = DriverHandle; + // + // return the device path + // + *DevicePathData = DevicePathBuffer; + return EFI_SUCCESS; +} - if (Operand == EFI_IFR_VARSTORE_OP) { - Storage->Type = EFI_HII_VARSTORE_BUFFER; +/** + Converts the unicode character of the string from uppercase to lowercase. + This is a internal function. - CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID)); - CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16)); + @param ConfigString String to be converted - AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name; - Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2); - ASSERT (Storage->Name != NULL); - for (Index2 = 0; AsciiString[Index2] != 0; Index2++) { - Storage->Name[Index2] = (CHAR16) AsciiString[Index2]; - } - // - // Append '\0' to the end of the unicode string. - // - Storage->Name[Index2] = 0; - } else if (Operand == EFI_IFR_VARSTORE_NAME_VALUE_OP) { - Storage->Type = EFI_HII_VARSTORE_NAME_VALUE; +**/ +VOID +EFIAPI +HiiToLower ( + IN EFI_STRING ConfigString + ) +{ + EFI_STRING String; + BOOLEAN Lower; - CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID)); - } else if (Operand == EFI_IFR_VARSTORE_EFI_OP) { - Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE; + ASSERT (ConfigString != NULL); - CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID)); - } - } + // + // 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'); } - - SafeFreePool (HiiPackageList); } - SafeFreePool (HandleBuffer); - - return EFI_SUCCESS; + return; } - /** Generate a sub string then output it. + This is a internal function. + @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 hex - string and to be the content of the generated - string. - @param Flag If TRUE, convert the buffer data in the same order - as the it resides in the Buffer. Else convert it - in the reverse direction. + + @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. + @param SubStr Points to the output string. It's caller's responsibility to free this buffer. **/ -STATIC VOID GenerateSubStr ( IN CONST EFI_STRING String, IN UINTN BufferLen, - IN UINT8 *Buffer, - IN BOOLEAN Flag, + IN VOID *Buffer, + IN UINT8 Flag, OUT EFI_STRING *SubStr ) { 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; } - - Length = BufferLen * 2 + 1 + StrLen (String) + 1; - Str = AllocateZeroPool (Length * sizeof (CHAR16)); + + // + // Header + Data + '&' + '\0' + // + Length = StrLen (String) + BufferLen * 2 + 1 + 1; + Str = AllocateZeroPool (Length * sizeof (CHAR16)); ASSERT (Str != NULL); - StrCpy (Str, String); - Length = (BufferLen * 2 + 1) * sizeof (CHAR16); + StrCpyS (Str, Length, String); - Status = BufToHexStringPrivate ( - Str + StrLen (String), - &Length, - Buffer, - BufferLen, - Flag - ); + StringHeader = Str + StrLen (String); + TemString = (CHAR16 *) StringHeader; + + switch (Flag) { + case 1: + // + // Convert Buffer to Hex String in reverse order + // + TemBuffer = ((UINT8 *) Buffer); + for (Index = 0; Index < BufferLen; Index ++, TemBuffer ++) { + UnicodeValueToStringS ( + TemString, + sizeof (CHAR16) * (Length - StrnLenS (Str, Length)), + PREFIX_ZERO | RADIX_HEX, + *TemBuffer, + 2 + ); + TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length)); + } + break; + case 2: + // + // 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++) { + UnicodeValueToStringS ( + TemString, + sizeof (CHAR16) * (Length - StrnLenS (Str, Length)), + PREFIX_ZERO | RADIX_HEX, + *TemName, + 4 + ); + TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length)); + } + break; + case 3: + // + // Convert Buffer to Hex String + // + TemBuffer = ((UINT8 *) Buffer) + BufferLen - 1; + for (Index = 0; Index < BufferLen; Index ++, TemBuffer --) { + UnicodeValueToStringS ( + TemString, + sizeof (CHAR16) * (Length - StrnLenS (Str, Length)), + PREFIX_ZERO | RADIX_HEX, + *TemBuffer, + 2 + ); + TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length)); + } + 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; } @@ -561,6 +327,8 @@ GenerateSubStr ( /** Retrieve the from String then output it. + This is a internal function. + @param String A sub string of a configuration string in format. @param ConfigBody Points to the output string. It's caller's @@ -571,7 +339,6 @@ GenerateSubStr ( @retval EFI_SUCCESS All existing storage is exported. **/ -STATIC EFI_STATUS OutputConfigBody ( IN EFI_STRING String, @@ -585,6 +352,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) { @@ -601,6 +375,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; @@ -609,55 +386,13 @@ OutputConfigBody ( *(Result + Length - 1) = 0; *ConfigBody = Result; return EFI_SUCCESS; - -} - - -#endif - -VOID * -ReallocatePool ( - IN VOID *OldPool, - IN UINTN OldSize, - IN UINTN NewSize - ) -/*++ - -Routine Description: - Adjusts the size of a previously allocated buffer. - -Arguments: - OldPool - A pointer to the buffer whose size is being adjusted. - OldSize - The size of the current buffer. - NewSize - The size of the new buffer. - -Returns: - Points to the new buffer - ---*/ -{ - VOID *NewPool; - - NewPool = NULL; - if (NewSize) { - NewPool = AllocateZeroPool (NewSize); - } - - if (OldPool) { - if (NewPool) { - CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize); - } - - gBS->FreePool (OldPool); - } - - return NewPool; } - /** Append a string to a multi-string format. + This is a internal function. + @param MultiString String in , , or . On input, the buffer length of this string is @@ -669,7 +404,6 @@ Returns: @retval EFI_SUCCESS AppendString is append to the end of MultiString **/ -STATIC EFI_STATUS AppendToMultiString ( IN OUT EFI_STRING *MultiString, @@ -678,6 +412,7 @@ AppendToMultiString ( { UINTN AppendStringSize; UINTN MultiStringSize; + UINTN MaxLen; if (MultiString == NULL || *MultiString == NULL || AppendString == NULL) { return EFI_INVALID_PARAMETER; @@ -685,6 +420,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. @@ -692,16 +428,17 @@ AppendToMultiString ( if (MultiStringSize + AppendStringSize > MAX_STRING_LENGTH || MultiStringSize > MAX_STRING_LENGTH) { *MultiString = (EFI_STRING) ReallocatePool ( - (VOID *) (*MultiString), MultiStringSize, - MultiStringSize + AppendStringSize + 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; } @@ -712,19 +449,20 @@ AppendToMultiString ( or WIDTH or VALUE. ::= 'OFFSET='&'WIDTH='&'VALUE'= + This is a internal function. + @param StringPtr String in format and points to the first character of . @param Number The output value. Caller takes the responsibility 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. **/ -STATIC EFI_STATUS GetValueOfNumber ( IN EFI_STRING StringPtr, @@ -737,26 +475,30 @@ 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 (EFI_STRING)); + 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) = 0; + *(Str + *Len) = L'\0'; Length = (Length + 1) / 2; Buf = (UINT8 *) AllocateZeroPool (Length); @@ -764,45 +506,3906 @@ GetValueOfNumber ( Status = EFI_OUT_OF_RESOURCES; goto Exit; } - - Status = R8_HexStringToBuf (Buf, &Length, Str, NULL); - if (EFI_ERROR (Status)) { - 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: - SafeFreePool (Str); + if (Str != NULL) { + FreePool (Str); + } + return Status; } - /** - This function allows a caller to extract the current configuration - for one or more named elements from one or more drivers. + To find the BlockName in the string with same value. - @param This A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL - instance. - @param Request A null-terminated Unicode string in - format. - @param Progress On return, points to a character in the Request - string. Points to the string's null terminator if - request was successful. Points to the most recent - & before the first failing name / value pair (or - the beginning of the string if the failure is in - the first name / value pair) if the request was - not successful. - @param Results Null-terminated Unicode string in - format which has all values - filled in for the names in the Request string. - String to be allocated by the called function. + @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_SUCCESS The Results string is filled with the values - corresponding to all requested names. - @retval EFI_OUT_OF_RESOURCES Not enough memory to store the parts of the - results that must be stored awaiting possible + @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) { + // + // ::=