/** @file\r
+Implementation of interfaces function for EFI_HII_CONFIG_ROUTING_PROTOCOL.\r
\r
Copyright (c) 2007 - 2008, Intel Corporation\r
All rights reserved. This program and the accompanying materials\r
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
\r
-Module Name:\r
-\r
- ConfigRouting.c\r
-\r
-Abstract:\r
-\r
- Implementation for EFI_HII_CONFIG_ROUTING_PROTOCOL.\r
-\r
-Revision History\r
-\r
-\r
**/\r
\r
\r
#include "HiiDatabase.h"\r
\r
-#ifndef DISABLE_UNUSED_HII_PROTOCOLS\r
-\r
/**\r
Calculate the number of Unicode characters of the incoming Configuration string,\r
not including NULL terminator.\r
\r
+ This is a internal function.\r
+\r
@param String String in <MultiConfigRequest> or\r
<MultiConfigResp> format.\r
\r
@return The number of Unicode characters.\r
\r
**/\r
-STATIC\r
UINTN\r
CalculateConfigStringLen (\r
IN EFI_STRING String\r
Convert the hex UNICODE %02x encoding of a UEFI device path to binary\r
from <PathHdr> of <ConfigHdr>.\r
\r
+ This is a internal function.\r
+\r
@param String UEFI configuration string\r
@param DevicePath binary of a UEFI device path.\r
\r
binary format.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
GetDevicePath (\r
IN EFI_STRING String,\r
UINTN Length;\r
EFI_STRING PathHdr;\r
EFI_STRING DevicePathString;\r
+ UINT8 *DevicePathBuffer;\r
+ CHAR16 TemStr[2];\r
+ UINTN Index;\r
+ UINT8 DigitUint8;\r
\r
if (String == NULL || DevicePath == NULL) {\r
return EFI_INVALID_PARAMETER;\r
// as the device path resides in RAM memory.\r
// Translate the data into binary.\r
//\r
- Length /= 2;\r
- *DevicePath = (UINT8 *) AllocateZeroPool (Length);\r
- if (*DevicePath == NULL) {\r
- SafeFreePool (DevicePathString);\r
+ DevicePathBuffer = (UINT8 *) AllocateZeroPool ((Length + 1) / 2);\r
+ if (DevicePathBuffer == NULL) {\r
+ FreePool (DevicePathString);\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- HexStringToBuffer (*DevicePath, &Length, DevicePathString);\r
+ ZeroMem (TemStr, sizeof (TemStr));\r
+ for (Index = 0; DevicePathString[Index] != L'\0'; Index ++) {\r
+ TemStr[0] = DevicePathString[Index];\r
+ DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
+ if ((Index & 1) == 0) {\r
+ DevicePathBuffer [Index/2] = DigitUint8;\r
+ } else {\r
+ DevicePathBuffer [Index/2] = (UINT8) ((DevicePathBuffer [Index/2] << 4) + DigitUint8);\r
+ }\r
+ }\r
\r
- SafeFreePool (DevicePathString);\r
+ FreePool (DevicePathString);\r
+ \r
+ *DevicePath = DevicePathBuffer;\r
\r
return EFI_SUCCESS;\r
\r
}\r
\r
-\r
/**\r
- Extract Storage from all Form Packages in current hii database.\r
-\r
- @param HiiDatabase EFI_HII_DATABASE_PROTOCOL instance.\r
- @param StorageListHead Storage link List head.\r
+ Converts the unicode character of the string from uppercase to lowercase.\r
+ This is a internal function.\r
\r
- @retval EFI_NOT_FOUND There is no form package in current hii database.\r
- @retval EFI_INVALID_PARAMETER Any parameter is invalid.\r
- @retval EFI_SUCCESS All existing storage is exported.\r
+ @param Str String to be converted\r
\r
**/\r
-STATIC\r
-EFI_STATUS\r
-ExportAllStorage (\r
- IN EFI_HII_DATABASE_PROTOCOL *HiiDatabase,\r
- IN OUT LIST_ENTRY *StorageListHead\r
-)\r
+VOID\r
+EFIAPI\r
+HiiToLower (\r
+ IN OUT CHAR16 *Str\r
+ )\r
{\r
- EFI_STATUS Status;\r
- UINTN BufferSize;\r
- UINTN HandleCount;\r
- EFI_HII_HANDLE *HandleBuffer;\r
- UINTN Index;\r
- UINTN Index2;\r
- EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
- EFI_HII_PACKAGE_HEADER *Package;\r
- UINT8 *OpCodeData;\r
- UINT8 Operand;\r
- UINT32 Offset;\r
- HII_FORMSET_STORAGE *Storage;\r
- EFI_HII_HANDLE HiiHandle;\r
- EFI_HANDLE DriverHandle;\r
- CHAR8 *AsciiString;\r
- UINT32 PackageListLength;\r
- EFI_HII_PACKAGE_HEADER PackageHeader;\r
-\r
- //\r
- // Find the package list which contains Form package.\r
- //\r
- BufferSize = 0;\r
- HandleBuffer = NULL;\r
- Status = HiiListPackageLists (\r
- HiiDatabase,\r
- EFI_HII_PACKAGE_FORM,\r
- NULL,\r
- &BufferSize,\r
- HandleBuffer\r
- );\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- HandleBuffer = AllocateZeroPool (BufferSize);\r
- ASSERT (HandleBuffer != NULL);\r
-\r
- Status = HiiListPackageLists (\r
- HiiDatabase,\r
- EFI_HII_PACKAGE_FORM,\r
- NULL,\r
- &BufferSize,\r
- HandleBuffer\r
- );\r
- }\r
- if (EFI_ERROR (Status)) {\r
- SafeFreePool (HandleBuffer);\r
- return Status;\r
- }\r
-\r
- HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);\r
- for (Index = 0; Index < HandleCount; Index++) {\r
- HiiHandle = HandleBuffer[Index];\r
-\r
- BufferSize = 0;\r
- HiiPackageList = NULL;\r
- Status = HiiExportPackageLists (HiiDatabase, HiiHandle, &BufferSize, HiiPackageList);\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- HiiPackageList = AllocateZeroPool (BufferSize);\r
- ASSERT (HiiPackageList != NULL);\r
- Status = HiiExportPackageLists (HiiDatabase, HiiHandle, &BufferSize, HiiPackageList);\r
+ CHAR16 *Ptr;\r
+ \r
+ for (Ptr = Str; *Ptr != L'\0'; Ptr++) {\r
+ if (*Ptr >= L'A' && *Ptr <= L'Z') {\r
+ *Ptr = (CHAR16) (*Ptr - L'A' + L'a');\r
}\r
- if (EFI_ERROR (Status)) {\r
- SafeFreePool (HandleBuffer);\r
- SafeFreePool (HiiPackageList);\r
- return Status;\r
- }\r
-\r
- //\r
- // Get Form package from this HII package List\r
- //\r
- Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
- CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
- Package = NULL;\r
- ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));\r
-\r
- while (Offset < PackageListLength) {\r
- Package = (EFI_HII_PACKAGE_HEADER *) (((UINT8 *) HiiPackageList) + Offset);\r
- CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
- if (PackageHeader.Type == EFI_HII_PACKAGE_FORM) {\r
- break;\r
- }\r
- Offset += PackageHeader.Length;\r
- }\r
- if (Offset >= PackageListLength) {\r
- //\r
- // Error here: No Form package found in this Package List\r
- //\r
- ASSERT (FALSE);\r
- }\r
-\r
- //\r
- // Search Storage definition in this Form package\r
- //\r
- Offset = sizeof (EFI_HII_PACKAGE_HEADER);\r
- while (Offset < PackageHeader.Length) {\r
- OpCodeData = ((UINT8 *) Package) + Offset;\r
- Offset += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
-\r
- Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
-\r
- if ((Operand == EFI_IFR_VARSTORE_OP) ||\r
- (Operand == EFI_IFR_VARSTORE_NAME_VALUE_OP) ||\r
- (Operand == EFI_IFR_VARSTORE_EFI_OP)) {\r
-\r
- Storage = AllocateZeroPool (sizeof (HII_FORMSET_STORAGE));\r
- ASSERT (Storage != NULL);\r
- InsertTailList (StorageListHead, &Storage->Entry);\r
-\r
- Storage->Signature = HII_FORMSET_STORAGE_SIGNATURE;\r
- Storage->HiiHandle = HiiHandle;\r
-\r
- Status = HiiGetPackageListHandle (HiiDatabase, HiiHandle, &DriverHandle);\r
- if (EFI_ERROR (Status)) {\r
- SafeFreePool (HandleBuffer);\r
- SafeFreePool (HiiPackageList);\r
- SafeFreePool (Storage);\r
- return Status;\r
- }\r
- Storage->DriverHandle = DriverHandle;\r
-\r
- if (Operand == EFI_IFR_VARSTORE_OP) {\r
- Storage->Type = EFI_HII_VARSTORE_BUFFER;\r
-\r
- CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
- CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));\r
-\r
- AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;\r
- Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);\r
- ASSERT (Storage->Name != NULL);\r
- for (Index2 = 0; AsciiString[Index2] != 0; Index2++) {\r
- Storage->Name[Index2] = (CHAR16) AsciiString[Index2];\r
- }\r
- //\r
- // Append '\0' to the end of the unicode string.\r
- //\r
- Storage->Name[Index2] = 0;\r
- } else if (Operand == EFI_IFR_VARSTORE_NAME_VALUE_OP) {\r
- Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;\r
-\r
- CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
- } else if (Operand == EFI_IFR_VARSTORE_EFI_OP) {\r
- Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;\r
-\r
- CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
- }\r
- }\r
- }\r
-\r
- SafeFreePool (HiiPackageList);\r
}\r
-\r
- SafeFreePool (HandleBuffer);\r
-\r
- return EFI_SUCCESS;\r
}\r
\r
-\r
/**\r
Generate a sub string then output it.\r
\r
+ This is a internal function.\r
+\r
@param String A constant string which is the prefix of the to be\r
generated string, e.g. GUID=\r
@param BufferLen The length of the Buffer in bytes.\r
\r
\r
**/\r
-STATIC\r
VOID\r
GenerateSubStr (\r
IN CONST EFI_STRING String,\r
{\r
UINTN Length;\r
EFI_STRING Str;\r
- EFI_STATUS Status;\r
EFI_STRING StringHeader;\r
+ CHAR16 *TemString;\r
+ CHAR16 *TemName;\r
+ UINT8 *TemBuffer;\r
+ UINTN Index;\r
\r
ASSERT (String != NULL && SubStr != NULL);\r
\r
}\r
\r
Length = StrLen (String) + BufferLen * 2 + 1 + 1;\r
- Str = AllocateZeroPool (Length * sizeof (CHAR16));\r
+ Str = AllocateZeroPool (Length * sizeof (CHAR16));\r
ASSERT (Str != NULL);\r
\r
StrCpy (Str, String);\r
Length = (BufferLen * 2 + 1) * sizeof (CHAR16);\r
\r
- Status = EFI_SUCCESS;\r
StringHeader = Str + StrLen (String);\r
+ TemString = (CHAR16 *) StringHeader;\r
\r
switch (Flag) {\r
case 1:\r
- Status = BufferToHexString (StringHeader, (UINT8 *) Buffer, BufferLen);\r
+ //\r
+ // Convert Buffer to Hex String in reverse order\r
+ //\r
+ TemBuffer = ((UINT8 *) Buffer);\r
+ for (Index = 0; Index < BufferLen; Index ++, TemBuffer ++) {\r
+ TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
+ }\r
break;\r
case 2:\r
- Status = UnicodeToConfigString (StringHeader, &Length, (CHAR16 *) Buffer);\r
+ //\r
+ // Check buffer is enough\r
+ //\r
+ TemName = (CHAR16 *) Buffer;\r
+ ASSERT (Length < ((StrLen (TemName) * 4 + 1) * sizeof (CHAR16)));\r
+ //\r
+ // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"\r
+ //\r
+ for (; *TemName != L'\0'; TemName++) {\r
+ TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);\r
+ }\r
break;\r
case 3:\r
- Status = BufToHexString (StringHeader, &Length, (UINT8 *) Buffer, BufferLen);\r
//\r
- // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.\r
+ // Convert Buffer to Hex String\r
//\r
- ToLower (StringHeader);\r
+ TemBuffer = ((UINT8 *) Buffer) + BufferLen - 1;\r
+ for (Index = 0; Index < BufferLen; Index ++, TemBuffer --) {\r
+ TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
+ }\r
break;\r
default:\r
break;\r
}\r
\r
- ASSERT_EFI_ERROR (Status);\r
+ //\r
+ // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.\r
+ //\r
+ HiiToLower (StringHeader);\r
StrCat (Str, L"&");\r
\r
*SubStr = Str;\r
/**\r
Retrieve the <ConfigBody> from String then output it.\r
\r
+ This is a internal function.\r
+\r
@param String A sub string of a configuration string in\r
<MultiConfigAltResp> format.\r
@param ConfigBody Points to the output string. It's caller's\r
@retval EFI_SUCCESS All existing storage is exported.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
OutputConfigBody (\r
IN EFI_STRING String,\r
\r
}\r
\r
-\r
-#endif\r
-\r
-VOID *\r
-ReallocatePool (\r
- IN VOID *OldPool,\r
- IN UINTN OldSize,\r
- IN UINTN NewSize\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Adjusts the size of a previously allocated buffer.\r
-\r
-Arguments:\r
- OldPool - A pointer to the buffer whose size is being adjusted.\r
- OldSize - The size of the current buffer.\r
- NewSize - The size of the new buffer.\r
-\r
-Returns:\r
- Points to the new buffer\r
-\r
---*/\r
-{\r
- VOID *NewPool;\r
-\r
- NewPool = NULL;\r
- if (NewSize) {\r
- NewPool = AllocateZeroPool (NewSize);\r
- }\r
-\r
- if (OldPool) {\r
- if (NewPool) {\r
- CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);\r
- }\r
-\r
- gBS->FreePool (OldPool);\r
- }\r
-\r
- return NewPool;\r
-}\r
-\r
-\r
/**\r
Append a string to a multi-string format.\r
\r
+ This is a internal function.\r
+\r
@param MultiString String in <MultiConfigRequest>,\r
<MultiConfigAltResp>, or <MultiConfigResp>. On\r
input, the buffer length of this string is\r
@retval EFI_SUCCESS AppendString is append to the end of MultiString\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
AppendToMultiString (\r
IN OUT EFI_STRING *MultiString,\r
if (MultiStringSize + AppendStringSize > MAX_STRING_LENGTH ||\r
MultiStringSize > MAX_STRING_LENGTH) {\r
*MultiString = (EFI_STRING) ReallocatePool (\r
- (VOID *) (*MultiString),\r
MultiStringSize,\r
- MultiStringSize + AppendStringSize\r
+ MultiStringSize + AppendStringSize,\r
+ (VOID *) (*MultiString)\r
);\r
+ ASSERT (*MultiString != NULL);\r
}\r
-\r
//\r
// Append the incoming string\r
//\r
or WIDTH or VALUE.\r
<BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>\r
\r
+ This is a internal function.\r
+\r
@param StringPtr String in <BlockConfig> format and points to the\r
first character of <Number>.\r
@param Number The output value. Caller takes the responsibility\r
successfully.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
GetValueOfNumber (\r
IN EFI_STRING StringPtr,\r
EFI_STRING Str;\r
UINT8 *Buf;\r
EFI_STATUS Status;\r
+ UINT8 DigitUint8;\r
+ UINTN Index;\r
+ CHAR16 TemStr[2];\r
\r
ASSERT (StringPtr != NULL && Number != NULL && Len != NULL);\r
- ASSERT (*StringPtr != 0);\r
+ ASSERT (*StringPtr != L'\0');\r
\r
Buf = NULL;\r
\r
TmpPtr = StringPtr;\r
- while (*StringPtr != 0 && *StringPtr != L'&') {\r
+ while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
StringPtr++;\r
}\r
*Len = StringPtr - TmpPtr;\r
goto Exit;\r
}\r
CopyMem (Str, TmpPtr, *Len * sizeof (CHAR16));\r
- *(Str + *Len) = 0;\r
+ *(Str + *Len) = L'\0';\r
\r
Length = (Length + 1) / 2;\r
Buf = (UINT8 *) AllocateZeroPool (Length);\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Exit;\r
}\r
-\r
- Status = HexStringToBuf (Buf, &Length, Str, NULL);\r
- if (EFI_ERROR (Status)) {\r
- goto Exit;\r
+ \r
+ Length = *Len;\r
+ ZeroMem (TemStr, sizeof (TemStr));\r
+ for (Index = 0; Index < Length; Index ++) {\r
+ TemStr[0] = Str[Length - Index - 1];\r
+ DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
+ if ((Index & 1) == 0) {\r
+ Buf [Index/2] = DigitUint8;\r
+ } else {\r
+ Buf [Index/2] = (UINT8) ((DigitUint8 << 4) + Buf [Index/2]);\r
+ }\r
}\r
\r
*Number = Buf;\r
Status = EFI_SUCCESS;\r
\r
Exit:\r
- SafeFreePool (Str);\r
+ if (Str != NULL) {\r
+ FreePool (Str);\r
+ }\r
+\r
return Status;\r
}\r
\r
OUT EFI_STRING *Results\r
)\r
{\r
-#ifndef DISABLE_UNUSED_HII_PROTOCOLS\r
-\r
HII_DATABASE_PRIVATE_DATA *Private;\r
EFI_STRING StringPtr;\r
EFI_STRING ConfigRequest;\r
EFI_STATUS Status;\r
LIST_ENTRY *Link;\r
HII_DATABASE_RECORD *Database;\r
+ UINT8 *DevicePathPkg;\r
UINT8 *CurrentDevicePath;\r
EFI_HANDLE DriverHandle;\r
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
EFI_STRING AccessProgress;\r
EFI_STRING AccessResults;\r
- UINTN RemainSize;\r
- EFI_STRING TmpPtr;\r
+ BOOLEAN FirstElement;\r
\r
if (This == NULL || Progress == NULL || Results == NULL) {\r
return EFI_INVALID_PARAMETER;\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ FirstElement = TRUE;\r
+\r
//\r
// Allocate a fix length of memory to store Results. Reallocate memory for\r
// Results if this fix length is insufficient.\r
//\r
Status = GetDevicePath (ConfigRequest, (UINT8 **) &DevicePath);\r
if (EFI_ERROR (Status)) {\r
- SafeFreePool (ConfigRequest);\r
+ FreePool (ConfigRequest);\r
return Status;\r
}\r
\r
Link = Link->ForwardLink\r
) {\r
Database = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
- CurrentDevicePath = Database->PackageList->DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
- if (CurrentDevicePath != NULL) {\r
+ \r
+ if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {\r
+ CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
if (CompareMem (\r
DevicePath,\r
CurrentDevicePath,\r
}\r
}\r
\r
- SafeFreePool (DevicePath);\r
+ FreePool (DevicePath);\r
\r
if (DriverHandle == NULL) {\r
//\r
// Set Progress to the 'G' in "GUID" of the routing header.\r
//\r
*Progress = StringPtr;\r
- SafeFreePool (ConfigRequest);\r
+ FreePool (ConfigRequest);\r
return EFI_NOT_FOUND;\r
}\r
\r
// AccessProgress indicates the parsing progress on <ConfigRequest>.\r
// Map it to the progress on <MultiConfigRequest> then return it.\r
//\r
- RemainSize = StrSize (AccessProgress);\r
- for (TmpPtr = StringPtr; CompareMem (TmpPtr, AccessProgress, RemainSize) != 0; TmpPtr++);\r
- *Progress = TmpPtr;\r
-\r
- SafeFreePool (ConfigRequest);\r
+ *Progress = StrStr (StringPtr, AccessProgress);\r
+ FreePool (ConfigRequest);\r
return Status;\r
}\r
\r
//\r
- // Attach this <ConfigAltResp> to a <MultiConfigAltResp>\r
+ // Attach this <ConfigAltResp> to a <MultiConfigAltResp>. There is a '&'\r
+ // which seperates the first <ConfigAltResp> and the following ones.\r
//\r
ASSERT (*AccessProgress == 0);\r
+\r
+ if (!FirstElement) {\r
+ Status = AppendToMultiString (Results, L"&");\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ \r
Status = AppendToMultiString (Results, AccessResults);\r
ASSERT_EFI_ERROR (Status);\r
- SafeFreePool (AccessResults);\r
+\r
+ FirstElement = FALSE;\r
+ \r
+ FreePool (AccessResults);\r
AccessResults = NULL;\r
- SafeFreePool (ConfigRequest);\r
+ FreePool (ConfigRequest);\r
ConfigRequest = NULL;\r
\r
//\r
}\r
\r
return EFI_SUCCESS;\r
-#else\r
- return EFI_UNSUPPORTED;\r
-#endif\r
\r
}\r
\r
OUT EFI_STRING *Results\r
)\r
{\r
-#ifndef DISABLE_UNUSED_HII_PROTOCOLS\r
-\r
EFI_STATUS Status;\r
- HII_DATABASE_PRIVATE_DATA *Private;\r
- LIST_ENTRY StorageListHdr;\r
- HII_FORMSET_STORAGE *Storage;\r
- LIST_ENTRY *Link;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
- UINTN Length;\r
- EFI_STRING PathHdr;\r
- UINTN PathHdrSize;\r
- EFI_STRING ConfigRequest;\r
- UINTN RequestSize;\r
- EFI_STRING StringPtr;\r
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
- EFI_STRING AccessProgress;\r
- EFI_STRING AccessResults;\r
- UINTN TmpSize;\r
+ EFI_STRING AccessResults; \r
+ UINTN Index;\r
+ EFI_HANDLE *ConfigAccessHandles;\r
+ UINTN NumberConfigAccessHandles;\r
+ BOOLEAN FirstElement;\r
\r
if (This == NULL || Results == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- InitializeListHead (&StorageListHdr);\r
-\r
- Status = ExportAllStorage (&Private->HiiDatabase, &StorageListHdr);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
//\r
// Allocate a fix length of memory to store Results. Reallocate memory for\r
// Results if this fix length is insufficient.\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- //\r
- // Parsing all formset storages.\r
- //\r
- for (Link = StorageListHdr.ForwardLink; Link != &StorageListHdr; Link = Link->ForwardLink) {\r
- Storage = CR (Link, HII_FORMSET_STORAGE, Entry, HII_FORMSET_STORAGE_SIGNATURE);\r
- //\r
- // Find the corresponding device path instance\r
- //\r
- Status = gBS->HandleProtocol (\r
- Storage->DriverHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **) &DevicePath\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Convert the device path binary to hex UNICODE %02x bytes in the same order\r
- // as the device path resides in RAM memory.\r
- //\r
- Length = GetDevicePathSize (DevicePath);\r
- PathHdrSize = (Length * 2 + 1) * sizeof (CHAR16);\r
- PathHdr = (EFI_STRING) AllocateZeroPool (PathHdrSize);\r
- if (PathHdr == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- Status = BufferToHexString (PathHdr, (UINT8 *) DevicePath, Length);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Generate a <ConfigRequest> with one <ConfigHdr> and zero <RequestElement>.\r
- // It means extract all possible configurations from this specific driver.\r
- //\r
- TmpSize = StrLen (L"GUID=&NAME=&PATH=");\r
- RequestSize = (TmpSize + 32 + StrLen (Storage->Name) * 4)\r
- * sizeof (CHAR16) + PathHdrSize;\r
- ConfigRequest = (EFI_STRING) AllocateZeroPool (RequestSize);\r
- if (ConfigRequest == NULL) {\r
- SafeFreePool (PathHdr);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Add <GuidHdr>\r
- // <GuidHdr> ::= 'GUID='<Guid>\r
- // Convert <Guid> in the same order as it resides in RAM memory.\r
- //\r
- StringPtr = ConfigRequest;\r
- StrnCpy (StringPtr, L"GUID=", StrLen (L"GUID="));\r
- StringPtr += StrLen (L"GUID=");\r
-\r
- Status = BufferToHexString (StringPtr, (UINT8 *) (&Storage->Guid), sizeof (EFI_GUID));\r
- ASSERT_EFI_ERROR (Status);\r
- \r
- StringPtr += 32;\r
- ASSERT (*StringPtr == 0);\r
- *StringPtr = L'&';\r
- StringPtr++;\r
-\r
- //\r
- // Add <NameHdr>\r
- // <NameHdr> ::= 'NAME='<String>\r
- //\r
- StrnCpy (StringPtr, L"NAME=", StrLen (L"NAME="));\r
- StringPtr += StrLen (L"NAME=");\r
-\r
- Length = (StrLen (Storage->Name) * 4 + 1) * sizeof (CHAR16);\r
- Status = UnicodeToConfigString (StringPtr, &Length, Storage->Name);\r
- ASSERT_EFI_ERROR (Status);\r
- StringPtr += StrLen (Storage->Name) * 4;\r
- \r
- *StringPtr = L'&';\r
- StringPtr++;\r
-\r
- //\r
- // Add <PathHdr>\r
- // <PathHdr> ::= '<PATH=>'<UEFI binary represented as hex UNICODE %02x>\r
- //\r
- StrnCpy (StringPtr, L"PATH=", StrLen (L"PATH="));\r
- StringPtr += StrLen (L"PATH=");\r
- StrCpy (StringPtr, PathHdr);\r
-\r
- SafeFreePool (PathHdr);\r
- PathHdr = NULL;\r
+ NumberConfigAccessHandles = 0;\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiHiiConfigAccessProtocolGuid,\r
+ NULL,\r
+ &NumberConfigAccessHandles,\r
+ &ConfigAccessHandles\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
\r
- //\r
- // BUGBUG: The "Implementation note" of ExportConfig() in UEFI spec makes the\r
- // code somewhat complex. Let's TBD here whether a <ConfigRequest> or a <ConfigHdr>\r
- // is required to call ConfigAccess.ExtractConfig().\r
- //\r
- // Here we use <ConfigHdr> to call ConfigAccess instance. It requires ConfigAccess\r
- // to handle such kind of "ConfigRequest". It is not supported till now.\r
- //\r
- // Either the ExportConfig will be updated or the ConfigAccess.ExtractConfig()\r
- // will be updated as soon as the decision is made.\r
+ FirstElement = TRUE;\r
\r
- //\r
- // Route the request to corresponding ConfigAccess protocol to extract settings.\r
- //\r
+ for (Index = 0; Index < NumberConfigAccessHandles; Index++) {\r
Status = gBS->HandleProtocol (\r
- Storage->DriverHandle,\r
+ ConfigAccessHandles[Index],\r
&gEfiHiiConfigAccessProtocolGuid,\r
- (VOID **) &ConfigAccess\r
+ (VOID **) &ConfigAccess\r
);\r
- ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
\r
Status = ConfigAccess->ExtractConfig (\r
ConfigAccess,\r
- ConfigRequest,\r
- &AccessProgress,\r
+ NULL,\r
+ NULL,\r
&AccessResults\r
);\r
- if (EFI_ERROR (Status)) {\r
- SafeFreePool (ConfigRequest);\r
- SafeFreePool (AccessResults);\r
- return EFI_INVALID_PARAMETER;\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Attach this <ConfigAltResp> to a <MultiConfigAltResp>. There is a '&'\r
+ // which seperates the first <ConfigAltResp> and the following ones. \r
+ //\r
+ if (!FirstElement) {\r
+ Status = AppendToMultiString (Results, L"&");\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ \r
+ Status = AppendToMultiString (Results, AccessResults);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ FirstElement = FALSE;\r
+ \r
+ FreePool (AccessResults);\r
+ AccessResults = NULL;\r
}\r
-\r
- //\r
- // Attach this <ConfigAltResp> to a <MultiConfigAltResp>\r
- //\r
- ASSERT (*AccessProgress == 0);\r
- Status = AppendToMultiString (Results, AccessResults);\r
- ASSERT_EFI_ERROR (Status);\r
- SafeFreePool (AccessResults);\r
- AccessResults = NULL;\r
- SafeFreePool (ConfigRequest);\r
- ConfigRequest = NULL;\r
-\r
}\r
+ FreePool (ConfigAccessHandles);\r
\r
- //\r
- // Free the exported storage resource\r
- //\r
- while (!IsListEmpty (&StorageListHdr)) {\r
- Storage = CR (\r
- StorageListHdr.ForwardLink,\r
- HII_FORMSET_STORAGE,\r
- Entry,\r
- HII_FORMSET_STORAGE_SIGNATURE\r
- );\r
- RemoveEntryList (&Storage->Entry);\r
- SafeFreePool (Storage->Name);\r
- SafeFreePool (Storage);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-#else\r
- return EFI_UNSUPPORTED;\r
-#endif\r
+ return EFI_SUCCESS; \r
}\r
\r
\r
OUT EFI_STRING *Progress\r
)\r
{\r
-#ifndef DISABLE_UNUSED_HII_PROTOCOLS\r
-\r
HII_DATABASE_PRIVATE_DATA *Private;\r
EFI_STRING StringPtr;\r
EFI_STRING ConfigResp;\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
LIST_ENTRY *Link;\r
HII_DATABASE_RECORD *Database;\r
+ UINT8 *DevicePathPkg;\r
UINT8 *CurrentDevicePath;\r
EFI_HANDLE DriverHandle;\r
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
EFI_STRING AccessProgress;\r
- UINTN RemainSize;\r
- EFI_STRING TmpPtr;\r
\r
if (This == NULL || Progress == NULL) {\r
return EFI_INVALID_PARAMETER;\r
//\r
Status = GetDevicePath (ConfigResp, (UINT8 **) &DevicePath);\r
if (EFI_ERROR (Status)) {\r
- SafeFreePool (ConfigResp);\r
+ FreePool (ConfigResp);\r
return Status;\r
}\r
\r
Link = Link->ForwardLink\r
) {\r
Database = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
- CurrentDevicePath = Database->PackageList->DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
- if (CurrentDevicePath != NULL) {\r
+\r
+ if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {\r
+ CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
if (CompareMem (\r
DevicePath,\r
CurrentDevicePath,\r
}\r
}\r
\r
- SafeFreePool (DevicePath);\r
+ FreePool (DevicePath);\r
\r
if (DriverHandle == NULL) {\r
//\r
// Set Progress to the 'G' in "GUID" of the routing header.\r
//\r
*Progress = StringPtr;\r
- SafeFreePool (ConfigResp);\r
+ FreePool (ConfigResp);\r
return EFI_NOT_FOUND;\r
}\r
\r
// AccessProgress indicates the parsing progress on <ConfigResp>.\r
// Map it to the progress on <MultiConfigResp> then return it.\r
//\r
- RemainSize = StrSize (AccessProgress);\r
- for (TmpPtr = StringPtr; CompareMem (TmpPtr, AccessProgress, RemainSize) != 0; TmpPtr++);\r
- *Progress = TmpPtr;\r
+ *Progress = StrStr (StringPtr, AccessProgress);\r
\r
- SafeFreePool (ConfigResp);\r
+ FreePool (ConfigResp);\r
return Status;\r
}\r
\r
- SafeFreePool (ConfigResp);\r
+ FreePool (ConfigResp);\r
ConfigResp = NULL;\r
\r
//\r
}\r
\r
return EFI_SUCCESS;\r
-#else\r
- return EFI_UNSUPPORTED;\r
-#endif\r
}\r
\r
\r
UINT8 *Value;\r
EFI_STRING ValueStr;\r
EFI_STRING ConfigElement;\r
+ UINTN Index;\r
+ UINT8 *TemBuffer;\r
+ CHAR16 *TemString;\r
\r
if (This == NULL || Progress == NULL || Config == NULL) {\r
return EFI_INVALID_PARAMETER;\r
Status = EFI_INVALID_PARAMETER;\r
goto Exit;\r
}\r
- while (*StringPtr++ != L'&');\r
+\r
+ while (*StringPtr != L'&' && *StringPtr != 0) {\r
+ StringPtr++;\r
+ }\r
+ if (*StringPtr == 0) {\r
+ *Progress = StringPtr;\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Exit;\r
+ }\r
+ //\r
+ // Skip '&'\r
+ //\r
+ StringPtr++;\r
\r
//\r
// Copy <ConfigHdr> and an additional '&' to <ConfigResp>\r
TmpBuffer,\r
(((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)\r
);\r
- SafeFreePool (TmpBuffer);\r
+ FreePool (TmpBuffer);\r
\r
StringPtr += Length;\r
if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
TmpBuffer,\r
(((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)\r
);\r
- SafeFreePool (TmpBuffer);\r
+ FreePool (TmpBuffer);\r
\r
StringPtr += Length;\r
if (*StringPtr != 0 && *StringPtr != L'&') {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Exit;\r
}\r
+ \r
+ TemString = ValueStr;\r
+ TemBuffer = Value + Width - 1;\r
+ for (Index = 0; Index < Width; Index ++, TemBuffer --) {\r
+ TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
+ }\r
+ HiiToLower (ValueStr);\r
\r
- Status = BufToHexString (ValueStr, &Length, Value, Width);\r
- ASSERT_EFI_ERROR (Status);\r
- ToLower (ValueStr);\r
-\r
- SafeFreePool (Value);\r
+ FreePool (Value);\r
Value = NULL;\r
\r
//\r
\r
AppendToMultiString (Config, ConfigElement);\r
\r
- SafeFreePool (ConfigElement);\r
- SafeFreePool (ValueStr);\r
+ FreePool (ConfigElement);\r
+ FreePool (ValueStr);\r
ConfigElement = NULL;\r
ValueStr = NULL;\r
\r
return EFI_SUCCESS;\r
\r
Exit:\r
-\r
- SafeFreePool (*Config);\r
- SafeFreePool (ValueStr);\r
- SafeFreePool (Value);\r
- SafeFreePool (ConfigElement);\r
+ FreePool (*Config);\r
+ if (ValueStr != NULL) {\r
+ FreePool (ValueStr);\r
+ }\r
+ if (Value != NULL) {\r
+ FreePool (Value);\r
+ }\r
+ if (ConfigElement != NULL) {\r
+ FreePool (ConfigElement);\r
+ }\r
\r
return Status;\r
\r
Status = EFI_INVALID_PARAMETER;\r
goto Exit;\r
}\r
- while (*StringPtr++ != L'&');\r
+\r
+ while (*StringPtr != L'&' && *StringPtr != 0) {\r
+ StringPtr++;\r
+ }\r
+ if (*StringPtr == 0) {\r
+ *Progress = StringPtr;\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Exit;\r
+ }\r
+ //\r
+ // Skip '&'\r
+ //\r
+ StringPtr++;\r
\r
//\r
// Parse each <ConfigElement> if exists\r
// Get Offset\r
//\r
Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
- if (Status == EFI_OUT_OF_RESOURCES) {\r
+ if (EFI_ERROR (Status)) {\r
*Progress = ConfigResp;\r
goto Exit;\r
}\r
TmpBuffer,\r
(((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)\r
);\r
- SafeFreePool (TmpBuffer);\r
+ FreePool (TmpBuffer);\r
\r
StringPtr += Length;\r
if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
TmpBuffer,\r
(((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)\r
);\r
- SafeFreePool (TmpBuffer);\r
+ FreePool (TmpBuffer);\r
\r
StringPtr += Length;\r
if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) {\r
// Get Value\r
//\r
Status = GetValueOfNumber (StringPtr, &Value, &Length);\r
- if (Status == EFI_OUT_OF_RESOURCES) {\r
+ if (EFI_ERROR (Status)) {\r
*Progress = ConfigResp;\r
goto Exit;\r
}\r
CopyMem (Block + Offset, Value, Width);\r
*BlockSize = Offset + Width - 1;\r
\r
- SafeFreePool (Value);\r
+ FreePool (Value);\r
Value = NULL;\r
\r
//\r
\r
Exit:\r
\r
- SafeFreePool (Value);\r
+ if (Value != NULL) {\r
+ FreePool (Value);\r
+ }\r
return Status;\r
}\r
\r
OUT EFI_STRING *AltCfgResp\r
)\r
{\r
-#ifndef DISABLE_UNUSED_HII_PROTOCOLS\r
-\r
EFI_STATUS Status;\r
EFI_STRING StringPtr;\r
- EFI_STRING HdrStart = NULL;\r
- EFI_STRING HdrEnd = NULL;\r
+ EFI_STRING HdrStart;\r
+ EFI_STRING HdrEnd;\r
EFI_STRING TmpPtr;\r
UINTN Length;\r
- EFI_STRING GuidStr = NULL;\r
- EFI_STRING NameStr = NULL;\r
- EFI_STRING PathStr = NULL;\r
- EFI_STRING AltIdStr = NULL;\r
- EFI_STRING Result = NULL;\r
- BOOLEAN GuidFlag = FALSE;\r
- BOOLEAN NameFlag = FALSE;\r
- BOOLEAN PathFlag = FALSE;\r
+ EFI_STRING GuidStr;\r
+ EFI_STRING NameStr;\r
+ EFI_STRING PathStr;\r
+ EFI_STRING AltIdStr;\r
+ EFI_STRING Result;\r
+ BOOLEAN GuidFlag;\r
+ BOOLEAN NameFlag;\r
+ BOOLEAN PathFlag;\r
+\r
+ HdrStart = NULL;\r
+ HdrEnd = NULL;\r
+ GuidStr = NULL;\r
+ NameStr = NULL;\r
+ PathStr = NULL;\r
+ AltIdStr = NULL;\r
+ Result = NULL;\r
+ GuidFlag = FALSE;\r
+ NameFlag = FALSE;\r
+ PathFlag = FALSE;\r
\r
if (This == NULL || Configuration == NULL || AltCfgResp == NULL) {\r
return EFI_INVALID_PARAMETER;\r
\r
Exit:\r
\r
- if (!EFI_ERROR (Status)) {\r
+ if (!EFI_ERROR (Status) && (Result != NULL)) {\r
//\r
// Copy the <ConfigHdr> and <ConfigBody>\r
//\r
}\r
}\r
\r
- SafeFreePool (GuidStr);\r
- SafeFreePool (NameStr);\r
- SafeFreePool (PathStr);\r
- SafeFreePool (AltIdStr);\r
- SafeFreePool (Result);\r
+ if (GuidStr != NULL) {\r
+ FreePool (GuidStr);\r
+ }\r
+ if (NameStr != NULL) {\r
+ FreePool (NameStr);\r
+ }\r
+ if (PathStr != NULL) {\r
+ FreePool (PathStr);\r
+ }\r
+ if (AltIdStr != NULL) {\r
+ FreePool (AltIdStr);\r
+ }\r
+ if (Result != NULL) {\r
+ FreePool (Result);\r
+ }\r
\r
return Status;\r
\r
-#else\r
- return EFI_UNSUPPORTED;\r
-#endif\r
-\r
}\r
\r
\r