3 Copyright (c) 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Implementation for EFI_HII_STRING_PROTOCOL.
26 #include "HiiDatabase.h"
28 CHAR16 mLanguageWindow
[16] = {
29 0x0000, 0x0080, 0x0100, 0x0300,
30 0x2000, 0x2080, 0x2100, 0x3000,
31 0x0080, 0x00C0, 0x0400, 0x0600,
32 0x0900, 0x3040, 0x30A0, 0xFF00
37 This function checks whether a global font info is referred by local
38 font info list or not. (i.e. HII_FONT_INFO is generated.) If not, create
39 a HII_FONT_INFO to refer it locally.
41 @param Private Hii database private structure.
42 @param StringPackage HII string package instance.
43 @param FontId Font identifer, which must be unique within the string package.
44 @param DuplicateEnable If true, duplicate HII_FONT_INFO which refers to
45 the same EFI_FONT_INFO is permitted. Otherwise it
47 @param GlobalFontInfo Input a global font info which specify a
49 @param LocalFontInfo Output a local font info which refers to a
52 @retval TRUE Already referred before calling this function.
53 @retval FALSE Not referred before calling this function.
58 ReferFontInfoLocally (
59 IN HII_DATABASE_PRIVATE_DATA
*Private
,
60 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
62 IN BOOLEAN DuplicateEnable
,
63 IN HII_GLOBAL_FONT_INFO
*GlobalFontInfo
,
64 OUT HII_FONT_INFO
**LocalFontInfo
67 HII_FONT_INFO
*LocalFont
;
70 ASSERT (Private
!= NULL
&& StringPackage
!= NULL
&& GlobalFontInfo
!= NULL
&& LocalFontInfo
!= NULL
);
72 if (!DuplicateEnable
) {
73 for (Link
= StringPackage
->FontInfoList
.ForwardLink
;
74 Link
!= &StringPackage
->FontInfoList
;
75 Link
= Link
->ForwardLink
77 LocalFont
= CR (Link
, HII_FONT_INFO
, Entry
, HII_FONT_INFO_SIGNATURE
);
78 if (LocalFont
->GlobalEntry
== &GlobalFontInfo
->Entry
) {
80 // Already referred by local font info list, return directly.
82 *LocalFontInfo
= LocalFont
;
87 // FontId identifies EFI_FONT_INFO in local string package uniquely.
88 // GlobalEntry points to a HII_GLOBAL_FONT_INFO which identifies
89 // EFI_FONT_INFO uniquely in whole hii database.
91 LocalFont
= (HII_FONT_INFO
*) AllocateZeroPool (sizeof (HII_FONT_INFO
));
92 ASSERT (LocalFont
!= NULL
);
94 LocalFont
->Signature
= HII_FONT_INFO_SIGNATURE
;
95 LocalFont
->FontId
= FontId
;
96 LocalFont
->GlobalEntry
= &GlobalFontInfo
->Entry
;
97 InsertTailList (&StringPackage
->FontInfoList
, &LocalFont
->Entry
);
99 *LocalFontInfo
= LocalFont
;
105 Convert Ascii string text to unicode string test.
107 @param StringSrc Points to current null-terminated Ascii string.
108 @param StringDest Buffer to store the converted string text.
109 @param BufferSize Length of the buffer.
111 @retval EFI_SUCCESS The string text was outputed successfully.
112 @retval EFI_BUFFER_TOO_SMALL Buffer is insufficient to store the found string
113 text. BufferSize is updated to the required buffer
119 ConvertToUnicodeText (
120 OUT EFI_STRING StringDest
,
122 IN OUT UINTN
*BufferSize
128 ASSERT (StringSrc
!= NULL
&& BufferSize
!= NULL
);
130 StringSize
= AsciiStrSize (StringSrc
) * 2;
131 if (*BufferSize
< StringSize
) {
132 *BufferSize
= StringSize
;
133 return EFI_BUFFER_TOO_SMALL
;
136 for (Index
= 0; Index
< AsciiStrLen (StringSrc
); Index
++) {
137 StringDest
[Index
] = (CHAR16
) StringSrc
[Index
];
140 StringDest
[Index
] = 0;
146 Calculate the size of StringSrc and output it. If StringDest is not NULL,
147 copy string text from src to dest.
149 @param StringSrc Points to current null-terminated string.
150 @param StringDest Buffer to store the string text.
151 @param BufferSize Length of the buffer.
153 @retval EFI_SUCCESS The string text was outputed successfully.
154 @retval EFI_BUFFER_TOO_SMALL Buffer is insufficient to store the found string
155 text. BufferSize is updated to the required buffer
161 GetUnicodeStringTextOrSize (
162 OUT EFI_STRING StringDest
, OPTIONAL
164 IN OUT UINTN
*BufferSize
171 ASSERT (StringSrc
!= NULL
&& BufferSize
!= NULL
);
173 ZeroMem (&Zero
, sizeof (CHAR16
));
174 StringSize
= sizeof (CHAR16
);
175 StringPtr
= StringSrc
;
176 while (CompareMem (StringPtr
, &Zero
, sizeof (CHAR16
)) != 0) {
177 StringSize
+= sizeof (CHAR16
);
178 StringPtr
+= sizeof (CHAR16
);
181 if (*BufferSize
< StringSize
) {
182 *BufferSize
= StringSize
;
183 return EFI_BUFFER_TOO_SMALL
;
185 if (StringDest
!= NULL
) {
186 CopyMem (StringDest
, StringSrc
, StringSize
);
189 *BufferSize
= StringSize
;
195 Copy string font info to a buffer.
197 @param StringPackage Hii string package instance.
198 @param FontId Font identifier which is unique in a string
200 @param StringFontInfo Buffer to record the output font info. It's
201 caller's responsibility to free this buffer.
203 @retval EFI_SUCCESS The string font is outputed successfully.
204 @retval EFI_NOT_FOUND The specified font id does not exist.
210 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
212 OUT EFI_FONT_INFO
**StringFontInfo
216 HII_FONT_INFO
*FontInfo
;
217 HII_GLOBAL_FONT_INFO
*GlobalFont
;
219 ASSERT (StringFontInfo
!= NULL
&& StringPackage
!= NULL
);
221 for (Link
= StringPackage
->FontInfoList
.ForwardLink
; Link
!= &StringPackage
->FontInfoList
; Link
= Link
->ForwardLink
) {
222 FontInfo
= CR (Link
, HII_FONT_INFO
, Entry
, HII_FONT_INFO_SIGNATURE
);
223 if (FontInfo
->FontId
== FontId
) {
224 GlobalFont
= CR (FontInfo
->GlobalEntry
, HII_GLOBAL_FONT_INFO
, Entry
, HII_GLOBAL_FONT_INFO_SIGNATURE
);
225 *StringFontInfo
= (EFI_FONT_INFO
*) AllocateZeroPool (GlobalFont
->FontInfoSize
);
226 if (*StringFontInfo
== NULL
) {
227 return EFI_OUT_OF_RESOURCES
;
229 CopyMem (*StringFontInfo
, GlobalFont
->FontInfo
, GlobalFont
->FontInfoSize
);
234 return EFI_NOT_FOUND
;
239 Parse all string blocks to find a String block specified by StringId.
240 If StringId = (EFI_STRING_ID) (-1), find out all EFI_HII_SIBT_FONT blocks
241 within this string package and backup its information.
242 If StringId = 0, output the string id of last string block (EFI_HII_SIBT_END).
244 @param Private Hii database private structure.
245 @param StringPackage Hii string package instance.
246 @param StringId The string's id, which is unique within
248 @param BlockType Output the block type of found string block.
249 @param StringBlockAddr Output the block address of found string block.
250 @param StringTextOffset Offset, relative to the found block address, of
251 the string text information.
252 @param LastStringId Output the last string id when StringId = 0.
254 @retval EFI_SUCCESS The string text and font is retrieved
256 @retval EFI_NOT_FOUND The specified text or font info can not be found
258 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
264 IN HII_DATABASE_PRIVATE_DATA
*Private
,
265 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
266 IN EFI_STRING_ID StringId
,
267 OUT UINT8
*BlockType
, OPTIONAL
268 OUT UINT8
**StringBlockAddr
, OPTIONAL
269 OUT UINTN
*StringTextOffset
, OPTIONAL
270 OUT EFI_STRING_ID
*LastStringId OPTIONAL
274 EFI_STRING_ID CurrentStringId
;
277 UINT8
*StringTextPtr
;
279 HII_FONT_INFO
*LocalFont
;
280 EFI_FONT_INFO
*FontInfo
;
281 HII_GLOBAL_FONT_INFO
*GlobalFont
;
285 EFI_HII_FONT_STYLE FontStyle
;
288 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
294 ASSERT (StringPackage
!= NULL
);
295 ASSERT (StringPackage
->Signature
== HII_STRING_PACKAGE_SIGNATURE
);
299 if (StringId
!= (EFI_STRING_ID
) (-1) && StringId
!= 0) {
300 ASSERT (BlockType
!= NULL
&& StringBlockAddr
!= NULL
&& StringTextOffset
!= NULL
);
302 ASSERT (Private
!= NULL
&& Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
305 ZeroMem (&Zero
, sizeof (CHAR16
));
308 // Parse the string blocks to get the string text and font.
310 BlockHdr
= StringPackage
->StringBlock
;
313 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
315 case EFI_HII_SIBT_STRING_SCSU
:
316 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
317 StringTextPtr
= BlockHdr
+ Offset
;
318 BlockSize
+= Offset
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
322 case EFI_HII_SIBT_STRING_SCSU_FONT
:
323 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
324 StringTextPtr
= BlockHdr
+ Offset
;
325 BlockSize
+= Offset
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
329 case EFI_HII_SIBT_STRINGS_SCSU
:
330 CopyMem (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
331 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
);
332 BlockSize
+= StringTextPtr
- BlockHdr
;
334 for (Index
= 0; Index
< StringCount
; Index
++) {
335 BlockSize
+= AsciiStrSize ((CHAR8
*) StringTextPtr
);
336 if (CurrentStringId
== StringId
) {
337 *BlockType
= *BlockHdr
;
338 *StringBlockAddr
= BlockHdr
;
339 *StringTextOffset
= StringTextPtr
- BlockHdr
;
342 StringTextPtr
= StringTextPtr
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
347 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
350 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
353 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
354 BlockSize
+= StringTextPtr
- BlockHdr
;
356 for (Index
= 0; Index
< StringCount
; Index
++) {
357 BlockSize
+= AsciiStrSize ((CHAR8
*) StringTextPtr
);
358 if (CurrentStringId
== StringId
) {
359 *BlockType
= *BlockHdr
;
360 *StringBlockAddr
= BlockHdr
;
361 *StringTextOffset
= StringTextPtr
- BlockHdr
;
364 StringTextPtr
= StringTextPtr
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
369 case EFI_HII_SIBT_STRING_UCS2
:
370 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
371 StringTextPtr
= BlockHdr
+ Offset
;
373 // Use StringSize to store the size of the specified string, including the NULL
376 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
377 BlockSize
+= Offset
+ StringSize
;
381 case EFI_HII_SIBT_STRING_UCS2_FONT
:
382 Offset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
383 StringTextPtr
= BlockHdr
+ Offset
;
385 // Use StrSize to store the size of the specified string, including the NULL
388 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
389 BlockSize
+= Offset
+ StringSize
;
393 case EFI_HII_SIBT_STRINGS_UCS2
:
394 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK
) - sizeof (CHAR16
);
395 StringTextPtr
= BlockHdr
+ Offset
;
397 CopyMem (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
398 for (Index
= 0; Index
< StringCount
; Index
++) {
399 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
400 BlockSize
+= StringSize
;
401 if (CurrentStringId
== StringId
) {
402 *BlockType
= *BlockHdr
;
403 *StringBlockAddr
= BlockHdr
;
404 *StringTextOffset
= StringTextPtr
- BlockHdr
;
407 StringTextPtr
= StringTextPtr
+ StringSize
;
412 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
413 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
414 StringTextPtr
= BlockHdr
+ Offset
;
418 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
421 for (Index
= 0; Index
< StringCount
; Index
++) {
422 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
423 BlockSize
+= StringSize
;
424 if (CurrentStringId
== StringId
) {
425 *BlockType
= *BlockHdr
;
426 *StringBlockAddr
= BlockHdr
;
427 *StringTextOffset
= StringTextPtr
- BlockHdr
;
430 StringTextPtr
= StringTextPtr
+ StringSize
;
435 case EFI_HII_SIBT_DUPLICATE
:
436 if (CurrentStringId
== StringId
) {
438 // Incoming StringId is an id of a duplicate string block.
439 // Update the StringId to be the previous string block.
440 // Go back to the header of string block to search.
444 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
445 sizeof (EFI_STRING_ID
)
447 ASSERT (StringId
!= CurrentStringId
);
451 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
456 case EFI_HII_SIBT_SKIP1
:
457 SkipCount
= (UINT16
) (*(BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
458 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
459 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
462 case EFI_HII_SIBT_SKIP2
:
463 CopyMem (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
464 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
465 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
468 case EFI_HII_SIBT_EXT1
:
471 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
474 BlockSize
+= Length8
;
477 case EFI_HII_SIBT_EXT2
:
478 CopyMem (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
479 if (Ext2
.BlockType2
== EFI_HII_SIBT_FONT
&& StringId
== (EFI_STRING_ID
) (-1)) {
481 // Find the relationship between global font info and the font info of
482 // this EFI_HII_SIBT_FONT block then backup its information in local package.
484 BlockHdr
+= sizeof (EFI_HII_SIBT_EXT2_BLOCK
);
485 CopyMem (&FontId
, BlockHdr
, sizeof (UINT8
));
486 BlockHdr
+= sizeof (UINT8
);
487 CopyMem (&FontSize
, BlockHdr
, sizeof (UINT16
));
488 BlockHdr
+= sizeof (UINT16
);
489 CopyMem (&FontStyle
, BlockHdr
, sizeof (EFI_HII_FONT_STYLE
));
490 BlockHdr
+= sizeof (EFI_HII_FONT_STYLE
);
491 GetUnicodeStringTextOrSize (NULL
, BlockHdr
, &StringSize
);
493 FontInfoSize
= sizeof (EFI_FONT_INFO
) - sizeof (CHAR16
) + StringSize
;
494 FontInfo
= (EFI_FONT_INFO
*) AllocateZeroPool (FontInfoSize
);
495 if (FontInfo
== NULL
) {
496 return EFI_OUT_OF_RESOURCES
;
498 FontInfo
->FontStyle
= FontStyle
;
499 FontInfo
->FontSize
= FontSize
;
500 CopyMem (FontInfo
->FontName
, BlockHdr
, StringSize
);
503 // If find the corresponding global font info, save the relationship.
504 // Otherwise ignore this EFI_HII_SIBT_FONT block.
506 if (IsFontInfoExisted (Private
, FontInfo
, NULL
, NULL
, &GlobalFont
)) {
507 ReferFontInfoLocally (Private
, StringPackage
, FontId
, TRUE
, GlobalFont
, &LocalFont
);
511 // Since string package tool set FontId initially to 0 and increases it
512 // progressively by one, StringPackage->FondId always represents an unique
513 // and available FontId.
515 StringPackage
->FontId
++;
517 SafeFreePool (FontInfo
);
520 BlockSize
+= Ext2
.Length
;
524 case EFI_HII_SIBT_EXT4
:
527 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
531 BlockSize
+= Length32
;
539 if (StringId
== CurrentStringId
- 1) {
540 *BlockType
= *BlockHdr
;
541 *StringBlockAddr
= BlockHdr
;
542 *StringTextOffset
= Offset
;
546 if (StringId
< CurrentStringId
- 1) {
547 return EFI_NOT_FOUND
;
550 BlockHdr
= StringPackage
->StringBlock
+ BlockSize
;
554 if (StringId
== (EFI_STRING_ID
) (-1)) {
558 if (StringId
== 0 && LastStringId
!= NULL
) {
559 *LastStringId
= CurrentStringId
;
563 return EFI_NOT_FOUND
;
568 Parse all string blocks to get a string specified by StringId.
570 @param Private Hii database private structure.
571 @param StringPackage Hii string package instance.
572 @param StringId The string's id, which is unique within
574 @param String Points to retrieved null-terminated string.
575 @param StringSize On entry, points to the size of the buffer pointed
576 to by String, in bytes. On return, points to the
577 length of the string, in bytes.
578 @param StringFontInfo If not NULL, allocate a buffer to record the
579 output font info. It's caller's responsibility to
582 @retval EFI_SUCCESS The string text and font is retrieved
584 @retval EFI_NOT_FOUND The specified text or font info can not be found
586 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to
593 IN HII_DATABASE_PRIVATE_DATA
*Private
,
594 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
595 IN EFI_STRING_ID StringId
,
596 OUT EFI_STRING String
,
597 IN OUT UINTN
*StringSize
,
598 OUT EFI_FONT_INFO
**StringFontInfo OPTIONAL
601 UINT8
*StringTextPtr
;
603 UINT8
*StringBlockAddr
;
604 UINTN StringTextOffset
;
608 ASSERT (StringPackage
!= NULL
&& StringSize
!= NULL
);
609 ASSERT (Private
!= NULL
&& Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
612 // Find the specified string block
614 Status
= FindStringBlock (
623 if (EFI_ERROR (Status
)) {
628 // Get the string text.
630 StringTextPtr
= StringBlockAddr
+ StringTextOffset
;
632 case EFI_HII_SIBT_STRING_SCSU
:
633 case EFI_HII_SIBT_STRING_SCSU_FONT
:
634 case EFI_HII_SIBT_STRINGS_SCSU
:
635 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
636 Status
= ConvertToUnicodeText (String
, (CHAR8
*) StringTextPtr
, StringSize
);
638 case EFI_HII_SIBT_STRING_UCS2
:
639 case EFI_HII_SIBT_STRING_UCS2_FONT
:
640 case EFI_HII_SIBT_STRINGS_UCS2
:
641 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
642 Status
= GetUnicodeStringTextOrSize (String
, StringTextPtr
, StringSize
);
645 return EFI_NOT_FOUND
;
647 if (EFI_ERROR (Status
)) {
652 // Get the string font. The FontId 0 is the default font for those string blocks which
653 // do not specify a font identifier. If default font is not specified, return NULL.
655 if (StringFontInfo
!= NULL
) {
657 case EFI_HII_SIBT_STRING_SCSU_FONT
:
658 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
659 case EFI_HII_SIBT_STRING_UCS2_FONT
:
660 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
661 FontId
= *(StringBlockAddr
+ sizeof (EFI_HII_STRING_BLOCK
));
666 Status
= GetStringFontInfo (StringPackage
, FontId
, StringFontInfo
);
667 if (Status
== EFI_NOT_FOUND
) {
668 *StringFontInfo
= NULL
;
677 Parse all string blocks to set a String specified by StringId.
679 @param Private HII database driver private structure.
680 @param StringPackage HII string package instance.
681 @param StringId The string's id, which is unique within
683 @param String Points to the new null-terminated string.
684 @param StringFontInfo Points to the input font info.
686 @retval EFI_SUCCESS The string was updated successfully.
687 @retval EFI_NOT_FOUND The string specified by StringId is not in the
689 @retval EFI_INVALID_PARAMETER The String or Language was NULL.
690 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
692 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
699 IN HII_DATABASE_PRIVATE_DATA
*Private
,
700 IN OUT HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
701 IN EFI_STRING_ID StringId
,
702 IN EFI_STRING String
,
703 IN EFI_FONT_INFO
*StringFontInfo OPTIONAL
706 UINT8
*StringTextPtr
;
708 UINT8
*StringBlockAddr
;
709 UINTN StringTextOffset
;
715 HII_FONT_INFO
*LocalFont
;
716 HII_GLOBAL_FONT_INFO
*GlobalFont
;
718 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
723 ASSERT (Private
!= NULL
&& StringPackage
!= NULL
&& String
!= NULL
);
724 ASSERT (Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
726 // Find the specified string block
728 Status
= FindStringBlock (
737 if (EFI_ERROR (Status
)) {
746 // The input StringFontInfo should exist in current database if specified.
748 if (StringFontInfo
!= NULL
) {
749 if (!IsFontInfoExisted (Private
, StringFontInfo
, NULL
, NULL
, &GlobalFont
)) {
750 return EFI_INVALID_PARAMETER
;
752 Referred
= ReferFontInfoLocally (
755 StringPackage
->FontId
,
761 StringPackage
->FontId
++;
765 // Update the FontId of the specified string block to input font info.
768 case EFI_HII_SIBT_STRING_SCSU_FONT
:
769 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
770 case EFI_HII_SIBT_STRING_UCS2_FONT
:
771 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
772 *(StringBlockAddr
+ sizeof (EFI_HII_STRING_BLOCK
)) = LocalFont
->FontId
;
776 // When modify the font info of these blocks, the block type should be updated
777 // to contain font info thus the whole structure should be revised.
778 // It is recommended to use tool to modify the block type not in the code.
780 return EFI_UNSUPPORTED
;
784 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
787 // Set the string text and font.
789 StringTextPtr
= StringBlockAddr
+ StringTextOffset
;
791 case EFI_HII_SIBT_STRING_SCSU
:
792 case EFI_HII_SIBT_STRING_SCSU_FONT
:
793 case EFI_HII_SIBT_STRINGS_SCSU
:
794 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
795 BlockSize
= OldBlockSize
+ StrLen (String
);
796 BlockSize
-= AsciiStrLen ((CHAR8
*) StringTextPtr
);
797 Block
= AllocateZeroPool (BlockSize
);
799 return EFI_OUT_OF_RESOURCES
;
802 CopyMem (Block
, StringPackage
->StringBlock
, StringTextPtr
- StringPackage
->StringBlock
);
803 BlockPtr
= Block
+ (StringTextPtr
- StringPackage
->StringBlock
);
805 while (*String
!= 0) {
806 *BlockPtr
++ = (CHAR8
) *String
++;
811 TmpSize
= OldBlockSize
- (StringTextPtr
- StringPackage
->StringBlock
) - AsciiStrSize ((CHAR8
*) StringTextPtr
);
814 StringTextPtr
+ AsciiStrSize ((CHAR8
*)StringTextPtr
),
818 SafeFreePool (StringPackage
->StringBlock
);
819 StringPackage
->StringBlock
= Block
;
820 StringPackage
->StringPkgHdr
->Header
.Length
+= (UINT32
) (BlockSize
- OldBlockSize
);
823 case EFI_HII_SIBT_STRING_UCS2
:
824 case EFI_HII_SIBT_STRING_UCS2_FONT
:
825 case EFI_HII_SIBT_STRINGS_UCS2
:
826 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
828 // Use StrSize to store the size of the specified string, including the NULL
831 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
833 BlockSize
= OldBlockSize
+ StrSize (String
) - StringSize
;
834 Block
= AllocateZeroPool (BlockSize
);
836 return EFI_OUT_OF_RESOURCES
;
839 CopyMem (Block
, StringPackage
->StringBlock
, StringTextPtr
- StringPackage
->StringBlock
);
840 BlockPtr
= Block
+ (StringTextPtr
- StringPackage
->StringBlock
);
842 CopyMem (BlockPtr
, String
, StrSize (String
));
843 BlockPtr
+= StrSize (String
);
847 StringTextPtr
+ StringSize
,
848 OldBlockSize
- (StringTextPtr
- StringPackage
->StringBlock
) - StringSize
851 SafeFreePool (StringPackage
->StringBlock
);
852 StringPackage
->StringBlock
= Block
;
853 StringPackage
->StringPkgHdr
->Header
.Length
+= (UINT32
) (BlockSize
- OldBlockSize
);
857 return EFI_NOT_FOUND
;
861 // Insert a new EFI_HII_SIBT_FONT_BLOCK to the header of string block, if incoming
862 // StringFontInfo does not exist in current string package.
864 // This new block does not impact on the value of StringId.
867 if (StringFontInfo
== NULL
|| Referred
) {
871 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
872 BlockSize
= OldBlockSize
+ sizeof (EFI_HII_SIBT_FONT_BLOCK
) - sizeof (CHAR16
) +
873 StrSize (GlobalFont
->FontInfo
->FontName
);
875 Block
= AllocateZeroPool (BlockSize
);
877 return EFI_OUT_OF_RESOURCES
;
881 Ext2
.Header
.BlockType
= EFI_HII_SIBT_EXT2
;
882 Ext2
.BlockType2
= EFI_HII_SIBT_FONT
;
883 Ext2
.Length
= (UINT16
) (BlockSize
- OldBlockSize
);
884 CopyMem (BlockPtr
, &Ext2
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
885 BlockPtr
+= sizeof (EFI_HII_SIBT_EXT2_BLOCK
);
887 *BlockPtr
= LocalFont
->FontId
;
888 BlockPtr
+= sizeof (UINT8
);
889 CopyMem (BlockPtr
, &GlobalFont
->FontInfo
->FontSize
, sizeof (UINT16
));
890 BlockPtr
+= sizeof (UINT16
);
891 CopyMem (BlockPtr
, &GlobalFont
->FontInfo
->FontStyle
, sizeof (UINT32
));
892 BlockPtr
+= sizeof (UINT32
);
895 GlobalFont
->FontInfo
->FontName
,
896 StrSize (GlobalFont
->FontInfo
->FontName
)
898 BlockPtr
+= StrSize (GlobalFont
->FontInfo
->FontName
);
900 CopyMem (BlockPtr
, StringPackage
->StringBlock
, OldBlockSize
);
902 SafeFreePool (StringPackage
->StringBlock
);
903 StringPackage
->StringBlock
= Block
;
904 StringPackage
->StringPkgHdr
->Header
.Length
+= Ext2
.Length
;
912 This function adds the string String to the group of strings owned by PackageList, with the
913 specified font information StringFontInfo and returns a new string id.
915 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
916 @param PackageList Handle of the package list where this string will
918 @param StringId On return, contains the new strings id, which is
919 unique within PackageList.
920 @param Language Points to the language for the new string.
921 @param LanguageName Points to the printable language name to associate
922 with the passed in Language field.If LanguageName
923 is not NULL and the string package header's
924 LanguageName associated with a given Language is
925 not zero, the LanguageName being passed in will
927 @param String Points to the new null-terminated string.
928 @param StringFontInfo Points to the new string's font information or
929 NULL if the string should have the default system
930 font, size and style.
932 @retval EFI_SUCCESS The new string was added successfully.
933 @retval EFI_NOT_FOUND The specified PackageList could not be found in
935 @retval EFI_OUT_OF_RESOURCES Could not add the string due to lack of resources.
936 @retval EFI_INVALID_PARAMETER String is NULL or StringId is NULL or Language is
938 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
945 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
946 IN EFI_HII_HANDLE PackageList
,
947 OUT EFI_STRING_ID
*StringId
,
948 IN CONST CHAR8
*Language
,
949 IN CONST CHAR16
*LanguageName
, OPTIONAL
950 IN CONST EFI_STRING String
,
951 IN CONST EFI_FONT_INFO
*StringFontInfo OPTIONAL
957 HII_DATABASE_PRIVATE_DATA
*Private
;
958 HII_DATABASE_RECORD
*DatabaseRecord
;
959 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
960 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
966 UINT32 Ucs2BlockSize
;
967 UINT32 FontBlockSize
;
968 UINT32 Ucs2FontBlockSize
;
969 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
970 HII_FONT_INFO
*LocalFont
;
971 HII_GLOBAL_FONT_INFO
*GlobalFont
;
973 if (This
== NULL
|| String
== NULL
|| StringId
== NULL
|| Language
== NULL
|| PackageList
== NULL
) {
974 return EFI_INVALID_PARAMETER
;
977 if (!IsHiiHandleValid (PackageList
)) {
978 return EFI_NOT_FOUND
;
981 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
985 // If StringFontInfo specify a paritcular font, it should exist in current database.
987 if (StringFontInfo
!= NULL
) {
988 if (!IsFontInfoExisted (Private
, (EFI_FONT_INFO
*) StringFontInfo
, NULL
, NULL
, &GlobalFont
)) {
989 return EFI_INVALID_PARAMETER
;
994 // Get the matching package list.
996 PackageListNode
= NULL
;
997 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
998 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
999 if (DatabaseRecord
->Handle
== PackageList
) {
1000 PackageListNode
= DatabaseRecord
->PackageList
;
1004 if (PackageListNode
== NULL
) {
1005 return EFI_NOT_FOUND
;
1009 // Try to get the matching string package. Create a new string package when failed.
1011 StringPackage
= NULL
;
1013 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1014 Link
!= &PackageListNode
->StringPkgHdr
;
1015 Link
= Link
->ForwardLink
1017 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1018 if (R8_EfiLibCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
)) {
1026 // LanguageName is required to create a new string package.
1028 if (LanguageName
== NULL
) {
1029 return EFI_INVALID_PARAMETER
;
1032 StringPackage
= AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE
));
1033 if (StringPackage
== NULL
) {
1034 return EFI_OUT_OF_RESOURCES
;
1037 StringPackage
->Signature
= HII_STRING_PACKAGE_SIGNATURE
;
1038 StringPackage
->FontId
= 0;
1039 InitializeListHead (&StringPackage
->FontInfoList
);
1042 // Fill in the string package header
1044 HeaderSize
= (UINT32
) (AsciiStrSize ((CHAR8
*) Language
) - 1 + sizeof (EFI_HII_STRING_PACKAGE_HDR
));
1045 StringPackage
->StringPkgHdr
= AllocateZeroPool (HeaderSize
);
1046 if (StringPackage
->StringPkgHdr
== NULL
) {
1047 SafeFreePool (StringPackage
);
1048 return EFI_OUT_OF_RESOURCES
;
1050 StringPackage
->StringPkgHdr
->Header
.Type
= EFI_HII_PACKAGE_STRINGS
;
1051 StringPackage
->StringPkgHdr
->HdrSize
= HeaderSize
;
1052 StringPackage
->StringPkgHdr
->StringInfoOffset
= HeaderSize
;
1053 CopyMem (StringPackage
->StringPkgHdr
->LanguageWindow
, mLanguageWindow
, 16 * sizeof (CHAR16
));;
1054 StringPackage
->StringPkgHdr
->LanguageName
= 1;
1055 AsciiStrCpy (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
);
1058 // Calculate the length of the string blocks, including string block to record
1059 // printable language full name and EFI_HII_SIBT_END_BLOCK.
1061 Ucs2BlockSize
= (UINT32
) (StrSize ((CHAR16
*) LanguageName
) +
1062 sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
) - sizeof (CHAR16
));
1064 BlockSize
= Ucs2BlockSize
+ sizeof (EFI_HII_SIBT_END_BLOCK
);
1065 StringPackage
->StringBlock
= (UINT8
*) AllocateZeroPool (BlockSize
);
1066 if (StringPackage
->StringBlock
== NULL
) {
1067 SafeFreePool (StringPackage
->StringPkgHdr
);
1068 SafeFreePool (StringPackage
);
1069 return EFI_OUT_OF_RESOURCES
;
1073 // Insert the string block of printable language full name
1075 BlockPtr
= StringPackage
->StringBlock
;
1076 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
1077 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1078 CopyMem (BlockPtr
, (EFI_STRING
) LanguageName
, StrSize ((EFI_STRING
) LanguageName
));
1079 BlockPtr
+= StrSize ((EFI_STRING
) LanguageName
);
1082 // Insert the end block
1084 *BlockPtr
= EFI_HII_SIBT_END
;
1087 // Append this string package node to string package array in this package list.
1089 StringPackage
->StringPkgHdr
->Header
.Length
= HeaderSize
+ BlockSize
;
1090 PackageListNode
->PackageListHdr
.PackageLength
+= StringPackage
->StringPkgHdr
->Header
.Length
;
1091 InsertTailList (&PackageListNode
->StringPkgHdr
, &StringPackage
->StringEntry
);
1096 // Create a string block and corresponding font block if exists, then append them
1097 // to the end of the string package.
1099 Status
= FindStringBlock (
1108 if (EFI_ERROR (Status
)) {
1112 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
1114 if (StringFontInfo
== NULL
) {
1116 // Create a EFI_HII_SIBT_STRING_UCS2_BLOCK since font info is not specified.
1119 Ucs2BlockSize
= (UINT32
) (StrSize (String
) + sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
)
1122 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ Ucs2BlockSize
);
1123 if (StringBlock
== NULL
) {
1124 return EFI_OUT_OF_RESOURCES
;
1127 // Copy original string blocks, except the EFI_HII_SIBT_END.
1129 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1131 // Create a EFI_HII_SIBT_STRING_UCS2 block
1133 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1134 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
1135 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1136 CopyMem (BlockPtr
, (EFI_STRING
) String
, StrSize ((EFI_STRING
) String
));
1137 BlockPtr
+= StrSize ((EFI_STRING
) String
);
1140 // Append a EFI_HII_SIBT_END block to the end.
1142 *BlockPtr
= EFI_HII_SIBT_END
;
1143 SafeFreePool (StringPackage
->StringBlock
);
1144 StringPackage
->StringBlock
= StringBlock
;
1145 StringPackage
->StringPkgHdr
->Header
.Length
+= Ucs2BlockSize
;
1146 PackageListNode
->PackageListHdr
.PackageLength
+= Ucs2BlockSize
;
1150 // StringFontInfo is specified here. If there is a EFI_HII_SIBT_FONT_BLOCK
1151 // which refers to this font info, create a EFI_HII_SIBT_STRING_UCS2_FONT block
1152 // only. Otherwise create a EFI_HII_SIBT_FONT block with a EFI_HII_SIBT_STRING
1153 // _UCS2_FONT block.
1155 Ucs2FontBlockSize
= (UINT32
) (StrSize (String
) + sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) -
1157 if (ReferFontInfoLocally (Private
, StringPackage
, StringPackage
->FontId
, FALSE
, GlobalFont
, &LocalFont
)) {
1159 // Create a EFI_HII_SIBT_STRING_UCS2_FONT block only.
1161 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ Ucs2FontBlockSize
);
1162 if (StringBlock
== NULL
) {
1163 return EFI_OUT_OF_RESOURCES
;
1166 // Copy original string blocks, except the EFI_HII_SIBT_END.
1168 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1170 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
1172 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1173 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2_FONT
;
1174 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1175 *BlockPtr
= LocalFont
->FontId
;
1176 BlockPtr
+= sizeof (UINT8
);
1177 CopyMem (BlockPtr
, (EFI_STRING
) String
, StrSize ((EFI_STRING
) String
));
1178 BlockPtr
+= StrSize ((EFI_STRING
) String
);
1181 // Append a EFI_HII_SIBT_END block to the end.
1183 *BlockPtr
= EFI_HII_SIBT_END
;
1184 SafeFreePool (StringPackage
->StringBlock
);
1185 StringPackage
->StringBlock
= StringBlock
;
1186 StringPackage
->StringPkgHdr
->Header
.Length
+= Ucs2FontBlockSize
;
1187 PackageListNode
->PackageListHdr
.PackageLength
+= Ucs2FontBlockSize
;
1191 // EFI_HII_SIBT_FONT_BLOCK does not exist in current string package, so
1192 // create a EFI_HII_SIBT_FONT block to record the font info, then generate
1193 // a EFI_HII_SIBT_STRING_UCS2_FONT block to record the incoming string.
1195 FontBlockSize
= (UINT32
) (StrSize (((EFI_FONT_INFO
*) StringFontInfo
)->FontName
) +
1196 sizeof (EFI_HII_SIBT_FONT_BLOCK
) - sizeof (CHAR16
));
1197 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ FontBlockSize
+ Ucs2FontBlockSize
);
1198 if (StringBlock
== NULL
) {
1199 return EFI_OUT_OF_RESOURCES
;
1202 // Copy original string blocks, except the EFI_HII_SIBT_END.
1204 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1207 // Create a EFI_HII_SIBT_FONT block firstly and then backup its info in string
1208 // package instance for future reference.
1210 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1212 Ext2
.Header
.BlockType
= EFI_HII_SIBT_EXT2
;
1213 Ext2
.BlockType2
= EFI_HII_SIBT_FONT
;
1214 Ext2
.Length
= (UINT16
) FontBlockSize
;
1215 CopyMem (BlockPtr
, &Ext2
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
1216 BlockPtr
+= sizeof (EFI_HII_SIBT_EXT2_BLOCK
);
1218 *BlockPtr
= LocalFont
->FontId
;
1219 BlockPtr
+= sizeof (UINT8
);
1220 CopyMem (BlockPtr
, &((EFI_FONT_INFO
*) StringFontInfo
)->FontSize
, sizeof (UINT16
));
1221 BlockPtr
+= sizeof (UINT16
);
1222 CopyMem (BlockPtr
, &((EFI_FONT_INFO
*) StringFontInfo
)->FontStyle
, sizeof (EFI_HII_FONT_STYLE
));
1223 BlockPtr
+= sizeof (EFI_HII_FONT_STYLE
);
1226 &((EFI_FONT_INFO
*) StringFontInfo
)->FontName
,
1227 StrSize (((EFI_FONT_INFO
*) StringFontInfo
)->FontName
)
1231 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
1233 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2_FONT
;
1234 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1235 *BlockPtr
= LocalFont
->FontId
;
1236 BlockPtr
+= sizeof (UINT8
);
1237 CopyMem (BlockPtr
, (EFI_STRING
) String
, StrSize ((EFI_STRING
) String
));
1238 BlockPtr
+= StrSize ((EFI_STRING
) String
);
1241 // Append a EFI_HII_SIBT_END block to the end.
1243 *BlockPtr
= EFI_HII_SIBT_END
;
1244 SafeFreePool (StringPackage
->StringBlock
);
1245 StringPackage
->StringBlock
= StringBlock
;
1246 StringPackage
->StringPkgHdr
->Header
.Length
+= FontBlockSize
+ Ucs2FontBlockSize
;
1247 PackageListNode
->PackageListHdr
.PackageLength
+= FontBlockSize
+ Ucs2FontBlockSize
;
1250 // Increase the FontId to make it unique since we already add
1251 // a EFI_HII_SIBT_FONT block to this string package.
1253 StringPackage
->FontId
++;
1262 This function retrieves the string specified by StringId which is associated
1263 with the specified PackageList in the language Language and copies it into
1264 the buffer specified by String.
1266 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1267 @param Language Points to the language for the retrieved string.
1268 @param PackageList The package list in the HII database to search for
1269 the specified string.
1270 @param StringId The string's id, which is unique within
1272 @param String Points to the new null-terminated string.
1273 @param StringSize On entry, points to the size of the buffer pointed
1274 to by String, in bytes. On return, points to the
1275 length of the string, in bytes.
1276 @param StringFontInfo If not NULL, points to the string's font
1277 information. It's caller's responsibility to free
1280 @retval EFI_SUCCESS The string was returned successfully.
1281 @retval EFI_NOT_FOUND The string specified by StringId is not available.
1282 @retval EFI_NOT_FOUND The string specified by StringId is available but
1283 not in the specified language.
1284 The specified PackageList is not in the database.
1285 @retval EFI_INVALID_LANGUAGE - The string specified by StringId is available but
1286 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to
1288 @retval EFI_INVALID_PARAMETER The String or Language or StringSize was NULL.
1289 @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the
1296 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1297 IN CONST CHAR8
*Language
,
1298 IN EFI_HII_HANDLE PackageList
,
1299 IN EFI_STRING_ID StringId
,
1300 OUT EFI_STRING String
,
1301 IN OUT UINTN
*StringSize
,
1302 OUT EFI_FONT_INFO
**StringFontInfo OPTIONAL
1307 HII_DATABASE_PRIVATE_DATA
*Private
;
1308 HII_DATABASE_RECORD
*DatabaseRecord
;
1309 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1310 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1312 if (This
== NULL
|| Language
== NULL
|| StringId
< 1 || StringSize
== NULL
|| PackageList
== NULL
) {
1313 return EFI_INVALID_PARAMETER
;
1316 if (String
== NULL
&& *StringSize
!= 0) {
1317 return EFI_INVALID_PARAMETER
;
1320 if (!IsHiiHandleValid (PackageList
)) {
1321 return EFI_NOT_FOUND
;
1324 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1325 PackageListNode
= NULL
;
1327 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1328 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1329 if (DatabaseRecord
->Handle
== PackageList
) {
1330 PackageListNode
= DatabaseRecord
->PackageList
;
1335 if (PackageListNode
!= NULL
) {
1337 // First search: to match the StringId in the specified language.
1339 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1340 Link
!= &PackageListNode
->StringPkgHdr
;
1341 Link
= Link
->ForwardLink
1343 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1344 if (R8_EfiLibCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
)) {
1345 Status
= GetStringWorker (Private
, StringPackage
, StringId
, String
, StringSize
, StringFontInfo
);
1346 if (Status
!= EFI_NOT_FOUND
) {
1352 // Second search: to match the StringId in other available languages if exist.
1354 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1355 Link
!= &PackageListNode
->StringPkgHdr
;
1356 Link
= Link
->ForwardLink
1358 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1359 Status
= GetStringWorker (Private
, StringPackage
, StringId
, String
, StringSize
, StringFontInfo
);
1360 if (!EFI_ERROR (Status
)) {
1361 return EFI_INVALID_LANGUAGE
;
1366 return EFI_NOT_FOUND
;
1372 This function updates the string specified by StringId in the specified PackageList to the text
1373 specified by String and, optionally, the font information specified by StringFontInfo.
1375 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1376 @param PackageList The package list containing the strings.
1377 @param StringId The string's id, which is unique within
1379 @param Language Points to the language for the updated string.
1380 @param String Points to the new null-terminated string.
1381 @param StringFontInfo Points to the string's font information or NULL if
1382 the string font information is not changed.
1384 @retval EFI_SUCCESS The string was updated successfully.
1385 @retval EFI_NOT_FOUND The string specified by StringId is not in the
1387 @retval EFI_INVALID_PARAMETER The String or Language was NULL.
1388 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
1390 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
1397 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1398 IN EFI_HII_HANDLE PackageList
,
1399 IN EFI_STRING_ID StringId
,
1400 IN CONST CHAR8
*Language
,
1401 IN CONST EFI_STRING String
,
1402 IN CONST EFI_FONT_INFO
*StringFontInfo OPTIONAL
1407 HII_DATABASE_PRIVATE_DATA
*Private
;
1408 HII_DATABASE_RECORD
*DatabaseRecord
;
1409 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1410 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1411 UINT32 OldPackageLen
;
1413 if (This
== NULL
|| Language
== NULL
|| StringId
< 1 || String
== NULL
|| PackageList
== NULL
) {
1414 return EFI_INVALID_PARAMETER
;
1417 if (!IsHiiHandleValid (PackageList
)) {
1418 return EFI_NOT_FOUND
;
1421 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1422 PackageListNode
= NULL
;
1424 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1425 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1426 if (DatabaseRecord
->Handle
== PackageList
) {
1427 PackageListNode
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*) (DatabaseRecord
->PackageList
);
1431 if (PackageListNode
!= NULL
) {
1432 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1433 Link
!= &PackageListNode
->StringPkgHdr
;
1434 Link
= Link
->ForwardLink
1436 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1437 if (R8_EfiLibCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
)) {
1438 OldPackageLen
= StringPackage
->StringPkgHdr
->Header
.Length
;
1439 Status
= SetStringWorker (
1443 (EFI_STRING
) String
,
1444 (EFI_FONT_INFO
*) StringFontInfo
1446 if (EFI_ERROR (Status
)) {
1449 PackageListNode
->PackageListHdr
.PackageLength
+= StringPackage
->StringPkgHdr
->Header
.Length
- OldPackageLen
;
1455 return EFI_NOT_FOUND
;
1461 This function returns the list of supported languages, in the format specified
1462 in Appendix M of UEFI 2.1 spec.
1464 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1465 @param PackageList The package list to examine.
1466 @param Languages Points to the buffer to hold the returned string.
1467 @param LanguagesSize On entry, points to the size of the buffer pointed
1468 to by Languages, in bytes. On return, points to
1469 the length of Languages, in bytes.
1471 @retval EFI_SUCCESS The languages were returned successfully.
1472 @retval EFI_INVALID_PARAMETER The Languages or LanguagesSize was NULL.
1473 @retval EFI_BUFFER_TOO_SMALL The LanguagesSize is too small to hold the list of
1474 supported languages. LanguageSize is updated to
1475 contain the required size.
1476 @retval EFI_NOT_FOUND Could not find string package in specified
1483 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1484 IN EFI_HII_HANDLE PackageList
,
1485 IN OUT CHAR8
*Languages
,
1486 IN OUT UINTN
*LanguagesSize
1490 HII_DATABASE_PRIVATE_DATA
*Private
;
1491 HII_DATABASE_RECORD
*DatabaseRecord
;
1492 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1493 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1496 if (This
== NULL
|| Languages
== NULL
|| LanguagesSize
== NULL
|| PackageList
== NULL
) {
1497 return EFI_INVALID_PARAMETER
;
1499 if (!IsHiiHandleValid (PackageList
)) {
1500 return EFI_NOT_FOUND
;
1503 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1505 PackageListNode
= NULL
;
1506 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1507 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1508 if (DatabaseRecord
->Handle
== PackageList
) {
1509 PackageListNode
= DatabaseRecord
->PackageList
;
1513 if (PackageListNode
== NULL
) {
1514 return EFI_NOT_FOUND
;
1518 // Search the languages in the specified packagelist.
1521 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1522 Link
!= &PackageListNode
->StringPkgHdr
;
1523 Link
= Link
->ForwardLink
1525 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1526 ResultSize
+= AsciiStrSize (StringPackage
->StringPkgHdr
->Language
);
1527 if (ResultSize
< *LanguagesSize
) {
1528 AsciiStrCpy (Languages
, StringPackage
->StringPkgHdr
->Language
);
1529 Languages
+= AsciiStrSize (StringPackage
->StringPkgHdr
->Language
);
1530 *(Languages
- 1) = L
';';
1533 if (ResultSize
== 0) {
1534 return EFI_NOT_FOUND
;
1537 if (*LanguagesSize
< ResultSize
) {
1538 *LanguagesSize
= ResultSize
;
1539 return EFI_BUFFER_TOO_SMALL
;
1542 *(Languages
- 1) = 0;
1548 Each string package has associated with it a single primary language and zero
1549 or more secondary languages. This routine returns the secondary languages
1550 associated with a package list.
1552 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1553 @param PackageList The package list to examine.
1554 @param FirstLanguage Points to the primary language.
1555 @param SecondaryLanguages Points to the buffer to hold the returned list of
1556 secondary languages for the specified
1557 FirstLanguage. If there are no secondary
1558 languages, the function returns successfully, but
1559 this is set to NULL.
1560 @param SecondaryLanguageSize On entry, points to the size of the buffer pointed
1561 to by SecondLanguages, in bytes. On return,
1562 points to the length of SecondLanguages in bytes.
1564 @retval EFI_SUCCESS Secondary languages were correctly returned.
1565 @retval EFI_INVALID_PARAMETER FirstLanguage or SecondLanguages or
1566 SecondLanguagesSize was NULL.
1567 @retval EFI_BUFFER_TOO_SMALL The buffer specified by SecondLanguagesSize is
1568 too small to hold the returned information.
1569 SecondLanguageSize is updated to hold the size of
1570 the buffer required.
1571 @retval EFI_INVALID_LANGUAGE The language specified by FirstLanguage is not
1572 present in the specified package list.
1573 @retval EFI_NOT_FOUND The specified PackageList is not in the Database.
1578 HiiGetSecondaryLanguages (
1579 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1580 IN EFI_HII_HANDLE PackageList
,
1581 IN CONST CHAR8
*FirstLanguage
,
1582 IN OUT CHAR8
*SecondLanguages
,
1583 IN OUT UINTN
*SecondLanguagesSize
1588 HII_DATABASE_PRIVATE_DATA
*Private
;
1589 HII_DATABASE_RECORD
*DatabaseRecord
;
1590 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1591 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1595 if (This
== NULL
|| PackageList
== NULL
|| FirstLanguage
== NULL
) {
1596 return EFI_INVALID_PARAMETER
;
1598 if (SecondLanguages
== NULL
|| SecondLanguagesSize
== NULL
) {
1599 return EFI_INVALID_PARAMETER
;
1601 if (!IsHiiHandleValid (PackageList
)) {
1602 return EFI_NOT_FOUND
;
1605 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1607 PackageListNode
= NULL
;
1608 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1609 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1610 if (DatabaseRecord
->Handle
== PackageList
) {
1611 PackageListNode
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*) (DatabaseRecord
->PackageList
);
1615 if (PackageListNode
== NULL
) {
1616 return EFI_NOT_FOUND
;
1621 for (Link1
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1622 Link1
!= &PackageListNode
->StringPkgHdr
;
1623 Link1
= Link1
->ForwardLink
1625 StringPackage
= CR (Link1
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1626 if (R8_EfiLibCompareLanguage (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) FirstLanguage
)) {
1627 Languages
= StringPackage
->StringPkgHdr
->Language
;
1629 // Language is a series of ';' terminated strings, first one is primary
1630 // language and following with other secondary languages or NULL if no
1631 // secondary languages any more.
1633 Languages
= AsciiStrStr (Languages
, ";");
1634 if (Languages
== NULL
) {
1639 ResultSize
= AsciiStrSize (Languages
);
1640 if (ResultSize
<= *SecondLanguagesSize
) {
1641 AsciiStrCpy (SecondLanguages
, Languages
);
1643 *SecondLanguagesSize
= ResultSize
;
1644 return EFI_BUFFER_TOO_SMALL
;
1651 return EFI_INVALID_LANGUAGE
;