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