2 Implementation for EFI_HII_STRING_PROTOCOL.
5 Copyright (c) 2007, 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.
239 If StringId = 0, output the string id of last string block (EFI_HII_SIBT_END).
241 @param Private Hii database private structure.
242 @param StringPackage Hii string package instance.
243 @param StringId The string's id, which is unique within
245 @param BlockType Output the block type of found string block.
246 @param StringBlockAddr Output the block address of found string block.
247 @param StringTextOffset Offset, relative to the found block address, of
248 the string text information.
249 @param LastStringId Output the last string id when StringId = 0.
251 @retval EFI_SUCCESS The string text and font is retrieved
253 @retval EFI_NOT_FOUND The specified text or font info can not be found
255 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
261 IN HII_DATABASE_PRIVATE_DATA
*Private
,
262 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
263 IN EFI_STRING_ID StringId
,
264 OUT UINT8
*BlockType
, OPTIONAL
265 OUT UINT8
**StringBlockAddr
, OPTIONAL
266 OUT UINTN
*StringTextOffset
, OPTIONAL
267 OUT EFI_STRING_ID
*LastStringId OPTIONAL
271 EFI_STRING_ID CurrentStringId
;
274 UINT8
*StringTextPtr
;
276 HII_FONT_INFO
*LocalFont
;
277 EFI_FONT_INFO
*FontInfo
;
278 HII_GLOBAL_FONT_INFO
*GlobalFont
;
282 EFI_HII_FONT_STYLE FontStyle
;
285 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
291 ASSERT (StringPackage
!= NULL
);
292 ASSERT (StringPackage
->Signature
== HII_STRING_PACKAGE_SIGNATURE
);
296 if (StringId
!= (EFI_STRING_ID
) (-1) && StringId
!= 0) {
297 ASSERT (BlockType
!= NULL
&& StringBlockAddr
!= NULL
&& StringTextOffset
!= NULL
);
299 ASSERT (Private
!= NULL
&& Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
302 ZeroMem (&Zero
, sizeof (CHAR16
));
305 // Parse the string blocks to get the string text and font.
307 BlockHdr
= StringPackage
->StringBlock
;
310 while (*BlockHdr
!= EFI_HII_SIBT_END
) {
312 case EFI_HII_SIBT_STRING_SCSU
:
313 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
314 StringTextPtr
= BlockHdr
+ Offset
;
315 BlockSize
+= Offset
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
319 case EFI_HII_SIBT_STRING_SCSU_FONT
:
320 Offset
= sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
321 StringTextPtr
= BlockHdr
+ Offset
;
322 BlockSize
+= Offset
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
326 case EFI_HII_SIBT_STRINGS_SCSU
:
327 CopyMem (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
328 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK
) - sizeof (UINT8
);
329 BlockSize
+= StringTextPtr
- BlockHdr
;
331 for (Index
= 0; Index
< StringCount
; Index
++) {
332 BlockSize
+= AsciiStrSize ((CHAR8
*) StringTextPtr
);
333 if (CurrentStringId
== StringId
) {
334 *BlockType
= *BlockHdr
;
335 *StringBlockAddr
= BlockHdr
;
336 *StringTextOffset
= StringTextPtr
- BlockHdr
;
339 StringTextPtr
= StringTextPtr
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
344 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
347 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
350 StringTextPtr
= BlockHdr
+ sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
) - sizeof (UINT8
);
351 BlockSize
+= StringTextPtr
- BlockHdr
;
353 for (Index
= 0; Index
< StringCount
; Index
++) {
354 BlockSize
+= AsciiStrSize ((CHAR8
*) StringTextPtr
);
355 if (CurrentStringId
== StringId
) {
356 *BlockType
= *BlockHdr
;
357 *StringBlockAddr
= BlockHdr
;
358 *StringTextOffset
= StringTextPtr
- BlockHdr
;
361 StringTextPtr
= StringTextPtr
+ AsciiStrSize ((CHAR8
*) StringTextPtr
);
366 case EFI_HII_SIBT_STRING_UCS2
:
367 Offset
= sizeof (EFI_HII_STRING_BLOCK
);
368 StringTextPtr
= BlockHdr
+ Offset
;
370 // Use StringSize to store the size of the specified string, including the NULL
373 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
374 BlockSize
+= Offset
+ StringSize
;
378 case EFI_HII_SIBT_STRING_UCS2_FONT
:
379 Offset
= sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
380 StringTextPtr
= BlockHdr
+ Offset
;
382 // Use StrSize to store the size of the specified string, including the NULL
385 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
386 BlockSize
+= Offset
+ StringSize
;
390 case EFI_HII_SIBT_STRINGS_UCS2
:
391 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK
) - sizeof (CHAR16
);
392 StringTextPtr
= BlockHdr
+ Offset
;
394 CopyMem (&StringCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
395 for (Index
= 0; Index
< StringCount
; Index
++) {
396 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
397 BlockSize
+= StringSize
;
398 if (CurrentStringId
== StringId
) {
399 *BlockType
= *BlockHdr
;
400 *StringBlockAddr
= BlockHdr
;
401 *StringTextOffset
= StringTextPtr
- BlockHdr
;
404 StringTextPtr
= StringTextPtr
+ StringSize
;
409 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
410 Offset
= sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
) - sizeof (CHAR16
);
411 StringTextPtr
= BlockHdr
+ Offset
;
415 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
418 for (Index
= 0; Index
< StringCount
; Index
++) {
419 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
420 BlockSize
+= StringSize
;
421 if (CurrentStringId
== StringId
) {
422 *BlockType
= *BlockHdr
;
423 *StringBlockAddr
= BlockHdr
;
424 *StringTextOffset
= StringTextPtr
- BlockHdr
;
427 StringTextPtr
= StringTextPtr
+ StringSize
;
432 case EFI_HII_SIBT_DUPLICATE
:
433 if (CurrentStringId
== StringId
) {
435 // Incoming StringId is an id of a duplicate string block.
436 // Update the StringId to be the previous string block.
437 // Go back to the header of string block to search.
441 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
),
442 sizeof (EFI_STRING_ID
)
444 ASSERT (StringId
!= CurrentStringId
);
448 BlockSize
+= sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK
);
453 case EFI_HII_SIBT_SKIP1
:
454 SkipCount
= (UINT16
) (*(BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
)));
455 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
456 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP1_BLOCK
);
459 case EFI_HII_SIBT_SKIP2
:
460 CopyMem (&SkipCount
, BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
), sizeof (UINT16
));
461 CurrentStringId
= (UINT16
) (CurrentStringId
+ SkipCount
);
462 BlockSize
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
465 case EFI_HII_SIBT_EXT1
:
468 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
471 BlockSize
+= Length8
;
474 case EFI_HII_SIBT_EXT2
:
475 CopyMem (&Ext2
, BlockHdr
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
476 if (Ext2
.BlockType2
== EFI_HII_SIBT_FONT
&& StringId
== (EFI_STRING_ID
) (-1)) {
478 // Find the relationship between global font info and the font info of
479 // this EFI_HII_SIBT_FONT block then backup its information in local package.
481 BlockHdr
+= sizeof (EFI_HII_SIBT_EXT2_BLOCK
);
482 CopyMem (&FontId
, BlockHdr
, sizeof (UINT8
));
483 BlockHdr
+= sizeof (UINT8
);
484 CopyMem (&FontSize
, BlockHdr
, sizeof (UINT16
));
485 BlockHdr
+= sizeof (UINT16
);
486 CopyMem (&FontStyle
, BlockHdr
, sizeof (EFI_HII_FONT_STYLE
));
487 BlockHdr
+= sizeof (EFI_HII_FONT_STYLE
);
488 GetUnicodeStringTextOrSize (NULL
, BlockHdr
, &StringSize
);
490 FontInfoSize
= sizeof (EFI_FONT_INFO
) - sizeof (CHAR16
) + StringSize
;
491 FontInfo
= (EFI_FONT_INFO
*) AllocateZeroPool (FontInfoSize
);
492 if (FontInfo
== NULL
) {
493 return EFI_OUT_OF_RESOURCES
;
495 FontInfo
->FontStyle
= FontStyle
;
496 FontInfo
->FontSize
= FontSize
;
497 CopyMem (FontInfo
->FontName
, BlockHdr
, StringSize
);
500 // If find the corresponding global font info, save the relationship.
501 // Otherwise ignore this EFI_HII_SIBT_FONT block.
503 if (IsFontInfoExisted (Private
, FontInfo
, NULL
, NULL
, &GlobalFont
)) {
504 ReferFontInfoLocally (Private
, StringPackage
, FontId
, TRUE
, GlobalFont
, &LocalFont
);
508 // Since string package tool set FontId initially to 0 and increases it
509 // progressively by one, StringPackage->FondId always represents an unique
510 // and available FontId.
512 StringPackage
->FontId
++;
517 BlockSize
+= Ext2
.Length
;
521 case EFI_HII_SIBT_EXT4
:
524 BlockHdr
+ sizeof (EFI_HII_STRING_BLOCK
) + sizeof (UINT8
),
528 BlockSize
+= Length32
;
536 if (StringId
== CurrentStringId
- 1) {
537 *BlockType
= *BlockHdr
;
538 *StringBlockAddr
= BlockHdr
;
539 *StringTextOffset
= Offset
;
543 if (StringId
< CurrentStringId
- 1) {
544 return EFI_NOT_FOUND
;
547 BlockHdr
= StringPackage
->StringBlock
+ BlockSize
;
551 if (StringId
== (EFI_STRING_ID
) (-1)) {
555 if (StringId
== 0 && LastStringId
!= NULL
) {
556 *LastStringId
= CurrentStringId
;
560 return EFI_NOT_FOUND
;
565 Parse all string blocks to get a string specified by StringId.
567 This is a internal function.
569 @param Private Hii database private structure.
570 @param StringPackage Hii string package instance.
571 @param StringId The string's id, which is unique within
573 @param String Points to retrieved null-terminated string.
574 @param StringSize On entry, points to the size of the buffer pointed
575 to by String, in bytes. On return, points to the
576 length of the string, in bytes.
577 @param StringFontInfo If not NULL, allocate a buffer to record the
578 output font info. It's caller's responsibility to
581 @retval EFI_SUCCESS The string text and font is retrieved
583 @retval EFI_NOT_FOUND The specified text or font info can not be found
585 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to
591 IN HII_DATABASE_PRIVATE_DATA
*Private
,
592 IN HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
593 IN EFI_STRING_ID StringId
,
594 OUT EFI_STRING String
,
595 IN OUT UINTN
*StringSize
,
596 OUT EFI_FONT_INFO
**StringFontInfo OPTIONAL
599 UINT8
*StringTextPtr
;
601 UINT8
*StringBlockAddr
;
602 UINTN StringTextOffset
;
606 ASSERT (StringPackage
!= NULL
&& StringSize
!= NULL
);
607 ASSERT (Private
!= NULL
&& Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
610 // Find the specified string block
612 Status
= FindStringBlock (
621 if (EFI_ERROR (Status
)) {
626 // Get the string text.
628 StringTextPtr
= StringBlockAddr
+ StringTextOffset
;
630 case EFI_HII_SIBT_STRING_SCSU
:
631 case EFI_HII_SIBT_STRING_SCSU_FONT
:
632 case EFI_HII_SIBT_STRINGS_SCSU
:
633 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
634 Status
= ConvertToUnicodeText (String
, (CHAR8
*) StringTextPtr
, StringSize
);
636 case EFI_HII_SIBT_STRING_UCS2
:
637 case EFI_HII_SIBT_STRING_UCS2_FONT
:
638 case EFI_HII_SIBT_STRINGS_UCS2
:
639 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
640 Status
= GetUnicodeStringTextOrSize (String
, StringTextPtr
, StringSize
);
643 return EFI_NOT_FOUND
;
645 if (EFI_ERROR (Status
)) {
650 // Get the string font. The FontId 0 is the default font for those string blocks which
651 // do not specify a font identifier. If default font is not specified, return NULL.
653 if (StringFontInfo
!= NULL
) {
655 case EFI_HII_SIBT_STRING_SCSU_FONT
:
656 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
657 case EFI_HII_SIBT_STRING_UCS2_FONT
:
658 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
659 FontId
= *(StringBlockAddr
+ sizeof (EFI_HII_STRING_BLOCK
));
664 Status
= GetStringFontInfo (StringPackage
, FontId
, StringFontInfo
);
665 if (Status
== EFI_NOT_FOUND
) {
666 *StringFontInfo
= NULL
;
675 Parse all string blocks to set a String specified by StringId.
677 This is a internal function.
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
698 IN HII_DATABASE_PRIVATE_DATA
*Private
,
699 IN OUT HII_STRING_PACKAGE_INSTANCE
*StringPackage
,
700 IN EFI_STRING_ID StringId
,
701 IN EFI_STRING String
,
702 IN EFI_FONT_INFO
*StringFontInfo OPTIONAL
705 UINT8
*StringTextPtr
;
707 UINT8
*StringBlockAddr
;
708 UINTN StringTextOffset
;
714 HII_FONT_INFO
*LocalFont
;
715 HII_GLOBAL_FONT_INFO
*GlobalFont
;
717 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
722 ASSERT (Private
!= NULL
&& StringPackage
!= NULL
&& String
!= NULL
);
723 ASSERT (Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
725 // Find the specified string block
727 Status
= FindStringBlock (
736 if (EFI_ERROR (Status
)) {
745 // The input StringFontInfo should exist in current database if specified.
747 if (StringFontInfo
!= NULL
) {
748 if (!IsFontInfoExisted (Private
, StringFontInfo
, NULL
, NULL
, &GlobalFont
)) {
749 return EFI_INVALID_PARAMETER
;
751 Referred
= ReferFontInfoLocally (
754 StringPackage
->FontId
,
760 StringPackage
->FontId
++;
764 // Update the FontId of the specified string block to input font info.
767 case EFI_HII_SIBT_STRING_SCSU_FONT
:
768 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
769 case EFI_HII_SIBT_STRING_UCS2_FONT
:
770 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
771 *(StringBlockAddr
+ sizeof (EFI_HII_STRING_BLOCK
)) = LocalFont
->FontId
;
775 // When modify the font info of these blocks, the block type should be updated
776 // to contain font info thus the whole structure should be revised.
777 // It is recommended to use tool to modify the block type not in the code.
779 return EFI_UNSUPPORTED
;
783 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
786 // Set the string text and font.
788 StringTextPtr
= StringBlockAddr
+ StringTextOffset
;
790 case EFI_HII_SIBT_STRING_SCSU
:
791 case EFI_HII_SIBT_STRING_SCSU_FONT
:
792 case EFI_HII_SIBT_STRINGS_SCSU
:
793 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
794 BlockSize
= OldBlockSize
+ StrLen (String
);
795 BlockSize
-= AsciiStrLen ((CHAR8
*) StringTextPtr
);
796 Block
= AllocateZeroPool (BlockSize
);
798 return EFI_OUT_OF_RESOURCES
;
801 CopyMem (Block
, StringPackage
->StringBlock
, StringTextPtr
- StringPackage
->StringBlock
);
802 BlockPtr
= Block
+ (StringTextPtr
- StringPackage
->StringBlock
);
804 while (*String
!= 0) {
805 *BlockPtr
++ = (CHAR8
) *String
++;
810 TmpSize
= OldBlockSize
- (StringTextPtr
- StringPackage
->StringBlock
) - AsciiStrSize ((CHAR8
*) StringTextPtr
);
813 StringTextPtr
+ AsciiStrSize ((CHAR8
*)StringTextPtr
),
817 FreePool (StringPackage
->StringBlock
);
818 StringPackage
->StringBlock
= Block
;
819 StringPackage
->StringPkgHdr
->Header
.Length
+= (UINT32
) (BlockSize
- OldBlockSize
);
822 case EFI_HII_SIBT_STRING_UCS2
:
823 case EFI_HII_SIBT_STRING_UCS2_FONT
:
824 case EFI_HII_SIBT_STRINGS_UCS2
:
825 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
827 // Use StrSize to store the size of the specified string, including the NULL
830 GetUnicodeStringTextOrSize (NULL
, StringTextPtr
, &StringSize
);
832 BlockSize
= OldBlockSize
+ StrSize (String
) - StringSize
;
833 Block
= AllocateZeroPool (BlockSize
);
835 return EFI_OUT_OF_RESOURCES
;
838 CopyMem (Block
, StringPackage
->StringBlock
, StringTextPtr
- StringPackage
->StringBlock
);
839 BlockPtr
= Block
+ (StringTextPtr
- StringPackage
->StringBlock
);
841 CopyMem (BlockPtr
, String
, StrSize (String
));
842 BlockPtr
+= StrSize (String
);
846 StringTextPtr
+ StringSize
,
847 OldBlockSize
- (StringTextPtr
- StringPackage
->StringBlock
) - StringSize
850 FreePool (StringPackage
->StringBlock
);
851 StringPackage
->StringBlock
= Block
;
852 StringPackage
->StringPkgHdr
->Header
.Length
+= (UINT32
) (BlockSize
- OldBlockSize
);
856 return EFI_NOT_FOUND
;
860 // Insert a new EFI_HII_SIBT_FONT_BLOCK to the header of string block, if incoming
861 // StringFontInfo does not exist in current string package.
863 // This new block does not impact on the value of StringId.
866 if (StringFontInfo
== NULL
|| Referred
) {
870 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
871 BlockSize
= OldBlockSize
+ sizeof (EFI_HII_SIBT_FONT_BLOCK
) - sizeof (CHAR16
) +
872 StrSize (GlobalFont
->FontInfo
->FontName
);
874 Block
= AllocateZeroPool (BlockSize
);
876 return EFI_OUT_OF_RESOURCES
;
880 Ext2
.Header
.BlockType
= EFI_HII_SIBT_EXT2
;
881 Ext2
.BlockType2
= EFI_HII_SIBT_FONT
;
882 Ext2
.Length
= (UINT16
) (BlockSize
- OldBlockSize
);
883 CopyMem (BlockPtr
, &Ext2
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
884 BlockPtr
+= sizeof (EFI_HII_SIBT_EXT2_BLOCK
);
886 *BlockPtr
= LocalFont
->FontId
;
887 BlockPtr
+= sizeof (UINT8
);
888 CopyMem (BlockPtr
, &GlobalFont
->FontInfo
->FontSize
, sizeof (UINT16
));
889 BlockPtr
+= sizeof (UINT16
);
890 CopyMem (BlockPtr
, &GlobalFont
->FontInfo
->FontStyle
, sizeof (UINT32
));
891 BlockPtr
+= sizeof (UINT32
);
894 GlobalFont
->FontInfo
->FontName
,
895 StrSize (GlobalFont
->FontInfo
->FontName
)
897 BlockPtr
+= StrSize (GlobalFont
->FontInfo
->FontName
);
899 CopyMem (BlockPtr
, StringPackage
->StringBlock
, OldBlockSize
);
901 FreePool (StringPackage
->StringBlock
);
902 StringPackage
->StringBlock
= Block
;
903 StringPackage
->StringPkgHdr
->Header
.Length
+= Ext2
.Length
;
911 This function adds the string String to the group of strings owned by PackageList, with the
912 specified font information StringFontInfo and returns a new string id.
914 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
915 @param PackageList Handle of the package list where this string will
917 @param StringId On return, contains the new strings id, which is
918 unique within PackageList.
919 @param Language Points to the language for the new string.
920 @param LanguageName Points to the printable language name to associate
921 with the passed in Language field.If LanguageName
922 is not NULL and the string package header's
923 LanguageName associated with a given Language is
924 not zero, the LanguageName being passed in will
926 @param String Points to the new null-terminated string.
927 @param StringFontInfo Points to the new string's font information or
928 NULL if the string should have the default system
929 font, size and style.
931 @retval EFI_SUCCESS The new string was added successfully.
932 @retval EFI_NOT_FOUND The specified PackageList could not be found in
934 @retval EFI_OUT_OF_RESOURCES Could not add the string due to lack of resources.
935 @retval EFI_INVALID_PARAMETER String is NULL or StringId is NULL or Language is
937 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
944 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
945 IN EFI_HII_HANDLE PackageList
,
946 OUT EFI_STRING_ID
*StringId
,
947 IN CONST CHAR8
*Language
,
948 IN CONST CHAR16
*LanguageName
, OPTIONAL
949 IN CONST EFI_STRING String
,
950 IN CONST EFI_FONT_INFO
*StringFontInfo OPTIONAL
956 HII_DATABASE_PRIVATE_DATA
*Private
;
957 HII_DATABASE_RECORD
*DatabaseRecord
;
958 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
959 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
965 UINT32 Ucs2BlockSize
;
966 UINT32 FontBlockSize
;
967 UINT32 Ucs2FontBlockSize
;
968 EFI_HII_SIBT_EXT2_BLOCK Ext2
;
969 HII_FONT_INFO
*LocalFont
;
970 HII_GLOBAL_FONT_INFO
*GlobalFont
;
971 CHAR8
*MatchedLanguage
;
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 MatchedLanguage
= GetBestLanguage (StringPackage
->StringPkgHdr
->Language
, FALSE
, (CHAR8
*) Language
, NULL
);
1019 if (MatchedLanguage
!= NULL
) {
1020 FreePool (MatchedLanguage
);
1028 // LanguageName is required to create a new string package.
1030 if (LanguageName
== NULL
) {
1031 return EFI_INVALID_PARAMETER
;
1034 StringPackage
= AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE
));
1035 if (StringPackage
== NULL
) {
1036 return EFI_OUT_OF_RESOURCES
;
1039 StringPackage
->Signature
= HII_STRING_PACKAGE_SIGNATURE
;
1040 StringPackage
->FontId
= 0;
1041 InitializeListHead (&StringPackage
->FontInfoList
);
1044 // Fill in the string package header
1046 HeaderSize
= (UINT32
) (AsciiStrSize ((CHAR8
*) Language
) - 1 + sizeof (EFI_HII_STRING_PACKAGE_HDR
));
1047 StringPackage
->StringPkgHdr
= AllocateZeroPool (HeaderSize
);
1048 if (StringPackage
->StringPkgHdr
== NULL
) {
1049 FreePool (StringPackage
);
1050 return EFI_OUT_OF_RESOURCES
;
1052 StringPackage
->StringPkgHdr
->Header
.Type
= EFI_HII_PACKAGE_STRINGS
;
1053 StringPackage
->StringPkgHdr
->HdrSize
= HeaderSize
;
1054 StringPackage
->StringPkgHdr
->StringInfoOffset
= HeaderSize
;
1055 CopyMem (StringPackage
->StringPkgHdr
->LanguageWindow
, mLanguageWindow
, 16 * sizeof (CHAR16
));;
1056 StringPackage
->StringPkgHdr
->LanguageName
= 1;
1057 AsciiStrCpy (StringPackage
->StringPkgHdr
->Language
, (CHAR8
*) Language
);
1060 // Calculate the length of the string blocks, including string block to record
1061 // printable language full name and EFI_HII_SIBT_END_BLOCK.
1063 Ucs2BlockSize
= (UINT32
) (StrSize ((CHAR16
*) LanguageName
) +
1064 sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
) - sizeof (CHAR16
));
1066 BlockSize
= Ucs2BlockSize
+ sizeof (EFI_HII_SIBT_END_BLOCK
);
1067 StringPackage
->StringBlock
= (UINT8
*) AllocateZeroPool (BlockSize
);
1068 if (StringPackage
->StringBlock
== NULL
) {
1069 FreePool (StringPackage
->StringPkgHdr
);
1070 FreePool (StringPackage
);
1071 return EFI_OUT_OF_RESOURCES
;
1075 // Insert the string block of printable language full name
1077 BlockPtr
= StringPackage
->StringBlock
;
1078 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
1079 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1080 CopyMem (BlockPtr
, (EFI_STRING
) LanguageName
, StrSize ((EFI_STRING
) LanguageName
));
1081 BlockPtr
+= StrSize ((EFI_STRING
) LanguageName
);
1084 // Insert the end block
1086 *BlockPtr
= EFI_HII_SIBT_END
;
1089 // Append this string package node to string package array in this package list.
1091 StringPackage
->StringPkgHdr
->Header
.Length
= HeaderSize
+ BlockSize
;
1092 PackageListNode
->PackageListHdr
.PackageLength
+= StringPackage
->StringPkgHdr
->Header
.Length
;
1093 InsertTailList (&PackageListNode
->StringPkgHdr
, &StringPackage
->StringEntry
);
1098 // Create a string block and corresponding font block if exists, then append them
1099 // to the end of the string package.
1101 Status
= FindStringBlock (
1110 if (EFI_ERROR (Status
)) {
1114 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
1116 if (StringFontInfo
== NULL
) {
1118 // Create a EFI_HII_SIBT_STRING_UCS2_BLOCK since font info is not specified.
1121 Ucs2BlockSize
= (UINT32
) (StrSize (String
) + sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK
)
1124 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ Ucs2BlockSize
);
1125 if (StringBlock
== NULL
) {
1126 return EFI_OUT_OF_RESOURCES
;
1129 // Copy original string blocks, except the EFI_HII_SIBT_END.
1131 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1133 // Create a EFI_HII_SIBT_STRING_UCS2 block
1135 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1136 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2
;
1137 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1138 CopyMem (BlockPtr
, (EFI_STRING
) String
, StrSize ((EFI_STRING
) String
));
1139 BlockPtr
+= StrSize ((EFI_STRING
) String
);
1142 // Append a EFI_HII_SIBT_END block to the end.
1144 *BlockPtr
= EFI_HII_SIBT_END
;
1145 FreePool (StringPackage
->StringBlock
);
1146 StringPackage
->StringBlock
= StringBlock
;
1147 StringPackage
->StringPkgHdr
->Header
.Length
+= Ucs2BlockSize
;
1148 PackageListNode
->PackageListHdr
.PackageLength
+= Ucs2BlockSize
;
1152 // StringFontInfo is specified here. If there is a EFI_HII_SIBT_FONT_BLOCK
1153 // which refers to this font info, create a EFI_HII_SIBT_STRING_UCS2_FONT block
1154 // only. Otherwise create a EFI_HII_SIBT_FONT block with a EFI_HII_SIBT_STRING
1155 // _UCS2_FONT block.
1157 Ucs2FontBlockSize
= (UINT32
) (StrSize (String
) + sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
) -
1159 if (ReferFontInfoLocally (Private
, StringPackage
, StringPackage
->FontId
, FALSE
, GlobalFont
, &LocalFont
)) {
1161 // Create a EFI_HII_SIBT_STRING_UCS2_FONT block only.
1163 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ Ucs2FontBlockSize
);
1164 if (StringBlock
== NULL
) {
1165 return EFI_OUT_OF_RESOURCES
;
1168 // Copy original string blocks, except the EFI_HII_SIBT_END.
1170 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1172 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
1174 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1175 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2_FONT
;
1176 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1177 *BlockPtr
= LocalFont
->FontId
;
1178 BlockPtr
+= sizeof (UINT8
);
1179 CopyMem (BlockPtr
, (EFI_STRING
) String
, StrSize ((EFI_STRING
) String
));
1180 BlockPtr
+= StrSize ((EFI_STRING
) String
);
1183 // Append a EFI_HII_SIBT_END block to the end.
1185 *BlockPtr
= EFI_HII_SIBT_END
;
1186 FreePool (StringPackage
->StringBlock
);
1187 StringPackage
->StringBlock
= StringBlock
;
1188 StringPackage
->StringPkgHdr
->Header
.Length
+= Ucs2FontBlockSize
;
1189 PackageListNode
->PackageListHdr
.PackageLength
+= Ucs2FontBlockSize
;
1193 // EFI_HII_SIBT_FONT_BLOCK does not exist in current string package, so
1194 // create a EFI_HII_SIBT_FONT block to record the font info, then generate
1195 // a EFI_HII_SIBT_STRING_UCS2_FONT block to record the incoming string.
1197 FontBlockSize
= (UINT32
) (StrSize (((EFI_FONT_INFO
*) StringFontInfo
)->FontName
) +
1198 sizeof (EFI_HII_SIBT_FONT_BLOCK
) - sizeof (CHAR16
));
1199 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ FontBlockSize
+ Ucs2FontBlockSize
);
1200 if (StringBlock
== NULL
) {
1201 return EFI_OUT_OF_RESOURCES
;
1204 // Copy original string blocks, except the EFI_HII_SIBT_END.
1206 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1209 // Create a EFI_HII_SIBT_FONT block firstly and then backup its info in string
1210 // package instance for future reference.
1212 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1214 Ext2
.Header
.BlockType
= EFI_HII_SIBT_EXT2
;
1215 Ext2
.BlockType2
= EFI_HII_SIBT_FONT
;
1216 Ext2
.Length
= (UINT16
) FontBlockSize
;
1217 CopyMem (BlockPtr
, &Ext2
, sizeof (EFI_HII_SIBT_EXT2_BLOCK
));
1218 BlockPtr
+= sizeof (EFI_HII_SIBT_EXT2_BLOCK
);
1220 *BlockPtr
= LocalFont
->FontId
;
1221 BlockPtr
+= sizeof (UINT8
);
1222 CopyMem (BlockPtr
, &((EFI_FONT_INFO
*) StringFontInfo
)->FontSize
, sizeof (UINT16
));
1223 BlockPtr
+= sizeof (UINT16
);
1224 CopyMem (BlockPtr
, &((EFI_FONT_INFO
*) StringFontInfo
)->FontStyle
, sizeof (EFI_HII_FONT_STYLE
));
1225 BlockPtr
+= sizeof (EFI_HII_FONT_STYLE
);
1228 &((EFI_FONT_INFO
*) StringFontInfo
)->FontName
,
1229 StrSize (((EFI_FONT_INFO
*) StringFontInfo
)->FontName
)
1233 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
1235 *BlockPtr
= EFI_HII_SIBT_STRING_UCS2_FONT
;
1236 BlockPtr
+= sizeof (EFI_HII_STRING_BLOCK
);
1237 *BlockPtr
= LocalFont
->FontId
;
1238 BlockPtr
+= sizeof (UINT8
);
1239 CopyMem (BlockPtr
, (EFI_STRING
) String
, StrSize ((EFI_STRING
) String
));
1240 BlockPtr
+= StrSize ((EFI_STRING
) String
);
1243 // Append a EFI_HII_SIBT_END block to the end.
1245 *BlockPtr
= EFI_HII_SIBT_END
;
1246 FreePool (StringPackage
->StringBlock
);
1247 StringPackage
->StringBlock
= StringBlock
;
1248 StringPackage
->StringPkgHdr
->Header
.Length
+= FontBlockSize
+ Ucs2FontBlockSize
;
1249 PackageListNode
->PackageListHdr
.PackageLength
+= FontBlockSize
+ Ucs2FontBlockSize
;
1252 // Increase the FontId to make it unique since we already add
1253 // a EFI_HII_SIBT_FONT block to this string package.
1255 StringPackage
->FontId
++;
1260 // Trigger any registered notification function
1263 return InvokeRegisteredFunction (
1265 EFI_HII_DATABASE_NOTIFY_NEW_PACK
,
1266 (VOID
*) StringPackage
,
1267 EFI_HII_PACKAGE_STRINGS
,
1277 This function retrieves the string specified by StringId which is associated
1278 with the specified PackageList in the language Language and copies it into
1279 the buffer specified by String.
1281 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1282 @param Language Points to the language for the retrieved string.
1283 @param PackageList The package list in the HII database to search for
1284 the specified string.
1285 @param StringId The string's id, which is unique within
1287 @param String Points to the new null-terminated string.
1288 @param StringSize On entry, points to the size of the buffer pointed
1289 to by String, in bytes. On return, points to the
1290 length of the string, in bytes.
1291 @param StringFontInfo If not NULL, points to the string's font
1292 information. It's caller's responsibility to free
1295 @retval EFI_SUCCESS The string was returned successfully.
1296 @retval EFI_NOT_FOUND The string specified by StringId is not available.
1297 @retval EFI_NOT_FOUND The string specified by StringId is available but
1298 not in the specified language.
1299 The specified PackageList is not in the database.
1300 @retval EFI_INVALID_LANGUAGE - The string specified by StringId is available but
1301 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to
1303 @retval EFI_INVALID_PARAMETER The String or Language or StringSize was NULL.
1304 @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the
1311 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1312 IN CONST CHAR8
*Language
,
1313 IN EFI_HII_HANDLE PackageList
,
1314 IN EFI_STRING_ID StringId
,
1315 OUT EFI_STRING String
,
1316 IN OUT UINTN
*StringSize
,
1317 OUT EFI_FONT_INFO
**StringFontInfo OPTIONAL
1322 HII_DATABASE_PRIVATE_DATA
*Private
;
1323 HII_DATABASE_RECORD
*DatabaseRecord
;
1324 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1325 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1326 CHAR8
*MatchedLanguage
;
1328 if (This
== NULL
|| Language
== NULL
|| StringId
< 1 || StringSize
== NULL
|| PackageList
== NULL
) {
1329 return EFI_INVALID_PARAMETER
;
1332 if (String
== NULL
&& *StringSize
!= 0) {
1333 return EFI_INVALID_PARAMETER
;
1336 if (!IsHiiHandleValid (PackageList
)) {
1337 return EFI_NOT_FOUND
;
1340 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1341 PackageListNode
= NULL
;
1343 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1344 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1345 if (DatabaseRecord
->Handle
== PackageList
) {
1346 PackageListNode
= DatabaseRecord
->PackageList
;
1351 if (PackageListNode
!= NULL
) {
1353 // First search: to match the StringId in the specified language.
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 MatchedLanguage
= GetBestLanguage (StringPackage
->StringPkgHdr
->Language
, FALSE
, (CHAR8
*) Language
, NULL
);
1361 if (MatchedLanguage
!= NULL
) {
1362 FreePool (MatchedLanguage
);
1363 Status
= GetStringWorker (Private
, StringPackage
, StringId
, String
, StringSize
, StringFontInfo
);
1364 if (Status
!= EFI_NOT_FOUND
) {
1370 // Second search: to match the StringId in other available languages if exist.
1372 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1373 Link
!= &PackageListNode
->StringPkgHdr
;
1374 Link
= Link
->ForwardLink
1376 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1377 Status
= GetStringWorker (Private
, StringPackage
, StringId
, String
, StringSize
, StringFontInfo
);
1378 if (!EFI_ERROR (Status
)) {
1379 return EFI_INVALID_LANGUAGE
;
1384 return EFI_NOT_FOUND
;
1390 This function updates the string specified by StringId in the specified PackageList to the text
1391 specified by String and, optionally, the font information specified by StringFontInfo.
1393 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1394 @param PackageList The package list containing the strings.
1395 @param StringId The string's id, which is unique within
1397 @param Language Points to the language for the updated string.
1398 @param String Points to the new null-terminated string.
1399 @param StringFontInfo Points to the string's font information or NULL if
1400 the string font information is not changed.
1402 @retval EFI_SUCCESS The string was updated successfully.
1403 @retval EFI_NOT_FOUND The string specified by StringId is not in the
1405 @retval EFI_INVALID_PARAMETER The String or Language was NULL.
1406 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
1408 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
1415 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1416 IN EFI_HII_HANDLE PackageList
,
1417 IN EFI_STRING_ID StringId
,
1418 IN CONST CHAR8
*Language
,
1419 IN CONST EFI_STRING String
,
1420 IN CONST EFI_FONT_INFO
*StringFontInfo OPTIONAL
1425 HII_DATABASE_PRIVATE_DATA
*Private
;
1426 HII_DATABASE_RECORD
*DatabaseRecord
;
1427 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1428 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1429 UINT32 OldPackageLen
;
1430 CHAR8
*MatchedLanguage
;
1432 if (This
== NULL
|| Language
== NULL
|| StringId
< 1 || String
== NULL
|| PackageList
== NULL
) {
1433 return EFI_INVALID_PARAMETER
;
1436 if (!IsHiiHandleValid (PackageList
)) {
1437 return EFI_NOT_FOUND
;
1440 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1441 PackageListNode
= NULL
;
1443 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1444 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1445 if (DatabaseRecord
->Handle
== PackageList
) {
1446 PackageListNode
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*) (DatabaseRecord
->PackageList
);
1450 if (PackageListNode
!= NULL
) {
1451 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1452 Link
!= &PackageListNode
->StringPkgHdr
;
1453 Link
= Link
->ForwardLink
1455 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1456 MatchedLanguage
= GetBestLanguage (StringPackage
->StringPkgHdr
->Language
, FALSE
, (CHAR8
*) Language
, NULL
);
1457 if (MatchedLanguage
!= NULL
) {
1458 FreePool (MatchedLanguage
);
1459 OldPackageLen
= StringPackage
->StringPkgHdr
->Header
.Length
;
1460 Status
= SetStringWorker (
1464 (EFI_STRING
) String
,
1465 (EFI_FONT_INFO
*) StringFontInfo
1467 if (EFI_ERROR (Status
)) {
1470 PackageListNode
->PackageListHdr
.PackageLength
+= StringPackage
->StringPkgHdr
->Header
.Length
- OldPackageLen
;
1476 return EFI_NOT_FOUND
;
1482 This function returns the list of supported languages, in the format specified
1483 in Appendix M of UEFI 2.1 spec.
1485 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1486 @param PackageList The package list to examine.
1487 @param Languages Points to the buffer to hold the returned string.
1488 @param LanguagesSize On entry, points to the size of the buffer pointed
1489 to by Languages, in bytes. On return, points to
1490 the length of Languages, in bytes.
1492 @retval EFI_SUCCESS The languages were returned successfully.
1493 @retval EFI_INVALID_PARAMETER The Languages or LanguagesSize was NULL.
1494 @retval EFI_BUFFER_TOO_SMALL The LanguagesSize is too small to hold the list of
1495 supported languages. LanguageSize is updated to
1496 contain the required size.
1497 @retval EFI_NOT_FOUND Could not find string package in specified
1504 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1505 IN EFI_HII_HANDLE PackageList
,
1506 IN OUT CHAR8
*Languages
,
1507 IN OUT UINTN
*LanguagesSize
1511 HII_DATABASE_PRIVATE_DATA
*Private
;
1512 HII_DATABASE_RECORD
*DatabaseRecord
;
1513 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1514 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1517 if (This
== NULL
|| Languages
== NULL
|| LanguagesSize
== NULL
|| PackageList
== NULL
) {
1518 return EFI_INVALID_PARAMETER
;
1520 if (!IsHiiHandleValid (PackageList
)) {
1521 return EFI_NOT_FOUND
;
1524 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1526 PackageListNode
= NULL
;
1527 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1528 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1529 if (DatabaseRecord
->Handle
== PackageList
) {
1530 PackageListNode
= DatabaseRecord
->PackageList
;
1534 if (PackageListNode
== NULL
) {
1535 return EFI_NOT_FOUND
;
1539 // Search the languages in the specified packagelist.
1542 for (Link
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1543 Link
!= &PackageListNode
->StringPkgHdr
;
1544 Link
= Link
->ForwardLink
1546 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1547 ResultSize
+= AsciiStrSize (StringPackage
->StringPkgHdr
->Language
);
1548 if (ResultSize
<= *LanguagesSize
) {
1549 AsciiStrCpy (Languages
, StringPackage
->StringPkgHdr
->Language
);
1550 Languages
+= AsciiStrSize (StringPackage
->StringPkgHdr
->Language
);
1551 *(Languages
- 1) = L
';';
1554 if (ResultSize
== 0) {
1555 return EFI_NOT_FOUND
;
1558 if (*LanguagesSize
< ResultSize
) {
1559 *LanguagesSize
= ResultSize
;
1560 return EFI_BUFFER_TOO_SMALL
;
1563 *(Languages
- 1) = 0;
1569 Each string package has associated with it a single primary language and zero
1570 or more secondary languages. This routine returns the secondary languages
1571 associated with a package list.
1573 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1574 @param PackageList The package list to examine.
1575 @param FirstLanguage Points to the primary language.
1576 @param SecondaryLanguages Points to the buffer to hold the returned list of
1577 secondary languages for the specified
1578 FirstLanguage. If there are no secondary
1579 languages, the function returns successfully, but
1580 this is set to NULL.
1581 @param SecondaryLanguagesSize On entry, points to the size of the buffer pointed
1582 to by SecondaryLanguages, in bytes. On return,
1583 points to the length of SecondaryLanguages in bytes.
1585 @retval EFI_SUCCESS Secondary languages were correctly returned.
1586 @retval EFI_INVALID_PARAMETER FirstLanguage or SecondaryLanguages or
1587 SecondaryLanguagesSize was NULL.
1588 @retval EFI_BUFFER_TOO_SMALL The buffer specified by SecondaryLanguagesSize is
1589 too small to hold the returned information.
1590 SecondLanguageSize is updated to hold the size of
1591 the buffer required.
1592 @retval EFI_INVALID_LANGUAGE The language specified by FirstLanguage is not
1593 present in the specified package list.
1594 @retval EFI_NOT_FOUND The specified PackageList is not in the Database.
1599 HiiGetSecondaryLanguages (
1600 IN CONST EFI_HII_STRING_PROTOCOL
*This
,
1601 IN EFI_HII_HANDLE PackageList
,
1602 IN CONST CHAR8
*FirstLanguage
,
1603 IN OUT CHAR8
*SecondaryLanguages
,
1604 IN OUT UINTN
*SecondaryLanguagesSize
1609 HII_DATABASE_PRIVATE_DATA
*Private
;
1610 HII_DATABASE_RECORD
*DatabaseRecord
;
1611 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1612 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1615 CHAR8
*MatchedLanguage
;
1617 if (This
== NULL
|| PackageList
== NULL
|| FirstLanguage
== NULL
) {
1618 return EFI_INVALID_PARAMETER
;
1620 if (SecondaryLanguages
== NULL
|| SecondaryLanguagesSize
== NULL
) {
1621 return EFI_INVALID_PARAMETER
;
1623 if (!IsHiiHandleValid (PackageList
)) {
1624 return EFI_NOT_FOUND
;
1627 Private
= HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1629 PackageListNode
= NULL
;
1630 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
1631 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1632 if (DatabaseRecord
->Handle
== PackageList
) {
1633 PackageListNode
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*) (DatabaseRecord
->PackageList
);
1637 if (PackageListNode
== NULL
) {
1638 return EFI_NOT_FOUND
;
1643 for (Link1
= PackageListNode
->StringPkgHdr
.ForwardLink
;
1644 Link1
!= &PackageListNode
->StringPkgHdr
;
1645 Link1
= Link1
->ForwardLink
1647 StringPackage
= CR (Link1
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1648 MatchedLanguage
= GetBestLanguage (StringPackage
->StringPkgHdr
->Language
, FALSE
, (CHAR8
*) FirstLanguage
, NULL
);
1649 if (MatchedLanguage
!= NULL
) {
1650 FreePool (MatchedLanguage
);
1651 Languages
= StringPackage
->StringPkgHdr
->Language
;
1653 // Language is a series of ';' terminated strings, first one is primary
1654 // language and following with other secondary languages or NULL if no
1655 // secondary languages any more.
1657 Languages
= AsciiStrStr (Languages
, ";");
1658 if (Languages
== NULL
) {
1663 ResultSize
= AsciiStrSize (Languages
);
1664 if (ResultSize
<= *SecondaryLanguagesSize
) {
1665 AsciiStrCpy (SecondaryLanguages
, Languages
);
1667 *SecondaryLanguagesSize
= ResultSize
;
1668 return EFI_BUFFER_TOO_SMALL
;
1675 return EFI_INVALID_LANGUAGE
;