3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Light weight lib to support EFI drivers.
23 #include "EfiDriverLib.h"
24 #include EFI_ARCH_PROTOCOL_DEFINITION (StatusCode)
26 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
38 // Global Interface for Debug Mask Protocol
40 EFI_DEBUG_MASK_PROTOCOL
*gDebugMaskInterface
= NULL
;
43 EfiInitializeDriverLib (
44 IN EFI_HANDLE ImageHandle
,
45 IN EFI_SYSTEM_TABLE
*SystemTable
51 Intialize Driver Lib if it has not yet been initialized.
55 ImageHandle - Standard EFI Image entry parameter
57 SystemTable - Standard EFI Image entry parameter
61 EFI_STATUS always returns EFI_SUCCESS
65 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
73 gBS
= gST
->BootServices
;
74 gRT
= gST
->RuntimeServices
;
80 // Get driver debug mask protocol interface
85 &gEfiDebugMaskProtocolGuid
,
86 (VOID
*) &gDebugMaskInterface
90 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
92 // Register EFI_STATUS_CODE_PROTOCOL notify function
94 EfiLibCreateProtocolNotifyEvent (
95 &gEfiStatusCodeRuntimeProtocolGuid
,
105 // Should be at EFI_D_INFO, but lets us know things are running
107 DEBUG ((EFI_D_INFO
, "EfiInitializeDriverLib: Started\n"));
114 IsIso639LanguageCode (
121 Tests whether a language code has format of ISO639-2.
125 Languages - The language code to be tested.
129 TRUE - Language code format is ISO 639-2.
130 FALSE - Language code format is not ISO 639-2.
137 // Find out format of Languages
139 for (Index
= 0; Languages
[Index
] != 0 && Languages
[Index
] != ';' && Languages
[Index
] != '-'; Index
++);
140 if (Languages
[Index
] != 0) {
142 // RFC4646 language code
148 // No ';' and '-', it's either ISO639-2 code (list) or single RFC4646 code
152 // Single RFC4646 language code without country code, e.g. "en"
158 // Languages in format of ISO639-2
164 EfiLibCompareLanguage (
172 Compare the first language instance of two language codes, either could be a
173 single language code or a language code list. This function assume Language1
174 and Language2 has the same language code format, i.e. either ISO639-2 or RFC4646.
178 Language1 - The first language code to be tested.
179 Language2 - The second language code to be tested.
183 TRUE - Language code match.
184 FALSE - Language code mismatch.
191 // Compare first two bytes of language tag
193 if ((Language1
[0] != Language2
[0]) || (Language1
[1] != Language2
[1])) {
197 if (IsIso639LanguageCode (Language1
)) {
199 // ISO639-2 language code, compare the third byte of language tag
201 return (BOOLEAN
) ((Language1
[2] == Language2
[2]) ? TRUE
: FALSE
);
205 // RFC4646 language code
207 for (Index
= 0; Language1
[Index
] != 0 && Language1
[Index
] != ';'; Index
++);
208 if ((EfiAsciiStrnCmp (Language1
, Language2
, Index
) == 0) && (Language2
[Index
] == 0 || Language2
[Index
] == ';')) {
217 NextSupportedLanguage (
224 Step to next language code of a language code list.
228 Languages - The language code list to traverse.
232 Pointer to next language code or NULL terminator if it's the last one.
238 if (IsIso639LanguageCode (Languages
)) {
240 // ISO639-2 language code
242 return (Languages
+ 3);
246 // Search in RFC4646 language code list
248 for (Index
= 0; Languages
[Index
] != 0 && Languages
[Index
] != ';'; Index
++);
249 if (Languages
[Index
] == ';') {
252 return (Languages
+ Index
);
256 EfiLibLookupUnicodeString (
258 IN CHAR8
*SupportedLanguages
,
259 IN EFI_UNICODE_STRING_TABLE
*UnicodeStringTable
,
260 OUT CHAR16
**UnicodeString
266 Translate a unicode string to a specified language if supported.
270 Language - The name of language to translate to
271 SupportedLanguages - Supported languages set
272 UnicodeStringTable - Pointer of one item in translation dictionary
273 UnicodeString - The translated string
277 EFI_INVALID_PARAMETER - Invalid parameter
278 EFI_UNSUPPORTED - System not supported this language or this string translation
279 EFI_SUCCESS - String successfully translated
284 // Make sure the parameters are valid
286 if (Language
== NULL
|| UnicodeString
== NULL
) {
287 return EFI_INVALID_PARAMETER
;
291 // If there are no supported languages, or the Unicode String Table is empty, then the
292 // Unicode String specified by Language is not supported by this Unicode String Table
294 if (SupportedLanguages
== NULL
|| UnicodeStringTable
== NULL
) {
295 return EFI_UNSUPPORTED
;
299 // Make sure Language is in the set of Supported Languages
301 while (*SupportedLanguages
!= 0) {
302 if (EfiLibCompareLanguage (Language
, SupportedLanguages
)) {
305 // Search the Unicode String Table for the matching Language specifier
307 while (UnicodeStringTable
->Language
!= NULL
) {
308 if (EfiLibCompareLanguage (Language
, UnicodeStringTable
->Language
)) {
311 // A matching string was found, so return it
313 *UnicodeString
= UnicodeStringTable
->UnicodeString
;
317 UnicodeStringTable
++;
320 return EFI_UNSUPPORTED
;
323 SupportedLanguages
= NextSupportedLanguage (SupportedLanguages
);
326 return EFI_UNSUPPORTED
;
330 EfiLibAddUnicodeString (
332 IN CHAR8
*SupportedLanguages
,
333 IN OUT EFI_UNICODE_STRING_TABLE
**UnicodeStringTable
,
334 IN CHAR16
*UnicodeString
340 Add an translation to the dictionary if this language if supported.
344 Language - The name of language to translate to
345 SupportedLanguages - Supported languages set
346 UnicodeStringTable - Translation dictionary
347 UnicodeString - The corresponding string for the language to be translated to
351 EFI_INVALID_PARAMETER - Invalid parameter
352 EFI_UNSUPPORTED - System not supported this language
353 EFI_ALREADY_STARTED - Already has a translation item of this language
354 EFI_OUT_OF_RESOURCES - No enough buffer to be allocated
355 EFI_SUCCESS - String successfully translated
359 UINTN NumberOfEntries
;
360 EFI_UNICODE_STRING_TABLE
*OldUnicodeStringTable
;
361 EFI_UNICODE_STRING_TABLE
*NewUnicodeStringTable
;
362 UINTN UnicodeStringLength
;
365 // Make sure the parameter are valid
367 if (Language
== NULL
|| UnicodeString
== NULL
|| UnicodeStringTable
== NULL
) {
368 return EFI_INVALID_PARAMETER
;
372 // If there are no supported languages, then a Unicode String can not be added
374 if (SupportedLanguages
== NULL
) {
375 return EFI_UNSUPPORTED
;
379 // If the Unicode String is empty, then a Unicode String can not be added
381 if (UnicodeString
[0] == 0) {
382 return EFI_INVALID_PARAMETER
;
386 // Make sure Language is a member of SupportedLanguages
388 while (*SupportedLanguages
!= 0) {
389 if (EfiLibCompareLanguage (Language
, SupportedLanguages
)) {
392 // Determine the size of the Unicode String Table by looking for a NULL Language entry
395 if (*UnicodeStringTable
!= NULL
) {
396 OldUnicodeStringTable
= *UnicodeStringTable
;
397 while (OldUnicodeStringTable
->Language
!= NULL
) {
398 if (EfiLibCompareLanguage (Language
, OldUnicodeStringTable
->Language
)) {
399 return EFI_ALREADY_STARTED
;
402 OldUnicodeStringTable
++;
408 // Allocate space for a new Unicode String Table. It must hold the current number of
409 // entries, plus 1 entry for the new Unicode String, plus 1 entry for the end of table
412 NewUnicodeStringTable
= EfiLibAllocatePool ((NumberOfEntries
+ 2) * sizeof (EFI_UNICODE_STRING_TABLE
));
413 if (NewUnicodeStringTable
== NULL
) {
414 return EFI_OUT_OF_RESOURCES
;
418 // If the current Unicode String Table contains any entries, then copy them to the
419 // newly allocated Unicode String Table.
421 if (*UnicodeStringTable
!= NULL
) {
423 NewUnicodeStringTable
,
425 NumberOfEntries
* sizeof (EFI_UNICODE_STRING_TABLE
)
430 // Allocate space for a copy of the Language specifier
432 NewUnicodeStringTable
[NumberOfEntries
].Language
= EfiLibAllocateCopyPool (EfiAsciiStrSize (Language
), Language
);
433 if (NewUnicodeStringTable
[NumberOfEntries
].Language
== NULL
) {
434 gBS
->FreePool (NewUnicodeStringTable
);
435 return EFI_OUT_OF_RESOURCES
;
439 // Compute the length of the Unicode String
441 for (UnicodeStringLength
= 0; UnicodeString
[UnicodeStringLength
] != 0; UnicodeStringLength
++)
445 // Allocate space for a copy of the Unicode String
447 NewUnicodeStringTable
[NumberOfEntries
].UnicodeString
= EfiLibAllocateCopyPool (
448 (UnicodeStringLength
+ 1) * sizeof (CHAR16
),
451 if (NewUnicodeStringTable
[NumberOfEntries
].UnicodeString
== NULL
) {
452 gBS
->FreePool (NewUnicodeStringTable
[NumberOfEntries
].Language
);
453 gBS
->FreePool (NewUnicodeStringTable
);
454 return EFI_OUT_OF_RESOURCES
;
458 // Mark the end of the Unicode String Table
460 NewUnicodeStringTable
[NumberOfEntries
+ 1].Language
= NULL
;
461 NewUnicodeStringTable
[NumberOfEntries
+ 1].UnicodeString
= NULL
;
464 // Free the old Unicode String Table
466 if (*UnicodeStringTable
!= NULL
) {
467 gBS
->FreePool (*UnicodeStringTable
);
471 // Point UnicodeStringTable at the newly allocated Unicode String Table
473 *UnicodeStringTable
= NewUnicodeStringTable
;
478 SupportedLanguages
= NextSupportedLanguage (SupportedLanguages
);
481 return EFI_UNSUPPORTED
;
485 EfiLibFreeUnicodeStringTable (
486 IN OUT EFI_UNICODE_STRING_TABLE
*UnicodeStringTable
496 UnicodeStringTable - The string table to be freed.
500 EFI_SUCCESS - The table successfully freed.
507 // If the Unicode String Table is NULL, then it is already freed
509 if (UnicodeStringTable
== NULL
) {
514 // Loop through the Unicode String Table until we reach the end of table marker
516 for (Index
= 0; UnicodeStringTable
[Index
].Language
!= NULL
; Index
++) {
519 // Free the Language string from the Unicode String Table
521 gBS
->FreePool (UnicodeStringTable
[Index
].Language
);
524 // Free the Unicode String from the Unicode String Table
526 if (UnicodeStringTable
[Index
].UnicodeString
!= NULL
) {
527 gBS
->FreePool (UnicodeStringTable
[Index
].UnicodeString
);
532 // Free the Unicode String Table itself
534 gBS
->FreePool (UnicodeStringTable
);