+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- UefiIfrCommon.c\r
-\r
-Abstract:\r
-\r
- Common Library Routines to assist handle HII elements.\r
-\r
---*/\r
-\r
-#include "UefiIfrLibrary.h"\r
-\r
-//\r
-// Hii vendor device path template\r
-//\r
-HII_VENDOR_DEVICE_PATH mHiiVendorDevicePathTemplate = {\r
- {\r
- {\r
- {\r
- HARDWARE_DEVICE_PATH,\r
- HW_VENDOR_DP,\r
- {\r
- (UINT8) (sizeof (HII_VENDOR_DEVICE_PATH_NODE)),\r
- (UINT8) ((sizeof (HII_VENDOR_DEVICE_PATH_NODE)) >> 8)\r
- }\r
- },\r
- EFI_IFR_TIANO_GUID,\r
- },\r
- 0,\r
- 0\r
- },\r
- {\r
- END_DEVICE_PATH_TYPE,\r
- END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
- {\r
- END_DEVICE_PATH_LENGTH\r
- }\r
- }\r
-};\r
-\r
-//\r
-// Hii relative protocols\r
-//\r
-BOOLEAN mHiiProtocolsInitialized = FALSE;\r
-\r
-EFI_HII_DATABASE_PROTOCOL *gIfrLibHiiDatabase;\r
-EFI_HII_STRING_PROTOCOL *gIfrLibHiiString;\r
-\r
-VOID\r
-LocateHiiProtocols (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- This function locate Hii relative protocols for later usage.\r
-\r
-Arguments:\r
- None.\r
-\r
-Returns:\r
- None.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
-\r
- if (mHiiProtocolsInitialized) {\r
- return;\r
- }\r
-\r
- Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &gIfrLibHiiDatabase);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &gIfrLibHiiString);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- mHiiProtocolsInitialized = TRUE;\r
-}\r
-\r
-EFI_HII_PACKAGE_LIST_HEADER *\r
-PreparePackageList (\r
- IN UINTN NumberOfPackages,\r
- IN EFI_GUID *GuidId,\r
- ...\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Assemble EFI_HII_PACKAGE_LIST according to the passed in packages.\r
-\r
-Arguments:\r
- NumberOfPackages - Number of packages.\r
- GuidId - Package GUID.\r
-\r
-Returns:\r
- Pointer of EFI_HII_PACKAGE_LIST_HEADER.\r
-\r
---*/\r
-{\r
- VA_LIST Marker;\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
-\r
- PackageListLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
-\r
- VA_START (Marker, GuidId);\r
- for (Index = 0; Index < NumberOfPackages; Index++) {\r
- EfiCopyMem (&PackageLength, VA_ARG (Marker, VOID *), sizeof (UINT32));\r
- PackageListLength += (PackageLength - sizeof (UINT32));\r
- }\r
- VA_END (Marker);\r
-\r
- //\r
- // Include the lenght of EFI_HII_PACKAGE_END\r
- //\r
- PackageListLength += sizeof (EFI_HII_PACKAGE_HEADER);\r
- PackageListHeader = EfiLibAllocateZeroPool (PackageListLength);\r
- ASSERT (PackageListHeader != NULL);\r
- EfiCopyMem (&PackageListHeader->PackageListGuid, GuidId, sizeof (EFI_GUID));\r
- PackageListHeader->PackageLength = PackageListLength;\r
-\r
- PackageListData = ((UINT8 *) PackageListHeader) + sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
-\r
- VA_START (Marker, GuidId);\r
- for (Index = 0; Index < NumberOfPackages; Index++) {\r
- PackageArray = (UINT8 *) VA_ARG (Marker, VOID *);\r
- EfiCopyMem (&PackageLength, PackageArray, sizeof (UINT32));\r
- PackageLength -= sizeof (UINT32);\r
- PackageArray += sizeof (UINT32);\r
- EfiCopyMem (PackageListData, PackageArray, PackageLength);\r
- PackageListData += PackageLength;\r
- }\r
- VA_END (Marker);\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
- EfiCopyMem (PackageListData, &PackageHeader, PackageHeader.Length);\r
-\r
- return PackageListHeader;\r
-}\r
-\r
-EFI_STATUS\r
-CreateHiiDriverHandle (\r
- OUT EFI_HANDLE *DriverHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- The HII driver handle passed in for HiiDatabase.NewPackageList() requires\r
- that there should be DevicePath Protocol installed on it.\r
- This routine create a virtual Driver Handle by installing a vendor device\r
- path on it, so as to use it to invoke HiiDatabase.NewPackageList().\r
-\r
-Arguments:\r
- DriverHandle - Handle to be returned\r
-\r
-Returns:\r
- EFI_SUCCESS - Handle destroy success.\r
- EFI_OUT_OF_RESOURCES - Not enough memory.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- HII_VENDOR_DEVICE_PATH_NODE *VendorDevicePath;\r
-\r
- VendorDevicePath = EfiLibAllocateCopyPool (sizeof (HII_VENDOR_DEVICE_PATH), &mHiiVendorDevicePathTemplate);\r
- if (VendorDevicePath == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\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->InstallMultipleProtocolInterfaces (\r
- DriverHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- VendorDevicePath,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-DestroyHiiDriverHandle (\r
- IN EFI_HANDLE DriverHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Destroy the Driver Handle created by CreateHiiDriverHandle().\r
-\r
-Arguments:\r
- DriverHandle - Handle returned by CreateHiiDriverHandle()\r
-\r
-Returns:\r
- EFI_SUCCESS - Handle destroy success.\r
- other - Handle destroy fail.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
-\r
- Status = gBS->HandleProtocol (\r
- DriverHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **) &DevicePath\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = gBS->UninstallProtocolInterface (\r
- DriverHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- DevicePath\r
- );\r
- gBS->FreePool (DevicePath);\r
- return Status;\r
-}\r
-\r
-EFI_HII_HANDLE\r
-DevicePathToHiiHandle (\r
- IN EFI_HII_DATABASE_PROTOCOL *HiiDatabase,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Find HII Handle associated with given Device Path.\r
-\r
-Arguments:\r
- HiiDatabase - Point to EFI_HII_DATABASE_PROTOCOL instance.\r
- DevicePath - Device Path associated with the HII package list handle.\r
-\r
-Returns:\r
- Handle - HII package list Handle associated with the Device Path.\r
- NULL - Hii Package list handle is not found.\r
-\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
- //\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 = EfiDevicePathSize (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 = EfiDevicePathSize (TmpDevicePath);\r
- if ((Size == BufferSize) && EfiCompareMem (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
- //\r
- // Retrieve all Hii Handles from HII database\r
- //\r
- BufferSize = 0x1000;\r
- HiiHandles = EfiLibAllocatePool (BufferSize);\r
- ASSERT (HiiHandles != NULL);\r
- Status = HiiDatabase->ListPackageLists (\r
- HiiDatabase,\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 = EfiLibAllocatePool (BufferSize);\r
- ASSERT (HiiHandles != NULL);\r
-\r
- Status = HiiDatabase->ListPackageLists (\r
- HiiDatabase,\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
- // Search Hii Handle by Driver Handle\r
- //\r
- HiiHandle = NULL;\r
- HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);\r
- for (Index = 0; Index < HandleCount; Index++) {\r
- Status = HiiDatabase->GetPackageListHandle (\r
- HiiDatabase,\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
-EFI_STATUS\r
-GetHiiHandles (\r
- IN OUT UINTN *HandleBufferLength,\r
- OUT EFI_HII_HANDLE **HiiHandleBuffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Determines the handles that are currently active in the database.\r
- It's the caller's responsibility to free handle buffer.\r
-\r
-Arguments:\r
- HiiDatabase - A pointer to the EFI_HII_DATABASE_PROTOCOL instance.\r
- HandleBufferLength - On input, a pointer to the length of the handle buffer. On output,\r
- the length of the handle buffer that is required for the handles found.\r
- HiiHandleBuffer - Pointer to an array of Hii Handles returned.\r
-\r
-Returns:\r
- EFI_SUCCESS - Get an array of Hii Handles successfully.\r
- EFI_INVALID_PARAMETER - Hii is NULL.\r
- EFI_NOT_FOUND - Database not found.\r
-\r
---*/\r
-{\r
- UINTN BufferLength;\r
- EFI_STATUS Status;\r
-\r
- BufferLength = 0;\r
-\r
- LocateHiiProtocols ();\r
-\r
- //\r
- // Try to find the actual buffer size for HiiHandle Buffer.\r
- //\r
- Status = gIfrLibHiiDatabase->ListPackageLists (\r
- gIfrLibHiiDatabase,\r
- EFI_HII_PACKAGE_TYPE_ALL,\r
- NULL,\r
- &BufferLength,\r
- *HiiHandleBuffer\r
- );\r
-\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- *HiiHandleBuffer = EfiLibAllocateZeroPool (BufferLength);\r
- Status = gIfrLibHiiDatabase->ListPackageLists (\r
- gIfrLibHiiDatabase,\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
-ExtractGuidFromHiiHandle (\r
- IN EFI_HII_HANDLE Handle,\r
- OUT EFI_GUID *Guid\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Extract Hii package list GUID for given HII handle.\r
-\r
-Arguments:\r
- HiiHandle - Hii handle\r
- Guid - Package list GUID\r
-\r
-Returns:\r
- EFI_SUCCESS - Successfully extract GUID from Hii database.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINTN BufferSize;\r
- EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
- EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\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
- // Extract GUID\r
- //\r
- EfiCopyMem (Guid, &HiiPackageList->PackageListGuid, sizeof (EFI_GUID));\r
-\r
- gBS->FreePool (HiiPackageList);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ExtractClassFromHiiHandle (\r
- IN EFI_HII_HANDLE Handle,\r
- OUT UINT16 *Class,\r
- OUT EFI_STRING_ID *FormSetTitle,\r
- OUT EFI_STRING_ID *FormSetHelp\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Extract formset class for given HII handle.\r
-\r
-Arguments:\r
- HiiHandle - Hii handle\r
- Class - Class of the formset\r
- FormSetTitle - Formset title string\r
- FormSetHelp - Formset help string\r
-\r
-Returns:\r
- EFI_SUCCESS - Successfully extract Class for specified Hii handle.\r
- EFI_NOT_FOUND - Class not found.\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 *OpCodeData;\r
- UINT32 Offset;\r
- 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
- //\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 (HiiPackageList == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- if (EFI_ERROR (Status)) {\r
- gBS->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
- Offset2 = 0;\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
- }\r
-\r
- if ((((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_GUID_OP) &&\r
- (EfiCompareGuid (&mIfrVendorGuid, &((EFI_IFR_GUID *) OpCodeData)->Guid)) &&\r
- (((EFI_IFR_GUID_CLASS *) OpCodeData)->ExtendOpCode == EFI_IFR_EXTEND_OP_CLASS)\r
- ) {\r
- //\r
- // Find GUIDed Class OpCode\r
- //\r
- EfiCopyMem (Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));\r
-\r
- //\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 *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) || (HiiPackageList == NULL)) {\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
- 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
- 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 EFI_SUCCESS;\r
-}\r