Home | History | Annotate | Download | only in SmBiosMiscDxe
      1 /*++
      2 
      3 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
      4 
      5   This program and the accompanying materials are licensed and made available under
      7   the terms and conditions of the BSD License that accompanies this distribution.
      9   The full text of the license may be found at
     11   http://opensource.org/licenses/bsd-license.php.
     13 
     15   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     17   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     19 
     21 
     23 
     24 Module Name:
     25 
     26   MiscNumberOfInstallableLanguagesFunction.c
     27 
     28 Abstract:
     29 
     30   This driver parses the mSmbiosMiscDataTable structure and reports
     31   any generated data.
     32 
     33 --*/
     34 
     35 
     36 #include "CommonHeader.h"
     37 
     38 #include "MiscSubclassDriver.h"
     39 
     40 /**
     41   Check whether the language is supported for given HII handle
     42 
     43   @param   HiiHandle     The HII package list handle.
     44   @param   Offset        The offest of current lanague in the supported languages.
     45   @param   CurrentLang   The language code.
     46 
     47   @retval  TRUE          Supported.
     48   @retval  FALSE         Not Supported.
     49 
     50 **/
     51 VOID
     52 EFIAPI
     53 CurrentLanguageMatch (
     54   IN  EFI_HII_HANDLE                   HiiHandle,
     55   OUT UINT16                           *Offset,
     56   OUT CHAR8                            *CurrentLang
     57   )
     58 {
     59   CHAR8     *DefaultLang;
     60   CHAR8     *BestLanguage;
     61   CHAR8     *Languages;
     62   CHAR8     *MatchLang;
     63   CHAR8     *EndMatchLang;
     64   UINTN     CompareLength;
     65 
     66   Languages = HiiGetSupportedLanguages (HiiHandle);
     67   if (Languages == NULL) {
     68     return;
     69   }
     70 
     71   CurrentLang  = GetEfiGlobalVariable (L"PlatformLang");
     72   DefaultLang  = (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang);
     73   BestLanguage = GetBestLanguage (
     74                    Languages,
     75                    FALSE,
     76                    (CurrentLang != NULL) ? CurrentLang : "",
     77                    DefaultLang,
     78                    NULL
     79                    );
     80   if (BestLanguage != NULL) {
     81     //
     82     // Find the best matching RFC 4646 language, compute the offset.
     83     //
     84     CompareLength = AsciiStrLen (BestLanguage);
     85     for (MatchLang = Languages, (*Offset) = 0; MatchLang != '\0'; (*Offset)++) {
     86       //
     87       // Seek to the end of current match language.
     88       //
     89       for (EndMatchLang = MatchLang; *EndMatchLang != '\0' && *EndMatchLang != ';'; EndMatchLang++);
     90 
     91       if ((EndMatchLang == MatchLang + CompareLength) && AsciiStrnCmp(MatchLang, BestLanguage, CompareLength) == 0) {
     92         //
     93         // Find the current best Language in the supported languages
     94         //
     95         break;
     96       }
     97       //
     98       // best language match be in the supported language.
     99       //
    100       ASSERT (*EndMatchLang == ';');
    101       MatchLang = EndMatchLang + 1;
    102     }
    103     FreePool (BestLanguage);
    104   }
    105 
    106   FreePool (Languages);
    107   if (CurrentLang != NULL) {
    108     FreePool (CurrentLang);
    109   }
    110   return ;
    111 }
    112 
    113 
    114 /**
    115   Get next language from language code list (with separator ';').
    116 
    117   @param  LangCode       Input: point to first language in the list. On
    118                          Otput: point to next language in the list, or
    119                                 NULL if no more language in the list.
    120   @param  Lang           The first language in the list.
    121 
    122 **/
    123 VOID
    124 EFIAPI
    125 GetNextLanguage (
    126   IN OUT CHAR8      **LangCode,
    127   OUT CHAR8         *Lang
    128   )
    129 {
    130   UINTN  Index;
    131   CHAR8  *StringPtr;
    132 
    133   ASSERT (LangCode != NULL);
    134   ASSERT (*LangCode != NULL);
    135   ASSERT (Lang != NULL);
    136 
    137   Index     = 0;
    138   StringPtr = *LangCode;
    139   while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {
    140     Index++;
    141   }
    142 
    143   CopyMem (Lang, StringPtr, Index);
    144   Lang[Index] = 0;
    145 
    146   if (StringPtr[Index] == ';') {
    147     Index++;
    148   }
    149   *LangCode = StringPtr + Index;
    150 }
    151 
    152 /**
    153   This function returns the number of supported languages on HiiHandle.
    154 
    155   @param   HiiHandle    The HII package list handle.
    156 
    157   @retval  The number of supported languages.
    158 
    159 **/
    160 UINT16
    161 EFIAPI
    162 GetSupportedLanguageNumber (
    163   IN EFI_HII_HANDLE    HiiHandle
    164   )
    165 {
    166   CHAR8   *Lang;
    167   CHAR8   *Languages;
    168   CHAR8   *LanguageString;
    169   UINT16  LangNumber;
    170 
    171   Languages = HiiGetSupportedLanguages (HiiHandle);
    172   if (Languages == NULL) {
    173     return 0;
    174   }
    175 
    176   LangNumber = 0;
    177   Lang = AllocatePool (AsciiStrSize (Languages));
    178   if (Lang != NULL) {
    179     LanguageString = Languages;
    180     while (*LanguageString != 0) {
    181       GetNextLanguage (&LanguageString, Lang);
    182       LangNumber++;
    183     }
    184     FreePool (Lang);
    185   }
    186   FreePool (Languages);
    187   return LangNumber;
    188 }
    189 
    190 
    191 /**
    192   This function makes boot time changes to the contents of the
    193   MiscNumberOfInstallableLanguages (Type 13).
    194 
    195   @param  RecordData                 Pointer to copy of RecordData from the Data Table.
    196 
    197   @retval EFI_SUCCESS                All parameters were valid.
    198   @retval EFI_UNSUPPORTED            Unexpected RecordType value.
    199   @retval EFI_INVALID_PARAMETER      Invalid parameter was found.
    200 
    201 **/
    202 MISC_SMBIOS_TABLE_FUNCTION(NumberOfInstallableLanguages)
    203 {
    204   UINTN                                     LangStrLen;
    205   CHAR8                                     CurrentLang[SMBIOS_STRING_MAX_LENGTH + 1];
    206   CHAR8                                     *OptionalStrStart;
    207   UINT16                                    Offset;
    208   EFI_STATUS                                Status;
    209   EFI_SMBIOS_HANDLE                         SmbiosHandle;
    210   SMBIOS_TABLE_TYPE13                       *SmbiosRecord;
    211   EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES  *ForType13InputData;
    212 
    213   ForType13InputData = (EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES *)RecordData;
    214 
    215   //
    216   // First check for invalid parameters.
    217   //
    218   if (RecordData == NULL) {
    219     return EFI_INVALID_PARAMETER;
    220   }
    221 
    222   ForType13InputData->NumberOfInstallableLanguages = GetSupportedLanguageNumber (mHiiHandle);
    223 
    224   //
    225   // Try to check if current langcode matches with the langcodes in installed languages
    226   //
    227   ZeroMem(CurrentLang, SMBIOS_STRING_MAX_LENGTH + 1);
    228   CurrentLanguageMatch (mHiiHandle, &Offset, CurrentLang);
    229   LangStrLen = AsciiStrLen(CurrentLang);
    230 
    231   //
    232   // Two zeros following the last string.
    233   //
    234   SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE13) + LangStrLen + 1 + 1);
    235   ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE13) + LangStrLen + 1 + 1);
    236 
    237   SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION;
    238   SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE13);
    239 
    240   //
    241   // Make handle chosen by smbios protocol.add automatically.
    242   //
    243   SmbiosRecord->Hdr.Handle = 0;
    244 
    245   SmbiosRecord->InstallableLanguages = (UINT8)ForType13InputData->NumberOfInstallableLanguages;
    246   SmbiosRecord->Flags = (UINT8)ForType13InputData->LanguageFlags.AbbreviatedLanguageFormat;
    247   SmbiosRecord->CurrentLanguages = 1;
    248   OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
    249   AsciiStrCpy(OptionalStrStart, CurrentLang);
    250 
    251   //
    252   // Now we have got the full smbios record, call smbios protocol to add this record.
    253   //
    254   SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
    255   Status = Smbios-> Add(
    256                       Smbios,
    257                       NULL,
    258                       &SmbiosHandle,
    259                       (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
    260                       );
    261   FreePool(SmbiosRecord);
    262   return Status;
    263 }
    264