]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/IfrSupportLib/UefiIfrString.c
UEFI HII: Merge UEFI HII support changes from branch.
[mirror_edk2.git] / MdeModulePkg / Library / IfrSupportLib / UefiIfrString.c
1 /** @file
2
3 Copyright (c) 2007, Intel Corporation
4 All rights reserved. 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 Module Name:
13
14 UefiIfrString.c
15
16 Abstract:
17
18 Common Library Routines to assist to handle String and Language.
19
20
21 **/
22
23 #include "UefiIfrLibraryInternal.h"
24
25 //
26 // Lookup table of ISO639-2 3 character language codes to ISO 639-1 2 character language codes
27 // Each entry is 5 CHAR8 values long. The first 3 CHAR8 values are the ISO 639-2 code.
28 // The last 2 CHAR8 values are the ISO 639-1 code.
29 //
30 CHAR8 Iso639ToRfc3066ConversionTable[] =
31 "\
32 aaraa\
33 abkab\
34 afraf\
35 amham\
36 araar\
37 asmas\
38 aymay\
39 azeaz\
40 bakba\
41 belbe\
42 benbn\
43 bihbh\
44 bisbi\
45 bodbo\
46 brebr\
47 bulbg\
48 catca\
49 cescs\
50 corkw\
51 cosco\
52 cymcy\
53 danda\
54 deude\
55 dzodz\
56 ellel\
57 engen\
58 epoeo\
59 estet\
60 euseu\
61 faofo\
62 fasfa\
63 fijfj\
64 finfi\
65 frafr\
66 fryfy\
67 gaiga\
68 gdhgd\
69 glggl\
70 grngn\
71 gujgu\
72 hauha\
73 hebhe\
74 hinhi\
75 hrvhr\
76 hunhu\
77 hyehy\
78 ikuiu\
79 ileie\
80 inaia\
81 indid\
82 ipkik\
83 islis\
84 itait\
85 jawjw\
86 jpnja\
87 kalkl\
88 kankn\
89 kasks\
90 katka\
91 kazkk\
92 khmkm\
93 kinrw\
94 kirky\
95 korko\
96 kurku\
97 laolo\
98 latla\
99 lavlv\
100 linln\
101 litlt\
102 ltzlb\
103 malml\
104 marmr\
105 mkdmk\
106 mlgmg\
107 mltmt\
108 molmo\
109 monmn\
110 mrimi\
111 msams\
112 myamy\
113 nauna\
114 nepne\
115 nldnl\
116 norno\
117 ocioc\
118 ormom\
119 panpa\
120 polpl\
121 porpt\
122 pusps\
123 quequ\
124 rohrm\
125 ronro\
126 runrn\
127 rusru\
128 sagsg\
129 sansa\
130 sinsi\
131 slksk\
132 slvsl\
133 smise\
134 smosm\
135 snasn\
136 sndsd\
137 somso\
138 sotst\
139 spaes\
140 sqisq\
141 srpsr\
142 sswss\
143 sunsu\
144 swasw\
145 swesv\
146 tamta\
147 tattt\
148 telte\
149 tgktg\
150 tgltl\
151 thath\
152 tsnts\
153 tuktk\
154 twitw\
155 uigug\
156 ukruk\
157 urdur\
158 uzbuz\
159 vievi\
160 volvo\
161 wolwo\
162 xhoxh\
163 yidyi\
164 zhaza\
165 zhozh\
166 zulzu\
167 ";
168
169
170 /**
171 Convert language code from RFC3066 to ISO639-2.
172
173 @param LanguageRfc3066 RFC3066 language code.
174 @param LanguageIso639 ISO639-2 language code.
175
176 @retval EFI_SUCCESS Language code converted.
177 @retval EFI_NOT_FOUND Language code not found.
178
179 **/
180 EFI_STATUS
181 ConvertRfc3066LanguageToIso639Language (
182 CHAR8 *LanguageRfc3066,
183 CHAR8 *LanguageIso639
184 )
185 {
186 UINTN Index;
187
188 if ((LanguageRfc3066[2] != '-') && (LanguageRfc3066[2] != 0)) {
189 CopyMem (LanguageIso639, LanguageRfc3066, 3);
190 return EFI_SUCCESS;
191 }
192
193 for (Index = 0; Iso639ToRfc3066ConversionTable[Index] != 0; Index += 5) {
194 if (CompareMem (LanguageRfc3066, &Iso639ToRfc3066ConversionTable[Index + 3], 2) == 0) {
195 CopyMem (LanguageIso639, &Iso639ToRfc3066ConversionTable[Index], 3);
196 return EFI_SUCCESS;
197 }
198 }
199
200 return EFI_NOT_FOUND;
201 }
202
203
204 /**
205 Convert language code list from RFC3066 to ISO639-2, e.g. "en-US;fr-FR" will
206 be converted to "engfra".
207
208 @param SupportedLanguages The RFC3066 language list.
209
210 @return The ISO639-2 language list.
211
212 **/
213 CHAR8 *
214 Rfc3066ToIso639 (
215 CHAR8 *SupportedLanguages
216 )
217 {
218 CHAR8 *Languages;
219 CHAR8 *ReturnValue;
220 CHAR8 *LangCodes;
221 CHAR8 LangRfc3066[RFC_3066_ENTRY_SIZE];
222 CHAR8 LangIso639[ISO_639_2_ENTRY_SIZE];
223 EFI_STATUS Status;
224
225 ReturnValue = AllocateZeroPool (AsciiStrSize (SupportedLanguages));
226 if (ReturnValue == NULL) {
227 return ReturnValue;
228 }
229
230 Languages = ReturnValue;
231 LangCodes = SupportedLanguages;
232 while (*LangCodes != 0) {
233 GetNextLanguage (&LangCodes, LangRfc3066);
234
235 Status = ConvertRfc3066LanguageToIso639Language (LangRfc3066, LangIso639);
236 if (!EFI_ERROR (Status)) {
237 CopyMem (Languages, LangIso639, 3);
238 Languages = Languages + 3;
239 }
240 }
241
242 return ReturnValue;
243 }
244
245
246 /**
247 Determine what is the current language setting
248
249 @param Lang Pointer of system language
250
251 @return Status code
252
253 **/
254 EFI_STATUS
255 GetCurrentLanguage (
256 OUT CHAR8 *Lang
257 )
258 {
259 EFI_STATUS Status;
260 UINTN Size;
261
262 //
263 // Get current language setting
264 //
265 Size = RFC_3066_ENTRY_SIZE;
266 Status = gRT->GetVariable (
267 L"PlatformLang",
268 &gEfiGlobalVariableGuid,
269 NULL,
270 &Size,
271 Lang
272 );
273
274 if (EFI_ERROR (Status)) {
275 AsciiStrCpy (Lang, (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang));
276 }
277
278 return Status;
279 }
280
281
282 /**
283 Get next language from language code list (with separator ';').
284
285 @param LangCode On input: point to first language in the list. On
286 output: point to next language in the list, or
287 NULL if no more language in the list.
288 @param Lang The first language in the list.
289
290 @return None.
291
292 **/
293 VOID
294 GetNextLanguage (
295 IN OUT CHAR8 **LangCode,
296 OUT CHAR8 *Lang
297 )
298 {
299 UINTN Index;
300 CHAR8 *StringPtr;
301
302 if (LangCode == NULL || *LangCode == NULL) {
303 *Lang = 0;
304 return;
305 }
306
307 Index = 0;
308 StringPtr = *LangCode;
309 while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {
310 Index++;
311 }
312
313 CopyMem (Lang, StringPtr, Index);
314 Lang[Index] = 0;
315
316 if (StringPtr[Index] == ';') {
317 Index++;
318 }
319 *LangCode = StringPtr + Index;
320 }
321
322
323 /**
324 This function returns the list of supported languages, in the format specified
325 in UEFI specification Appendix M.
326
327 @param HiiHandle The HII package list handle.
328
329 @return The supported languages.
330
331 **/
332 CHAR8 *
333 GetSupportedLanguages (
334 IN EFI_HII_HANDLE HiiHandle
335 )
336 {
337 EFI_STATUS Status;
338 UINTN BufferSize;
339 CHAR8 *LanguageString;
340
341 LocateHiiProtocols ();
342
343 //
344 // Collect current supported Languages for given HII handle
345 //
346 BufferSize = 0x1000;
347 LanguageString = AllocatePool (BufferSize);
348 Status = gIfrLibHiiString->GetLanguages (gIfrLibHiiString, HiiHandle, LanguageString, &BufferSize);
349 if (Status == EFI_BUFFER_TOO_SMALL) {
350 gBS->FreePool (LanguageString);
351 LanguageString = AllocatePool (BufferSize);
352 Status = gIfrLibHiiString->GetLanguages (gIfrLibHiiString, HiiHandle, LanguageString, &BufferSize);
353 }
354
355 if (EFI_ERROR (Status)) {
356 LanguageString = NULL;
357 }
358
359 return LanguageString;
360 }
361
362
363 /**
364 This function returns the number of supported languages
365
366 @param HiiHandle The HII package list handle.
367
368 @return The number of supported languages.
369
370 **/
371 UINT16
372 GetSupportedLanguageNumber (
373 IN EFI_HII_HANDLE HiiHandle
374 )
375 {
376 CHAR8 *Languages;
377 CHAR8 *LanguageString;
378 UINT16 LangNumber;
379 CHAR8 Lang[RFC_3066_ENTRY_SIZE];
380
381 Languages = GetSupportedLanguages (HiiHandle);
382 if (Languages == NULL) {
383 return 0;
384 }
385
386 LangNumber = 0;
387 LanguageString = Languages;
388 while (*LanguageString != 0) {
389 GetNextLanguage (&LanguageString, Lang);
390 LangNumber++;
391 }
392 gBS->FreePool (Languages);
393
394 return LangNumber;
395 }
396
397
398 /**
399 Get string specified by StringId form the HiiHandle.
400
401 @param HiiHandle The HII handle of package list.
402 @param StringId The String ID.
403 @param String The output string.
404
405 @retval EFI_NOT_FOUND String is not found.
406 @retval EFI_SUCCESS Operation is successful.
407 @retval EFI_OUT_OF_RESOURCES There is not enought memory in the system.
408 @retval EFI_INVALID_PARAMETER The String is NULL.
409
410 **/
411 EFI_STATUS
412 GetStringFromHandle (
413 IN EFI_HII_HANDLE HiiHandle,
414 IN EFI_STRING_ID StringId,
415 OUT EFI_STRING *String
416 )
417 {
418 EFI_STATUS Status;
419 UINTN StringSize;
420
421 if (String == NULL) {
422 return EFI_INVALID_PARAMETER;
423 }
424
425 StringSize = IFR_LIB_DEFAULT_STRING_SIZE;
426 *String = AllocateZeroPool (StringSize);
427 if (*String == NULL) {
428 return EFI_OUT_OF_RESOURCES;
429 }
430
431 Status = IfrLibGetString (HiiHandle, StringId, *String, &StringSize);
432 if (Status == EFI_BUFFER_TOO_SMALL) {
433 gBS->FreePool (*String);
434 *String = AllocateZeroPool (StringSize);
435 if (*String == NULL) {
436 return EFI_OUT_OF_RESOURCES;
437 }
438 Status = IfrLibGetString (HiiHandle, StringId, *String, &StringSize);
439 }
440
441 return Status;
442 }
443
444
445 /**
446 Get the string given the StringId and String package Producer's Guid.
447
448 @param ProducerGuid The Guid of String package list.
449 @param StringId The String ID.
450 @param String The output string.
451
452 @retval EFI_NOT_FOUND String is not found.
453 @retval EFI_SUCCESS Operation is successful.
454 @retval EFI_OUT_OF_RESOURCES There is not enought memory in the system.
455
456 **/
457 EFI_STATUS
458 GetStringFromToken (
459 IN EFI_GUID *ProducerGuid,
460 IN EFI_STRING_ID StringId,
461 OUT EFI_STRING *String
462 )
463 {
464 EFI_STATUS Status;
465 UINTN Index;
466 UINTN HandleBufferLen;
467 EFI_HII_HANDLE *HiiHandleBuffer;
468 EFI_GUID Guid;
469
470 Status = GetHiiHandles (&HandleBufferLen, &HiiHandleBuffer);
471 if (EFI_ERROR(Status)) {
472 return Status;
473 }
474 for (Index = 0; Index < (HandleBufferLen / sizeof (EFI_HII_HANDLE)); Index++) {
475 Status = ExtractGuidFromHiiHandle (HiiHandleBuffer[Index], &Guid);
476 if (EFI_ERROR(Status)) {
477 return Status;
478 }
479 if (CompareGuid (&Guid, ProducerGuid) == TRUE) {
480 break;
481 }
482 }
483
484 if (Index >= (HandleBufferLen / sizeof (EFI_HII_HANDLE))) {
485 Status = EFI_NOT_FOUND;
486 goto Out;
487 }
488
489 Status = GetStringFromHandle (HiiHandleBuffer[Index], StringId, String);
490
491 Out:
492 if (HiiHandleBuffer != NULL) {
493 gBS->FreePool (HiiHandleBuffer);
494 }
495 return Status;
496 }
497
498
499 /**
500 This function adds the string into String Package of each language.
501
502 @param PackageList Handle of the package list where this string will
503 be added.
504 @param StringId On return, contains the new strings id, which is
505 unique within PackageList.
506 @param String Points to the new null-terminated string.
507
508 @retval EFI_SUCCESS The new string was added successfully.
509 @retval EFI_NOT_FOUND The specified PackageList could not be found in
510 database.
511 @retval EFI_OUT_OF_RESOURCES Could not add the string due to lack of resources.
512 @retval EFI_INVALID_PARAMETER String is NULL or StringId is NULL is NULL.
513
514 **/
515 EFI_STATUS
516 IfrLibNewString (
517 IN EFI_HII_HANDLE PackageList,
518 OUT EFI_STRING_ID *StringId,
519 IN CONST EFI_STRING String
520 )
521 {
522 EFI_STATUS Status;
523 CHAR8 *Languages;
524 CHAR8 *LangStrings;
525 CHAR8 Lang[RFC_3066_ENTRY_SIZE];
526
527 Status = EFI_SUCCESS;
528
529 LocateHiiProtocols ();
530
531 Languages = GetSupportedLanguages (PackageList);
532
533 LangStrings = Languages;
534 while (*LangStrings != 0) {
535 GetNextLanguage (&LangStrings, Lang);
536
537 Status = gIfrLibHiiString->NewString (
538 gIfrLibHiiString,
539 PackageList,
540 StringId,
541 Lang,
542 NULL,
543 String,
544 NULL
545 );
546 if (EFI_ERROR (Status)) {
547 break;
548 }
549 }
550
551 gBS->FreePool (Languages);
552
553 return Status;
554 }
555
556
557 /**
558 This function try to retrieve string from String package of current language.
559 If fail, it try to retrieve string from String package of first language it support.
560
561 @param PackageList The package list in the HII database to search for
562 the specified string.
563 @param StringId The string's id, which is unique within
564 PackageList.
565 @param String Points to the new null-terminated string.
566 @param StringSize On entry, points to the size of the buffer pointed
567 to by String, in bytes. On return, points to the
568 length of the string, in bytes.
569
570 @retval EFI_SUCCESS The string was returned successfully.
571 @retval EFI_NOT_FOUND The string specified by StringId is not available.
572 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringLength is too small
573 to hold the string.
574 @retval EFI_INVALID_PARAMETER The String or StringSize was NULL.
575
576 **/
577 EFI_STATUS
578 IfrLibGetString (
579 IN EFI_HII_HANDLE PackageList,
580 IN EFI_STRING_ID StringId,
581 OUT EFI_STRING String,
582 IN OUT UINTN *StringSize
583 )
584 {
585 EFI_STATUS Status;
586 CHAR8 *Languages;
587 CHAR8 *LangStrings;
588 CHAR8 Lang[RFC_3066_ENTRY_SIZE];
589 CHAR8 CurrentLang[RFC_3066_ENTRY_SIZE];
590
591 LocateHiiProtocols ();
592
593 GetCurrentLanguage (CurrentLang);
594
595 Status = gIfrLibHiiString->GetString (
596 gIfrLibHiiString,
597 CurrentLang,
598 PackageList,
599 StringId,
600 String,
601 StringSize,
602 NULL
603 );
604
605 if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
606 Languages = GetSupportedLanguages (PackageList);
607 LangStrings = Languages;
608 GetNextLanguage (&LangStrings, Lang);
609 gBS->FreePool (Languages);
610
611 Status = gIfrLibHiiString->GetString (
612 gIfrLibHiiString,
613 Lang,
614 PackageList,
615 StringId,
616 String,
617 StringSize,
618 NULL
619 );
620 }
621
622 return Status;
623 }
624
625
626 /**
627 This function updates the string in String package of each language.
628
629 @param PackageList The package list containing the strings.
630 @param StringId The string's id, which is unique within
631 PackageList.
632 @param String Points to the new null-terminated string.
633
634 @retval EFI_SUCCESS The string was updated successfully.
635 @retval EFI_NOT_FOUND The string specified by StringId is not in the
636 database.
637 @retval EFI_INVALID_PARAMETER The String was NULL.
638 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
639 task.
640
641 **/
642 EFI_STATUS
643 IfrLibSetString (
644 IN EFI_HII_HANDLE PackageList,
645 IN EFI_STRING_ID StringId,
646 IN CONST EFI_STRING String
647 )
648 {
649 EFI_STATUS Status;
650 CHAR8 *Languages;
651 CHAR8 *LangStrings;
652 CHAR8 Lang[RFC_3066_ENTRY_SIZE];
653
654 Status = EFI_SUCCESS;
655
656 LocateHiiProtocols ();
657
658 Languages = GetSupportedLanguages (PackageList);
659
660 LangStrings = Languages;
661 while (*LangStrings != 0) {
662 GetNextLanguage (&LangStrings, Lang);
663
664 Status = gIfrLibHiiString->SetString (
665 gIfrLibHiiString,
666 PackageList,
667 StringId,
668 Lang,
669 String,
670 NULL
671 );
672 if (EFI_ERROR (Status)) {
673 break;
674 }
675 }
676
677 gBS->FreePool (Languages);
678
679 return Status;
680 }
681