]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/UefiLib/UefiLib.c
fix no ascii char
[mirror_edk2.git] / MdePkg / Library / UefiLib / UefiLib.c
CommitLineData
e386b444 1/** @file\r
2 Mde UEFI library functions.\r
3\r
4 Copyright (c) 2006 - 2007, Intel Corporation<BR>\r
5 All rights reserved. This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
e386b444 13**/\r
14\r
1efcc4ae 15\r
f734a10a 16#include "UefiLibInternal.h"\r
e386b444 17\r
18/**\r
19 Compare whether two names of languages are identical.\r
20\r
21 @param Language1 Name of language 1.\r
22 @param Language2 Name of language 2.\r
23\r
24 @retval TRUE Language 1 and language 2 are the same.\r
25 @retval FALSE Language 1 and language 2 are not the same.\r
26\r
27**/\r
e386b444 28BOOLEAN\r
29CompareIso639LanguageCode (\r
30 IN CONST CHAR8 *Language1,\r
31 IN CONST CHAR8 *Language2\r
32 )\r
33{\r
34 UINT32 Name1;\r
35 UINT32 Name2;\r
36\r
37 Name1 = ReadUnaligned24 ((CONST UINT32 *) Language1);\r
38 Name2 = ReadUnaligned24 ((CONST UINT32 *) Language2);\r
39\r
40 return (BOOLEAN) (Name1 == Name2);\r
41}\r
42\r
43/**\r
44 This function searches the list of configuration tables stored in the EFI System\r
45 Table for a table with a GUID that matches TableGuid. If a match is found,\r
46 then a pointer to the configuration table is returned in Table, and EFI_SUCCESS\r
47 is returned. If a matching GUID is not found, then EFI_NOT_FOUND is returned.\r
9edc73ad 48 If TableGuid is NULL, then ASSERT().\r
49 If Table is NULL, then ASSERT().\r
e386b444 50\r
51 @param TableGuid Pointer to table's GUID type..\r
52 @param Table Pointer to the table associated with TableGuid in the EFI System Table.\r
53\r
54 @retval EFI_SUCCESS A configuration table matching TableGuid was found.\r
55 @retval EFI_NOT_FOUND A configuration table matching TableGuid could not be found.\r
56\r
57**/\r
58EFI_STATUS\r
59EFIAPI\r
60EfiGetSystemConfigurationTable (\r
61 IN EFI_GUID *TableGuid,\r
62 OUT VOID **Table\r
63 )\r
64{\r
65 EFI_SYSTEM_TABLE *SystemTable;\r
66 UINTN Index;\r
67\r
68 ASSERT (TableGuid != NULL);\r
69 ASSERT (Table != NULL);\r
70\r
71 SystemTable = gST;\r
72 *Table = NULL;\r
73 for (Index = 0; Index < SystemTable->NumberOfTableEntries; Index++) {\r
74 if (CompareGuid (TableGuid, &(SystemTable->ConfigurationTable[Index].VendorGuid))) {\r
75 *Table = SystemTable->ConfigurationTable[Index].VendorTable;\r
76 return EFI_SUCCESS;\r
77 }\r
78 }\r
79\r
80 return EFI_NOT_FOUND;\r
81}\r
82\r
83/**\r
84 This function causes the notification function to be executed for every protocol\r
85 of type ProtocolGuid instance that exists in the system when this function is\r
86 invoked. In addition, every time a protocol of type ProtocolGuid instance is\r
87 installed or reinstalled, the notification function is also executed.\r
88\r
89 @param ProtocolGuid Supplies GUID of the protocol upon whose installation the event is fired.\r
90 @param NotifyTpl Supplies the task priority level of the event notifications.\r
91 @param NotifyFunction Supplies the function to notify when the event is signaled.\r
92 @param NotifyContext The context parameter to pass to NotifyFunction.\r
93 @param Registration A pointer to a memory location to receive the registration value.\r
94\r
95 @return The notification event that was created.\r
96\r
97**/\r
98EFI_EVENT\r
99EFIAPI\r
100EfiCreateProtocolNotifyEvent(\r
101 IN EFI_GUID *ProtocolGuid,\r
102 IN EFI_TPL NotifyTpl,\r
103 IN EFI_EVENT_NOTIFY NotifyFunction,\r
104 IN VOID *NotifyContext, OPTIONAL\r
105 OUT VOID **Registration\r
106 )\r
107{\r
108 EFI_STATUS Status;\r
109 EFI_EVENT Event;\r
110\r
111 //\r
112 // Create the event\r
113 //\r
114\r
115 Status = gBS->CreateEvent (\r
116 EVT_NOTIFY_SIGNAL,\r
117 NotifyTpl,\r
118 NotifyFunction,\r
119 NotifyContext,\r
120 &Event\r
121 );\r
122 ASSERT_EFI_ERROR (Status);\r
123\r
124 //\r
125 // Register for protocol notifactions on this event\r
126 //\r
127\r
128 Status = gBS->RegisterProtocolNotify (\r
129 ProtocolGuid,\r
130 Event,\r
131 Registration\r
132 );\r
133\r
134 ASSERT_EFI_ERROR (Status);\r
135\r
136 //\r
137 // Kick the event so we will perform an initial pass of\r
138 // current installed drivers\r
139 //\r
140\r
141 gBS->SignalEvent (Event);\r
142 return Event;\r
143}\r
144\r
145/**\r
146 This function creates an event using NotifyTpl, NoifyFunction, and NotifyContext.\r
147 This event is signaled with EfiNamedEventSignal(). This provide the ability for\r
148 one or more listeners on the same event named by the GUID specified by Name.\r
9edc73ad 149 If Name is NULL, then ASSERT().\r
150 If NotifyTpl is not a legal TPL value, then ASSERT().\r
151 If NotifyFunction is NULL, then ASSERT().\r
e386b444 152\r
153 @param Name Supplies GUID name of the event.\r
154 @param NotifyTpl Supplies the task priority level of the event notifications.\r
155 @param NotifyFunction Supplies the function to notify when the event is signaled.\r
156 @param NotifyContext The context parameter to pass to NotifyFunction.\r
157 @param Registration A pointer to a memory location to receive the registration value.\r
158\r
159 @retval EFI_SUCCESS A named event was created.\r
160 @retval EFI_OUT_OF_RESOURCES There are not enough resource to create the named event.\r
161\r
162**/\r
163EFI_STATUS\r
164EFIAPI\r
165EfiNamedEventListen (\r
166 IN CONST EFI_GUID *Name,\r
167 IN EFI_TPL NotifyTpl,\r
168 IN EFI_EVENT_NOTIFY NotifyFunction,\r
169 IN CONST VOID *NotifyContext, OPTIONAL\r
170 OUT VOID *Registration OPTIONAL\r
171 )\r
172{\r
173 EFI_STATUS Status;\r
174 EFI_EVENT Event;\r
175 VOID *RegistrationLocal;\r
176\r
9edc73ad 177 ASSERT (Name != NULL);\r
178 ASSERT (NotifyFunction != NULL);\r
179 ASSERT (NotifyTpl <= TPL_HIGH_LEVEL);\r
180 \r
e386b444 181 //\r
182 // Create event\r
183 //\r
184 Status = gBS->CreateEvent (\r
185 EVT_NOTIFY_SIGNAL,\r
186 NotifyTpl,\r
187 NotifyFunction,\r
188 (VOID *) NotifyContext,\r
189 &Event\r
190 );\r
191 ASSERT_EFI_ERROR (Status);\r
192\r
193 //\r
194 // The Registration is not optional to RegisterProtocolNotify().\r
195 // To make it optional to EfiNamedEventListen(), may need to substitute with a local.\r
196 //\r
197 if (Registration != NULL) {\r
198 RegistrationLocal = Registration;\r
199 } else {\r
200 RegistrationLocal = &RegistrationLocal;\r
201 }\r
202\r
203 //\r
204 // Register for an installation of protocol interface\r
205 //\r
206\r
207 Status = gBS->RegisterProtocolNotify (\r
208 (EFI_GUID *) Name,\r
209 Event,\r
210 RegistrationLocal\r
211 );\r
212 ASSERT_EFI_ERROR (Status);\r
213\r
9edc73ad 214 return Status;\r
e386b444 215}\r
216\r
217/**\r
218 This function signals the named event specified by Name. The named event must\r
219 have been created with EfiNamedEventListen().\r
220\r
221 @param Name Supplies GUID name of the event.\r
222\r
223 @retval EFI_SUCCESS A named event was signaled.\r
224 @retval EFI_OUT_OF_RESOURCES There are not enough resource to signal the named event.\r
225\r
226**/\r
227EFI_STATUS\r
228EFIAPI\r
229EfiNamedEventSignal (\r
230 IN CONST EFI_GUID *Name\r
231 )\r
232{\r
233 EFI_STATUS Status;\r
234 EFI_HANDLE Handle;\r
235\r
236 Handle = NULL;\r
237 Status = gBS->InstallProtocolInterface (\r
238 &Handle,\r
239 (EFI_GUID *) Name,\r
240 EFI_NATIVE_INTERFACE,\r
241 NULL\r
242 );\r
243 ASSERT_EFI_ERROR (Status);\r
244\r
245 Status = gBS->UninstallProtocolInterface (\r
246 Handle,\r
247 (EFI_GUID *) Name,\r
248 NULL\r
249 );\r
250 ASSERT_EFI_ERROR (Status);\r
251\r
9edc73ad 252 return Status;\r
e386b444 253}\r
254\r
255/**\r
256 Returns the current TPL.\r
257\r
258 This function returns the current TPL. There is no EFI service to directly\r
259 retrieve the current TPL. Instead, the RaiseTPL() function is used to raise\r
260 the TPL to TPL_HIGH_LEVEL. This will return the current TPL. The TPL level\r
261 can then immediately be restored back to the current TPL level with a call\r
262 to RestoreTPL().\r
263\r
264 @param VOID\r
265\r
42eedea9 266 @retval EFI_TPL The current TPL.\r
e386b444 267\r
268**/\r
269EFI_TPL\r
270EFIAPI\r
271EfiGetCurrentTpl (\r
272 VOID\r
273 )\r
274{\r
275 EFI_TPL Tpl;\r
276\r
277 Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
278 gBS->RestoreTPL (Tpl);\r
279\r
280 return Tpl;\r
281}\r
282\r
283\r
284/**\r
285 This function initializes a basic mutual exclusion lock to the released state\r
286 and returns the lock. Each lock provides mutual exclusion access at its task\r
287 priority level. Since there is no preemption or multiprocessor support in EFI,\r
288 acquiring the lock only consists of raising to the locks TPL.\r
9edc73ad 289 If Lock is NULL, then ASSERT().\r
290 If Priority is not a valid TPL value, then ASSERT().\r
e386b444 291\r
292 @param Lock A pointer to the lock data structure to initialize.\r
293 @param Priority EFI TPL associated with the lock.\r
294\r
295 @return The lock.\r
296\r
297**/\r
298EFI_LOCK *\r
299EFIAPI\r
300EfiInitializeLock (\r
301 IN OUT EFI_LOCK *Lock,\r
302 IN EFI_TPL Priority\r
303 )\r
304{\r
305 ASSERT (Lock != NULL);\r
306 ASSERT (Priority <= TPL_HIGH_LEVEL);\r
307\r
308 Lock->Tpl = Priority;\r
309 Lock->OwnerTpl = TPL_APPLICATION;\r
310 Lock->Lock = EfiLockReleased ;\r
311 return Lock;\r
312}\r
313\r
314/**\r
315 This function raises the system's current task priority level to the task\r
316 priority level of the mutual exclusion lock. Then, it places the lock in the\r
317 acquired state.\r
9edc73ad 318 If Lock is NULL, then ASSERT().\r
319 If Lock is not initialized, then ASSERT().\r
320 If Lock is already in the acquired state, then ASSERT().\r
e386b444 321\r
42eedea9 322 @param Lock The task lock with priority level.\r
e386b444 323\r
324**/\r
325VOID\r
326EFIAPI\r
327EfiAcquireLock (\r
328 IN EFI_LOCK *Lock\r
329 )\r
330{\r
331 ASSERT (Lock != NULL);\r
332 ASSERT (Lock->Lock == EfiLockReleased);\r
333\r
334 Lock->OwnerTpl = gBS->RaiseTPL (Lock->Tpl);\r
335 Lock->Lock = EfiLockAcquired;\r
336}\r
337\r
338/**\r
339 This function raises the system's current task priority level to the task\r
340 priority level of the mutual exclusion lock. Then, it attempts to place the\r
341 lock in the acquired state.\r
342\r
343 @param Lock A pointer to the lock to acquire.\r
344\r
345 @retval EFI_SUCCESS The lock was acquired.\r
346 @retval EFI_ACCESS_DENIED The lock could not be acquired because it is already owned.\r
347\r
348**/\r
349EFI_STATUS\r
350EFIAPI\r
351EfiAcquireLockOrFail (\r
352 IN EFI_LOCK *Lock\r
353 )\r
354{\r
355\r
356 ASSERT (Lock != NULL);\r
357 ASSERT (Lock->Lock != EfiLockUninitialized);\r
358\r
359 if (Lock->Lock == EfiLockAcquired) {\r
360 //\r
361 // Lock is already owned, so bail out\r
362 //\r
363 return EFI_ACCESS_DENIED;\r
364 }\r
365\r
366 Lock->OwnerTpl = gBS->RaiseTPL (Lock->Tpl);\r
367\r
368 Lock->Lock = EfiLockAcquired;\r
369\r
370 return EFI_SUCCESS;\r
371}\r
372\r
373/**\r
374 This function transitions a mutual exclusion lock from the acquired state to\r
375 the released state, and restores the system's task priority level to its\r
376 previous level.\r
377\r
378 @param Lock A pointer to the lock to release.\r
379\r
380**/\r
381VOID\r
382EFIAPI\r
383EfiReleaseLock (\r
384 IN EFI_LOCK *Lock\r
385 )\r
386{\r
387 EFI_TPL Tpl;\r
388\r
389 ASSERT (Lock != NULL);\r
390 ASSERT (Lock->Lock == EfiLockAcquired);\r
391\r
392 Tpl = Lock->OwnerTpl;\r
393\r
394 Lock->Lock = EfiLockReleased;\r
395\r
396 gBS->RestoreTPL (Tpl);\r
397}\r
398\r
399/**\r
400 Tests whether a controller handle is being managed by a specific driver.\r
401\r
402 This function tests whether the driver specified by DriverBindingHandle is\r
403 currently managing the controller specified by ControllerHandle. This test\r
404 is performed by evaluating if the the protocol specified by ProtocolGuid is\r
405 present on ControllerHandle and is was opened by DriverBindingHandle with an\r
406 attribute of EFI_OPEN_PROTOCOL_BY_DRIVER.\r
407 If ProtocolGuid is NULL, then ASSERT().\r
408\r
409 @param ControllerHandle A handle for a controller to test.\r
410 @param DriverBindingHandle Specifies the driver binding handle for the\r
411 driver.\r
412 @param ProtocolGuid Specifies the protocol that the driver specified\r
413 by DriverBindingHandle opens in its Start()\r
414 function.\r
415\r
416 @retval EFI_SUCCESS ControllerHandle is managed by the driver\r
417 specifed by DriverBindingHandle.\r
418 @retval EFI_UNSUPPORTED ControllerHandle is not managed by the driver\r
419 specifed by DriverBindingHandle.\r
420\r
421**/\r
422EFI_STATUS\r
423EFIAPI\r
424EfiTestManagedDevice (\r
425 IN CONST EFI_HANDLE ControllerHandle,\r
426 IN CONST EFI_HANDLE DriverBindingHandle,\r
427 IN CONST EFI_GUID *ProtocolGuid\r
428 )\r
429{\r
430 EFI_STATUS Status;\r
431 VOID *ManagedInterface;\r
432\r
433 ASSERT (ProtocolGuid != NULL);\r
434\r
435 Status = gBS->OpenProtocol (\r
436 ControllerHandle,\r
437 (EFI_GUID *) ProtocolGuid,\r
438 &ManagedInterface,\r
439 DriverBindingHandle,\r
440 ControllerHandle,\r
441 EFI_OPEN_PROTOCOL_BY_DRIVER\r
442 );\r
443 if (!EFI_ERROR (Status)) {\r
444 gBS->CloseProtocol (\r
445 ControllerHandle,\r
446 (EFI_GUID *) ProtocolGuid,\r
447 DriverBindingHandle,\r
448 ControllerHandle\r
449 );\r
450 return EFI_UNSUPPORTED;\r
451 }\r
452\r
453 if (Status != EFI_ALREADY_STARTED) {\r
454 return EFI_UNSUPPORTED;\r
455 }\r
456\r
457 return EFI_SUCCESS;\r
458}\r
459\r
460/**\r
461 Tests whether a child handle is a child device of the controller.\r
462\r
463 This function tests whether ChildHandle is one of the children of\r
464 ControllerHandle. This test is performed by checking to see if the protocol\r
465 specified by ProtocolGuid is present on ControllerHandle and opened by\r
466 ChildHandle with an attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
467 If ProtocolGuid is NULL, then ASSERT().\r
468\r
469 @param ControllerHandle A handle for a (parent) controller to test.\r
470 @param ChildHandle A child handle to test.\r
42eedea9 471 @param ProtocolGuid Supplies the protocol that the child controller\r
e386b444 472 opens on its parent controller.\r
473\r
474 @retval EFI_SUCCESS ChildHandle is a child of the ControllerHandle.\r
475 @retval EFI_UNSUPPORTED ChildHandle is not a child of the\r
476 ControllerHandle.\r
477\r
478**/\r
479EFI_STATUS\r
480EFIAPI\r
481EfiTestChildHandle (\r
482 IN CONST EFI_HANDLE ControllerHandle,\r
483 IN CONST EFI_HANDLE ChildHandle,\r
484 IN CONST EFI_GUID *ProtocolGuid\r
485 )\r
486{\r
487 EFI_STATUS Status;\r
488 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;\r
489 UINTN EntryCount;\r
490 UINTN Index;\r
491\r
492 ASSERT (ProtocolGuid != NULL);\r
493\r
494 //\r
495 // Retrieve the list of agents that are consuming the specific protocol\r
496 // on ControllerHandle.\r
497 //\r
498 Status = gBS->OpenProtocolInformation (\r
499 ControllerHandle,\r
500 (EFI_GUID *) ProtocolGuid,\r
501 &OpenInfoBuffer,\r
502 &EntryCount\r
503 );\r
504 if (EFI_ERROR (Status)) {\r
505 return EFI_UNSUPPORTED;\r
506 }\r
507\r
508 //\r
509 // Inspect if ChildHandle is one of the agents.\r
510 //\r
511 Status = EFI_UNSUPPORTED;\r
512 for (Index = 0; Index < EntryCount; Index++) {\r
513 if ((OpenInfoBuffer[Index].ControllerHandle == ChildHandle) &&\r
514 (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
515 Status = EFI_SUCCESS;\r
516 break;\r
517 }\r
518 }\r
519\r
520 FreePool (OpenInfoBuffer);\r
521 return Status;\r
522}\r
523\r
524/**\r
dd51a993 525 This function looks up a Unicode string in UnicodeStringTable.\r
526 If Language is a member of SupportedLanguages and a Unicode\r
527 string is found in UnicodeStringTable that matches the\r
528 language code specified by Language, then it is returned in\r
e386b444 529 UnicodeString.\r
530\r
dd51a993 531 @param Language A pointer to the ISO 639-2\r
532 language code for the Unicode\r
533 string to look up and return.\r
534 \r
535 @param SupportedLanguages A pointer to the set of ISO\r
536 639-2language\r
537 codes that the Unicode string\r
538 table supports. Language must\r
539 be a member of this set.\r
540 \r
541 @param UnicodeStringTable A pointer to the table of\r
542 Unicode strings.\r
543 \r
544 @param UnicodeString A pointer to the Unicode\r
545 string from UnicodeStringTable\r
546 that matches the language\r
547 specified by Language.\r
548\r
549 @retval EFI_SUCCESS The Unicode string that\r
550 matches the language specified\r
551 by Language was found in the\r
552 table of Unicoide strings\r
553 UnicodeStringTable, and it was\r
554 returned in UnicodeString.\r
555 \r
e386b444 556 @retval EFI_INVALID_PARAMETER Language is NULL.\r
dd51a993 557 \r
e386b444 558 @retval EFI_INVALID_PARAMETER UnicodeString is NULL.\r
559 @retval EFI_UNSUPPORTED SupportedLanguages is NULL.\r
dd51a993 560 \r
e386b444 561 @retval EFI_UNSUPPORTED UnicodeStringTable is NULL.\r
dd51a993 562 \r
563 @retval EFI_UNSUPPORTED The language specified by\r
564 Language is not a member\r
565 ofSupportedLanguages.\r
566 \r
567 @retval EFI_UNSUPPORTED The language specified by\r
568 Language is not supported by\r
569 UnicodeStringTable.\r
e386b444 570\r
571**/\r
572EFI_STATUS\r
573EFIAPI\r
574LookupUnicodeString (\r
575 IN CONST CHAR8 *Language,\r
576 IN CONST CHAR8 *SupportedLanguages,\r
577 IN CONST EFI_UNICODE_STRING_TABLE *UnicodeStringTable,\r
578 OUT CHAR16 **UnicodeString\r
579 )\r
580{\r
581 //\r
582 // Make sure the parameters are valid\r
583 //\r
584 if (Language == NULL || UnicodeString == NULL) {\r
585 return EFI_INVALID_PARAMETER;\r
586 }\r
587\r
588 //\r
589 // If there are no supported languages, or the Unicode String Table is empty, then the\r
590 // Unicode String specified by Language is not supported by this Unicode String Table\r
591 //\r
592 if (SupportedLanguages == NULL || UnicodeStringTable == NULL) {\r
593 return EFI_UNSUPPORTED;\r
594 }\r
595\r
596 //\r
597 // Make sure Language is in the set of Supported Languages\r
598 //\r
599 while (*SupportedLanguages != 0) {\r
600 if (CompareIso639LanguageCode (Language, SupportedLanguages)) {\r
601\r
602 //\r
603 // Search the Unicode String Table for the matching Language specifier\r
604 //\r
605 while (UnicodeStringTable->Language != NULL) {\r
606 if (CompareIso639LanguageCode (Language, UnicodeStringTable->Language)) {\r
607\r
608 //\r
609 // A matching string was found, so return it\r
610 //\r
611 *UnicodeString = UnicodeStringTable->UnicodeString;\r
612 return EFI_SUCCESS;\r
613 }\r
614\r
615 UnicodeStringTable++;\r
616 }\r
617\r
618 return EFI_UNSUPPORTED;\r
619 }\r
620\r
621 SupportedLanguages += 3;\r
622 }\r
623\r
624 return EFI_UNSUPPORTED;\r
625}\r
626\r
dd51a993 627\r
628\r
e386b444 629/**\r
dd51a993 630 This function looks up a Unicode string in UnicodeStringTable.\r
631 If Language is a member of SupportedLanguages and a Unicode\r
632 string is found in UnicodeStringTable that matches the\r
633 language code specified by Language, then it is returned in\r
634 UnicodeString.\r
635\r
636 @param Language A pointer to the ISO 639-2 or\r
637 RFC 3066 language code for the\r
638 Unicode string to look up and\r
639 return.\r
640 \r
641 @param SupportedLanguages A pointer to the set of ISO\r
642 639-2 or RFC 3066 language\r
643 codes that the Unicode string\r
644 table supports. Language must\r
645 be a member of this set.\r
646 \r
647 @param UnicodeStringTable A pointer to the table of\r
648 Unicode strings.\r
649 \r
650 @param UnicodeString A pointer to the Unicode\r
651 string from UnicodeStringTable\r
652 that matches the language\r
653 specified by Language.\r
654\r
655 @param Iso639Language Specify the language code\r
656 format supported. If true,\r
657 then the format follow ISO\r
658 639-2. If false, then it\r
659 follows RFC3066.\r
660\r
661 @retval EFI_SUCCESS The Unicode string that\r
662 matches the language specified\r
663 by Language was found in the\r
664 table of Unicoide strings\r
665 UnicodeStringTable, and it was\r
666 returned in UnicodeString.\r
667 \r
668 @retval EFI_INVALID_PARAMETER Language is NULL.\r
669 \r
670 @retval EFI_INVALID_PARAMETER UnicodeString is NULL.\r
671 \r
672 @retval EFI_UNSUPPORTED SupportedLanguages is NULL.\r
673 \r
674 @retval EFI_UNSUPPORTED UnicodeStringTable is NULL.\r
675 \r
676 @retval EFI_UNSUPPORTED The language specified by\r
677 Language is not a member\r
678 ofSupportedLanguages.\r
679 \r
680 @retval EFI_UNSUPPORTED The language specified by\r
681 Language is not supported by\r
682 UnicodeStringTable.\r
683\r
684**/\r
685EFI_STATUS\r
9edc73ad 686\r
dd51a993 687EFIAPI\r
688LookupUnicodeString2 (\r
689 IN CONST CHAR8 *Language,\r
690 IN CONST CHAR8 *SupportedLanguages,\r
691 IN CONST EFI_UNICODE_STRING_TABLE *UnicodeStringTable,\r
692 OUT CHAR16 **UnicodeString,\r
693 IN BOOLEAN Iso639Language\r
694 )\r
695{\r
696 BOOLEAN Found;\r
697 UINTN Index;\r
698 CHAR8 *LanguageString;\r
699\r
700 //\r
701 // Make sure the parameters are valid\r
702 //\r
703 if (Language == NULL || UnicodeString == NULL) {\r
704 return EFI_INVALID_PARAMETER;\r
705 }\r
706\r
707 //\r
708 // If there are no supported languages, or the Unicode String Table is empty, then the\r
709 // Unicode String specified by Language is not supported by this Unicode String Table\r
710 //\r
711 if (SupportedLanguages == NULL || UnicodeStringTable == NULL) {\r
712 return EFI_UNSUPPORTED;\r
713 }\r
714\r
715 //\r
716 // Make sure Language is in the set of Supported Languages\r
717 //\r
718 Found = FALSE;\r
719 while (*SupportedLanguages != 0) {\r
720 if (Iso639Language) {\r
721 if (CompareIso639LanguageCode (Language, SupportedLanguages)) {\r
722 Found = TRUE;\r
723 break;\r
724 }\r
725 SupportedLanguages += 3;\r
726 } else {\r
727 for (Index = 0; SupportedLanguages[Index] != 0 && SupportedLanguages[Index] != ';'; Index++);\r
634aa59d 728 if ((AsciiStrnCmp(SupportedLanguages, Language, Index) == 0) && (Language[Index] == 0)) {\r
dd51a993 729 Found = TRUE;\r
730 break;\r
731 }\r
732 SupportedLanguages += Index;\r
733 for (; *SupportedLanguages != 0 && *SupportedLanguages == ';'; SupportedLanguages++);\r
734 }\r
735 }\r
736\r
737 //\r
738 // If Language is not a member of SupportedLanguages, then return EFI_UNSUPPORTED\r
739 //\r
740 if (!Found) {\r
741 return EFI_UNSUPPORTED;\r
742 }\r
743\r
744 //\r
745 // Search the Unicode String Table for the matching Language specifier\r
746 //\r
747 while (UnicodeStringTable->Language != NULL) {\r
748 LanguageString = UnicodeStringTable->Language;\r
749 while (0 != *LanguageString) {\r
750 for (Index = 0 ;LanguageString[Index] != 0 && LanguageString[Index] != ';'; Index++);\r
751 if (AsciiStrnCmp(LanguageString, Language, Index) == 0) {\r
752 *UnicodeString = UnicodeStringTable->UnicodeString;\r
753 return EFI_SUCCESS;\r
754 }\r
755 LanguageString += Index;\r
756 for (Index = 0 ;LanguageString[Index] != 0 && LanguageString[Index] == ';'; Index++);\r
757 }\r
758 UnicodeStringTable++;\r
759 }\r
760\r
761 return EFI_UNSUPPORTED;\r
762}\r
763\r
764\r
765/**\r
766 \r
e386b444 767 This function adds a Unicode string to UnicodeStringTable.\r
dd51a993 768 If Language is a member of SupportedLanguages then\r
769 UnicodeString is added to UnicodeStringTable. New buffers are\r
770 allocated for both Language and UnicodeString. The contents\r
771 of Language and UnicodeString are copied into these new\r
772 buffers. These buffers are automatically freed when\r
e386b444 773 FreeUnicodeStringTable() is called.\r
774\r
dd51a993 775 @param Language A pointer to the ISO 639-2\r
776 language code for the Unicode\r
e386b444 777 string to add.\r
dd51a993 778 \r
779 @param SupportedLanguages A pointer to the set of ISO\r
780 639-2 language codes that the\r
781 Unicode string table supports.\r
782 Language must be a member of\r
783 this set.\r
784 \r
785 @param UnicodeStringTable A pointer to the table of\r
786 Unicode strings.\r
787 \r
788 @param UnicodeString A pointer to the Unicode\r
789 string to add.\r
790\r
791 @retval EFI_SUCCESS The Unicode string that\r
792 matches the language specified\r
793 by Language was found in the\r
794 table of Unicode strings\r
795 UnicodeStringTable, and it was\r
e386b444 796 returned in UnicodeString.\r
dd51a993 797 \r
e386b444 798 @retval EFI_INVALID_PARAMETER Language is NULL.\r
dd51a993 799 \r
e386b444 800 @retval EFI_INVALID_PARAMETER UnicodeString is NULL.\r
dd51a993 801 \r
e386b444 802 @retval EFI_INVALID_PARAMETER UnicodeString is an empty string.\r
dd51a993 803 \r
e386b444 804 @retval EFI_UNSUPPORTED SupportedLanguages is NULL.\r
dd51a993 805 \r
806 @retval EFI_ALREADY_STARTED A Unicode string with language\r
807 Language is already present in\r
808 UnicodeStringTable.\r
809 \r
810 @retval EFI_OUT_OF_RESOURCES There is not enough memory to\r
811 add another Unicode string to\r
812 UnicodeStringTable.\r
813 \r
814 @retval EFI_UNSUPPORTED The language specified by\r
815 Language is not a member of\r
816 SupportedLanguages.\r
e386b444 817\r
818**/\r
819EFI_STATUS\r
820EFIAPI\r
821AddUnicodeString (\r
822 IN CONST CHAR8 *Language,\r
823 IN CONST CHAR8 *SupportedLanguages,\r
824 IN EFI_UNICODE_STRING_TABLE **UnicodeStringTable,\r
825 IN CONST CHAR16 *UnicodeString\r
826 )\r
827{\r
828 UINTN NumberOfEntries;\r
829 EFI_UNICODE_STRING_TABLE *OldUnicodeStringTable;\r
830 EFI_UNICODE_STRING_TABLE *NewUnicodeStringTable;\r
831 UINTN UnicodeStringLength;\r
832\r
833 //\r
834 // Make sure the parameter are valid\r
835 //\r
836 if (Language == NULL || UnicodeString == NULL || UnicodeStringTable == NULL) {\r
837 return EFI_INVALID_PARAMETER;\r
838 }\r
839\r
840 //\r
841 // If there are no supported languages, then a Unicode String can not be added\r
842 //\r
843 if (SupportedLanguages == NULL) {\r
844 return EFI_UNSUPPORTED;\r
845 }\r
846\r
847 //\r
848 // If the Unicode String is empty, then a Unicode String can not be added\r
849 //\r
850 if (UnicodeString[0] == 0) {\r
851 return EFI_INVALID_PARAMETER;\r
852 }\r
853\r
854 //\r
855 // Make sure Language is a member of SupportedLanguages\r
856 //\r
857 while (*SupportedLanguages != 0) {\r
858 if (CompareIso639LanguageCode (Language, SupportedLanguages)) {\r
859\r
860 //\r
861 // Determine the size of the Unicode String Table by looking for a NULL Language entry\r
862 //\r
863 NumberOfEntries = 0;\r
864 if (*UnicodeStringTable != NULL) {\r
865 OldUnicodeStringTable = *UnicodeStringTable;\r
866 while (OldUnicodeStringTable->Language != NULL) {\r
867 if (CompareIso639LanguageCode (Language, OldUnicodeStringTable->Language)) {\r
868 return EFI_ALREADY_STARTED;\r
869 }\r
870\r
871 OldUnicodeStringTable++;\r
872 NumberOfEntries++;\r
873 }\r
874 }\r
875\r
876 //\r
877 // Allocate space for a new Unicode String Table. It must hold the current number of\r
878 // entries, plus 1 entry for the new Unicode String, plus 1 entry for the end of table\r
879 // marker\r
880 //\r
881 NewUnicodeStringTable = AllocatePool ((NumberOfEntries + 2) * sizeof (EFI_UNICODE_STRING_TABLE));\r
882 if (NewUnicodeStringTable == NULL) {\r
883 return EFI_OUT_OF_RESOURCES;\r
884 }\r
885\r
886 //\r
887 // If the current Unicode String Table contains any entries, then copy them to the\r
888 // newly allocated Unicode String Table.\r
889 //\r
890 if (*UnicodeStringTable != NULL) {\r
891 CopyMem (\r
892 NewUnicodeStringTable,\r
893 *UnicodeStringTable,\r
894 NumberOfEntries * sizeof (EFI_UNICODE_STRING_TABLE)\r
895 );\r
896 }\r
897\r
898 //\r
899 // Allocate space for a copy of the Language specifier\r
900 //\r
901 NewUnicodeStringTable[NumberOfEntries].Language = AllocateCopyPool (3, Language);\r
902 if (NewUnicodeStringTable[NumberOfEntries].Language == NULL) {\r
903 gBS->FreePool (NewUnicodeStringTable);\r
904 return EFI_OUT_OF_RESOURCES;\r
905 }\r
906\r
907 //\r
908 // Compute the length of the Unicode String\r
909 //\r
910 for (UnicodeStringLength = 0; UnicodeString[UnicodeStringLength] != 0; UnicodeStringLength++)\r
911 ;\r
912\r
913 //\r
914 // Allocate space for a copy of the Unicode String\r
915 //\r
916 NewUnicodeStringTable[NumberOfEntries].UnicodeString = AllocateCopyPool (\r
917 (UnicodeStringLength + 1) * sizeof (CHAR16),\r
918 UnicodeString\r
919 );\r
920 if (NewUnicodeStringTable[NumberOfEntries].UnicodeString == NULL) {\r
921 gBS->FreePool (NewUnicodeStringTable[NumberOfEntries].Language);\r
922 gBS->FreePool (NewUnicodeStringTable);\r
923 return EFI_OUT_OF_RESOURCES;\r
924 }\r
925\r
926 //\r
927 // Mark the end of the Unicode String Table\r
928 //\r
929 NewUnicodeStringTable[NumberOfEntries + 1].Language = NULL;\r
930 NewUnicodeStringTable[NumberOfEntries + 1].UnicodeString = NULL;\r
931\r
932 //\r
933 // Free the old Unicode String Table\r
934 //\r
935 if (*UnicodeStringTable != NULL) {\r
936 gBS->FreePool (*UnicodeStringTable);\r
937 }\r
938\r
939 //\r
940 // Point UnicodeStringTable at the newly allocated Unicode String Table\r
941 //\r
942 *UnicodeStringTable = NewUnicodeStringTable;\r
943\r
944 return EFI_SUCCESS;\r
945 }\r
946\r
947 SupportedLanguages += 3;\r
948 }\r
949\r
950 return EFI_UNSUPPORTED;\r
951}\r
952\r
dd51a993 953\r
954/**\r
955 \r
956 This function adds a Unicode string to UnicodeStringTable.\r
957 If Language is a member of SupportedLanguages then\r
958 UnicodeString is added to UnicodeStringTable. New buffers are\r
959 allocated for both Language and UnicodeString. The contents\r
960 of Language and UnicodeString are copied into these new\r
961 buffers. These buffers are automatically freed when\r
962 FreeUnicodeStringTable() is called.\r
963\r
964 @param Language A pointer to the ISO 639-2 or\r
965 RFC 3066 language code for the\r
966 Unicode string to add.\r
967 \r
968 @param SupportedLanguages A pointer to the set of ISO\r
969 639-2 or RFC 3.66 language\r
970 codes that the Unicode string\r
971 table supports. Language must\r
972 be a member of this set.\r
973 \r
974 @param UnicodeStringTable A pointer to the table of\r
975 Unicode strings.\r
976 \r
977 @param UnicodeString A pointer to the Unicode\r
978 string to add.\r
979 \r
980 @param Iso639Language Specify the language code\r
981 format supported. If true,\r
982 then the format follow ISO\r
983 639-2. If false, then it\r
984 follows RFC3066.\r
985\r
986 @retval EFI_SUCCESS The Unicode string that\r
987 matches the language specified\r
988 by Language was found in the\r
989 table of Unicode strings\r
990 UnicodeStringTable, and it was\r
991 returned in UnicodeString.\r
992 \r
993 @retval EFI_INVALID_PARAMETER Language is NULL.\r
994 \r
995 @retval EFI_INVALID_PARAMETER UnicodeString is NULL.\r
996 \r
997 @retval EFI_INVALID_PARAMETER UnicodeString is an empty string.\r
998 \r
999 @retval EFI_UNSUPPORTED SupportedLanguages is NULL.\r
1000 \r
1001 @retval EFI_ALREADY_STARTED A Unicode string with language\r
1002 Language is already present in\r
1003 UnicodeStringTable.\r
1004 \r
1005 @retval EFI_OUT_OF_RESOURCES There is not enough memory to\r
1006 add another Unicode string to\r
1007 UnicodeStringTable.\r
1008 \r
1009 @retval EFI_UNSUPPORTED The language specified by\r
1010 Language is not a member of\r
1011 SupportedLanguages.\r
1012\r
1013**/\r
1014EFI_STATUS\r
1015EFIAPI\r
1016AddUnicodeString2 (\r
1017 IN CONST CHAR8 *Language,\r
1018 IN CONST CHAR8 *SupportedLanguages,\r
1019 IN EFI_UNICODE_STRING_TABLE **UnicodeStringTable,\r
1020 IN CONST CHAR16 *UnicodeString,\r
1021 IN BOOLEAN Iso639Language\r
1022 )\r
1023{\r
1024 UINTN NumberOfEntries;\r
1025 EFI_UNICODE_STRING_TABLE *OldUnicodeStringTable;\r
1026 EFI_UNICODE_STRING_TABLE *NewUnicodeStringTable;\r
1027 UINTN UnicodeStringLength;\r
1028 BOOLEAN Found;\r
1029 UINTN Index;\r
1030 CHAR8 *LanguageString;\r
1031\r
1032 //\r
1033 // Make sure the parameter are valid\r
1034 //\r
1035 if (Language == NULL || UnicodeString == NULL || UnicodeStringTable == NULL) {\r
1036 return EFI_INVALID_PARAMETER;\r
1037 }\r
1038\r
1039 //\r
1040 // If there are no supported languages, then a Unicode String can not be added\r
1041 //\r
1042 if (SupportedLanguages == NULL) {\r
1043 return EFI_UNSUPPORTED;\r
1044 }\r
1045\r
1046 //\r
1047 // If the Unicode String is empty, then a Unicode String can not be added\r
1048 //\r
1049 if (UnicodeString[0] == 0) {\r
1050 return EFI_INVALID_PARAMETER;\r
1051 }\r
1052\r
1053 //\r
1054 // Make sure Language is a member of SupportedLanguages\r
1055 //\r
1056 Found = FALSE;\r
1057 while (*SupportedLanguages != 0) {\r
1058 if (Iso639Language) {\r
1059 if (CompareIso639LanguageCode (Language, SupportedLanguages)) {\r
1060 Found = TRUE;\r
1061 break;\r
1062 }\r
1063 SupportedLanguages += 3;\r
1064 } else {\r
1065 for (Index = 0; SupportedLanguages[Index] != 0 && SupportedLanguages[Index] != ';'; Index++);\r
1066 if (AsciiStrnCmp(SupportedLanguages, Language, Index) == 0) {\r
1067 Found = TRUE;\r
1068 break;\r
1069 }\r
1070 SupportedLanguages += Index;\r
1071 for (; *SupportedLanguages != 0 && *SupportedLanguages == ';'; SupportedLanguages++);\r
1072 }\r
1073 }\r
1074\r
1075 //\r
1076 // If Language is not a member of SupportedLanguages, then return EFI_UNSUPPORTED\r
1077 //\r
1078 if (!Found) {\r
1079 return EFI_UNSUPPORTED;\r
1080 }\r
1081\r
1082 //\r
1083 // Determine the size of the Unicode String Table by looking for a NULL Language entry\r
1084 //\r
1085 NumberOfEntries = 0;\r
1086 if (*UnicodeStringTable != NULL) {\r
1087 OldUnicodeStringTable = *UnicodeStringTable;\r
1088 while (OldUnicodeStringTable->Language != NULL) {\r
1089 LanguageString = OldUnicodeStringTable->Language;\r
1090\r
42eedea9 1091 while (*LanguageString != 0) {\r
dd51a993 1092 for (Index = 0; LanguageString[Index] != 0 && LanguageString[Index] != ';'; Index++);\r
1093\r
1094 if (AsciiStrnCmp (Language, LanguageString, Index) == 0) { \r
1095 return EFI_ALREADY_STARTED;\r
1096 }\r
1097 LanguageString += Index;\r
1098 for (; *LanguageString != 0 && *LanguageString == ';'; LanguageString++);\r
1099 }\r
1100 OldUnicodeStringTable++;\r
1101 NumberOfEntries++;\r
1102 }\r
1103 }\r
1104\r
1105 //\r
1106 // Allocate space for a new Unicode String Table. It must hold the current number of\r
1107 // entries, plus 1 entry for the new Unicode String, plus 1 entry for the end of table\r
1108 // marker\r
1109 //\r
1110 NewUnicodeStringTable = AllocatePool ((NumberOfEntries + 2) * sizeof (EFI_UNICODE_STRING_TABLE));\r
1111 if (NewUnicodeStringTable == NULL) {\r
1112 return EFI_OUT_OF_RESOURCES;\r
1113 }\r
1114\r
1115 //\r
1116 // If the current Unicode String Table contains any entries, then copy them to the\r
1117 // newly allocated Unicode String Table.\r
1118 //\r
1119 if (*UnicodeStringTable != NULL) {\r
1120 CopyMem (\r
1121 NewUnicodeStringTable,\r
1122 *UnicodeStringTable,\r
1123 NumberOfEntries * sizeof (EFI_UNICODE_STRING_TABLE)\r
1124 );\r
1125 }\r
1126\r
1127 //\r
1128 // Allocate space for a copy of the Language specifier\r
1129 //\r
1130 NewUnicodeStringTable[NumberOfEntries].Language = AllocateCopyPool (AsciiStrSize(Language), Language);\r
1131 if (NewUnicodeStringTable[NumberOfEntries].Language == NULL) {\r
1132 gBS->FreePool (NewUnicodeStringTable);\r
1133 return EFI_OUT_OF_RESOURCES;\r
1134 }\r
1135\r
1136 //\r
1137 // Compute the length of the Unicode String\r
1138 //\r
1139 for (UnicodeStringLength = 0; UnicodeString[UnicodeStringLength] != 0; UnicodeStringLength++);\r
1140\r
1141 //\r
1142 // Allocate space for a copy of the Unicode String\r
1143 //\r
1144 NewUnicodeStringTable[NumberOfEntries].UnicodeString = AllocateCopyPool (StrSize (UnicodeString), UnicodeString);\r
1145 if (NewUnicodeStringTable[NumberOfEntries].UnicodeString == NULL) {\r
1146 gBS->FreePool (NewUnicodeStringTable[NumberOfEntries].Language);\r
1147 gBS->FreePool (NewUnicodeStringTable);\r
1148 return EFI_OUT_OF_RESOURCES;\r
1149 }\r
1150\r
1151 //\r
1152 // Mark the end of the Unicode String Table\r
1153 //\r
1154 NewUnicodeStringTable[NumberOfEntries + 1].Language = NULL;\r
1155 NewUnicodeStringTable[NumberOfEntries + 1].UnicodeString = NULL;\r
1156\r
1157 //\r
1158 // Free the old Unicode String Table\r
1159 //\r
1160 if (*UnicodeStringTable != NULL) {\r
1161 gBS->FreePool (*UnicodeStringTable);\r
1162 }\r
1163\r
1164 //\r
1165 // Point UnicodeStringTable at the newly allocated Unicode String Table\r
1166 //\r
1167 *UnicodeStringTable = NewUnicodeStringTable;\r
1168\r
1169 return EFI_SUCCESS;\r
1170}\r
1171\r
e386b444 1172/**\r
1173 This function frees the table of Unicode strings in UnicodeStringTable.\r
1174 If UnicodeStringTable is NULL, then EFI_SUCCESS is returned.\r
dd51a993 1175 Otherwise, each language code, and each Unicode string in the Unicode string \r
e386b444 1176 table are freed, and EFI_SUCCESS is returned.\r
1177\r
1178 @param UnicodeStringTable A pointer to the table of Unicode strings.\r
1179\r
1180 @retval EFI_SUCCESS The Unicode string table was freed.\r
1181\r
1182**/\r
1183EFI_STATUS\r
1184EFIAPI\r
1185FreeUnicodeStringTable (\r
1186 IN EFI_UNICODE_STRING_TABLE *UnicodeStringTable\r
1187 )\r
1188{\r
1189 UINTN Index;\r
1190\r
1191 //\r
1192 // If the Unicode String Table is NULL, then it is already freed\r
1193 //\r
1194 if (UnicodeStringTable == NULL) {\r
1195 return EFI_SUCCESS;\r
1196 }\r
1197\r
1198 //\r
1199 // Loop through the Unicode String Table until we reach the end of table marker\r
1200 //\r
1201 for (Index = 0; UnicodeStringTable[Index].Language != NULL; Index++) {\r
1202\r
1203 //\r
1204 // Free the Language string from the Unicode String Table\r
1205 //\r
1206 gBS->FreePool (UnicodeStringTable[Index].Language);\r
1207\r
1208 //\r
1209 // Free the Unicode String from the Unicode String Table\r
1210 //\r
1211 if (UnicodeStringTable[Index].UnicodeString != NULL) {\r
1212 gBS->FreePool (UnicodeStringTable[Index].UnicodeString);\r
1213 }\r
1214 }\r
1215\r
1216 //\r
1217 // Free the Unicode String Table itself\r
1218 //\r
1219 gBS->FreePool (UnicodeStringTable);\r
1220\r
1221 return EFI_SUCCESS;\r
1222}\r
1223\r
f8d18bad 1224/**\r
1225 Determine what is the current language setting. The space reserved for Lang\r
1226 must be at least RFC_3066_ENTRY_SIZE bytes;\r
1227\r
1228 If Lang is NULL, then ASSERT.\r
1229\r
1230 @param Lang Pointer of system language. Lang will always be filled with \r
1231 a valid RFC 3066 language string. If "PlatformLang" is not\r
1232 set in the system, the default language specifed by PcdUefiVariableDefaultPlatformLang\r
1233 is returned.\r
1234\r
1235 @return EFI_SUCCESS If the EFI Variable with "PlatformLang" is set and return in Lang.\r
1236 @return EFI_NOT_FOUND If the EFI Variable with "PlatformLang" is not set, but a valid default language is return in Lang.\r
1237\r
1238**/\r
1239EFI_STATUS\r
1240EFIAPI\r
1241GetCurrentLanguage (\r
1242 OUT CHAR8 *Lang\r
1243 )\r
1244{\r
1245 EFI_STATUS Status;\r
1246 UINTN Size;\r
1247\r
1248 ASSERT (Lang != NULL);\r
1249\r
1250 //\r
1251 // Get current language setting\r
1252 //\r
1253 Size = RFC_3066_ENTRY_SIZE;\r
1254 Status = gRT->GetVariable (\r
1255 L"PlatformLang",\r
1256 &gEfiGlobalVariableGuid,\r
1257 NULL,\r
1258 &Size,\r
1259 Lang\r
1260 );\r
1261\r
1262 if (EFI_ERROR (Status)) {\r
1263 AsciiStrCpy (Lang, (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang));\r
1264 }\r
1265\r
1266 return Status;\r
1267}\r
1268\r
1269\r
1c280088 1270\r