+#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