]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/HiiLib/HiiLib.c
Merged in the following trackers from EDK:
[mirror_edk2.git] / MdePkg / Library / HiiLib / HiiLib.c
index 6cc5e764e9ec33259da7e9125c9b32577a29a5c5..940536620cfc69b683afb856c2af2915769eb8ee 100644 (file)
 \r
 **/\r
 \r
+#include "InternalHiiLib.h"\r
 \r
-#include <PiDxe.h>\r
+CONST EFI_HII_DATABASE_PROTOCOL   *mHiiDatabaseProt;\r
+CONST EFI_HII_STRING_PROTOCOL     *mHiiStringProt;\r
+BOOLEAN mHiiProtocolsInitialized = FALSE;\r
 \r
-#include <Library/HiiLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
 \r
 /**\r
-  This function allocates pool for an EFI_HII_PACKAGES structure\r
-  with enough space for the variable argument list of package pointers.\r
-  The allocated structure is initialized using NumberOfPackages, Guid,\r
-  and the variable length argument list of package pointers.\r
 \r
-  @param  NumberOfPackages The number of HII packages to prepare.\r
-  @param  Guid Package GUID.\r
+  This function locate Hii relative protocols for later usage.\r
 \r
-  @return The allocated and initialized packages.\r
+  @param VOID\r
+\r
+  @retval  VOID\r
 \r
 **/\r
+VOID\r
+LocateHiiProtocols (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  if (mHiiProtocolsInitialized) {\r
+    return;\r
+  }\r
+\r
+  Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &mHiiDatabaseProt);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &mHiiStringProt);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  mHiiProtocolsInitialized = TRUE;\r
+}\r
+\r
+\r
+\r
+EFI_HII_PACKAGE_LIST_HEADER *\r
+InternalHiiLibPreparePackages (\r
+  IN UINTN           NumberOfPackages,\r
+  IN CONST EFI_GUID  *GuidId, OPTIONAL\r
+  VA_LIST            Marker\r
+  )\r
+{\r
+  EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
+  UINT8                       *PackageListData;\r
+  UINT32                      PackageListLength;\r
+  UINT32                      PackageLength;\r
+  EFI_HII_PACKAGE_HEADER      PackageHeader;\r
+  UINT8                       *PackageArray;\r
+  UINTN                       Index;\r
+  VA_LIST                     MarkerBackup;\r
+\r
+  PackageListLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+\r
+  MarkerBackup = Marker;\r
+  \r
+  for (Index = 0; Index < NumberOfPackages; Index++) {\r
+    CopyMem (&PackageLength, VA_ARG (Marker, VOID *), sizeof (UINT32));\r
+    PackageListLength += (PackageLength - sizeof (UINT32));\r
+  }\r
+\r
+  //\r
+  // Include the lenght of EFI_HII_PACKAGE_END\r
+  //\r
+  PackageListLength += sizeof (EFI_HII_PACKAGE_HEADER);\r
+  PackageListHeader = AllocateZeroPool (PackageListLength);\r
+  ASSERT (PackageListHeader != NULL);\r
+  CopyMem (&PackageListHeader->PackageListGuid, GuidId, sizeof (EFI_GUID));\r
+  PackageListHeader->PackageLength = PackageListLength;\r
+\r
+  PackageListData = ((UINT8 *) PackageListHeader) + sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+\r
+  Marker = MarkerBackup;\r
+  for (Index = 0; Index < NumberOfPackages; Index++) {\r
+    PackageArray = (UINT8 *) VA_ARG (Marker, VOID *);\r
+    CopyMem (&PackageLength, PackageArray, sizeof (UINT32));\r
+    PackageLength  -= sizeof (UINT32);\r
+    PackageArray += sizeof (UINT32);\r
+    CopyMem (PackageListData, PackageArray, PackageLength);\r
+    PackageListData += PackageLength;\r
+  }\r
+\r
+  //\r
+  // Append EFI_HII_PACKAGE_END\r
+  //\r
+  PackageHeader.Type = EFI_HII_PACKAGE_END;\r
+  PackageHeader.Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
+  CopyMem (PackageListData, &PackageHeader, PackageHeader.Length);\r
+\r
+  return PackageListHeader;\r
+}\r
+\r
 EFI_HII_PACKAGE_LIST_HEADER *\r
 EFIAPI\r
