]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
Sync in bug fix from EDK I:
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / ConfigRouting.c
index aed93be1f03f7e2c0db37f5e9025d5d9aee27c76..ca85619113d8648029745e494bf53afcb9fbcd33 100644 (file)
@@ -140,182 +140,6 @@ GetDevicePath (
 }\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
@@ -674,8 +498,7 @@ HiiConfigRoutingExtractConfig (
   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
@@ -707,6 +530,8 @@ HiiConfigRoutingExtractConfig (
     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
@@ -802,20 +627,27 @@ HiiConfigRoutingExtractConfig (
       // 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
@@ -869,20 +701,12 @@ HiiConfigRoutingExportConfig (
   )\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
@@ -897,15 +721,6 @@ HiiConfigRoutingExportConfig (
     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
@@ -915,164 +730,58 @@ HiiConfigRoutingExportConfig (
     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
@@ -1122,8 +831,6 @@ HiiConfigRoutingRouteConfig (
   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
@@ -1244,9 +951,7 @@ HiiConfigRoutingRouteConfig (
       // 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