1 | /** @file
|
---|
2 | Language settings
|
---|
3 |
|
---|
4 | Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
|
---|
5 | SPDX-License-Identifier: BSD-2-Clause-Patent
|
---|
6 |
|
---|
7 | **/
|
---|
8 |
|
---|
9 | #include "Bds.h"
|
---|
10 | #define ISO_639_2_ENTRY_SIZE 3
|
---|
11 |
|
---|
12 | /**
|
---|
13 | Check if lang is in supported language codes according to language string.
|
---|
14 |
|
---|
15 | This code is used to check if lang is in in supported language codes. It can handle
|
---|
16 | RFC4646 and ISO639 language tags.
|
---|
17 | In ISO639 language tags, take 3-characters as a delimitation to find matched string.
|
---|
18 | In RFC4646 language tags, take semicolon as a delimitation to find matched string.
|
---|
19 |
|
---|
20 | For example:
|
---|
21 | SupportedLang = "engfraengfra"
|
---|
22 | Iso639Language = TRUE
|
---|
23 | Lang = "eng", the return value is "TRUE", or
|
---|
24 | Lang = "chs", the return value is "FALSE".
|
---|
25 | Another example:
|
---|
26 | SupportedLang = "en;fr;en-US;fr-FR"
|
---|
27 | Iso639Language = FALSE
|
---|
28 | Lang = "en", the return value is "TRUE", or
|
---|
29 | Lang = "zh", the return value is "FALSE".
|
---|
30 |
|
---|
31 | @param SupportedLang Platform supported language codes.
|
---|
32 | @param Lang Configured language.
|
---|
33 | @param Iso639Language A bool value to signify if the handler is operated on ISO639 or RFC4646.
|
---|
34 |
|
---|
35 | @retval TRUE lang is in supported language codes.
|
---|
36 | @retval FALSE lang is not in supported language codes.
|
---|
37 |
|
---|
38 | **/
|
---|
39 | BOOLEAN
|
---|
40 | IsLangInSupportedLangCodes(
|
---|
41 | IN CHAR8 *SupportedLang,
|
---|
42 | IN CHAR8 *Lang,
|
---|
43 | IN BOOLEAN Iso639Language
|
---|
44 | )
|
---|
45 | {
|
---|
46 | UINTN Index;
|
---|
47 | UINTN CompareLength;
|
---|
48 | UINTN LanguageLength;
|
---|
49 |
|
---|
50 | if (Iso639Language) {
|
---|
51 | CompareLength = ISO_639_2_ENTRY_SIZE;
|
---|
52 | for (Index = 0; Index < AsciiStrLen (SupportedLang); Index += CompareLength) {
|
---|
53 | if (AsciiStrnCmp (Lang, SupportedLang + Index, CompareLength) == 0) {
|
---|
54 | //
|
---|
55 | // Successfully find the Lang string in SupportedLang string.
|
---|
56 | //
|
---|
57 | return TRUE;
|
---|
58 | }
|
---|
59 | }
|
---|
60 | return FALSE;
|
---|
61 | } else {
|
---|
62 | //
|
---|
63 | // Compare RFC4646 language code
|
---|
64 | //
|
---|
65 | for (LanguageLength = 0; Lang[LanguageLength] != '\0'; LanguageLength++);
|
---|
66 |
|
---|
67 | for (; *SupportedLang != '\0'; SupportedLang += CompareLength) {
|
---|
68 | //
|
---|
69 | // Skip ';' characters in SupportedLang
|
---|
70 | //
|
---|
71 | for (; *SupportedLang != '\0' && *SupportedLang == ';'; SupportedLang++);
|
---|
72 | //
|
---|
73 | // Determine the length of the next language code in SupportedLang
|
---|
74 | //
|
---|
75 | for (CompareLength = 0; SupportedLang[CompareLength] != '\0' && SupportedLang[CompareLength] != ';'; CompareLength++);
|
---|
76 |
|
---|
77 | if ((CompareLength == LanguageLength) &&
|
---|
78 | (AsciiStrnCmp (Lang, SupportedLang, CompareLength) == 0)) {
|
---|
79 | //
|
---|
80 | // Successfully find the Lang string in SupportedLang string.
|
---|
81 | //
|
---|
82 | return TRUE;
|
---|
83 | }
|
---|
84 | }
|
---|
85 | return FALSE;
|
---|
86 | }
|
---|
87 | }
|
---|
88 |
|
---|
89 | /**
|
---|
90 | Initialize Lang or PlatformLang variable, if Lang or PlatformLang variable is not found,
|
---|
91 | or it has been set to an unsupported value(not one of platform supported language codes),
|
---|
92 | set the default language code to it.
|
---|
93 |
|
---|
94 | @param LangName Language name, L"Lang" or L"PlatformLang".
|
---|
95 | @param SupportedLang Platform supported language codes.
|
---|
96 | @param DefaultLang Default language code.
|
---|
97 | @param Iso639Language A bool value to signify if the handler is operated on ISO639 or RFC4646,
|
---|
98 | TRUE for L"Lang" LangName or FALSE for L"PlatformLang" LangName.
|
---|
99 |
|
---|
100 | **/
|
---|
101 | VOID
|
---|
102 | InitializeLangVariable (
|
---|
103 | IN CHAR16 *LangName,
|
---|
104 | IN CHAR8 *SupportedLang,
|
---|
105 | IN CHAR8 *DefaultLang,
|
---|
106 | IN BOOLEAN Iso639Language
|
---|
107 | )
|
---|
108 | {
|
---|
109 | CHAR8 *Lang;
|
---|
110 |
|
---|
111 | //
|
---|
112 | // Find current Lang or PlatformLang from EFI Variable.
|
---|
113 | //
|
---|
114 | GetEfiGlobalVariable2 (LangName, (VOID **) &Lang, NULL);
|
---|
115 |
|
---|
116 | //
|
---|
117 | // If Lang or PlatformLang variable is not found,
|
---|
118 | // or it has been set to an unsupported value(not one of the supported language codes),
|
---|
119 | // set the default language code to it.
|
---|
120 | //
|
---|
121 | if ((Lang == NULL) || !IsLangInSupportedLangCodes (SupportedLang, Lang, Iso639Language)) {
|
---|
122 | //
|
---|
123 | // The default language code should be one of the supported language codes.
|
---|
124 | //
|
---|
125 | ASSERT (IsLangInSupportedLangCodes (SupportedLang, DefaultLang, Iso639Language));
|
---|
126 | BdsDxeSetVariableAndReportStatusCodeOnError (
|
---|
127 | LangName,
|
---|
128 | &gEfiGlobalVariableGuid,
|
---|
129 | EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
---|
130 | AsciiStrSize (DefaultLang),
|
---|
131 | DefaultLang
|
---|
132 | );
|
---|
133 | }
|
---|
134 |
|
---|
135 | if (Lang != NULL) {
|
---|
136 | FreePool (Lang);
|
---|
137 | }
|
---|
138 | }
|
---|
139 |
|
---|
140 | /**
|
---|
141 | Determine the current language that will be used
|
---|
142 | based on language related EFI Variables.
|
---|
143 |
|
---|
144 | @param LangCodesSettingRequired - If required to set LangCodes variable
|
---|
145 |
|
---|
146 | **/
|
---|
147 | VOID
|
---|
148 | InitializeLanguage (
|
---|
149 | BOOLEAN LangCodesSettingRequired
|
---|
150 | )
|
---|
151 | {
|
---|
152 | EFI_STATUS Status;
|
---|
153 | CHAR8 *LangCodes;
|
---|
154 | CHAR8 *PlatformLangCodes;
|
---|
155 |
|
---|
156 | LangCodes = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultLangCodes);
|
---|
157 | PlatformLangCodes = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes);
|
---|
158 | if (LangCodesSettingRequired) {
|
---|
159 | if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
|
---|
160 | //
|
---|
161 | // UEFI 2.1 depricated this variable so we support turning it off
|
---|
162 | //
|
---|
163 | Status = gRT->SetVariable (
|
---|
164 | L"LangCodes",
|
---|
165 | &gEfiGlobalVariableGuid,
|
---|
166 | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
---|
167 | AsciiStrSize (LangCodes),
|
---|
168 | LangCodes
|
---|
169 | );
|
---|
170 | //
|
---|
171 | // Platform needs to make sure setting volatile variable before calling 3rd party code shouldn't fail.
|
---|
172 | //
|
---|
173 | ASSERT_EFI_ERROR(Status);
|
---|
174 | }
|
---|
175 |
|
---|
176 | Status = gRT->SetVariable (
|
---|
177 | L"PlatformLangCodes",
|
---|
178 | &gEfiGlobalVariableGuid,
|
---|
179 | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
---|
180 | AsciiStrSize (PlatformLangCodes),
|
---|
181 | PlatformLangCodes
|
---|
182 | );
|
---|
183 | //
|
---|
184 | // Platform needs to make sure setting volatile variable before calling 3rd party code shouldn't fail.
|
---|
185 | //
|
---|
186 | ASSERT_EFI_ERROR(Status);
|
---|
187 | }
|
---|
188 |
|
---|
189 | if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
|
---|
190 | //
|
---|
191 | // UEFI 2.1 depricated this variable so we support turning it off
|
---|
192 | //
|
---|
193 | InitializeLangVariable (L"Lang", LangCodes, (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang), TRUE);
|
---|
194 | }
|
---|
195 | InitializeLangVariable (L"PlatformLang", PlatformLangCodes, (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang), FALSE);
|
---|
196 | }
|
---|