/** @file\r
+Implementation of interfaces function for EFI_HII_CONFIG_ROUTING_PROTOCOL.\r
\r
-Copyright (c) 2007 - 2008, Intel Corporation\r
+Copyright (c) 2007 - 2009, Intel Corporation\r
All rights reserved. This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\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
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
+ DevicePathBuffer = (UINT8 *) AllocateZeroPool ((Length + 1) / 2);\r
+ if (DevicePathBuffer == NULL) {\r
FreePool (DevicePathString);\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- HexStringToBufInReverseOrder (*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
FreePool (DevicePathString);\r
+ \r
+ *DevicePath = DevicePathBuffer;\r
\r
return EFI_SUCCESS;\r
\r
}\r
\r
+/**\r
+ Converts the unicode character of the string from uppercase to lowercase.\r
+ This is a internal function.\r
+\r
+ @param Str String to be converted\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+HiiToLower (\r
+ IN OUT CHAR16 *Str\r
+ )\r
+{\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
+ }\r
+}\r
\r
/**\r
Generate a sub string then output it.\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 = BufInReverseOrderToHexString (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
}\r
\r
-\r
-/**\r
- Adjusts the size of a previously allocated buffer.\r
-\r
-\r
- @param OldPool A pointer to the buffer whose size is being adjusted.\r
- @param OldSize The size of the current buffer.\r
- @param NewSize The size of the new buffer.\r
-\r
- @return The new buffer allocated.\r
-\r
-**/\r
-VOID *\r
-ReallocatePool (\r
- IN VOID *OldPool,\r
- IN UINTN OldSize,\r
- IN UINTN NewSize\r
- )\r
-{\r
- VOID *NewPool;\r
-\r
- NewPool = NULL;\r
- if (NewSize != 0) {\r
- NewPool = AllocateZeroPool (NewSize);\r
- }\r
-\r
- if (OldPool != NULL) {\r
- if (NewPool != NULL) {\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
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
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
if (Str != NULL) {\r
FreePool (Str);\r
}\r
+\r
return Status;\r
}\r
\r
OUT EFI_STRING *Results\r
)\r
{\r
- HII_DATABASE_PRIVATE_DATA *Private;\r
EFI_STRING StringPtr;\r
EFI_STRING ConfigRequest;\r
UINTN Length;\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\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
BOOLEAN FirstElement;\r
\r
- //\r
- // For size reduction, please define PcdSupportFullConfigRoutingProtocol \r
- // as FALSE. But this renders the system to not 100% compliant with\r
- // UEFI 2.1. Use this with caution.\r
- //\r
- if (!FeaturePcdGet (PcdSupportFullConfigRoutingProtocol)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
if (This == NULL || Progress == NULL || Results == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
StringPtr = Request;\r
*Progress = StringPtr;\r
\r
}\r
\r
//\r
- // Find driver which matches the routing data.\r
+ // Find driver handle by device path\r
//\r
DriverHandle = NULL;\r
- for (Link = Private->DatabaseList.ForwardLink;\r
- Link != &Private->DatabaseList;\r
- Link = Link->ForwardLink\r
- ) {\r
- Database = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
- \r
- if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {\r
- CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
- if (CompareMem (\r
- DevicePath,\r
- CurrentDevicePath,\r
- GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath)\r
- ) == 0) {\r
- DriverHandle = Database->DriverHandle;\r
- break;\r
- }\r
- }\r
- }\r
-\r
+ TempDevicePath = DevicePath;\r
+ Status = gBS->LocateDevicePath (\r
+ &gEfiDevicePathProtocolGuid,\r
+ &TempDevicePath,\r
+ &DriverHandle\r
+ );\r
FreePool (DevicePath);\r
\r
- if (DriverHandle == NULL) {\r
+ if (EFI_ERROR (Status) || (DriverHandle == NULL)) {\r
//\r
- // Routing data does not match any known driver.\r
+ // Cannot find any known driver.\r
// Set Progress to the 'G' in "GUID" of the routing header.\r
//\r
*Progress = StringPtr;\r
UINTN NumberConfigAccessHandles;\r
BOOLEAN FirstElement;\r
\r
- //\r
- // For size reduction, please define PcdSupportFullConfigRoutingProtocol \r
- // as FALSE. But this renders the system to not 100% compliant with\r
- // UEFI 2.1. Use this with caution.\r
- //\r
- if (!FeaturePcdGet (PcdSupportFullConfigRoutingProtocol)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
if (This == NULL || Results == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
AccessResults = NULL;\r
}\r
}\r
- gBS->FreePool (ConfigAccessHandles);\r
+ FreePool (ConfigAccessHandles);\r
\r
return EFI_SUCCESS; \r
}\r
OUT EFI_STRING *Progress\r
)\r
{\r
- HII_DATABASE_PRIVATE_DATA *Private;\r
EFI_STRING StringPtr;\r
EFI_STRING ConfigResp;\r
UINTN Length;\r
EFI_STATUS Status;\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
- LIST_ENTRY *Link;\r
- HII_DATABASE_RECORD *Database;\r
- UINT8 *DevicePathPkg;\r
- UINT8 *CurrentDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
EFI_HANDLE DriverHandle;\r
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
EFI_STRING AccessProgress;\r
\r
- //\r
- // For size reduction, please define PcdSupportFullConfigRoutingProtocol \r
- // as FALSE. But this renders the system to not 100% compliant with\r
- // UEFI 2.1. Use this with caution.\r
- //\r
- if (!FeaturePcdGet (PcdSupportFullConfigRoutingProtocol)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
if (This == NULL || Progress == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
StringPtr = Configuration;\r
*Progress = StringPtr;\r
\r
}\r
\r
//\r
- // Find driver which matches the routing data.\r
+ // Find driver handle by device path\r
//\r
DriverHandle = NULL;\r
- for (Link = Private->DatabaseList.ForwardLink;\r
- Link != &Private->DatabaseList;\r
- Link = Link->ForwardLink\r
- ) {\r
- Database = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
-\r
- if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {\r
- CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
- if (CompareMem (\r
- DevicePath,\r
- CurrentDevicePath,\r
- GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath)\r
- ) == 0) {\r
- DriverHandle = Database->DriverHandle;\r
- break;\r
- }\r
- }\r
- }\r
-\r
+ TempDevicePath = DevicePath;\r
+ Status = gBS->LocateDevicePath (\r
+ &gEfiDevicePathProtocolGuid,\r
+ &TempDevicePath,\r
+ &DriverHandle\r
+ );\r
FreePool (DevicePath);\r
\r
- if (DriverHandle == NULL) {\r
+ if (EFI_ERROR (Status) || (DriverHandle == NULL)) {\r
//\r
- // Routing data does not match any known driver.\r
+ // Cannot find any known driver.\r
// Set Progress to the 'G' in "GUID" of the routing header.\r
//\r
*Progress = StringPtr;\r
OUT EFI_STRING *Progress\r
)\r
{\r
- HII_DATABASE_PRIVATE_DATA *Private;\r
EFI_STRING StringPtr;\r
UINTN Length;\r
EFI_STATUS Status;\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
return EFI_INVALID_PARAMETER;\r
}\r
\r
-\r
- Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
- ASSERT (Private != NULL);\r
-\r
StringPtr = ConfigRequest;\r
ValueStr = NULL;\r
Value = NULL;\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Exit;\r
}\r
-\r
- Status = BufToHexString (ValueStr, &Length, Value, Width);\r
- ASSERT_EFI_ERROR (Status);\r
- ToLower (ValueStr);\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
FreePool (Value);\r
Value = NULL;\r
if (Value != NULL) {\r
FreePool (Value);\r
}\r
- if (ConfigElement) {\r
+ if (ConfigElement != NULL) {\r
FreePool (ConfigElement);\r
}\r
\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
// 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
BOOLEAN NameFlag;\r
BOOLEAN PathFlag;\r
\r
- //\r
- // For size reduction, please define PcdSupportFullConfigRoutingProtocol \r
- // as FALSE. But this renders the system to not 100% compliant with\r
- // UEFI 2.1. Use this with caution.\r
- //\r
- if (!FeaturePcdGet (PcdSupportFullConfigRoutingProtocol)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
HdrStart = NULL;\r
HdrEnd = NULL;\r
GuidStr = NULL;\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