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 |
|
---|
61 | return FALSE;
|
---|
62 | } else {
|
---|
63 | //
|
---|
64 | // Compare RFC4646 language code
|
---|
65 | //
|
---|
66 | for (LanguageLength = 0; Lang[LanguageLength] != '\0'; LanguageLength++) {
|
---|
67 | }
|
---|
68 |
|
---|
69 | for ( ; *SupportedLang != '\0'; SupportedLang += CompareLength) {
|
---|
70 | //
|
---|
71 | // Skip ';' characters in SupportedLang
|
---|
72 | //
|
---|
73 | for ( ; *SupportedLang != '\0' && *SupportedLang == ';'; SupportedLang++) {
|
---|
74 | }
|
---|
75 |
|
---|
76 | //
|
---|
77 | // Determine the length of the next language code in SupportedLang
|
---|
78 | //
|
---|
79 | for (CompareLength = 0; SupportedLang[CompareLength] != '\0' && SupportedLang[CompareLength] != ';'; CompareLength++) {
|
---|
80 | }
|
---|
81 |
|
---|
82 | if ((CompareLength == LanguageLength) &&
|
---|
83 | (AsciiStrnCmp (Lang, SupportedLang, CompareLength) == 0))
|
---|
84 | {
|
---|
85 | //
|
---|
86 | // Successfully find the Lang string in SupportedLang string.
|
---|
87 | //
|
---|
88 | return TRUE;
|
---|
89 | }
|
---|
90 | }
|
---|
91 |
|
---|
92 | return FALSE;
|
---|
93 | }
|
---|
94 | }
|
---|
95 |
|
---|
96 | /**
|
---|
97 | Initialize Lang or PlatformLang variable, if Lang or PlatformLang variable is not found,
|
---|
98 | or it has been set to an unsupported value(not one of platform supported language codes),
|
---|
99 | set the default language code to it.
|
---|
100 |
|
---|
101 | @param LangName Language name, L"Lang" or L"PlatformLang".
|
---|
102 | @param SupportedLang Platform supported language codes.
|
---|
103 | @param DefaultLang Default language code.
|
---|
104 | @param Iso639Language A bool value to signify if the handler is operated on ISO639 or RFC4646,
|
---|
105 | TRUE for L"Lang" LangName or FALSE for L"PlatformLang" LangName.
|
---|
106 |
|
---|
107 | **/
|
---|
108 | VOID
|
---|
109 | InitializeLangVariable (
|
---|
110 | IN CHAR16 *LangName,
|
---|
111 | IN CHAR8 *SupportedLang,
|
---|
112 | IN CHAR8 *DefaultLang,
|
---|
113 | IN BOOLEAN Iso639Language
|
---|
114 | )
|
---|
115 | {
|
---|
116 | CHAR8 *Lang;
|
---|
117 |
|
---|
118 | //
|
---|
119 | // Find current Lang or PlatformLang from EFI Variable.
|
---|
120 | //
|
---|
121 | GetEfiGlobalVariable2 (LangName, (VOID **)&Lang, NULL);
|
---|
122 |
|
---|
123 | //
|
---|
124 | // If Lang or PlatformLang variable is not found,
|
---|
125 | // or it has been set to an unsupported value(not one of the supported language codes),
|
---|
126 | // set the default language code to it.
|
---|
127 | //
|
---|
128 | if ((Lang == NULL) || !IsLangInSupportedLangCodes (SupportedLang, Lang, Iso639Language)) {
|
---|
129 | //
|
---|
130 | // The default language code should be one of the supported language codes.
|
---|
131 | //
|
---|
132 | ASSERT (IsLangInSupportedLangCodes (SupportedLang, DefaultLang, Iso639Language));
|
---|
133 | BdsDxeSetVariableAndReportStatusCodeOnError (
|
---|
134 | LangName,
|
---|
135 | &gEfiGlobalVariableGuid,
|
---|
136 | EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
---|
137 | AsciiStrSize (DefaultLang),
|
---|
138 | DefaultLang
|
---|
139 | );
|
---|
140 | }
|
---|
141 |
|
---|
142 | if (Lang != NULL) {
|
---|
143 | FreePool (Lang);
|
---|
144 | }
|
---|
145 | }
|
---|
146 |
|
---|
147 | /**
|
---|
148 | Determine the current language that will be used
|
---|
149 | based on language related EFI Variables.
|
---|
150 |
|
---|
151 | @param LangCodesSettingRequired - If required to set LangCodes variable
|
---|
152 |
|
---|
153 | **/
|
---|
154 | VOID
|
---|
155 | InitializeLanguage (
|
---|
156 | BOOLEAN LangCodesSettingRequired
|
---|
157 | )
|
---|
158 | {
|
---|
159 | EFI_STATUS Status;
|
---|
160 | CHAR8 *LangCodes;
|
---|
161 | CHAR8 *PlatformLangCodes;
|
---|
162 |
|
---|
163 | LangCodes = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultLangCodes);
|
---|
164 | PlatformLangCodes = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes);
|
---|
165 | if (LangCodesSettingRequired) {
|
---|
166 | if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
|
---|
167 | //
|
---|
168 | // UEFI 2.1 depricated this variable so we support turning it off
|
---|
169 | //
|
---|
170 | Status = gRT->SetVariable (
|
---|
171 | L"LangCodes",
|
---|
172 | &gEfiGlobalVariableGuid,
|
---|
173 | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
---|
174 | AsciiStrSize (LangCodes),
|
---|
175 | LangCodes
|
---|
176 | );
|
---|
177 | //
|
---|
178 | // Platform needs to make sure setting volatile variable before calling 3rd party code shouldn't fail.
|
---|
179 | //
|
---|
180 | ASSERT_EFI_ERROR (Status);
|
---|
181 | }
|
---|
182 |
|
---|
183 | Status = gRT->SetVariable (
|
---|
184 | L"PlatformLangCodes",
|
---|
185 | &gEfiGlobalVariableGuid,
|
---|
186 | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
---|
187 | AsciiStrSize (PlatformLangCodes),
|
---|
188 | PlatformLangCodes
|
---|
189 | );
|
---|
190 | //
|
---|
191 | // Platform needs to make sure setting volatile variable before calling 3rd party code shouldn't fail.
|
---|
192 | //
|
---|
193 | ASSERT_EFI_ERROR (Status);
|
---|
194 | }
|
---|
195 |
|
---|
196 | if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
|
---|
197 | //
|
---|
198 | // UEFI 2.1 depricated this variable so we support turning it off
|
---|
199 | //
|
---|
200 | InitializeLangVariable (L"Lang", LangCodes, (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultLang), TRUE);
|
---|
201 | }
|
---|
202 |
|
---|
203 | InitializeLangVariable (L"PlatformLang", PlatformLangCodes, (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLang), FALSE);
|
---|
204 | }
|
---|