Home | History | Annotate | Download | only in UefiEfiIfrSupportLib
      1 /*++
      2 
      3 Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
      4 This program and the accompanying materials
      5 are licensed and made available under the terms and conditions of the BSD License
      6 which accompanies this distribution.  The full text of the license may be found at
      7 http://opensource.org/licenses/bsd-license.php
      8 
      9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 Module Name:
     13 
     14   UefiIfrString.c
     15 
     16 Abstract:
     17 
     18   Common Library Routines to assist to handle String and Language.
     19 
     20 --*/
     21 
     22 #include "UefiIfrLibrary.h"
     23 
     24 //
     25 // Lookup table of ISO639-2 3 character language codes to ISO 639-1 2 character language codes
     26 // Each entry is 5 CHAR8 values long.  The first 3 CHAR8 values are the ISO 639-2 code.
     27 // The last 2 CHAR8 values are the ISO 639-1 code.
     28 //
     29 CHAR8 Iso639ToRfc3066ConversionTable[] =
     30 "\
     31 aaraa\
     32 abkab\
     33 afraf\
     34 amham\
     35 araar\
     36 asmas\
     37 aymay\
     38 azeaz\
     39 bakba\
     40 belbe\
     41 benbn\
     42 bihbh\
     43 bisbi\
     44 bodbo\
     45 brebr\
     46 bulbg\
     47 catca\
     48 cescs\
     49 corkw\
     50 cosco\
     51 cymcy\
     52 danda\
     53 deude\
     54 dzodz\
     55 ellel\
     56 engen\
     57 epoeo\
     58 estet\
     59 euseu\
     60 faofo\
     61 fasfa\
     62 fijfj\
     63 finfi\
     64 frafr\
     65 fryfy\
     66 gaiga\
     67 gdhgd\
     68 glggl\
     69 grngn\
     70 gujgu\
     71 hauha\
     72 hebhe\
     73 hinhi\
     74 hrvhr\
     75 hunhu\
     76 hyehy\
     77 ikuiu\
     78 ileie\
     79 inaia\
     80 indid\
     81 ipkik\
     82 islis\
     83 itait\
     84 jawjw\
     85 jpnja\
     86 kalkl\
     87 kankn\
     88 kasks\
     89 katka\
     90 kazkk\
     91 khmkm\
     92 kinrw\
     93 kirky\
     94 korko\
     95 kurku\
     96 laolo\
     97 latla\
     98 lavlv\
     99 linln\
    100 litlt\
    101 ltzlb\
    102 malml\
    103 marmr\
    104 mkdmk\
    105 mlgmg\
    106 mltmt\
    107 molmo\
    108 monmn\
    109 mrimi\
    110 msams\
    111 myamy\
    112 nauna\
    113 nepne\
    114 nldnl\
    115 norno\
    116 ocioc\
    117 ormom\
    118 panpa\
    119 polpl\
    120 porpt\
    121 pusps\
    122 quequ\
    123 rohrm\
    124 ronro\
    125 runrn\
    126 rusru\
    127 sagsg\
    128 sansa\
    129 sinsi\
    130 slksk\
    131 slvsl\
    132 smise\
    133 smosm\
    134 snasn\
    135 sndsd\
    136 somso\
    137 sotst\
    138 spaes\
    139 sqisq\
    140 srpsr\
    141 sswss\
    142 sunsu\
    143 swasw\
    144 swesv\
    145 tamta\
    146 tattt\
    147 telte\
    148 tgktg\
    149 tgltl\
    150 thath\
    151 tsnts\
    152 tuktk\
    153 twitw\
    154 uigug\
    155 ukruk\
    156 urdur\
    157 uzbuz\
    158 vievi\
    159 volvo\
    160 wolwo\
    161 xhoxh\
    162 yidyi\
    163 zhaza\
    164 zhozh\
    165 zulzu\
    166 ";
    167 
    168 EFI_STATUS
    169 ConvertRfc3066LanguageToIso639Language (
    170   CHAR8   *LanguageRfc3066,
    171   CHAR8   *LanguageIso639
    172   )
    173 /*++
    174 
    175 Routine Description:
    176   Convert language code from RFC3066 to ISO639-2.
    177 
    178 Arguments:
    179   LanguageRfc3066 - RFC3066 language code.
    180   LanguageIso639  - ISO639-2 language code.
    181 
    182 Returns:
    183   EFI_SUCCESS   - Language code converted.
    184   EFI_NOT_FOUND - Language code not found.
    185 
    186 --*/
    187 {
    188   UINTN  Index;
    189 
    190   if ((LanguageRfc3066[2] != '-') && (LanguageRfc3066[2] != 0)) {
    191     EfiCopyMem (LanguageIso639, LanguageRfc3066, 3);
    192     return EFI_SUCCESS;
    193   }
    194 
    195   for (Index = 0; Iso639ToRfc3066ConversionTable[Index] != 0; Index += 5) {
    196     if (EfiCompareMem (LanguageRfc3066, &Iso639ToRfc3066ConversionTable[Index + 3], 2) == 0) {
    197       EfiCopyMem (LanguageIso639, &Iso639ToRfc3066ConversionTable[Index], 3);
    198       return EFI_SUCCESS;
    199     }
    200   }
    201 
    202   return EFI_NOT_FOUND;
    203 }
    204 
    205 CHAR8 *
    206 Rfc3066ToIso639 (
    207   CHAR8  *SupportedLanguages
    208   )
    209 /*++
    210 
    211 Routine Description:
    212   Convert language code list from RFC3066 to ISO639-2, e.g. "en-US;fr-FR" will
    213   be converted to "engfra".
    214 
    215 Arguments:
    216   SupportedLanguages - The RFC3066 language list.
    217 
    218 Returns:
    219   The ISO639-2 language list.
    220 
    221 --*/
    222 {
    223   CHAR8       *Languages;
    224   CHAR8       *ReturnValue;
    225   CHAR8       *LangCodes;
    226   CHAR8       LangRfc3066[RFC_3066_ENTRY_SIZE];
    227   CHAR8       LangIso639[ISO_639_2_ENTRY_SIZE];
    228   EFI_STATUS  Status;
    229 
    230   ReturnValue = EfiLibAllocateZeroPool (EfiAsciiStrSize (SupportedLanguages));
    231   if (ReturnValue == NULL) {
    232     return ReturnValue;
    233   }
    234 
    235   Languages = ReturnValue;
    236   LangCodes = SupportedLanguages;
    237   while (*LangCodes != 0) {
    238     GetNextLanguage (&LangCodes, LangRfc3066);
    239 
    240     Status = ConvertRfc3066LanguageToIso639Language (LangRfc3066, LangIso639);
    241     if (!EFI_ERROR (Status)) {
    242       EfiCopyMem (Languages, LangIso639, 3);
    243       Languages = Languages + 3;
    244     }
    245   }
    246 
    247   return ReturnValue;
    248 }
    249 
    250 EFI_STATUS
    251 GetCurrentLanguage (
    252   OUT     CHAR8               *Lang
    253   )
    254 /*++
    255 
    256 Routine Description:
    257   Determine what is the current language setting
    258 
    259 Arguments:
    260   Lang      - Pointer of system language
    261 
    262 Returns:
    263   Status code
    264 
    265 --*/
    266 {
    267   EFI_STATUS  Status;
    268   UINTN       Size;
    269 
    270   //
    271   // Get current language setting
    272   //
    273   Size = RFC_3066_ENTRY_SIZE;
    274   Status = gRT->GetVariable (
    275                   L"PlatformLang",
    276                   &gEfiGlobalVariableGuid,
    277                   NULL,
    278                   &Size,
    279                   Lang
    280                   );
    281 
    282   if (EFI_ERROR (Status)) {
    283     EfiAsciiStrCpy (Lang, (CHAR8 *) "en-US");
    284   }
    285 
    286   return Status;
    287 }
    288 
    289 VOID
    290 GetNextLanguage (
    291   IN OUT CHAR8      **LangCode,
    292   OUT CHAR8         *Lang
    293   )
    294 /*++
    295 
    296 Routine Description:
    297   Get next language from language code list (with separator ';').
    298 
    299 Arguments:
    300   LangCode - On input: point to first language in the list. On output: point to
    301              next language in the list, or NULL if no more language in the list.
    302   Lang     - The first language in the list.
    303 
    304 Returns:
    305   None.
    306 
    307 --*/
    308 {
    309   UINTN  Index;
    310   CHAR8  *StringPtr;
    311 
    312   if (LangCode == NULL || *LangCode == NULL) {
    313     *Lang = 0;
    314     return;
    315   }
    316 
    317   Index = 0;
    318   StringPtr = *LangCode;
    319   while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {
    320     Index++;
    321   }
    322 
    323   EfiCopyMem (Lang, StringPtr, Index);
    324   Lang[Index] = 0;
    325 
    326   if (StringPtr[Index] == ';') {
    327     Index++;
    328   }
    329   *LangCode = StringPtr + Index;
    330 }
    331 
    332 CHAR8 *
    333 GetSupportedLanguages (
    334   IN EFI_HII_HANDLE           HiiHandle
    335   )
    336 /*++
    337 
    338 Routine Description:
    339   This function returns the list of supported languages, in the format specified
    340   in UEFI specification Appendix M.
    341 
    342 Arguments:
    343   HiiHandle  - The HII package list handle.
    344 
    345 Returns:
    346   The supported languages.
    347 
    348 --*/
    349 {
    350   EFI_STATUS  Status;
    351   UINTN       BufferSize;
    352   CHAR8       *LanguageString;
    353 
    354   LocateHiiProtocols ();
    355 
    356   //
    357   // Collect current supported Languages for given HII handle
    358   //
    359   BufferSize = 0x1000;
    360   LanguageString = EfiLibAllocatePool (BufferSize);
    361   Status = gIfrLibHiiString->GetLanguages (gIfrLibHiiString, HiiHandle, LanguageString, &BufferSize);
    362   if (Status == EFI_BUFFER_TOO_SMALL) {
    363     gBS->FreePool (LanguageString);
    364     LanguageString = EfiLibAllocatePool (BufferSize);
    365     Status = gIfrLibHiiString->GetLanguages (gIfrLibHiiString, HiiHandle, LanguageString, &BufferSize);
    366   }
    367 
    368   if (EFI_ERROR (Status)) {
    369     LanguageString = NULL;
    370   }
    371 
    372   return LanguageString;
    373 }
    374 
    375 UINT16
    376 GetSupportedLanguageNumber (
    377   IN EFI_HII_HANDLE           HiiHandle
    378   )
    379 /*++
    380 
    381 Routine Description:
    382   This function returns the number of supported languages
    383 
    384 Arguments:
    385   HiiHandle  - The HII package list handle.
    386 
    387 Returns:
    388   The  number of supported languages.
    389 
    390 --*/
    391 {
    392   CHAR8   *Languages;
    393   CHAR8   *LanguageString;
    394   UINT16  LangNumber;
    395   CHAR8   Lang[RFC_3066_ENTRY_SIZE];
    396 
    397   Languages = GetSupportedLanguages (HiiHandle);
    398   if (Languages == NULL) {
    399     return 0;
    400   }
    401 
    402   LangNumber = 0;
    403   LanguageString = Languages;
    404   while (*LanguageString != 0) {
    405     GetNextLanguage (&LanguageString, Lang);
    406     LangNumber++;
    407   }
    408   gBS->FreePool (Languages);
    409 
    410   return LangNumber;
    411 }
    412 
    413 EFI_STATUS
    414 GetStringFromHandle (
    415   IN  EFI_HII_HANDLE                  HiiHandle,
    416   IN  EFI_STRING_ID                   StringId,
    417   OUT EFI_STRING                      *String
    418   )
    419 /*++
    420 
    421 Routine Description:
    422   Get string specified by StringId form the HiiHandle.
    423 
    424 Arguments:
    425   HiiHandle     - The HII handle of package list.
    426   StringId      - The String ID.
    427   String        - The output string.
    428 
    429 Returns:
    430   EFI_NOT_FOUND         - String is not found.
    431   EFI_SUCCESS           - Operation is successful.
    432   EFI_OUT_OF_RESOURCES  - There is not enought memory in the system.
    433   EFI_INVALID_PARAMETER - The String is NULL.
    434 
    435 --*/
    436 {
    437   EFI_STATUS                          Status;
    438   UINTN                               StringSize;
    439 
    440   if (String == NULL) {
    441     return EFI_INVALID_PARAMETER;
    442   }
    443 
    444   StringSize = IFR_LIB_DEFAULT_STRING_SIZE;
    445   *String    = EfiLibAllocateZeroPool (StringSize);
    446   if (*String == NULL) {
    447     return EFI_OUT_OF_RESOURCES;
    448   }
    449 
    450   Status = IfrLibGetString (HiiHandle, StringId, *String, &StringSize);
    451   if (Status == EFI_BUFFER_TOO_SMALL) {
    452     gBS->FreePool (*String);
    453     *String = EfiLibAllocateZeroPool (StringSize);
    454     if (*String == NULL) {
    455       return EFI_OUT_OF_RESOURCES;
    456     }
    457     Status = IfrLibGetString (HiiHandle, StringId, *String, &StringSize);
    458   }
    459 
    460   return Status;
    461 }
    462 
    463 EFI_STATUS
    464 GetStringFromToken (
    465   IN  EFI_GUID                        *ProducerGuid,
    466   IN  EFI_STRING_ID                   StringId,
    467   OUT EFI_STRING                      *String
    468   )
    469 /*++
    470 
    471 Routine Description:
    472   Get the string given the StringId and String package Producer's Guid.
    473 
    474 Arguments:
    475   ProducerGuid  - The Guid of String package list.
    476   StringId      - The String ID.
    477   String        - The output string.
    478 
    479 Returns:
    480   EFI_NOT_FOUND         - String is not found.
    481   EFI_SUCCESS           - Operation is successful.
    482   EFI_OUT_OF_RESOURCES  - There is not enought memory in the system.
    483 
    484 --*/
    485 {
    486   EFI_STATUS      Status;
    487   UINTN           Index;
    488   UINTN           HandleBufferLen;
    489   EFI_HII_HANDLE  *HiiHandleBuffer;
    490   EFI_GUID        Guid;
    491 
    492   HiiHandleBuffer = NULL;
    493   Status = GetHiiHandles (&HandleBufferLen, &HiiHandleBuffer);
    494   if (EFI_ERROR(Status)) {
    495     return Status;
    496   }
    497   for (Index = 0; Index < (HandleBufferLen / sizeof (EFI_HII_HANDLE)); Index++) {
    498     Status = ExtractGuidFromHiiHandle (HiiHandleBuffer[Index], &Guid);
    499     if (EFI_ERROR(Status)) {
    500       return Status;
    501     }
    502     if (EfiCompareGuid (&Guid, ProducerGuid) == TRUE) {
    503       break;
    504     }
    505   }
    506 
    507   if (Index >= (HandleBufferLen / sizeof (EFI_HII_HANDLE))) {
    508     Status = EFI_NOT_FOUND;
    509     goto Out;
    510   }
    511 
    512   Status = GetStringFromHandle (HiiHandleBuffer[Index], StringId, String);
    513 
    514 Out:
    515   if (HiiHandleBuffer != NULL) {
    516     gBS->FreePool (HiiHandleBuffer);
    517   }
    518   return Status;
    519 }
    520 
    521 EFI_STATUS
    522 IfrLibNewString (
    523   IN  EFI_HII_HANDLE                  PackageList,
    524   OUT EFI_STRING_ID                   *StringId,
    525   IN  CONST EFI_STRING                String
    526   )
    527 /*++
    528 
    529   Routine Description:
    530     This function adds the string into String Package of each language.
    531 
    532   Arguments:
    533     PackageList       - Handle of the package list where this string will be added.
    534     StringId          - On return, contains the new strings id, which is unique within PackageList.
    535     String            - Points to the new null-terminated string.
    536 
    537   Returns:
    538     EFI_SUCCESS            - The new string was added successfully.
    539     EFI_NOT_FOUND          - The specified PackageList could not be found in database.
    540     EFI_OUT_OF_RESOURCES   - Could not add the string due to lack of resources.
    541     EFI_INVALID_PARAMETER  - String is NULL or StringId is NULL is NULL.
    542 
    543 --*/
    544 {
    545   EFI_STATUS  Status;
    546   CHAR8       *Languages;
    547   CHAR8       *LangStrings;
    548   CHAR8       Lang[RFC_3066_ENTRY_SIZE];
    549 
    550   Status = EFI_SUCCESS;
    551 
    552   LocateHiiProtocols ();
    553 
    554   Languages = GetSupportedLanguages (PackageList);
    555   if (Languages == NULL) {
    556     return EFI_NOT_FOUND;
    557   }
    558 
    559   if (StringId == NULL) {
    560     return EFI_INVALID_PARAMETER;
    561   }
    562   *StringId = 0;
    563 
    564   LangStrings = Languages;
    565   while (*LangStrings != 0) {
    566     GetNextLanguage (&LangStrings, Lang);
    567 
    568     if (*StringId == 0) {
    569       Status = gIfrLibHiiString->NewString (
    570                                    gIfrLibHiiString,
    571                                    PackageList,
    572                                    StringId,
    573                                    Lang,
    574                                    NULL,
    575                                    String,
    576                                    NULL
    577                                    );
    578     } else {
    579       Status = gIfrLibHiiString->SetString (
    580                                    gIfrLibHiiString,
    581                                    PackageList,
    582                                    *StringId,
    583                                    Lang,
    584                                    String,
    585                                    NULL
    586                                    );
    587     }
    588 
    589     if (EFI_ERROR (Status)) {
    590       break;
    591     }
    592   }
    593 
    594   gBS->FreePool (Languages);
    595 
    596   return Status;
    597 }
    598 
    599 EFI_STATUS
    600 IfrLibGetString (
    601   IN  EFI_HII_HANDLE                  PackageList,
    602   IN  EFI_STRING_ID                   StringId,
    603   OUT EFI_STRING                      String,
    604   IN  OUT UINTN                       *StringSize
    605   )
    606 /*++
    607 
    608   Routine Description:
    609     This function try to retrieve string from String package of current language.
    610     If fail, it try to retrieve string from String package of first language it support.
    611 
    612   Arguments:
    613     PackageList       - The package list in the HII database to search for the specified string.
    614     StringId          - The string's id, which is unique within PackageList.
    615     String            - Points to the new null-terminated string.
    616     StringSize        - On entry, points to the size of the buffer pointed to by String, in bytes. On return,
    617                         points to the length of the string, in bytes.
    618 
    619   Returns:
    620     EFI_SUCCESS            - The string was returned successfully.
    621     EFI_NOT_FOUND          - The string specified by StringId is not available.
    622     EFI_BUFFER_TOO_SMALL   - The buffer specified by StringLength is too small to hold the string.
    623     EFI_INVALID_PARAMETER  - The String or StringSize was NULL.
    624 
    625 --*/
    626 {
    627   EFI_STATUS  Status;
    628   CHAR8       *Languages;
    629   CHAR8       *LangStrings;
    630   CHAR8       Lang[RFC_3066_ENTRY_SIZE];
    631   CHAR8       CurrentLang[RFC_3066_ENTRY_SIZE];
    632 
    633   LocateHiiProtocols ();
    634 
    635   GetCurrentLanguage (CurrentLang);
    636 
    637   Status = gIfrLibHiiString->GetString (
    638                                gIfrLibHiiString,
    639                                CurrentLang,
    640                                PackageList,
    641                                StringId,
    642                                String,
    643                                StringSize,
    644                                NULL
    645                                );
    646 
    647   if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
    648     Languages = GetSupportedLanguages (PackageList);
    649     LangStrings = Languages;
    650     GetNextLanguage (&LangStrings, Lang);
    651     gBS->FreePool (Languages);
    652 
    653     Status = gIfrLibHiiString->GetString (
    654                                  gIfrLibHiiString,
    655                                  Lang,
    656                                  PackageList,
    657                                  StringId,
    658                                  String,
    659                                  StringSize,
    660                                  NULL
    661                                  );
    662   }
    663 
    664   return Status;
    665 }
    666 
    667 EFI_STATUS
    668 IfrLibSetString (
    669   IN EFI_HII_HANDLE                   PackageList,
    670   IN EFI_STRING_ID                    StringId,
    671   IN CONST EFI_STRING                 String
    672   )
    673 /*++
    674 
    675   Routine Description:
    676     This function updates the string in String package of each language.
    677 
    678   Arguments:
    679     PackageList       - The package list containing the strings.
    680     StringId          - The string's id, which is unique within PackageList.
    681     String            - Points to the new null-terminated string.
    682 
    683   Returns:
    684     EFI_SUCCESS            - The string was updated successfully.
    685     EFI_NOT_FOUND          - The string specified by StringId is not in the database.
    686     EFI_INVALID_PARAMETER  - The String was NULL.
    687     EFI_OUT_OF_RESOURCES   - The system is out of resources to accomplish the task.
    688 
    689 --*/
    690 {
    691   EFI_STATUS  Status;
    692   CHAR8       *Languages;
    693   CHAR8       *LangStrings;
    694   CHAR8       Lang[RFC_3066_ENTRY_SIZE];
    695 
    696   Status = EFI_SUCCESS;
    697 
    698   LocateHiiProtocols ();
    699 
    700   Languages = GetSupportedLanguages (PackageList);
    701   if (Languages == NULL) {
    702     return EFI_NOT_FOUND;
    703   }
    704 
    705   LangStrings = Languages;
    706   while (*LangStrings != 0) {
    707     GetNextLanguage (&LangStrings, Lang);
    708 
    709     Status = gIfrLibHiiString->SetString (
    710                                  gIfrLibHiiString,
    711                                  PackageList,
    712                                  StringId,
    713                                  Lang,
    714                                  String,
    715                                  NULL
    716                                  );
    717     if (EFI_ERROR (Status)) {
    718       break;
    719     }
    720   }
    721 
    722   gBS->FreePool (Languages);
    723 
    724   return Status;
    725 }
    726 
    727