2 Implementation for EFI_HII_STRING_PROTOCOL.
5 Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
6 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include "HiiDatabase.h"
20 CHAR16 mLanguageWindow
[16] = {
21 0x0000, 0x0080, 0x0100, 0x0300,
22 0x2000, 0x2080, 0x2100, 0x3000,
23 0x0080, 0x00C0, 0x0400, 0x0600,
24 0x0900, 0x3040, 0x30A0, 0xFF00
29 This function checks whether a global font info is referred by local
30 font info list or not. (i.e. HII_FONT_INFO is generated.) If not, create
31 a HII_FONT_INFO to refer it locally.
33 This is a internal function.
36 @param Private Hii database private structure.
37 @param StringPackage HII string package instance.
38 @param FontId Font identifer, which must be unique within the string package.
39 @param DuplicateEnable If true, duplicate HII_FONT_INFO which refers to
40 the same EFI_FONT_INFO is permitted. Otherwise it
42 @param GlobalFontInfo Input a global font info which specify a
44 @param LocalFontInfo Output a local font info which refers to a
47 @retval TRUE Already referred before calling this function.
48 @retval FALSE Not referred before calling this function.
52 ReferFontInfoLocally (
53 IN HII_DATABASE_PRIVATE_DATA
*Private
,
54 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
56 IN BOOLEAN DuplicateEnable
,
57 IN HII_GLOBAL_FONT_INFO
*GlobalFontInfo
,
58 OUT HII_FONT_INFO
**LocalFontInfo
61 HII_FONT_INFO
*LocalFont
;
64 ASSERT (Private
!= NULL
&& StringPackage
!= NULL
&& GlobalFontInfo
!= NULL
&& LocalFontInfo
!= NULL
);
66 if (!DuplicateEnable
) {
67 for (Link
= StringPackage
->FontInfoList
.ForwardLink
;
68 Link
!= &StringPackage
->FontInfoList
;
69 Link
= Link
->ForwardLink
71 LocalFont
= CR (Link
, HII_FONT_INFO
, Entry
, HII_FONT_INFO_SIGNATURE
);
72 if (LocalFont
->GlobalEntry
== &GlobalFontInfo
->Entry
) {
74 // Already referred by local font info list, return directly.
76 *LocalFontInfo
= LocalFont
;
81 // FontId identifies EFI_FONT_INFO in local string package uniquely.
82 // GlobalEntry points to a HII_GLOBAL_FONT_INFO which identifies
83 // EFI_FONT_INFO uniquely in whole hii database.
85 LocalFont
= (HII_FONT_INFO
*) AllocateZeroPool (sizeof (HII_FONT_INFO
));
86 ASSERT (LocalFont
!= NULL
);
88 LocalFont
->Signature
= HII_FONT_INFO_SIGNATURE
;
89 LocalFont
->FontId
= FontId
;
90 LocalFont
->GlobalEntry
= &GlobalFontInfo
->Entry
;
91 InsertTailList (&StringPackage
->FontInfoList
, &LocalFont
->Entry
);
93 *LocalFontInfo
= LocalFont
;
99 Convert Ascii string text to unicode string test.
101 This is a internal function.
104 @param StringDest Buffer to store the string text. If it is NULL,
105 only the size will be returned.
106 @param StringSrc Points to current null-terminated string.
107 @param BufferSize Length of the buffer.
109 @retval EFI_SUCCESS The string text was outputed successfully.
110 @retval EFI_BUFFER_TOO_SMALL Buffer is insufficient to store the found string
111 text. BufferSize is updated to the required buffer
116 ConvertToUnicodeText (
117 OUT EFI_STRING StringDest
,
119 IN OUT UINTN
*BufferSize
125 ASSERT (StringSrc
!= NULL
&& BufferSize
!= NULL
);
127 StringSize
= AsciiStrSize (StringSrc
) * 2;
128 if (*BufferSize
< StringSize
|| StringDest
== NULL
) {
129 *BufferSize
= StringSize
;
130 return EFI_BUFFER_TOO_SMALL
;
133 for (Index
= 0; Index
< AsciiStrLen (StringSrc
); Index
++) {
134 StringDest
[Index
] = (CHAR16
) StringSrc
[Index
];
137 StringDest
[Index
] = 0;
143 Calculate the size of StringSrc and output it. If StringDest is not NULL,
144 copy string text from src to dest.
146 This is a internal function.
148 @param StringDest Buffer to store the string text. If it is NULL,
149 only the size will be returned.
150 @param StringSrc Points to current null-terminated string.
151 @param BufferSize Length of the buffer.
153 @retval EFI_SUCCESS The string text was outputed successfully.
154 @retval EFI_BUFFER_TOO_SMALL Buffer is insufficient to store the found string
155 text. BufferSize is updated to the required buffer
160 GetUnicodeStringTextOrSize (
161 OUT EFI_STRING StringDest
, OPTIONAL
163 IN OUT UINTN
*BufferSize
169 ASSERT (StringSrc
!= NULL
&& BufferSize
!= NULL
);
171 StringSize
= sizeof (CHAR16
);
172 StringPtr
= StringSrc
;
173 while (ReadUnaligned16 ((UINT16
*) StringPtr
) != 0) {
174 StringSize
+= sizeof (CHAR16
);
175 StringPtr
+= sizeof (CHAR16
);
178 if (*BufferSize
< StringSize
) {
179 *BufferSize
= StringSize
;
180 return EFI_BUFFER_TOO_SMALL
;
182 if (StringDest
!= NULL
) {
183 CopyMem (StringDest
, StringSrc
, StringSize
);
186 *BufferSize
= StringSize
;
192 Copy string font info to a buffer.
194 This is a internal function.
196 @param StringPackage Hii string package instance.
197 @param FontId Font identifier which is unique in a string
199 @param StringFontInfo Buffer to record the output font info. It's
200 caller's responsibility to free this buffer.
202 @retval EFI_SUCCESS The string font is outputed successfully.
203 @retval EFI_NOT_FOUND The specified font id does not exist.
208 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
210 OUT EFI_FONT_INFO
**StringFontInfo
214 HII_FONT_INFO
*FontInfo
;
215 HII_GLOBAL_FONT_INFO
*GlobalFont
;
217 ASSERT (StringFontInfo
!= NULL
&& StringPackage
!= NULL
);
219 for (Link
= StringPackage
->FontInfoList
.ForwardLink
; Link
!= &StringPackage
->FontInfoList
; Link
= Link
->ForwardLink
) {
220 FontInfo
= CR (Link
, HII_FONT_INFO
, Entry
, HII_FONT_INFO_SIGNATURE
);
221 if (FontInfo
->FontId
== FontId
) {
222 GlobalFont
= CR (FontInfo
->GlobalEntry
, HII_GLOBAL_FONT_INFO
, Entry
, HII_GLOBAL_FONT_INFO_SIGNATURE
);
223 *StringFontInfo
= (EFI_FONT_INFO
*) AllocateZeroPool (GlobalFont
->FontInfoSize
);
224 if (*StringFontInfo
== NULL
) {
225 return EFI_OUT_OF_RESOURCES
;
227 CopyMem (*StringFontInfo
, GlobalFont
->FontInfo
, GlobalFont
->FontInfoSize
);
232 return EFI_NOT_FOUND
;
237 Parse all string blocks to find a String block specified by StringId.
238 If StringId = (EFI_STRING_ID) (-1), find out all EFI_HII_SIBT_FONT blocks
239 within this string package and backup its information. If LastStringId is
240 specified, the string id of last string block will also be output.
241 If StringId = 0, output the string id of last string block (EFI_HII_SIBT_STRING).
243 @param Private Hii database private structure.
244 @param StringPackage Hii string package instance.
245 @param StringId The string's id, which is unique within
247 @param BlockType Output the block type of found string block.
248 @param StringBlockAddr Output the block address of found string block.
249 @param StringTextOffset Offset, relative to the found block address, of
250 the string text information.
251 @param LastStringId Output the last string id when StringId = 0 or StringId = -1.
252 @param StartStringId The first id in the skip block which StringId in the block.
254 @retval EFI_SUCCESS The string text and font is retrieved
256 @retval EFI_NOT_FOUND The specified text or font info can not be found
258 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
264 IN HII_DATABASE_PRIVATE_DATA
*Private
,
265 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
266 IN EFI_STRING_ID StringId
,
267 OUT UINT8
*BlockType
, OPTIONAL
268 OUT UINT8
**StringBlockAddr
, OPTIONAL
269 OUT UINTN
*StringTextOffset
, OPTIONAL
270 OUT EFI_STRING_ID
*LastStringId
, OPTIONAL
271 OUT EFI_STRING_ID
*StartStringId OPTIONAL
275 EFI_STRING_ID CurrentStringId
;
278 UINT8
*StringTextPtr
;
280 HII_FONT_INFO
*LocalFont
;
281 EFI_FONT_INFO
*FontInfo
;
282 HII_GLOBAL_FONT_INFO
*GlobalFont
;
286 EFI_HII_FONT_STYLE FontStyle
;
289 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
295 ASSERT (StringPackage
!= NULL
);
296 ASSERT (StringPackage
->Signature
== HII_STRING_PACKAGE_SIGNATURE
);
301 if (StringId
!= (EFI_STRING_ID
) (-1) && StringId
!= 0) {
302 ASSERT (BlockType
!= NULL
&& StringBlockAddr
!= NULL
&& StringTextOffset
!= NULL
);
303 if (StringId
> StringPackage
->MaxStringId
) {
304 return EFI_NOT_FOUND
;
307 ASSERT (Private
!= NULL
&& Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
308 if (StringId
== 0 && LastStringId
!= NULL
) {
309 *LastStringId
= StringPackage
->MaxStringId
;
314 ZeroMem (&Zero
, sizeof (CHAR16
));
317 // Parse the string blocks to get the string text and font.
319 BlockHdr
= StringPackage
->StringBlock
;
322 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
324 case EFI_HII_SIBT_STRING_SCSU
:
325 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
326 StringTextPtr
= BlockHdr
+ Offset
;
327 BlockSize
+= Offset
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
331 case EFI_HII_SIBT_STRING_SCSU_FONT
:
332 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
333 StringTextPtr
= BlockHdr
+ Offset
;
334 BlockSize
+= Offset
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
338 case EFI_HII_SIBT_STRINGS_SCSU
:
339 CopyMem (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
340 StringTextPtr
= (UINT8
*)((UINTN
)BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
));
341 BlockSize
+= StringTextPtr
- BlockHdr
;
343 for (Index
= 0; Index
< StringCount
; Index
++) {
344 BlockSize
+= AsciiStrSize ((CHAR8
*) StringTextPtr
);
345 if (CurrentStringId
== StringId
) {
346 ASSERT (BlockType
!= NULL
&& StringBlockAddr
!= NULL
&& StringTextOffset
!= NULL
);
347 *BlockType
= *BlockHdr
;
348 *StringBlockAddr
= BlockHdr
;
349 *StringTextOffset
= StringTextPtr
- BlockHdr
;
352 StringTextPtr
= StringTextPtr
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
357 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
360 (UINT8
*)((UINTN
)BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
)),
363 StringTextPtr
= (UINT8
*)((UINTN
)BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
));
364 BlockSize
+= StringTextPtr
- BlockHdr
;
366 for (Index
= 0; Index
< StringCount
; Index
++) {
367 BlockSize
+= AsciiStrSize ((CHAR8
*) StringTextPtr
);
368 if (CurrentStringId
== StringId
) {
369 ASSERT (BlockType
!= NULL
&& StringBlockAddr
!= NULL
&& StringTextOffset
!= NULL
);
370 *BlockType
= *BlockHdr
;
371 *StringBlockAddr
= BlockHdr
;
372 *StringTextOffset
= StringTextPtr
- BlockHdr
;
375 StringTextPtr
= StringTextPtr
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
380 case EFI_HII_SIBT_STRING_UCS2
:
381 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
382 StringTextPtr
= BlockHdr
+ Offset
;
384 // Use StringSize to store the size of the specified string, including the NULL
387 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
388 BlockSize
+= Offset
+ StringSize
;
392 case EFI_HII_SIBT_STRING_UCS2_FONT
:
393 Offset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
394 StringTextPtr
= BlockHdr
+ Offset
;
396 // Use StrSize to store the size of the specified string, including the NULL
399 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
400 BlockSize
+= Offset
+ StringSize
;
404 case EFI_HII_SIBT_STRINGS_UCS2
:
405 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK
) - sizeof (CHAR16
);
406 StringTextPtr
= BlockHdr
+ Offset
;
408 CopyMem (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
409 for (Index
= 0; Index
< StringCount
; Index
++) {
410 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
411 BlockSize
+= StringSize
;
412 if (CurrentStringId
== StringId
) {
413 ASSERT (BlockType
!= NULL
&& StringBlockAddr
!= NULL
&& StringTextOffset
!= NULL
);
414 *BlockType
= *BlockHdr
;
415 *StringBlockAddr
= BlockHdr
;
416 *StringTextOffset
= StringTextPtr
- BlockHdr
;
419 StringTextPtr
= StringTextPtr
+ StringSize
;
424 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
425 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
426 StringTextPtr
= BlockHdr
+ Offset
;
430 (UINT8
*)((UINTN
)BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
)),
433 for (Index
= 0; Index
< StringCount
; Index
++) {
434 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
435 BlockSize
+= StringSize
;
436 if (CurrentStringId
== StringId
) {
437 ASSERT (BlockType
!= NULL
&& StringBlockAddr
!= NULL
&& StringTextOffset
!= NULL
);
438 *BlockType
= *BlockHdr
;
439 *StringBlockAddr
= BlockHdr
;
440 *StringTextOffset
= StringTextPtr
- BlockHdr
;
443 StringTextPtr
= StringTextPtr
+ StringSize
;
448 case EFI_HII_SIBT_DUPLICATE
:
449 if (CurrentStringId
== StringId
) {
451 // Incoming StringId is an id of a duplicate string block.
452 // Update the StringId to be the previous string block.
453 // Go back to the header of string block to search.
457 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
458 sizeof (EFI_STRING_ID
)
460 ASSERT (StringId
!= CurrentStringId
);
464 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
469 case EFI_HII_SIBT_SKIP1
:
470 SkipCount
= (UINT16
) (*(UINT8
*)((UINTN
)BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
471 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
472 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
475 case EFI_HII_SIBT_SKIP2
:
476 CopyMem (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
477 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
478 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
481 case EFI_HII_SIBT_EXT1
:
484 (UINT8
*)((UINTN
)BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
)),
487 BlockSize
+= Length8
;
490 case EFI_HII_SIBT_EXT2
:
491 CopyMem (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
492 if (Ext2
.BlockType2
== EFI_HII_SIBT_FONT
&& StringId
== (EFI_STRING_ID
) (-1)) {
494 // Find the relationship between global font info and the font info of
495 // this EFI_HII_SIBT_FONT block then backup its information in local package.
497 BlockHdr
+= sizeof (EFI_HII_SIBT_EXT2_BLOCK
);
498 CopyMem (&FontId
, BlockHdr
, sizeof (UINT8
));
500 CopyMem (&FontSize
, BlockHdr
, sizeof (UINT16
));
501 BlockHdr
+= sizeof (UINT16
);
502 CopyMem (&FontStyle
, BlockHdr
, sizeof (EFI_HII_FONT_STYLE
));
503 BlockHdr
+= sizeof (EFI_HII_FONT_STYLE
);
504 GetUnicodeStringTextOrSize (NULL
, BlockHdr
, &StringSize
);
506 FontInfoSize
= sizeof (EFI_FONT_INFO
) - sizeof (CHAR16
) + StringSize
;
507 FontInfo
= (EFI_FONT_INFO
*) AllocateZeroPool (FontInfoSize
);
508 if (FontInfo
== NULL
) {
509 return EFI_OUT_OF_RESOURCES
;
511 FontInfo
->FontStyle
= FontStyle
;
512 FontInfo
->FontSize
= FontSize
;
513 CopyMem (FontInfo
->FontName
, BlockHdr
, StringSize
);
516 // If find the corresponding global font info, save the relationship.
517 // Otherwise ignore this EFI_HII_SIBT_FONT block.
519 if (IsFontInfoExisted (Private
, FontInfo
, NULL
, NULL
, &GlobalFont
)) {
520 ReferFontInfoLocally (Private
, StringPackage
, FontId
, TRUE
, GlobalFont
, &LocalFont
);
524 // Since string package tool set FontId initially to 0 and increases it
525 // progressively by one, StringPackage->FondId always represents an unique
526 // and available FontId.
528 StringPackage
->FontId
++;
533 BlockSize
+= Ext2
.Length
;
537 case EFI_HII_SIBT_EXT4
:
540 (UINT8
*)((UINTN
)BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
)),
544 BlockSize
+= Length32
;
551 if (StringId
> 0 && StringId
!= (EFI_STRING_ID
)(-1)) {
552 ASSERT (BlockType
!= NULL
&& StringBlockAddr
!= NULL
&& StringTextOffset
!= NULL
);
553 *BlockType
= *BlockHdr
;
554 *StringBlockAddr
= BlockHdr
;
555 *StringTextOffset
= Offset
;
557 if (StringId
== CurrentStringId
- 1) {
559 // if only one skip item, return EFI_NOT_FOUND.
561 if(*BlockType
== EFI_HII_SIBT_SKIP2
|| *BlockType
== EFI_HII_SIBT_SKIP1
) {
562 return EFI_NOT_FOUND
;
568 if (StringId
< CurrentStringId
- 1) {
569 return EFI_NOT_FOUND
;
572 BlockHdr
= StringPackage
->StringBlock
+ BlockSize
;
573 if (StartStringId
!= NULL
) {
574 *StartStringId
= CurrentStringId
;
579 // Get last string ID
581 if (StringId
== (EFI_STRING_ID
) (-1) && LastStringId
!= NULL
) {
582 *LastStringId
= (EFI_STRING_ID
) (CurrentStringId
- 1);
586 return EFI_NOT_FOUND
;
591 Parse all string blocks to get a string specified by StringId.
593 This is a internal function.
595 @param Private Hii database private structure.
596 @param StringPackage Hii string package instance.
597 @param StringId The string's id, which is unique within
599 @param String Points to retrieved null-terminated string.
600 @param StringSize On entry, points to the size of the buffer pointed
601 to by String, in bytes. On return, points to the
602 length of the string, in bytes.
603 @param StringFontInfo If not NULL, allocate a buffer to record the
604 output font info. It's caller's responsibility to
607 @retval EFI_SUCCESS The string text and font is retrieved
609 @retval EFI_NOT_FOUND The specified text or font info can not be found
611 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to
617 IN HII_DATABASE_PRIVATE_DATA
*Private
,
618 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
619 IN EFI_STRING_ID StringId
,
620 OUT EFI_STRING String
,
621 IN OUT UINTN
*StringSize
, OPTIONAL
622 OUT EFI_FONT_INFO
**StringFontInfo OPTIONAL
625 UINT8
*StringTextPtr
;
627 UINT8
*StringBlockAddr
;
628 UINTN StringTextOffset
;
632 ASSERT (StringPackage
!= NULL
);
633 ASSERT (Private
!= NULL
&& Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
636 // Find the specified string block
638 Status
= FindStringBlock (
648 if (EFI_ERROR (Status
)) {
652 if (StringSize
== NULL
) {
654 // String text buffer is not requested
660 // Get the string text.
662 StringTextPtr
= StringBlockAddr
+ StringTextOffset
;
664 case EFI_HII_SIBT_STRING_SCSU
:
665 case EFI_HII_SIBT_STRING_SCSU_FONT
:
666 case EFI_HII_SIBT_STRINGS_SCSU
:
667 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
668 Status
= ConvertToUnicodeText (String
, (CHAR8
*) StringTextPtr
, StringSize
);
670 case EFI_HII_SIBT_STRING_UCS2
:
671 case EFI_HII_SIBT_STRING_UCS2_FONT
:
672 case EFI_HII_SIBT_STRINGS_UCS2
:
673 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
674 Status
= GetUnicodeStringTextOrSize (String
, StringTextPtr
, StringSize
);
677 return EFI_NOT_FOUND
;
679 if (EFI_ERROR (Status
)) {
684 // Get the string font. The FontId 0 is the default font for those string blocks which
685 // do not specify a font identifier. If default font is not specified, return NULL.
687 if (StringFontInfo
!= NULL
) {
689 case EFI_HII_SIBT_STRING_SCSU_FONT
:
690 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
691 case EFI_HII_SIBT_STRING_UCS2_FONT
:
692 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
693 FontId
= *(StringBlockAddr
+ sizeof (EFI_HII_STRING_BLOCK
));
698 Status
= GetStringFontInfo (StringPackage
, FontId
, StringFontInfo
);
699 if (Status
== EFI_NOT_FOUND
) {
700 *StringFontInfo
= NULL
;
708 If GetStringBlock find the StringId's string is not saved in the exist string block,
709 this function will create the UCS2 string block to save the string; also split the
710 skip block into two or one skip block.
712 This is a internal function.
714 @param StringPackage Hii string package instance.
715 @param StartStringId The first id in the skip block which StringId in the block.
716 @param StringId The string's id, which is unique within
718 @param BlockType Output the block type of found string block.
719 @param StringBlockAddr Output the block address of found string block.
720 @param FontBlock whether this string block has font info.
722 @retval EFI_SUCCESS The string font is outputed successfully.
723 @retval EFI_OUT_OF_RESOURCES NO resource for the memory to save the new string block.
727 InsertLackStringBlock (
728 IN OUT HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
729 IN EFI_STRING_ID StartStringId
,
730 IN EFI_STRING_ID StringId
,
731 IN OUT UINT8
*BlockType
,
732 IN OUT UINT8
**StringBlockAddr
,
742 UINT32 NewUCSBlockLen
;
743 UINT8
*OldStringAddr
;
748 OldStringAddr
= *StringBlockAddr
;
750 ASSERT (*BlockType
== EFI_HII_SIBT_SKIP1
|| *BlockType
== EFI_HII_SIBT_SKIP2
);
752 // Old skip block size.
754 if (*BlockType
== EFI_HII_SIBT_SKIP1
) {
755 SkipLen
= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
756 IdCount
= *(UINT8
*)(OldStringAddr
+ sizeof (EFI_HII_STRING_BLOCK
));
758 SkipLen
= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
759 IdCount
= *(UINT16
*)(OldStringAddr
+ sizeof (EFI_HII_STRING_BLOCK
));
763 // New create UCS or UCS2 block size.
766 NewUCSBlockLen
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
);
768 NewUCSBlockLen
= sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
);
771 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
773 if (StartStringId
== StringId
) {
775 // New block + [Skip block]
778 NewBlockSize
= OldBlockSize
+ NewUCSBlockLen
;
780 NewBlockSize
= OldBlockSize
+ NewUCSBlockLen
- SkipLen
;
782 } else if (StartStringId
+ IdCount
- 1 == StringId
){
784 // Skip block + New block
786 NewBlockSize
= OldBlockSize
+ NewUCSBlockLen
;
787 FrontSkipNum
= StringId
- StartStringId
;
790 // Skip block + New block + [Skip block]
792 NewBlockSize
= OldBlockSize
+ NewUCSBlockLen
+ SkipLen
;
793 FrontSkipNum
= StringId
- StartStringId
;
796 StringBlock
= (UINT8
*) AllocateZeroPool (NewBlockSize
);
797 if (StringBlock
== NULL
) {
798 return EFI_OUT_OF_RESOURCES
;
802 // Copy old block in front of skip block.
804 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldStringAddr
- StringPackage
->StringBlock
);
805 BlockPtr
= StringBlock
+ (OldStringAddr
- StringPackage
->StringBlock
);
807 if (FrontSkipNum
> 0) {
808 *BlockPtr
= *BlockType
;
809 if (*BlockType
== EFI_HII_SIBT_SKIP1
) {
810 *(BlockPtr
+ sizeof (EFI_HII_STRING_BLOCK
)) = (UINT8
) FrontSkipNum
;
812 *(UINT16
*)(BlockPtr
+ sizeof (EFI_HII_STRING_BLOCK
)) = (UINT16
) FrontSkipNum
;
818 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
820 *StringBlockAddr
= BlockPtr
;
822 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2_FONT
;
824 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
826 BlockPtr
+= NewUCSBlockLen
;
828 if (IdCount
> FrontSkipNum
+ 1) {
829 *BlockPtr
= *BlockType
;
830 if (*BlockType
== EFI_HII_SIBT_SKIP1
) {
831 *(BlockPtr
+ sizeof (EFI_HII_STRING_BLOCK
)) = (UINT8
) (IdCount
- FrontSkipNum
- 1);
833 *(UINT16
*)(BlockPtr
+ sizeof (EFI_HII_STRING_BLOCK
)) = (UINT16
) (IdCount
- FrontSkipNum
- 1);
839 // Append a EFI_HII_SIBT_END block to the end.
841 CopyMem (BlockPtr
, OldStringAddr
+ SkipLen
, OldBlockSize
- (OldStringAddr
- StringPackage
->StringBlock
) - SkipLen
);
844 *BlockType
= EFI_HII_SIBT_STRING_UCS2_FONT
;
846 *BlockType
= EFI_HII_SIBT_STRING_UCS2
;
848 FreePool (StringPackage
->StringBlock
);
849 StringPackage
->StringBlock
= StringBlock
;
850 StringPackage
->StringPkgHdr
->Header
.Length
+= NewBlockSize
- OldBlockSize
;
856 Parse all string blocks to set a String specified by StringId.
858 This is a internal function.
860 @param Private HII database driver private structure.
861 @param StringPackage HII string package instance.
862 @param StringId The string's id, which is unique within
864 @param String Points to the new null-terminated string.
865 @param StringFontInfo Points to the input font info.
867 @retval EFI_SUCCESS The string was updated successfully.
868 @retval EFI_NOT_FOUND The string specified by StringId is not in the
870 @retval EFI_INVALID_PARAMETER The String or Language was NULL.
871 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
873 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
879 IN HII_DATABASE_PRIVATE_DATA
*Private
,
880 IN OUT HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
881 IN EFI_STRING_ID StringId
,
882 IN EFI_STRING String
,
883 IN EFI_FONT_INFO
*StringFontInfo OPTIONAL
886 UINT8
*StringTextPtr
;
888 UINT8
*StringBlockAddr
;
889 UINTN StringTextOffset
;
895 HII_FONT_INFO
*LocalFont
;
896 HII_GLOBAL_FONT_INFO
*GlobalFont
;
898 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
901 EFI_STRING_ID StartStringId
;
905 ASSERT (Private
!= NULL
&& StringPackage
!= NULL
&& String
!= NULL
);
906 ASSERT (Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
908 // Find the specified string block
910 Status
= FindStringBlock (
920 if (EFI_ERROR (Status
) && (BlockType
== EFI_HII_SIBT_SKIP1
|| BlockType
== EFI_HII_SIBT_SKIP2
)) {
921 Status
= InsertLackStringBlock(StringPackage
,
926 (BOOLEAN
)(StringFontInfo
!= NULL
)
928 if (EFI_ERROR (Status
)) {
931 if (StringFontInfo
!= NULL
) {
932 StringTextOffset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
934 StringTextOffset
= sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
) - sizeof (CHAR16
);
943 // The input StringFontInfo should exist in current database if specified.
945 if (StringFontInfo
!= NULL
) {
946 if (!IsFontInfoExisted (Private
, StringFontInfo
, NULL
, NULL
, &GlobalFont
)) {
947 return EFI_INVALID_PARAMETER
;
949 Referred
= ReferFontInfoLocally (
952 StringPackage
->FontId
,
958 StringPackage
->FontId
++;
962 // Update the FontId of the specified string block to input font info.
965 case EFI_HII_SIBT_STRING_SCSU_FONT
:
966 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
967 case EFI_HII_SIBT_STRING_UCS2_FONT
:
968 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
969 *(StringBlockAddr
+ sizeof (EFI_HII_STRING_BLOCK
)) = LocalFont
->FontId
;
973 // When modify the font info of these blocks, the block type should be updated
974 // to contain font info thus the whole structure should be revised.
975 // It is recommended to use tool to modify the block type not in the code.
977 return EFI_UNSUPPORTED
;
981 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
984 // Set the string text and font.
986 StringTextPtr
= StringBlockAddr
+ StringTextOffset
;
988 case EFI_HII_SIBT_STRING_SCSU
:
989 case EFI_HII_SIBT_STRING_SCSU_FONT
:
990 case EFI_HII_SIBT_STRINGS_SCSU
:
991 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
992 BlockSize
= OldBlockSize
+ StrLen (String
);
993 BlockSize
-= AsciiStrSize ((CHAR8
*) StringTextPtr
);
994 Block
= AllocateZeroPool (BlockSize
);
996 return EFI_OUT_OF_RESOURCES
;
999 CopyMem (Block
, StringPackage
->StringBlock
, StringTextPtr
- StringPackage
->StringBlock
);
1000 BlockPtr
= Block
+ (StringTextPtr
- StringPackage
->StringBlock
);
1002 while (*String
!= 0) {
1003 *BlockPtr
++ = (CHAR8
) *String
++;
1008 TmpSize
= OldBlockSize
- (StringTextPtr
- StringPackage
->StringBlock
) - AsciiStrSize ((CHAR8
*) StringTextPtr
);
1011 StringTextPtr
+ AsciiStrSize ((CHAR8
*)StringTextPtr
),
1015 FreePool (StringPackage
->StringBlock
);
1016 StringPackage
->StringBlock
= Block
;
1017 StringPackage
->StringPkgHdr
->Header
.Length
+= (UINT32
) (BlockSize
- OldBlockSize
);
1020 case EFI_HII_SIBT_STRING_UCS2
:
1021 case EFI_HII_SIBT_STRING_UCS2_FONT
:
1022 case EFI_HII_SIBT_STRINGS_UCS2
:
1023 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
1025 // Use StrSize to store the size of the specified string, including the NULL
1028 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
1030 BlockSize
= OldBlockSize
+ StrSize (String
) - StringSize
;
1031 Block
= AllocateZeroPool (BlockSize
);
1032 if (Block
== NULL
) {
1033 return EFI_OUT_OF_RESOURCES
;
1036 CopyMem (Block
, StringPackage
->StringBlock
, StringTextPtr
- StringPackage
->StringBlock
);
1037 BlockPtr
= Block
+ (StringTextPtr
- StringPackage
->StringBlock
);
1039 CopyMem (BlockPtr
, String
, StrSize (String
));
1040 BlockPtr
+= StrSize (String
);
1044 StringTextPtr
+ StringSize
,
1045 OldBlockSize
- (StringTextPtr
- StringPackage
->StringBlock
) - StringSize
1048 FreePool (StringPackage
->StringBlock
);
1049 StringPackage
->StringBlock
= Block
;
1050 StringPackage
->StringPkgHdr
->Header
.Length
+= (UINT32
) (BlockSize
- OldBlockSize
);
1054 return EFI_NOT_FOUND
;
1058 // Insert a new EFI_HII_SIBT_FONT_BLOCK to the header of string block, if incoming
1059 // StringFontInfo does not exist in current string package.
1061 // This new block does not impact on the value of StringId.
1064 if (StringFontInfo
== NULL
|| Referred
) {
1068 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
1069 BlockSize
= OldBlockSize
+ sizeof (EFI_HII_SIBT_FONT_BLOCK
) - sizeof (CHAR16
) +
1070 StrSize (GlobalFont
->FontInfo
->FontName
);
1072 Block
= AllocateZeroPool (BlockSize
);
1073 if (Block
== NULL
) {
1074 return EFI_OUT_OF_RESOURCES
;
1078 Ext2
.Header
.BlockType
= EFI_HII_SIBT_EXT2
;
1079 Ext2
.BlockType2
= EFI_HII_SIBT_FONT
;
1080 Ext2
.Length
= (UINT16
) (BlockSize
- OldBlockSize
);
1081 CopyMem (BlockPtr
, &Ext2
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
1082 BlockPtr
+= sizeof (EFI_HII_SIBT_EXT2_BLOCK
);
1084 *BlockPtr
= LocalFont
->FontId
;
1086 CopyMem (BlockPtr
, &GlobalFont
->FontInfo
->FontSize
, sizeof (UINT16
));
1087 BlockPtr
+= sizeof (UINT16
);
1088 CopyMem (BlockPtr
, &GlobalFont
->FontInfo
->FontStyle
, sizeof (UINT32
));
1089 BlockPtr
+= sizeof (UINT32
);
1092 GlobalFont
->FontInfo
->FontName
,
1093 StrSize (GlobalFont
->FontInfo
->FontName
)
1095 BlockPtr
+= StrSize (GlobalFont
->FontInfo
->FontName
);
1097 CopyMem (BlockPtr
, StringPackage
->StringBlock
, OldBlockSize
);
1099 FreePool (StringPackage
->StringBlock
);
1100 StringPackage
->StringBlock
= Block
;
1101 StringPackage
->StringPkgHdr
->Header
.Length
+= Ext2
.Length
;
1109 This function adds the string String to the group of strings owned by PackageList, with the
1110 specified font information StringFontInfo and returns a new string id.
1111 The new string identifier is guaranteed to be unique within the package list.
1112 That new string identifier is reserved for all languages in the package list.
1115 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1116 @param PackageList Handle of the package list where this string will
1118 @param StringId On return, contains the new strings id, which is
1119 unique within PackageList.
1120 @param Language Points to the language for the new string.
1121 @param LanguageName Points to the printable language name to associate
1122 with the passed in Language field.If LanguageName
1123 is not NULL and the string package header's
1124 LanguageName associated with a given Language is
1125 not zero, the LanguageName being passed in will
1127 @param String Points to the new null-terminated string.
1128 @param StringFontInfo Points to the new string's font information or
1129 NULL if the string should have the default system
1130 font, size and style.
1132 @retval EFI_SUCCESS The new string was added successfully.
1133 @retval EFI_NOT_FOUND The specified PackageList could not be found in
1135 @retval EFI_OUT_OF_RESOURCES Could not add the string due to lack of resources.
1136 @retval EFI_INVALID_PARAMETER String is NULL or StringId is NULL or Language is
1138 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
1145 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1146 IN EFI_HII_HANDLE PackageList
,
1147 OUT EFI_STRING_ID
*StringId
,
1148 IN CONST CHAR8
*Language
,
1149 IN CONST CHAR16
*LanguageName
, OPTIONAL
1150 IN CONST EFI_STRING String
,
1151 IN CONST EFI_FONT_INFO
*StringFontInfo OPTIONAL
1156 HII_DATABASE_PRIVATE_DATA
*Private
;
1157 HII_DATABASE_RECORD
*DatabaseRecord
;
1158 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1159 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1162 UINT32 OldBlockSize
;
1165 UINT32 Ucs2BlockSize
;
1166 UINT32 FontBlockSize
;
1167 UINT32 Ucs2FontBlockSize
;
1168 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
1169 HII_FONT_INFO
*LocalFont
;
1170 HII_GLOBAL_FONT_INFO
*GlobalFont
;
1171 EFI_STRING_ID NewStringId
;
1172 EFI_STRING_ID NextStringId
;
1173 EFI_STRING_ID Index
;
1174 HII_STRING_PACKAGE_INSTANCE
*MatchStringPackage
;
1175 BOOLEAN NewStringPackageCreated
;
1178 if (This
== NULL
|| String
== NULL
|| StringId
== NULL
|| Language
== NULL
|| PackageList
== NULL
) {
1179 return EFI_INVALID_PARAMETER
;
1182 if (!IsHiiHandleValid (PackageList
)) {
1183 return EFI_NOT_FOUND
;
1186 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1190 // If StringFontInfo specify a paritcular font, it should exist in current database.
1192 if (StringFontInfo
!= NULL
) {
1193 if (!IsFontInfoExisted (Private
, (EFI_FONT_INFO
*) StringFontInfo
, NULL
, NULL
, &GlobalFont
)) {
1194 return EFI_INVALID_PARAMETER
;
1199 // Get the matching package list.
1201 PackageListNode
= NULL
;
1202 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1203 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1204 if (DatabaseRecord
->Handle
== PackageList
) {
1205 PackageListNode
= DatabaseRecord
->PackageList
;
1209 if (PackageListNode
== NULL
) {
1210 return EFI_NOT_FOUND
;
1213 Status
= EFI_SUCCESS
;
1214 NewStringPackageCreated
= FALSE
;
1217 StringPackage
= NULL
;
1218 MatchStringPackage
= NULL
;
1219 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1220 Link
!= &PackageListNode
->StringPkgHdr
;
1221 Link
= Link
->ForwardLink
1223 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1225 // Create a string block and corresponding font block if exists, then append them
1226 // to the end of the string package.
1228 Status
= FindStringBlock (
1238 if (EFI_ERROR (Status
)) {
1242 // Make sure that new StringId is same in all String Packages for the different language.
1244 if (NewStringId
!= 0 && NewStringId
!= NextStringId
) {
1246 Status
= EFI_INVALID_PARAMETER
;
1249 NewStringId
= NextStringId
;
1251 // Get the matched string package with language.
1253 if (HiiCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
)) {
1254 MatchStringPackage
= StringPackage
;
1256 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
1258 // Create a blank EFI_HII_SIBT_STRING_UCS2_BLOCK to reserve new string ID.
1260 Ucs2BlockSize
= (UINT32
) sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
);
1262 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ Ucs2BlockSize
);
1263 if (StringBlock
== NULL
) {
1264 Status
= EFI_OUT_OF_RESOURCES
;
1268 // Copy original string blocks, except the EFI_HII_SIBT_END.
1270 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1272 // Create a blank EFI_HII_SIBT_STRING_UCS2 block
1274 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1275 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
1276 BlockPtr
+= sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
);
1279 // Append a EFI_HII_SIBT_END block to the end.
1281 *BlockPtr
= EFI_HII_SIBT_END
;
1282 FreePool (StringPackage
->StringBlock
);
1283 StringPackage
->StringBlock
= StringBlock
;
1284 StringPackage
->StringPkgHdr
->Header
.Length
+= Ucs2BlockSize
;
1285 PackageListNode
->PackageListHdr
.PackageLength
+= Ucs2BlockSize
;
1288 if (NewStringId
== 0) {
1290 // No string package is found.
1291 // Create new string package. StringId 1 is reserved for Language Name string.
1298 *StringId
= (EFI_STRING_ID
) (NewStringId
+ 1);
1301 if (MatchStringPackage
!= NULL
) {
1302 StringPackage
= MatchStringPackage
;
1305 // LanguageName is required to create a new string package.
1307 if (LanguageName
== NULL
) {
1308 Status
= EFI_INVALID_PARAMETER
;
1312 StringPackage
= AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE
));
1313 if (StringPackage
== NULL
) {
1314 Status
= EFI_OUT_OF_RESOURCES
;
1318 StringPackage
->Signature
= HII_STRING_PACKAGE_SIGNATURE
;
1319 StringPackage
->MaxStringId
= *StringId
;
1320 StringPackage
->FontId
= 0;
1321 InitializeListHead (&StringPackage
->FontInfoList
);
1324 // Fill in the string package header
1326 HeaderSize
= (UINT32
) (AsciiStrSize ((CHAR8
*) Language
) - 1 + sizeof (EFI_HII_STRING_PACKAGE_HDR
));
1327 StringPackage
->StringPkgHdr
= AllocateZeroPool (HeaderSize
);
1328 if (StringPackage
->StringPkgHdr
== NULL
) {
1329 FreePool (StringPackage
);
1330 Status
= EFI_OUT_OF_RESOURCES
;
1333 StringPackage
->StringPkgHdr
->Header
.Type
= EFI_HII_PACKAGE_STRINGS
;
1334 StringPackage
->StringPkgHdr
->HdrSize
= HeaderSize
;
1335 StringPackage
->StringPkgHdr
->StringInfoOffset
= HeaderSize
;
1336 CopyMem (StringPackage
->StringPkgHdr
->LanguageWindow
, mLanguageWindow
, 16 * sizeof (CHAR16
));
1337 StringPackage
->StringPkgHdr
->LanguageName
= 1;
1338 AsciiStrCpyS (StringPackage
->StringPkgHdr
->Language
, (HeaderSize
- OFFSET_OF(EFI_HII_STRING_PACKAGE_HDR
,Language
)) / sizeof (CHAR8
), (CHAR8
*) Language
);
1341 // Calculate the length of the string blocks, including string block to record
1342 // printable language full name and EFI_HII_SIBT_END_BLOCK.
1344 Ucs2BlockSize
= (UINT32
) (StrSize ((CHAR16
*) LanguageName
) +
1345 (*StringId
- 1) * sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
) - sizeof (CHAR16
));
1347 BlockSize
= Ucs2BlockSize
+ sizeof (EFI_HII_SIBT_END_BLOCK
);
1348 StringPackage
->StringBlock
= (UINT8
*) AllocateZeroPool (BlockSize
);
1349 if (StringPackage
->StringBlock
== NULL
) {
1350 FreePool (StringPackage
->StringPkgHdr
);
1351 FreePool (StringPackage
);
1352 Status
= EFI_OUT_OF_RESOURCES
;
1357 // Insert the string block of printable language full name
1359 BlockPtr
= StringPackage
->StringBlock
;
1360 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
1361 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1362 CopyMem (BlockPtr
, (EFI_STRING
) LanguageName
, StrSize ((EFI_STRING
) LanguageName
));
1363 BlockPtr
+= StrSize ((EFI_STRING
) LanguageName
);
1364 for (Index
= 2; Index
<= *StringId
- 1; Index
++) {
1365 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
1366 BlockPtr
+= sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
);
1369 // Insert the end block
1371 *BlockPtr
= EFI_HII_SIBT_END
;
1374 // Append this string package node to string package array in this package list.
1376 StringPackage
->StringPkgHdr
->Header
.Length
= HeaderSize
+ BlockSize
;
1377 PackageListNode
->PackageListHdr
.PackageLength
+= StringPackage
->StringPkgHdr
->Header
.Length
;
1378 InsertTailList (&PackageListNode
->StringPkgHdr
, &StringPackage
->StringEntry
);
1379 NewStringPackageCreated
= TRUE
;
1382 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
1384 if (StringFontInfo
== NULL
) {
1386 // Create a EFI_HII_SIBT_STRING_UCS2_BLOCK since font info is not specified.
1388 Ucs2BlockSize
= (UINT32
) (StrSize (String
) + sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
)
1391 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ Ucs2BlockSize
);
1392 if (StringBlock
== NULL
) {
1393 Status
= EFI_OUT_OF_RESOURCES
;
1397 // Copy original string blocks, except the EFI_HII_SIBT_END.
1399 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1401 // Create a EFI_HII_SIBT_STRING_UCS2 block
1403 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1404 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
1405 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1406 CopyMem (BlockPtr
, (EFI_STRING
) String
, StrSize ((EFI_STRING
) String
));
1407 BlockPtr
+= StrSize ((EFI_STRING
) String
);
1410 // Append a EFI_HII_SIBT_END block to the end.
1412 *BlockPtr
= EFI_HII_SIBT_END
;
1413 FreePool (StringPackage
->StringBlock
);
1414 StringPackage
->StringBlock
= StringBlock
;
1415 StringPackage
->StringPkgHdr
->Header
.Length
+= Ucs2BlockSize
;
1416 PackageListNode
->PackageListHdr
.PackageLength
+= Ucs2BlockSize
;
1420 // StringFontInfo is specified here. If there is a EFI_HII_SIBT_FONT_BLOCK
1421 // which refers to this font info, create a EFI_HII_SIBT_STRING_UCS2_FONT block
1422 // only. Otherwise create a EFI_HII_SIBT_FONT block with a EFI_HII_SIBT_STRING
1423 // _UCS2_FONT block.
1425 Ucs2FontBlockSize
= (UINT32
) (StrSize (String
) + sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) -
1427 if (ReferFontInfoLocally (Private
, StringPackage
, StringPackage
->FontId
, FALSE
, GlobalFont
, &LocalFont
)) {
1429 // Create a EFI_HII_SIBT_STRING_UCS2_FONT block only.
1431 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ Ucs2FontBlockSize
);
1432 if (StringBlock
== NULL
) {
1433 Status
= EFI_OUT_OF_RESOURCES
;
1437 // Copy original string blocks, except the EFI_HII_SIBT_END.
1439 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1441 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
1443 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1444 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2_FONT
;
1445 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1446 *BlockPtr
= LocalFont
->FontId
;
1448 CopyMem (BlockPtr
, (EFI_STRING
) String
, StrSize ((EFI_STRING
) String
));
1449 BlockPtr
+= StrSize ((EFI_STRING
) String
);
1452 // Append a EFI_HII_SIBT_END block to the end.
1454 *BlockPtr
= EFI_HII_SIBT_END
;
1455 FreePool (StringPackage
->StringBlock
);
1456 StringPackage
->StringBlock
= StringBlock
;
1457 StringPackage
->StringPkgHdr
->Header
.Length
+= Ucs2FontBlockSize
;
1458 PackageListNode
->PackageListHdr
.PackageLength
+= Ucs2FontBlockSize
;
1462 // EFI_HII_SIBT_FONT_BLOCK does not exist in current string package, so
1463 // create a EFI_HII_SIBT_FONT block to record the font info, then generate
1464 // a EFI_HII_SIBT_STRING_UCS2_FONT block to record the incoming string.
1466 FontBlockSize
= (UINT32
) (StrSize (((EFI_FONT_INFO
*) StringFontInfo
)->FontName
) +
1467 sizeof (EFI_HII_SIBT_FONT_BLOCK
) - sizeof (CHAR16
));
1468 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ FontBlockSize
+ Ucs2FontBlockSize
);
1469 if (StringBlock
== NULL
) {
1470 Status
= EFI_OUT_OF_RESOURCES
;
1474 // Copy original string blocks, except the EFI_HII_SIBT_END.
1476 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1479 // Create a EFI_HII_SIBT_FONT block firstly and then backup its info in string
1480 // package instance for future reference.
1482 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1484 Ext2
.Header
.BlockType
= EFI_HII_SIBT_EXT2
;
1485 Ext2
.BlockType2
= EFI_HII_SIBT_FONT
;
1486 Ext2
.Length
= (UINT16
) FontBlockSize
;
1487 CopyMem (BlockPtr
, &Ext2
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
1488 BlockPtr
+= sizeof (EFI_HII_SIBT_EXT2_BLOCK
);
1490 *BlockPtr
= LocalFont
->FontId
;
1492 CopyMem (BlockPtr
, &((EFI_FONT_INFO
*) StringFontInfo
)->FontSize
, sizeof (UINT16
));
1493 BlockPtr
+= sizeof (UINT16
);
1494 CopyMem (BlockPtr
, &((EFI_FONT_INFO
*) StringFontInfo
)->FontStyle
, sizeof (EFI_HII_FONT_STYLE
));
1495 BlockPtr
+= sizeof (EFI_HII_FONT_STYLE
);
1498 &((EFI_FONT_INFO
*) StringFontInfo
)->FontName
,
1499 StrSize (((EFI_FONT_INFO
*) StringFontInfo
)->FontName
)
1501 BlockPtr
+= StrSize (((EFI_FONT_INFO
*) StringFontInfo
)->FontName
);
1503 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
1505 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2_FONT
;
1506 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1507 *BlockPtr
= LocalFont
->FontId
;
1509 CopyMem (BlockPtr
, (EFI_STRING
) String
, StrSize ((EFI_STRING
) String
));
1510 BlockPtr
+= StrSize ((EFI_STRING
) String
);
1513 // Append a EFI_HII_SIBT_END block to the end.
1515 *BlockPtr
= EFI_HII_SIBT_END
;
1516 FreePool (StringPackage
->StringBlock
);
1517 StringPackage
->StringBlock
= StringBlock
;
1518 StringPackage
->StringPkgHdr
->Header
.Length
+= FontBlockSize
+ Ucs2FontBlockSize
;
1519 PackageListNode
->PackageListHdr
.PackageLength
+= FontBlockSize
+ Ucs2FontBlockSize
;
1522 // Increase the FontId to make it unique since we already add
1523 // a EFI_HII_SIBT_FONT block to this string package.
1525 StringPackage
->FontId
++;
1530 if (!EFI_ERROR (Status
) && NewStringPackageCreated
) {
1532 // Trigger any registered notification function for new string package
1534 Status
= InvokeRegisteredFunction (
1536 EFI_HII_DATABASE_NOTIFY_NEW_PACK
,
1537 (VOID
*) StringPackage
,
1538 EFI_HII_PACKAGE_STRINGS
,
1543 if (!EFI_ERROR (Status
)) {
1545 // Update MaxString Id to new StringId
1547 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1548 Link
!= &PackageListNode
->StringPkgHdr
;
1549 Link
= Link
->ForwardLink
1551 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1552 StringPackage
->MaxStringId
= *StringId
;
1554 } else if (NewStringPackageCreated
) {
1556 // Free the allocated new string Package when new string can't be added.
1558 RemoveEntryList (&StringPackage
->StringEntry
);
1559 FreePool (StringPackage
->StringBlock
);
1560 FreePool (StringPackage
->StringPkgHdr
);
1561 FreePool (StringPackage
);
1569 This function retrieves the string specified by StringId which is associated
1570 with the specified PackageList in the language Language and copies it into
1571 the buffer specified by String.
1573 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1574 @param Language Points to the language for the retrieved string.
1575 @param PackageList The package list in the HII database to search for
1576 the specified string.
1577 @param StringId The string's id, which is unique within
1579 @param String Points to the new null-terminated string.
1580 @param StringSize On entry, points to the size of the buffer pointed
1581 to by String, in bytes. On return, points to the
1582 length of the string, in bytes.
1583 @param StringFontInfo If not NULL, points to the string's font
1584 information. It's caller's responsibility to free
1587 @retval EFI_SUCCESS The string was returned successfully.
1588 @retval EFI_NOT_FOUND The string specified by StringId is not available.
1589 @retval EFI_NOT_FOUND The string specified by StringId is available but
1590 not in the specified language.
1591 The specified PackageList is not in the database.
1592 @retval EFI_INVALID_LANGUAGE - The string specified by StringId is available but
1593 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to
1595 @retval EFI_INVALID_PARAMETER The Language or StringSize was NULL.
1596 @retval EFI_INVALID_PARAMETER The value referenced by StringSize was not zero and String was NULL.
1597 @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the
1604 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1605 IN CONST CHAR8
*Language
,
1606 IN EFI_HII_HANDLE PackageList
,
1607 IN EFI_STRING_ID StringId
,
1608 OUT EFI_STRING String
,
1609 IN OUT UINTN
*StringSize
,
1610 OUT EFI_FONT_INFO
**StringFontInfo OPTIONAL
1615 HII_DATABASE_PRIVATE_DATA
*Private
;
1616 HII_DATABASE_RECORD
*DatabaseRecord
;
1617 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1618 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1620 if (This
== NULL
|| Language
== NULL
|| StringId
< 1 || StringSize
== NULL
|| PackageList
== NULL
) {
1621 return EFI_INVALID_PARAMETER
;
1624 if (String
== NULL
&& *StringSize
!= 0) {
1625 return EFI_INVALID_PARAMETER
;
1628 if (!IsHiiHandleValid (PackageList
)) {
1629 return EFI_NOT_FOUND
;
1632 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1633 PackageListNode
= NULL
;
1635 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1636 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1637 if (DatabaseRecord
->Handle
== PackageList
) {
1638 PackageListNode
= DatabaseRecord
->PackageList
;
1643 if (PackageListNode
!= NULL
) {
1645 // First search: to match the StringId in the specified language.
1647 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1648 Link
!= &PackageListNode
->StringPkgHdr
;
1649 Link
= Link
->ForwardLink
1651 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1652 if (HiiCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
)) {
1653 Status
= GetStringWorker (Private
, StringPackage
, StringId
, String
, StringSize
, StringFontInfo
);
1654 if (Status
!= EFI_NOT_FOUND
) {
1660 // Second search: to match the StringId in other available languages if exist.
1662 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1663 Link
!= &PackageListNode
->StringPkgHdr
;
1664 Link
= Link
->ForwardLink
1666 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1667 Status
= GetStringWorker (Private
, StringPackage
, StringId
, NULL
, NULL
, NULL
);
1668 if (!EFI_ERROR (Status
)) {
1669 return EFI_INVALID_LANGUAGE
;
1674 return EFI_NOT_FOUND
;
1680 This function updates the string specified by StringId in the specified PackageList to the text
1681 specified by String and, optionally, the font information specified by StringFontInfo.
1683 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1684 @param PackageList The package list containing the strings.
1685 @param StringId The string's id, which is unique within
1687 @param Language Points to the language for the updated string.
1688 @param String Points to the new null-terminated string.
1689 @param StringFontInfo Points to the string's font information or NULL if
1690 the string font information is not changed.
1692 @retval EFI_SUCCESS The string was updated successfully.
1693 @retval EFI_NOT_FOUND The string specified by StringId is not in the
1695 @retval EFI_INVALID_PARAMETER The String or Language was NULL.
1696 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
1698 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
1705 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1706 IN EFI_HII_HANDLE PackageList
,
1707 IN EFI_STRING_ID StringId
,
1708 IN CONST CHAR8
*Language
,
1709 IN CONST EFI_STRING String
,
1710 IN CONST EFI_FONT_INFO
*StringFontInfo OPTIONAL
1715 HII_DATABASE_PRIVATE_DATA
*Private
;
1716 HII_DATABASE_RECORD
*DatabaseRecord
;
1717 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1718 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1719 UINT32 OldPackageLen
;
1721 if (This
== NULL
|| Language
== NULL
|| StringId
< 1 || String
== NULL
|| PackageList
== NULL
) {
1722 return EFI_INVALID_PARAMETER
;
1725 if (!IsHiiHandleValid (PackageList
)) {
1726 return EFI_NOT_FOUND
;
1729 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1730 PackageListNode
= NULL
;
1732 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1733 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1734 if (DatabaseRecord
->Handle
== PackageList
) {
1735 PackageListNode
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*) (DatabaseRecord
->PackageList
);
1739 if (PackageListNode
!= NULL
) {
1740 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1741 Link
!= &PackageListNode
->StringPkgHdr
;
1742 Link
= Link
->ForwardLink
1744 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1745 if (HiiCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
)) {
1746 OldPackageLen
= StringPackage
->StringPkgHdr
->Header
.Length
;
1747 Status
= SetStringWorker (
1751 (EFI_STRING
) String
,
1752 (EFI_FONT_INFO
*) StringFontInfo
1754 if (EFI_ERROR (Status
)) {
1757 PackageListNode
->PackageListHdr
.PackageLength
+= StringPackage
->StringPkgHdr
->Header
.Length
- OldPackageLen
;
1763 return EFI_NOT_FOUND
;
1769 This function returns the list of supported languages, in the format specified
1770 in Appendix M of UEFI 2.1 spec.
1772 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1773 @param PackageList The package list to examine.
1774 @param Languages Points to the buffer to hold the returned
1775 null-terminated ASCII string.
1776 @param LanguagesSize On entry, points to the size of the buffer pointed
1777 to by Languages, in bytes. On return, points to
1778 the length of Languages, in bytes.
1780 @retval EFI_SUCCESS The languages were returned successfully.
1781 @retval EFI_INVALID_PARAMETER The LanguagesSize was NULL.
1782 @retval EFI_INVALID_PARAMETER The value referenced by LanguagesSize is not zero and Languages is NULL.
1783 @retval EFI_BUFFER_TOO_SMALL The LanguagesSize is too small to hold the list of
1784 supported languages. LanguageSize is updated to
1785 contain the required size.
1786 @retval EFI_NOT_FOUND Could not find string package in specified
1793 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1794 IN EFI_HII_HANDLE PackageList
,
1795 IN OUT CHAR8
*Languages
,
1796 IN OUT UINTN
*LanguagesSize
1800 HII_DATABASE_PRIVATE_DATA
*Private
;
1801 HII_DATABASE_RECORD
*DatabaseRecord
;
1802 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1803 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1806 if (This
== NULL
|| LanguagesSize
== NULL
|| PackageList
== NULL
) {
1807 return EFI_INVALID_PARAMETER
;
1809 if (*LanguagesSize
!= 0 && Languages
== NULL
) {
1810 return EFI_INVALID_PARAMETER
;
1812 if (!IsHiiHandleValid (PackageList
)) {
1813 return EFI_NOT_FOUND
;
1816 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1818 PackageListNode
= NULL
;
1819 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1820 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1821 if (DatabaseRecord
->Handle
== PackageList
) {
1822 PackageListNode
= DatabaseRecord
->PackageList
;
1826 if (PackageListNode
== NULL
) {
1827 return EFI_NOT_FOUND
;
1831 // Search the languages in the specified packagelist.
1834 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1835 Link
!= &PackageListNode
->StringPkgHdr
;
1836 Link
= Link
->ForwardLink
1838 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1839 ResultSize
+= AsciiStrSize (StringPackage
->StringPkgHdr
->Language
);
1840 if (ResultSize
<= *LanguagesSize
) {
1841 AsciiStrCpyS (Languages
, *LanguagesSize
/ sizeof (CHAR8
), StringPackage
->StringPkgHdr
->Language
);
1842 Languages
+= AsciiStrSize (StringPackage
->StringPkgHdr
->Language
);
1843 *(Languages
- 1) = L
';';
1846 if (ResultSize
== 0) {
1847 return EFI_NOT_FOUND
;
1850 if (*LanguagesSize
< ResultSize
) {
1851 *LanguagesSize
= ResultSize
;
1852 return EFI_BUFFER_TOO_SMALL
;
1855 *(Languages
- 1) = 0;
1861 Each string package has associated with it a single primary language and zero
1862 or more secondary languages. This routine returns the secondary languages
1863 associated with a package list.
1865 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1866 @param PackageList The package list to examine.
1867 @param PrimaryLanguage Points to the null-terminated ASCII string that specifies
1868 the primary language. Languages are specified in the
1869 format specified in Appendix M of the UEFI 2.0 specification.
1870 @param SecondaryLanguages Points to the buffer to hold the returned null-terminated
1871 ASCII string that describes the list of
1872 secondary languages for the specified
1873 PrimaryLanguage. If there are no secondary
1874 languages, the function returns successfully, but
1875 this is set to NULL.
1876 @param SecondaryLanguagesSize On entry, points to the size of the buffer pointed
1877 to by SecondaryLanguages, in bytes. On return,
1878 points to the length of SecondaryLanguages in bytes.
1880 @retval EFI_SUCCESS Secondary languages were correctly returned.
1881 @retval EFI_INVALID_PARAMETER PrimaryLanguage or SecondaryLanguagesSize was NULL.
1882 @retval EFI_INVALID_PARAMETER The value referenced by SecondaryLanguagesSize is not
1883 zero and SecondaryLanguages is NULL.
1884 @retval EFI_BUFFER_TOO_SMALL The buffer specified by SecondaryLanguagesSize is
1885 too small to hold the returned information.
1886 SecondaryLanguageSize is updated to hold the size of
1887 the buffer required.
1888 @retval EFI_INVALID_LANGUAGE The language specified by PrimaryLanguage is not
1889 present in the specified package list.
1890 @retval EFI_NOT_FOUND The specified PackageList is not in the Database.
1895 HiiGetSecondaryLanguages (
1896 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1897 IN EFI_HII_HANDLE PackageList
,
1898 IN CONST CHAR8
*PrimaryLanguage
,
1899 IN OUT CHAR8
*SecondaryLanguages
,
1900 IN OUT UINTN
*SecondaryLanguagesSize
1905 HII_DATABASE_PRIVATE_DATA
*Private
;
1906 HII_DATABASE_RECORD
*DatabaseRecord
;
1907 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1908 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1912 if (This
== NULL
|| PackageList
== NULL
|| PrimaryLanguage
== NULL
|| SecondaryLanguagesSize
== NULL
) {
1913 return EFI_INVALID_PARAMETER
;
1915 if (SecondaryLanguages
== NULL
&& *SecondaryLanguagesSize
!= 0) {
1916 return EFI_INVALID_PARAMETER
;
1918 if (!IsHiiHandleValid (PackageList
)) {
1919 return EFI_NOT_FOUND
;
1922 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1924 PackageListNode
= NULL
;
1925 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1926 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1927 if (DatabaseRecord
->Handle
== PackageList
) {
1928 PackageListNode
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*) (DatabaseRecord
->PackageList
);
1932 if (PackageListNode
== NULL
) {
1933 return EFI_NOT_FOUND
;
1938 for (Link1
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1939 Link1
!= &PackageListNode
->StringPkgHdr
;
1940 Link1
= Link1
->ForwardLink
1942 StringPackage
= CR (Link1
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1943 if (HiiCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) PrimaryLanguage
)) {
1944 Languages
= StringPackage
->StringPkgHdr
->Language
;
1946 // Language is a series of ';' terminated strings, first one is primary
1947 // language and following with other secondary languages or NULL if no
1948 // secondary languages any more.
1950 Languages
= AsciiStrStr (Languages
, ";");
1951 if (Languages
== NULL
) {
1956 ResultSize
= AsciiStrSize (Languages
);
1957 if (ResultSize
<= *SecondaryLanguagesSize
) {
1958 AsciiStrCpyS (SecondaryLanguages
, *SecondaryLanguagesSize
/ sizeof (CHAR8
), Languages
);
1960 *SecondaryLanguagesSize
= ResultSize
;
1961 return EFI_BUFFER_TOO_SMALL
;
1968 return EFI_INVALID_LANGUAGE
;
1972 Converts the ascii character of the string from uppercase to lowercase.
1973 This is a internal function.
1975 @param ConfigString String to be converted
1981 IN CHAR8
*ConfigString
1984 ASSERT (ConfigString
!= NULL
);
1987 // Convert all hex digits in range [A-F] in the configuration header to [a-f]
1989 for (; *ConfigString
!= '\0'; ConfigString
++) {
1990 if ( *ConfigString
>= 'A' && *ConfigString
<= 'Z') {
1991 *ConfigString
= (CHAR8
) (*ConfigString
- 'A' + 'a');
1997 Compare whether two names of languages are identical.
1999 @param Language1 Name of language 1 from StringPackage
2000 @param Language2 Name of language 2 to be compared with language 1.
2003 @retval FALSE not same
2007 HiiCompareLanguage (
2008 IN CHAR8
*Language1
,
2018 // Convert to lower to compare.
2020 StrLen
= AsciiStrSize (Language1
);
2021 Lan1
= AllocateZeroPool (StrLen
);
2022 ASSERT (Lan1
!= NULL
);
2023 AsciiStrCpyS(Lan1
, StrLen
/ sizeof (CHAR8
), Language1
);
2024 AsciiHiiToLower (Lan1
);
2026 StrLen
= AsciiStrSize (Language2
);
2027 Lan2
= AllocateZeroPool (StrLen
);
2028 ASSERT (Lan2
!= NULL
);
2029 AsciiStrCpyS(Lan2
, StrLen
/ sizeof (CHAR8
), Language2
);
2030 AsciiHiiToLower (Lan2
);
2033 // Compare the Primary Language in Language1 to Language2
2035 for (Index
= 0; Lan1
[Index
] != 0 && Lan1
[Index
] != ';'; Index
++) {
2036 if (Lan1
[Index
] != Lan2
[Index
]) {
2038 // Return FALSE if any characters are different.
2050 // Only return TRUE if Language2[Index] is a Null-terminator which means
2051 // the Primary Language in Language1 is the same length as Language2. If
2052 // Language2[Index] is not a Null-terminator, then Language2 is longer than
2053 // the Primary Language in Language1, and FALSE must be returned.
2055 return (BOOLEAN
) (Language2
[Index
] == 0);