]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Foundation/Library/Dxe/UefiEfiIfrSupportLib/UefiIfrCommon.c
Sync all bug fixes between EDK1.04 and EDK1.06 into EdkCompatibilityPkg.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / UefiEfiIfrSupportLib / UefiIfrCommon.c
index 90afafe83721df7d5243e31d9264e77d458ffb21..c41a85c38da223264d0ef7621fbdfe05b86c0f80 100644 (file)
@@ -37,6 +37,7 @@ HII_VENDOR_DEVICE_PATH  mHiiVendorDevicePathTemplate = {
       },\r
       EFI_IFR_TIANO_GUID,\r
     },\r
+    0,\r
     0\r
   },\r
   {\r
@@ -181,22 +182,23 @@ Returns:
 {\r
   EFI_STATUS                   Status;\r
   HII_VENDOR_DEVICE_PATH_NODE  *VendorDevicePath;\r
-  UINT64                       MonotonicCount;\r
 \r
   VendorDevicePath = EfiLibAllocateCopyPool (sizeof (HII_VENDOR_DEVICE_PATH), &mHiiVendorDevicePathTemplate);\r
   if (VendorDevicePath == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  gBS->GetNextMonotonicCount (&MonotonicCount);\r
-  VendorDevicePath->MonotonicCount = (UINT32) MonotonicCount;\r
+  //\r
+  // Use memory address as unique ID to distinguish from different device paths\r
+  //\r
+  VendorDevicePath->UniqueId = (UINT64) ((UINTN) VendorDevicePath);\r
 \r
   *DriverHandle = NULL;\r
-  Status = gBS->InstallProtocolInterface (\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
                   DriverHandle,\r
                   &gEfiDevicePathProtocolGuid,\r
-                  EFI_NATIVE_INTERFACE,\r
-                  VendorDevicePath\r
+                  VendorDevicePath,\r
+                  NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
@@ -240,7 +242,7 @@ Returns:
                   &gEfiDevicePathProtocolGuid,\r
                   DevicePath\r
                   );\r
-\r
+  gBS->FreePool (DevicePath);\r
   return Status;\r
 }\r
 \r
@@ -511,6 +513,7 @@ Arguments:
 \r
 Returns:\r
   EFI_SUCCESS     - Successfully extract Class for specified Hii handle.\r
+  EFI_NOT_FOUND   - Class not found.\r
 \r
 --*/\r
 {\r
@@ -525,10 +528,12 @@ Returns:
   UINT32                       Offset2;\r
   UINT32                       PackageListLength;\r
   EFI_HII_PACKAGE_HEADER       PackageHeader;\r
+  BOOLEAN                      ClassFound;\r
 \r
   *Class = EFI_NON_DEVICE_CLASS;\r
   *FormSetTitle = 0;\r
   *FormSetHelp = 0;\r
+  ClassFound = FALSE;\r
 \r
   //\r
   // Locate HII Database protocol\r
@@ -574,7 +579,7 @@ Returns:
     Package = ((UINT8 *) HiiPackageList) + Offset;\r
     EfiCopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
 \r
-    if (PackageHeader.Type == EFI_HII_PACKAGE_FORM) {\r
+    if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
       //\r
       // Search Class Opcode in this Form Package\r
       //\r
@@ -602,6 +607,139 @@ Returns:
           //\r
           // Till now, we ought to have found the formset Opcode\r
           //\r
+          ClassFound = TRUE;\r
+          break;\r
+        }\r
+\r
+        Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
+      }\r
+\r
+      if (Offset2 < PackageHeader.Length) {\r
+        //\r
+        // Target formset found\r
+        //\r
+        break;\r
+      }\r
+    }\r
+\r
+    Offset += PackageHeader.Length;\r
+  }\r
+\r
+  gBS->FreePool (HiiPackageList);\r
+\r
+  return ClassFound ? EFI_SUCCESS : EFI_NOT_FOUND;\r
+}\r
+\r
+EFI_STATUS\r
+ExtractClassGuidFromHiiHandle (\r
+  IN      EFI_HII_HANDLE      Handle,\r
+  OUT     UINT8               *NumberOfClassGuid,\r
+  OUT     EFI_GUID            **ClassGuid,\r
+  OUT     EFI_STRING_ID       *FormSetTitle,\r
+  OUT     EFI_STRING_ID       *FormSetHelp\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Extract formset ClassGuid for given HII handle.\r
+\r
+Arguments:\r
+  HiiHandle         - Hii handle\r
+  NumberOfClassGuid - Number of ClassGuid\r
+  ClassGuid         - Pointer to callee allocated buffer, an array of ClassGuid\r
+  FormSetTitle      - Formset title string\r
+  FormSetHelp       - Formset help string\r
+\r
+Returns:\r
+  EFI_SUCCESS     - Successfully extract Class for specified Hii handle.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                   Status;\r
+  UINTN                        BufferSize;\r
+  EFI_HII_DATABASE_PROTOCOL    *HiiDatabase;\r
+  EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;\r
+  UINT8                        *Package;\r
+  UINT8                        *FormSet;\r
+  UINT8                        *OpCodeData;\r
+  UINT32                       Offset;\r
+  UINT32                       Offset2;\r
+  UINT32                       PackageListLength;\r
+  EFI_HII_PACKAGE_HEADER       PackageHeader;\r
+\r
+  if (NumberOfClassGuid == NULL || ClassGuid == NULL || FormSetTitle == NULL || FormSetHelp == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *NumberOfClassGuid = 0;\r
+  *ClassGuid = NULL;\r
+  *FormSetTitle = 0;\r
+  *FormSetHelp = 0;\r
+\r
+  //\r
+  // Locate HII Database protocol\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiHiiDatabaseProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &HiiDatabase\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Get HII PackageList\r
+  //\r
+  BufferSize = 0;\r
+  HiiPackageList = NULL;\r
+  Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    HiiPackageList = EfiLibAllocatePool (BufferSize);\r
+    ASSERT (HiiPackageList != NULL);\r
+\r
+    Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);\r
+  }\r
+  if (EFI_ERROR (Status)) {\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
+  Offset2 = 0;\r
+  FormSet = NULL;\r
+  EfiCopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
+\r
+  while (Offset < PackageListLength) {\r
+    Package = ((UINT8 *) HiiPackageList) + Offset;\r
+    EfiCopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+\r
+    if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
+      //\r
+      // Search Class Opcode in this Form Package\r
+      //\r
+      Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
+      while (Offset2 < PackageHeader.Length) {\r
+        OpCodeData = Package + Offset2;\r
+\r
+        if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
+          //\r
+          // Find FormSet OpCode\r
+          //\r
+          EfiCopyMem (FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
+          EfiCopyMem (FormSetHelp, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));\r
+          if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length > ((UINTN) &((EFI_IFR_FORM_SET *) 0)->Flags)) {\r
+            //\r
+            // New version of formset OpCode\r
+            //\r
+            *NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);\r
+            *ClassGuid = EfiLibAllocateCopyPool (\r
+                           *NumberOfClassGuid * sizeof (EFI_GUID),\r
+                           ((EFI_IFR_FORM_SET *) OpCodeData)->ClassGuid\r
+                           );\r
+          }\r
           break;\r
         }\r
 \r