From ea58467bf78ef522e85912efec55c41f094b5a4b Mon Sep 17 00:00:00 2001 From: qwang12 Date: Wed, 7 May 2008 08:49:04 +0000 Subject: [PATCH] Add in supports for platform Setup module which is programmed using Framework HII interface. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5175 6f19259b-4bc3-4df7-8a09-765794883524 --- .../FrameworkHiiToUefiHiiThunk/Forms.c | 58 ++- .../FrameworkHiiToUefiHiiThunk/HiiDatabase.c | 335 +++++++++++++++++- .../FrameworkHiiToUefiHiiThunk/HiiDatabase.h | 9 +- .../FrameworkHiiToUefiHiiThunk/Package.c | 20 +- .../FrameworkHiiToUefiHiiThunk/Strings.c | 84 ++++- .../FrameworkHiiToUefiHiiThunk/Utility.c | 63 ++++ .../FrameworkHiiToUefiHiiThunk/Utility.h | 19 + 7 files changed, 567 insertions(+), 21 deletions(-) diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Forms.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Forms.c index 205eea604b..17f12a75eb 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Forms.c +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Forms.c @@ -42,6 +42,39 @@ Returns: return EFI_UNSUPPORTED; } +#pragma pack(push, 1) +typedef struct { + EFI_HII_PACK_HEADER PackageHeader; + FRAMEWORK_EFI_IFR_FORM_SET FormSet; + FRAMEWORK_EFI_IFR_END_FORM_SET EndFormSet; +} FRAMEWORK_HII_FORMSET_TEMPLATE; +#pragma pack(pop) + +FRAMEWORK_HII_FORMSET_TEMPLATE FormSetTemplate = { + { + sizeof (FRAMEWORK_HII_FORMSET_TEMPLATE), + EFI_HII_IFR + }, + { + { + FRAMEWORK_EFI_IFR_FORM_SET_OP, + sizeof (FRAMEWORK_EFI_IFR_FORM_SET) + }, + //Guid + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + FRAMEWORK_EFI_IFR_END_FORM_SET_OP, + sizeof (FRAMEWORK_EFI_IFR_END_FORM_SET) + } +}; + EFI_STATUS EFIAPI HiiGetForms ( @@ -87,8 +120,29 @@ Returns: --*/ { - ASSERT (FALSE); - return EFI_UNSUPPORTED; + EFI_HII_THUNK_PRIVATE_DATA *Private; + HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *MapEntry; + FRAMEWORK_HII_FORMSET_TEMPLATE *OutputFormSet; + + if (*BufferLengthTemp < sizeof(FRAMEWORK_HII_FORMSET_TEMPLATE)) { + *BufferLengthTemp = sizeof(FRAMEWORK_HII_FORMSET_TEMPLATE); + return EFI_BUFFER_TOO_SMALL; + } + + Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This); + + MapEntry = FrameworkHiiHandleToMapDatabaseEntry (Private, Handle); + + if (MapEntry == NULL) { + return EFI_NOT_FOUND; + } + + OutputFormSet = (FRAMEWORK_HII_FORMSET_TEMPLATE *) Buffer; + + CopyMem (OutputFormSet, &FormSetTemplate, sizeof (FRAMEWORK_HII_FORMSET_TEMPLATE)); + CopyMem (&OutputFormSet->FormSet.Guid, &MapEntry->TagGuid, sizeof (EFI_GUID)); + + return EFI_SUCCESS; } diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.c index 09c571dfaa..53863d8114 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.c +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.c @@ -15,8 +15,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "HiiDatabase.h" +EFI_HII_THUNK_PRIVATE_DATA *mHiiThunkPrivateData; -EFI_HII_THUNK_PRIVATE_DATA HiiThunkPrivateDataTempate = { +EFI_HII_THUNK_PRIVATE_DATA mHiiThunkPrivateDataTempate = { {//Signature EFI_HII_THUNK_DRIVER_DATA_SIGNATURE }, @@ -47,10 +48,16 @@ EFI_HII_THUNK_PRIVATE_DATA HiiThunkPrivateDataTempate = { }, { //StaticHiiHandle //The FRAMEWORK_EFI_HII_HANDLE starts from 1 - // and increase upwords untill reach 2^(sizeof (FRAMEWORK_EFI_HII_HANDLE)) - 1. + // and increase upwords untill reach the value of StaticPureUefiHiiHandle. // The code will assert to prevent overflow. (FRAMEWORK_EFI_HII_HANDLE) 1 }, + { //StaticPureUefiHiiHandle + //The Static FRAMEWORK_EFI_HII_HANDLE starts from 0xFFFF + // and decrease downwords untill reach the value of StaticHiiHandle. + // The code will assert to prevent overflow. + (FRAMEWORK_EFI_HII_HANDLE) 0xFFFF + }, { NULL, NULL //HiiHandleLinkList }, @@ -62,6 +69,255 @@ CONST EFI_HII_IMAGE_PROTOCOL *mHiiImageProtocol; CONST EFI_HII_STRING_PROTOCOL *mHiiStringProtocol; CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRoutingProtocol; +EFI_STATUS +RegisterUefiHiiHandle ( + EFI_HII_THUNK_PRIVATE_DATA *Private, + EFI_HII_HANDLE UefiHiiHandle + ) +{ + EFI_STATUS Status; + EFI_GUID PackageGuid; + HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMappingEntry; + + HandleMappingEntry = AllocateZeroPool (sizeof (*HandleMappingEntry)); + HandleMappingEntry->Signature = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_SIGNATURE; + + Status = AssignPureUefiHiiHandle (Private, &HandleMappingEntry->FrameworkHiiHandle); + if (EFI_ERROR (Status)) { + return Status; + } + + HandleMappingEntry->UefiHiiHandle = UefiHiiHandle; + Status = HiiLibExtractGuidFromHiiHandle (UefiHiiHandle, &PackageGuid); + ASSERT_EFI_ERROR (Status); + + CopyGuid(&HandleMappingEntry->TagGuid, &PackageGuid); + + InsertTailList (&Private->HiiThunkHandleMappingDBListHead, &HandleMappingEntry->List); + + return EFI_SUCCESS; +} + + +EFI_STATUS +UnRegisterUefiHiiHandle ( + EFI_HII_THUNK_PRIVATE_DATA *Private, + EFI_HII_HANDLE UefiHiiHandle + ) +{ + HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *MapEntry; + + MapEntry = UefiHiiHandleToMapDatabaseEntry (Private, UefiHiiHandle); + ASSERT (MapEntry != NULL); + + RemoveEntryList (&MapEntry->List); + + FreePool (MapEntry); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +AddPackNotify ( + IN UINT8 PackageType, + IN CONST EFI_GUID *PackageGuid, + IN CONST EFI_HII_PACKAGE_HEADER *Package, + IN EFI_HII_HANDLE Handle, + IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType + ) +{ + EFI_STATUS Status; + EFI_HII_THUNK_PRIVATE_DATA *Private; + + ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS); + ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK); + + Status = EFI_SUCCESS; + Private = mHiiThunkPrivateData; + + // + // We only create a MapEntry if the Uefi Hii Handle is only already registered + // by the HII Thunk Layer. + // + if (UefiHiiHandleToMapDatabaseEntry (Private, Handle) == NULL) { + Status = RegisterUefiHiiHandle (Private, Handle); + } + + return Status; +} +EFI_STATUS +EFIAPI +NewPackNotify ( + IN UINT8 PackageType, + IN CONST EFI_GUID *PackageGuid, + IN CONST EFI_HII_PACKAGE_HEADER *Package, + IN EFI_HII_HANDLE Handle, + IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType + ) +{ + EFI_STATUS Status; + EFI_HII_THUNK_PRIVATE_DATA *Private; + + ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS); + ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK); + + if (mInFrameworkHiiNewPack) { + return EFI_SUCCESS; + } + + Status = EFI_SUCCESS; + Private = mHiiThunkPrivateData; + + // + // We only + // + if (UefiHiiHandleToMapDatabaseEntry (Private, Handle) == NULL) { + Status = RegisterUefiHiiHandle (Private, Handle); + } + + return Status; +} + +BOOLEAN +IsLastStringPack ( + IN CONST EFI_HII_PACKAGE_HEADER *Package, + IN EFI_HII_HANDLE Handle + ) +{ + EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList; + UINTN BufferSize; + EFI_STATUS Status; + EFI_HII_PACKAGE_HEADER *PackageHdrPtr; + EFI_HII_PACKAGE_HEADER PackageHeader; + BOOLEAN Match; + + Match = FALSE; + HiiPackageList = NULL; + BufferSize = 0; + Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList); + ASSERT (Status != EFI_NOT_FOUND); + + if (Status == EFI_BUFFER_TOO_SMALL) { + HiiPackageList = AllocateZeroPool (BufferSize); + ASSERT (HiiPackageList != NULL); + + Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList); + } + + + PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) HiiPackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER)); + CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER)); + + Status = EFI_SUCCESS; + + while (PackageHeader.Type != EFI_HII_PACKAGE_END) { + switch (PackageHeader.Type) { + case EFI_HII_PACKAGE_STRINGS: + if (CompareMem (Package, PackageHdrPtr, Package->Length) != 0) { + FreePool (HiiPackageList); + return FALSE; + } + break; + default: + break; + } + // + // goto header of next package + // + PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length); + CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER)); + } + + FreePool (HiiPackageList); + return TRUE; +} + +EFI_STATUS +EFIAPI +RemovePackNotify ( + IN UINT8 PackageType, + IN CONST EFI_GUID *PackageGuid, + IN CONST EFI_HII_PACKAGE_HEADER *Package, + IN EFI_HII_HANDLE Handle, + IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType + ) +{ + EFI_STATUS Status; + EFI_HII_THUNK_PRIVATE_DATA *Private; + HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY * MapEntry; + + Status = EFI_SUCCESS; + + ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS); + ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK); + + Private = mHiiThunkPrivateData; + + MapEntry = UefiHiiHandleToMapDatabaseEntry (Private, Handle); + + if (MapEntry->FrameworkHiiHandle > Private->StaticHiiHandle) { + // + // This is a PackageList registered using UEFI HII Protocol Instance. + // The MapEntry->TagGuid for this type of PackageList is a auto generated GUID + // to link StringPack with IfrPack. + // RemovePackNotify is only used to remove PackageList when it is removed by + // calling mHiiDatabase->RemovePackageList interface. + if (IsLastStringPack (Package, Handle)) { + Status = UnRegisterUefiHiiHandle (Private, Handle); + } + } + + return Status; +} + +EFI_STATUS +EFIAPI +MapUefiHiiHandles ( + EFI_HII_THUNK_PRIVATE_DATA *Private + ) +{ + UINTN HandleBufferLength; + EFI_HII_HANDLE *HandleBuffer; + EFI_STATUS Status; + UINTN Index; + HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY * MapEntry; + + HandleBufferLength = 0; + HandleBuffer = NULL; + Status = mHiiDatabase->ListPackageLists ( + mHiiDatabase, + EFI_HII_PACKAGE_TYPE_ALL, + NULL, + &HandleBufferLength, + HandleBuffer + ); + if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) { + return Status; + } + + HandleBuffer = AllocateZeroPool (HandleBufferLength); + Status = mHiiDatabase->ListPackageLists ( + mHiiDatabase, + EFI_HII_PACKAGE_TYPE_ALL, + NULL, + &HandleBufferLength, + HandleBuffer + ); + + for (Index = 0; Index < HandleBufferLength / sizeof (EFI_HII_HANDLE); Index++) { + MapEntry = UefiHiiHandleToMapDatabaseEntry (Private, HandleBuffer[Index]); + // + // Only register those UEFI HII Handles that are registered using the UEFI HII database interface. + // + if (MapEntry == NULL) { + Status = RegisterUefiHiiHandle (Private, HandleBuffer[Index]); + ASSERT_EFI_ERROR (Status); + } + } + + return EFI_SUCCESS; +} EFI_STATUS EFIAPI @@ -89,10 +345,12 @@ Returns: ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiHiiProtocolGuid); - HiiData = AllocateCopyPool (sizeof (EFI_HII_THUNK_PRIVATE_DATA), &HiiThunkPrivateDataTempate); + HiiData = AllocateCopyPool (sizeof (EFI_HII_THUNK_PRIVATE_DATA), &mHiiThunkPrivateDataTempate); ASSERT (HiiData != NULL); InitializeListHead (&HiiData->HiiThunkHandleMappingDBListHead); + mHiiThunkPrivateData = HiiData; + Status = gBS->LocateProtocol ( &gEfiHiiDatabaseProtocolGuid, NULL, @@ -140,6 +398,39 @@ Returns: ); ASSERT_EFI_ERROR (Status); + Status = MapUefiHiiHandles (HiiData); + ASSERT_EFI_ERROR (Status); + + Status = mHiiDatabase->RegisterPackageNotify ( + mHiiDatabase, + EFI_HII_PACKAGE_STRINGS, + NULL, + NewPackNotify, + EFI_HII_DATABASE_NOTIFY_NEW_PACK, + &HiiData->NewPackNotifyHandle + ); + ASSERT_EFI_ERROR (Status); + + Status = mHiiDatabase->RegisterPackageNotify ( + mHiiDatabase, + EFI_HII_PACKAGE_STRINGS, + NULL, + AddPackNotify, + EFI_HII_DATABASE_NOTIFY_ADD_PACK, + &HiiData->AddPackNotifyHandle + ); + ASSERT_EFI_ERROR (Status); + + Status = mHiiDatabase->RegisterPackageNotify ( + mHiiDatabase, + EFI_HII_PACKAGE_STRINGS, + NULL, + RemovePackNotify, + EFI_HII_DATABASE_NOTIFY_REMOVE_PACK, + &HiiData->RemovePackNotifyHandle + ); + ASSERT_EFI_ERROR (Status); + return Status; } @@ -161,7 +452,43 @@ Returns: --*/ { - ASSERT (FALSE); + UINT16 Count; + LIST_ENTRY *ListEntry; + HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry; + EFI_HII_THUNK_PRIVATE_DATA *Private; + + if (HandleBufferLength == NULL) { + return EFI_INVALID_PARAMETER; + } + + Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This); + + Count = 0; + for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink; + ListEntry != &Private->HiiThunkHandleMappingDBListHead; + ListEntry = ListEntry->ForwardLink + ) { + Count++; + } + + if (Count > *HandleBufferLength) { + *HandleBufferLength = (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE)); + return EFI_BUFFER_TOO_SMALL; + } + + Count = 0; + for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink; + ListEntry != &Private->HiiThunkHandleMappingDBListHead; + ListEntry = ListEntry->ForwardLink + ) { + HandleMapEntry = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry); + + Handle[Count] = HandleMapEntry->FrameworkHiiHandle; + + Count++; + } + + *HandleBufferLength = (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE)); return EFI_SUCCESS; } diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.h b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.h index 4ad9856141..64a8aeacaa 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.h +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.h @@ -74,13 +74,17 @@ typedef struct { EFI_HANDLE Handle; EFI_HII_PROTOCOL Hii; FRAMEWORK_EFI_HII_HANDLE StaticHiiHandle; + FRAMEWORK_EFI_HII_HANDLE StaticPureUefiHiiHandle; // // This LIST_ENTRY is the list head which has HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY type // as list entry. // LIST_ENTRY HiiThunkHandleMappingDBListHead; - + + EFI_HANDLE NewPackNotifyHandle; + EFI_HANDLE RemovePackNotifyHandle; + EFI_HANDLE AddPackNotifyHandle; } EFI_HII_THUNK_PRIVATE_DATA; @@ -146,6 +150,9 @@ extern CONST EFI_HII_IMAGE_PROTOCOL *mHiiImageProtocol; extern CONST EFI_HII_STRING_PROTOCOL *mHiiStringProtocol; extern CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRoutingProtocol; +extern BOOLEAN mInFrameworkHiiNewPack; + + // // Prototypes // diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Package.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Package.c index a1370eae35..9624e377f4 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Package.c +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Package.c @@ -327,6 +327,7 @@ UefiRegisterPackageList( EFI_HANDLE UefiHiiDriverHandle; UefiHiiDriverHandle = NULL; + UefiPackageListHeader = NULL; Status = GetIfrAndStringPackNum (Packages, &IfrPackNum, &StringPackNum); ASSERT_EFI_ERROR (Status); @@ -342,7 +343,10 @@ UefiRegisterPackageList( ASSERT (HandleMappingEntry != NULL); HandleMappingEntry->Signature = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_SIGNATURE; - HandleMappingEntry->FrameworkHiiHandle = Private->StaticHiiHandle++; + Status = AssignHiiHandle (Private, &HandleMappingEntry->FrameworkHiiHandle); + if (EFI_ERROR (Status)) { + goto Done; + } // // Packages->GuidId may be NULL. In such case, caller of FramworkHii->NewPack is registering @@ -429,11 +433,13 @@ Done: *Handle = HandleMappingEntry->FrameworkHiiHandle; } - FreePool (UefiPackageListHeader); + SafeFreePool (UefiPackageListHeader); return Status; } +BOOLEAN mInFrameworkHiiNewPack = FALSE; + EFI_STATUS EFIAPI HiiNewPack ( @@ -471,6 +477,14 @@ Returns: return EFI_INVALID_PARAMETER; } + // + // We use a simple Global variable to inform NewPackNotify + // that the package list registered here is already registered + // in the HII Thunk Layer. So NewPackNotify does not need to + // call RegisterUefiHiiHandle () to registered it. + // + mInFrameworkHiiNewPack = TRUE; + Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This); Status = UefiRegisterPackageList ( @@ -479,6 +493,8 @@ Returns: Handle ); + mInFrameworkHiiNewPack = FALSE; + return Status; } diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Strings.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Strings.c index 6907718b33..06f3f1c309 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Strings.c +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Strings.c @@ -81,7 +81,7 @@ HiiThunkNewStringForAllStringPackages ( HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry; EFI_STRING_ID StringId1; EFI_STRING_ID StringId2; - CHAR8 *UefiStringProtocolLanguage; + CHAR8 *AsciiLanguage; BOOLEAN Found; ASSERT (TagGuid != NULL); @@ -90,14 +90,12 @@ HiiThunkNewStringForAllStringPackages ( StringId2 = (EFI_STRING_ID) 0; Found = FALSE; - // - // BugBug: We will handle the case that Language is not NULL later. - // - ASSERT (Language == NULL); - - //if (Language == NULL) { - UefiStringProtocolLanguage = NULL; - //} + if (Language == NULL) { + AsciiLanguage = NULL; + } else { + AsciiLanguage = AllocateZeroPool (StrLen (Language) + 1); + UnicodeStrToAsciiStr (Language, AsciiLanguage); + } for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink; ListEntry != &Private->HiiThunkHandleMappingDBListHead; @@ -109,9 +107,32 @@ HiiThunkNewStringForAllStringPackages ( if (CompareGuid (TagGuid, &HandleMapEntry->TagGuid)) { Found = TRUE; if (*Reference == 0) { - Status = HiiLibNewString (HandleMapEntry->UefiHiiHandle, &StringId2, NewString); + if (AsciiLanguage == NULL) { + Status = HiiLibNewString (HandleMapEntry->UefiHiiHandle, &StringId2, NewString); + } else { + Status = mHiiStringProtocol->NewString ( + mHiiStringProtocol, + HandleMapEntry->UefiHiiHandle, + &StringId2, + AsciiLanguage, + NULL, + NewString, + NULL + ); + } } else { - Status = HiiLibSetString (HandleMapEntry->UefiHiiHandle, *Reference, NewString); + if (AsciiLanguage == NULL) { + Status = HiiLibSetString (HandleMapEntry->UefiHiiHandle, *Reference, NewString); + } else { + Status = mHiiStringProtocol->SetString ( + mHiiStringProtocol, + HandleMapEntry->UefiHiiHandle, + *Reference, + AsciiLanguage, + NewString, + NULL + ); + } } if (EFI_ERROR (Status)) { return Status; @@ -177,7 +198,8 @@ Returns: // // For UNI file, some String may not be defined for a language. This has been true for a lot of platform code. // For this case, EFI_NOT_FOUND will be returned. To allow the old code to be run without porting, we don't assert - // on EFI_NOT_FOUND. The missing String will be declared if user select differnt languages for the platform. + // on EFI_NOT_FOUND. The missing Strings will be shown if user select a differnt languages other than the default + // English language for the platform. // ASSERT_EFI_ERROR (EFI_ERROR (Status) && Status != EFI_NOT_FOUND); @@ -206,6 +228,32 @@ Returns: return EFI_UNSUPPORTED; } +typedef struct { + CHAR8 *Iso639; + CHAR8 *Rfc3066; +} ISO639TORFC3066MAP; + +ISO639TORFC3066MAP Iso639ToRfc3066Map [] = { + {"eng", "en-US"}, + {"fra", "fr-FR"}, +}; + +CHAR8 * +Iso639ToRfc3066 ( + CHAR8 *Iso638Lang + ) +{ + UINTN Index; + + for (Index = 0; Index < sizeof (Iso639ToRfc3066Map) / sizeof (Iso639ToRfc3066Map[0]); Index++) { + if (AsciiStrnCmp (Iso638Lang, Iso639ToRfc3066Map[Index].Iso639, AsciiStrSize (Iso638Lang)) == 0) { + return Iso639ToRfc3066Map[Index].Rfc3066; + } + } + + return (CHAR8 *) NULL; +} + EFI_STATUS EFIAPI HiiGetString ( @@ -249,6 +297,7 @@ Returns: HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry; CHAR8 *AsciiLanguage; EFI_HII_THUNK_PRIVATE_DATA *Private; + CHAR8 *Rfc3066AsciiLanguage; Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This); @@ -260,6 +309,17 @@ Returns: return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStr (LanguageString, AsciiLanguage); + + Rfc3066AsciiLanguage = Iso639ToRfc3066 (AsciiLanguage); + // + // Caller of Framework HII Interface uses the Language Identification String defined + // in Iso639. So map it to the Language Identifier defined in RFC3066. + // + if (Rfc3066AsciiLanguage != NULL) { + FreePool (AsciiLanguage); + AsciiLanguage = AllocateCopyPool (AsciiStrSize (Rfc3066AsciiLanguage), Rfc3066AsciiLanguage); + } + } for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink; diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Utility.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Utility.c index bc5e1ce126..03da20eb0d 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Utility.c +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Utility.c @@ -83,6 +83,28 @@ FrameworkHiiHandleToMapDatabaseEntry ( return (HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *) NULL; } +HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY * +UefiHiiHandleToMapDatabaseEntry ( + IN CONST EFI_HII_THUNK_PRIVATE_DATA *Private, + IN EFI_HII_HANDLE UefiHiiHandle + ) +{ + LIST_ENTRY *ListEntry; + HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry; + + for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink; + ListEntry != &Private->HiiThunkHandleMappingDBListHead; + ListEntry = ListEntry->ForwardLink + ) { + HandleMapEntry = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry); + + if (UefiHiiHandle == HandleMapEntry->UefiHiiHandle) { + return HandleMapEntry; + } + } + + return (HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *) NULL; +} EFI_HII_HANDLE * TagGuidToUefiIfrHiiHandle ( @@ -108,7 +130,48 @@ TagGuidToUefiIfrHiiHandle ( } +BOOLEAN +IsFrameworkHiiDatabaseHandleDepleted ( + IN CONST EFI_HII_THUNK_PRIVATE_DATA *Private + ) +{ + return (BOOLEAN) (Private->StaticHiiHandle == (UINTN) Private->StaticPureUefiHiiHandle); +} +EFI_STATUS +AssignHiiHandle ( + IN OUT EFI_HII_THUNK_PRIVATE_DATA *Private, + OUT FRAMEWORK_EFI_HII_HANDLE *Handle + ) +{ + ASSERT (Handle != NULL); + *Handle = Private->StaticHiiHandle; + Private->StaticHiiHandle += 1; + + if (IsFrameworkHiiDatabaseHandleDepleted (Private)) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +AssignPureUefiHiiHandle ( + IN OUT EFI_HII_THUNK_PRIVATE_DATA *Private, + OUT FRAMEWORK_EFI_HII_HANDLE *Handle + ) +{ + ASSERT (Handle != NULL); + + *Handle = Private->StaticPureUefiHiiHandle; + Private->StaticPureUefiHiiHandle -= 1; + + if (IsFrameworkHiiDatabaseHandleDepleted (Private)) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Utility.h b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Utility.h index 7426edfb9d..5504cc5267 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Utility.h +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Utility.h @@ -46,6 +46,12 @@ FrameworkHiiHandleToMapDatabaseEntry ( ) ; +HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY * +UefiHiiHandleToMapDatabaseEntry ( + IN CONST EFI_HII_THUNK_PRIVATE_DATA *Private, + IN EFI_HII_HANDLE UefiHiiHandle + ) +; EFI_HII_HANDLE * TagGuidToUefiIfrHiiHandle ( @@ -54,4 +60,17 @@ TagGuidToUefiIfrHiiHandle ( ) ; +EFI_STATUS +AssignHiiHandle ( + IN OUT EFI_HII_THUNK_PRIVATE_DATA *Private, + OUT FRAMEWORK_EFI_HII_HANDLE *Handle + ) +; + +EFI_STATUS +AssignPureUefiHiiHandle ( + IN OUT EFI_HII_THUNK_PRIVATE_DATA *Private, + OUT FRAMEWORK_EFI_HII_HANDLE *Handle + ) +; #endif