-PreparePackages (\r
-  IN CONST  UINTN     NumberOfPackages,\r
-  IN CONST  EFI_GUID  *Guid OPTIONAL,\r
+HiiLibPreparePackageList (\r
+  IN UINTN                    NumberOfPackages,\r
+  IN CONST EFI_GUID           *GuidId,\r
   ...\r
   )\r
 {\r
+  EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
+  VA_LIST                     Marker;\r
+\r
+  ASSERT (GuidId != NULL);\r
+\r
+  VA_START (Marker, GuidId);\r
+  PackageListHeader = InternalHiiLibPreparePackages (NumberOfPackages, GuidId, Marker);\r
+  VA_END (Marker);\r
+\r
+  return PackageListHeader;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiLibAddPackages (\r
+  IN       UINTN               NumberOfPackages,\r
+  IN CONST EFI_GUID            *GuidId,\r
+  IN       EFI_HANDLE          DriverHandle, OPTIONAL\r
+  OUT      EFI_HII_HANDLE      *HiiHandle, OPTIONAL\r
+  ...\r
+  )\r
+{\r
+  VA_LIST                   Args;\r
+  EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
+  EFI_STATUS                Status;\r
+\r
+  ASSERT (HiiHandle != NULL);\r
+\r
+  LocateHiiProtocols ();\r
+\r
+  VA_START (Args, HiiHandle);\r
+  PackageListHeader = InternalHiiLibPreparePackages (NumberOfPackages, GuidId, Args);\r
+\r
+  Status      = mHiiDatabaseProt->NewPackageList (mHiiDatabaseProt, PackageListHeader, DriverHandle, HiiHandle);\r
+  if (HiiHandle != NULL) {\r
+    if (EFI_ERROR (Status)) {\r
+      *HiiHandle = NULL;\r
+    }\r
+  }\r
+\r
+  FreePool (PackageListHeader);\r
+  VA_END (Args);\r
+  \r
+  return Status;\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+HiiLibRemovePackages (\r
+  IN      EFI_HII_HANDLE      HiiHandle\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+  ASSERT (HiiHandle != NULL);\r
+\r
+  LocateHiiProtocols ();\r
+\r
+  Status = mHiiDatabaseProt->RemovePackageList (mHiiDatabaseProt, HiiHandle);\r
+  ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiLibGetHiiHandles (\r
+  IN OUT UINTN                     *HandleBufferLength,\r
+  OUT    EFI_HII_HANDLE            **HiiHandleBuffer\r
+  )\r
+{\r
+  UINTN       BufferLength;\r
+  EFI_STATUS  Status;\r
+\r
+  ASSERT (HandleBufferLength != NULL);\r
+  ASSERT (HiiHandleBuffer != NULL);\r
+\r
+  BufferLength = 0;\r
+\r
+  LocateHiiProtocols ();\r
+\r
+  //\r
+  // Try to find the actual buffer size for HiiHandle Buffer.\r
+  //\r
+  Status = mHiiDatabaseProt->ListPackageLists (\r
+                                 mHiiDatabaseProt,\r
+                                 EFI_HII_PACKAGE_TYPE_ALL,\r
+                                 NULL,\r
+                                 &BufferLength,\r
+                                 *HiiHandleBuffer\r
+                                 );\r
+\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+      *HiiHandleBuffer = AllocateZeroPool (BufferLength);\r
+      Status = mHiiDatabaseProt->ListPackageLists (\r
+                                     mHiiDatabaseProt,\r
+                                     EFI_HII_PACKAGE_TYPE_ALL,\r
+                                     NULL,\r
+                                     &BufferLength,\r
+                                     *HiiHandleBuffer\r
+                                     );\r
+      //\r
+      // we should not fail here.\r
+      //\r
+      ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+  *HandleBufferLength = BufferLength;\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiLibExtractGuidFromHiiHandle (\r
+  IN      EFI_HII_HANDLE      Handle,\r
+  OUT     EFI_GUID            *Guid\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  UINTN                        BufferSize;\r
+  EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;\r
+\r
+  ASSERT (Guid != NULL);\r
+\r
+  //\r
+  // Get HII PackageList\r
+  //\r
+  BufferSize = 0;\r
+  HiiPackageList = NULL;\r
+\r
+  LocateHiiProtocols ();\r
+\r
+  Status = mHiiDatabaseProt->ExportPackageLists (mHiiDatabaseProt, Handle, &BufferSize, HiiPackageList);\r
+  ASSERT (Status != EFI_NOT_FOUND);\r
+  \r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    HiiPackageList = AllocatePool (BufferSize);\r
+    ASSERT (HiiPackageList != NULL);\r
+\r
+    Status = mHiiDatabaseProt->ExportPackageLists (mHiiDatabaseProt, Handle, &BufferSize, HiiPackageList);\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Extract GUID\r
+  //\r
+  CopyMem (Guid, &HiiPackageList->PackageListGuid, sizeof (EFI_GUID));\r
+\r
+  gBS->FreePool (HiiPackageList);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_HII_HANDLE\r
+EFIAPI\r
+HiiLibDevicePathToHiiHandle (\r
+  IN EFI_DEVICE_PATH_PROTOCOL   *DevicePath\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_DEVICE_PATH_PROTOCOL    *TmpDevicePath;\r
+  UINTN                       BufferSize;\r
+  UINTN                       HandleCount;\r
+  UINTN                       Index;\r
+  EFI_HANDLE                  *Handles;\r
+  EFI_HANDLE                  Handle;\r
+  UINTN                       Size;\r
+  EFI_HANDLE                  DriverHandle;\r
+  EFI_HII_HANDLE              *HiiHandles;\r
+  EFI_HII_HANDLE              HiiHandle;\r
+\r
+  ASSERT (DevicePath != NULL);\r
+\r
+  //\r
+  // Locate Device Path Protocol handle buffer\r
+  //\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  NULL,\r
+                  &HandleCount,\r
+                  &Handles\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Search Driver Handle by Device Path\r
+  //\r
+  DriverHandle = NULL;\r
+  BufferSize = GetDevicePathSize (DevicePath);\r
+  for(Index = 0; Index < HandleCount; Index++) {\r
+    Handle = Handles[Index];\r
+    gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **) &TmpDevicePath);\r
+\r
+    //\r
+    // Check whether DevicePath match\r
+    //\r
+    Size = GetDevicePathSize (TmpDevicePath);\r
+    if ((Size == BufferSize) && CompareMem (DevicePath, TmpDevicePath, Size) == 0) {\r
+      DriverHandle = Handle;\r
+      break;\r
+    }\r
+  }\r
+  gBS->FreePool (Handles);\r
+\r
+  if (DriverHandle == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  LocateHiiProtocols ();\r
+\r
+  //\r
+  // Retrieve all Hii Handles from HII database\r
+  //\r
+  BufferSize = 0x1000;\r
+  HiiHandles = AllocatePool (BufferSize);\r
+  ASSERT (HiiHandles != NULL);\r
+  Status = mHiiDatabaseProt->ListPackageLists (\r
+                          mHiiDatabaseProt,\r
+                          EFI_HII_PACKAGE_TYPE_ALL,\r
+                          NULL,\r
+                          &BufferSize,\r
+                          HiiHandles\r
+                          );\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    gBS->FreePool (HiiHandles);\r
+    HiiHandles = AllocatePool (BufferSize);\r
+    ASSERT (HiiHandles != NULL);\r
+\r
+    Status = mHiiDatabaseProt->ListPackageLists (\r
+                            mHiiDatabaseProt,\r
+                            EFI_HII_PACKAGE_TYPE_ALL,\r
+                            NULL,\r
+                            &BufferSize,\r
+                            HiiHandles\r
+                            );\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    gBS->FreePool (HiiHandles);\r
+    return NULL;\r
+  }\r
+\r
   //\r
-  // BugBug: Need more detail on UEFI spec.\r
+  // Search Hii Handle by Driver Handle\r
   //\r
-  ASSERT (FALSE);\r
-  return NULL;\r
+  HiiHandle = NULL;\r
+  HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);\r
+  for (Index = 0; Index < HandleCount; Index++) {\r
+    Status = mHiiDatabaseProt->GetPackageListHandle (\r
+                            mHiiDatabaseProt,\r
+                            HiiHandles[Index],\r
+                            &Handle\r
+                            );\r
+    if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {\r
+      HiiHandle = HiiHandles[Index];\r
+      break;\r
+    }\r
+  }\r
+\r
+  gBS->FreePool (HiiHandles);\r
+  return HiiHandle;\r
+}\r
+\r
+BOOLEAN\r
+IsHiiHandleRegistered (\r
+  EFI_HII_HANDLE    HiiHandle\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  UINTN                        BufferSize;\r
+  EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;\r
+\r
+  ASSERT (HiiHandle != NULL);\r
+\r
+  HiiPackageList = NULL;\r
+  BufferSize = 0;\r
+\r
+  LocateHiiProtocols ();\r
+\r
+  Status = mHiiDatabaseProt->ExportPackageLists (\r
+             mHiiDatabaseProt,\r
+             HiiHandle,\r
+             &BufferSize,\r
+             HiiPackageList\r
+             );\r
+\r
+  return (BOOLEAN) (Status == EFI_BUFFER_TOO_SMALL);\r
 }\r
+\r