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