| /** @file | |
| HII Library implementation that uses DXE protocols and services. | |
| Copyright (c) 2006 - 2008, Intel Corporation<BR> | |
| All rights reserved. This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| **/ | |
| #include "InternalHiiLib.h" | |
| // | |
| // Lookup table of ISO639-2 3 character language codes to ISO 639-1 2 character language codes | |
| // Each entry is 5 CHAR8 values long. The first 3 CHAR8 values are the ISO 639-2 code. | |
| // The last 2 CHAR8 values are the ISO 639-1 code. | |
| // | |
| GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 Iso639ToRfc3066ConversionTable[] = | |
| "\ | |
| aaraa\ | |
| abkab\ | |
| afraf\ | |
| amham\ | |
| araar\ | |
| asmas\ | |
| aymay\ | |
| azeaz\ | |
| bakba\ | |
| belbe\ | |
| benbn\ | |
| bihbh\ | |
| bisbi\ | |
| bodbo\ | |
| brebr\ | |
| bulbg\ | |
| catca\ | |
| cescs\ | |
| corkw\ | |
| cosco\ | |
| cymcy\ | |
| danda\ | |
| deude\ | |
| dzodz\ | |
| ellel\ | |
| engen\ | |
| epoeo\ | |
| estet\ | |
| euseu\ | |
| faofo\ | |
| fasfa\ | |
| fijfj\ | |
| finfi\ | |
| frafr\ | |
| fryfy\ | |
| gaiga\ | |
| gdhgd\ | |
| glggl\ | |
| grngn\ | |
| gujgu\ | |
| hauha\ | |
| hebhe\ | |
| hinhi\ | |
| hrvhr\ | |
| hunhu\ | |
| hyehy\ | |
| ikuiu\ | |
| ileie\ | |
| inaia\ | |
| indid\ | |
| ipkik\ | |
| islis\ | |
| itait\ | |
| jawjw\ | |
| jpnja\ | |
| kalkl\ | |
| kankn\ | |
| kasks\ | |
| katka\ | |
| kazkk\ | |
| khmkm\ | |
| kinrw\ | |
| kirky\ | |
| korko\ | |
| kurku\ | |
| laolo\ | |
| latla\ | |
| lavlv\ | |
| linln\ | |
| litlt\ | |
| ltzlb\ | |
| malml\ | |
| marmr\ | |
| mkdmk\ | |
| mlgmg\ | |
| mltmt\ | |
| molmo\ | |
| monmn\ | |
| mrimi\ | |
| msams\ | |
| myamy\ | |
| nauna\ | |
| nepne\ | |
| nldnl\ | |
| norno\ | |
| ocioc\ | |
| ormom\ | |
| panpa\ | |
| polpl\ | |
| porpt\ | |
| pusps\ | |
| quequ\ | |
| rohrm\ | |
| ronro\ | |
| runrn\ | |
| rusru\ | |
| sagsg\ | |
| sansa\ | |
| sinsi\ | |
| slksk\ | |
| slvsl\ | |
| smise\ | |
| smosm\ | |
| snasn\ | |
| sndsd\ | |
| somso\ | |
| sotst\ | |
| spaes\ | |
| sqisq\ | |
| srpsr\ | |
| sswss\ | |
| sunsu\ | |
| swasw\ | |
| swesv\ | |
| tamta\ | |
| tattt\ | |
| telte\ | |
| tgktg\ | |
| tgltl\ | |
| thath\ | |
| tsnts\ | |
| tuktk\ | |
| twitw\ | |
| uigug\ | |
| ukruk\ | |
| urdur\ | |
| uzbuz\ | |
| vievi\ | |
| volvo\ | |
| wolwo\ | |
| xhoxh\ | |
| yidyi\ | |
| zhaza\ | |
| zhozh\ | |
| zulzu\ | |
| "; | |
| /** | |
| This function adds the string into String Package of each language | |
| supported by the package list. | |
| If String is NULL, then ASSERT. | |
| If StringId is NULL, the ASSERT. | |
| If PackageList could not be found in the default HII database, then ASSERT. | |
| @param PackageList Handle of the package list where this string will | |
| be added. | |
| @param StringId On return, contains the new strings id, which is | |
| unique within PackageList. | |
| @param String Points to the new null-terminated string. | |
| @retval EFI_SUCCESS The new string was added successfully. | |
| @retval EFI_OUT_OF_RESOURCES Could not add the string due to lack of resources. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| HiiLibNewString ( | |
| IN EFI_HII_HANDLE PackageList, | |
| OUT EFI_STRING_ID *StringId, | |
| IN CONST EFI_STRING String | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| CHAR8 *Languages; | |
| CHAR8 *LangStrings; | |
| CHAR8 Lang[RFC_3066_ENTRY_SIZE]; | |
| ASSERT (String != NULL); | |
| ASSERT (StringId != NULL); | |
| Status = EFI_SUCCESS; | |
| Languages = HiiLibGetSupportedLanguages (PackageList); | |
| ASSERT (Languages != NULL); | |
| LangStrings = Languages; | |
| while (*LangStrings != 0) { | |
| HiiLibGetNextLanguage (&LangStrings, Lang); | |
| // | |
| // For each language supported by the package, | |
| // a string token is created. | |
| // | |
| Status = mHiiStringProt->NewString ( | |
| mHiiStringProt, | |
| PackageList, | |
| StringId, | |
| Lang, | |
| NULL, | |
| String, | |
| NULL | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| break; | |
| } | |
| } | |
| FreePool (Languages); | |
| return Status; | |
| } | |
| /** | |
| This function update the specified string in String Package of each language | |
| supported by the package list. | |
| If String is NULL, then ASSERT. | |
| If PackageList could not be found in the default HII database, then ASSERT. | |
| If StringId is not found in PackageList, then ASSERT. | |
| @param PackageList Handle of the package list where this string will | |
| be added. | |
| @param StringId Ths String Id to be updated. | |
| @param String Points to the new null-terminated string. | |
| @retval EFI_SUCCESS The new string was added successfully. | |
| @retval EFI_OUT_OF_RESOURCES Could not add the string due to lack of resources. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| HiiLibSetString ( | |
| IN EFI_HII_HANDLE PackageList, | |
| IN EFI_STRING_ID StringId, | |
| IN CONST EFI_STRING String | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| CHAR8 *Languages; | |
| CHAR8 *LangStrings; | |
| CHAR8 Lang[RFC_3066_ENTRY_SIZE]; | |
| ASSERT (IsHiiHandleRegistered (PackageList)); | |
| Status = EFI_SUCCESS; | |
| Languages = HiiLibGetSupportedLanguages (PackageList); | |
| ASSERT (Languages != NULL); | |
| LangStrings = Languages; | |
| while (*LangStrings != 0) { | |
| HiiLibGetNextLanguage (&LangStrings, Lang); | |
| // | |
| // For each language supported by the package, | |
| // the string is updated. | |
| // | |
| Status = mHiiStringProt->SetString ( | |
| mHiiStringProt, | |
| PackageList, | |
| StringId, | |
| Lang, | |
| String, | |
| NULL | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| break; | |
| } | |
| } | |
| FreePool (Languages); | |
| return Status; | |
| } | |
| /** | |
| Get the string given the StringId and String package Producer's Guid. The caller | |
| is responsible to free the *String. | |
| If PackageList with the matching ProducerGuid is not found, then ASSERT. | |
| If PackageList with the matching ProducerGuid is found but no String is | |
| specified by StringId is found, then ASSERT. | |
| @param ProducerGuid The Guid of String package list. | |
| @param StringId The String ID. | |
| @param String The output string. | |
| @retval EFI_SUCCESS Operation is successful. | |
| @retval EFI_OUT_OF_RESOURCES There is not enought memory in the system. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| HiiLibGetStringFromToken ( | |
| IN EFI_GUID *ProducerGuid, | |
| IN EFI_STRING_ID StringId, | |
| OUT EFI_STRING *String | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| UINTN Index; | |
| UINTN HandleBufferLen; | |
| EFI_HII_HANDLE *HiiHandleBuffer; | |
| EFI_GUID Guid; | |
| Status = HiiLibGetHiiHandles (&HandleBufferLen, &HiiHandleBuffer); | |
| if (EFI_ERROR(Status)) { | |
| return Status; | |
| } | |
| for (Index = 0; Index < (HandleBufferLen / sizeof (EFI_HII_HANDLE)); Index++) { | |
| Status = HiiLibExtractGuidFromHiiHandle (HiiHandleBuffer[Index], &Guid); | |
| if (EFI_ERROR(Status)) { | |
| return Status; | |
| } | |
| if (CompareGuid (&Guid, ProducerGuid)) { | |
| break; | |
| } | |
| } | |
| if (Index >= (HandleBufferLen / sizeof (EFI_HII_HANDLE))) { | |
| // | |
| // If PackageList with the matching ProducerGuid is not found, then ASSERT. | |
| // | |
| ASSERT (FALSE); | |
| Status = EFI_NOT_FOUND; | |
| goto Out; | |
| } | |
| Status = HiiLibGetStringFromHandle (HiiHandleBuffer[Index], StringId, String); | |
| Out: | |
| if (HiiHandleBuffer != NULL) { | |
| FreePool (HiiHandleBuffer); | |
| } | |
| return Status; | |
| } | |
| /** | |
| This function try to retrieve string from String package of current language. | |
| If fails, it try to retrieve string from String package of first language it support. | |
| If StringSize is NULL, then ASSERT. | |
| If String is NULL and *StringSize is not 0, then ASSERT. | |
| If PackageList could not be found in the default HII database, then ASSERT. | |
| If StringId is not found in PackageList, then ASSERT. | |
| @param PackageList The package list in the HII database to search for | |
| the specified string. | |
| @param StringId The string's id, which is unique within | |
| PackageList. | |
| @param String Points to the new null-terminated string. | |
| @param StringSize On entry, points to the size of the buffer pointed | |
| to by String, in bytes. On return, points to the | |
| length of the string, in bytes. | |
| @retval EFI_SUCCESS The string was returned successfully. | |
| @retval EFI_NOT_FOUND The string specified by StringId is not available. | |
| @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringLength is too small | |
| to hold the string. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| HiiLibGetString ( | |
| IN EFI_HII_HANDLE PackageList, | |
| IN EFI_STRING_ID StringId, | |
| OUT EFI_STRING String, | |
| IN OUT UINTN *StringSize | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| CHAR8 *Languages; | |
| CHAR8 *LangStrings; | |
| CHAR8 Lang[RFC_3066_ENTRY_SIZE]; | |
| CHAR8 CurrentLang[RFC_3066_ENTRY_SIZE]; | |
| ASSERT (StringSize != NULL); | |
| ASSERT (!(*StringSize != 0 && String == NULL)); | |
| ASSERT (IsHiiHandleRegistered (PackageList)); | |
| GetCurrentLanguage (CurrentLang); | |
| Status = mHiiStringProt->GetString ( | |
| mHiiStringProt, | |
| CurrentLang, | |
| PackageList, | |
| StringId, | |
| String, | |
| StringSize, | |
| NULL | |
| ); | |
| if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) { | |
| Languages = HiiLibGetSupportedLanguages (PackageList); | |
| ASSERT (Languages != NULL); | |
| LangStrings = Languages; | |
| HiiLibGetNextLanguage (&LangStrings, Lang); | |
| FreePool (Languages); | |
| Status = mHiiStringProt->GetString ( | |
| mHiiStringProt, | |
| Lang, | |
| PackageList, | |
| StringId, | |
| String, | |
| StringSize, | |
| NULL | |
| ); | |
| } | |
| return Status; | |
| } | |
| /** | |
| Get string specified by StringId form the HiiHandle. The caller | |
| is responsible to free the *String. | |
| If String is NULL, then ASSERT. | |
| If HiiHandle could not be found in the default HII database, then ASSERT. | |
| If StringId is not found in PackageList, then ASSERT. | |
| @param HiiHandle The HII handle of package list. | |
| @param StringId The String ID. | |
| @param String The output string. | |
| @retval EFI_NOT_FOUND String is not found. | |
| @retval EFI_SUCCESS Operation is successful. | |
| @retval EFI_OUT_OF_RESOURCES There is not enought memory in the system. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| HiiLibGetStringFromHandle ( | |
| IN EFI_HII_HANDLE HiiHandle, | |
| IN EFI_STRING_ID StringId, | |
| OUT EFI_STRING *String | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| UINTN StringSize; | |
| ASSERT (String != NULL); | |
| StringSize = HII_LIB_DEFAULT_STRING_SIZE; | |
| *String = AllocateZeroPool (StringSize); | |
| if (*String == NULL) { | |
| return EFI_OUT_OF_RESOURCES; | |
| } | |
| Status = HiiLibGetString (HiiHandle, StringId, *String, &StringSize); | |
| if (Status == EFI_BUFFER_TOO_SMALL) { | |
| FreePool (*String); | |
| *String = AllocateZeroPool (StringSize); | |
| if (*String == NULL) { | |
| return EFI_OUT_OF_RESOURCES; | |
| } | |
| Status = HiiLibGetString (HiiHandle, StringId, *String, &StringSize); | |
| } | |
| return Status; | |
| } | |
| /** | |
| Convert language code from RFC3066 to ISO639-2. | |
| @param LanguageRfc3066 RFC3066 language code. | |
| @param LanguageIso639 ISO639-2 language code. | |
| @retval EFI_SUCCESS Language code converted. | |
| @retval EFI_NOT_FOUND Language code not found. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| ConvertRfc3066LanguageToIso639Language ( | |
| IN CHAR8 *LanguageRfc3066, | |
| OUT CHAR8 *LanguageIso639 | |
| ) | |
| { | |
| UINTN Index; | |
| if ((LanguageRfc3066[2] != '-') && (LanguageRfc3066[2] != 0)) { | |
| CopyMem (LanguageIso639, LanguageRfc3066, 3); | |
| return EFI_SUCCESS; | |
| } | |
| for (Index = 0; Iso639ToRfc3066ConversionTable[Index] != 0; Index += 5) { | |
| if (CompareMem (LanguageRfc3066, &Iso639ToRfc3066ConversionTable[Index + 3], 2) == 0) { | |
| CopyMem (LanguageIso639, &Iso639ToRfc3066ConversionTable[Index], 3); | |
| return EFI_SUCCESS; | |
| } | |
| } | |
| return EFI_NOT_FOUND; | |
| } | |
| /** | |
| Convert language code from ISO639-2 to RFC3066. | |
| LanguageIso639 contain a single ISO639-2 code such as | |
| "eng" or "fra". | |
| The LanguageRfc3066 must be a buffer large enough | |
| for RFC_3066_ENTRY_SIZE characters. | |
| If LanguageIso639 is NULL, then ASSERT. | |
| If LanguageRfc3066 is NULL, then ASSERT. | |
| @param LanguageIso639 ISO639-2 language code. | |
| @param LanguageRfc3066 RFC3066 language code. | |
| @retval EFI_SUCCESS Language code converted. | |
| @retval EFI_NOT_FOUND Language code not found. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| ConvertIso639LanguageToRfc3066Language ( | |
| IN CONST CHAR8 *LanguageIso639, | |
| OUT CHAR8 *LanguageRfc3066 | |
| ) | |
| { | |
| UINTN Index; | |
| for (Index = 0; Iso639ToRfc3066ConversionTable[Index] != 0; Index += 5) { | |
| if (CompareMem (LanguageIso639, &Iso639ToRfc3066ConversionTable[Index], 3) == 0) { | |
| CopyMem (LanguageRfc3066, &Iso639ToRfc3066ConversionTable[Index + 3], 2); | |
| return EFI_SUCCESS; | |
| } | |
| } | |
| return EFI_NOT_FOUND; | |
| } | |
| /** | |
| Convert language code list from RFC3066 to ISO639-2, e.g. "en-US;fr-FR" will | |
| be converted to "engfra". | |
| @param SupportedLanguages The RFC3066 language list. | |
| @return The ISO639-2 language list. | |
| **/ | |
| CHAR8 * | |
| EFIAPI | |
| Rfc3066ToIso639 ( | |
| CHAR8 *SupportedLanguages | |
| ) | |
| { | |
| CHAR8 *Languages; | |
| CHAR8 *ReturnValue; | |
| CHAR8 *LangCodes; | |
| CHAR8 LangRfc3066[RFC_3066_ENTRY_SIZE]; | |
| CHAR8 LangIso639[ISO_639_2_ENTRY_SIZE]; | |
| EFI_STATUS Status; | |
| ReturnValue = AllocateZeroPool (AsciiStrSize (SupportedLanguages)); | |
| if (ReturnValue == NULL) { | |
| return ReturnValue; | |
| } | |
| Languages = ReturnValue; | |
| LangCodes = SupportedLanguages; | |
| while (*LangCodes != 0) { | |
| HiiLibGetNextLanguage (&LangCodes, LangRfc3066); | |
| Status = ConvertRfc3066LanguageToIso639Language (LangRfc3066, LangIso639); | |
| if (!EFI_ERROR (Status)) { | |
| CopyMem (Languages, LangIso639, 3); | |
| Languages = Languages + 3; | |
| } | |
| } | |
| return ReturnValue; | |
| } | |