1 /*++ 2 3 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 4 5 6 This program and the accompanying materials are licensed and made available under 7 8 the terms and conditions of the BSD License that accompanies this distribution. 9 10 The full text of the license may be found at 11 12 http://opensource.org/licenses/bsd-license.php. 13 14 15 16 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 17 18 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 19 20 21 22 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. CurrentLanguageMatch(IN EFI_HII_HANDLE HiiHandle,OUT UINT16 * Offset,OUT CHAR8 * CurrentLang)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 ';'). GetNextLanguage(IN OUT CHAR8 ** LangCode,OUT CHAR8 * Lang)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 /** GetSupportedLanguageNumber(IN EFI_HII_HANDLE HiiHandle)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 MISC_SMBIOS_TABLE_FUNCTION(NumberOfInstallableLanguages)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