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