1 /** @file
2
3 Copyright (c) 2009 - 2012, 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 **/
13
14 #include "MiscSubclassDriver.h"
15 /*++
16 Check whether the language is supported for given HII handle
17
18 @param HiiHandle The HII package list handle.
19 @param Offset The offest of current lanague in the supported languages.
20 @param CurrentLang The language code.
21
22 @retval TRUE Supported.
23 @retval FALSE Not Supported.
24
25 --*/
26 VOID
27 EFIAPI
CurrentLanguageMatch(IN EFI_HII_HANDLE HiiHandle,OUT UINT16 * Offset,OUT CHAR8 * CurrentLang)28 CurrentLanguageMatch (
29 IN EFI_HII_HANDLE HiiHandle,
30 OUT UINT16 *Offset,
31 OUT CHAR8 *CurrentLang
32 )
33 {
34 CHAR8 *DefaultLang;
35 CHAR8 *BestLanguage;
36 CHAR8 *Languages;
37 CHAR8 *MatchLang;
38 CHAR8 *EndMatchLang;
39 UINTN CompareLength;
40
41 Languages = HiiGetSupportedLanguages (HiiHandle);
42 if (Languages == NULL) {
43 return;
44 }
45
46 GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&CurrentLang, NULL);
47 DefaultLang = (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang);
48 BestLanguage = GetBestLanguage (
49 Languages,
50 FALSE,
51 (CurrentLang != NULL) ? CurrentLang : "",
52 DefaultLang,
53 NULL
54 );
55 if (BestLanguage != NULL) {
56 //
57 // Find the best matching RFC 4646 language, compute the offset.
58 //
59 CompareLength = AsciiStrLen (BestLanguage);
60 for (MatchLang = Languages, (*Offset) = 0; MatchLang != '\0'; (*Offset)++) {
61 //
62 // Seek to the end of current match language.
63 //
64 for (EndMatchLang = MatchLang; *EndMatchLang != '\0' && *EndMatchLang != ';'; EndMatchLang++);
65
66 if ((EndMatchLang == MatchLang + CompareLength) && AsciiStrnCmp(MatchLang, BestLanguage, CompareLength) == 0) {
67 //
68 // Find the current best Language in the supported languages
69 //
70 break;
71 }
72 //
73 // best language match be in the supported language.
74 //
75 ASSERT (*EndMatchLang == ';');
76 MatchLang = EndMatchLang + 1;
77 }
78 FreePool (BestLanguage);
79 }
80
81 FreePool (Languages);
82 if (CurrentLang != NULL) {
83 FreePool (CurrentLang);
84 }
85 return ;
86 }
87
88
89 /**
90 Get next language from language code list (with separator ';').
91
92 @param LangCode Input: point to first language in the list. On
93 Otput: point to next language in the list, or
94 NULL if no more language in the list.
95 @param Lang The first language in the list.
96
97 **/
98 VOID
99 EFIAPI
GetNextLanguage(IN OUT CHAR8 ** LangCode,OUT CHAR8 * Lang)100 GetNextLanguage (
101 IN OUT CHAR8 **LangCode,
102 OUT CHAR8 *Lang
103 )
104 {
105 UINTN Index;
106 CHAR8 *StringPtr;
107
108 ASSERT (LangCode != NULL);
109 ASSERT (*LangCode != NULL);
110 ASSERT (Lang != NULL);
111
112 Index = 0;
113 StringPtr = *LangCode;
114 while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {
115 Index++;
116 }
117
118 CopyMem (Lang, StringPtr, Index);
119 Lang[Index] = 0;
120
121 if (StringPtr[Index] == ';') {
122 Index++;
123 }
124 *LangCode = StringPtr + Index;
125 }
126
127 /**
128 This function returns the number of supported languages on HiiHandle.
129
130 @param HiiHandle The HII package list handle.
131
132 @retval The number of supported languages.
133
134 **/
135 UINT16
136 EFIAPI
GetSupportedLanguageNumber(IN EFI_HII_HANDLE HiiHandle)137 GetSupportedLanguageNumber (
138 IN EFI_HII_HANDLE HiiHandle
139 )
140 {
141 CHAR8 *Lang;
142 CHAR8 *Languages;
143 CHAR8 *LanguageString;
144 UINT16 LangNumber;
145
146 Languages = HiiGetSupportedLanguages (HiiHandle);
147 if (Languages == NULL) {
148 return 0;
149 }
150
151 LangNumber = 0;
152 Lang = AllocatePool (AsciiStrSize (Languages));
153 if (Lang != NULL) {
154 LanguageString = Languages;
155 while (*LanguageString != 0) {
156 GetNextLanguage (&LanguageString, Lang);
157 LangNumber++;
158 }
159 FreePool (Lang);
160 }
161 FreePool (Languages);
162 return LangNumber;
163 }
164
165
166 /**
167 This function makes boot time changes to the contents of the
168 MiscNumberOfInstallableLanguages (Type 13).
169
170 @param RecordData Pointer to copy of RecordData from the Data Table.
171
172 @retval EFI_SUCCESS All parameters were valid.
173 @retval EFI_UNSUPPORTED Unexpected RecordType value.
174 @retval EFI_INVALID_PARAMETER Invalid parameter was found.
175
176 **/
MISC_SMBIOS_TABLE_FUNCTION(NumberOfInstallableLanguages)177 MISC_SMBIOS_TABLE_FUNCTION(NumberOfInstallableLanguages)
178 {
179 UINTN LangStrLen;
180 CHAR8 CurrentLang[SMBIOS_STRING_MAX_LENGTH + 1];
181 CHAR8 *OptionalStrStart;
182 UINT16 Offset;
183 EFI_STATUS Status;
184 EFI_SMBIOS_HANDLE SmbiosHandle;
185 SMBIOS_TABLE_TYPE13 *SmbiosRecord;
186 EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES *ForType13InputData;
187
188 ForType13InputData = (EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES *)RecordData;
189
190 //
191 // First check for invalid parameters.
192 //
193 if (RecordData == NULL) {
194 return EFI_INVALID_PARAMETER;
195 }
196
197 ForType13InputData->NumberOfInstallableLanguages = GetSupportedLanguageNumber (mHiiHandle);
198
199 //
200 // Try to check if current langcode matches with the langcodes in installed languages
201 //
202 ZeroMem(CurrentLang, SMBIOS_STRING_MAX_LENGTH + 1);
203 CurrentLanguageMatch (mHiiHandle, &Offset, CurrentLang);
204 LangStrLen = AsciiStrLen(CurrentLang);
205
206 //
207 // Two zeros following the last string.
208 //
209 SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE13) + LangStrLen + 1 + 1);
210 ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE13) + LangStrLen + 1 + 1);
211
212 SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION;
213 SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE13);
214 //
215 // Make handle chosen by smbios protocol.add automatically.
216 //
217 SmbiosRecord->Hdr.Handle = 0;
218
219 SmbiosRecord->InstallableLanguages = (UINT8)ForType13InputData->NumberOfInstallableLanguages;
220 SmbiosRecord->Flags = (UINT8)ForType13InputData->LanguageFlags.AbbreviatedLanguageFormat;
221 SmbiosRecord->CurrentLanguages = 1;
222 OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
223 AsciiStrCpy(OptionalStrStart, CurrentLang);
224 //
225 // Now we have got the full smbios record, call smbios protocol to add this record.
226 //
227 Status = AddSmbiosRecord (Smbios, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord);
228
229 FreePool(SmbiosRecord);
230 return Status;
231 }
232