X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FHiiDatabaseDxe%2FConfigRouting.c;h=a97e28b8dd6090a49a8f888a677794a4f8cbfe59;hb=4a4297160fda8ff9646a7ae0cad7989a8aaeb619;hp=aed93be1f03f7e2c0db37f5e9025d5d9aee27c76;hpb=676df92c2c0c5bdeb0f8e27349f5dd467928ce09;p=mirror_edk2.git diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c index aed93be1f0..a97e28b8dd 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 - 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 @@ -9,21 +10,11 @@ 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" +extern HII_DATABASE_PRIVATE_DATA mPrivate; /** Calculate the number of Unicode characters of the incoming Configuration string, @@ -42,7 +33,7 @@ CalculateConfigStringLen ( IN EFI_STRING String ) { - UINTN Length; + EFI_STRING TmpPtr; // // "GUID=" should be the first element of incoming string. @@ -50,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); } @@ -73,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. @@ -84,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; } @@ -102,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; // @@ -112,210 +111,93 @@ 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; } - - HexStringToBufInReverseOrder (*DevicePath, &Length, DevicePathString); - - FreePool (DevicePathString); - - return EFI_SUCCESS; - -} - - -/** - Extract Storage from all Form Packages in current hii database. - - This is a internal function. - - @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. - -**/ -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)) { - if (HandleBuffer != NULL) { - FreePool (HandleBuffer); + // 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); } - 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)) { - FreePool (HandleBuffer); - FreePool (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; - } - 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)) { - FreePool (HandleBuffer); - FreePool (HiiPackageList); - FreePool (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'); } - - FreePool (HiiPackageList); } - FreePool (HandleBuffer); - - return EFI_SUCCESS; + return; } - /** Generate a sub string then output it. @@ -323,12 +205,16 @@ ExportAllStorage ( @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. @@ -345,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; } @@ -419,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) { @@ -435,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; @@ -443,47 +365,8 @@ OutputConfigBody ( *(Result + Length - 1) = 0; *ConfigBody = Result; return EFI_SUCCESS; - -} - - -/** - Adjusts the size of a previously allocated buffer. - - - @param OldPool A pointer to the buffer whose size is being adjusted. - @param OldSize The size of the current buffer. - @param NewSize The size of the new buffer. - - @return The new buffer allocated. - -**/ -VOID * -ReallocatePool ( - IN VOID *OldPool, - IN UINTN OldSize, - IN UINTN NewSize - ) -{ - VOID *NewPool; - - NewPool = NULL; - if (NewSize != 0) { - NewPool = AllocateZeroPool (NewSize); - } - - if (OldPool != NULL) { - if (NewPool != NULL) { - CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize); - } - - gBS->FreePool (OldPool); - } - - return NewPool; } - /** Append a string to a multi-string format. @@ -508,6 +391,7 @@ AppendToMultiString ( { UINTN AppendStringSize; UINTN MultiStringSize; + UINTN MaxLen; if (MultiString == NULL || *MultiString == NULL || AppendString == NULL) { return EFI_INVALID_PARAMETER; @@ -515,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. @@ -522,16 +407,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; } @@ -550,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. @@ -568,26 +454,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); @@ -595,10 +485,17 @@ GetValueOfNumber ( Status = EFI_OUT_OF_RESOURCES; goto Exit; } - - Status = 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; @@ -608,132 +505,3983 @@ Exit: 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 - future protocols. - @retval EFI_NOT_FOUND Routing data doesn't match any known driver. - Progress set to the "G" in "GUID" of the routing - header that doesn't match. Note: There is no - requirement that all routing data be validated - before any configuration extraction. - @retval EFI_INVALID_PARAMETER For example, passing in a NULL for the Request - parameter would result in this type of error. The - Progress parameter is set to NULL. - @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set to most recent & - before the error or the beginning of the string. - @retval EFI_INVALID_PARAMETER Unknown name. Progress points to the & before the - name in question. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to store necessary structures. + @retval EFI_SUCCESS The function finishes successfully. **/ EFI_STATUS -EFIAPI -HiiConfigRoutingExtractConfig ( - IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, - IN CONST EFI_STRING Request, - OUT EFI_STRING *Progress, - OUT EFI_STRING *Results +FindSameBlockElement( + IN EFI_STRING String, + IN EFI_STRING BlockName, + IN UINT8 *Buffer, + OUT BOOLEAN *Found, + IN UINTN BufferLen ) { - HII_DATABASE_PRIVATE_DATA *Private; - EFI_STRING StringPtr; - EFI_STRING ConfigRequest; - UINTN Length; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_STATUS Status; - LIST_ENTRY *Link; - HII_DATABASE_RECORD *Database; - UINT8 *DevicePathPkg; - UINT8 *CurrentDevicePath; - EFI_HANDLE DriverHandle; - EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; - EFI_STRING AccessProgress; - EFI_STRING AccessResults; - UINTN RemainSize; - EFI_STRING TmpPtr; - - // - // For size reduction, please define PcdSupportFullConfigRoutingProtocol - // as FALSE. But this renders the system to not 100% compliant with - // UEFI 2.1. Use this with caution. - // - if (!FeaturePcdGet (PcdSupportFullConfigRoutingProtocol)) { - return EFI_UNSUPPORTED; + 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; +} - if (This == NULL || Progress == NULL || Results == NULL) { - return EFI_INVALID_PARAMETER; - } +/** + Compare the in ConfigAltResp and DefaultAltCfgResp, if the + in DefaultAltCfgResp but not in ConfigAltResp,add it to the ConfigAltResp. - if (Request == NULL) { - *Progress = NULL; - return EFI_INVALID_PARAMETER; - } + @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. - Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This); - StringPtr = Request; - *Progress = StringPtr; + @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; // - // The first element of should be - // , which is in 'GUID=' syntax. + // Make BlockPtr point to the first with AltConfigHdr in DefaultAltCfgResp. // - if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) { - return EFI_INVALID_PARAMETER; - } - + AltConfigHdrPtr = StrStr (DefaultAltCfgResp, AltConfigHdr); + ASSERT (AltConfigHdrPtr != NULL); + BlockPtr = StrStr (AltConfigHdrPtr, L"&OFFSET="); // - // Allocate a fix length of memory to store Results. Reallocate memory for - // Results if this fix length is insufficient. + // Make StringPtr point to the AltConfigHdr in ConfigAltResp. // - *Results = (EFI_STRING) AllocateZeroPool (MAX_STRING_LENGTH); - if (*Results == NULL) { - return EFI_OUT_OF_RESOURCES; - } + StringPtr = StrStr (*ConfigAltResp, AltConfigHdr); + ASSERT (StringPtr != NULL); - while (*StringPtr != 0 && StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) == 0) { + while (BlockPtr != NULL) { // - // If parsing error, set Progress to the beginning of the - // or most recent & before the error. + // Find the "&OFFSET=" block and get the value of the Number with AltConfigHdr in DefaultAltCfgResp. // - if (StringPtr == Request) { - *Progress = StringPtr; - } else { - *Progress = StringPtr - 1; + BlockPtrStart = BlockPtr; + BlockPtr += StrLen (L"&OFFSET="); + Status = GetValueOfNumber (BlockPtr, &TempBuffer, &OffsetLength); + if (EFI_ERROR (Status)) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; } - // - // Process each of + // 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) { + // + // ::=