]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/UefiHiiLib/HiiLib.c
MdeModulePkg:Add new API HiiGetFormSetFromHiiHandle into UefiHiiLib
[mirror_edk2.git] / MdeModulePkg / Library / UefiHiiLib / HiiLib.c
index 66d72acf27556b82bee1a59a78ff843297dfad52..1aa0edc62c4ce3908b4d72eff022d9293ebd7a82 100644 (file)
@@ -377,6 +377,117 @@ HiiGetHiiHandles (
   }\r
 }\r
 \r
+/**\r
+  This function allows a caller to extract the form set opcode form the Hii Handle.\r
+  The returned buffer is allocated using AllocatePool().The caller is responsible \r
+  for freeing the allocated buffer using FreePool().\r
+\r
+  @param Handle            The HII handle.\r
+  @param Buffer            On return, opints to a pointer which point to the buffer that contain the formset opcode.\r
+  @param BufferSize        On return, points to the length of the buffer.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES   No enough memory resource is allocated.\r
+  @retval EFI_NOT_FOUND          Can't find the package data for the input Handle.\r
+  @retval EFI_INVALID_PARAMETER  The input parameters are not correct.\r
+  @retval EFI_SUCCESS            Get the formset opcode from the hii handle sucessfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetFormSetFromHiiHandle(\r
+  IN  EFI_HII_HANDLE     Handle,\r
+  OUT EFI_IFR_FORM_SET   **Buffer,\r
+  OUT UINTN              *BufferSize\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  UINTN                        PackageListSize;\r
+  UINTN                        TempSize;\r
+  EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;\r
+  UINT8                        *Package;\r
+  UINT8                        *OpCodeData;\r
+  EFI_IFR_FORM_SET             *FormSetBuffer;\r
+  EFI_IFR_FORM_SET             *TempBuffer;\r
+  UINT32                       Offset;\r
+  UINT32                       Offset2;\r
+  UINT32                       PackageListLength;\r
+  EFI_HII_PACKAGE_HEADER       PackageHeader;\r
+\r
+  TempSize = 0;\r
+  FormSetBuffer = NULL;\r
+  TempBuffer    = NULL;\r
+\r
+  //\r
+  // Get HII PackageList\r
+  //\r
+  PackageListSize = 0;\r
+  HiiPackageList = NULL;\r
+  Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &PackageListSize, HiiPackageList);\r
+  if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {\r
+    return Status;\r
+  }\r
+\r
+  HiiPackageList = AllocatePool (PackageListSize);\r
+  if (HiiPackageList == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &PackageListSize, HiiPackageList);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Get Form package from this HII package List\r
+  //\r
+  Status = EFI_NOT_FOUND;\r
+  Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+  PackageListLength = ReadUnaligned32 (&HiiPackageList->PackageLength);\r
+\r
+  while (Offset < PackageListLength) {\r
+    Package = ((UINT8 *) HiiPackageList) + Offset;\r
+    CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+    Offset += PackageHeader.Length;\r
+\r
+    if (PackageHeader.Type != EFI_HII_PACKAGE_FORMS) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Search FormSet Opcode in this Form Package\r
+    //\r
+    Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
+    while (Offset2 < PackageHeader.Length) {\r
+      OpCodeData = Package + Offset2;\r
+      Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
+\r
+      if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode != EFI_IFR_FORM_SET_OP) {\r
+        continue;\r
+      }\r
+\r
+      if (FormSetBuffer != NULL){\r
+        TempBuffer = AllocateCopyPool (TempSize + ((EFI_IFR_OP_HEADER *) OpCodeData)->Length, FormSetBuffer);\r
+        CopyMem (TempBuffer + TempSize,  OpCodeData, ((EFI_IFR_OP_HEADER *) OpCodeData)->Length);\r
+        FreePool(FormSetBuffer);\r
+      } else {\r
+        TempBuffer = AllocateCopyPool (TempSize + ((EFI_IFR_OP_HEADER *) OpCodeData)->Length, OpCodeData);\r
+      }\r
+      TempSize += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
+      FormSetBuffer = TempBuffer;\r
+\r
+      Status = EFI_SUCCESS;\r
+      //\r
+      //One form package has one formset, exit current form package to search other form package in the packagelist.\r
+      //\r
+      break;\r
+    }\r
+  }\r
+  FreePool (HiiPackageList);\r
+\r
+  *BufferSize = TempSize;\r
+  *Buffer = FormSetBuffer;\r
+\r
+  return Status;\r
+}\r
+\r
 /**\r
   Converts all hex dtring characters in range ['A'..'F'] to ['a'..'f'] for \r
   hex digits that appear between a '=' and a '&' in a config string.\r