2 Implementation for EFI_HII_STRING_PROTOCOL.
5 Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "HiiDatabase.h"
19 CHAR16 mLanguageWindow
[16] = {
20 0x0000, 0x0080, 0x0100, 0x0300,
21 0x2000, 0x2080, 0x2100, 0x3000,
22 0x0080, 0x00C0, 0x0400, 0x0600,
23 0x0900, 0x3040, 0x30A0, 0xFF00
28 This function checks whether a global font info is referred by local
29 font info list or not. (i.e. HII_FONT_INFO is generated.) If not, create
30 a HII_FONT_INFO to refer it locally.
32 This is a internal function.
35 @param Private Hii database private structure.
36 @param StringPackage HII string package instance.
37 @param FontId Font identifer, which must be unique within the string package.
38 @param DuplicateEnable If true, duplicate HII_FONT_INFO which refers to
39 the same EFI_FONT_INFO is permitted. Otherwise it
41 @param GlobalFontInfo Input a global font info which specify a
43 @param LocalFontInfo Output a local font info which refers to a
46 @retval TRUE Already referred before calling this function.
47 @retval FALSE Not referred before calling this function.
51 ReferFontInfoLocally (
52 IN HII_DATABASE_PRIVATE_DATA
*Private
,
53 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
55 IN BOOLEAN DuplicateEnable
,
56 IN HII_GLOBAL_FONT_INFO
*GlobalFontInfo
,
57 OUT HII_FONT_INFO
**LocalFontInfo
60 HII_FONT_INFO
*LocalFont
;
63 ASSERT (Private
!= NULL
&& StringPackage
!= NULL
&& GlobalFontInfo
!= NULL
&& LocalFontInfo
!= NULL
);
65 if (!DuplicateEnable
) {
66 for (Link
= StringPackage
->FontInfoList
.ForwardLink
;
67 Link
!= &StringPackage
->FontInfoList
;
68 Link
= Link
->ForwardLink
70 LocalFont
= CR (Link
, HII_FONT_INFO
, Entry
, HII_FONT_INFO_SIGNATURE
);
71 if (LocalFont
->GlobalEntry
== &GlobalFontInfo
->Entry
) {
73 // Already referred by local font info list, return directly.
75 *LocalFontInfo
= LocalFont
;
80 // FontId identifies EFI_FONT_INFO in local string package uniquely.
81 // GlobalEntry points to a HII_GLOBAL_FONT_INFO which identifies
82 // EFI_FONT_INFO uniquely in whole hii database.
84 LocalFont
= (HII_FONT_INFO
*) AllocateZeroPool (sizeof (HII_FONT_INFO
));
85 ASSERT (LocalFont
!= NULL
);
87 LocalFont
->Signature
= HII_FONT_INFO_SIGNATURE
;
88 LocalFont
->FontId
= FontId
;
89 LocalFont
->GlobalEntry
= &GlobalFontInfo
->Entry
;
90 InsertTailList (&StringPackage
->FontInfoList
, &LocalFont
->Entry
);
92 *LocalFontInfo
= LocalFont
;
98 Convert Ascii string text to unicode string test.
100 This is a internal function.
103 @param StringDest Buffer to store the string text. If it is NULL,
104 only the size will be returned.
105 @param StringSrc Points to current null-terminated string.
106 @param BufferSize Length of the buffer.
108 @retval EFI_SUCCESS The string text was outputed successfully.
109 @retval EFI_BUFFER_TOO_SMALL Buffer is insufficient to store the found string
110 text. BufferSize is updated to the required buffer
115 ConvertToUnicodeText (
116 OUT EFI_STRING StringDest
,
118 IN OUT UINTN
*BufferSize
124 ASSERT (StringSrc
!= NULL
&& BufferSize
!= NULL
);
126 StringSize
= AsciiStrSize (StringSrc
) * 2;
127 if (*BufferSize
< StringSize
|| StringDest
== NULL
) {
128 *BufferSize
= StringSize
;
129 return EFI_BUFFER_TOO_SMALL
;
132 for (Index
= 0; Index
< AsciiStrLen (StringSrc
); Index
++) {
133 StringDest
[Index
] = (CHAR16
) StringSrc
[Index
];
136 StringDest
[Index
] = 0;
142 Calculate the size of StringSrc and output it. If StringDest is not NULL,
143 copy string text from src to dest.
145 This is a internal function.
147 @param StringDest Buffer to store the string text. If it is NULL,
148 only the size will be returned.
149 @param StringSrc Points to current null-terminated string.
150 @param BufferSize Length of the buffer.
152 @retval EFI_SUCCESS The string text was outputed successfully.
153 @retval EFI_BUFFER_TOO_SMALL Buffer is insufficient to store the found string
154 text. BufferSize is updated to the required buffer
159 GetUnicodeStringTextOrSize (
160 OUT EFI_STRING StringDest
, OPTIONAL
162 IN OUT UINTN
*BufferSize
168 ASSERT (StringSrc
!= NULL
&& BufferSize
!= NULL
);
170 StringSize
= sizeof (CHAR16
);
171 StringPtr
= StringSrc
;
172 while (ReadUnaligned16 ((UINT16
*) StringPtr
) != 0) {
173 StringSize
+= sizeof (CHAR16
);
174 StringPtr
+= sizeof (CHAR16
);
177 if (*BufferSize
< StringSize
) {
178 *BufferSize
= StringSize
;
179 return EFI_BUFFER_TOO_SMALL
;
181 if (StringDest
!= NULL
) {
182 CopyMem (StringDest
, StringSrc
, StringSize
);
185 *BufferSize
= StringSize
;
191 Copy string font info to a buffer.
193 This is a internal function.
195 @param StringPackage Hii string package instance.
196 @param FontId Font identifier which is unique in a string
198 @param StringFontInfo Buffer to record the output font info. It's
199 caller's responsibility to free this buffer.
201 @retval EFI_SUCCESS The string font is outputed successfully.
202 @retval EFI_NOT_FOUND The specified font id does not exist.
207 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
209 OUT EFI_FONT_INFO
**StringFontInfo
213 HII_FONT_INFO
*FontInfo
;
214 HII_GLOBAL_FONT_INFO
*GlobalFont
;
216 ASSERT (StringFontInfo
!= NULL
&& StringPackage
!= NULL
);
218 for (Link
= StringPackage
->FontInfoList
.ForwardLink
; Link
!= &StringPackage
->FontInfoList
; Link
= Link
->ForwardLink
) {
219 FontInfo
= CR (Link
, HII_FONT_INFO
, Entry
, HII_FONT_INFO_SIGNATURE
);
220 if (FontInfo
->FontId
== FontId
) {
221 GlobalFont
= CR (FontInfo
->GlobalEntry
, HII_GLOBAL_FONT_INFO
, Entry
, HII_GLOBAL_FONT_INFO_SIGNATURE
);
222 *StringFontInfo
= (EFI_FONT_INFO
*) AllocateZeroPool (GlobalFont
->FontInfoSize
);
223 if (*StringFontInfo
== NULL
) {
224 return EFI_OUT_OF_RESOURCES
;
226 CopyMem (*StringFontInfo
, GlobalFont
->FontInfo
, GlobalFont
->FontInfoSize
);
231 return EFI_NOT_FOUND
;
236 Parse all string blocks to find a String block specified by StringId.
237 If StringId = (EFI_STRING_ID) (-1), find out all EFI_HII_SIBT_FONT blocks
238 within this string package and backup its information. If LastStringId is
239 specified, the string id of last string block will also be output.
240 If StringId = 0, output the string id of last string block (EFI_HII_SIBT_STRING).
242 @param Private Hii database private structure.
243 @param StringPackage Hii string package instance.
244 @param StringId The string's id, which is unique within
246 @param BlockType Output the block type of found string block.
247 @param StringBlockAddr Output the block address of found string block.
248 @param StringTextOffset Offset, relative to the found block address, of
249 the string text information.
250 @param LastStringId Output the last string id when StringId = 0 or StringId = -1.
252 @retval EFI_SUCCESS The string text and font is retrieved
254 @retval EFI_NOT_FOUND The specified text or font info can not be found
256 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
262 IN HII_DATABASE_PRIVATE_DATA
*Private
,
263 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
264 IN EFI_STRING_ID StringId
,
265 OUT UINT8
*BlockType
, OPTIONAL
266 OUT UINT8
**StringBlockAddr
, OPTIONAL
267 OUT UINTN
*StringTextOffset
, OPTIONAL
268 OUT EFI_STRING_ID
*LastStringId OPTIONAL
272 EFI_STRING_ID CurrentStringId
;
275 UINT8
*StringTextPtr
;
277 HII_FONT_INFO
*LocalFont
;
278 EFI_FONT_INFO
*FontInfo
;
279 HII_GLOBAL_FONT_INFO
*GlobalFont
;
283 EFI_HII_FONT_STYLE FontStyle
;
286 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
292 ASSERT (StringPackage
!= NULL
);
293 ASSERT (StringPackage
->Signature
== HII_STRING_PACKAGE_SIGNATURE
);
297 if (StringId
!= (EFI_STRING_ID
) (-1) && StringId
!= 0) {
298 ASSERT (BlockType
!= NULL
&& StringBlockAddr
!= NULL
&& StringTextOffset
!= NULL
);
299 if (StringId
> StringPackage
->MaxStringId
) {
300 return EFI_NOT_FOUND
;
303 ASSERT (Private
!= NULL
&& Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
304 if (StringId
== 0 && LastStringId
!= NULL
) {
305 *LastStringId
= StringPackage
->MaxStringId
;
310 ZeroMem (&Zero
, sizeof (CHAR16
));
313 // Parse the string blocks to get the string text and font.
315 BlockHdr
= StringPackage
->StringBlock
;
318 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
320 case EFI_HII_SIBT_STRING_SCSU
:
321 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
322 StringTextPtr
= BlockHdr
+ Offset
;
323 BlockSize
+= Offset
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
327 case EFI_HII_SIBT_STRING_SCSU_FONT
:
328 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
329 StringTextPtr
= BlockHdr
+ Offset
;
330 BlockSize
+= Offset
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
334 case EFI_HII_SIBT_STRINGS_SCSU
:
335 CopyMem (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
336 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
);
337 BlockSize
+= StringTextPtr
- BlockHdr
;
339 for (Index
= 0; Index
< StringCount
; Index
++) {
340 BlockSize
+= AsciiStrSize ((CHAR8
*) StringTextPtr
);
341 if (CurrentStringId
== StringId
) {
342 *BlockType
= *BlockHdr
;
343 *StringBlockAddr
= BlockHdr
;
344 *StringTextOffset
= StringTextPtr
- BlockHdr
;
347 StringTextPtr
= StringTextPtr
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
352 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
355 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
358 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
359 BlockSize
+= StringTextPtr
- BlockHdr
;
361 for (Index
= 0; Index
< StringCount
; Index
++) {
362 BlockSize
+= AsciiStrSize ((CHAR8
*) StringTextPtr
);
363 if (CurrentStringId
== StringId
) {
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 *BlockType
= *BlockHdr
;
408 *StringBlockAddr
= BlockHdr
;
409 *StringTextOffset
= StringTextPtr
- BlockHdr
;
412 StringTextPtr
= StringTextPtr
+ StringSize
;
417 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
418 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
419 StringTextPtr
= BlockHdr
+ Offset
;
423 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
426 for (Index
= 0; Index
< StringCount
; Index
++) {
427 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
428 BlockSize
+= StringSize
;
429 if (CurrentStringId
== StringId
) {
430 *BlockType
= *BlockHdr
;
431 *StringBlockAddr
= BlockHdr
;
432 *StringTextOffset
= StringTextPtr
- BlockHdr
;
435 StringTextPtr
= StringTextPtr
+ StringSize
;
440 case EFI_HII_SIBT_DUPLICATE
:
441 if (CurrentStringId
== StringId
) {
443 // Incoming StringId is an id of a duplicate string block.
444 // Update the StringId to be the previous string block.
445 // Go back to the header of string block to search.
449 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
450 sizeof (EFI_STRING_ID
)
452 ASSERT (StringId
!= CurrentStringId
);
456 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
461 case EFI_HII_SIBT_SKIP1
:
462 SkipCount
= (UINT16
) (*(BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
463 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
464 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
467 case EFI_HII_SIBT_SKIP2
:
468 CopyMem (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
469 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
470 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
473 case EFI_HII_SIBT_EXT1
:
476 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
479 BlockSize
+= Length8
;
482 case EFI_HII_SIBT_EXT2
:
483 CopyMem (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
484 if (Ext2
.BlockType2
== EFI_HII_SIBT_FONT
&& StringId
== (EFI_STRING_ID
) (-1)) {
486 // Find the relationship between global font info and the font info of
487 // this EFI_HII_SIBT_FONT block then backup its information in local package.
489 BlockHdr
+= sizeof (EFI_HII_SIBT_EXT2_BLOCK
);
490 CopyMem (&FontId
, BlockHdr
, sizeof (UINT8
));
491 BlockHdr
+= sizeof (UINT8
);
492 CopyMem (&FontSize
, BlockHdr
, sizeof (UINT16
));
493 BlockHdr
+= sizeof (UINT16
);
494 CopyMem (&FontStyle
, BlockHdr
, sizeof (EFI_HII_FONT_STYLE
));
495 BlockHdr
+= sizeof (EFI_HII_FONT_STYLE
);
496 GetUnicodeStringTextOrSize (NULL
, BlockHdr
, &StringSize
);
498 FontInfoSize
= sizeof (EFI_FONT_INFO
) - sizeof (CHAR16
) + StringSize
;
499 FontInfo
= (EFI_FONT_INFO
*) AllocateZeroPool (FontInfoSize
);
500 if (FontInfo
== NULL
) {
501 return EFI_OUT_OF_RESOURCES
;
503 FontInfo
->FontStyle
= FontStyle
;
504 FontInfo
->FontSize
= FontSize
;
505 CopyMem (FontInfo
->FontName
, BlockHdr
, StringSize
);
508 // If find the corresponding global font info, save the relationship.
509 // Otherwise ignore this EFI_HII_SIBT_FONT block.
511 if (IsFontInfoExisted (Private
, FontInfo
, NULL
, NULL
, &GlobalFont
)) {
512 ReferFontInfoLocally (Private
, StringPackage
, FontId
, TRUE
, GlobalFont
, &LocalFont
);
516 // Since string package tool set FontId initially to 0 and increases it
517 // progressively by one, StringPackage->FondId always represents an unique
518 // and available FontId.
520 StringPackage
->FontId
++;
525 BlockSize
+= Ext2
.Length
;
529 case EFI_HII_SIBT_EXT4
:
532 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
536 BlockSize
+= Length32
;
544 if (StringId
== CurrentStringId
- 1) {
545 *BlockType
= *BlockHdr
;
546 *StringBlockAddr
= BlockHdr
;
547 *StringTextOffset
= Offset
;
551 if (StringId
< CurrentStringId
- 1) {
552 return EFI_NOT_FOUND
;
555 BlockHdr
= StringPackage
->StringBlock
+ BlockSize
;
560 // Get last string ID
562 if (StringId
== (EFI_STRING_ID
) (-1)) {
563 *LastStringId
= (EFI_STRING_ID
) (CurrentStringId
- 1);
567 return EFI_NOT_FOUND
;
572 Parse all string blocks to get a string specified by StringId.
574 This is a internal function.
576 @param Private Hii database private structure.
577 @param StringPackage Hii string package instance.
578 @param StringId The string's id, which is unique within
580 @param String Points to retrieved null-terminated string.
581 @param StringSize On entry, points to the size of the buffer pointed
582 to by String, in bytes. On return, points to the
583 length of the string, in bytes.
584 @param StringFontInfo If not NULL, allocate a buffer to record the
585 output font info. It's caller's responsibility to
588 @retval EFI_SUCCESS The string text and font is retrieved
590 @retval EFI_NOT_FOUND The specified text or font info can not be found
592 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to
598 IN HII_DATABASE_PRIVATE_DATA
*Private
,
599 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
600 IN EFI_STRING_ID StringId
,
601 OUT EFI_STRING String
,
602 IN OUT UINTN
*StringSize
, OPTIONAL
603 OUT EFI_FONT_INFO
**StringFontInfo OPTIONAL
606 UINT8
*StringTextPtr
;
608 UINT8
*StringBlockAddr
;
609 UINTN StringTextOffset
;
613 ASSERT (StringPackage
!= NULL
);
614 ASSERT (Private
!= NULL
&& Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
617 // Find the specified string block
619 Status
= FindStringBlock (
628 if (EFI_ERROR (Status
)) {
632 if (StringSize
== NULL
) {
634 // String text buffer is not requested
640 // Get the string text.
642 StringTextPtr
= StringBlockAddr
+ StringTextOffset
;
644 case EFI_HII_SIBT_STRING_SCSU
:
645 case EFI_HII_SIBT_STRING_SCSU_FONT
:
646 case EFI_HII_SIBT_STRINGS_SCSU
:
647 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
648 Status
= ConvertToUnicodeText (String
, (CHAR8
*) StringTextPtr
, StringSize
);
650 case EFI_HII_SIBT_STRING_UCS2
:
651 case EFI_HII_SIBT_STRING_UCS2_FONT
:
652 case EFI_HII_SIBT_STRINGS_UCS2
:
653 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
654 Status
= GetUnicodeStringTextOrSize (String
, StringTextPtr
, StringSize
);
657 return EFI_NOT_FOUND
;
659 if (EFI_ERROR (Status
)) {
664 // Get the string font. The FontId 0 is the default font for those string blocks which
665 // do not specify a font identifier. If default font is not specified, return NULL.
667 if (StringFontInfo
!= NULL
) {
669 case EFI_HII_SIBT_STRING_SCSU_FONT
:
670 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
671 case EFI_HII_SIBT_STRING_UCS2_FONT
:
672 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
673 FontId
= *(StringBlockAddr
+ sizeof (EFI_HII_STRING_BLOCK
));
678 Status
= GetStringFontInfo (StringPackage
, FontId
, StringFontInfo
);
679 if (Status
== EFI_NOT_FOUND
) {
680 *StringFontInfo
= NULL
;
689 Parse all string blocks to set a String specified by StringId.
691 This is a internal function.
693 @param Private HII database driver private structure.
694 @param StringPackage HII string package instance.
695 @param StringId The string's id, which is unique within
697 @param String Points to the new null-terminated string.
698 @param StringFontInfo Points to the input font info.
700 @retval EFI_SUCCESS The string was updated successfully.
701 @retval EFI_NOT_FOUND The string specified by StringId is not in the
703 @retval EFI_INVALID_PARAMETER The String or Language was NULL.
704 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
706 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
712 IN HII_DATABASE_PRIVATE_DATA
*Private
,
713 IN OUT HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
714 IN EFI_STRING_ID StringId
,
715 IN EFI_STRING String
,
716 IN EFI_FONT_INFO
*StringFontInfo OPTIONAL
719 UINT8
*StringTextPtr
;
721 UINT8
*StringBlockAddr
;
722 UINTN StringTextOffset
;
728 HII_FONT_INFO
*LocalFont
;
729 HII_GLOBAL_FONT_INFO
*GlobalFont
;
731 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
736 ASSERT (Private
!= NULL
&& StringPackage
!= NULL
&& String
!= NULL
);
737 ASSERT (Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
739 // Find the specified string block
741 Status
= FindStringBlock (
750 if (EFI_ERROR (Status
)) {
759 // The input StringFontInfo should exist in current database if specified.
761 if (StringFontInfo
!= NULL
) {
762 if (!IsFontInfoExisted (Private
, StringFontInfo
, NULL
, NULL
, &GlobalFont
)) {
763 return EFI_INVALID_PARAMETER
;
765 Referred
= ReferFontInfoLocally (
768 StringPackage
->FontId
,
774 StringPackage
->FontId
++;
778 // Update the FontId of the specified string block to input font info.
781 case EFI_HII_SIBT_STRING_SCSU_FONT
:
782 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
783 case EFI_HII_SIBT_STRING_UCS2_FONT
:
784 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
785 *(StringBlockAddr
+ sizeof (EFI_HII_STRING_BLOCK
)) = LocalFont
->FontId
;
789 // When modify the font info of these blocks, the block type should be updated
790 // to contain font info thus the whole structure should be revised.
791 // It is recommended to use tool to modify the block type not in the code.
793 return EFI_UNSUPPORTED
;
797 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
800 // Set the string text and font.
802 StringTextPtr
= StringBlockAddr
+ StringTextOffset
;
804 case EFI_HII_SIBT_STRING_SCSU
:
805 case EFI_HII_SIBT_STRING_SCSU_FONT
:
806 case EFI_HII_SIBT_STRINGS_SCSU
:
807 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
808 BlockSize
= OldBlockSize
+ StrLen (String
);
809 BlockSize
-= AsciiStrLen ((CHAR8
*) StringTextPtr
);
810 Block
= AllocateZeroPool (BlockSize
);
812 return EFI_OUT_OF_RESOURCES
;
815 CopyMem (Block
, StringPackage
->StringBlock
, StringTextPtr
- StringPackage
->StringBlock
);
816 BlockPtr
= Block
+ (StringTextPtr
- StringPackage
->StringBlock
);
818 while (*String
!= 0) {
819 *BlockPtr
++ = (CHAR8
) *String
++;
824 TmpSize
= OldBlockSize
- (StringTextPtr
- StringPackage
->StringBlock
) - AsciiStrSize ((CHAR8
*) StringTextPtr
);
827 StringTextPtr
+ AsciiStrSize ((CHAR8
*)StringTextPtr
),
831 FreePool (StringPackage
->StringBlock
);
832 StringPackage
->StringBlock
= Block
;
833 StringPackage
->StringPkgHdr
->Header
.Length
+= (UINT32
) (BlockSize
- OldBlockSize
);
836 case EFI_HII_SIBT_STRING_UCS2
:
837 case EFI_HII_SIBT_STRING_UCS2_FONT
:
838 case EFI_HII_SIBT_STRINGS_UCS2
:
839 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
841 // Use StrSize to store the size of the specified string, including the NULL
844 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
846 BlockSize
= OldBlockSize
+ StrSize (String
) - StringSize
;
847 Block
= AllocateZeroPool (BlockSize
);
849 return EFI_OUT_OF_RESOURCES
;
852 CopyMem (Block
, StringPackage
->StringBlock
, StringTextPtr
- StringPackage
->StringBlock
);
853 BlockPtr
= Block
+ (StringTextPtr
- StringPackage
->StringBlock
);
855 CopyMem (BlockPtr
, String
, StrSize (String
));
856 BlockPtr
+= StrSize (String
);
860 StringTextPtr
+ StringSize
,
861 OldBlockSize
- (StringTextPtr
- StringPackage
->StringBlock
) - StringSize
864 FreePool (StringPackage
->StringBlock
);
865 StringPackage
->StringBlock
= Block
;
866 StringPackage
->StringPkgHdr
->Header
.Length
+= (UINT32
) (BlockSize
- OldBlockSize
);
870 return EFI_NOT_FOUND
;
874 // Insert a new EFI_HII_SIBT_FONT_BLOCK to the header of string block, if incoming
875 // StringFontInfo does not exist in current string package.
877 // This new block does not impact on the value of StringId.
880 if (StringFontInfo
== NULL
|| Referred
) {
884 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
885 BlockSize
= OldBlockSize
+ sizeof (EFI_HII_SIBT_FONT_BLOCK
) - sizeof (CHAR16
) +
886 StrSize (GlobalFont
->FontInfo
->FontName
);
888 Block
= AllocateZeroPool (BlockSize
);
890 return EFI_OUT_OF_RESOURCES
;
894 Ext2
.Header
.BlockType
= EFI_HII_SIBT_EXT2
;
895 Ext2
.BlockType2
= EFI_HII_SIBT_FONT
;
896 Ext2
.Length
= (UINT16
) (BlockSize
- OldBlockSize
);
897 CopyMem (BlockPtr
, &Ext2
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
898 BlockPtr
+= sizeof (EFI_HII_SIBT_EXT2_BLOCK
);
900 *BlockPtr
= LocalFont
->FontId
;
901 BlockPtr
+= sizeof (UINT8
);
902 CopyMem (BlockPtr
, &GlobalFont
->FontInfo
->FontSize
, sizeof (UINT16
));
903 BlockPtr
+= sizeof (UINT16
);
904 CopyMem (BlockPtr
, &GlobalFont
->FontInfo
->FontStyle
, sizeof (UINT32
));
905 BlockPtr
+= sizeof (UINT32
);
908 GlobalFont
->FontInfo
->FontName
,
909 StrSize (GlobalFont
->FontInfo
->FontName
)
911 BlockPtr
+= StrSize (GlobalFont
->FontInfo
->FontName
);
913 CopyMem (BlockPtr
, StringPackage
->StringBlock
, OldBlockSize
);
915 FreePool (StringPackage
->StringBlock
);
916 StringPackage
->StringBlock
= Block
;
917 StringPackage
->StringPkgHdr
->Header
.Length
+= Ext2
.Length
;
925 This function adds the string String to the group of strings owned by PackageList, with the
926 specified font information StringFontInfo and returns a new string id.
927 The new string identifier is guaranteed to be unique within the package list.
928 That new string identifier is reserved for all languages in the package list.
931 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
932 @param PackageList Handle of the package list where this string will
934 @param StringId On return, contains the new strings id, which is
935 unique within PackageList.
936 @param Language Points to the language for the new string.
937 @param LanguageName Points to the printable language name to associate
938 with the passed in Language field.If LanguageName
939 is not NULL and the string package header's
940 LanguageName associated with a given Language is
941 not zero, the LanguageName being passed in will
943 @param String Points to the new null-terminated string.
944 @param StringFontInfo Points to the new string's font information or
945 NULL if the string should have the default system
946 font, size and style.
948 @retval EFI_SUCCESS The new string was added successfully.
949 @retval EFI_NOT_FOUND The specified PackageList could not be found in
951 @retval EFI_OUT_OF_RESOURCES Could not add the string due to lack of resources.
952 @retval EFI_INVALID_PARAMETER String is NULL or StringId is NULL or Language is
954 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
961 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
962 IN EFI_HII_HANDLE PackageList
,
963 OUT EFI_STRING_ID
*StringId
,
964 IN CONST CHAR8
*Language
,
965 IN CONST CHAR16
*LanguageName
, OPTIONAL
966 IN CONST EFI_STRING String
,
967 IN CONST EFI_FONT_INFO
*StringFontInfo OPTIONAL
972 HII_DATABASE_PRIVATE_DATA
*Private
;
973 HII_DATABASE_RECORD
*DatabaseRecord
;
974 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
975 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
981 UINT32 Ucs2BlockSize
;
982 UINT32 FontBlockSize
;
983 UINT32 Ucs2FontBlockSize
;
984 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
985 HII_FONT_INFO
*LocalFont
;
986 HII_GLOBAL_FONT_INFO
*GlobalFont
;
987 EFI_STRING_ID NewStringId
;
988 EFI_STRING_ID NextStringId
;
990 HII_STRING_PACKAGE_INSTANCE
*MatchStringPackage
;
991 BOOLEAN NewStringPackageCreated
;
994 if (This
== NULL
|| String
== NULL
|| StringId
== NULL
|| Language
== NULL
|| PackageList
== NULL
) {
995 return EFI_INVALID_PARAMETER
;
998 if (!IsHiiHandleValid (PackageList
)) {
999 return EFI_NOT_FOUND
;
1002 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1006 // If StringFontInfo specify a paritcular font, it should exist in current database.
1008 if (StringFontInfo
!= NULL
) {
1009 if (!IsFontInfoExisted (Private
, (EFI_FONT_INFO
*) StringFontInfo
, NULL
, NULL
, &GlobalFont
)) {
1010 return EFI_INVALID_PARAMETER
;
1015 // Get the matching package list.
1017 PackageListNode
= NULL
;
1018 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1019 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1020 if (DatabaseRecord
->Handle
== PackageList
) {
1021 PackageListNode
= DatabaseRecord
->PackageList
;
1025 if (PackageListNode
== NULL
) {
1026 return EFI_NOT_FOUND
;
1029 Status
= EFI_SUCCESS
;
1030 NewStringPackageCreated
= FALSE
;
1033 StringPackage
= NULL
;
1034 MatchStringPackage
= NULL
;
1035 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1036 Link
!= &PackageListNode
->StringPkgHdr
;
1037 Link
= Link
->ForwardLink
1039 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1041 // Create a string block and corresponding font block if exists, then append them
1042 // to the end of the string package.
1044 Status
= FindStringBlock (
1053 if (EFI_ERROR (Status
)) {
1057 // Make sure that new StringId is same in all String Packages for the different language.
1059 if (NewStringId
!= 0 && NewStringId
!= NextStringId
) {
1061 Status
= EFI_INVALID_PARAMETER
;
1064 NewStringId
= NextStringId
;
1066 // Get the matched string package with language.
1068 if (HiiCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
)) {
1069 MatchStringPackage
= StringPackage
;
1071 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
1073 // Create a blank EFI_HII_SIBT_STRING_UCS2_BLOCK to reserve new string ID.
1075 Ucs2BlockSize
= (UINT32
) sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
);
1077 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ Ucs2BlockSize
);
1078 if (StringBlock
== NULL
) {
1079 Status
= EFI_OUT_OF_RESOURCES
;
1083 // Copy original string blocks, except the EFI_HII_SIBT_END.
1085 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1087 // Create a blank EFI_HII_SIBT_STRING_UCS2 block
1089 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1090 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
1091 BlockPtr
+= sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
);
1094 // Append a EFI_HII_SIBT_END block to the end.
1096 *BlockPtr
= EFI_HII_SIBT_END
;
1097 FreePool (StringPackage
->StringBlock
);
1098 StringPackage
->StringBlock
= StringBlock
;
1099 StringPackage
->StringPkgHdr
->Header
.Length
+= Ucs2BlockSize
;
1100 PackageListNode
->PackageListHdr
.PackageLength
+= Ucs2BlockSize
;
1103 if (NewStringId
== 0) {
1105 // No string package is found.
1106 // Create new string package. StringId 1 is reserved for Language Name string.
1113 *StringId
= (EFI_STRING_ID
) (NewStringId
+ 1);
1116 if (MatchStringPackage
!= NULL
) {
1117 StringPackage
= MatchStringPackage
;
1120 // LanguageName is required to create a new string package.
1122 if (LanguageName
== NULL
) {
1123 Status
= EFI_INVALID_PARAMETER
;
1127 StringPackage
= AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE
));
1128 if (StringPackage
== NULL
) {
1129 Status
= EFI_OUT_OF_RESOURCES
;
1133 StringPackage
->Signature
= HII_STRING_PACKAGE_SIGNATURE
;
1134 StringPackage
->MaxStringId
= *StringId
;
1135 StringPackage
->FontId
= 0;
1136 InitializeListHead (&StringPackage
->FontInfoList
);
1139 // Fill in the string package header
1141 HeaderSize
= (UINT32
) (AsciiStrSize ((CHAR8
*) Language
) - 1 + sizeof (EFI_HII_STRING_PACKAGE_HDR
));
1142 StringPackage
->StringPkgHdr
= AllocateZeroPool (HeaderSize
);
1143 if (StringPackage
->StringPkgHdr
== NULL
) {
1144 FreePool (StringPackage
);
1145 Status
= EFI_OUT_OF_RESOURCES
;
1148 StringPackage
->StringPkgHdr
->Header
.Type
= EFI_HII_PACKAGE_STRINGS
;
1149 StringPackage
->StringPkgHdr
->HdrSize
= HeaderSize
;
1150 StringPackage
->StringPkgHdr
->StringInfoOffset
= HeaderSize
;
1151 CopyMem (StringPackage
->StringPkgHdr
->LanguageWindow
, mLanguageWindow
, 16 * sizeof (CHAR16
));
1152 StringPackage
->StringPkgHdr
->LanguageName
= 1;
1153 AsciiStrCpy (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
);
1156 // Calculate the length of the string blocks, including string block to record
1157 // printable language full name and EFI_HII_SIBT_END_BLOCK.
1159 Ucs2BlockSize
= (UINT32
) (StrSize ((CHAR16
*) LanguageName
) +
1160 (*StringId
- 1) * sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
) - sizeof (CHAR16
));
1162 BlockSize
= Ucs2BlockSize
+ sizeof (EFI_HII_SIBT_END_BLOCK
);
1163 StringPackage
->StringBlock
= (UINT8
*) AllocateZeroPool (BlockSize
);
1164 if (StringPackage
->StringBlock
== NULL
) {
1165 FreePool (StringPackage
->StringPkgHdr
);
1166 FreePool (StringPackage
);
1167 Status
= EFI_OUT_OF_RESOURCES
;
1172 // Insert the string block of printable language full name
1174 BlockPtr
= StringPackage
->StringBlock
;
1175 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
1176 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1177 CopyMem (BlockPtr
, (EFI_STRING
) LanguageName
, StrSize ((EFI_STRING
) LanguageName
));
1178 BlockPtr
+= StrSize ((EFI_STRING
) LanguageName
);
1179 for (Index
= 2; Index
<= *StringId
- 1; Index
++) {
1180 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
1181 BlockPtr
+= sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
);
1184 // Insert the end block
1186 *BlockPtr
= EFI_HII_SIBT_END
;
1189 // Append this string package node to string package array in this package list.
1191 StringPackage
->StringPkgHdr
->Header
.Length
= HeaderSize
+ BlockSize
;
1192 PackageListNode
->PackageListHdr
.PackageLength
+= StringPackage
->StringPkgHdr
->Header
.Length
;
1193 InsertTailList (&PackageListNode
->StringPkgHdr
, &StringPackage
->StringEntry
);
1194 NewStringPackageCreated
= TRUE
;
1197 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
1199 if (StringFontInfo
== NULL
) {
1201 // Create a EFI_HII_SIBT_STRING_UCS2_BLOCK since font info is not specified.
1203 Ucs2BlockSize
= (UINT32
) (StrSize (String
) + sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
)
1206 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ Ucs2BlockSize
);
1207 if (StringBlock
== NULL
) {
1208 Status
= EFI_OUT_OF_RESOURCES
;
1212 // Copy original string blocks, except the EFI_HII_SIBT_END.
1214 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1216 // Create a EFI_HII_SIBT_STRING_UCS2 block
1218 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1219 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
1220 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1221 CopyMem (BlockPtr
, (EFI_STRING
) String
, StrSize ((EFI_STRING
) String
));
1222 BlockPtr
+= StrSize ((EFI_STRING
) String
);
1225 // Append a EFI_HII_SIBT_END block to the end.
1227 *BlockPtr
= EFI_HII_SIBT_END
;
1228 FreePool (StringPackage
->StringBlock
);
1229 StringPackage
->StringBlock
= StringBlock
;
1230 StringPackage
->StringPkgHdr
->Header
.Length
+= Ucs2BlockSize
;
1231 PackageListNode
->PackageListHdr
.PackageLength
+= Ucs2BlockSize
;
1235 // StringFontInfo is specified here. If there is a EFI_HII_SIBT_FONT_BLOCK
1236 // which refers to this font info, create a EFI_HII_SIBT_STRING_UCS2_FONT block
1237 // only. Otherwise create a EFI_HII_SIBT_FONT block with a EFI_HII_SIBT_STRING
1238 // _UCS2_FONT block.
1240 Ucs2FontBlockSize
= (UINT32
) (StrSize (String
) + sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) -
1242 if (ReferFontInfoLocally (Private
, StringPackage
, StringPackage
->FontId
, FALSE
, GlobalFont
, &LocalFont
)) {
1244 // Create a EFI_HII_SIBT_STRING_UCS2_FONT block only.
1246 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ Ucs2FontBlockSize
);
1247 if (StringBlock
== NULL
) {
1248 Status
= EFI_OUT_OF_RESOURCES
;
1252 // Copy original string blocks, except the EFI_HII_SIBT_END.
1254 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1256 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
1258 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1259 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2_FONT
;
1260 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1261 *BlockPtr
= LocalFont
->FontId
;
1262 BlockPtr
+= sizeof (UINT8
);
1263 CopyMem (BlockPtr
, (EFI_STRING
) String
, StrSize ((EFI_STRING
) String
));
1264 BlockPtr
+= StrSize ((EFI_STRING
) String
);
1267 // Append a EFI_HII_SIBT_END block to the end.
1269 *BlockPtr
= EFI_HII_SIBT_END
;
1270 FreePool (StringPackage
->StringBlock
);
1271 StringPackage
->StringBlock
= StringBlock
;
1272 StringPackage
->StringPkgHdr
->Header
.Length
+= Ucs2FontBlockSize
;
1273 PackageListNode
->PackageListHdr
.PackageLength
+= Ucs2FontBlockSize
;
1277 // EFI_HII_SIBT_FONT_BLOCK does not exist in current string package, so
1278 // create a EFI_HII_SIBT_FONT block to record the font info, then generate
1279 // a EFI_HII_SIBT_STRING_UCS2_FONT block to record the incoming string.
1281 FontBlockSize
= (UINT32
) (StrSize (((EFI_FONT_INFO
*) StringFontInfo
)->FontName
) +
1282 sizeof (EFI_HII_SIBT_FONT_BLOCK
) - sizeof (CHAR16
));
1283 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ FontBlockSize
+ Ucs2FontBlockSize
);
1284 if (StringBlock
== NULL
) {
1285 Status
= EFI_OUT_OF_RESOURCES
;
1289 // Copy original string blocks, except the EFI_HII_SIBT_END.
1291 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1294 // Create a EFI_HII_SIBT_FONT block firstly and then backup its info in string
1295 // package instance for future reference.
1297 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1299 Ext2
.Header
.BlockType
= EFI_HII_SIBT_EXT2
;
1300 Ext2
.BlockType2
= EFI_HII_SIBT_FONT
;
1301 Ext2
.Length
= (UINT16
) FontBlockSize
;
1302 CopyMem (BlockPtr
, &Ext2
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
1303 BlockPtr
+= sizeof (EFI_HII_SIBT_EXT2_BLOCK
);
1305 *BlockPtr
= LocalFont
->FontId
;
1306 BlockPtr
+= sizeof (UINT8
);
1307 CopyMem (BlockPtr
, &((EFI_FONT_INFO
*) StringFontInfo
)->FontSize
, sizeof (UINT16
));
1308 BlockPtr
+= sizeof (UINT16
);
1309 CopyMem (BlockPtr
, &((EFI_FONT_INFO
*) StringFontInfo
)->FontStyle
, sizeof (EFI_HII_FONT_STYLE
));
1310 BlockPtr
+= sizeof (EFI_HII_FONT_STYLE
);
1313 &((EFI_FONT_INFO
*) StringFontInfo
)->FontName
,
1314 StrSize (((EFI_FONT_INFO
*) StringFontInfo
)->FontName
)
1316 BlockPtr
+= StrSize (((EFI_FONT_INFO
*) StringFontInfo
)->FontName
);
1318 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
1320 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2_FONT
;
1321 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1322 *BlockPtr
= LocalFont
->FontId
;
1323 BlockPtr
+= sizeof (UINT8
);
1324 CopyMem (BlockPtr
, (EFI_STRING
) String
, StrSize ((EFI_STRING
) String
));
1325 BlockPtr
+= StrSize ((EFI_STRING
) String
);
1328 // Append a EFI_HII_SIBT_END block to the end.
1330 *BlockPtr
= EFI_HII_SIBT_END
;
1331 FreePool (StringPackage
->StringBlock
);
1332 StringPackage
->StringBlock
= StringBlock
;
1333 StringPackage
->StringPkgHdr
->Header
.Length
+= FontBlockSize
+ Ucs2FontBlockSize
;
1334 PackageListNode
->PackageListHdr
.PackageLength
+= FontBlockSize
+ Ucs2FontBlockSize
;
1337 // Increase the FontId to make it unique since we already add
1338 // a EFI_HII_SIBT_FONT block to this string package.
1340 StringPackage
->FontId
++;
1345 if (!EFI_ERROR (Status
) && NewStringPackageCreated
) {
1347 // Trigger any registered notification function for new string package
1349 Status
= InvokeRegisteredFunction (
1351 EFI_HII_DATABASE_NOTIFY_NEW_PACK
,
1352 (VOID
*) StringPackage
,
1353 EFI_HII_PACKAGE_STRINGS
,
1358 if (!EFI_ERROR (Status
)) {
1360 // Update MaxString Id to new StringId
1362 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1363 Link
!= &PackageListNode
->StringPkgHdr
;
1364 Link
= Link
->ForwardLink
1366 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1367 StringPackage
->MaxStringId
= *StringId
;
1369 } else if (NewStringPackageCreated
) {
1371 // Free the allocated new string Package when new string can't be added.
1373 RemoveEntryList (&StringPackage
->StringEntry
);
1374 FreePool (StringPackage
->StringBlock
);
1375 FreePool (StringPackage
->StringPkgHdr
);
1376 FreePool (StringPackage
);
1384 This function retrieves the string specified by StringId which is associated
1385 with the specified PackageList in the language Language and copies it into
1386 the buffer specified by String.
1388 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1389 @param Language Points to the language for the retrieved string.
1390 @param PackageList The package list in the HII database to search for
1391 the specified string.
1392 @param StringId The string's id, which is unique within
1394 @param String Points to the new null-terminated string.
1395 @param StringSize On entry, points to the size of the buffer pointed
1396 to by String, in bytes. On return, points to the
1397 length of the string, in bytes.
1398 @param StringFontInfo If not NULL, points to the string's font
1399 information. It's caller's responsibility to free
1402 @retval EFI_SUCCESS The string was returned successfully.
1403 @retval EFI_NOT_FOUND The string specified by StringId is not available.
1404 @retval EFI_NOT_FOUND The string specified by StringId is available but
1405 not in the specified language.
1406 The specified PackageList is not in the database.
1407 @retval EFI_INVALID_LANGUAGE - The string specified by StringId is available but
1408 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to
1410 @retval EFI_INVALID_PARAMETER The String or Language or StringSize was NULL.
1411 @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the
1418 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1419 IN CONST CHAR8
*Language
,
1420 IN EFI_HII_HANDLE PackageList
,
1421 IN EFI_STRING_ID StringId
,
1422 OUT EFI_STRING String
,
1423 IN OUT UINTN
*StringSize
,
1424 OUT EFI_FONT_INFO
**StringFontInfo OPTIONAL
1429 HII_DATABASE_PRIVATE_DATA
*Private
;
1430 HII_DATABASE_RECORD
*DatabaseRecord
;
1431 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1432 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1434 if (This
== NULL
|| Language
== NULL
|| StringId
< 1 || StringSize
== NULL
|| PackageList
== NULL
) {
1435 return EFI_INVALID_PARAMETER
;
1438 if (String
== NULL
&& *StringSize
!= 0) {
1439 return EFI_INVALID_PARAMETER
;
1442 if (!IsHiiHandleValid (PackageList
)) {
1443 return EFI_NOT_FOUND
;
1446 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1447 PackageListNode
= NULL
;
1449 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1450 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1451 if (DatabaseRecord
->Handle
== PackageList
) {
1452 PackageListNode
= DatabaseRecord
->PackageList
;
1457 if (PackageListNode
!= NULL
) {
1459 // First search: to match the StringId in the specified language.
1461 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1462 Link
!= &PackageListNode
->StringPkgHdr
;
1463 Link
= Link
->ForwardLink
1465 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1466 if (HiiCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
)) {
1467 Status
= GetStringWorker (Private
, StringPackage
, StringId
, String
, StringSize
, StringFontInfo
);
1468 if (Status
!= EFI_NOT_FOUND
) {
1474 // Second search: to match the StringId in other available languages if exist.
1476 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1477 Link
!= &PackageListNode
->StringPkgHdr
;
1478 Link
= Link
->ForwardLink
1480 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1481 Status
= GetStringWorker (Private
, StringPackage
, StringId
, NULL
, NULL
, NULL
);
1482 if (!EFI_ERROR (Status
)) {
1483 return EFI_INVALID_LANGUAGE
;
1488 return EFI_NOT_FOUND
;
1494 This function updates the string specified by StringId in the specified PackageList to the text
1495 specified by String and, optionally, the font information specified by StringFontInfo.
1497 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1498 @param PackageList The package list containing the strings.
1499 @param StringId The string's id, which is unique within
1501 @param Language Points to the language for the updated string.
1502 @param String Points to the new null-terminated string.
1503 @param StringFontInfo Points to the string's font information or NULL if
1504 the string font information is not changed.
1506 @retval EFI_SUCCESS The string was updated successfully.
1507 @retval EFI_NOT_FOUND The string specified by StringId is not in the
1509 @retval EFI_INVALID_PARAMETER The String or Language was NULL.
1510 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
1512 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
1519 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1520 IN EFI_HII_HANDLE PackageList
,
1521 IN EFI_STRING_ID StringId
,
1522 IN CONST CHAR8
*Language
,
1523 IN CONST EFI_STRING String
,
1524 IN CONST EFI_FONT_INFO
*StringFontInfo OPTIONAL
1529 HII_DATABASE_PRIVATE_DATA
*Private
;
1530 HII_DATABASE_RECORD
*DatabaseRecord
;
1531 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1532 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1533 UINT32 OldPackageLen
;
1535 if (This
== NULL
|| Language
== NULL
|| StringId
< 1 || String
== NULL
|| PackageList
== NULL
) {
1536 return EFI_INVALID_PARAMETER
;
1539 if (!IsHiiHandleValid (PackageList
)) {
1540 return EFI_NOT_FOUND
;
1543 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1544 PackageListNode
= NULL
;
1546 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1547 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1548 if (DatabaseRecord
->Handle
== PackageList
) {
1549 PackageListNode
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*) (DatabaseRecord
->PackageList
);
1553 if (PackageListNode
!= NULL
) {
1554 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1555 Link
!= &PackageListNode
->StringPkgHdr
;
1556 Link
= Link
->ForwardLink
1558 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1559 if (HiiCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
)) {
1560 OldPackageLen
= StringPackage
->StringPkgHdr
->Header
.Length
;
1561 Status
= SetStringWorker (
1565 (EFI_STRING
) String
,
1566 (EFI_FONT_INFO
*) StringFontInfo
1568 if (EFI_ERROR (Status
)) {
1571 PackageListNode
->PackageListHdr
.PackageLength
+= StringPackage
->StringPkgHdr
->Header
.Length
- OldPackageLen
;
1577 return EFI_NOT_FOUND
;
1583 This function returns the list of supported languages, in the format specified
1584 in Appendix M of UEFI 2.1 spec.
1586 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1587 @param PackageList The package list to examine.
1588 @param Languages Points to the buffer to hold the returned string.
1589 @param LanguagesSize On entry, points to the size of the buffer pointed
1590 to by Languages, in bytes. On return, points to
1591 the length of Languages, in bytes.
1593 @retval EFI_SUCCESS The languages were returned successfully.
1594 @retval EFI_INVALID_PARAMETER The Languages or LanguagesSize was NULL.
1595 @retval EFI_BUFFER_TOO_SMALL The LanguagesSize is too small to hold the list of
1596 supported languages. LanguageSize is updated to
1597 contain the required size.
1598 @retval EFI_NOT_FOUND Could not find string package in specified
1605 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1606 IN EFI_HII_HANDLE PackageList
,
1607 IN OUT CHAR8
*Languages
,
1608 IN OUT UINTN
*LanguagesSize
1612 HII_DATABASE_PRIVATE_DATA
*Private
;
1613 HII_DATABASE_RECORD
*DatabaseRecord
;
1614 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1615 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1618 if (This
== NULL
|| Languages
== NULL
|| LanguagesSize
== NULL
|| PackageList
== NULL
) {
1619 return EFI_INVALID_PARAMETER
;
1621 if (!IsHiiHandleValid (PackageList
)) {
1622 return EFI_NOT_FOUND
;
1625 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1627 PackageListNode
= NULL
;
1628 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1629 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1630 if (DatabaseRecord
->Handle
== PackageList
) {
1631 PackageListNode
= DatabaseRecord
->PackageList
;
1635 if (PackageListNode
== NULL
) {
1636 return EFI_NOT_FOUND
;
1640 // Search the languages in the specified packagelist.
1643 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1644 Link
!= &PackageListNode
->StringPkgHdr
;
1645 Link
= Link
->ForwardLink
1647 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1648 ResultSize
+= AsciiStrSize (StringPackage
->StringPkgHdr
->Language
);
1649 if (ResultSize
<= *LanguagesSize
) {
1650 AsciiStrCpy (Languages
, StringPackage
->StringPkgHdr
->Language
);
1651 Languages
+= AsciiStrSize (StringPackage
->StringPkgHdr
->Language
);
1652 *(Languages
- 1) = L
';';
1655 if (ResultSize
== 0) {
1656 return EFI_NOT_FOUND
;
1659 if (*LanguagesSize
< ResultSize
) {
1660 *LanguagesSize
= ResultSize
;
1661 return EFI_BUFFER_TOO_SMALL
;
1664 *(Languages
- 1) = 0;
1670 Each string package has associated with it a single primary language and zero
1671 or more secondary languages. This routine returns the secondary languages
1672 associated with a package list.
1674 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1675 @param PackageList The package list to examine.
1676 @param FirstLanguage Points to the primary language.
1677 @param SecondaryLanguages Points to the buffer to hold the returned list of
1678 secondary languages for the specified
1679 FirstLanguage. If there are no secondary
1680 languages, the function returns successfully, but
1681 this is set to NULL.
1682 @param SecondaryLanguagesSize On entry, points to the size of the buffer pointed
1683 to by SecondaryLanguages, in bytes. On return,
1684 points to the length of SecondaryLanguages in bytes.
1686 @retval EFI_SUCCESS Secondary languages were correctly returned.
1687 @retval EFI_INVALID_PARAMETER FirstLanguage or SecondaryLanguages or
1688 SecondaryLanguagesSize was NULL.
1689 @retval EFI_BUFFER_TOO_SMALL The buffer specified by SecondaryLanguagesSize is
1690 too small to hold the returned information.
1691 SecondLanguageSize is updated to hold the size of
1692 the buffer required.
1693 @retval EFI_INVALID_LANGUAGE The language specified by FirstLanguage is not
1694 present in the specified package list.
1695 @retval EFI_NOT_FOUND The specified PackageList is not in the Database.
1700 HiiGetSecondaryLanguages (
1701 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1702 IN EFI_HII_HANDLE PackageList
,
1703 IN CONST CHAR8
*FirstLanguage
,
1704 IN OUT CHAR8
*SecondaryLanguages
,
1705 IN OUT UINTN
*SecondaryLanguagesSize
1710 HII_DATABASE_PRIVATE_DATA
*Private
;
1711 HII_DATABASE_RECORD
*DatabaseRecord
;
1712 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1713 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1717 if (This
== NULL
|| PackageList
== NULL
|| FirstLanguage
== NULL
) {
1718 return EFI_INVALID_PARAMETER
;
1720 if (SecondaryLanguages
== NULL
|| SecondaryLanguagesSize
== NULL
) {
1721 return EFI_INVALID_PARAMETER
;
1723 if (!IsHiiHandleValid (PackageList
)) {
1724 return EFI_NOT_FOUND
;
1727 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1729 PackageListNode
= NULL
;
1730 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1731 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1732 if (DatabaseRecord
->Handle
== PackageList
) {
1733 PackageListNode
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*) (DatabaseRecord
->PackageList
);
1737 if (PackageListNode
== NULL
) {
1738 return EFI_NOT_FOUND
;
1743 for (Link1
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1744 Link1
!= &PackageListNode
->StringPkgHdr
;
1745 Link1
= Link1
->ForwardLink
1747 StringPackage
= CR (Link1
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1748 if (HiiCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) FirstLanguage
)) {
1749 Languages
= StringPackage
->StringPkgHdr
->Language
;
1751 // Language is a series of ';' terminated strings, first one is primary
1752 // language and following with other secondary languages or NULL if no
1753 // secondary languages any more.
1755 Languages
= AsciiStrStr (Languages
, ";");
1756 if (Languages
== NULL
) {
1761 ResultSize
= AsciiStrSize (Languages
);
1762 if (ResultSize
<= *SecondaryLanguagesSize
) {
1763 AsciiStrCpy (SecondaryLanguages
, Languages
);
1765 *SecondaryLanguagesSize
= ResultSize
;
1766 return EFI_BUFFER_TOO_SMALL
;
1773 return EFI_INVALID_LANGUAGE
;
1777 Compare whether two names of languages are identical.
1779 @param Language1 Name of language 1
1780 @param Language2 Name of language 2
1783 @retval FALSE not same
1787 HiiCompareLanguage (
1788 IN CHAR8
*Language1
,
1794 // This library interface is simply obsolete.
1795 // Include the source code to user code.
1799 for (Index
= 0; (Language1
[Index
] != 0) && (Language2
[Index
] != 0); Index
++) {
1800 if (Language1
[Index
] != Language2
[Index
]) {
1805 if (((Language1
[Index
] == 0) && (Language2
[Index
] == 0)) ||
1806 ((Language1
[Index
] == 0) && (Language2
[Index
] != ';')) ||
1807 ((Language1
[Index
] == ';') && (Language2
[Index
] != 0)) ||
1808 ((Language1
[Index
] == ';') && (Language2
[Index
] != ';'))) {