OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
OcUnicodeCollationEngCommon.c
Go to the documentation of this file.
1
10
14
15CHAR8 mOtherChars[] = {
16 '0',
17 '1',
18 '2',
19 '3',
20 '4',
21 '5',
22 '6',
23 '7',
24 '8',
25 '9',
26 '\\',
27 '.',
28 '_',
29 '^',
30 '$',
31 '~',
32 '!',
33 '#',
34 '%',
35 '&',
36 '-',
37 '{',
38 '}',
39 '(',
40 ')',
41 '@',
42 '`',
43 '\'',
44 '\0'
45};
46
47//
48// Supported language list, meant to contain one extra language if necessary.
49//
50STATIC CHAR8 UnicodeLanguages[6] = "en";
51
52//
53// EFI Unicode Collation2 Protocol supporting RFC 4646 language code
54//
55GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_COLLATION_PROTOCOL gInternalUnicode2Eng = {
63};
64
65VOID
67 VOID
68 )
69{
70 EFI_STATUS Status;
71 CHAR8 *PlatformLang;
72 UINTN Size;
73
74 //
75 // On several platforms EFI_PLATFORM_LANG_VARIABLE_NAME is not available.
76 // Fallback to "en-US" which is supported by this library and the wide majority of others.
77 //
78 Size = 0;
79 PlatformLang = NULL;
80 Status = gRT->GetVariable (
81 EFI_PLATFORM_LANG_VARIABLE_NAME,
83 NULL,
84 &Size,
85 PlatformLang
86 );
87 if (Status == EFI_BUFFER_TOO_SMALL) {
88 Status = gBS->AllocatePool (
89 EfiBootServicesData,
90 Size,
91 (VOID **)&PlatformLang
92 );
93 if (!EFI_ERROR (Status)) {
94 Status = gRT->GetVariable (
95 EFI_PLATFORM_LANG_VARIABLE_NAME,
97 NULL,
98 &Size,
99 PlatformLang
100 );
101 if (EFI_ERROR (Status)) {
102 gBS->FreePool (PlatformLang);
103 }
104 }
105 }
106
107 if (!EFI_ERROR (Status)) {
108 if (AsciiStrnLenS (PlatformLang, Size) < 2) {
109 gBS->FreePool (PlatformLang);
110 PlatformLang = NULL;
111 }
112 } else {
113 PlatformLang = NULL;
114 }
115
116 if (PlatformLang == NULL) {
117 //
118 // No value or something broken, discard and fallback.
119 //
120 gRT->SetVariable (
121 EFI_PLATFORM_LANG_VARIABLE_NAME,
123 EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
124 sizeof ("en-US"),
125 "en-US"
126 );
127 } else if (AsciiStrnCmp (PlatformLang, "en", 2) != 0) {
128 //
129 // On some platforms with missing gEfiUnicodeCollation2ProtocolGuid EFI_PLATFORM_LANG_VARIABLE_NAME is set
130 // to the value different from "en" or "en-...". This is not going to work with our driver and UEFI Shell
131 // will fail to load. Since we did not overwrite EFI_PLATFORM_LANG_VARIABLE_NAME, and it uses some other language,
132 // workaround by appending the other language to the list of supported ones.
133 //
135 sizeof (UnicodeLanguages) == 6 && sizeof (UnicodeLanguages[0]) == 1,
136 "UnicodeLanguages must contain one extra language"
137 );
138 UnicodeLanguages[2] = ';';
139 UnicodeLanguages[3] = PlatformLang[0];
140 UnicodeLanguages[4] = PlatformLang[1];
141 UnicodeLanguages[5] = '\0';
142 }
143
144 //
145 // Free allocated memory for platform languages
146 //
147 if (PlatformLang != NULL) {
148 gBS->FreePool (PlatformLang);
149 }
150}
151
152VOID
154 VOID
155 )
156{
157 UINTN Index;
158 UINTN Index2;
159
160 //
161 // Initialize mapping tables for the supported languages
162 //
163 for (Index = 0; Index < MAP_TABLE_SIZE; Index++) {
164 mEngUpperMap[Index] = (CHAR8)Index;
165 mEngLowerMap[Index] = (CHAR8)Index;
166 mEngInfoMap[Index] = 0;
167
168 if (((Index >= 'a') && (Index <= 'z')) || ((Index >= 0xe0) && (Index <= 0xf6)) || ((Index >= 0xf8) && (Index <= 0xfe))) {
169 Index2 = Index - 0x20;
170 mEngUpperMap[Index] = (CHAR8)Index2;
171 mEngLowerMap[Index2] = (CHAR8)Index;
172
173 mEngInfoMap[Index] |= CHAR_FAT_VALID;
174 mEngInfoMap[Index2] |= CHAR_FAT_VALID;
175 }
176 }
177
178 for (Index = 0; mOtherChars[Index] != 0; Index++) {
179 Index2 = mOtherChars[Index];
180 mEngInfoMap[Index2] |= CHAR_FAT_VALID;
181 }
182}
183
196INTN
197EFIAPI
199 IN EFI_UNICODE_COLLATION_PROTOCOL *This,
200 IN CHAR16 *Str1,
201 IN CHAR16 *Str2
202 )
203{
204 while (*Str1 != 0) {
205 if (TO_UPPER (*Str1) != TO_UPPER (*Str2)) {
206 break;
207 }
208
209 Str1 += 1;
210 Str2 += 1;
211 }
212
213 return TO_UPPER (*Str1) - TO_UPPER (*Str2);
214}
215
224VOID
225EFIAPI
227 IN EFI_UNICODE_COLLATION_PROTOCOL *This,
228 IN OUT CHAR16 *Str
229 )
230{
231 while (*Str != 0) {
232 *Str = TO_LOWER (*Str);
233 Str += 1;
234 }
235}
236
245VOID
246EFIAPI
248 IN EFI_UNICODE_COLLATION_PROTOCOL *This,
249 IN OUT CHAR16 *Str
250 )
251{
252 while (*Str != 0) {
253 *Str = TO_UPPER (*Str);
254 Str += 1;
255 }
256}
257
270BOOLEAN
271EFIAPI
273 IN EFI_UNICODE_COLLATION_PROTOCOL *This,
274 IN CHAR16 *String,
275 IN CHAR16 *Pattern
276 )
277{
278 CHAR16 CharC;
279 CHAR16 CharP;
280 CHAR16 Index3;
281
282 for ( ; ;) {
283 CharP = *Pattern;
284 Pattern += 1;
285
286 switch (CharP) {
287 case 0:
288 //
289 // End of pattern. If end of string, TRUE match
290 //
291 if (*String != 0) {
292 return FALSE;
293 } else {
294 return TRUE;
295 }
296
297 case '*':
298 //
299 // Match zero or more chars
300 //
301 while (*String != 0) {
302 if (EngMetaiMatch (This, String, Pattern)) {
303 return TRUE;
304 }
305
306 String += 1;
307 }
308
309 return EngMetaiMatch (This, String, Pattern);
310
311 case '?':
312 //
313 // Match any one char
314 //
315 if (*String == 0) {
316 return FALSE;
317 }
318
319 String += 1;
320 break;
321
322 case '[':
323 //
324 // Match char set
325 //
326 CharC = *String;
327 if (CharC == 0) {
328 //
329 // syntax problem
330 //
331 return FALSE;
332 }
333
334 Index3 = 0;
335 CharP = *Pattern++;
336 while (CharP != 0) {
337 if (CharP == ']') {
338 return FALSE;
339 }
340
341 if (CharP == '-') {
342 //
343 // if range of chars, get high range
344 //
345 CharP = *Pattern;
346 if ((CharP == 0) || (CharP == ']')) {
347 //
348 // syntax problem
349 //
350 return FALSE;
351 }
352
353 if ((TO_UPPER (CharC) >= TO_UPPER (Index3)) && (TO_UPPER (CharC) <= TO_UPPER (CharP))) {
354 //
355 // if in range, it's a match
356 //
357 break;
358 }
359 }
360
361 Index3 = CharP;
362 if (TO_UPPER (CharC) == TO_UPPER (CharP)) {
363 //
364 // if char matches
365 //
366 break;
367 }
368
369 CharP = *Pattern++;
370 }
371
372 //
373 // skip to end of match char set
374 //
375 while ((CharP != 0) && (CharP != ']')) {
376 CharP = *Pattern;
377 Pattern += 1;
378 }
379
380 String += 1;
381 break;
382
383 default:
384 CharC = *String;
385 if (TO_UPPER (CharC) != TO_UPPER (CharP)) {
386 return FALSE;
387 }
388
389 String += 1;
390 break;
391 }
392 }
393}
394
406VOID
407EFIAPI
409 IN EFI_UNICODE_COLLATION_PROTOCOL *This,
410 IN UINTN FatSize,
411 IN CHAR8 *Fat,
412 OUT CHAR16 *String
413 )
414{
415 //
416 // No DBCS issues, just expand and add null terminate to end of string
417 //
418 while ((*Fat != 0) && (FatSize != 0)) {
419 *String = *Fat;
420 String += 1;
421 Fat += 1;
422 FatSize -= 1;
423 }
424
425 *String = 0;
426}
427
443BOOLEAN
444EFIAPI
446 IN EFI_UNICODE_COLLATION_PROTOCOL *This,
447 IN CHAR16 *String,
448 IN UINTN FatSize,
449 OUT CHAR8 *Fat
450 )
451{
452 BOOLEAN SpecialCharExist;
453
454 SpecialCharExist = FALSE;
455 while ((*String != 0) && (FatSize != 0)) {
456 //
457 // Skip '.' or ' ' when making a fat name
458 //
459 if ((*String != '.') && (*String != ' ')) {
460 //
461 // If this is a valid fat char, move it.
462 // Otherwise, move a '_' and flag the fact that the name needs a long file name.
463 //
464 if ((*String < MAP_TABLE_SIZE) && ((mEngInfoMap[*String] & CHAR_FAT_VALID) != 0)) {
465 *Fat = mEngUpperMap[*String];
466 } else {
467 *Fat = '_';
468 SpecialCharExist = TRUE;
469 }
470
471 Fat += 1;
472 FatSize -= 1;
473 }
474
475 String += 1;
476 }
477
478 //
479 // Do not terminate that fat string
480 //
481 return SpecialCharExist;
482}
DMG_SIZE_DEVICE_PATH Size
STATIC_ASSERT(BYTES_PER_PIXEL==sizeof(UINT32), "Non 4-byte pixels are unsupported!")
EFI_BOOT_SERVICES * gBS
VOID OcUnicodeCollationInitializeMappingTables(VOID)
STATIC CHAR8 UnicodeLanguages[6]
BOOLEAN EFIAPI EngStrToFat(IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN CHAR16 *String, IN UINTN FatSize, OUT CHAR8 *Fat)
CHAR8 mOtherChars[]
VOID EFIAPI EngStrLwr(IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN OUT CHAR16 *Str)
VOID EFIAPI EngFatToStr(IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN UINTN FatSize, IN CHAR8 *Fat, OUT CHAR16 *String)
VOID OcUnicodeCollationUpdatePlatformLanguage(VOID)
VOID EFIAPI EngStrUpr(IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN OUT CHAR16 *Str)
CHAR8 mEngLowerMap[MAP_TABLE_SIZE]
CHAR8 mEngUpperMap[MAP_TABLE_SIZE]
BOOLEAN EFIAPI EngMetaiMatch(IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN CHAR16 *String, IN CHAR16 *Pattern)
CHAR8 mEngInfoMap[MAP_TABLE_SIZE]
INTN EFIAPI EngStriColl(IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN CHAR16 *Str1, IN CHAR16 *Str2)
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_COLLATION_PROTOCOL gInternalUnicode2Eng
#define TO_UPPER(a)
#define MAP_TABLE_SIZE
#define CHAR_FAT_VALID
#define TO_LOWER(a)
EFI_RUNTIME_SERVICES * gRT
EFI_GUID gEfiGlobalVariableGuid