2 Implementation for EFI_HII_STRING_PROTOCOL.
5 Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>
6 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include "HiiDatabase.h"
14 CHAR16 mLanguageWindow
[16] = {
15 0x0000, 0x0080, 0x0100, 0x0300,
16 0x2000, 0x2080, 0x2100, 0x3000,
17 0x0080, 0x00C0, 0x0400, 0x0600,
18 0x0900, 0x3040, 0x30A0, 0xFF00
23 This function checks whether a global font info is referred by local
24 font info list or not. (i.e. HII_FONT_INFO is generated.) If not, create
25 a HII_FONT_INFO to refer it locally.
27 This is a internal function.
30 @param Private Hii database private structure.
31 @param StringPackage HII string package instance.
32 @param FontId Font identifer, which must be unique within the string package.
33 @param DuplicateEnable If true, duplicate HII_FONT_INFO which refers to
34 the same EFI_FONT_INFO is permitted. Otherwise it
36 @param GlobalFontInfo Input a global font info which specify a
38 @param LocalFontInfo Output a local font info which refers to a
41 @retval TRUE Already referred before calling this function.
42 @retval FALSE Not referred before calling this function.
46 ReferFontInfoLocally (
47 IN HII_DATABASE_PRIVATE_DATA
*Private
,
48 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
50 IN BOOLEAN DuplicateEnable
,
51 IN HII_GLOBAL_FONT_INFO
*GlobalFontInfo
,
52 OUT HII_FONT_INFO
**LocalFontInfo
55 HII_FONT_INFO
*LocalFont
;
58 ASSERT (Private
!= NULL
&& StringPackage
!= NULL
&& GlobalFontInfo
!= NULL
&& LocalFontInfo
!= NULL
);
60 if (!DuplicateEnable
) {
61 for (Link
= StringPackage
->FontInfoList
.ForwardLink
;
62 Link
!= &StringPackage
->FontInfoList
;
63 Link
= Link
->ForwardLink
65 LocalFont
= CR (Link
, HII_FONT_INFO
, Entry
, HII_FONT_INFO_SIGNATURE
);
66 if (LocalFont
->GlobalEntry
== &GlobalFontInfo
->Entry
) {
68 // Already referred by local font info list, return directly.
70 *LocalFontInfo
= LocalFont
;
75 // FontId identifies EFI_FONT_INFO in local string package uniquely.
76 // GlobalEntry points to a HII_GLOBAL_FONT_INFO which identifies
77 // EFI_FONT_INFO uniquely in whole hii database.
79 LocalFont
= (HII_FONT_INFO
*) AllocateZeroPool (sizeof (HII_FONT_INFO
));
80 ASSERT (LocalFont
!= NULL
);
82 LocalFont
->Signature
= HII_FONT_INFO_SIGNATURE
;
83 LocalFont
->FontId
= FontId
;
84 LocalFont
->GlobalEntry
= &GlobalFontInfo
->Entry
;
85 InsertTailList (&StringPackage
->FontInfoList
, &LocalFont
->Entry
);
87 *LocalFontInfo
= LocalFont
;
93 Convert Ascii string text to unicode string test.
95 This is a internal function.
98 @param StringDest Buffer to store the string text. If it is NULL,
99 only the size will be returned.
100 @param StringSrc Points to current null-terminated string.
101 @param BufferSize Length of the buffer.
103 @retval EFI_SUCCESS The string text was outputted successfully.
104 @retval EFI_BUFFER_TOO_SMALL Buffer is insufficient to store the found string
105 text. BufferSize is updated to the required buffer
110 ConvertToUnicodeText (
111 OUT EFI_STRING StringDest
,
113 IN OUT UINTN
*BufferSize
119 ASSERT (StringSrc
!= NULL
&& BufferSize
!= NULL
);
121 StringSize
= AsciiStrSize (StringSrc
) * 2;
122 if (*BufferSize
< StringSize
|| StringDest
== NULL
) {
123 *BufferSize
= StringSize
;
124 return EFI_BUFFER_TOO_SMALL
;
127 for (Index
= 0; Index
< AsciiStrLen (StringSrc
); Index
++) {
128 StringDest
[Index
] = (CHAR16
) StringSrc
[Index
];
131 StringDest
[Index
] = 0;
137 Calculate the size of StringSrc and output it. If StringDest is not NULL,
138 copy string text from src to dest.
140 This is a internal function.
142 @param StringDest Buffer to store the string text. If it is NULL,
143 only the size will be returned.
144 @param StringSrc Points to current null-terminated string.
145 @param BufferSize Length of the buffer.
147 @retval EFI_SUCCESS The string text was outputted successfully.
148 @retval EFI_BUFFER_TOO_SMALL Buffer is insufficient to store the found string
149 text. BufferSize is updated to the required buffer
154 GetUnicodeStringTextOrSize (
155 OUT EFI_STRING StringDest
, OPTIONAL
157 IN OUT UINTN
*BufferSize
163 ASSERT (StringSrc
!= NULL
&& BufferSize
!= NULL
);
165 StringSize
= sizeof (CHAR16
);
166 StringPtr
= StringSrc
;
167 while (ReadUnaligned16 ((UINT16
*) StringPtr
) != 0) {
168 StringSize
+= sizeof (CHAR16
);
169 StringPtr
+= sizeof (CHAR16
);
172 if (*BufferSize
< StringSize
) {
173 *BufferSize
= StringSize
;
174 return EFI_BUFFER_TOO_SMALL
;
176 if (StringDest
!= NULL
) {
177 CopyMem (StringDest
, StringSrc
, StringSize
);
180 *BufferSize
= StringSize
;
186 Copy string font info to a buffer.
188 This is a internal function.
190 @param StringPackage Hii string package instance.
191 @param FontId Font identifier which is unique in a string
193 @param StringFontInfo Buffer to record the output font info. It's
194 caller's responsibility to free this buffer.
196 @retval EFI_SUCCESS The string font is outputted successfully.
197 @retval EFI_NOT_FOUND The specified font id does not exist.
202 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
204 OUT EFI_FONT_INFO
**StringFontInfo
208 HII_FONT_INFO
*FontInfo
;
209 HII_GLOBAL_FONT_INFO
*GlobalFont
;
211 ASSERT (StringFontInfo
!= NULL
&& StringPackage
!= NULL
);
213 for (Link
= StringPackage
->FontInfoList
.ForwardLink
; Link
!= &StringPackage
->FontInfoList
; Link
= Link
->ForwardLink
) {
214 FontInfo
= CR (Link
, HII_FONT_INFO
, Entry
, HII_FONT_INFO_SIGNATURE
);
215 if (FontInfo
->FontId
== FontId
) {
216 GlobalFont
= CR (FontInfo
->GlobalEntry
, HII_GLOBAL_FONT_INFO
, Entry
, HII_GLOBAL_FONT_INFO_SIGNATURE
);
217 *StringFontInfo
= (EFI_FONT_INFO
*) AllocateZeroPool (GlobalFont
->FontInfoSize
);
218 if (*StringFontInfo
== NULL
) {
219 return EFI_OUT_OF_RESOURCES
;
221 CopyMem (*StringFontInfo
, GlobalFont
->FontInfo
, GlobalFont
->FontInfoSize
);
226 return EFI_NOT_FOUND
;
231 Parse all string blocks to find a String block specified by StringId.
232 If StringId = (EFI_STRING_ID) (-1), find out all EFI_HII_SIBT_FONT blocks
233 within this string package and backup its information. If LastStringId is
234 specified, the string id of last string block will also be output.
235 If StringId = 0, output the string id of last string block (EFI_HII_SIBT_STRING).
237 @param Private Hii database private structure.
238 @param StringPackage Hii string package instance.
239 @param StringId The string's id, which is unique within
241 @param BlockType Output the block type of found string block.
242 @param StringBlockAddr Output the block address of found string block.
243 @param StringTextOffset Offset, relative to the found block address, of
244 the string text information.
245 @param LastStringId Output the last string id when StringId = 0 or StringId = -1.
246 @param StartStringId The first id in the skip block which StringId in the block.
248 @retval EFI_SUCCESS The string text and font is retrieved
250 @retval EFI_NOT_FOUND The specified text or font info can not be found
252 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
258 IN HII_DATABASE_PRIVATE_DATA
*Private
,
259 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
260 IN EFI_STRING_ID StringId
,
261 OUT UINT8
*BlockType
, OPTIONAL
262 OUT UINT8
**StringBlockAddr
, OPTIONAL
263 OUT UINTN
*StringTextOffset
, OPTIONAL
264 OUT EFI_STRING_ID
*LastStringId
, OPTIONAL
265 OUT EFI_STRING_ID
*StartStringId OPTIONAL
269 EFI_STRING_ID CurrentStringId
;
272 UINT8
*StringTextPtr
;
274 HII_FONT_INFO
*LocalFont
;
275 EFI_FONT_INFO
*FontInfo
;
276 HII_GLOBAL_FONT_INFO
*GlobalFont
;
280 EFI_HII_FONT_STYLE FontStyle
;
283 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
289 ASSERT (StringPackage
!= NULL
);
290 ASSERT (StringPackage
->Signature
== HII_STRING_PACKAGE_SIGNATURE
);
295 if (StringId
!= (EFI_STRING_ID
) (-1) && StringId
!= 0) {
296 ASSERT (BlockType
!= NULL
&& StringBlockAddr
!= NULL
&& StringTextOffset
!= NULL
);
297 if (StringId
> StringPackage
->MaxStringId
) {
298 return EFI_NOT_FOUND
;
301 ASSERT (Private
!= NULL
&& Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
302 if (StringId
== 0 && LastStringId
!= NULL
) {
303 *LastStringId
= StringPackage
->MaxStringId
;
308 ZeroMem (&Zero
, sizeof (CHAR16
));
311 // Parse the string blocks to get the string text and font.
313 BlockHdr
= StringPackage
->StringBlock
;
316 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
318 case EFI_HII_SIBT_STRING_SCSU
:
319 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
320 StringTextPtr
= BlockHdr
+ Offset
;
321 BlockSize
+= Offset
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
325 case EFI_HII_SIBT_STRING_SCSU_FONT
:
326 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
327 StringTextPtr
= BlockHdr
+ Offset
;
328 BlockSize
+= Offset
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
332 case EFI_HII_SIBT_STRINGS_SCSU
:
333 CopyMem (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
334 StringTextPtr
= (UINT8
*)((UINTN
)BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
));
335 BlockSize
+= StringTextPtr
- BlockHdr
;
337 for (Index
= 0; Index
< StringCount
; Index
++) {
338 BlockSize
+= AsciiStrSize ((CHAR8
*) StringTextPtr
);
339 if (CurrentStringId
== StringId
) {
340 ASSERT (BlockType
!= NULL
&& StringBlockAddr
!= NULL
&& StringTextOffset
!= NULL
);
341 *BlockType
= *BlockHdr
;
342 *StringBlockAddr
= BlockHdr
;
343 *StringTextOffset
= StringTextPtr
- BlockHdr
;
346 StringTextPtr
= StringTextPtr
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
351 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
354 (UINT8
*)((UINTN
)BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
)),
357 StringTextPtr
= (UINT8
*)((UINTN
)BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
));
358 BlockSize
+= StringTextPtr
- BlockHdr
;
360 for (Index
= 0; Index
< StringCount
; Index
++) {
361 BlockSize
+= AsciiStrSize ((CHAR8
*) StringTextPtr
);
362 if (CurrentStringId
== StringId
) {
363 ASSERT (BlockType
!= NULL
&& StringBlockAddr
!= NULL
&& StringTextOffset
!= NULL
);
364 *BlockType
= *BlockHdr
;
365 *StringBlockAddr
= BlockHdr
;
366 *StringTextOffset
= StringTextPtr
- BlockHdr
;
369 StringTextPtr
= StringTextPtr
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
374 case EFI_HII_SIBT_STRING_UCS2
:
375 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
376 StringTextPtr
= BlockHdr
+ Offset
;
378 // Use StringSize to store the size of the specified string, including the NULL
381 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
382 BlockSize
+= Offset
+ StringSize
;
386 case EFI_HII_SIBT_STRING_UCS2_FONT
:
387 Offset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
388 StringTextPtr
= BlockHdr
+ Offset
;
390 // Use StrSize to store the size of the specified string, including the NULL
393 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
394 BlockSize
+= Offset
+ StringSize
;
398 case EFI_HII_SIBT_STRINGS_UCS2
:
399 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK
) - sizeof (CHAR16
);
400 StringTextPtr
= BlockHdr
+ Offset
;
402 CopyMem (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
403 for (Index
= 0; Index
< StringCount
; Index
++) {
404 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
405 BlockSize
+= StringSize
;
406 if (CurrentStringId
== StringId
) {
407 ASSERT (BlockType
!= NULL
&& StringBlockAddr
!= NULL
&& StringTextOffset
!= NULL
);
408 *BlockType
= *BlockHdr
;
409 *StringBlockAddr
= BlockHdr
;
410 *StringTextOffset
= StringTextPtr
- BlockHdr
;
413 StringTextPtr
= StringTextPtr
+ StringSize
;
418 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
419 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
420 StringTextPtr
= BlockHdr
+ Offset
;
424 (UINT8
*)((UINTN
)BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
)),
427 for (Index
= 0; Index
< StringCount
; Index
++) {
428 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
429 BlockSize
+= StringSize
;
430 if (CurrentStringId
== StringId
) {
431 ASSERT (BlockType
!= NULL
&& StringBlockAddr
!= NULL
&& StringTextOffset
!= NULL
);
432 *BlockType
= *BlockHdr
;
433 *StringBlockAddr
= BlockHdr
;
434 *StringTextOffset
= StringTextPtr
- BlockHdr
;
437 StringTextPtr
= StringTextPtr
+ StringSize
;
442 case EFI_HII_SIBT_DUPLICATE
:
443 if (CurrentStringId
== StringId
) {
445 // Incoming StringId is an id of a duplicate string block.
446 // Update the StringId to be the previous string block.
447 // Go back to the header of string block to search.
451 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
452 sizeof (EFI_STRING_ID
)
454 ASSERT (StringId
!= CurrentStringId
);
458 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
463 case EFI_HII_SIBT_SKIP1
:
464 SkipCount
= (UINT16
) (*(UINT8
*)((UINTN
)BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
465 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
466 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
469 case EFI_HII_SIBT_SKIP2
:
470 CopyMem (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
471 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
472 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
475 case EFI_HII_SIBT_EXT1
:
478 (UINT8
*)((UINTN
)BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
)),
481 BlockSize
+= Length8
;
484 case EFI_HII_SIBT_EXT2
:
485 CopyMem (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
486 if (Ext2
.BlockType2
== EFI_HII_SIBT_FONT
&& StringId
== (EFI_STRING_ID
) (-1)) {
488 // Find the relationship between global font info and the font info of
489 // this EFI_HII_SIBT_FONT block then backup its information in local package.
491 BlockHdr
+= sizeof (EFI_HII_SIBT_EXT2_BLOCK
);
492 CopyMem (&FontId
, BlockHdr
, sizeof (UINT8
));
494 CopyMem (&FontSize
, BlockHdr
, sizeof (UINT16
));
495 BlockHdr
+= sizeof (UINT16
);
496 CopyMem (&FontStyle
, BlockHdr
, sizeof (EFI_HII_FONT_STYLE
));
497 BlockHdr
+= sizeof (EFI_HII_FONT_STYLE
);
498 GetUnicodeStringTextOrSize (NULL
, BlockHdr
, &StringSize
);
500 FontInfoSize
= sizeof (EFI_FONT_INFO
) - sizeof (CHAR16
) + StringSize
;
501 FontInfo
= (EFI_FONT_INFO
*) AllocateZeroPool (FontInfoSize
);
502 if (FontInfo
== NULL
) {
503 return EFI_OUT_OF_RESOURCES
;
505 FontInfo
->FontStyle
= FontStyle
;
506 FontInfo
->FontSize
= FontSize
;
507 CopyMem (FontInfo
->FontName
, BlockHdr
, StringSize
);
510 // If find the corresponding global font info, save the relationship.
511 // Otherwise ignore this EFI_HII_SIBT_FONT block.
513 if (IsFontInfoExisted (Private
, FontInfo
, NULL
, NULL
, &GlobalFont
)) {
514 ReferFontInfoLocally (Private
, StringPackage
, FontId
, TRUE
, GlobalFont
, &LocalFont
);
518 // Since string package tool set FontId initially to 0 and increases it
519 // progressively by one, StringPackage->FondId always represents an unique
520 // and available FontId.
522 StringPackage
->FontId
++;
527 BlockSize
+= Ext2
.Length
;
531 case EFI_HII_SIBT_EXT4
:
534 (UINT8
*)((UINTN
)BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
)),
538 BlockSize
+= Length32
;
545 if (StringId
> 0 && StringId
!= (EFI_STRING_ID
)(-1)) {
546 ASSERT (BlockType
!= NULL
&& StringBlockAddr
!= NULL
&& StringTextOffset
!= NULL
);
547 *BlockType
= *BlockHdr
;
548 *StringBlockAddr
= BlockHdr
;
549 *StringTextOffset
= Offset
;
551 if (StringId
== CurrentStringId
- 1) {
553 // if only one skip item, return EFI_NOT_FOUND.
555 if(*BlockType
== EFI_HII_SIBT_SKIP2
|| *BlockType
== EFI_HII_SIBT_SKIP1
) {
556 return EFI_NOT_FOUND
;
562 if (StringId
< CurrentStringId
- 1) {
563 return EFI_NOT_FOUND
;
566 BlockHdr
= StringPackage
->StringBlock
+ BlockSize
;
567 if (StartStringId
!= NULL
) {
568 *StartStringId
= CurrentStringId
;
573 // Get last string ID
575 if (StringId
== (EFI_STRING_ID
) (-1) && LastStringId
!= NULL
) {
576 *LastStringId
= (EFI_STRING_ID
) (CurrentStringId
- 1);
580 return EFI_NOT_FOUND
;
585 Parse all string blocks to get a string specified by StringId.
587 This is a internal function.
589 @param Private Hii database private structure.
590 @param StringPackage Hii string package instance.
591 @param StringId The string's id, which is unique within
593 @param String Points to retrieved null-terminated string.
594 @param StringSize On entry, points to the size of the buffer pointed
595 to by String, in bytes. On return, points to the
596 length of the string, in bytes.
597 @param StringFontInfo If not NULL, allocate a buffer to record the
598 output font info. It's caller's responsibility to
601 @retval EFI_SUCCESS The string text and font is retrieved
603 @retval EFI_NOT_FOUND The specified text or font info can not be found
605 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to
611 IN HII_DATABASE_PRIVATE_DATA
*Private
,
612 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
613 IN EFI_STRING_ID StringId
,
614 OUT EFI_STRING String
,
615 IN OUT UINTN
*StringSize
, OPTIONAL
616 OUT EFI_FONT_INFO
**StringFontInfo OPTIONAL
619 UINT8
*StringTextPtr
;
621 UINT8
*StringBlockAddr
;
622 UINTN StringTextOffset
;
626 ASSERT (StringPackage
!= NULL
);
627 ASSERT (Private
!= NULL
&& Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
630 // Find the specified string block
632 Status
= FindStringBlock (
642 if (EFI_ERROR (Status
)) {
646 if (StringSize
== NULL
) {
648 // String text buffer is not requested
654 // Get the string text.
656 StringTextPtr
= StringBlockAddr
+ StringTextOffset
;
658 case EFI_HII_SIBT_STRING_SCSU
:
659 case EFI_HII_SIBT_STRING_SCSU_FONT
:
660 case EFI_HII_SIBT_STRINGS_SCSU
:
661 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
662 Status
= ConvertToUnicodeText (String
, (CHAR8
*) StringTextPtr
, StringSize
);
664 case EFI_HII_SIBT_STRING_UCS2
:
665 case EFI_HII_SIBT_STRING_UCS2_FONT
:
666 case EFI_HII_SIBT_STRINGS_UCS2
:
667 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
668 Status
= GetUnicodeStringTextOrSize (String
, StringTextPtr
, StringSize
);
671 return EFI_NOT_FOUND
;
673 if (EFI_ERROR (Status
)) {
678 // Get the string font. The FontId 0 is the default font for those string blocks which
679 // do not specify a font identifier. If default font is not specified, return NULL.
681 if (StringFontInfo
!= NULL
) {
683 case EFI_HII_SIBT_STRING_SCSU_FONT
:
684 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
685 case EFI_HII_SIBT_STRING_UCS2_FONT
:
686 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
687 FontId
= *(StringBlockAddr
+ sizeof (EFI_HII_STRING_BLOCK
));
692 Status
= GetStringFontInfo (StringPackage
, FontId
, StringFontInfo
);
693 if (Status
== EFI_NOT_FOUND
) {
694 *StringFontInfo
= NULL
;
702 If GetStringBlock find the StringId's string is not saved in the exist string block,
703 this function will create the UCS2 string block to save the string; also split the
704 skip block into two or one skip block.
706 This is a internal function.
708 @param StringPackage Hii string package instance.
709 @param StartStringId The first id in the skip block which StringId in the block.
710 @param StringId The string's id, which is unique within
712 @param BlockType Output the block type of found string block.
713 @param StringBlockAddr Output the block address of found string block.
714 @param FontBlock whether this string block has font info.
716 @retval EFI_SUCCESS The string font is outputted successfully.
717 @retval EFI_OUT_OF_RESOURCES NO resource for the memory to save the new string block.
721 InsertLackStringBlock (
722 IN OUT HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
723 IN EFI_STRING_ID StartStringId
,
724 IN EFI_STRING_ID StringId
,
725 IN OUT UINT8
*BlockType
,
726 IN OUT UINT8
**StringBlockAddr
,
736 UINT32 NewUCSBlockLen
;
737 UINT8
*OldStringAddr
;
742 OldStringAddr
= *StringBlockAddr
;
744 ASSERT (*BlockType
== EFI_HII_SIBT_SKIP1
|| *BlockType
== EFI_HII_SIBT_SKIP2
);
746 // Old skip block size.
748 if (*BlockType
== EFI_HII_SIBT_SKIP1
) {
749 SkipLen
= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
750 IdCount
= *(UINT8
*)(OldStringAddr
+ sizeof (EFI_HII_STRING_BLOCK
));
752 SkipLen
= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
753 IdCount
= *(UINT16
*)(OldStringAddr
+ sizeof (EFI_HII_STRING_BLOCK
));
757 // New create UCS or UCS2 block size.
760 NewUCSBlockLen
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
);
762 NewUCSBlockLen
= sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
);
765 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
767 if (StartStringId
== StringId
) {
769 // New block + [Skip block]
772 NewBlockSize
= OldBlockSize
+ NewUCSBlockLen
;
774 NewBlockSize
= OldBlockSize
+ NewUCSBlockLen
- SkipLen
;
776 } else if (StartStringId
+ IdCount
- 1 == StringId
){
778 // Skip block + New block
780 NewBlockSize
= OldBlockSize
+ NewUCSBlockLen
;
781 FrontSkipNum
= StringId
- StartStringId
;
784 // Skip block + New block + [Skip block]
786 NewBlockSize
= OldBlockSize
+ NewUCSBlockLen
+ SkipLen
;
787 FrontSkipNum
= StringId
- StartStringId
;
790 StringBlock
= (UINT8
*) AllocateZeroPool (NewBlockSize
);
791 if (StringBlock
== NULL
) {
792 return EFI_OUT_OF_RESOURCES
;
796 // Copy old block in front of skip block.
798 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldStringAddr
- StringPackage
->StringBlock
);
799 BlockPtr
= StringBlock
+ (OldStringAddr
- StringPackage
->StringBlock
);
801 if (FrontSkipNum
> 0) {
802 *BlockPtr
= *BlockType
;
803 if (*BlockType
== EFI_HII_SIBT_SKIP1
) {
804 *(BlockPtr
+ sizeof (EFI_HII_STRING_BLOCK
)) = (UINT8
) FrontSkipNum
;
806 *(UINT16
*)(BlockPtr
+ sizeof (EFI_HII_STRING_BLOCK
)) = (UINT16
) FrontSkipNum
;
812 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
814 *StringBlockAddr
= BlockPtr
;
816 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2_FONT
;
818 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
820 BlockPtr
+= NewUCSBlockLen
;
822 if (IdCount
> FrontSkipNum
+ 1) {
823 *BlockPtr
= *BlockType
;
824 if (*BlockType
== EFI_HII_SIBT_SKIP1
) {
825 *(BlockPtr
+ sizeof (EFI_HII_STRING_BLOCK
)) = (UINT8
) (IdCount
- FrontSkipNum
- 1);
827 *(UINT16
*)(BlockPtr
+ sizeof (EFI_HII_STRING_BLOCK
)) = (UINT16
) (IdCount
- FrontSkipNum
- 1);
833 // Append a EFI_HII_SIBT_END block to the end.
835 CopyMem (BlockPtr
, OldStringAddr
+ SkipLen
, OldBlockSize
- (OldStringAddr
- StringPackage
->StringBlock
) - SkipLen
);
838 *BlockType
= EFI_HII_SIBT_STRING_UCS2_FONT
;
840 *BlockType
= EFI_HII_SIBT_STRING_UCS2
;
842 FreePool (StringPackage
->StringBlock
);
843 StringPackage
->StringBlock
= StringBlock
;
844 StringPackage
->StringPkgHdr
->Header
.Length
+= NewBlockSize
- OldBlockSize
;
850 Parse all string blocks to set a String specified by StringId.
852 This is a internal function.
854 @param Private HII database driver private structure.
855 @param StringPackage HII string package instance.
856 @param StringId The string's id, which is unique within
858 @param String Points to the new null-terminated string.
859 @param StringFontInfo Points to the input font info.
861 @retval EFI_SUCCESS The string was updated successfully.
862 @retval EFI_NOT_FOUND The string specified by StringId is not in the
864 @retval EFI_INVALID_PARAMETER The String or Language was NULL.
865 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
867 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
873 IN HII_DATABASE_PRIVATE_DATA
*Private
,
874 IN OUT HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
875 IN EFI_STRING_ID StringId
,
876 IN EFI_STRING String
,
877 IN EFI_FONT_INFO
*StringFontInfo OPTIONAL
880 UINT8
*StringTextPtr
;
882 UINT8
*StringBlockAddr
;
883 UINTN StringTextOffset
;
889 HII_FONT_INFO
*LocalFont
;
890 HII_GLOBAL_FONT_INFO
*GlobalFont
;
892 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
895 EFI_STRING_ID StartStringId
;
899 ASSERT (Private
!= NULL
&& StringPackage
!= NULL
&& String
!= NULL
);
900 ASSERT (Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
902 // Find the specified string block
904 Status
= FindStringBlock (
914 if (EFI_ERROR (Status
) && (BlockType
== EFI_HII_SIBT_SKIP1
|| BlockType
== EFI_HII_SIBT_SKIP2
)) {
915 Status
= InsertLackStringBlock(StringPackage
,
920 (BOOLEAN
)(StringFontInfo
!= NULL
)
922 if (EFI_ERROR (Status
)) {
925 if (StringFontInfo
!= NULL
) {
926 StringTextOffset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
928 StringTextOffset
= sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
) - sizeof (CHAR16
);
937 // The input StringFontInfo should exist in current database if specified.
939 if (StringFontInfo
!= NULL
) {
940 if (!IsFontInfoExisted (Private
, StringFontInfo
, NULL
, NULL
, &GlobalFont
)) {
941 return EFI_INVALID_PARAMETER
;
943 Referred
= ReferFontInfoLocally (
946 StringPackage
->FontId
,
952 StringPackage
->FontId
++;
956 // Update the FontId of the specified string block to input font info.
959 case EFI_HII_SIBT_STRING_SCSU_FONT
:
960 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
961 case EFI_HII_SIBT_STRING_UCS2_FONT
:
962 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
963 *(StringBlockAddr
+ sizeof (EFI_HII_STRING_BLOCK
)) = LocalFont
->FontId
;
967 // When modify the font info of these blocks, the block type should be updated
968 // to contain font info thus the whole structure should be revised.
969 // It is recommended to use tool to modify the block type not in the code.
971 return EFI_UNSUPPORTED
;
975 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
978 // Set the string text and font.
980 StringTextPtr
= StringBlockAddr
+ StringTextOffset
;
982 case EFI_HII_SIBT_STRING_SCSU
:
983 case EFI_HII_SIBT_STRING_SCSU_FONT
:
984 case EFI_HII_SIBT_STRINGS_SCSU
:
985 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
986 BlockSize
= OldBlockSize
+ StrLen (String
);
987 BlockSize
-= AsciiStrSize ((CHAR8
*) StringTextPtr
);
988 Block
= AllocateZeroPool (BlockSize
);
990 return EFI_OUT_OF_RESOURCES
;
993 CopyMem (Block
, StringPackage
->StringBlock
, StringTextPtr
- StringPackage
->StringBlock
);
994 BlockPtr
= Block
+ (StringTextPtr
- StringPackage
->StringBlock
);
996 while (*String
!= 0) {
997 *BlockPtr
++ = (CHAR8
) *String
++;
1002 TmpSize
= OldBlockSize
- (StringTextPtr
- StringPackage
->StringBlock
) - AsciiStrSize ((CHAR8
*) StringTextPtr
);
1005 StringTextPtr
+ AsciiStrSize ((CHAR8
*)StringTextPtr
),
1009 ZeroMem (StringPackage
->StringBlock
, OldBlockSize
);
1010 FreePool (StringPackage
->StringBlock
);
1011 StringPackage
->StringBlock
= Block
;
1012 StringPackage
->StringPkgHdr
->Header
.Length
+= (UINT32
) (BlockSize
- OldBlockSize
);
1015 case EFI_HII_SIBT_STRING_UCS2
:
1016 case EFI_HII_SIBT_STRING_UCS2_FONT
:
1017 case EFI_HII_SIBT_STRINGS_UCS2
:
1018 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
1020 // Use StrSize to store the size of the specified string, including the NULL
1023 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
1025 BlockSize
= OldBlockSize
+ StrSize (String
) - StringSize
;
1026 Block
= AllocateZeroPool (BlockSize
);
1027 if (Block
== NULL
) {
1028 return EFI_OUT_OF_RESOURCES
;
1031 CopyMem (Block
, StringPackage
->StringBlock
, StringTextPtr
- StringPackage
->StringBlock
);
1032 BlockPtr
= Block
+ (StringTextPtr
- StringPackage
->StringBlock
);
1034 CopyMem (BlockPtr
, String
, StrSize (String
));
1035 BlockPtr
+= StrSize (String
);
1039 StringTextPtr
+ StringSize
,
1040 OldBlockSize
- (StringTextPtr
- StringPackage
->StringBlock
) - StringSize
1043 ZeroMem (StringPackage
->StringBlock
, OldBlockSize
);
1044 FreePool (StringPackage
->StringBlock
);
1045 StringPackage
->StringBlock
= Block
;
1046 StringPackage
->StringPkgHdr
->Header
.Length
+= (UINT32
) (BlockSize
- OldBlockSize
);
1050 return EFI_NOT_FOUND
;
1054 // Insert a new EFI_HII_SIBT_FONT_BLOCK to the header of string block, if incoming
1055 // StringFontInfo does not exist in current string package.
1057 // This new block does not impact on the value of StringId.
1060 if (StringFontInfo
== NULL
|| Referred
) {
1064 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
1065 BlockSize
= OldBlockSize
+ sizeof (EFI_HII_SIBT_FONT_BLOCK
) - sizeof (CHAR16
) +
1066 StrSize (GlobalFont
->FontInfo
->FontName
);
1068 Block
= AllocateZeroPool (BlockSize
);
1069 if (Block
== NULL
) {
1070 return EFI_OUT_OF_RESOURCES
;
1074 Ext2
.Header
.BlockType
= EFI_HII_SIBT_EXT2
;
1075 Ext2
.BlockType2
= EFI_HII_SIBT_FONT
;
1076 Ext2
.Length
= (UINT16
) (BlockSize
- OldBlockSize
);
1077 CopyMem (BlockPtr
, &Ext2
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
1078 BlockPtr
+= sizeof (EFI_HII_SIBT_EXT2_BLOCK
);
1080 *BlockPtr
= LocalFont
->FontId
;
1082 CopyMem (BlockPtr
, &GlobalFont
->FontInfo
->FontSize
, sizeof (UINT16
));
1083 BlockPtr
+= sizeof (UINT16
);
1084 CopyMem (BlockPtr
, &GlobalFont
->FontInfo
->FontStyle
, sizeof (UINT32
));
1085 BlockPtr
+= sizeof (UINT32
);
1088 GlobalFont
->FontInfo
->FontName
,
1089 StrSize (GlobalFont
->FontInfo
->FontName
)
1091 BlockPtr
+= StrSize (GlobalFont
->FontInfo
->FontName
);
1093 CopyMem (BlockPtr
, StringPackage
->StringBlock
, OldBlockSize
);
1095 ZeroMem (StringPackage
->StringBlock
, OldBlockSize
);
1096 FreePool (StringPackage
->StringBlock
);
1097 StringPackage
->StringBlock
= Block
;
1098 StringPackage
->StringPkgHdr
->Header
.Length
+= Ext2
.Length
;
1106 This function adds the string String to the group of strings owned by PackageList, with the
1107 specified font information StringFontInfo and returns a new string id.
1108 The new string identifier is guaranteed to be unique within the package list.
1109 That new string identifier is reserved for all languages in the package list.
1112 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1113 @param PackageList Handle of the package list where this string will
1115 @param StringId On return, contains the new strings id, which is
1116 unique within PackageList.
1117 @param Language Points to the language for the new string.
1118 @param LanguageName Points to the printable language name to associate
1119 with the passed in Language field.If LanguageName
1120 is not NULL and the string package header's
1121 LanguageName associated with a given Language is
1122 not zero, the LanguageName being passed in will
1124 @param String Points to the new null-terminated string.
1125 @param StringFontInfo Points to the new string's font information or
1126 NULL if the string should have the default system
1127 font, size and style.
1129 @retval EFI_SUCCESS The new string was added successfully.
1130 @retval EFI_NOT_FOUND The specified PackageList could not be found in
1132 @retval EFI_OUT_OF_RESOURCES Could not add the string due to lack of resources.
1133 @retval EFI_INVALID_PARAMETER String is NULL or StringId is NULL or Language is
1135 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
1142 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1143 IN EFI_HII_HANDLE PackageList
,
1144 OUT EFI_STRING_ID
*StringId
,
1145 IN CONST CHAR8
*Language
,
1146 IN CONST CHAR16
*LanguageName
, OPTIONAL
1147 IN CONST EFI_STRING String
,
1148 IN CONST EFI_FONT_INFO
*StringFontInfo OPTIONAL
1153 HII_DATABASE_PRIVATE_DATA
*Private
;
1154 HII_DATABASE_RECORD
*DatabaseRecord
;
1155 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1156 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1159 UINT32 OldBlockSize
;
1162 UINT32 Ucs2BlockSize
;
1163 UINT32 FontBlockSize
;
1164 UINT32 Ucs2FontBlockSize
;
1165 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
1166 HII_FONT_INFO
*LocalFont
;
1167 HII_GLOBAL_FONT_INFO
*GlobalFont
;
1168 EFI_STRING_ID NewStringId
;
1169 EFI_STRING_ID NextStringId
;
1170 EFI_STRING_ID Index
;
1171 HII_STRING_PACKAGE_INSTANCE
*MatchStringPackage
;
1172 BOOLEAN NewStringPackageCreated
;
1175 if (This
== NULL
|| String
== NULL
|| StringId
== NULL
|| Language
== NULL
|| PackageList
== NULL
) {
1176 return EFI_INVALID_PARAMETER
;
1179 if (!IsHiiHandleValid (PackageList
)) {
1180 return EFI_NOT_FOUND
;
1183 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1187 // If StringFontInfo specify a paritcular font, it should exist in current database.
1189 if (StringFontInfo
!= NULL
) {
1190 if (!IsFontInfoExisted (Private
, (EFI_FONT_INFO
*) StringFontInfo
, NULL
, NULL
, &GlobalFont
)) {
1191 return EFI_INVALID_PARAMETER
;
1196 // Get the matching package list.
1198 PackageListNode
= NULL
;
1199 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1200 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1201 if (DatabaseRecord
->Handle
== PackageList
) {
1202 PackageListNode
= DatabaseRecord
->PackageList
;
1206 if (PackageListNode
== NULL
) {
1207 return EFI_NOT_FOUND
;
1210 EfiAcquireLock (&mHiiDatabaseLock
);
1212 Status
= EFI_SUCCESS
;
1213 NewStringPackageCreated
= FALSE
;
1216 StringPackage
= NULL
;
1217 MatchStringPackage
= NULL
;
1218 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1219 Link
!= &PackageListNode
->StringPkgHdr
;
1220 Link
= Link
->ForwardLink
1222 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1224 // Create a string block and corresponding font block if exists, then append them
1225 // to the end of the string package.
1227 Status
= FindStringBlock (
1237 if (EFI_ERROR (Status
)) {
1241 // Make sure that new StringId is same in all String Packages for the different language.
1243 if (NewStringId
!= 0 && NewStringId
!= NextStringId
) {
1245 Status
= EFI_INVALID_PARAMETER
;
1248 NewStringId
= NextStringId
;
1250 // Get the matched string package with language.
1252 if (HiiCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
)) {
1253 MatchStringPackage
= StringPackage
;
1255 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
1257 // Create a blank EFI_HII_SIBT_STRING_UCS2_BLOCK to reserve new string ID.
1259 Ucs2BlockSize
= (UINT32
) sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
);
1261 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ Ucs2BlockSize
);
1262 if (StringBlock
== NULL
) {
1263 Status
= EFI_OUT_OF_RESOURCES
;
1267 // Copy original string blocks, except the EFI_HII_SIBT_END.
1269 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1271 // Create a blank EFI_HII_SIBT_STRING_UCS2 block
1273 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1274 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
1275 BlockPtr
+= sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
);
1278 // Append a EFI_HII_SIBT_END block to the end.
1280 *BlockPtr
= EFI_HII_SIBT_END
;
1281 ZeroMem (StringPackage
->StringBlock
, OldBlockSize
);
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 ZeroMem (StringPackage
->StringBlock
, OldBlockSize
);
1414 FreePool (StringPackage
->StringBlock
);
1415 StringPackage
->StringBlock
= StringBlock
;
1416 StringPackage
->StringPkgHdr
->Header
.Length
+= Ucs2BlockSize
;
1417 PackageListNode
->PackageListHdr
.PackageLength
+= Ucs2BlockSize
;
1421 // StringFontInfo is specified here. If there is a EFI_HII_SIBT_FONT_BLOCK
1422 // which refers to this font info, create a EFI_HII_SIBT_STRING_UCS2_FONT block
1423 // only. Otherwise create a EFI_HII_SIBT_FONT block with a EFI_HII_SIBT_STRING
1424 // _UCS2_FONT block.
1426 Ucs2FontBlockSize
= (UINT32
) (StrSize (String
) + sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) -
1428 if (ReferFontInfoLocally (Private
, StringPackage
, StringPackage
->FontId
, FALSE
, GlobalFont
, &LocalFont
)) {
1430 // Create a EFI_HII_SIBT_STRING_UCS2_FONT block only.
1432 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ Ucs2FontBlockSize
);
1433 if (StringBlock
== NULL
) {
1434 Status
= EFI_OUT_OF_RESOURCES
;
1438 // Copy original string blocks, except the EFI_HII_SIBT_END.
1440 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1442 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
1444 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1445 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2_FONT
;
1446 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1447 *BlockPtr
= LocalFont
->FontId
;
1449 CopyMem (BlockPtr
, (EFI_STRING
) String
, StrSize ((EFI_STRING
) String
));
1450 BlockPtr
+= StrSize ((EFI_STRING
) String
);
1453 // Append a EFI_HII_SIBT_END block to the end.
1455 *BlockPtr
= EFI_HII_SIBT_END
;
1456 ZeroMem (StringPackage
->StringBlock
, OldBlockSize
);
1457 FreePool (StringPackage
->StringBlock
);
1458 StringPackage
->StringBlock
= StringBlock
;
1459 StringPackage
->StringPkgHdr
->Header
.Length
+= Ucs2FontBlockSize
;
1460 PackageListNode
->PackageListHdr
.PackageLength
+= Ucs2FontBlockSize
;
1464 // EFI_HII_SIBT_FONT_BLOCK does not exist in current string package, so
1465 // create a EFI_HII_SIBT_FONT block to record the font info, then generate
1466 // a EFI_HII_SIBT_STRING_UCS2_FONT block to record the incoming string.
1468 FontBlockSize
= (UINT32
) (StrSize (((EFI_FONT_INFO
*) StringFontInfo
)->FontName
) +
1469 sizeof (EFI_HII_SIBT_FONT_BLOCK
) - sizeof (CHAR16
));
1470 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ FontBlockSize
+ Ucs2FontBlockSize
);
1471 if (StringBlock
== NULL
) {
1472 Status
= EFI_OUT_OF_RESOURCES
;
1476 // Copy original string blocks, except the EFI_HII_SIBT_END.
1478 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1481 // Create a EFI_HII_SIBT_FONT block firstly and then backup its info in string
1482 // package instance for future reference.
1484 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1486 Ext2
.Header
.BlockType
= EFI_HII_SIBT_EXT2
;
1487 Ext2
.BlockType2
= EFI_HII_SIBT_FONT
;
1488 Ext2
.Length
= (UINT16
) FontBlockSize
;
1489 CopyMem (BlockPtr
, &Ext2
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
1490 BlockPtr
+= sizeof (EFI_HII_SIBT_EXT2_BLOCK
);
1492 *BlockPtr
= LocalFont
->FontId
;
1494 CopyMem (BlockPtr
, &((EFI_FONT_INFO
*) StringFontInfo
)->FontSize
, sizeof (UINT16
));
1495 BlockPtr
+= sizeof (UINT16
);
1496 CopyMem (BlockPtr
, &((EFI_FONT_INFO
*) StringFontInfo
)->FontStyle
, sizeof (EFI_HII_FONT_STYLE
));
1497 BlockPtr
+= sizeof (EFI_HII_FONT_STYLE
);
1500 &((EFI_FONT_INFO
*) StringFontInfo
)->FontName
,
1501 StrSize (((EFI_FONT_INFO
*) StringFontInfo
)->FontName
)
1503 BlockPtr
+= StrSize (((EFI_FONT_INFO
*) StringFontInfo
)->FontName
);
1505 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
1507 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2_FONT
;
1508 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1509 *BlockPtr
= LocalFont
->FontId
;
1511 CopyMem (BlockPtr
, (EFI_STRING
) String
, StrSize ((EFI_STRING
) String
));
1512 BlockPtr
+= StrSize ((EFI_STRING
) String
);
1515 // Append a EFI_HII_SIBT_END block to the end.
1517 *BlockPtr
= EFI_HII_SIBT_END
;
1518 ZeroMem (StringPackage
->StringBlock
, OldBlockSize
);
1519 FreePool (StringPackage
->StringBlock
);
1520 StringPackage
->StringBlock
= StringBlock
;
1521 StringPackage
->StringPkgHdr
->Header
.Length
+= FontBlockSize
+ Ucs2FontBlockSize
;
1522 PackageListNode
->PackageListHdr
.PackageLength
+= FontBlockSize
+ Ucs2FontBlockSize
;
1525 // Increase the FontId to make it unique since we already add
1526 // a EFI_HII_SIBT_FONT block to this string package.
1528 StringPackage
->FontId
++;
1533 if (!EFI_ERROR (Status
) && NewStringPackageCreated
) {
1535 // Trigger any registered notification function for new string package
1537 Status
= InvokeRegisteredFunction (
1539 EFI_HII_DATABASE_NOTIFY_NEW_PACK
,
1540 (VOID
*) StringPackage
,
1541 EFI_HII_PACKAGE_STRINGS
,
1546 if (!EFI_ERROR (Status
)) {
1548 // Update MaxString Id to new StringId
1550 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1551 Link
!= &PackageListNode
->StringPkgHdr
;
1552 Link
= Link
->ForwardLink
1554 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1555 StringPackage
->MaxStringId
= *StringId
;
1557 } else if (NewStringPackageCreated
) {
1559 // Free the allocated new string Package when new string can't be added.
1561 RemoveEntryList (&StringPackage
->StringEntry
);
1562 FreePool (StringPackage
->StringBlock
);
1563 FreePool (StringPackage
->StringPkgHdr
);
1564 FreePool (StringPackage
);
1567 // The contents of HiiDataBase may updated,need to check.
1570 // Check whether need to get the contents of HiiDataBase.
1571 // Only after ReadyToBoot to do the export.
1573 if (gExportAfterReadyToBoot
) {
1574 if (!EFI_ERROR (Status
)) {
1575 HiiGetDatabaseInfo(&Private
->HiiDatabase
);
1579 EfiReleaseLock (&mHiiDatabaseLock
);
1586 This function retrieves the string specified by StringId which is associated
1587 with the specified PackageList in the language Language and copies it into
1588 the buffer specified by String.
1590 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1591 @param Language Points to the language for the retrieved string.
1592 @param PackageList The package list in the HII database to search for
1593 the specified string.
1594 @param StringId The string's id, which is unique within
1596 @param String Points to the new null-terminated string.
1597 @param StringSize On entry, points to the size of the buffer pointed
1598 to by String, in bytes. On return, points to the
1599 length of the string, in bytes.
1600 @param StringFontInfo If not NULL, points to the string's font
1601 information. It's caller's responsibility to free
1604 @retval EFI_SUCCESS The string was returned successfully.
1605 @retval EFI_NOT_FOUND The string specified by StringId is not available.
1606 @retval EFI_NOT_FOUND The string specified by StringId is available but
1607 not in the specified language.
1608 The specified PackageList is not in the database.
1609 @retval EFI_INVALID_LANGUAGE - The string specified by StringId is available but
1610 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to
1612 @retval EFI_INVALID_PARAMETER The Language or StringSize was NULL.
1613 @retval EFI_INVALID_PARAMETER The value referenced by StringSize was not zero and String was NULL.
1614 @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the
1621 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1622 IN CONST CHAR8
*Language
,
1623 IN EFI_HII_HANDLE PackageList
,
1624 IN EFI_STRING_ID StringId
,
1625 OUT EFI_STRING String
,
1626 IN OUT UINTN
*StringSize
,
1627 OUT EFI_FONT_INFO
**StringFontInfo OPTIONAL
1632 HII_DATABASE_PRIVATE_DATA
*Private
;
1633 HII_DATABASE_RECORD
*DatabaseRecord
;
1634 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1635 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1637 if (This
== NULL
|| Language
== NULL
|| StringId
< 1 || StringSize
== NULL
|| PackageList
== NULL
) {
1638 return EFI_INVALID_PARAMETER
;
1641 if (String
== NULL
&& *StringSize
!= 0) {
1642 return EFI_INVALID_PARAMETER
;
1645 if (!IsHiiHandleValid (PackageList
)) {
1646 return EFI_NOT_FOUND
;
1649 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1650 PackageListNode
= NULL
;
1652 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1653 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1654 if (DatabaseRecord
->Handle
== PackageList
) {
1655 PackageListNode
= DatabaseRecord
->PackageList
;
1660 if (PackageListNode
!= NULL
) {
1662 // First search: to match the StringId in the specified language.
1664 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1665 Link
!= &PackageListNode
->StringPkgHdr
;
1666 Link
= Link
->ForwardLink
1668 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1669 if (HiiCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
)) {
1670 Status
= GetStringWorker (Private
, StringPackage
, StringId
, String
, StringSize
, StringFontInfo
);
1671 if (Status
!= EFI_NOT_FOUND
) {
1677 // Second search: to match the StringId in other available languages if exist.
1679 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1680 Link
!= &PackageListNode
->StringPkgHdr
;
1681 Link
= Link
->ForwardLink
1683 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1684 Status
= GetStringWorker (Private
, StringPackage
, StringId
, NULL
, NULL
, NULL
);
1685 if (!EFI_ERROR (Status
)) {
1686 return EFI_INVALID_LANGUAGE
;
1691 return EFI_NOT_FOUND
;
1697 This function updates the string specified by StringId in the specified PackageList to the text
1698 specified by String and, optionally, the font information specified by StringFontInfo.
1700 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1701 @param PackageList The package list containing the strings.
1702 @param StringId The string's id, which is unique within
1704 @param Language Points to the language for the updated string.
1705 @param String Points to the new null-terminated string.
1706 @param StringFontInfo Points to the string's font information or NULL if
1707 the string font information is not changed.
1709 @retval EFI_SUCCESS The string was updated successfully.
1710 @retval EFI_NOT_FOUND The string specified by StringId is not in the
1712 @retval EFI_INVALID_PARAMETER The String or Language was NULL.
1713 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
1715 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
1722 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1723 IN EFI_HII_HANDLE PackageList
,
1724 IN EFI_STRING_ID StringId
,
1725 IN CONST CHAR8
*Language
,
1726 IN CONST EFI_STRING String
,
1727 IN CONST EFI_FONT_INFO
*StringFontInfo OPTIONAL
1732 HII_DATABASE_PRIVATE_DATA
*Private
;
1733 HII_DATABASE_RECORD
*DatabaseRecord
;
1734 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1735 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1736 UINT32 OldPackageLen
;
1738 if (This
== NULL
|| Language
== NULL
|| StringId
< 1 || String
== NULL
|| PackageList
== NULL
) {
1739 return EFI_INVALID_PARAMETER
;
1742 if (!IsHiiHandleValid (PackageList
)) {
1743 return EFI_NOT_FOUND
;
1746 EfiAcquireLock (&mHiiDatabaseLock
);
1748 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1749 PackageListNode
= NULL
;
1751 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1752 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1753 if (DatabaseRecord
->Handle
== PackageList
) {
1754 PackageListNode
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*) (DatabaseRecord
->PackageList
);
1758 if (PackageListNode
!= NULL
) {
1759 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1760 Link
!= &PackageListNode
->StringPkgHdr
;
1761 Link
= Link
->ForwardLink
1763 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1764 if (HiiCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
)) {
1765 OldPackageLen
= StringPackage
->StringPkgHdr
->Header
.Length
;
1766 Status
= SetStringWorker (
1770 (EFI_STRING
) String
,
1771 (EFI_FONT_INFO
*) StringFontInfo
1773 if (EFI_ERROR (Status
)) {
1774 EfiReleaseLock (&mHiiDatabaseLock
);
1777 PackageListNode
->PackageListHdr
.PackageLength
+= StringPackage
->StringPkgHdr
->Header
.Length
- OldPackageLen
;
1779 // Check whether need to get the contents of HiiDataBase.
1780 // Only after ReadyToBoot to do the export.
1782 if (gExportAfterReadyToBoot
) {
1783 HiiGetDatabaseInfo(&Private
->HiiDatabase
);
1785 EfiReleaseLock (&mHiiDatabaseLock
);
1791 EfiReleaseLock (&mHiiDatabaseLock
);
1792 return EFI_NOT_FOUND
;
1798 This function returns the list of supported languages, in the format specified
1799 in Appendix M of UEFI 2.1 spec.
1801 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1802 @param PackageList The package list to examine.
1803 @param Languages Points to the buffer to hold the returned
1804 null-terminated ASCII string.
1805 @param LanguagesSize On entry, points to the size of the buffer pointed
1806 to by Languages, in bytes. On return, points to
1807 the length of Languages, in bytes.
1809 @retval EFI_SUCCESS The languages were returned successfully.
1810 @retval EFI_INVALID_PARAMETER The LanguagesSize was NULL.
1811 @retval EFI_INVALID_PARAMETER The value referenced by LanguagesSize is not zero and Languages is NULL.
1812 @retval EFI_BUFFER_TOO_SMALL The LanguagesSize is too small to hold the list of
1813 supported languages. LanguageSize is updated to
1814 contain the required size.
1815 @retval EFI_NOT_FOUND Could not find string package in specified
1822 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1823 IN EFI_HII_HANDLE PackageList
,
1824 IN OUT CHAR8
*Languages
,
1825 IN OUT UINTN
*LanguagesSize
1829 HII_DATABASE_PRIVATE_DATA
*Private
;
1830 HII_DATABASE_RECORD
*DatabaseRecord
;
1831 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1832 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1835 if (This
== NULL
|| LanguagesSize
== NULL
|| PackageList
== NULL
) {
1836 return EFI_INVALID_PARAMETER
;
1838 if (*LanguagesSize
!= 0 && Languages
== NULL
) {
1839 return EFI_INVALID_PARAMETER
;
1841 if (!IsHiiHandleValid (PackageList
)) {
1842 return EFI_NOT_FOUND
;
1845 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1847 PackageListNode
= NULL
;
1848 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1849 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1850 if (DatabaseRecord
->Handle
== PackageList
) {
1851 PackageListNode
= DatabaseRecord
->PackageList
;
1855 if (PackageListNode
== NULL
) {
1856 return EFI_NOT_FOUND
;
1860 // Search the languages in the specified packagelist.
1863 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1864 Link
!= &PackageListNode
->StringPkgHdr
;
1865 Link
= Link
->ForwardLink
1867 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1868 ResultSize
+= AsciiStrSize (StringPackage
->StringPkgHdr
->Language
);
1869 if (ResultSize
<= *LanguagesSize
) {
1870 AsciiStrCpyS (Languages
, *LanguagesSize
/ sizeof (CHAR8
), StringPackage
->StringPkgHdr
->Language
);
1871 Languages
+= AsciiStrSize (StringPackage
->StringPkgHdr
->Language
);
1872 *(Languages
- 1) = L
';';
1875 if (ResultSize
== 0) {
1876 return EFI_NOT_FOUND
;
1879 if (*LanguagesSize
< ResultSize
) {
1880 *LanguagesSize
= ResultSize
;
1881 return EFI_BUFFER_TOO_SMALL
;
1884 *(Languages
- 1) = 0;
1890 Each string package has associated with it a single primary language and zero
1891 or more secondary languages. This routine returns the secondary languages
1892 associated with a package list.
1894 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1895 @param PackageList The package list to examine.
1896 @param PrimaryLanguage Points to the null-terminated ASCII string that specifies
1897 the primary language. Languages are specified in the
1898 format specified in Appendix M of the UEFI 2.0 specification.
1899 @param SecondaryLanguages Points to the buffer to hold the returned null-terminated
1900 ASCII string that describes the list of
1901 secondary languages for the specified
1902 PrimaryLanguage. If there are no secondary
1903 languages, the function returns successfully, but
1904 this is set to NULL.
1905 @param SecondaryLanguagesSize On entry, points to the size of the buffer pointed
1906 to by SecondaryLanguages, in bytes. On return,
1907 points to the length of SecondaryLanguages in bytes.
1909 @retval EFI_SUCCESS Secondary languages were correctly returned.
1910 @retval EFI_INVALID_PARAMETER PrimaryLanguage or SecondaryLanguagesSize was NULL.
1911 @retval EFI_INVALID_PARAMETER The value referenced by SecondaryLanguagesSize is not
1912 zero and SecondaryLanguages is NULL.
1913 @retval EFI_BUFFER_TOO_SMALL The buffer specified by SecondaryLanguagesSize is
1914 too small to hold the returned information.
1915 SecondaryLanguageSize is updated to hold the size of
1916 the buffer required.
1917 @retval EFI_INVALID_LANGUAGE The language specified by PrimaryLanguage is not
1918 present in the specified package list.
1919 @retval EFI_NOT_FOUND The specified PackageList is not in the Database.
1924 HiiGetSecondaryLanguages (
1925 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1926 IN EFI_HII_HANDLE PackageList
,
1927 IN CONST CHAR8
*PrimaryLanguage
,
1928 IN OUT CHAR8
*SecondaryLanguages
,
1929 IN OUT UINTN
*SecondaryLanguagesSize
1934 HII_DATABASE_PRIVATE_DATA
*Private
;
1935 HII_DATABASE_RECORD
*DatabaseRecord
;
1936 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1937 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1941 if (This
== NULL
|| PackageList
== NULL
|| PrimaryLanguage
== NULL
|| SecondaryLanguagesSize
== NULL
) {
1942 return EFI_INVALID_PARAMETER
;
1944 if (SecondaryLanguages
== NULL
&& *SecondaryLanguagesSize
!= 0) {
1945 return EFI_INVALID_PARAMETER
;
1947 if (!IsHiiHandleValid (PackageList
)) {
1948 return EFI_NOT_FOUND
;
1951 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1953 PackageListNode
= NULL
;
1954 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1955 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1956 if (DatabaseRecord
->Handle
== PackageList
) {
1957 PackageListNode
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*) (DatabaseRecord
->PackageList
);
1961 if (PackageListNode
== NULL
) {
1962 return EFI_NOT_FOUND
;
1967 for (Link1
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1968 Link1
!= &PackageListNode
->StringPkgHdr
;
1969 Link1
= Link1
->ForwardLink
1971 StringPackage
= CR (Link1
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1972 if (HiiCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) PrimaryLanguage
)) {
1973 Languages
= StringPackage
->StringPkgHdr
->Language
;
1975 // Language is a series of ';' terminated strings, first one is primary
1976 // language and following with other secondary languages or NULL if no
1977 // secondary languages any more.
1979 Languages
= AsciiStrStr (Languages
, ";");
1980 if (Languages
== NULL
) {
1985 ResultSize
= AsciiStrSize (Languages
);
1986 if (ResultSize
<= *SecondaryLanguagesSize
) {
1987 AsciiStrCpyS (SecondaryLanguages
, *SecondaryLanguagesSize
/ sizeof (CHAR8
), Languages
);
1989 *SecondaryLanguagesSize
= ResultSize
;
1990 return EFI_BUFFER_TOO_SMALL
;
1997 return EFI_INVALID_LANGUAGE
;
2001 Converts the ascii character of the string from uppercase to lowercase.
2002 This is a internal function.
2004 @param ConfigString String to be converted
2010 IN CHAR8
*ConfigString
2013 ASSERT (ConfigString
!= NULL
);
2016 // Convert all hex digits in range [A-F] in the configuration header to [a-f]
2018 for (; *ConfigString
!= '\0'; ConfigString
++) {
2019 if ( *ConfigString
>= 'A' && *ConfigString
<= 'Z') {
2020 *ConfigString
= (CHAR8
) (*ConfigString
- 'A' + 'a');
2026 Compare whether two names of languages are identical.
2028 @param Language1 Name of language 1 from StringPackage
2029 @param Language2 Name of language 2 to be compared with language 1.
2032 @retval FALSE not same
2036 HiiCompareLanguage (
2037 IN CHAR8
*Language1
,
2047 // Convert to lower to compare.
2049 StrLen
= AsciiStrSize (Language1
);
2050 Lan1
= AllocateZeroPool (StrLen
);
2051 ASSERT (Lan1
!= NULL
);
2052 AsciiStrCpyS(Lan1
, StrLen
/ sizeof (CHAR8
), Language1
);
2053 AsciiHiiToLower (Lan1
);
2055 StrLen
= AsciiStrSize (Language2
);
2056 Lan2
= AllocateZeroPool (StrLen
);
2057 ASSERT (Lan2
!= NULL
);
2058 AsciiStrCpyS(Lan2
, StrLen
/ sizeof (CHAR8
), Language2
);
2059 AsciiHiiToLower (Lan2
);
2062 // Compare the Primary Language in Language1 to Language2
2064 for (Index
= 0; Lan1
[Index
] != 0 && Lan1
[Index
] != ';'; Index
++) {
2065 if (Lan1
[Index
] != Lan2
[Index
]) {
2067 // Return FALSE if any characters are different.
2079 // Only return TRUE if Language2[Index] is a Null-terminator which means
2080 // the Primary Language in Language1 is the same length as Language2. If
2081 // Language2[Index] is not a Null-terminator, then Language2 is longer than
2082 // the Primary Language in Language1, and FALSE must be returned.
2084 return (BOOLEAN
) (Language2
[Index
] == 0);