}\r
\r
\r
-/**\r
- Extract Storage from all Form Packages in current hii database.\r
-\r
- This is a internal function.\r
-\r
- @param HiiDatabase EFI_HII_DATABASE_PROTOCOL instance.\r
- @param StorageListHead Storage link List head.\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
-\r
-**/\r
-EFI_STATUS\r
-ExportAllStorage (\r
- IN EFI_HII_DATABASE_PROTOCOL *HiiDatabase,\r
- IN OUT LIST_ENTRY *StorageListHead\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
- if (HandleBuffer != NULL) {\r
- FreePool (HandleBuffer);\r
- }\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
- }\r
- if (EFI_ERROR (Status)) {\r
- FreePool (HandleBuffer);\r
- FreePool (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
- FreePool (HandleBuffer);\r
- FreePool (HiiPackageList);\r
- FreePool (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
- FreePool (HiiPackageList);\r
- }\r
-\r
- FreePool (HandleBuffer);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
/**\r
Generate a sub string then output it.\r
\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
//\r
// For size reduction, please define PcdSupportFullConfigRoutingProtocol \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
// 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
+ *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
+\r
+ FirstElement = FALSE;\r
+ \r
FreePool (AccessResults);\r
AccessResults = NULL;\r
FreePool (ConfigRequest);\r
)\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
+ EFI_STRING AccessResults; \r
+ UINTN Index;\r
+ EFI_HANDLE *ConfigAccessHandles;\r
+ UINTN NumberConfigAccessHandles;\r
+ BOOLEAN FirstElement;\r
\r
//\r
// For size reduction, please define PcdSupportFullConfigRoutingProtocol \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 = BufInReverseOrderToHexString (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
- RequestSize = (StrLen (L"GUID=&NAME=&PATH=") + 32) * sizeof (CHAR16) + PathHdrSize;\r
- if (Storage->Name != NULL) {\r
- RequestSize += StrLen (Storage->Name) * 4 * sizeof (CHAR16);\r
- }\r
- \r
- ConfigRequest = (EFI_STRING) AllocateZeroPool (RequestSize);\r
- if (ConfigRequest == NULL) {\r
- FreePool (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 = BufInReverseOrderToHexString (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
- if (Storage->Name != NULL) {\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
- \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
- FreePool (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
- AccessProgress = NULL;\r
- AccessResults = NULL;\r
Status = ConfigAccess->ExtractConfig (\r
ConfigAccess,\r
- ConfigRequest,\r
- &AccessProgress,\r
+ NULL,\r
+ NULL,\r
&AccessResults\r
);\r
- if (EFI_ERROR (Status)) {\r
- FreePool (ConfigRequest);\r
- if (AccessProgress != NULL) {\r
- FreePool (AccessProgress);\r
- }\r
- if (AccessResults != NULL) {\r
- FreePool (AccessResults);\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
- return EFI_INVALID_PARAMETER;\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
- FreePool (AccessResults);\r
- AccessResults = NULL;\r
- FreePool (ConfigRequest);\r
- ConfigRequest = NULL;\r
-\r
- }\r
+ \r
+ Status = AppendToMultiString (Results, AccessResults);\r
+ ASSERT_EFI_ERROR (Status);\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
- FreePool (Storage->Name);\r
- FreePool (Storage);\r
+ FirstElement = FALSE;\r
+ \r
+ FreePool (AccessResults);\r
+ AccessResults = NULL;\r
+ }\r
}\r
+ gBS->FreePool (ConfigAccessHandles);\r
\r
- return EFI_SUCCESS;\r
+ return EFI_SUCCESS; \r
}\r
\r
\r
EFI_HANDLE DriverHandle;\r
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
EFI_STRING AccessProgress;\r
- UINTN RemainSize;\r
- EFI_STRING TmpPtr;\r
\r
//\r
// For size reduction, please define PcdSupportFullConfigRoutingProtocol \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
FreePool (ConfigResp);\r
return Status;\r