Home | History | Annotate | Download | only in UefiHiiLib
      1 /** @file
      2   HII Library implementation that uses DXE protocols and services.
      3 
      4   Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
      5   This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 
     16 #include "InternalHiiLib.h"
     17 
     18 /**
     19   This function create a new string in String Package or updates an existing
     20   string in a String Package.  If StringId is 0, then a new string is added to
     21   a String Package.  If StringId is not zero, then a string in String Package is
     22   updated.  If SupportedLanguages is NULL, then the string is added or updated
     23   for all the languages that the String Package supports.  If SupportedLanguages
     24   is not NULL, then the string is added or updated for the set of languages
     25   specified by SupportedLanguages.
     26 
     27   If HiiHandle is NULL, then ASSERT().
     28   If String is NULL, then ASSERT().
     29 
     30   @param[in]  HiiHandle           A handle that was previously registered in the
     31                                   HII Database.
     32   @param[in]  StringId            If zero, then a new string is created in the
     33                                   String Package associated with HiiHandle.  If
     34                                   non-zero, then the string specified by StringId
     35                                   is updated in the String Package  associated
     36                                   with HiiHandle.
     37   @param[in]  String              A pointer to the Null-terminated Unicode string
     38                                   to add or update in the String Package associated
     39                                   with HiiHandle.
     40   @param[in]  SupportedLanguages  A pointer to a Null-terminated ASCII string of
     41                                   language codes.  If this parameter is NULL, then
     42                                   String is added or updated in the String Package
     43                                   associated with HiiHandle for all the languages
     44                                   that the String Package supports.  If this
     45                                   parameter is not NULL, then then String is added
     46                                   or updated in the String Package associated with
     47                                   HiiHandle for the set oflanguages specified by
     48                                   SupportedLanguages.  The format of
     49                                   SupportedLanguages must follow the language
     50                                   format assumed the HII Database.
     51 
     52   @retval 0      The string could not be added or updated in the String Package.
     53   @retval Other  The EFI_STRING_ID of the newly added or updated string.
     54 
     55 **/
     56 EFI_STRING_ID
     57 EFIAPI
     58 HiiSetString (
     59   IN EFI_HII_HANDLE    HiiHandle,
     60   IN EFI_STRING_ID     StringId,            OPTIONAL
     61   IN CONST EFI_STRING  String,
     62   IN CONST CHAR8       *SupportedLanguages  OPTIONAL
     63   )
     64 {
     65   EFI_STATUS     Status;
     66   CHAR8          *AllocatedLanguages;
     67   CHAR8          *Supported;
     68   CHAR8          *Language;
     69 
     70   ASSERT (HiiHandle != NULL);
     71   ASSERT (String != NULL);
     72 
     73   if (SupportedLanguages == NULL) {
     74     //
     75     // Retrieve the languages that the package specified by HiiHandle supports
     76     //
     77     AllocatedLanguages = HiiGetSupportedLanguages (HiiHandle);
     78   } else {
     79     //
     80     // Allocate a copy of the SupportLanguages string that passed in
     81     //
     82     AllocatedLanguages = AllocateCopyPool (AsciiStrSize (SupportedLanguages), SupportedLanguages);
     83   }
     84 
     85   //
     86   // If there are not enough resources for the supported languages string, then return a StringId of 0
     87   //
     88   if (AllocatedLanguages == NULL) {
     89     return (EFI_STRING_ID)(0);
     90   }
     91 
     92   Status = EFI_INVALID_PARAMETER;
     93   //
     94   // Loop through each language that the string supports
     95   //
     96   for (Supported = AllocatedLanguages; *Supported != '\0'; ) {
     97     //
     98     // Cache a pointer to the beginning of the current language in the list of languages
     99     //
    100     Language = Supported;
    101 
    102     //
    103     // Search for the next language seperator and replace it with a Null-terminator
    104     //
    105     for (; *Supported != 0 && *Supported != ';'; Supported++);
    106     if (*Supported != 0) {
    107       *(Supported++) = '\0';
    108     }
    109 
    110     if ((SupportedLanguages == NULL) && AsciiStrnCmp (Language, UEFI_CONFIG_LANG, AsciiStrLen (UEFI_CONFIG_LANG)) == 0) {
    111       //
    112       // Skip string package used for keyword protocol.
    113       //
    114       continue;
    115     }
    116 
    117     //
    118     // If StringId is 0, then call NewString().  Otherwise, call SetString()
    119     //
    120     if (StringId == (EFI_STRING_ID)(0)) {
    121       Status = gHiiString->NewString (gHiiString, HiiHandle, &StringId, Language, NULL, String, NULL);
    122     } else {
    123       Status = gHiiString->SetString (gHiiString, HiiHandle, StringId, Language, String, NULL);
    124     }
    125 
    126     //
    127     // If there was an error, then break out of the loop and return a StringId of 0
    128     //
    129     if (EFI_ERROR (Status)) {
    130       break;
    131     }
    132   }
    133 
    134   //
    135   // Free the buffer of supported languages
    136   //
    137   FreePool (AllocatedLanguages);
    138 
    139   if (EFI_ERROR (Status)) {
    140     return (EFI_STRING_ID)(0);
    141   } else {
    142     return StringId;
    143   }
    144 }
    145 
    146 
    147 /**
    148   Retrieves a string from a string package names by GUID in a specific language.
    149   If the language is not specified, then a string from a string package in the
    150   current platform  language is retrieved.  If the string can not be retrieved
    151   using the specified language or the current platform language, then the string
    152   is retrieved from the string package in the first language the string package
    153   supports.  The returned string is allocated using AllocatePool().  The caller
    154   is responsible for freeing the allocated buffer using FreePool().
    155 
    156   If PackageListGuid is NULL, then ASSERT().
    157   If StringId is 0, then ASSERT.
    158 
    159   @param[in]  PackageListGuid  The GUID of a package list that was previously
    160                                registered in the HII Database.
    161   @param[in]  StringId         The identifier of the string to retrieved from the
    162                                string package associated with PackageListGuid.
    163   @param[in]  Language         The language of the string to retrieve.  If this
    164                                parameter is NULL, then the current platform
    165                                language is used.  The format of Language must
    166                                follow the language format assumed the HII Database.
    167 
    168   @retval NULL   The package list specified by PackageListGuid is not present in the
    169                  HII Database.
    170   @retval NULL   The string specified by StringId is not present in the string package.
    171   @retval Other  The string was returned.
    172 
    173 **/
    174 EFI_STRING
    175 EFIAPI
    176 HiiGetPackageString (
    177   IN CONST EFI_GUID  *PackageListGuid,
    178   IN EFI_STRING_ID   StringId,
    179   IN CONST CHAR8     *Language  OPTIONAL
    180   )
    181 {
    182   EFI_HANDLE  *HiiHandleBuffer;
    183   EFI_HANDLE  HiiHandle;
    184 
    185   ASSERT (PackageListGuid != NULL);
    186 
    187   HiiHandleBuffer = HiiGetHiiHandles (PackageListGuid);
    188   if (HiiHandleBuffer == NULL) {
    189     return NULL;
    190   }
    191 
    192   HiiHandle = HiiHandleBuffer[0];
    193   FreePool (HiiHandleBuffer);
    194 
    195   return HiiGetString (HiiHandle, StringId, Language);
    196 }
    197 
    198 /**
    199   Retrieves a string from a string package in a specific language.  If the language
    200   is not specified, then a string from a string package in the current platform
    201   language is retrieved.  If the string can not be retrieved using the specified
    202   language or the current platform language, then the string is retrieved from
    203   the string package in the first language the string package supports.  The
    204   returned string is allocated using AllocatePool().  The caller is responsible
    205   for freeing the allocated buffer using FreePool().
    206 
    207   If HiiHandle is NULL, then ASSERT().
    208   If StringId is 0, then ASSET.
    209 
    210   @param[in]  HiiHandle  A handle that was previously registered in the HII Database.
    211   @param[in]  StringId   The identifier of the string to retrieved from the string
    212                          package associated with HiiHandle.
    213   @param[in]  Language   The language of the string to retrieve.  If this parameter
    214                          is NULL, then the current platform language is used.  The
    215                          format of Language must follow the language format assumed
    216                          the HII Database.
    217 
    218   @retval NULL   The string specified by StringId is not present in the string package.
    219   @retval Other  The string was returned.
    220 
    221 **/
    222 EFI_STRING
    223 EFIAPI
    224 HiiGetString (
    225   IN EFI_HII_HANDLE  HiiHandle,
    226   IN EFI_STRING_ID   StringId,
    227   IN CONST CHAR8     *Language  OPTIONAL
    228   )
    229 {
    230   EFI_STATUS  Status;
    231   UINTN       StringSize;
    232   CHAR16      TempString;
    233   EFI_STRING  String;
    234   CHAR8       *SupportedLanguages;
    235   CHAR8       *PlatformLanguage;
    236   CHAR8       *BestLanguage;
    237 
    238   ASSERT (HiiHandle != NULL);
    239   ASSERT (StringId != 0);
    240 
    241   //
    242   // Initialize all allocated buffers to NULL
    243   //
    244   SupportedLanguages = NULL;
    245   PlatformLanguage   = NULL;
    246   BestLanguage       = NULL;
    247   String             = NULL;
    248 
    249   //
    250   // Get the languages that the package specified by HiiHandle supports
    251   //
    252   SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
    253   if (SupportedLanguages == NULL) {
    254     goto Error;
    255   }
    256 
    257   //
    258   // Get the current platform language setting
    259   //
    260   GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&PlatformLanguage, NULL);
    261 
    262   //
    263   // If Languag is NULL, then set it to an empty string, so it will be
    264   // skipped by GetBestLanguage()
    265   //
    266   if (Language == NULL) {
    267     Language = "";
    268   }
    269 
    270   //
    271   // Get the best matching language from SupportedLanguages
    272   //
    273   BestLanguage = GetBestLanguage (
    274                    SupportedLanguages,
    275                    FALSE,                                             // RFC 4646 mode
    276                    Language,                                          // Highest priority
    277                    PlatformLanguage != NULL ? PlatformLanguage : "",  // Next highest priority
    278                    SupportedLanguages,                                // Lowest priority
    279                    NULL
    280                    );
    281   if (BestLanguage == NULL) {
    282     goto Error;
    283   }
    284 
    285   //
    286   // Retrieve the size of the string in the string package for the BestLanguage
    287   //
    288   StringSize = 0;
    289   Status = gHiiString->GetString (
    290                          gHiiString,
    291                          BestLanguage,
    292                          HiiHandle,
    293                          StringId,
    294                          &TempString,
    295                          &StringSize,
    296                          NULL
    297                          );
    298   //
    299   // If GetString() returns EFI_SUCCESS for a zero size,
    300   // then there are no supported languages registered for HiiHandle.  If GetString()
    301   // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
    302   // in the HII Database
    303   //
    304   if (Status != EFI_BUFFER_TOO_SMALL) {
    305     goto Error;
    306   }
    307 
    308   //
    309   // Allocate a buffer for the return string
    310   //
    311   String = AllocateZeroPool (StringSize);
    312   if (String == NULL) {
    313     goto Error;
    314   }
    315 
    316   //
    317   // Retrieve the string from the string package
    318   //
    319   Status = gHiiString->GetString (
    320                          gHiiString,
    321                          BestLanguage,
    322                          HiiHandle,
    323                          StringId,
    324                          String,
    325                          &StringSize,
    326                          NULL
    327                          );
    328   if (EFI_ERROR (Status)) {
    329     //
    330     // Free the buffer and return NULL if the supported languages can not be retrieved.
    331     //
    332     FreePool (String);
    333     String = NULL;
    334   }
    335 
    336 Error:
    337   //
    338   // Free allocated buffers
    339   //
    340   if (SupportedLanguages != NULL) {
    341     FreePool (SupportedLanguages);
    342   }
    343   if (PlatformLanguage != NULL) {
    344     FreePool (PlatformLanguage);
    345   }
    346   if (BestLanguage != NULL) {
    347     FreePool (BestLanguage);
    348   }
    349 
    350   //
    351   // Return the Null-terminated Unicode string
    352   //
    353   return String;
    354 }
    355 
    356