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