OpenCore  1.0.4
OpenCore Bootloader
1.0.4
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
String.c
Go to the documentation of this file.
1
11#include "HiiDatabase.h"
12
13CHAR16 mLanguageWindow[16] = {
14 0x0000, 0x0080, 0x0100, 0x0300,
15 0x2000, 0x2080, 0x2100, 0x3000,
16 0x0080, 0x00C0, 0x0400, 0x0600,
17 0x0900, 0x3040, 0x30A0, 0xFF00
18};
19
43BOOLEAN
45 IN HII_DATABASE_PRIVATE_DATA *Private,
46 IN HII_STRING_PACKAGE_INSTANCE *StringPackage,
47 IN UINT8 FontId,
48 IN BOOLEAN DuplicateEnable,
49 IN HII_GLOBAL_FONT_INFO *GlobalFontInfo,
50 OUT HII_FONT_INFO **LocalFontInfo
51 )
52{
53 HII_FONT_INFO *LocalFont;
54 LIST_ENTRY *Link;
55
56 ASSERT (Private != NULL && StringPackage != NULL && GlobalFontInfo != NULL && LocalFontInfo != NULL);
57
58 if (!DuplicateEnable) {
59 for (Link = StringPackage->FontInfoList.ForwardLink;
60 Link != &StringPackage->FontInfoList;
61 Link = Link->ForwardLink
62 )
63 {
64 LocalFont = CR (Link, HII_FONT_INFO, Entry, HII_FONT_INFO_SIGNATURE);
65 if (LocalFont->GlobalEntry == &GlobalFontInfo->Entry) {
66 //
67 // Already referred by local font info list, return directly.
68 //
69 *LocalFontInfo = LocalFont;
70 return TRUE;
71 }
72 }
73 }
74
75 // FontId identifies EFI_FONT_INFO in local string package uniquely.
76 // GlobalEntry points to a HII_GLOBAL_FONT_INFO which identifies
77 // EFI_FONT_INFO uniquely in whole hii database.
78 //
79 LocalFont = (HII_FONT_INFO *)AllocateZeroPool (sizeof (HII_FONT_INFO));
80 ASSERT (LocalFont != NULL);
81
83 LocalFont->FontId = FontId;
84 LocalFont->GlobalEntry = &GlobalFontInfo->Entry;
85 InsertTailList (&StringPackage->FontInfoList, &LocalFont->Entry);
86
87 *LocalFontInfo = LocalFont;
88 return FALSE;
89}
90
108EFI_STATUS
110 OUT EFI_STRING StringDest,
111 IN CHAR8 *StringSrc,
112 IN OUT UINTN *BufferSize
113 )
114{
115 UINTN StringSize;
116 UINTN Index;
117
118 ASSERT (StringSrc != NULL && BufferSize != NULL);
119
120 StringSize = AsciiStrSize (StringSrc) * 2;
121 if ((*BufferSize < StringSize) || (StringDest == NULL)) {
122 *BufferSize = StringSize;
123 return EFI_BUFFER_TOO_SMALL;
124 }
125
126 for (Index = 0; Index < AsciiStrLen (StringSrc); Index++) {
127 StringDest[Index] = (CHAR16)StringSrc[Index];
128 }
129
130 StringDest[Index] = 0;
131 return EFI_SUCCESS;
132}
133
151EFI_STATUS
153 OUT EFI_STRING StringDest, OPTIONAL
154 IN UINT8 *StringSrc,
155 IN OUT UINTN *BufferSize
156 )
157{
158 UINTN StringSize;
159 UINT8 *StringPtr;
160
161 ASSERT (StringSrc != NULL && BufferSize != NULL);
162
163 StringSize = sizeof (CHAR16);
164 StringPtr = StringSrc;
165 while (ReadUnaligned16 ((UINT16 *)StringPtr) != 0) {
166 StringSize += sizeof (CHAR16);
167 StringPtr += sizeof (CHAR16);
168 }
169
170 if (*BufferSize < StringSize) {
171 *BufferSize = StringSize;
172 return EFI_BUFFER_TOO_SMALL;
173 }
174
175 if (StringDest != NULL) {
176 CopyMem (StringDest, StringSrc, StringSize);
177 }
178
179 *BufferSize = StringSize;
180 return EFI_SUCCESS;
181}
182
198EFI_STATUS
200 IN HII_STRING_PACKAGE_INSTANCE *StringPackage,
201 IN UINT8 FontId,
202 OUT EFI_FONT_INFO **StringFontInfo
203 )
204{
205 LIST_ENTRY *Link;
206 HII_FONT_INFO *FontInfo;
207 HII_GLOBAL_FONT_INFO *GlobalFont;
208
209 ASSERT (StringFontInfo != NULL && StringPackage != NULL);
210
211 for (Link = StringPackage->FontInfoList.ForwardLink; Link != &StringPackage->FontInfoList; Link = Link->ForwardLink) {
212 FontInfo = CR (Link, HII_FONT_INFO, Entry, HII_FONT_INFO_SIGNATURE);
213 if (FontInfo->FontId == FontId) {
214 GlobalFont = CR (FontInfo->GlobalEntry, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);
215 *StringFontInfo = (EFI_FONT_INFO *)AllocateZeroPool (GlobalFont->FontInfoSize);
216 if (*StringFontInfo == NULL) {
217 return EFI_OUT_OF_RESOURCES;
218 }
219
220 CopyMem (*StringFontInfo, GlobalFont->FontInfo, GlobalFont->FontInfoSize);
221 return EFI_SUCCESS;
222 }
223 }
224
225 return EFI_NOT_FOUND;
226}
227
254EFI_STATUS
256 IN HII_DATABASE_PRIVATE_DATA *Private,
257 IN HII_STRING_PACKAGE_INSTANCE *StringPackage,
258 IN EFI_STRING_ID StringId,
259 OUT UINT8 *BlockType, OPTIONAL
260 OUT UINT8 **StringBlockAddr, OPTIONAL
261 OUT UINTN *StringTextOffset, OPTIONAL
262 OUT EFI_STRING_ID *LastStringId, OPTIONAL
263 OUT EFI_STRING_ID *StartStringId OPTIONAL
264 )
265{
266 UINT8 *BlockHdr;
267 EFI_STRING_ID CurrentStringId;
268 UINTN BlockSize;
269 UINTN Index;
270 UINT8 *StringTextPtr;
271 UINTN Offset;
272 HII_FONT_INFO *LocalFont;
273 EFI_FONT_INFO *FontInfo;
274 HII_GLOBAL_FONT_INFO *GlobalFont;
275 UINTN FontInfoSize;
276 UINT16 StringCount;
277 UINT16 SkipCount;
278 EFI_HII_FONT_STYLE FontStyle;
279 UINT16 FontSize;
280 UINT8 Length8;
281 EFI_HII_SIBT_EXT2_BLOCK Ext2;
282 UINT8 FontId;
283 UINT32 Length32;
284 UINTN StringSize;
285 CHAR16 Zero;
286
287 ASSERT (StringPackage != NULL);
288 ASSERT (StringPackage->Signature == HII_STRING_PACKAGE_SIGNATURE);
289
290 CurrentStringId = 1;
291 StringSize = 0;
292
293 if ((StringId != (EFI_STRING_ID)(-1)) && (StringId != 0)) {
294 ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);
295 if (StringId > StringPackage->MaxStringId) {
296 return EFI_NOT_FOUND;
297 }
298 } else {
299 ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
300 if ((StringId == 0) && (LastStringId != NULL)) {
301 *LastStringId = StringPackage->MaxStringId;
302 return EFI_SUCCESS;
303 }
304 }
305
306 ZeroMem (&Zero, sizeof (CHAR16));
307
308 //
309 // Parse the string blocks to get the string text and font.
310 //
311 BlockHdr = StringPackage->StringBlock;
312 BlockSize = 0;
313 Offset = 0;
314 while (*BlockHdr != EFI_HII_SIBT_END) {
315 switch (*BlockHdr) {
316 case EFI_HII_SIBT_STRING_SCSU:
317 Offset = sizeof (EFI_HII_STRING_BLOCK);
318 StringTextPtr = BlockHdr + Offset;
319 BlockSize += Offset + AsciiStrSize ((CHAR8 *)StringTextPtr);
320 CurrentStringId++;
321 break;
322
323 case EFI_HII_SIBT_STRING_SCSU_FONT:
324 Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
325 StringTextPtr = BlockHdr + Offset;
326 BlockSize += Offset + AsciiStrSize ((CHAR8 *)StringTextPtr);
327 CurrentStringId++;
328 break;
329
330 case EFI_HII_SIBT_STRINGS_SCSU:
331 CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
332 StringTextPtr = (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8));
333 BlockSize += StringTextPtr - BlockHdr;
334
335 for (Index = 0; Index < StringCount; Index++) {
336 BlockSize += AsciiStrSize ((CHAR8 *)StringTextPtr);
337 if (CurrentStringId == StringId) {
338 ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);
339 *BlockType = *BlockHdr;
340 *StringBlockAddr = BlockHdr;
341 *StringTextOffset = StringTextPtr - BlockHdr;
342 return EFI_SUCCESS;
343 }
344
345 StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr);
346 CurrentStringId++;
347 }
348
349 break;
350
351 case EFI_HII_SIBT_STRINGS_SCSU_FONT:
352 CopyMem (
353 &StringCount,
354 (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
355 sizeof (UINT16)
356 );
357 StringTextPtr = (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8));
358 BlockSize += StringTextPtr - BlockHdr;
359
360 for (Index = 0; Index < StringCount; Index++) {
361 BlockSize += AsciiStrSize ((CHAR8 *)StringTextPtr);
362 if (CurrentStringId == StringId) {
363 ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);
364 *BlockType = *BlockHdr;
365 *StringBlockAddr = BlockHdr;
366 *StringTextOffset = StringTextPtr - BlockHdr;
367 return EFI_SUCCESS;
368 }
369
370 StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr);
371 CurrentStringId++;
372 }
373
374 break;
375
376 case EFI_HII_SIBT_STRING_UCS2:
377 Offset = sizeof (EFI_HII_STRING_BLOCK);
378 StringTextPtr = BlockHdr + Offset;
379 //
380 // Use StringSize to store the size of the specified string, including the NULL
381 // terminator.
382 //
383 GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);
384 BlockSize += Offset + StringSize;
385 CurrentStringId++;
386 break;
387
388 case EFI_HII_SIBT_STRING_UCS2_FONT:
389 Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);
390 StringTextPtr = BlockHdr + Offset;
391 //
392 // Use StrSize to store the size of the specified string, including the NULL
393 // terminator.
394 //
395 GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);
396 BlockSize += Offset + StringSize;
397 CurrentStringId++;
398 break;
399
400 case EFI_HII_SIBT_STRINGS_UCS2:
401 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
402 StringTextPtr = BlockHdr + Offset;
403 BlockSize += Offset;
404 CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
405 for (Index = 0; Index < StringCount; Index++) {
406 GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);
407 BlockSize += StringSize;
408 if (CurrentStringId == StringId) {
409 ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);
410 *BlockType = *BlockHdr;
411 *StringBlockAddr = BlockHdr;
412 *StringTextOffset = StringTextPtr - BlockHdr;
413 return EFI_SUCCESS;
414 }
415
416 StringTextPtr = StringTextPtr + StringSize;
417 CurrentStringId++;
418 }
419
420 break;
421
422 case EFI_HII_SIBT_STRINGS_UCS2_FONT:
423 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
424 StringTextPtr = BlockHdr + Offset;
425 BlockSize += Offset;
426 CopyMem (
427 &StringCount,
428 (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
429 sizeof (UINT16)
430 );
431 for (Index = 0; Index < StringCount; Index++) {
432 GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);
433 BlockSize += StringSize;
434 if (CurrentStringId == StringId) {
435 ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);
436 *BlockType = *BlockHdr;
437 *StringBlockAddr = BlockHdr;
438 *StringTextOffset = StringTextPtr - BlockHdr;
439 return EFI_SUCCESS;
440 }
441
442 StringTextPtr = StringTextPtr + StringSize;
443 CurrentStringId++;
444 }
445
446 break;
447
448 case EFI_HII_SIBT_DUPLICATE:
449 if (CurrentStringId == StringId) {
450 //
451 // Incoming StringId is an id of a duplicate string block.
452 // Update the StringId to be the previous string block.
453 // Go back to the header of string block to search.
454 //
455 CopyMem (
456 &StringId,
457 BlockHdr + sizeof (EFI_HII_STRING_BLOCK),
458 sizeof (EFI_STRING_ID)
459 );
460 ASSERT (StringId != CurrentStringId);
461 CurrentStringId = 1;
462 BlockSize = 0;
463 } else {
464 BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
465 CurrentStringId++;
466 }
467
468 break;
469
470 case EFI_HII_SIBT_SKIP1:
471 SkipCount = (UINT16)(*(UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
472 CurrentStringId = (UINT16)(CurrentStringId + SkipCount);
473 BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
474 break;
475
476 case EFI_HII_SIBT_SKIP2:
477 CopyMem (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
478 CurrentStringId = (UINT16)(CurrentStringId + SkipCount);
479 BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
480 break;
481
482 case EFI_HII_SIBT_EXT1:
483 CopyMem (
484 &Length8,
485 (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
486 sizeof (UINT8)
487 );
488 BlockSize += Length8;
489 break;
490
491 case EFI_HII_SIBT_EXT2:
492 CopyMem (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
493 if ((Ext2.BlockType2 == EFI_HII_SIBT_FONT) && (StringId == (EFI_STRING_ID)(-1))) {
494 //
495 // Find the relationship between global font info and the font info of
496 // this EFI_HII_SIBT_FONT block then backup its information in local package.
497 //
498 BlockHdr += sizeof (EFI_HII_SIBT_EXT2_BLOCK);
499 CopyMem (&FontId, BlockHdr, sizeof (UINT8));
500 BlockHdr++;
501 CopyMem (&FontSize, BlockHdr, sizeof (UINT16));
502 BlockHdr += sizeof (UINT16);
503 CopyMem (&FontStyle, BlockHdr, sizeof (EFI_HII_FONT_STYLE));
504 BlockHdr += sizeof (EFI_HII_FONT_STYLE);
505 GetUnicodeStringTextOrSize (NULL, BlockHdr, &StringSize);
506
507 FontInfoSize = sizeof (EFI_FONT_INFO) - sizeof (CHAR16) + StringSize;
508 FontInfo = (EFI_FONT_INFO *)AllocateZeroPool (FontInfoSize);
509 if (FontInfo == NULL) {
510 return EFI_OUT_OF_RESOURCES;
511 }
512
513 FontInfo->FontStyle = FontStyle;
514 FontInfo->FontSize = FontSize;
515 CopyMem (FontInfo->FontName, BlockHdr, StringSize);
516
517 //
518 // If find the corresponding global font info, save the relationship.
519 // Otherwise ignore this EFI_HII_SIBT_FONT block.
520 //
521 if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, &GlobalFont)) {
522 ReferFontInfoLocally (Private, StringPackage, FontId, TRUE, GlobalFont, &LocalFont);
523 }
524
525 //
526 // Since string package tool set FontId initially to 0 and increases it
527 // progressively by one, StringPackage->FondId always represents a unique
528 // and available FontId.
529 //
530 StringPackage->FontId++;
531
532 FreePool (FontInfo);
533 }
534
535 BlockSize += Ext2.Length;
536
537 break;
538
539 case EFI_HII_SIBT_EXT4:
540 CopyMem (
541 &Length32,
542 (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
543 sizeof (UINT32)
544 );
545
546 BlockSize += Length32;
547 break;
548
549 default:
550 break;
551 }
552
553 if ((StringId > 0) && (StringId != (EFI_STRING_ID)(-1))) {
554 ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);
555 *BlockType = *BlockHdr;
556 *StringBlockAddr = BlockHdr;
557 *StringTextOffset = Offset;
558
559 if (StringId == CurrentStringId - 1) {
560 //
561 // if only one skip item, return EFI_NOT_FOUND.
562 //
563 if ((*BlockType == EFI_HII_SIBT_SKIP2) || (*BlockType == EFI_HII_SIBT_SKIP1)) {
564 return EFI_NOT_FOUND;
565 } else {
566 return EFI_SUCCESS;
567 }
568 }
569
570 if (StringId < CurrentStringId - 1) {
571 return EFI_NOT_FOUND;
572 }
573 }
574
575 BlockHdr = StringPackage->StringBlock + BlockSize;
576 if (StartStringId != NULL) {
577 *StartStringId = CurrentStringId;
578 }
579 }
580
581 //
582 // Get last string ID
583 //
584 if ((StringId == (EFI_STRING_ID)(-1)) && (LastStringId != NULL)) {
585 *LastStringId = (EFI_STRING_ID)(CurrentStringId - 1);
586 return EFI_SUCCESS;
587 }
588
589 return EFI_NOT_FOUND;
590}
591
617EFI_STATUS
619 IN HII_DATABASE_PRIVATE_DATA *Private,
620 IN HII_STRING_PACKAGE_INSTANCE *StringPackage,
621 IN EFI_STRING_ID StringId,
622 OUT EFI_STRING String,
623 IN OUT UINTN *StringSize, OPTIONAL
624 OUT EFI_FONT_INFO **StringFontInfo OPTIONAL
625 )
626{
627 UINT8 *StringTextPtr;
628 UINT8 BlockType;
629 UINT8 *StringBlockAddr;
630 UINTN StringTextOffset;
631 EFI_STATUS Status;
632 UINT8 FontId;
633
634 ASSERT (StringPackage != NULL);
635 ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
636
637 //
638 // Find the specified string block
639 //
640 Status = FindStringBlock (
641 Private,
642 StringPackage,
643 StringId,
644 &BlockType,
645 &StringBlockAddr,
646 &StringTextOffset,
647 NULL,
648 NULL
649 );
650 if (EFI_ERROR (Status)) {
651 return Status;
652 }
653
654 if (StringSize == NULL) {
655 //
656 // String text buffer is not requested
657 //
658 return EFI_SUCCESS;
659 }
660
661 //
662 // Get the string text.
663 //
664 StringTextPtr = StringBlockAddr + StringTextOffset;
665 switch (BlockType) {
666 case EFI_HII_SIBT_STRING_SCSU:
667 case EFI_HII_SIBT_STRING_SCSU_FONT:
668 case EFI_HII_SIBT_STRINGS_SCSU:
669 case EFI_HII_SIBT_STRINGS_SCSU_FONT:
670 Status = ConvertToUnicodeText (String, (CHAR8 *)StringTextPtr, StringSize);
671 break;
672 case EFI_HII_SIBT_STRING_UCS2:
673 case EFI_HII_SIBT_STRING_UCS2_FONT:
674 case EFI_HII_SIBT_STRINGS_UCS2:
675 case EFI_HII_SIBT_STRINGS_UCS2_FONT:
676 Status = GetUnicodeStringTextOrSize (String, StringTextPtr, StringSize);
677 break;
678 default:
679 return EFI_NOT_FOUND;
680 }
681
682 if (EFI_ERROR (Status)) {
683 return Status;
684 }
685
686 //
687 // Get the string font. The FontId 0 is the default font for those string blocks which
688 // do not specify a font identifier. If default font is not specified, return NULL.
689 //
690 if (StringFontInfo != NULL) {
691 switch (BlockType) {
692 case EFI_HII_SIBT_STRING_SCSU_FONT:
693 case EFI_HII_SIBT_STRINGS_SCSU_FONT:
694 case EFI_HII_SIBT_STRING_UCS2_FONT:
695 case EFI_HII_SIBT_STRINGS_UCS2_FONT:
696 FontId = *(StringBlockAddr + sizeof (EFI_HII_STRING_BLOCK));
697 break;
698 default:
699 FontId = 0;
700 }
701
702 Status = GetStringFontInfo (StringPackage, FontId, StringFontInfo);
703 if (Status == EFI_NOT_FOUND) {
704 *StringFontInfo = NULL;
705 }
706 }
707
708 return EFI_SUCCESS;
709}
710
730EFI_STATUS
732 IN OUT HII_STRING_PACKAGE_INSTANCE *StringPackage,
733 IN EFI_STRING_ID StartStringId,
734 IN EFI_STRING_ID StringId,
735 IN OUT UINT8 *BlockType,
736 IN OUT UINT8 **StringBlockAddr,
737 IN BOOLEAN FontBlock
738 )
739{
740 UINT8 *BlockPtr;
741 UINT8 *StringBlock;
742 UINT32 SkipLen;
743 UINT32 OldBlockSize;
744 UINT32 NewBlockSize;
745 UINT32 FrontSkipNum;
746 UINT32 NewUCSBlockLen;
747 UINT8 *OldStringAddr;
748 UINT32 IdCount;
749
750 FrontSkipNum = 0;
751 SkipLen = 0;
752 OldStringAddr = *StringBlockAddr;
753
754 ASSERT (*BlockType == EFI_HII_SIBT_SKIP1 || *BlockType == EFI_HII_SIBT_SKIP2);
755 //
756 // Old skip block size.
757 //
758 if (*BlockType == EFI_HII_SIBT_SKIP1) {
759 SkipLen = sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
760 IdCount = *(UINT8 *)(OldStringAddr + sizeof (EFI_HII_STRING_BLOCK));
761 } else {
762 SkipLen = sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
763 IdCount = *(UINT16 *)(OldStringAddr + sizeof (EFI_HII_STRING_BLOCK));
764 }
765
766 //
767 // New create UCS or UCS2 block size.
768 //
769 if (FontBlock) {
770 NewUCSBlockLen = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK);
771 } else {
772 NewUCSBlockLen = sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK);
773 }
774
775 OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;
776
777 if (StartStringId == StringId) {
778 //
779 // New block + [Skip block]
780 //
781 if (IdCount > 1) {
782 NewBlockSize = OldBlockSize + NewUCSBlockLen;
783 } else {
784 NewBlockSize = OldBlockSize + NewUCSBlockLen - SkipLen;
785 }
786 } else if (StartStringId + IdCount - 1 == StringId) {
787 //
788 // Skip block + New block
789 //
790 NewBlockSize = OldBlockSize + NewUCSBlockLen;
791 FrontSkipNum = StringId - StartStringId;
792 } else {
793 //
794 // Skip block + New block + [Skip block]
795 //
796 NewBlockSize = OldBlockSize + NewUCSBlockLen + SkipLen;
797 FrontSkipNum = StringId - StartStringId;
798 }
799
800 StringBlock = (UINT8 *)AllocateZeroPool (NewBlockSize);
801 if (StringBlock == NULL) {
802 return EFI_OUT_OF_RESOURCES;
803 }
804
805 //
806 // Copy old block in front of skip block.
807 //
808 CopyMem (StringBlock, StringPackage->StringBlock, OldStringAddr - StringPackage->StringBlock);
809 BlockPtr = StringBlock + (OldStringAddr - StringPackage->StringBlock);
810
811 if (FrontSkipNum > 0) {
812 *BlockPtr = *BlockType;
813 if (*BlockType == EFI_HII_SIBT_SKIP1) {
814 *(BlockPtr + sizeof (EFI_HII_STRING_BLOCK)) = (UINT8)FrontSkipNum;
815 } else {
816 *(UINT16 *)(BlockPtr + sizeof (EFI_HII_STRING_BLOCK)) = (UINT16)FrontSkipNum;
817 }
818
819 BlockPtr += SkipLen;
820 }
821
822 //
823 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
824 //
825 *StringBlockAddr = BlockPtr;
826 if (FontBlock) {
827 *BlockPtr = EFI_HII_SIBT_STRING_UCS2_FONT;
828 } else {
829 *BlockPtr = EFI_HII_SIBT_STRING_UCS2;
830 }
831
832 BlockPtr += NewUCSBlockLen;
833
834 if (IdCount > FrontSkipNum + 1) {
835 *BlockPtr = *BlockType;
836 if (*BlockType == EFI_HII_SIBT_SKIP1) {
837 *(BlockPtr + sizeof (EFI_HII_STRING_BLOCK)) = (UINT8)(IdCount - FrontSkipNum - 1);
838 } else {
839 *(UINT16 *)(BlockPtr + sizeof (EFI_HII_STRING_BLOCK)) = (UINT16)(IdCount - FrontSkipNum - 1);
840 }
841
842 BlockPtr += SkipLen;
843 }
844
845 //
846 // Append a EFI_HII_SIBT_END block to the end.
847 //
848 CopyMem (BlockPtr, OldStringAddr + SkipLen, OldBlockSize - (OldStringAddr - StringPackage->StringBlock) - SkipLen);
849
850 if (FontBlock) {
851 *BlockType = EFI_HII_SIBT_STRING_UCS2_FONT;
852 } else {
853 *BlockType = EFI_HII_SIBT_STRING_UCS2;
854 }
855
856 FreePool (StringPackage->StringBlock);
857 StringPackage->StringBlock = StringBlock;
858 StringPackage->StringPkgHdr->Header.Length += NewBlockSize - OldBlockSize;
859
860 return EFI_SUCCESS;
861}
862
885EFI_STATUS
887 IN HII_DATABASE_PRIVATE_DATA *Private,
888 IN OUT HII_STRING_PACKAGE_INSTANCE *StringPackage,
889 IN EFI_STRING_ID StringId,
890 IN EFI_STRING String,
891 IN EFI_FONT_INFO *StringFontInfo OPTIONAL
892 )
893{
894 UINT8 *StringTextPtr;
895 UINT8 BlockType;
896 UINT8 *StringBlockAddr;
897 UINTN StringTextOffset;
898 EFI_STATUS Status;
899 UINT8 *Block;
900 UINT8 *BlockPtr;
901 UINTN BlockSize;
902 UINTN OldBlockSize;
903 HII_FONT_INFO *LocalFont;
904 HII_GLOBAL_FONT_INFO *GlobalFont;
905 BOOLEAN Referred;
906 EFI_HII_SIBT_EXT2_BLOCK Ext2;
907 UINTN StringSize;
908 UINTN TmpSize;
909 EFI_STRING_ID StartStringId;
910
911 StartStringId = 0;
912 StringSize = 0;
913 ASSERT (Private != NULL && StringPackage != NULL && String != NULL);
914 ASSERT (Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
915 //
916 // Find the specified string block
917 //
918 Status = FindStringBlock (
919 Private,
920 StringPackage,
921 StringId,
922 &BlockType,
923 &StringBlockAddr,
924 &StringTextOffset,
925 NULL,
926 &StartStringId
927 );
928 if (EFI_ERROR (Status) && ((BlockType == EFI_HII_SIBT_SKIP1) || (BlockType == EFI_HII_SIBT_SKIP2))) {
929 Status = InsertLackStringBlock (
930 StringPackage,
931 StartStringId,
932 StringId,
933 &BlockType,
934 &StringBlockAddr,
935 (BOOLEAN)(StringFontInfo != NULL)
936 );
937 if (EFI_ERROR (Status)) {
938 return Status;
939 }
940
941 if (StringFontInfo != NULL) {
942 StringTextOffset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);
943 } else {
944 StringTextOffset = sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK) - sizeof (CHAR16);
945 }
946 }
947
948 LocalFont = NULL;
949 GlobalFont = NULL;
950 Referred = FALSE;
951
952 //
953 // The input StringFontInfo should exist in current database if specified.
954 //
955 if (StringFontInfo != NULL) {
956 if (!IsFontInfoExisted (Private, StringFontInfo, NULL, NULL, &GlobalFont)) {
957 return EFI_INVALID_PARAMETER;
958 } else {
959 Referred = ReferFontInfoLocally (
960 Private,
961 StringPackage,
962 StringPackage->FontId,
963 FALSE,
964 GlobalFont,
965 &LocalFont
966 );
967 if (!Referred) {
968 StringPackage->FontId++;
969 }
970 }
971
972 //
973 // Update the FontId of the specified string block to input font info.
974 //
975 switch (BlockType) {
976 case EFI_HII_SIBT_STRING_SCSU_FONT:
977 case EFI_HII_SIBT_STRINGS_SCSU_FONT:
978 case EFI_HII_SIBT_STRING_UCS2_FONT:
979 case EFI_HII_SIBT_STRINGS_UCS2_FONT:
980 *(StringBlockAddr + sizeof (EFI_HII_STRING_BLOCK)) = LocalFont->FontId;
981 break;
982 default:
983 //
984 // When modify the font info of these blocks, the block type should be updated
985 // to contain font info thus the whole structure should be revised.
986 // It is recommended to use tool to modify the block type not in the code.
987 //
988 return EFI_UNSUPPORTED;
989 }
990 }
991
992 OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;
993
994 //
995 // Set the string text and font.
996 //
997 StringTextPtr = StringBlockAddr + StringTextOffset;
998 switch (BlockType) {
999 case EFI_HII_SIBT_STRING_SCSU:
1000 case EFI_HII_SIBT_STRING_SCSU_FONT:
1001 case EFI_HII_SIBT_STRINGS_SCSU:
1002 case EFI_HII_SIBT_STRINGS_SCSU_FONT:
1003 BlockSize = OldBlockSize + StrLen (String);
1004 BlockSize -= AsciiStrSize ((CHAR8 *)StringTextPtr);
1005 Block = AllocateZeroPool (BlockSize);
1006 if (Block == NULL) {
1007 return EFI_OUT_OF_RESOURCES;
1008 }
1009
1010 CopyMem (Block, StringPackage->StringBlock, StringTextPtr - StringPackage->StringBlock);
1011 BlockPtr = Block + (StringTextPtr - StringPackage->StringBlock);
1012
1013 while (*String != 0) {
1014 *BlockPtr++ = (CHAR8)*String++;
1015 }
1016
1017 *BlockPtr++ = 0;
1018
1019 TmpSize = OldBlockSize - (StringTextPtr - StringPackage->StringBlock) - AsciiStrSize ((CHAR8 *)StringTextPtr);
1020 CopyMem (
1021 BlockPtr,
1022 StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr),
1023 TmpSize
1024 );
1025
1026 ZeroMem (StringPackage->StringBlock, OldBlockSize);
1027 FreePool (StringPackage->StringBlock);
1028 StringPackage->StringBlock = Block;
1029 StringPackage->StringPkgHdr->Header.Length += (UINT32)(BlockSize - OldBlockSize);
1030 break;
1031
1032 case EFI_HII_SIBT_STRING_UCS2:
1033 case EFI_HII_SIBT_STRING_UCS2_FONT:
1034 case EFI_HII_SIBT_STRINGS_UCS2:
1035 case EFI_HII_SIBT_STRINGS_UCS2_FONT:
1036 //
1037 // Use StrSize to store the size of the specified string, including the NULL
1038 // terminator.
1039 //
1040 GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);
1041
1042 BlockSize = OldBlockSize + StrSize (String) - StringSize;
1043 Block = AllocateZeroPool (BlockSize);
1044 if (Block == NULL) {
1045 return EFI_OUT_OF_RESOURCES;
1046 }
1047
1048 CopyMem (Block, StringPackage->StringBlock, StringTextPtr - StringPackage->StringBlock);
1049 BlockPtr = Block + (StringTextPtr - StringPackage->StringBlock);
1050
1051 CopyMem (BlockPtr, String, StrSize (String));
1052 BlockPtr += StrSize (String);
1053
1054 CopyMem (
1055 BlockPtr,
1056 StringTextPtr + StringSize,
1057 OldBlockSize - (StringTextPtr - StringPackage->StringBlock) - StringSize
1058 );
1059
1060 ZeroMem (StringPackage->StringBlock, OldBlockSize);
1061 FreePool (StringPackage->StringBlock);
1062 StringPackage->StringBlock = Block;
1063 StringPackage->StringPkgHdr->Header.Length += (UINT32)(BlockSize - OldBlockSize);
1064 break;
1065
1066 default:
1067 return EFI_NOT_FOUND;
1068 }
1069
1070 //
1071 // Insert a new EFI_HII_SIBT_FONT_BLOCK to the header of string block, if incoming
1072 // StringFontInfo does not exist in current string package.
1073 //
1074 // This new block does not impact on the value of StringId.
1075 //
1076 //
1077 if ((StringFontInfo == NULL) || Referred) {
1078 return EFI_SUCCESS;
1079 }
1080
1081 OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;
1082 BlockSize = OldBlockSize + sizeof (EFI_HII_SIBT_FONT_BLOCK) - sizeof (CHAR16) +
1083 StrSize (GlobalFont->FontInfo->FontName);
1084
1085 Block = AllocateZeroPool (BlockSize);
1086 if (Block == NULL) {
1087 return EFI_OUT_OF_RESOURCES;
1088 }
1089
1090 BlockPtr = Block;
1091 Ext2.Header.BlockType = EFI_HII_SIBT_EXT2;
1092 Ext2.BlockType2 = EFI_HII_SIBT_FONT;
1093 Ext2.Length = (UINT16)(BlockSize - OldBlockSize);
1094 CopyMem (BlockPtr, &Ext2, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
1095 BlockPtr += sizeof (EFI_HII_SIBT_EXT2_BLOCK);
1096
1097 *BlockPtr = LocalFont->FontId;
1098 BlockPtr++;
1099 CopyMem (BlockPtr, &GlobalFont->FontInfo->FontSize, sizeof (UINT16));
1100 BlockPtr += sizeof (UINT16);
1101 CopyMem (BlockPtr, &GlobalFont->FontInfo->FontStyle, sizeof (UINT32));
1102 BlockPtr += sizeof (UINT32);
1103 CopyMem (
1104 BlockPtr,
1105 GlobalFont->FontInfo->FontName,
1106 StrSize (GlobalFont->FontInfo->FontName)
1107 );
1108 BlockPtr += StrSize (GlobalFont->FontInfo->FontName);
1109
1110 CopyMem (BlockPtr, StringPackage->StringBlock, OldBlockSize);
1111
1112 ZeroMem (StringPackage->StringBlock, OldBlockSize);
1113 FreePool (StringPackage->StringBlock);
1114 StringPackage->StringBlock = Block;
1115 StringPackage->StringPkgHdr->Header.Length += Ext2.Length;
1116
1117 return EFI_SUCCESS;
1118}
1119
1154EFI_STATUS
1155EFIAPI
1157 IN CONST EFI_HII_STRING_PROTOCOL *This,
1158 IN EFI_HII_HANDLE PackageList,
1159 OUT EFI_STRING_ID *StringId,
1160 IN CONST CHAR8 *Language,
1161 IN CONST CHAR16 *LanguageName, OPTIONAL
1162 IN CONST EFI_STRING String,
1163 IN CONST EFI_FONT_INFO *StringFontInfo OPTIONAL
1164 )
1165{
1166 EFI_STATUS Status;
1167 LIST_ENTRY *Link;
1169 HII_DATABASE_RECORD *DatabaseRecord;
1170 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;
1171 HII_STRING_PACKAGE_INSTANCE *StringPackage;
1172 UINT32 HeaderSize;
1173 UINT32 BlockSize;
1174 UINT32 OldBlockSize;
1175 UINT8 *StringBlock;
1176 UINT8 *BlockPtr;
1177 UINT32 Ucs2BlockSize;
1178 UINT32 FontBlockSize;
1179 UINT32 Ucs2FontBlockSize;
1180 EFI_HII_SIBT_EXT2_BLOCK Ext2;
1181 HII_FONT_INFO *LocalFont;
1182 HII_GLOBAL_FONT_INFO *GlobalFont;
1183 EFI_STRING_ID NewStringId;
1184 EFI_STRING_ID NextStringId;
1185 EFI_STRING_ID Index;
1186 HII_STRING_PACKAGE_INSTANCE *MatchStringPackage;
1187 BOOLEAN NewStringPackageCreated;
1188
1189 if ((This == NULL) || (String == NULL) || (StringId == NULL) || (Language == NULL) || (PackageList == NULL)) {
1190 return EFI_INVALID_PARAMETER;
1191 }
1192
1193 if (!IsHiiHandleValid (PackageList)) {
1194 return EFI_NOT_FOUND;
1195 }
1196
1198 GlobalFont = NULL;
1199
1200 //
1201 // If StringFontInfo specify a paritcular font, it should exist in current database.
1202 //
1203 if (StringFontInfo != NULL) {
1204 if (!IsFontInfoExisted (Private, (EFI_FONT_INFO *)StringFontInfo, NULL, NULL, &GlobalFont)) {
1205 return EFI_INVALID_PARAMETER;
1206 }
1207 }
1208
1209 //
1210 // Get the matching package list.
1211 //
1212 PackageListNode = NULL;
1213 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
1214 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
1215 if (DatabaseRecord->Handle == PackageList) {
1216 PackageListNode = DatabaseRecord->PackageList;
1217 break;
1218 }
1219 }
1220
1221 if (PackageListNode == NULL) {
1222 return EFI_NOT_FOUND;
1223 }
1224
1225 EfiAcquireLock (&mHiiDatabaseLock);
1226
1227 Status = EFI_SUCCESS;
1228 NewStringPackageCreated = FALSE;
1229 NewStringId = 0;
1230 NextStringId = 0;
1231 StringPackage = NULL;
1232 MatchStringPackage = NULL;
1233 for (Link = PackageListNode->StringPkgHdr.ForwardLink;
1234 Link != &PackageListNode->StringPkgHdr;
1235 Link = Link->ForwardLink
1236 )
1237 {
1238 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
1239 //
1240 // Create a string block and corresponding font block if exists, then append them
1241 // to the end of the string package.
1242 //
1243 Status = FindStringBlock (
1244 Private,
1245 StringPackage,
1246 0,
1247 NULL,
1248 NULL,
1249 NULL,
1250 &NextStringId,
1251 NULL
1252 );
1253 if (EFI_ERROR (Status)) {
1254 goto Done;
1255 }
1256
1257 //
1258 // Make sure that new StringId is same in all String Packages for the different language.
1259 //
1260 if ((NewStringId != 0) && (NewStringId != NextStringId)) {
1261 ASSERT (FALSE);
1262 Status = EFI_INVALID_PARAMETER;
1263 goto Done;
1264 }
1265
1266 NewStringId = NextStringId;
1267 //
1268 // Get the matched string package with language.
1269 //
1270 if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *)Language)) {
1271 MatchStringPackage = StringPackage;
1272 } else {
1273 OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;
1274 //
1275 // Create a blank EFI_HII_SIBT_STRING_UCS2_BLOCK to reserve new string ID.
1276 //
1277 Ucs2BlockSize = (UINT32)sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK);
1278
1279 StringBlock = (UINT8 *)AllocateZeroPool (OldBlockSize + Ucs2BlockSize);
1280 if (StringBlock == NULL) {
1281 Status = EFI_OUT_OF_RESOURCES;
1282 goto Done;
1283 }
1284
1285 //
1286 // Copy original string blocks, except the EFI_HII_SIBT_END.
1287 //
1288 CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));
1289 //
1290 // Create a blank EFI_HII_SIBT_STRING_UCS2 block
1291 //
1292 BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);
1293 *BlockPtr = EFI_HII_SIBT_STRING_UCS2;
1294 BlockPtr += sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK);
1295
1296 //
1297 // Append a EFI_HII_SIBT_END block to the end.
1298 //
1299 *BlockPtr = EFI_HII_SIBT_END;
1300 ZeroMem (StringPackage->StringBlock, OldBlockSize);
1301 FreePool (StringPackage->StringBlock);
1302 StringPackage->StringBlock = StringBlock;
1303 StringPackage->StringPkgHdr->Header.Length += Ucs2BlockSize;
1304 PackageListNode->PackageListHdr.PackageLength += Ucs2BlockSize;
1305 }
1306 }
1307
1308 if (NewStringId == 0) {
1309 //
1310 // No string package is found.
1311 // Create new string package. StringId 1 is reserved for Language Name string.
1312 //
1313 *StringId = 2;
1314 } else {
1315 //
1316 // Set new StringId
1317 //
1318 *StringId = (EFI_STRING_ID)(NewStringId + 1);
1319 }
1320
1321 if (MatchStringPackage != NULL) {
1322 StringPackage = MatchStringPackage;
1323 } else {
1324 //
1325 // LanguageName is required to create a new string package.
1326 //
1327 if (LanguageName == NULL) {
1328 Status = EFI_INVALID_PARAMETER;
1329 goto Done;
1330 }
1331
1332 StringPackage = AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE));
1333 if (StringPackage == NULL) {
1334 Status = EFI_OUT_OF_RESOURCES;
1335 goto Done;
1336 }
1337
1338 StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE;
1339 StringPackage->MaxStringId = *StringId;
1340 StringPackage->FontId = 0;
1341 InitializeListHead (&StringPackage->FontInfoList);
1342
1343 //
1344 // Fill in the string package header
1345 //
1346 HeaderSize = (UINT32)(AsciiStrSize ((CHAR8 *)Language) - 1 + sizeof (EFI_HII_STRING_PACKAGE_HDR));
1347 StringPackage->StringPkgHdr = AllocateZeroPool (HeaderSize);
1348 if (StringPackage->StringPkgHdr == NULL) {
1349 FreePool (StringPackage);
1350 Status = EFI_OUT_OF_RESOURCES;
1351 goto Done;
1352 }
1353
1354 StringPackage->StringPkgHdr->Header.Type = EFI_HII_PACKAGE_STRINGS;
1355 StringPackage->StringPkgHdr->HdrSize = HeaderSize;
1356 StringPackage->StringPkgHdr->StringInfoOffset = HeaderSize;
1357 CopyMem (StringPackage->StringPkgHdr->LanguageWindow, mLanguageWindow, 16 * sizeof (CHAR16));
1358 StringPackage->StringPkgHdr->LanguageName = 1;
1359 AsciiStrCpyS (StringPackage->StringPkgHdr->Language, (HeaderSize - OFFSET_OF (EFI_HII_STRING_PACKAGE_HDR, Language)) / sizeof (CHAR8), (CHAR8 *)Language);
1360
1361 //
1362 // Calculate the length of the string blocks, including string block to record
1363 // printable language full name and EFI_HII_SIBT_END_BLOCK.
1364 //
1365 Ucs2BlockSize = (UINT32)(StrSize ((CHAR16 *)LanguageName) +
1366 (*StringId - 1) * sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK) - sizeof (CHAR16));
1367
1368 BlockSize = Ucs2BlockSize + sizeof (EFI_HII_SIBT_END_BLOCK);
1369 StringPackage->StringBlock = (UINT8 *)AllocateZeroPool (BlockSize);
1370 if (StringPackage->StringBlock == NULL) {
1371 FreePool (StringPackage->StringPkgHdr);
1372 FreePool (StringPackage);
1373 Status = EFI_OUT_OF_RESOURCES;
1374 goto Done;
1375 }
1376
1377 //
1378 // Insert the string block of printable language full name
1379 //
1380 BlockPtr = StringPackage->StringBlock;
1381 *BlockPtr = EFI_HII_SIBT_STRING_UCS2;
1382 BlockPtr += sizeof (EFI_HII_STRING_BLOCK);
1383 CopyMem (BlockPtr, (EFI_STRING)LanguageName, StrSize ((EFI_STRING)LanguageName));
1384 BlockPtr += StrSize ((EFI_STRING)LanguageName);
1385 for (Index = 2; Index <= *StringId - 1; Index++) {
1386 *BlockPtr = EFI_HII_SIBT_STRING_UCS2;
1387 BlockPtr += sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK);
1388 }
1389
1390 //
1391 // Insert the end block
1392 //
1393 *BlockPtr = EFI_HII_SIBT_END;
1394
1395 //
1396 // Append this string package node to string package array in this package list.
1397 //
1398 StringPackage->StringPkgHdr->Header.Length = HeaderSize + BlockSize;
1399 PackageListNode->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length;
1400 InsertTailList (&PackageListNode->StringPkgHdr, &StringPackage->StringEntry);
1401 NewStringPackageCreated = TRUE;
1402 }
1403
1404 OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;
1405
1406 if (StringFontInfo == NULL) {
1407 //
1408 // Create a EFI_HII_SIBT_STRING_UCS2_BLOCK since font info is not specified.
1409 //
1410 Ucs2BlockSize = (UINT32)(StrSize (String) + sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK)
1411 - sizeof (CHAR16));
1412
1413 StringBlock = (UINT8 *)AllocateZeroPool (OldBlockSize + Ucs2BlockSize);
1414 if (StringBlock == NULL) {
1415 Status = EFI_OUT_OF_RESOURCES;
1416 goto Done;
1417 }
1418
1419 //
1420 // Copy original string blocks, except the EFI_HII_SIBT_END.
1421 //
1422 CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));
1423 //
1424 // Create a EFI_HII_SIBT_STRING_UCS2 block
1425 //
1426 BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);
1427 *BlockPtr = EFI_HII_SIBT_STRING_UCS2;
1428 BlockPtr += sizeof (EFI_HII_STRING_BLOCK);
1429 CopyMem (BlockPtr, (EFI_STRING)String, StrSize ((EFI_STRING)String));
1430 BlockPtr += StrSize ((EFI_STRING)String);
1431
1432 //
1433 // Append a EFI_HII_SIBT_END block to the end.
1434 //
1435 *BlockPtr = EFI_HII_SIBT_END;
1436 ZeroMem (StringPackage->StringBlock, OldBlockSize);
1437 FreePool (StringPackage->StringBlock);
1438 StringPackage->StringBlock = StringBlock;
1439 StringPackage->StringPkgHdr->Header.Length += Ucs2BlockSize;
1440 PackageListNode->PackageListHdr.PackageLength += Ucs2BlockSize;
1441 } else {
1442 //
1443 // StringFontInfo is specified here. If there is a EFI_HII_SIBT_FONT_BLOCK
1444 // which refers to this font info, create a EFI_HII_SIBT_STRING_UCS2_FONT block
1445 // only. Otherwise create a EFI_HII_SIBT_FONT block with a EFI_HII_SIBT_STRING
1446 // _UCS2_FONT block.
1447 //
1448 Ucs2FontBlockSize = (UINT32)(StrSize (String) + sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) -
1449 sizeof (CHAR16));
1450 if (ReferFontInfoLocally (Private, StringPackage, StringPackage->FontId, FALSE, GlobalFont, &LocalFont)) {
1451 //
1452 // Create a EFI_HII_SIBT_STRING_UCS2_FONT block only.
1453 //
1454 StringBlock = (UINT8 *)AllocateZeroPool (OldBlockSize + Ucs2FontBlockSize);
1455 if (StringBlock == NULL) {
1456 Status = EFI_OUT_OF_RESOURCES;
1457 goto Done;
1458 }
1459
1460 //
1461 // Copy original string blocks, except the EFI_HII_SIBT_END.
1462 //
1463 CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));
1464 //
1465 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
1466 //
1467 BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);
1468 *BlockPtr = EFI_HII_SIBT_STRING_UCS2_FONT;
1469 BlockPtr += sizeof (EFI_HII_STRING_BLOCK);
1470 *BlockPtr = LocalFont->FontId;
1471 BlockPtr++;
1472 CopyMem (BlockPtr, (EFI_STRING)String, StrSize ((EFI_STRING)String));
1473 BlockPtr += StrSize ((EFI_STRING)String);
1474
1475 //
1476 // Append a EFI_HII_SIBT_END block to the end.
1477 //
1478 *BlockPtr = EFI_HII_SIBT_END;
1479 ZeroMem (StringPackage->StringBlock, OldBlockSize);
1480 FreePool (StringPackage->StringBlock);
1481 StringPackage->StringBlock = StringBlock;
1482 StringPackage->StringPkgHdr->Header.Length += Ucs2FontBlockSize;
1483 PackageListNode->PackageListHdr.PackageLength += Ucs2FontBlockSize;
1484 } else {
1485 //
1486 // EFI_HII_SIBT_FONT_BLOCK does not exist in current string package, so
1487 // create a EFI_HII_SIBT_FONT block to record the font info, then generate
1488 // a EFI_HII_SIBT_STRING_UCS2_FONT block to record the incoming string.
1489 //
1490 FontBlockSize = (UINT32)(StrSize (((EFI_FONT_INFO *)StringFontInfo)->FontName) +
1491 sizeof (EFI_HII_SIBT_FONT_BLOCK) - sizeof (CHAR16));
1492 StringBlock = (UINT8 *)AllocateZeroPool (OldBlockSize + FontBlockSize + Ucs2FontBlockSize);
1493 if (StringBlock == NULL) {
1494 Status = EFI_OUT_OF_RESOURCES;
1495 goto Done;
1496 }
1497
1498 //
1499 // Copy original string blocks, except the EFI_HII_SIBT_END.
1500 //
1501 CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));
1502
1503 //
1504 // Create a EFI_HII_SIBT_FONT block firstly and then backup its info in string
1505 // package instance for future reference.
1506 //
1507 BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);
1508
1509 Ext2.Header.BlockType = EFI_HII_SIBT_EXT2;
1510 Ext2.BlockType2 = EFI_HII_SIBT_FONT;
1511 Ext2.Length = (UINT16)FontBlockSize;
1512 CopyMem (BlockPtr, &Ext2, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
1513 BlockPtr += sizeof (EFI_HII_SIBT_EXT2_BLOCK);
1514
1515 *BlockPtr = LocalFont->FontId;
1516 BlockPtr++;
1517 CopyMem (BlockPtr, &((EFI_FONT_INFO *)StringFontInfo)->FontSize, sizeof (UINT16));
1518 BlockPtr += sizeof (UINT16);
1519 CopyMem (BlockPtr, &((EFI_FONT_INFO *)StringFontInfo)->FontStyle, sizeof (EFI_HII_FONT_STYLE));
1520 BlockPtr += sizeof (EFI_HII_FONT_STYLE);
1521 CopyMem (
1522 BlockPtr,
1523 &((EFI_FONT_INFO *)StringFontInfo)->FontName,
1524 StrSize (((EFI_FONT_INFO *)StringFontInfo)->FontName)
1525 );
1526 BlockPtr += StrSize (((EFI_FONT_INFO *)StringFontInfo)->FontName);
1527 //
1528 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
1529 //
1530 *BlockPtr = EFI_HII_SIBT_STRING_UCS2_FONT;
1531 BlockPtr += sizeof (EFI_HII_STRING_BLOCK);
1532 *BlockPtr = LocalFont->FontId;
1533 BlockPtr++;
1534 CopyMem (BlockPtr, (EFI_STRING)String, StrSize ((EFI_STRING)String));
1535 BlockPtr += StrSize ((EFI_STRING)String);
1536
1537 //
1538 // Append a EFI_HII_SIBT_END block to the end.
1539 //
1540 *BlockPtr = EFI_HII_SIBT_END;
1541 ZeroMem (StringPackage->StringBlock, OldBlockSize);
1542 FreePool (StringPackage->StringBlock);
1543 StringPackage->StringBlock = StringBlock;
1544 StringPackage->StringPkgHdr->Header.Length += FontBlockSize + Ucs2FontBlockSize;
1545 PackageListNode->PackageListHdr.PackageLength += FontBlockSize + Ucs2FontBlockSize;
1546
1547 //
1548 // Increase the FontId to make it unique since we already add
1549 // a EFI_HII_SIBT_FONT block to this string package.
1550 //
1551 StringPackage->FontId++;
1552 }
1553 }
1554
1555Done:
1556 if (!EFI_ERROR (Status) && NewStringPackageCreated) {
1557 //
1558 // Trigger any registered notification function for new string package
1559 //
1560 Status = InvokeRegisteredFunction (
1561 Private,
1562 EFI_HII_DATABASE_NOTIFY_NEW_PACK,
1563 (VOID *)StringPackage,
1564 EFI_HII_PACKAGE_STRINGS,
1565 PackageList
1566 );
1567 }
1568
1569 if (!EFI_ERROR (Status)) {
1570 //
1571 // Update MaxString Id to new StringId
1572 //
1573 for (Link = PackageListNode->StringPkgHdr.ForwardLink;
1574 Link != &PackageListNode->StringPkgHdr;
1575 Link = Link->ForwardLink
1576 )
1577 {
1578 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
1579 StringPackage->MaxStringId = *StringId;
1580 }
1581 } else if (NewStringPackageCreated) {
1582 //
1583 // Free the allocated new string Package when new string can't be added.
1584 //
1585 RemoveEntryList (&StringPackage->StringEntry);
1586 FreePool (StringPackage->StringBlock);
1587 FreePool (StringPackage->StringPkgHdr);
1588 FreePool (StringPackage);
1589 }
1590
1591 //
1592 // The contents of HiiDataBase may updated,need to check.
1593 //
1594 //
1595 // Check whether need to get the contents of HiiDataBase.
1596 // Only after ReadyToBoot to do the export.
1597 //
1599 if (!EFI_ERROR (Status)) {
1600 HiiGetDatabaseInfo (&Private->HiiDatabase);
1601 }
1602 }
1603
1604 EfiReleaseLock (&mHiiDatabaseLock);
1605
1606 return Status;
1607}
1608
1642EFI_STATUS
1643EFIAPI
1645 IN CONST EFI_HII_STRING_PROTOCOL *This,
1646 IN CONST CHAR8 *Language,
1647 IN EFI_HII_HANDLE PackageList,
1648 IN EFI_STRING_ID StringId,
1649 OUT EFI_STRING String,
1650 IN OUT UINTN *StringSize,
1651 OUT EFI_FONT_INFO **StringFontInfo OPTIONAL
1652 )
1653{
1654 EFI_STATUS Status;
1655 LIST_ENTRY *Link;
1657 HII_DATABASE_RECORD *DatabaseRecord;
1658 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;
1659 HII_STRING_PACKAGE_INSTANCE *StringPackage;
1660
1661 if ((This == NULL) || (Language == NULL) || (StringId < 1) || (StringSize == NULL) || (PackageList == NULL)) {
1662 return EFI_INVALID_PARAMETER;
1663 }
1664
1665 if ((String == NULL) && (*StringSize != 0)) {
1666 return EFI_INVALID_PARAMETER;
1667 }
1668
1669 if (!IsHiiHandleValid (PackageList)) {
1670 return EFI_NOT_FOUND;
1671 }
1672
1674 PackageListNode = NULL;
1675
1676 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
1677 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
1678 if (DatabaseRecord->Handle == PackageList) {
1679 PackageListNode = DatabaseRecord->PackageList;
1680 break;
1681 }
1682 }
1683
1684 if (PackageListNode != NULL) {
1685 //
1686 // First search: to match the StringId in the specified language.
1687 //
1688 for (Link = PackageListNode->StringPkgHdr.ForwardLink;
1689 Link != &PackageListNode->StringPkgHdr;
1690 Link = Link->ForwardLink
1691 )
1692 {
1693 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
1694 if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *)Language)) {
1695 Status = GetStringWorker (Private, StringPackage, StringId, String, StringSize, StringFontInfo);
1696 if (Status != EFI_NOT_FOUND) {
1697 return Status;
1698 }
1699 }
1700 }
1701
1702 //
1703 // Second search: to match the StringId in other available languages if exist.
1704 //
1705 for (Link = PackageListNode->StringPkgHdr.ForwardLink;
1706 Link != &PackageListNode->StringPkgHdr;
1707 Link = Link->ForwardLink
1708 )
1709 {
1710 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
1711 Status = GetStringWorker (Private, StringPackage, StringId, NULL, NULL, NULL);
1712 if (!EFI_ERROR (Status)) {
1713 return EFI_INVALID_LANGUAGE;
1714 }
1715 }
1716 }
1717
1718 return EFI_NOT_FOUND;
1719}
1720
1744EFI_STATUS
1745EFIAPI
1747 IN CONST EFI_HII_STRING_PROTOCOL *This,
1748 IN EFI_HII_HANDLE PackageList,
1749 IN EFI_STRING_ID StringId,
1750 IN CONST CHAR8 *Language,
1751 IN CONST EFI_STRING String,
1752 IN CONST EFI_FONT_INFO *StringFontInfo OPTIONAL
1753 )
1754{
1755 EFI_STATUS Status;
1756 LIST_ENTRY *Link;
1758 HII_DATABASE_RECORD *DatabaseRecord;
1759 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;
1760 HII_STRING_PACKAGE_INSTANCE *StringPackage;
1761 UINT32 OldPackageLen;
1762
1763 if ((This == NULL) || (Language == NULL) || (StringId < 1) || (String == NULL) || (PackageList == NULL)) {
1764 return EFI_INVALID_PARAMETER;
1765 }
1766
1767 if (!IsHiiHandleValid (PackageList)) {
1768 return EFI_NOT_FOUND;
1769 }
1770
1771 EfiAcquireLock (&mHiiDatabaseLock);
1772
1774 PackageListNode = NULL;
1775
1776 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
1777 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
1778 if (DatabaseRecord->Handle == PackageList) {
1779 PackageListNode = (HII_DATABASE_PACKAGE_LIST_INSTANCE *)(DatabaseRecord->PackageList);
1780 }
1781 }
1782
1783 if (PackageListNode != NULL) {
1784 for (Link = PackageListNode->StringPkgHdr.ForwardLink;
1785 Link != &PackageListNode->StringPkgHdr;
1786 Link = Link->ForwardLink
1787 )
1788 {
1789 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
1790 if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *)Language)) {
1791 OldPackageLen = StringPackage->StringPkgHdr->Header.Length;
1792 Status = SetStringWorker (
1793 Private,
1794 StringPackage,
1795 StringId,
1796 (EFI_STRING)String,
1797 (EFI_FONT_INFO *)StringFontInfo
1798 );
1799 if (EFI_ERROR (Status)) {
1800 EfiReleaseLock (&mHiiDatabaseLock);
1801 return Status;
1802 }
1803
1804 PackageListNode->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length - OldPackageLen;
1805 //
1806 // Check whether need to get the contents of HiiDataBase.
1807 // Only after ReadyToBoot to do the export.
1808 //
1810 HiiGetDatabaseInfo (&Private->HiiDatabase);
1811 }
1812
1813 EfiReleaseLock (&mHiiDatabaseLock);
1814 return EFI_SUCCESS;
1815 }
1816 }
1817 }
1818
1819 EfiReleaseLock (&mHiiDatabaseLock);
1820 return EFI_NOT_FOUND;
1821}
1822
1845EFI_STATUS
1846EFIAPI
1848 IN CONST EFI_HII_STRING_PROTOCOL *This,
1849 IN EFI_HII_HANDLE PackageList,
1850 IN OUT CHAR8 *Languages,
1851 IN OUT UINTN *LanguagesSize
1852 )
1853{
1854 LIST_ENTRY *Link;
1856 HII_DATABASE_RECORD *DatabaseRecord;
1857 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;
1858 HII_STRING_PACKAGE_INSTANCE *StringPackage;
1859 UINTN ResultSize;
1860
1861 if ((This == NULL) || (LanguagesSize == NULL) || (PackageList == NULL)) {
1862 return EFI_INVALID_PARAMETER;
1863 }
1864
1865 if ((*LanguagesSize != 0) && (Languages == NULL)) {
1866 return EFI_INVALID_PARAMETER;
1867 }
1868
1869 if (!IsHiiHandleValid (PackageList)) {
1870 return EFI_NOT_FOUND;
1871 }
1872
1874
1875 PackageListNode = NULL;
1876 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
1877 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
1878 if (DatabaseRecord->Handle == PackageList) {
1879 PackageListNode = DatabaseRecord->PackageList;
1880 break;
1881 }
1882 }
1883
1884 if (PackageListNode == NULL) {
1885 return EFI_NOT_FOUND;
1886 }
1887
1888 //
1889 // Search the languages in the specified packagelist.
1890 //
1891 ResultSize = 0;
1892 for (Link = PackageListNode->StringPkgHdr.ForwardLink;
1893 Link != &PackageListNode->StringPkgHdr;
1894 Link = Link->ForwardLink
1895 )
1896 {
1897 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
1898 ResultSize += AsciiStrSize (StringPackage->StringPkgHdr->Language);
1899 if (ResultSize <= *LanguagesSize) {
1900 AsciiStrCpyS (Languages, *LanguagesSize / sizeof (CHAR8), StringPackage->StringPkgHdr->Language);
1901 Languages += AsciiStrSize (StringPackage->StringPkgHdr->Language);
1902 *(Languages - 1) = L';';
1903 }
1904 }
1905
1906 if (ResultSize == 0) {
1907 return EFI_NOT_FOUND;
1908 }
1909
1910 if (*LanguagesSize < ResultSize) {
1911 *LanguagesSize = ResultSize;
1912 return EFI_BUFFER_TOO_SMALL;
1913 }
1914
1915 *(Languages - 1) = 0;
1916 return EFI_SUCCESS;
1917}
1918
1952EFI_STATUS
1953EFIAPI
1955 IN CONST EFI_HII_STRING_PROTOCOL *This,
1956 IN EFI_HII_HANDLE PackageList,
1957 IN CONST CHAR8 *PrimaryLanguage,
1958 IN OUT CHAR8 *SecondaryLanguages,
1959 IN OUT UINTN *SecondaryLanguagesSize
1960 )
1961{
1962 LIST_ENTRY *Link;
1963 LIST_ENTRY *Link1;
1965 HII_DATABASE_RECORD *DatabaseRecord;
1966 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;
1967 HII_STRING_PACKAGE_INSTANCE *StringPackage;
1968 CHAR8 *Languages;
1969 UINTN ResultSize;
1970
1971 if ((This == NULL) || (PackageList == NULL) || (PrimaryLanguage == NULL) || (SecondaryLanguagesSize == NULL)) {
1972 return EFI_INVALID_PARAMETER;
1973 }
1974
1975 if ((SecondaryLanguages == NULL) && (*SecondaryLanguagesSize != 0)) {
1976 return EFI_INVALID_PARAMETER;
1977 }
1978
1979 if (!IsHiiHandleValid (PackageList)) {
1980 return EFI_NOT_FOUND;
1981 }
1982
1984
1985 PackageListNode = NULL;
1986 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
1987 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
1988 if (DatabaseRecord->Handle == PackageList) {
1989 PackageListNode = (HII_DATABASE_PACKAGE_LIST_INSTANCE *)(DatabaseRecord->PackageList);
1990 break;
1991 }
1992 }
1993
1994 if (PackageListNode == NULL) {
1995 return EFI_NOT_FOUND;
1996 }
1997
1998 Languages = NULL;
1999 ResultSize = 0;
2000 for (Link1 = PackageListNode->StringPkgHdr.ForwardLink;
2001 Link1 != &PackageListNode->StringPkgHdr;
2002 Link1 = Link1->ForwardLink
2003 )
2004 {
2005 StringPackage = CR (Link1, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
2006 if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *)PrimaryLanguage)) {
2007 Languages = StringPackage->StringPkgHdr->Language;
2008 //
2009 // Language is a series of ';' terminated strings, first one is primary
2010 // language and following with other secondary languages or NULL if no
2011 // secondary languages any more.
2012 //
2013 Languages = AsciiStrStr (Languages, ";");
2014 if (Languages == NULL) {
2015 break;
2016 }
2017
2018 Languages++;
2019
2020 ResultSize = AsciiStrSize (Languages);
2021 if (ResultSize <= *SecondaryLanguagesSize) {
2022 AsciiStrCpyS (SecondaryLanguages, *SecondaryLanguagesSize / sizeof (CHAR8), Languages);
2023 } else {
2024 *SecondaryLanguagesSize = ResultSize;
2025 return EFI_BUFFER_TOO_SMALL;
2026 }
2027
2028 return EFI_SUCCESS;
2029 }
2030 }
2031
2032 return EFI_INVALID_LANGUAGE;
2033}
2034
2042VOID
2043EFIAPI
2045 IN CHAR8 *ConfigString
2046 )
2047{
2048 ASSERT (ConfigString != NULL);
2049
2050 //
2051 // Convert all hex digits in range [A-F] in the configuration header to [a-f]
2052 //
2053 for ( ; *ConfigString != '\0'; ConfigString++) {
2054 if ((*ConfigString >= 'A') && (*ConfigString <= 'Z')) {
2055 *ConfigString = (CHAR8)(*ConfigString - 'A' + 'a');
2056 }
2057 }
2058}
2059
2070BOOLEAN
2072 IN CHAR8 *Language1,
2073 IN CHAR8 *Language2
2074 )
2075{
2076 UINTN Index;
2077 UINTN StrLen;
2078 CHAR8 *Lan1;
2079 CHAR8 *Lan2;
2080
2081 //
2082 // Convert to lower to compare.
2083 //
2084 StrLen = AsciiStrSize (Language1);
2085 Lan1 = AllocateZeroPool (StrLen);
2086 ASSERT (Lan1 != NULL);
2087 AsciiStrCpyS (Lan1, StrLen / sizeof (CHAR8), Language1);
2088 AsciiHiiToLower (Lan1);
2089
2090 StrLen = AsciiStrSize (Language2);
2091 Lan2 = AllocateZeroPool (StrLen);
2092 ASSERT (Lan2 != NULL);
2093 AsciiStrCpyS (Lan2, StrLen / sizeof (CHAR8), Language2);
2094 AsciiHiiToLower (Lan2);
2095
2096 //
2097 // Compare the Primary Language in Language1 to Language2
2098 //
2099 for (Index = 0; Lan1[Index] != 0 && Lan1[Index] != ';'; Index++) {
2100 if (Lan1[Index] != Lan2[Index]) {
2101 //
2102 // Return FALSE if any characters are different.
2103 //
2104 FreePool (Lan1);
2105 FreePool (Lan2);
2106 return FALSE;
2107 }
2108 }
2109
2110 FreePool (Lan1);
2111 FreePool (Lan2);
2112
2113 //
2114 // Only return TRUE if Language2[Index] is a Null-terminator which means
2115 // the Primary Language in Language1 is the same length as Language2. If
2116 // Language2[Index] is not a Null-terminator, then Language2 is longer than
2117 // the Primary Language in Language1, and FALSE must be returned.
2118 //
2119 return (BOOLEAN)(Language2[Index] == 0);
2120}
UINT16 BlockSize
Definition Apm.h:32
EFI_STATUS HiiGetDatabaseInfo(IN CONST EFI_HII_DATABASE_PROTOCOL *This)
Definition Database.c:3467
BOOLEAN IsHiiHandleValid(EFI_HII_HANDLE Handle)
Definition Database.c:123
EFI_STATUS InvokeRegisteredFunction(IN HII_DATABASE_PRIVATE_DATA *Private, IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, IN VOID *PackageInstance, IN UINT8 PackageType, IN EFI_HII_HANDLE Handle)
Definition Database.c:160
EFI_LOCK mHiiDatabaseLock
Definition Database.c:25
BOOLEAN IsFontInfoExisted(IN HII_DATABASE_PRIVATE_DATA *Private, IN EFI_FONT_INFO *FontInfo, IN EFI_FONT_INFO_MASK *FontInfoMask, OPTIONAL IN EFI_FONT_HANDLE FontHandle, OPTIONAL OUT HII_GLOBAL_FONT_INFO **GlobalFontInfo OPTIONAL)
Definition Font.c:1175
BOOLEAN gExportAfterReadyToBoot
#define HII_DATABASE_RECORD_SIGNATURE
#define HII_GLOBAL_FONT_INFO_SIGNATURE
#define HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS(a)
#define HII_DATABASE_PRIVATE_DATA_SIGNATURE
#define HII_STRING_PACKAGE_SIGNATURE
#define HII_FONT_INFO_SIGNATURE
EFI_STATUS GetStringWorker(IN HII_DATABASE_PRIVATE_DATA *Private, IN HII_STRING_PACKAGE_INSTANCE *StringPackage, IN EFI_STRING_ID StringId, OUT EFI_STRING String, IN OUT UINTN *StringSize, OPTIONAL OUT EFI_FONT_INFO **StringFontInfo OPTIONAL)
Definition String.c:618
EFI_STATUS SetStringWorker(IN HII_DATABASE_PRIVATE_DATA *Private, IN OUT HII_STRING_PACKAGE_INSTANCE *StringPackage, IN EFI_STRING_ID StringId, IN EFI_STRING String, IN EFI_FONT_INFO *StringFontInfo OPTIONAL)
Definition String.c:886
EFI_STATUS FindStringBlock(IN HII_DATABASE_PRIVATE_DATA *Private, IN HII_STRING_PACKAGE_INSTANCE *StringPackage, IN EFI_STRING_ID StringId, OUT UINT8 *BlockType, OPTIONAL OUT UINT8 **StringBlockAddr, OPTIONAL OUT UINTN *StringTextOffset, OPTIONAL OUT EFI_STRING_ID *LastStringId, OPTIONAL OUT EFI_STRING_ID *StartStringId OPTIONAL)
Definition String.c:255
EFI_STATUS ConvertToUnicodeText(OUT EFI_STRING StringDest, IN CHAR8 *StringSrc, IN OUT UINTN *BufferSize)
Definition String.c:109
EFI_STATUS InsertLackStringBlock(IN OUT HII_STRING_PACKAGE_INSTANCE *StringPackage, IN EFI_STRING_ID StartStringId, IN EFI_STRING_ID StringId, IN OUT UINT8 *BlockType, IN OUT UINT8 **StringBlockAddr, IN BOOLEAN FontBlock)
Definition String.c:731
BOOLEAN ReferFontInfoLocally(IN HII_DATABASE_PRIVATE_DATA *Private, IN HII_STRING_PACKAGE_INSTANCE *StringPackage, IN UINT8 FontId, IN BOOLEAN DuplicateEnable, IN HII_GLOBAL_FONT_INFO *GlobalFontInfo, OUT HII_FONT_INFO **LocalFontInfo)
Definition String.c:44
EFI_STATUS EFIAPI InternalHiiGetString(IN CONST EFI_HII_STRING_PROTOCOL *This, IN CONST CHAR8 *Language, IN EFI_HII_HANDLE PackageList, IN EFI_STRING_ID StringId, OUT EFI_STRING String, IN OUT UINTN *StringSize, OUT EFI_FONT_INFO **StringFontInfo OPTIONAL)
Definition String.c:1644
EFI_STATUS EFIAPI HiiGetSecondaryLanguages(IN CONST EFI_HII_STRING_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, IN CONST CHAR8 *PrimaryLanguage, IN OUT CHAR8 *SecondaryLanguages, IN OUT UINTN *SecondaryLanguagesSize)
Definition String.c:1954
EFI_STATUS EFIAPI HiiGetLanguages(IN CONST EFI_HII_STRING_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, IN OUT CHAR8 *Languages, IN OUT UINTN *LanguagesSize)
Definition String.c:1847
EFI_STATUS EFIAPI InternalHiiSetString(IN CONST EFI_HII_STRING_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, IN EFI_STRING_ID StringId, IN CONST CHAR8 *Language, IN CONST EFI_STRING String, IN CONST EFI_FONT_INFO *StringFontInfo OPTIONAL)
Definition String.c:1746
CHAR16 mLanguageWindow[16]
Definition String.c:13
EFI_STATUS EFIAPI HiiNewString(IN CONST EFI_HII_STRING_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, OUT EFI_STRING_ID *StringId, IN CONST CHAR8 *Language, IN CONST CHAR16 *LanguageName, OPTIONAL IN CONST EFI_STRING String, IN CONST EFI_FONT_INFO *StringFontInfo OPTIONAL)
Definition String.c:1156
EFI_STATUS GetUnicodeStringTextOrSize(OUT EFI_STRING StringDest, OPTIONAL IN UINT8 *StringSrc, IN OUT UINTN *BufferSize)
Definition String.c:152
BOOLEAN HiiCompareLanguage(IN CHAR8 *Language1, IN CHAR8 *Language2)
Definition String.c:2071
EFI_STATUS GetStringFontInfo(IN HII_STRING_PACKAGE_INSTANCE *StringPackage, IN UINT8 FontId, OUT EFI_FONT_INFO **StringFontInfo)
Definition String.c:199
VOID EFIAPI AsciiHiiToLower(IN CHAR8 *ConfigString)
Definition String.c:2044
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
UINT16 EFIAPI ReadUnaligned16(IN CONST UINT16 *Buffer)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define ASSERT(x)
Definition coder.h:55
EFI_HII_PACKAGE_LIST_HEADER PackageListHdr
EFI_HII_DATABASE_PROTOCOL HiiDatabase
HII_DATABASE_PACKAGE_LIST_INSTANCE * PackageList
EFI_HII_HANDLE Handle
LIST_ENTRY Entry
LIST_ENTRY * GlobalEntry
EFI_FONT_INFO * FontInfo
EFI_HII_STRING_PACKAGE_HDR * StringPkgHdr