\r
#include <PiDxe.h>\r
\r
+#include <Protocol/HiiDatabase.h>\r
+#include <Protocol/HiiString.h>\r
+#include <Protocol/DevicePath.h>\r
+\r
+#include <Guid/GlobalVariable.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
#include <Library/HiiLib.h>\r
#include <Library/DebugLib.h>\r
#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+#include <MdeModuleHii.h>\r
+\r
+#include "InternalHiiLib.h"\r
+\r
+\r
+EFI_HII_DATABASE_PROTOCOL *mHiiDatabaseProt;\r
+EFI_HII_STRING_PROTOCOL *mHiiStringProt;\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
+ },\r
+ {\r
+ END_DEVICE_PATH_TYPE,\r
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+ { \r
+ END_DEVICE_PATH_LENGTH\r
+ }\r
+ }\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UefiHiiLibConstructor (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ \r
+ Status = gBS->LocateProtocol (\r
+ &gEfiHiiDatabaseProtocolGuid,\r
+ NULL,\r
+ (VOID **) &mHiiDatabaseProt\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ ASSERT (mHiiDatabaseProt != NULL);\r
+\r
+ Status = gBS->LocateProtocol (\r
+ &gEfiHiiStringProtocolGuid,\r
+ NULL,\r
+ (VOID **) &mHiiStringProt\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ ASSERT (mHiiStringProt != NULL);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+HiiLibGetCurrentLanguage (\r
+ OUT CHAR8 *Lang\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Determine what is the current language setting\r
+\r
+Arguments:\r
+ Lang - Pointer of system language\r
+\r
+Returns:\r
+ Status code\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Size;\r
+\r
+ //\r
+ // Get current language setting\r
+ //\r
+ Size = RFC_3066_ENTRY_SIZE;\r
+ Status = gRT->GetVariable (\r
+ L"PlatformLang",\r
+ &gEfiGlobalVariableGuid,\r
+ NULL,\r
+ &Size,\r
+ Lang\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ AsciiStrCpy (Lang, (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang));\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+VOID\r
+HiiLibGetNextLanguage (\r
+ IN OUT CHAR8 **LangCode,\r
+ OUT CHAR8 *Lang\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Get next language from language code list (with separator ';').\r
+\r
+Arguments:\r
+ LangCode - On input: point to first language in the list. On output: point to\r
+ next language in the list, or NULL if no more language in the list.\r
+ Lang - The first language in the list.\r
+\r
+Returns:\r
+ None.\r
+\r
+--*/\r
+{\r
+ UINTN Index;\r
+ CHAR8 *StringPtr;\r
+\r
+ if (LangCode == NULL || *LangCode == NULL) {\r
+ *Lang = 0;\r
+ return;\r
+ }\r
+\r
+ Index = 0;\r
+ StringPtr = *LangCode;\r
+ while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {\r
+ Index++;\r
+ }\r
+\r
+ CopyMem (Lang, StringPtr, Index);\r
+ Lang[Index] = 0;\r
+\r
+ if (StringPtr[Index] == ';') {\r
+ Index++;\r
+ }\r
+ *LangCode = StringPtr + Index;\r
+}\r
+\r
+CHAR8 *\r
+HiiLibGetSupportedLanguages (\r
+ IN EFI_HII_HANDLE HiiHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ This function returns the list of supported languages, in the format specified\r
+ in UEFI specification Appendix M.\r
+\r
+Arguments:\r
+ HiiHandle - The HII package list handle.\r
+\r
+Returns:\r
+ The supported languages.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN BufferSize;\r
+ CHAR8 *LanguageString;\r
+\r
+ //\r
+ // Collect current supported Languages for given HII handle\r
+ //\r
+ BufferSize = 0x1000;\r
+ LanguageString = AllocatePool (BufferSize);\r
+ Status = mHiiStringProt->GetLanguages (mHiiStringProt, HiiHandle, LanguageString, &BufferSize);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ gBS->FreePool (LanguageString);\r
+ LanguageString = AllocatePool (BufferSize);\r
+ Status = mHiiStringProt->GetLanguages (mHiiStringProt, HiiHandle, LanguageString, &BufferSize);\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ LanguageString = NULL;\r
+ }\r
+\r
+ return LanguageString;\r
+}\r
+\r
+UINT16\r
+HiiLibGetSupportedLanguageNumber (\r
+ IN EFI_HII_HANDLE HiiHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ This function returns the number of supported languages\r
+\r
+Arguments:\r
+ HiiHandle - The HII package list handle.\r
+\r
+Returns:\r
+ The number of supported languages.\r
+\r
+--*/\r
+{\r
+ CHAR8 *Languages;\r
+ CHAR8 *LanguageString;\r
+ UINT16 LangNumber;\r
+ CHAR8 Lang[RFC_3066_ENTRY_SIZE];\r
+\r
+ Languages = HiiLibGetSupportedLanguages (HiiHandle);\r
+ if (Languages == NULL) {\r
+ return 0;\r
+ }\r
+\r
+ LangNumber = 0;\r
+ LanguageString = Languages;\r
+ while (*LanguageString != 0) {\r
+ HiiLibGetNextLanguage (&LanguageString, Lang);\r
+ LangNumber++;\r
+ }\r
+ gBS->FreePool (Languages);\r
+\r
+ return LangNumber;\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
+HiiLibPreparePackageList (\r
+ IN UINTN NumberOfPackages,\r
+ IN CONST 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
+ EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
+ VA_LIST Marker;\r
+\r
+ VA_START (Marker, GuidId);\r
+ PackageListHeader = InternalHiiLibPreparePackages (NumberOfPackages, GuidId, Marker);\r
+ VA_END (Marker);\r
+\r
+ return PackageListHeader;\r
+}\r
+\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
+ This function allocates pool for an EFI_HII_PACKAGE_LIST structure\r
+ with additional space that is big enough to host all packages described by the variable \r
+ argument list of package pointers. The allocated structure is initialized using NumberOfPackages, \r
+ GuidId, 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
+ Then, EFI_HII_PACKAGE_LIST will be register to the default System HII Database. The\r
+ Handle to the newly registered Package List is returned throught HiiHandle.\r
\r
- @return The allocated and initialized packages.\r
+ @param NumberOfPackages The number of HII packages to register.\r
+ @param GuidId Package List GUID ID.\r
+ @param HiiHandle The ID used to retrieve the Package List later.\r
+ @param ... The variable argument list describing all HII Package.\r
+\r
+ @return\r
+ The allocated and initialized packages.\r
\r
**/\r
-EFI_HII_PACKAGE_LIST_HEADER *\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiLibAddPackagesToHiiDatabase (\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
+\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
+EFI_STATUS\r
+EFIAPI\r
+HiiLibAddFontPackageToHiiDatabase (\r
+ IN UINTN FontSize,\r
+ IN CONST UINT8 *FontBinary,\r
+ IN CONST EFI_GUID *GuidId,\r
+ OUT EFI_HII_HANDLE *HiiHandle OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 *Location;\r
+ EFI_HII_SIMPLE_FONT_PACKAGE_HDR *SimplifiedFont;\r
+ UINTN PackageLength;\r
+ EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r
+ UINT8 *Package;\r
+\r
+ //\r
+ // Add 4 bytes to the header for entire length for PreparePackageList use only.\r
+ // Looks ugly. Might be updated when font tool is ready.\r
+ //\r
+ PackageLength = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + FontSize + 4;\r
+ Package = AllocateZeroPool (PackageLength);\r
+ if (Package == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ CopyMem (Package, &PackageLength, 4);\r
+ SimplifiedFont = (EFI_HII_SIMPLE_FONT_PACKAGE_HDR*) (Package + 4);\r
+ SimplifiedFont->Header.Length = (UINT32) (PackageLength - 4);\r
+ SimplifiedFont->Header.Type = EFI_HII_PACKAGE_SIMPLE_FONTS;\r
+ SimplifiedFont->NumberOfNarrowGlyphs = (UINT16) (FontSize / sizeof (EFI_NARROW_GLYPH));\r
+ \r
+ Location = (UINT8 *) (&SimplifiedFont->NumberOfWideGlyphs + 1);\r
+ CopyMem (Location, FontBinary, FontSize);\r
+ \r
+ //\r
+ // Add this simplified font package to a package list then install it.\r
+ //\r
+ PackageList = HiiLibPreparePackageList (1, GuidId, Package);\r
+ Status = mHiiDatabaseProt->NewPackageList (mHiiDatabaseProt, PackageList, NULL, HiiHandle);\r
+ ASSERT_EFI_ERROR (Status);\r
+ SafeFreePool (PackageList);\r
+ SafeFreePool (Package); \r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiLibRemovePackagesFromHiiDatabase (\r
+ IN EFI_HII_HANDLE HiiHandle\r
+ )\r
+{\r
+ return mHiiDatabaseProt->RemovePackageList (mHiiDatabaseProt, HiiHandle);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiLibCreateString (\r
+ IN EFI_HII_HANDLE PackageList,\r
+ OUT EFI_STRING_ID *StringId,\r
+ IN CONST EFI_STRING String\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ CHAR8 *Languages;\r
+ CHAR8 *LangStrings;\r
+ CHAR8 Lang[RFC_3066_ENTRY_SIZE];\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ Languages = HiiLibGetSupportedLanguages (PackageList);\r
+\r
+ LangStrings = Languages;\r
+ while (*LangStrings != 0) {\r
+ HiiLibGetNextLanguage (&LangStrings, Lang);\r
+\r
+ Status = mHiiStringProt->NewString (\r
+ mHiiStringProt,\r
+ PackageList,\r
+ StringId,\r
+ Lang,\r
+ NULL,\r
+ String,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ FreePool (Languages);\r
+\r
+ return Status;\r
+ \r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiLibUpdateString (\r
+ IN EFI_HII_HANDLE PackageList,\r
+ IN EFI_STRING_ID StringId,\r
+ IN CONST EFI_STRING String\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ CHAR8 *Languages;\r
+ CHAR8 *LangStrings;\r
+ CHAR8 Lang[RFC_3066_ENTRY_SIZE];\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ Languages = HiiLibGetSupportedLanguages (PackageList);\r
+\r
+ LangStrings = Languages;\r
+ while (*LangStrings != 0) {\r
+ HiiLibGetNextLanguage (&LangStrings, Lang);\r
+\r
+ Status = mHiiStringProt->SetString (\r
+ mHiiStringProt,\r
+ PackageList,\r
+ StringId,\r
+ Lang,\r
+ String,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ FreePool (Languages);\r
+\r
+ return Status;\r
+}\r
+\r
+// //\r
+// //////////////////////////////////////////////////\r
+// //\r
+\r
+//\r
+// This function is Implementation Specifc. HII_VENDOR_DEVICE_PATH\r
+// This should be moved to MdeModulepkg.\r
+//\r
+EFI_STATUS\r
EFIAPI\r
-PreparePackages (\r
- IN CONST UINTN NumberOfPackages,\r
- IN CONST EFI_GUID *Guid OPTIONAL,\r
+HiiLibCreateHiiDriverHandle (\r
+ OUT EFI_HANDLE *DriverHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ HII_VENDOR_DEVICE_PATH_NODE *VendorDevicePath;\r
+ UINT64 MonotonicCount;\r
+\r
+ VendorDevicePath = AllocateCopyPool (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
+ *DriverHandle = NULL;\r
+ Status = gBS->InstallProtocolInterface (\r
+ DriverHandle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ VendorDevicePath\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiLibDestroyHiiDriverHandle (\r
+ IN EFI_HANDLE DriverHandle\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
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+HiiLibExtractDefault(\r
+ IN VOID *Buffer,\r
+ IN UINTN *BufferSize,\r
+ UINTN Number,\r
...\r
)\r
+/*++\r
+\r
+ Routine Description:\r
+\r
+ Configure the buffer accrording to ConfigBody strings.\r
+\r
+ Arguments:\r
+ DefaultId - the ID of default.\r
+ Buffer - the start address of buffer.\r
+ BufferSize - the size of buffer.\r
+ Number - the number of the strings.\r
+\r
+ Returns:\r
+ EFI_BUFFER_TOO_SMALL - the BufferSize is too small to operate.\r
+ EFI_INVALID_PARAMETER - Buffer is NULL or BufferSize is 0.\r
+ EFI_SUCCESS - Operation successful.\r
+\r
+--*/\r
{\r
+ VA_LIST Args;\r
+ UINTN Index;\r
+ UINT32 TotalLen;\r
+ UINT8 *BufCfgArray;\r
+ UINT8 *BufferPos;\r
+ UINT16 Offset;\r
+ UINT16 Width;\r
+ UINT8 *Value;\r
+\r
+ if ((Buffer == NULL) || (BufferSize == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Offset = 0;\r
+ Width = 0;\r
+ Value = NULL;\r
+\r
+ VA_START (Args, Number);\r
+ for (Index = 0; Index < Number; Index++) {\r
+ BufCfgArray = (UINT8 *) VA_ARG (Args, VOID *);\r
+ CopyMem (&TotalLen, BufCfgArray, sizeof (UINT32));\r
+ BufferPos = BufCfgArray + sizeof (UINT32);\r
+\r
+ while ((UINT32)(BufferPos - BufCfgArray) < TotalLen) {\r
+ CopyMem (&Offset, BufferPos, sizeof (UINT16));\r
+ BufferPos += sizeof (UINT16);\r
+ CopyMem (&Width, BufferPos, sizeof (UINT16));\r
+ BufferPos += sizeof (UINT16);\r
+ Value = BufferPos;\r
+ BufferPos += Width;\r
+\r
+ if ((UINTN)(Offset + Width) > *BufferSize) {\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ CopyMem ((UINT8 *)Buffer + Offset, Value, Width);\r
+ }\r
+ }\r
+ VA_END (Args);\r
+\r
+ *BufferSize = (UINTN)Offset;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+STATIC EFI_GUID mIfrVendorGuid = EFI_IFR_TIANO_GUID;\r
+\r
+EFI_STATUS\r
+HiiLibExtractClassFromHiiHandle (\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
+\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
+ *Class = EFI_NON_DEVICE_CLASS;\r
+ *FormSetTitle = 0;\r
+ *FormSetHelp = 0;\r
+\r
//\r
- // BugBug: Need more detail on UEFI spec.\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 = AllocatePool (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
- ASSERT (FALSE);\r
- return NULL;\r
+ // Get Form package from this HII package List\r
+ //\r
+ Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+ Offset2 = 0;\r
+ CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
+\r
+ while (Offset < PackageListLength) {\r
+ Package = ((UINT8 *) HiiPackageList) + Offset;\r
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+\r
+ if (PackageHeader.Type == EFI_HII_PACKAGE_FORM) {\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
+ CopyMem (FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
+ CopyMem (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
+ CompareGuid (&mIfrVendorGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER))) &&\r
+ (((EFI_IFR_GUID_CLASS *) OpCodeData)->ExtendOpCode == EFI_IFR_EXTEND_OP_CLASS)\r
+ ) {\r
+ //\r
+ // Find GUIDed Class OpCode\r
+ //\r
+ CopyMem (Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));\r
+\r
+ //\r
+ // Till now, we ought to have found the formset Opcode\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
+\r