2 Implementation for EFI_HII_STRING_PROTOCOL.
5 Copyright (c) 2007 - 2010, Intel Corporation
6 All rights reserved. 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
,
603 OUT EFI_FONT_INFO
**StringFontInfo OPTIONAL
606 UINT8
*StringTextPtr
;
608 UINT8
*StringBlockAddr
;
609 UINTN StringTextOffset
;
613 ASSERT (StringPackage
!= NULL
&& StringSize
!= 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
)) {
633 // Get the string text.
635 StringTextPtr
= StringBlockAddr
+ StringTextOffset
;
637 case EFI_HII_SIBT_STRING_SCSU
:
638 case EFI_HII_SIBT_STRING_SCSU_FONT
:
639 case EFI_HII_SIBT_STRINGS_SCSU
:
640 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
641 Status
= ConvertToUnicodeText (String
, (CHAR8
*) StringTextPtr
, StringSize
);
643 case EFI_HII_SIBT_STRING_UCS2
:
644 case EFI_HII_SIBT_STRING_UCS2_FONT
:
645 case EFI_HII_SIBT_STRINGS_UCS2
:
646 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
647 Status
= GetUnicodeStringTextOrSize (String
, StringTextPtr
, StringSize
);
650 return EFI_NOT_FOUND
;
652 if (EFI_ERROR (Status
)) {
657 // Get the string font. The FontId 0 is the default font for those string blocks which
658 // do not specify a font identifier. If default font is not specified, return NULL.
660 if (StringFontInfo
!= NULL
) {
662 case EFI_HII_SIBT_STRING_SCSU_FONT
:
663 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
664 case EFI_HII_SIBT_STRING_UCS2_FONT
:
665 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
666 FontId
= *(StringBlockAddr
+ sizeof (EFI_HII_STRING_BLOCK
));
671 Status
= GetStringFontInfo (StringPackage
, FontId
, StringFontInfo
);
672 if (Status
== EFI_NOT_FOUND
) {
673 *StringFontInfo
= NULL
;
682 Parse all string blocks to set a String specified by StringId.
684 This is a internal function.
686 @param Private HII database driver private structure.
687 @param StringPackage HII string package instance.
688 @param StringId The string's id, which is unique within
690 @param String Points to the new null-terminated string.
691 @param StringFontInfo Points to the input font info.
693 @retval EFI_SUCCESS The string was updated successfully.
694 @retval EFI_NOT_FOUND The string specified by StringId is not in the
696 @retval EFI_INVALID_PARAMETER The String or Language was NULL.
697 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
699 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
705 IN HII_DATABASE_PRIVATE_DATA
*Private
,
706 IN OUT HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
707 IN EFI_STRING_ID StringId
,
708 IN EFI_STRING String
,
709 IN EFI_FONT_INFO
*StringFontInfo OPTIONAL
712 UINT8
*StringTextPtr
;
714 UINT8
*StringBlockAddr
;
715 UINTN StringTextOffset
;
721 HII_FONT_INFO
*LocalFont
;
722 HII_GLOBAL_FONT_INFO
*GlobalFont
;
724 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
729 ASSERT (Private
!= NULL
&& StringPackage
!= NULL
&& String
!= NULL
);
730 ASSERT (Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
732 // Find the specified string block
734 Status
= FindStringBlock (
743 if (EFI_ERROR (Status
)) {
752 // The input StringFontInfo should exist in current database if specified.
754 if (StringFontInfo
!= NULL
) {
755 if (!IsFontInfoExisted (Private
, StringFontInfo
, NULL
, NULL
, &GlobalFont
)) {
756 return EFI_INVALID_PARAMETER
;
758 Referred
= ReferFontInfoLocally (
761 StringPackage
->FontId
,
767 StringPackage
->FontId
++;
771 // Update the FontId of the specified string block to input font info.
774 case EFI_HII_SIBT_STRING_SCSU_FONT
:
775 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
776 case EFI_HII_SIBT_STRING_UCS2_FONT
:
777 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
778 *(StringBlockAddr
+ sizeof (EFI_HII_STRING_BLOCK
)) = LocalFont
->FontId
;
782 // When modify the font info of these blocks, the block type should be updated
783 // to contain font info thus the whole structure should be revised.
784 // It is recommended to use tool to modify the block type not in the code.
786 return EFI_UNSUPPORTED
;
790 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
793 // Set the string text and font.
795 StringTextPtr
= StringBlockAddr
+ StringTextOffset
;
797 case EFI_HII_SIBT_STRING_SCSU
:
798 case EFI_HII_SIBT_STRING_SCSU_FONT
:
799 case EFI_HII_SIBT_STRINGS_SCSU
:
800 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
801 BlockSize
= OldBlockSize
+ StrLen (String
);
802 BlockSize
-= AsciiStrLen ((CHAR8
*) StringTextPtr
);
803 Block
= AllocateZeroPool (BlockSize
);
805 return EFI_OUT_OF_RESOURCES
;
808 CopyMem (Block
, StringPackage
->StringBlock
, StringTextPtr
- StringPackage
->StringBlock
);
809 BlockPtr
= Block
+ (StringTextPtr
- StringPackage
->StringBlock
);
811 while (*String
!= 0) {
812 *BlockPtr
++ = (CHAR8
) *String
++;
817 TmpSize
= OldBlockSize
- (StringTextPtr
- StringPackage
->StringBlock
) - AsciiStrSize ((CHAR8
*) StringTextPtr
);
820 StringTextPtr
+ AsciiStrSize ((CHAR8
*)StringTextPtr
),
824 FreePool (StringPackage
->StringBlock
);
825 StringPackage
->StringBlock
= Block
;
826 StringPackage
->StringPkgHdr
->Header
.Length
+= (UINT32
) (BlockSize
- OldBlockSize
);
829 case EFI_HII_SIBT_STRING_UCS2
:
830 case EFI_HII_SIBT_STRING_UCS2_FONT
:
831 case EFI_HII_SIBT_STRINGS_UCS2
:
832 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
834 // Use StrSize to store the size of the specified string, including the NULL
837 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
839 BlockSize
= OldBlockSize
+ StrSize (String
) - StringSize
;
840 Block
= AllocateZeroPool (BlockSize
);
842 return EFI_OUT_OF_RESOURCES
;
845 CopyMem (Block
, StringPackage
->StringBlock
, StringTextPtr
- StringPackage
->StringBlock
);
846 BlockPtr
= Block
+ (StringTextPtr
- StringPackage
->StringBlock
);
848 CopyMem (BlockPtr
, String
, StrSize (String
));
849 BlockPtr
+= StrSize (String
);
853 StringTextPtr
+ StringSize
,
854 OldBlockSize
- (StringTextPtr
- StringPackage
->StringBlock
) - StringSize
857 FreePool (StringPackage
->StringBlock
);
858 StringPackage
->StringBlock
= Block
;
859 StringPackage
->StringPkgHdr
->Header
.Length
+= (UINT32
) (BlockSize
- OldBlockSize
);
863 return EFI_NOT_FOUND
;
867 // Insert a new EFI_HII_SIBT_FONT_BLOCK to the header of string block, if incoming
868 // StringFontInfo does not exist in current string package.
870 // This new block does not impact on the value of StringId.
873 if (StringFontInfo
== NULL
|| Referred
) {
877 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
878 BlockSize
= OldBlockSize
+ sizeof (EFI_HII_SIBT_FONT_BLOCK
) - sizeof (CHAR16
) +
879 StrSize (GlobalFont
->FontInfo
->FontName
);
881 Block
= AllocateZeroPool (BlockSize
);
883 return EFI_OUT_OF_RESOURCES
;
887 Ext2
.Header
.BlockType
= EFI_HII_SIBT_EXT2
;
888 Ext2
.BlockType2
= EFI_HII_SIBT_FONT
;
889 Ext2
.Length
= (UINT16
) (BlockSize
- OldBlockSize
);
890 CopyMem (BlockPtr
, &Ext2
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
891 BlockPtr
+= sizeof (EFI_HII_SIBT_EXT2_BLOCK
);
893 *BlockPtr
= LocalFont
->FontId
;
894 BlockPtr
+= sizeof (UINT8
);
895 CopyMem (BlockPtr
, &GlobalFont
->FontInfo
->FontSize
, sizeof (UINT16
));
896 BlockPtr
+= sizeof (UINT16
);
897 CopyMem (BlockPtr
, &GlobalFont
->FontInfo
->FontStyle
, sizeof (UINT32
));
898 BlockPtr
+= sizeof (UINT32
);
901 GlobalFont
->FontInfo
->FontName
,
902 StrSize (GlobalFont
->FontInfo
->FontName
)
904 BlockPtr
+= StrSize (GlobalFont
->FontInfo
->FontName
);
906 CopyMem (BlockPtr
, StringPackage
->StringBlock
, OldBlockSize
);
908 FreePool (StringPackage
->StringBlock
);
909 StringPackage
->StringBlock
= Block
;
910 StringPackage
->StringPkgHdr
->Header
.Length
+= Ext2
.Length
;
918 This function adds the string String to the group of strings owned by PackageList, with the
919 specified font information StringFontInfo and returns a new string id.
920 The new string identifier is guaranteed to be unique within the package list.
921 That new string identifier is reserved for all languages in the package list.
924 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
925 @param PackageList Handle of the package list where this string will
927 @param StringId On return, contains the new strings id, which is
928 unique within PackageList.
929 @param Language Points to the language for the new string.
930 @param LanguageName Points to the printable language name to associate
931 with the passed in Language field.If LanguageName
932 is not NULL and the string package header's
933 LanguageName associated with a given Language is
934 not zero, the LanguageName being passed in will
936 @param String Points to the new null-terminated string.
937 @param StringFontInfo Points to the new string's font information or
938 NULL if the string should have the default system
939 font, size and style.
941 @retval EFI_SUCCESS The new string was added successfully.
942 @retval EFI_NOT_FOUND The specified PackageList could not be found in
944 @retval EFI_OUT_OF_RESOURCES Could not add the string due to lack of resources.
945 @retval EFI_INVALID_PARAMETER String is NULL or StringId is NULL or Language is
947 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
954 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
955 IN EFI_HII_HANDLE PackageList
,
956 OUT EFI_STRING_ID
*StringId
,
957 IN CONST CHAR8
*Language
,
958 IN CONST CHAR16
*LanguageName
, OPTIONAL
959 IN CONST EFI_STRING String
,
960 IN CONST EFI_FONT_INFO
*StringFontInfo OPTIONAL
965 HII_DATABASE_PRIVATE_DATA
*Private
;
966 HII_DATABASE_RECORD
*DatabaseRecord
;
967 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
968 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
974 UINT32 Ucs2BlockSize
;
975 UINT32 FontBlockSize
;
976 UINT32 Ucs2FontBlockSize
;
977 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
978 HII_FONT_INFO
*LocalFont
;
979 HII_GLOBAL_FONT_INFO
*GlobalFont
;
980 EFI_STRING_ID NewStringId
;
981 EFI_STRING_ID NextStringId
;
983 HII_STRING_PACKAGE_INSTANCE
*MatchStringPackage
;
984 BOOLEAN NewStringPackageCreated
;
987 if (This
== NULL
|| String
== NULL
|| StringId
== NULL
|| Language
== NULL
|| PackageList
== NULL
) {
988 return EFI_INVALID_PARAMETER
;
991 if (!IsHiiHandleValid (PackageList
)) {
992 return EFI_NOT_FOUND
;
995 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
999 // If StringFontInfo specify a paritcular font, it should exist in current database.
1001 if (StringFontInfo
!= NULL
) {
1002 if (!IsFontInfoExisted (Private
, (EFI_FONT_INFO
*) StringFontInfo
, NULL
, NULL
, &GlobalFont
)) {
1003 return EFI_INVALID_PARAMETER
;
1008 // Get the matching package list.
1010 PackageListNode
= NULL
;
1011 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1012 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1013 if (DatabaseRecord
->Handle
== PackageList
) {
1014 PackageListNode
= DatabaseRecord
->PackageList
;
1018 if (PackageListNode
== NULL
) {
1019 return EFI_NOT_FOUND
;
1022 Status
= EFI_SUCCESS
;
1023 NewStringPackageCreated
= FALSE
;
1026 StringPackage
= NULL
;
1027 MatchStringPackage
= NULL
;
1028 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1029 Link
!= &PackageListNode
->StringPkgHdr
;
1030 Link
= Link
->ForwardLink
1032 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1034 // Create a string block and corresponding font block if exists, then append them
1035 // to the end of the string package.
1037 Status
= FindStringBlock (
1046 if (EFI_ERROR (Status
)) {
1050 // Make sure that new StringId is same in all String Packages for the different language.
1052 if (NewStringId
!= 0 && NewStringId
!= NextStringId
) {
1054 Status
= EFI_INVALID_PARAMETER
;
1057 NewStringId
= NextStringId
;
1059 // Get the matched string package with language.
1061 if (HiiCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
)) {
1062 MatchStringPackage
= StringPackage
;
1064 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
1066 // Create a blank EFI_HII_SIBT_STRING_UCS2_BLOCK to reserve new string ID.
1068 Ucs2BlockSize
= (UINT32
) sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
);
1070 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ Ucs2BlockSize
);
1071 if (StringBlock
== NULL
) {
1072 Status
= EFI_OUT_OF_RESOURCES
;
1076 // Copy original string blocks, except the EFI_HII_SIBT_END.
1078 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1080 // Create a blank EFI_HII_SIBT_STRING_UCS2 block
1082 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1083 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
1084 BlockPtr
+= sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
);
1087 // Append a EFI_HII_SIBT_END block to the end.
1089 *BlockPtr
= EFI_HII_SIBT_END
;
1090 FreePool (StringPackage
->StringBlock
);
1091 StringPackage
->StringBlock
= StringBlock
;
1092 StringPackage
->StringPkgHdr
->Header
.Length
+= Ucs2BlockSize
;
1093 PackageListNode
->PackageListHdr
.PackageLength
+= Ucs2BlockSize
;
1096 if (NewStringId
== 0) {
1098 // No string package is found.
1099 // Create new string package. StringId 1 is reserved for Language Name string.
1106 *StringId
= (EFI_STRING_ID
) (NewStringId
+ 1);
1109 if (MatchStringPackage
!= NULL
) {
1110 StringPackage
= MatchStringPackage
;
1113 // LanguageName is required to create a new string package.
1115 if (LanguageName
== NULL
) {
1116 Status
= EFI_INVALID_PARAMETER
;
1120 StringPackage
= AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE
));
1121 if (StringPackage
== NULL
) {
1122 Status
= EFI_OUT_OF_RESOURCES
;
1126 StringPackage
->Signature
= HII_STRING_PACKAGE_SIGNATURE
;
1127 StringPackage
->MaxStringId
= *StringId
;
1128 StringPackage
->FontId
= 0;
1129 InitializeListHead (&StringPackage
->FontInfoList
);
1132 // Fill in the string package header
1134 HeaderSize
= (UINT32
) (AsciiStrSize ((CHAR8
*) Language
) - 1 + sizeof (EFI_HII_STRING_PACKAGE_HDR
));
1135 StringPackage
->StringPkgHdr
= AllocateZeroPool (HeaderSize
);
1136 if (StringPackage
->StringPkgHdr
== NULL
) {
1137 FreePool (StringPackage
);
1138 Status
= EFI_OUT_OF_RESOURCES
;
1141 StringPackage
->StringPkgHdr
->Header
.Type
= EFI_HII_PACKAGE_STRINGS
;
1142 StringPackage
->StringPkgHdr
->HdrSize
= HeaderSize
;
1143 StringPackage
->StringPkgHdr
->StringInfoOffset
= HeaderSize
;
1144 CopyMem (StringPackage
->StringPkgHdr
->LanguageWindow
, mLanguageWindow
, 16 * sizeof (CHAR16
));
1145 StringPackage
->StringPkgHdr
->LanguageName
= 1;
1146 AsciiStrCpy (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
);
1149 // Calculate the length of the string blocks, including string block to record
1150 // printable language full name and EFI_HII_SIBT_END_BLOCK.
1152 Ucs2BlockSize
= (UINT32
) (StrSize ((CHAR16
*) LanguageName
) +
1153 (*StringId
- 1) * sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
) - sizeof (CHAR16
));
1155 BlockSize
= Ucs2BlockSize
+ sizeof (EFI_HII_SIBT_END_BLOCK
);
1156 StringPackage
->StringBlock
= (UINT8
*) AllocateZeroPool (BlockSize
);
1157 if (StringPackage
->StringBlock
== NULL
) {
1158 FreePool (StringPackage
->StringPkgHdr
);
1159 FreePool (StringPackage
);
1160 Status
= EFI_OUT_OF_RESOURCES
;
1165 // Insert the string block of printable language full name
1167 BlockPtr
= StringPackage
->StringBlock
;
1168 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
1169 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1170 CopyMem (BlockPtr
, (EFI_STRING
) LanguageName
, StrSize ((EFI_STRING
) LanguageName
));
1171 BlockPtr
+= StrSize ((EFI_STRING
) LanguageName
);
1172 for (Index
= 2; Index
<= *StringId
- 1; Index
++) {
1173 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
1174 BlockPtr
+= sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
);
1177 // Insert the end block
1179 *BlockPtr
= EFI_HII_SIBT_END
;
1182 // Append this string package node to string package array in this package list.
1184 StringPackage
->StringPkgHdr
->Header
.Length
= HeaderSize
+ BlockSize
;
1185 PackageListNode
->PackageListHdr
.PackageLength
+= StringPackage
->StringPkgHdr
->Header
.Length
;
1186 InsertTailList (&PackageListNode
->StringPkgHdr
, &StringPackage
->StringEntry
);
1187 NewStringPackageCreated
= TRUE
;
1190 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
1192 if (StringFontInfo
== NULL
) {
1194 // Create a EFI_HII_SIBT_STRING_UCS2_BLOCK since font info is not specified.
1196 Ucs2BlockSize
= (UINT32
) (StrSize (String
) + sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
)
1199 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ Ucs2BlockSize
);
1200 if (StringBlock
== NULL
) {
1201 Status
= EFI_OUT_OF_RESOURCES
;
1205 // Copy original string blocks, except the EFI_HII_SIBT_END.
1207 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1209 // Create a EFI_HII_SIBT_STRING_UCS2 block
1211 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1212 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
1213 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1214 CopyMem (BlockPtr
, (EFI_STRING
) String
, StrSize ((EFI_STRING
) String
));
1215 BlockPtr
+= StrSize ((EFI_STRING
) String
);
1218 // Append a EFI_HII_SIBT_END block to the end.
1220 *BlockPtr
= EFI_HII_SIBT_END
;
1221 FreePool (StringPackage
->StringBlock
);
1222 StringPackage
->StringBlock
= StringBlock
;
1223 StringPackage
->StringPkgHdr
->Header
.Length
+= Ucs2BlockSize
;
1224 PackageListNode
->PackageListHdr
.PackageLength
+= Ucs2BlockSize
;
1228 // StringFontInfo is specified here. If there is a EFI_HII_SIBT_FONT_BLOCK
1229 // which refers to this font info, create a EFI_HII_SIBT_STRING_UCS2_FONT block
1230 // only. Otherwise create a EFI_HII_SIBT_FONT block with a EFI_HII_SIBT_STRING
1231 // _UCS2_FONT block.
1233 Ucs2FontBlockSize
= (UINT32
) (StrSize (String
) + sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) -
1235 if (ReferFontInfoLocally (Private
, StringPackage
, StringPackage
->FontId
, FALSE
, GlobalFont
, &LocalFont
)) {
1237 // Create a EFI_HII_SIBT_STRING_UCS2_FONT block only.
1239 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ Ucs2FontBlockSize
);
1240 if (StringBlock
== NULL
) {
1241 Status
= EFI_OUT_OF_RESOURCES
;
1245 // Copy original string blocks, except the EFI_HII_SIBT_END.
1247 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1249 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
1251 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1252 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2_FONT
;
1253 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1254 *BlockPtr
= LocalFont
->FontId
;
1255 BlockPtr
+= sizeof (UINT8
);
1256 CopyMem (BlockPtr
, (EFI_STRING
) String
, StrSize ((EFI_STRING
) String
));
1257 BlockPtr
+= StrSize ((EFI_STRING
) String
);
1260 // Append a EFI_HII_SIBT_END block to the end.
1262 *BlockPtr
= EFI_HII_SIBT_END
;
1263 FreePool (StringPackage
->StringBlock
);
1264 StringPackage
->StringBlock
= StringBlock
;
1265 StringPackage
->StringPkgHdr
->Header
.Length
+= Ucs2FontBlockSize
;
1266 PackageListNode
->PackageListHdr
.PackageLength
+= Ucs2FontBlockSize
;
1270 // EFI_HII_SIBT_FONT_BLOCK does not exist in current string package, so
1271 // create a EFI_HII_SIBT_FONT block to record the font info, then generate
1272 // a EFI_HII_SIBT_STRING_UCS2_FONT block to record the incoming string.
1274 FontBlockSize
= (UINT32
) (StrSize (((EFI_FONT_INFO
*) StringFontInfo
)->FontName
) +
1275 sizeof (EFI_HII_SIBT_FONT_BLOCK
) - sizeof (CHAR16
));
1276 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ FontBlockSize
+ Ucs2FontBlockSize
);
1277 if (StringBlock
== NULL
) {
1278 Status
= EFI_OUT_OF_RESOURCES
;
1282 // Copy original string blocks, except the EFI_HII_SIBT_END.
1284 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1287 // Create a EFI_HII_SIBT_FONT block firstly and then backup its info in string
1288 // package instance for future reference.
1290 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1292 Ext2
.Header
.BlockType
= EFI_HII_SIBT_EXT2
;
1293 Ext2
.BlockType2
= EFI_HII_SIBT_FONT
;
1294 Ext2
.Length
= (UINT16
) FontBlockSize
;
1295 CopyMem (BlockPtr
, &Ext2
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
1296 BlockPtr
+= sizeof (EFI_HII_SIBT_EXT2_BLOCK
);
1298 *BlockPtr
= LocalFont
->FontId
;
1299 BlockPtr
+= sizeof (UINT8
);
1300 CopyMem (BlockPtr
, &((EFI_FONT_INFO
*) StringFontInfo
)->FontSize
, sizeof (UINT16
));
1301 BlockPtr
+= sizeof (UINT16
);
1302 CopyMem (BlockPtr
, &((EFI_FONT_INFO
*) StringFontInfo
)->FontStyle
, sizeof (EFI_HII_FONT_STYLE
));
1303 BlockPtr
+= sizeof (EFI_HII_FONT_STYLE
);
1306 &((EFI_FONT_INFO
*) StringFontInfo
)->FontName
,
1307 StrSize (((EFI_FONT_INFO
*) StringFontInfo
)->FontName
)
1309 BlockPtr
+= StrSize (((EFI_FONT_INFO
*) StringFontInfo
)->FontName
);
1311 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
1313 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2_FONT
;
1314 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1315 *BlockPtr
= LocalFont
->FontId
;
1316 BlockPtr
+= sizeof (UINT8
);
1317 CopyMem (BlockPtr
, (EFI_STRING
) String
, StrSize ((EFI_STRING
) String
));
1318 BlockPtr
+= StrSize ((EFI_STRING
) String
);
1321 // Append a EFI_HII_SIBT_END block to the end.
1323 *BlockPtr
= EFI_HII_SIBT_END
;
1324 FreePool (StringPackage
->StringBlock
);
1325 StringPackage
->StringBlock
= StringBlock
;
1326 StringPackage
->StringPkgHdr
->Header
.Length
+= FontBlockSize
+ Ucs2FontBlockSize
;
1327 PackageListNode
->PackageListHdr
.PackageLength
+= FontBlockSize
+ Ucs2FontBlockSize
;
1330 // Increase the FontId to make it unique since we already add
1331 // a EFI_HII_SIBT_FONT block to this string package.
1333 StringPackage
->FontId
++;
1338 if (!EFI_ERROR (Status
) && NewStringPackageCreated
) {
1340 // Trigger any registered notification function for new string package
1342 Status
= InvokeRegisteredFunction (
1344 EFI_HII_DATABASE_NOTIFY_NEW_PACK
,
1345 (VOID
*) StringPackage
,
1346 EFI_HII_PACKAGE_STRINGS
,
1351 if (!EFI_ERROR (Status
)) {
1353 // Update MaxString Id to new StringId
1355 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1356 Link
!= &PackageListNode
->StringPkgHdr
;
1357 Link
= Link
->ForwardLink
1359 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1360 StringPackage
->MaxStringId
= *StringId
;
1362 } else if (NewStringPackageCreated
) {
1364 // Free the allocated new string Package when new string can't be added.
1366 RemoveEntryList (&StringPackage
->StringEntry
);
1367 FreePool (StringPackage
->StringBlock
);
1368 FreePool (StringPackage
->StringPkgHdr
);
1369 FreePool (StringPackage
);
1377 This function retrieves the string specified by StringId which is associated
1378 with the specified PackageList in the language Language and copies it into
1379 the buffer specified by String.
1381 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1382 @param Language Points to the language for the retrieved string.
1383 @param PackageList The package list in the HII database to search for
1384 the specified string.
1385 @param StringId The string's id, which is unique within
1387 @param String Points to the new null-terminated string.
1388 @param StringSize On entry, points to the size of the buffer pointed
1389 to by String, in bytes. On return, points to the
1390 length of the string, in bytes.
1391 @param StringFontInfo If not NULL, points to the string's font
1392 information. It's caller's responsibility to free
1395 @retval EFI_SUCCESS The string was returned successfully.
1396 @retval EFI_NOT_FOUND The string specified by StringId is not available.
1397 @retval EFI_NOT_FOUND The string specified by StringId is available but
1398 not in the specified language.
1399 The specified PackageList is not in the database.
1400 @retval EFI_INVALID_LANGUAGE - The string specified by StringId is available but
1401 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to
1403 @retval EFI_INVALID_PARAMETER The String or Language or StringSize was NULL.
1404 @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the
1411 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1412 IN CONST CHAR8
*Language
,
1413 IN EFI_HII_HANDLE PackageList
,
1414 IN EFI_STRING_ID StringId
,
1415 OUT EFI_STRING String
,
1416 IN OUT UINTN
*StringSize
,
1417 OUT EFI_FONT_INFO
**StringFontInfo OPTIONAL
1422 HII_DATABASE_PRIVATE_DATA
*Private
;
1423 HII_DATABASE_RECORD
*DatabaseRecord
;
1424 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1425 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1427 if (This
== NULL
|| Language
== NULL
|| StringId
< 1 || StringSize
== NULL
|| PackageList
== NULL
) {
1428 return EFI_INVALID_PARAMETER
;
1431 if (String
== NULL
&& *StringSize
!= 0) {
1432 return EFI_INVALID_PARAMETER
;
1435 if (!IsHiiHandleValid (PackageList
)) {
1436 return EFI_NOT_FOUND
;
1439 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1440 PackageListNode
= NULL
;
1442 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1443 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1444 if (DatabaseRecord
->Handle
== PackageList
) {
1445 PackageListNode
= DatabaseRecord
->PackageList
;
1450 if (PackageListNode
!= NULL
) {
1452 // First search: to match the StringId in the specified language.
1454 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1455 Link
!= &PackageListNode
->StringPkgHdr
;
1456 Link
= Link
->ForwardLink
1458 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1459 if (HiiCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
)) {
1460 Status
= GetStringWorker (Private
, StringPackage
, StringId
, String
, StringSize
, StringFontInfo
);
1461 if (Status
!= EFI_NOT_FOUND
) {
1467 // Second search: to match the StringId in other available languages if exist.
1469 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1470 Link
!= &PackageListNode
->StringPkgHdr
;
1471 Link
= Link
->ForwardLink
1473 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1474 Status
= GetStringWorker (Private
, StringPackage
, StringId
, String
, StringSize
, StringFontInfo
);
1475 if (!EFI_ERROR (Status
)) {
1476 return EFI_INVALID_LANGUAGE
;
1481 return EFI_NOT_FOUND
;
1487 This function updates the string specified by StringId in the specified PackageList to the text
1488 specified by String and, optionally, the font information specified by StringFontInfo.
1490 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1491 @param PackageList The package list containing the strings.
1492 @param StringId The string's id, which is unique within
1494 @param Language Points to the language for the updated string.
1495 @param String Points to the new null-terminated string.
1496 @param StringFontInfo Points to the string's font information or NULL if
1497 the string font information is not changed.
1499 @retval EFI_SUCCESS The string was updated successfully.
1500 @retval EFI_NOT_FOUND The string specified by StringId is not in the
1502 @retval EFI_INVALID_PARAMETER The String or Language was NULL.
1503 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
1505 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
1512 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1513 IN EFI_HII_HANDLE PackageList
,
1514 IN EFI_STRING_ID StringId
,
1515 IN CONST CHAR8
*Language
,
1516 IN CONST EFI_STRING String
,
1517 IN CONST EFI_FONT_INFO
*StringFontInfo OPTIONAL
1522 HII_DATABASE_PRIVATE_DATA
*Private
;
1523 HII_DATABASE_RECORD
*DatabaseRecord
;
1524 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1525 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1526 UINT32 OldPackageLen
;
1528 if (This
== NULL
|| Language
== NULL
|| StringId
< 1 || String
== NULL
|| PackageList
== NULL
) {
1529 return EFI_INVALID_PARAMETER
;
1532 if (!IsHiiHandleValid (PackageList
)) {
1533 return EFI_NOT_FOUND
;
1536 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1537 PackageListNode
= NULL
;
1539 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1540 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1541 if (DatabaseRecord
->Handle
== PackageList
) {
1542 PackageListNode
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*) (DatabaseRecord
->PackageList
);
1546 if (PackageListNode
!= NULL
) {
1547 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1548 Link
!= &PackageListNode
->StringPkgHdr
;
1549 Link
= Link
->ForwardLink
1551 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1552 if (HiiCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
)) {
1553 OldPackageLen
= StringPackage
->StringPkgHdr
->Header
.Length
;
1554 Status
= SetStringWorker (
1558 (EFI_STRING
) String
,
1559 (EFI_FONT_INFO
*) StringFontInfo
1561 if (EFI_ERROR (Status
)) {
1564 PackageListNode
->PackageListHdr
.PackageLength
+= StringPackage
->StringPkgHdr
->Header
.Length
- OldPackageLen
;
1570 return EFI_NOT_FOUND
;
1576 This function returns the list of supported languages, in the format specified
1577 in Appendix M of UEFI 2.1 spec.
1579 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1580 @param PackageList The package list to examine.
1581 @param Languages Points to the buffer to hold the returned string.
1582 @param LanguagesSize On entry, points to the size of the buffer pointed
1583 to by Languages, in bytes. On return, points to
1584 the length of Languages, in bytes.
1586 @retval EFI_SUCCESS The languages were returned successfully.
1587 @retval EFI_INVALID_PARAMETER The Languages or LanguagesSize was NULL.
1588 @retval EFI_BUFFER_TOO_SMALL The LanguagesSize is too small to hold the list of
1589 supported languages. LanguageSize is updated to
1590 contain the required size.
1591 @retval EFI_NOT_FOUND Could not find string package in specified
1598 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1599 IN EFI_HII_HANDLE PackageList
,
1600 IN OUT CHAR8
*Languages
,
1601 IN OUT UINTN
*LanguagesSize
1605 HII_DATABASE_PRIVATE_DATA
*Private
;
1606 HII_DATABASE_RECORD
*DatabaseRecord
;
1607 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1608 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1611 if (This
== NULL
|| Languages
== NULL
|| LanguagesSize
== NULL
|| PackageList
== NULL
) {
1612 return EFI_INVALID_PARAMETER
;
1614 if (!IsHiiHandleValid (PackageList
)) {
1615 return EFI_NOT_FOUND
;
1618 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1620 PackageListNode
= NULL
;
1621 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1622 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1623 if (DatabaseRecord
->Handle
== PackageList
) {
1624 PackageListNode
= DatabaseRecord
->PackageList
;
1628 if (PackageListNode
== NULL
) {
1629 return EFI_NOT_FOUND
;
1633 // Search the languages in the specified packagelist.
1636 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1637 Link
!= &PackageListNode
->StringPkgHdr
;
1638 Link
= Link
->ForwardLink
1640 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1641 ResultSize
+= AsciiStrSize (StringPackage
->StringPkgHdr
->Language
);
1642 if (ResultSize
<= *LanguagesSize
) {
1643 AsciiStrCpy (Languages
, StringPackage
->StringPkgHdr
->Language
);
1644 Languages
+= AsciiStrSize (StringPackage
->StringPkgHdr
->Language
);
1645 *(Languages
- 1) = L
';';
1648 if (ResultSize
== 0) {
1649 return EFI_NOT_FOUND
;
1652 if (*LanguagesSize
< ResultSize
) {
1653 *LanguagesSize
= ResultSize
;
1654 return EFI_BUFFER_TOO_SMALL
;
1657 *(Languages
- 1) = 0;
1663 Each string package has associated with it a single primary language and zero
1664 or more secondary languages. This routine returns the secondary languages
1665 associated with a package list.
1667 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1668 @param PackageList The package list to examine.
1669 @param FirstLanguage Points to the primary language.
1670 @param SecondaryLanguages Points to the buffer to hold the returned list of
1671 secondary languages for the specified
1672 FirstLanguage. If there are no secondary
1673 languages, the function returns successfully, but
1674 this is set to NULL.
1675 @param SecondaryLanguagesSize On entry, points to the size of the buffer pointed
1676 to by SecondaryLanguages, in bytes. On return,
1677 points to the length of SecondaryLanguages in bytes.
1679 @retval EFI_SUCCESS Secondary languages were correctly returned.
1680 @retval EFI_INVALID_PARAMETER FirstLanguage or SecondaryLanguages or
1681 SecondaryLanguagesSize was NULL.
1682 @retval EFI_BUFFER_TOO_SMALL The buffer specified by SecondaryLanguagesSize is
1683 too small to hold the returned information.
1684 SecondLanguageSize is updated to hold the size of
1685 the buffer required.
1686 @retval EFI_INVALID_LANGUAGE The language specified by FirstLanguage is not
1687 present in the specified package list.
1688 @retval EFI_NOT_FOUND The specified PackageList is not in the Database.
1693 HiiGetSecondaryLanguages (
1694 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1695 IN EFI_HII_HANDLE PackageList
,
1696 IN CONST CHAR8
*FirstLanguage
,
1697 IN OUT CHAR8
*SecondaryLanguages
,
1698 IN OUT UINTN
*SecondaryLanguagesSize
1703 HII_DATABASE_PRIVATE_DATA
*Private
;
1704 HII_DATABASE_RECORD
*DatabaseRecord
;
1705 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1706 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1710 if (This
== NULL
|| PackageList
== NULL
|| FirstLanguage
== NULL
) {
1711 return EFI_INVALID_PARAMETER
;
1713 if (SecondaryLanguages
== NULL
|| SecondaryLanguagesSize
== NULL
) {
1714 return EFI_INVALID_PARAMETER
;
1716 if (!IsHiiHandleValid (PackageList
)) {
1717 return EFI_NOT_FOUND
;
1720 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1722 PackageListNode
= NULL
;
1723 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1724 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1725 if (DatabaseRecord
->Handle
== PackageList
) {
1726 PackageListNode
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*) (DatabaseRecord
->PackageList
);
1730 if (PackageListNode
== NULL
) {
1731 return EFI_NOT_FOUND
;
1736 for (Link1
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1737 Link1
!= &PackageListNode
->StringPkgHdr
;
1738 Link1
= Link1
->ForwardLink
1740 StringPackage
= CR (Link1
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1741 if (HiiCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) FirstLanguage
)) {
1742 Languages
= StringPackage
->StringPkgHdr
->Language
;
1744 // Language is a series of ';' terminated strings, first one is primary
1745 // language and following with other secondary languages or NULL if no
1746 // secondary languages any more.
1748 Languages
= AsciiStrStr (Languages
, ";");
1749 if (Languages
== NULL
) {
1754 ResultSize
= AsciiStrSize (Languages
);
1755 if (ResultSize
<= *SecondaryLanguagesSize
) {
1756 AsciiStrCpy (SecondaryLanguages
, Languages
);
1758 *SecondaryLanguagesSize
= ResultSize
;
1759 return EFI_BUFFER_TOO_SMALL
;
1766 return EFI_INVALID_LANGUAGE
;
1770 Compare whether two names of languages are identical.
1772 @param Language1 Name of language 1
1773 @param Language2 Name of language 2
1776 @retval FALSE not same
1780 HiiCompareLanguage (
1781 IN CHAR8
*Language1
,
1787 // This library interface is simply obsolete.
1788 // Include the source code to user code.
1792 for (Index
= 0; (Language1
[Index
] != 0) && (Language2
[Index
] != 0); Index
++) {
1793 if (Language1
[Index
] != Language2
[Index
]) {
1798 if (((Language1
[Index
] == 0) && (Language2
[Index
] == 0)) ||
1799 ((Language1
[Index
] == 0) && (Language2
[Index
] != ';')) ||
1800 ((Language1
[Index
] == ';') && (Language2
[Index
] != 0)) ||
1801 ((Language1
[Index
] == ';') && (Language2
[Index
] != ';'))) {