\r
#include "HiiDatabase.h"\r
\r
+EFI_HII_THUNK_PRIVATE_DATA *mHiiThunkPrivateData;\r
\r
-EFI_HII_THUNK_PRIVATE_DATA HiiThunkPrivateDataTempate = {\r
+EFI_HII_THUNK_PRIVATE_DATA mHiiThunkPrivateDataTempate = {\r
{//Signature\r
EFI_HII_THUNK_DRIVER_DATA_SIGNATURE \r
},\r
},\r
{ //StaticHiiHandle\r
//The FRAMEWORK_EFI_HII_HANDLE starts from 1 \r
- // and increase upwords untill reach 2^(sizeof (FRAMEWORK_EFI_HII_HANDLE)) - 1. \r
+ // and increase upwords untill reach the value of StaticPureUefiHiiHandle. \r
// The code will assert to prevent overflow.\r
(FRAMEWORK_EFI_HII_HANDLE) 1 \r
},\r
+ { //StaticPureUefiHiiHandle\r
+ //The Static FRAMEWORK_EFI_HII_HANDLE starts from 0xFFFF \r
+ // and decrease downwords untill reach the value of StaticHiiHandle. \r
+ // The code will assert to prevent overflow.\r
+ (FRAMEWORK_EFI_HII_HANDLE) 0xFFFF \r
+ },\r
{\r
NULL, NULL //HiiHandleLinkList\r
},\r
CONST EFI_HII_STRING_PROTOCOL *mHiiStringProtocol;\r
CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRoutingProtocol;\r
\r
+EFI_STATUS\r
+RegisterUefiHiiHandle (\r
+ EFI_HII_THUNK_PRIVATE_DATA *Private,\r
+ EFI_HII_HANDLE UefiHiiHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_GUID PackageGuid;\r
+ HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMappingEntry;\r
+\r
+ HandleMappingEntry = AllocateZeroPool (sizeof (*HandleMappingEntry));\r
+ HandleMappingEntry->Signature = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_SIGNATURE;\r
+\r
+ Status = AssignPureUefiHiiHandle (Private, &HandleMappingEntry->FrameworkHiiHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ \r
+ HandleMappingEntry->UefiHiiHandle = UefiHiiHandle;\r
+ Status = HiiLibExtractGuidFromHiiHandle (UefiHiiHandle, &PackageGuid);\r
+ ASSERT_EFI_ERROR (Status);\r
+ \r
+ CopyGuid(&HandleMappingEntry->TagGuid, &PackageGuid);\r
+ \r
+ InsertTailList (&Private->HiiThunkHandleMappingDBListHead, &HandleMappingEntry->List);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+UnRegisterUefiHiiHandle (\r
+ EFI_HII_THUNK_PRIVATE_DATA *Private,\r
+ EFI_HII_HANDLE UefiHiiHandle\r
+ )\r
+{\r
+ HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *MapEntry;\r
+\r
+ MapEntry = UefiHiiHandleToMapDatabaseEntry (Private, UefiHiiHandle);\r
+ ASSERT (MapEntry != NULL);\r
+ \r
+ RemoveEntryList (&MapEntry->List);\r
+\r
+ FreePool (MapEntry);\r
+ \r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AddPackNotify (\r
+ IN UINT8 PackageType,\r
+ IN CONST EFI_GUID *PackageGuid,\r
+ IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
+ IN EFI_HII_HANDLE Handle,\r
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_THUNK_PRIVATE_DATA *Private;\r
+\r
+ ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS);\r
+ ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK);\r
+\r
+ Status = EFI_SUCCESS;\r
+ Private = mHiiThunkPrivateData;\r
+\r
+ //\r
+ // We only create a MapEntry if the Uefi Hii Handle is only already registered\r
+ // by the HII Thunk Layer.\r
+ //\r
+ if (UefiHiiHandleToMapDatabaseEntry (Private, Handle) == NULL) {\r
+ Status = RegisterUefiHiiHandle (Private, Handle);\r
+ } \r
+\r
+ return Status; \r
+}\r
+EFI_STATUS\r
+EFIAPI\r
+NewPackNotify (\r
+ IN UINT8 PackageType,\r
+ IN CONST EFI_GUID *PackageGuid,\r
+ IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
+ IN EFI_HII_HANDLE Handle,\r
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_THUNK_PRIVATE_DATA *Private;\r
+\r
+ ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS);\r
+ ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK);\r
+\r
+ if (mInFrameworkHiiNewPack) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ Status = EFI_SUCCESS;\r
+ Private = mHiiThunkPrivateData;\r
+\r
+ //\r
+ // We only\r
+ //\r
+ if (UefiHiiHandleToMapDatabaseEntry (Private, Handle) == NULL) {\r
+ Status = RegisterUefiHiiHandle (Private, Handle);\r
+ } \r
+\r
+ return Status;\r
+}\r
+\r
+BOOLEAN\r
+IsLastStringPack (\r
+ IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
+ IN EFI_HII_HANDLE Handle\r
+ )\r
+{\r
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
+ UINTN BufferSize;\r
+ EFI_STATUS Status;\r
+ EFI_HII_PACKAGE_HEADER *PackageHdrPtr;\r
+ EFI_HII_PACKAGE_HEADER PackageHeader;\r
+ BOOLEAN Match;\r
+\r
+ Match = FALSE;\r
+ HiiPackageList = NULL;\r
+ BufferSize = 0;\r
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
+ ASSERT (Status != EFI_NOT_FOUND);\r
+ \r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ HiiPackageList = AllocateZeroPool (BufferSize);\r
+ ASSERT (HiiPackageList != NULL);\r
+\r
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
+ }\r
+\r
+ \r
+ PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) HiiPackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
+ CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ while (PackageHeader.Type != EFI_HII_PACKAGE_END) {\r
+ switch (PackageHeader.Type) {\r
+ case EFI_HII_PACKAGE_STRINGS:\r
+ if (CompareMem (Package, PackageHdrPtr, Package->Length) != 0) {\r
+ FreePool (HiiPackageList);\r
+ return FALSE;\r
+ }\r
+ break; \r
+ default:\r
+ break;\r
+ }\r
+ //\r
+ // goto header of next package\r
+ //\r
+ PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);\r
+ CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
+ }\r
+\r
+ FreePool (HiiPackageList);\r
+ return TRUE;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+RemovePackNotify (\r
+ IN UINT8 PackageType,\r
+ IN CONST EFI_GUID *PackageGuid,\r
+ IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
+ IN EFI_HII_HANDLE Handle,\r
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_THUNK_PRIVATE_DATA *Private;\r
+ HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY * MapEntry;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS);\r
+ ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK);\r
+\r
+ Private = mHiiThunkPrivateData;\r
+\r
+ MapEntry = UefiHiiHandleToMapDatabaseEntry (Private, Handle);\r
+\r
+ if (MapEntry->FrameworkHiiHandle > Private->StaticHiiHandle) {\r
+ //\r
+ // This is a PackageList registered using UEFI HII Protocol Instance.\r
+ // The MapEntry->TagGuid for this type of PackageList is a auto generated GUID\r
+ // to link StringPack with IfrPack.\r
+ // RemovePackNotify is only used to remove PackageList when it is removed by\r
+ // calling mHiiDatabase->RemovePackageList interface.\r
+ if (IsLastStringPack (Package, Handle)) {\r
+ Status = UnRegisterUefiHiiHandle (Private, Handle);\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MapUefiHiiHandles (\r
+ EFI_HII_THUNK_PRIVATE_DATA *Private\r
+ )\r
+{\r
+ UINTN HandleBufferLength;\r
+ EFI_HII_HANDLE *HandleBuffer;\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY * MapEntry;\r
+\r
+ HandleBufferLength = 0;\r
+ HandleBuffer = NULL;\r
+ Status = mHiiDatabase->ListPackageLists (\r
+ mHiiDatabase,\r
+ EFI_HII_PACKAGE_TYPE_ALL,\r
+ NULL,\r
+ &HandleBufferLength,\r
+ HandleBuffer\r
+ );\r
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {\r
+ return Status;\r
+ }\r
+\r
+ HandleBuffer = AllocateZeroPool (HandleBufferLength);\r
+ Status = mHiiDatabase->ListPackageLists (\r
+ mHiiDatabase,\r
+ EFI_HII_PACKAGE_TYPE_ALL,\r
+ NULL,\r
+ &HandleBufferLength,\r
+ HandleBuffer\r
+ );\r
+\r
+ for (Index = 0; Index < HandleBufferLength / sizeof (EFI_HII_HANDLE); Index++) {\r
+ MapEntry = UefiHiiHandleToMapDatabaseEntry (Private, HandleBuffer[Index]);\r
+ //\r
+ // Only register those UEFI HII Handles that are registered using the UEFI HII database interface.\r
+ //\r
+ if (MapEntry == NULL) {\r
+ Status = RegisterUefiHiiHandle (Private, HandleBuffer[Index]);\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS; \r
+}\r
\r
EFI_STATUS\r
EFIAPI\r
\r
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiHiiProtocolGuid);\r
\r
- HiiData = AllocateCopyPool (sizeof (EFI_HII_THUNK_PRIVATE_DATA), &HiiThunkPrivateDataTempate);\r
+ HiiData = AllocateCopyPool (sizeof (EFI_HII_THUNK_PRIVATE_DATA), &mHiiThunkPrivateDataTempate);\r
ASSERT (HiiData != NULL);\r
InitializeListHead (&HiiData->HiiThunkHandleMappingDBListHead);\r
\r
+ mHiiThunkPrivateData = HiiData;\r
+\r
Status = gBS->LocateProtocol (\r
&gEfiHiiDatabaseProtocolGuid,\r
NULL,\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
+ Status = MapUefiHiiHandles (HiiData);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Status = mHiiDatabase->RegisterPackageNotify (\r
+ mHiiDatabase,\r
+ EFI_HII_PACKAGE_STRINGS,\r
+ NULL,\r
+ NewPackNotify,\r
+ EFI_HII_DATABASE_NOTIFY_NEW_PACK,\r
+ &HiiData->NewPackNotifyHandle\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Status = mHiiDatabase->RegisterPackageNotify (\r
+ mHiiDatabase,\r
+ EFI_HII_PACKAGE_STRINGS,\r
+ NULL,\r
+ AddPackNotify,\r
+ EFI_HII_DATABASE_NOTIFY_ADD_PACK,\r
+ &HiiData->AddPackNotifyHandle\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Status = mHiiDatabase->RegisterPackageNotify (\r
+ mHiiDatabase,\r
+ EFI_HII_PACKAGE_STRINGS,\r
+ NULL,\r
+ RemovePackNotify,\r
+ EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
+ &HiiData->RemovePackNotifyHandle\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
return Status;\r
}\r
\r
\r
--*/\r
{\r
- ASSERT (FALSE);\r
+ UINT16 Count;\r
+ LIST_ENTRY *ListEntry;\r
+ HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
+ EFI_HII_THUNK_PRIVATE_DATA *Private;\r
+\r
+ if (HandleBufferLength == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This); \r
+\r
+ Count = 0;\r
+ for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;\r
+ ListEntry != &Private->HiiThunkHandleMappingDBListHead;\r
+ ListEntry = ListEntry->ForwardLink\r
+ ) {\r
+ Count++;\r
+ }\r
+\r
+ if (Count > *HandleBufferLength) {\r
+ *HandleBufferLength = (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE));\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ Count = 0;\r
+ for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;\r
+ ListEntry != &Private->HiiThunkHandleMappingDBListHead;\r
+ ListEntry = ListEntry->ForwardLink\r
+ ) {\r
+ HandleMapEntry = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry);\r
+\r
+ Handle[Count] = HandleMapEntry->FrameworkHiiHandle;\r
+ \r
+ Count++;\r
+ } \r
+\r
+ *HandleBufferLength = (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE));\r
return EFI_SUCCESS;\r
}\r
\r
HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
EFI_STRING_ID StringId1;\r
EFI_STRING_ID StringId2;\r
- CHAR8 *UefiStringProtocolLanguage;\r
+ CHAR8 *AsciiLanguage;\r
BOOLEAN Found;\r
\r
ASSERT (TagGuid != NULL);\r
StringId2 = (EFI_STRING_ID) 0;\r
Found = FALSE;\r
\r
- //\r
- // BugBug: We will handle the case that Language is not NULL later.\r
- //\r
- ASSERT (Language == NULL);\r
- \r
- //if (Language == NULL) {\r
- UefiStringProtocolLanguage = NULL;\r
- //}\r
+ if (Language == NULL) {\r
+ AsciiLanguage = NULL;\r
+ } else {\r
+ AsciiLanguage = AllocateZeroPool (StrLen (Language) + 1);\r
+ UnicodeStrToAsciiStr (Language, AsciiLanguage);\r
+ }\r
\r
for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;\r
ListEntry != &Private->HiiThunkHandleMappingDBListHead;\r
if (CompareGuid (TagGuid, &HandleMapEntry->TagGuid)) {\r
Found = TRUE;\r
if (*Reference == 0) {\r
- Status = HiiLibNewString (HandleMapEntry->UefiHiiHandle, &StringId2, NewString);\r
+ if (AsciiLanguage == NULL) {\r
+ Status = HiiLibNewString (HandleMapEntry->UefiHiiHandle, &StringId2, NewString);\r
+ } else {\r
+ Status = mHiiStringProtocol->NewString (\r
+ mHiiStringProtocol,\r
+ HandleMapEntry->UefiHiiHandle,\r
+ &StringId2,\r
+ AsciiLanguage,\r
+ NULL,\r
+ NewString,\r
+ NULL\r
+ );\r
+ }\r
} else {\r
- Status = HiiLibSetString (HandleMapEntry->UefiHiiHandle, *Reference, NewString);\r
+ if (AsciiLanguage == NULL) {\r
+ Status = HiiLibSetString (HandleMapEntry->UefiHiiHandle, *Reference, NewString);\r
+ } else {\r
+ Status = mHiiStringProtocol->SetString (\r
+ mHiiStringProtocol,\r
+ HandleMapEntry->UefiHiiHandle,\r
+ *Reference,\r
+ AsciiLanguage,\r
+ NewString,\r
+ NULL\r
+ );\r
+ }\r
}\r
if (EFI_ERROR (Status)) {\r
return Status;\r
//\r
// For UNI file, some String may not be defined for a language. This has been true for a lot of platform code.\r
// For this case, EFI_NOT_FOUND will be returned. To allow the old code to be run without porting, we don't assert \r
- // on EFI_NOT_FOUND. The missing String will be declared if user select differnt languages for the platform.\r
+ // on EFI_NOT_FOUND. The missing Strings will be shown if user select a differnt languages other than the default\r
+ // English language for the platform.\r
//\r
ASSERT_EFI_ERROR (EFI_ERROR (Status) && Status != EFI_NOT_FOUND); \r
\r
return EFI_UNSUPPORTED;\r
}\r
\r
+typedef struct {\r
+ CHAR8 *Iso639;\r
+ CHAR8 *Rfc3066;\r
+} ISO639TORFC3066MAP;\r
+\r
+ISO639TORFC3066MAP Iso639ToRfc3066Map [] = {\r
+ {"eng", "en-US"},\r
+ {"fra", "fr-FR"},\r
+};\r
+\r
+CHAR8 *\r
+Iso639ToRfc3066 (\r
+ CHAR8 *Iso638Lang\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ for (Index = 0; Index < sizeof (Iso639ToRfc3066Map) / sizeof (Iso639ToRfc3066Map[0]); Index++) {\r
+ if (AsciiStrnCmp (Iso638Lang, Iso639ToRfc3066Map[Index].Iso639, AsciiStrSize (Iso638Lang)) == 0) {\r
+ return Iso639ToRfc3066Map[Index].Rfc3066;\r
+ }\r
+ }\r
+\r
+ return (CHAR8 *) NULL;\r
+}\r
+\r
EFI_STATUS\r
EFIAPI\r
HiiGetString (\r
HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
CHAR8 *AsciiLanguage;\r
EFI_HII_THUNK_PRIVATE_DATA *Private;\r
+ CHAR8 *Rfc3066AsciiLanguage;\r
\r
Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
\r
return EFI_OUT_OF_RESOURCES;\r
}\r
UnicodeStrToAsciiStr (LanguageString, AsciiLanguage);\r
+\r
+ Rfc3066AsciiLanguage = Iso639ToRfc3066 (AsciiLanguage);\r
+ //\r
+ // Caller of Framework HII Interface uses the Language Identification String defined \r
+ // in Iso639. So map it to the Language Identifier defined in RFC3066.\r
+ //\r
+ if (Rfc3066AsciiLanguage != NULL) {\r
+ FreePool (AsciiLanguage);\r
+ AsciiLanguage = AllocateCopyPool (AsciiStrSize (Rfc3066AsciiLanguage), Rfc3066AsciiLanguage);\r
+ }\r
+ \r
}\r
\r
for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;\r