]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/HiiDatabaseDxe/String.c
De-unicode in comment for all source files.
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / String.c
1 /** @file
2
3 Copyright (c) 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 String.c
15
16 Abstract:
17
18 Implementation for EFI_HII_STRING_PROTOCOL.
19
20 Revision History
21
22
23 **/
24
25
26 #include "HiiDatabase.h"
27
28 CHAR16 mLanguageWindow[16] = {
29 0x0000, 0x0080, 0x0100, 0x0300,
30 0x2000, 0x2080, 0x2100, 0x3000,
31 0x0080, 0x00C0, 0x0400, 0x0600,
32 0x0900, 0x3040, 0x30A0, 0xFF00
33 };
34
35
36 /**
37 This function checks whether a global font info is referred by local
38 font info list or not. (i.e. HII_FONT_INFO is generated.) If not, create
39 a HII_FONT_INFO to refer it locally.
40
41 @param Private Hii database private structure.
42 @param StringPackage HII string package instance.
43 @param DuplicateEnable If true, duplicate HII_FONT_INFO which refers to
44 the same EFI_FONT_INFO is permitted. Otherwise it
45 is not allowed.
46 @param GlobalFontInfo Input a global font info which specify a
47 EFI_FONT_INFO.
48 @param LocalFontInfo Output a local font info which refers to a
49 EFI_FONT_INFO.
50
51 @retval TRUE Already referred before calling this function.
52 @retval FALSE Not referred before calling this function.
53
54 **/
55 STATIC
56 BOOLEAN
57 ReferFontInfoLocally (
58 IN HII_DATABASE_PRIVATE_DATA *Private,
59 IN HII_STRING_PACKAGE_INSTANCE *StringPackage,
60 IN BOOLEAN DuplicateEnable,
61 IN HII_GLOBAL_FONT_INFO *GlobalFontInfo,
62 OUT HII_FONT_INFO **LocalFontInfo
63 )
64 {
65 HII_FONT_INFO *LocalFont;
66 LIST_ENTRY *Link;
67
68 ASSERT (Private != NULL && StringPackage != NULL && GlobalFontInfo != NULL && LocalFontInfo != NULL);
69
70 if (!DuplicateEnable) {
71 for (Link = StringPackage->FontInfoList.ForwardLink;
72 Link != &StringPackage->FontInfoList;
73 Link = Link->ForwardLink
74 ) {
75 LocalFont = CR (Link, HII_FONT_INFO, Entry, HII_FONT_INFO_SIGNATURE);
76 if (LocalFont->GlobalEntry == &GlobalFontInfo->Entry) {
77 //
78 // Already referred by local font info list, return directly.
79 //
80 *LocalFontInfo = LocalFont;
81 return TRUE;
82 }
83 }
84 }
85 //
86 // Since string package tool set FontId initially to 0 and increases it
87 // progressively by one, StringPackage->FondId always represents an unique
88 // and available FontId.
89 //
90 // FontId identifies EFI_FONT_INFO in local string package uniquely.
91 // GlobalEntry points to a HII_GLOBAL_FONT_INFO which identifies
92 // EFI_FONT_INFO uniquely in whole hii database.
93 //
94 LocalFont = (HII_FONT_INFO *) AllocateZeroPool (sizeof (HII_FONT_INFO));
95 ASSERT (LocalFont != NULL);
96
97 LocalFont->Signature = HII_FONT_INFO_SIGNATURE;
98 LocalFont->FontId = StringPackage->FontId;
99 LocalFont->GlobalEntry = &GlobalFontInfo->Entry;
100 InsertTailList (&StringPackage->FontInfoList, &LocalFont->Entry);
101
102 StringPackage->FontId++;
103
104 *LocalFontInfo = LocalFont;
105 return FALSE;
106 }
107
108
109 /**
110 Convert Ascii string text to unicode string test.
111
112 @param StringSrc Points to current null-terminated Ascii string.
113 @param StringDest Buffer to store the converted string text.
114 @param BufferSize Length of the buffer.
115
116 @retval EFI_SUCCESS The string text was outputed successfully.
117 @retval EFI_BUFFER_TOO_SMALL Buffer is insufficient to store the found string
118 text. BufferSize is updated to the required buffer
119 size.
120
121 **/
122 STATIC
123 EFI_STATUS
124 ConvertToUnicodeText (
125 OUT EFI_STRING StringDest,
126 IN CHAR8 *StringSrc,
127 IN OUT UINTN *BufferSize
128 )
129 {
130 UINTN StringSize;
131 UINTN Index;
132
133 ASSERT (StringSrc != NULL && BufferSize != NULL);
134
135 StringSize = AsciiStrSize (StringSrc) * 2;
136 if (*BufferSize < StringSize) {
137 *BufferSize = StringSize;
138 return EFI_BUFFER_TOO_SMALL;
139 }
140
141 for (Index = 0; Index < AsciiStrLen (StringSrc); Index++) {
142 StringDest[Index] = (CHAR16) StringSrc[Index];
143 }
144
145 StringDest[Index] = 0;
146 return EFI_SUCCESS;
147 }
148
149
150 /**
151 Calculate the size of StringSrc and output it. If StringDest is not NULL,
152 copy string text from src to dest.
153
154 @param StringSrc Points to current null-terminated string.
155 @param StringDest Buffer to store the string text.
156 @param BufferSize Length of the buffer.
157
158 @retval EFI_SUCCESS The string text was outputed successfully.
159 @retval EFI_BUFFER_TOO_SMALL Buffer is insufficient to store the found string
160 text. BufferSize is updated to the required buffer
161 size.
162
163 **/
164 STATIC
165 EFI_STATUS
166 GetUnicodeStringTextOrSize (
167 OUT EFI_STRING StringDest, OPTIONAL
168 IN UINT8 *StringSrc,
169 IN OUT UINTN *BufferSize
170 )
171 {
172 UINTN StringSize;
173 CHAR16 Zero;
174 UINT8 *StringPtr;
175
176 ASSERT (StringSrc != NULL && BufferSize != NULL);
177
178 ZeroMem (&Zero, sizeof (CHAR16));
179 StringSize = sizeof (CHAR16);
180 StringPtr = StringSrc;
181 while (CompareMem (StringPtr, &Zero, sizeof (CHAR16)) != 0) {
182 StringSize += sizeof (CHAR16);
183 StringPtr += sizeof (CHAR16);
184 }
185
186 if (StringDest != NULL) {
187 if (*BufferSize < StringSize) {
188 *BufferSize = StringSize;
189 return EFI_BUFFER_TOO_SMALL;
190 }
191 CopyMem (StringDest, StringSrc, StringSize);
192 return EFI_SUCCESS;
193 }
194
195 *BufferSize = StringSize;
196 return EFI_SUCCESS;
197 }
198
199
200 /**
201 Copy string font info to a buffer.
202
203 @param StringPackage Hii string package instance.
204 @param FontId Font identifier which is unique in a string
205 package.
206 @param StringFontInfo Buffer to record the output font info. It's
207 caller's responsibility to free this buffer.
208
209 @retval EFI_SUCCESS The string font is outputed successfully.
210 @retval EFI_NOT_FOUND The specified font id does not exist.
211
212 **/
213 STATIC
214 EFI_STATUS
215 GetStringFontInfo (
216 IN HII_STRING_PACKAGE_INSTANCE *StringPackage,
217 IN UINT8 FontId,
218 OUT EFI_FONT_INFO **StringFontInfo
219 )
220 {
221 LIST_ENTRY *Link;
222 HII_FONT_INFO *FontInfo;
223 HII_GLOBAL_FONT_INFO *GlobalFont;
224
225 ASSERT (StringFontInfo != NULL && StringPackage != NULL);
226
227 for (Link = StringPackage->FontInfoList.ForwardLink; Link != &StringPackage->FontInfoList; Link = Link->ForwardLink) {
228 FontInfo = CR (Link, HII_FONT_INFO, Entry, HII_FONT_INFO_SIGNATURE);
229 if (FontInfo->FontId == FontId) {
230 GlobalFont = CR (FontInfo->GlobalEntry, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);
231 *StringFontInfo = (EFI_FONT_INFO *) AllocateZeroPool (GlobalFont->FontInfoSize);
232 if (*StringFontInfo == NULL) {
233 return EFI_OUT_OF_RESOURCES;
234 }
235 CopyMem (*StringFontInfo, GlobalFont->FontInfo, GlobalFont->FontInfoSize);
236 return EFI_SUCCESS;
237 }
238 }
239
240 return EFI_NOT_FOUND;
241 }
242
243
244 /**
245 Parse all string blocks to find a String block specified by StringId.
246 If StringId = (EFI_STRING_ID) (-1), find out all EFI_HII_SIBT_FONT blocks
247 within this string package and backup its information.
248 If StringId = 0, output the string id of last string block (EFI_HII_SIBT_END).
249
250 @param Private Hii database private structure.
251 @param StringPackage Hii string package instance.
252 @param StringId The string's id, which is unique within
253 PackageList.
254 @param BlockType Output the block type of found string block.
255 @param StringBlockAddr Output the block address of found string block.
256 @param StringTextOffset Offset, relative to the found block address, of
257 the string text information.
258 @param LastStringId Output the last string id when StringId = 0.
259
260 @retval EFI_SUCCESS The string text and font is retrieved
261 successfully.
262 @retval EFI_NOT_FOUND The specified text or font info can not be found
263 out.
264 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
265 task.
266
267 **/
268 EFI_STATUS
269 FindStringBlock (
270 IN HII_DATABASE_PRIVATE_DATA *Private,
271 IN HII_STRING_PACKAGE_INSTANCE *StringPackage,
272 IN EFI_STRING_ID StringId,
273 OUT UINT8 *BlockType, OPTIONAL
274 OUT UINT8 **StringBlockAddr, OPTIONAL
275 OUT UINTN *StringTextOffset, OPTIONAL
276 OUT EFI_STRING_ID *LastStringId OPTIONAL
277 )
278 {
279 UINT8 *BlockHdr;
280 EFI_STRING_ID CurrentStringId;
281 UINTN BlockSize;
282 UINTN Index;
283 UINT8 *StringTextPtr;
284 UINTN Offset;
285 HII_FONT_INFO *LocalFont;
286 EFI_FONT_INFO *FontInfo;
287 HII_GLOBAL_FONT_INFO *GlobalFont;
288 UINTN FontInfoSize;
289 UINT16 StringCount;
290 UINT16 SkipCount;
291 EFI_HII_FONT_STYLE FontStyle;
292 UINT16 FontSize;
293 UINT8 Length8;
294 EFI_HII_SIBT_EXT2_BLOCK Ext2;
295 UINT32 Length32;
296 UINTN StringSize;
297 CHAR16 Zero;
298
299 ASSERT (StringPackage != NULL);
300 ASSERT (StringPackage->Signature == HII_STRING_PACKAGE_SIGNATURE);
301
302 CurrentStringId = 1;
303
304 if (StringId != (EFI_STRING_ID) (-1) && StringId != 0) {
305 ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);
306 } else {
307 ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
308 }
309
310 ZeroMem (&Zero, sizeof (CHAR16));
311
312 //
313 // Parse the string blocks to get the string text and font.
314 //
315 BlockHdr = StringPackage->StringBlock;
316 BlockSize = 0;
317 Offset = 0;
318 while (*BlockHdr != EFI_HII_SIBT_END) {
319 switch (*BlockHdr) {
320 case EFI_HII_SIBT_STRING_SCSU:
321 Offset = sizeof (EFI_HII_STRING_BLOCK);
322 StringTextPtr = BlockHdr + Offset;
323 BlockSize += Offset + AsciiStrSize ((CHAR8 *) StringTextPtr);
324 CurrentStringId++;
325 break;
326
327 case EFI_HII_SIBT_STRING_SCSU_FONT:
328 Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
329 StringTextPtr = BlockHdr + Offset;
330 BlockSize += Offset + AsciiStrSize ((CHAR8 *) StringTextPtr);
331 CurrentStringId++;
332 break;
333
334 case EFI_HII_SIBT_STRINGS_SCSU:
335 CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
336 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8);
337 BlockSize += StringTextPtr - BlockHdr;
338
339 for (Index = 0; Index < StringCount; Index++) {
340 BlockSize += AsciiStrSize ((CHAR8 *) StringTextPtr);
341 if (CurrentStringId == StringId) {
342 *BlockType = *BlockHdr;
343 *StringBlockAddr = BlockHdr;
344 *StringTextOffset = StringTextPtr - BlockHdr;
345 return EFI_SUCCESS;
346 }
347 StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *) StringTextPtr);
348 CurrentStringId++;
349 }
350 break;
351
352 case EFI_HII_SIBT_STRINGS_SCSU_FONT:
353 CopyMem (
354 &StringCount,
355 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
356 sizeof (UINT16)
357 );
358 StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8);
359 BlockSize += StringTextPtr - BlockHdr;
360
361 for (Index = 0; Index < StringCount; Index++) {
362 BlockSize += AsciiStrSize ((CHAR8 *) StringTextPtr);
363 if (CurrentStringId == StringId) {
364 *BlockType = *BlockHdr;
365 *StringBlockAddr = BlockHdr;
366 *StringTextOffset = StringTextPtr - BlockHdr;
367 return EFI_SUCCESS;
368 }
369 StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *) StringTextPtr);
370 CurrentStringId++;
371 }
372 break;
373
374 case EFI_HII_SIBT_STRING_UCS2:
375 Offset = sizeof (EFI_HII_STRING_BLOCK);
376 StringTextPtr = BlockHdr + Offset;
377 //
378 // Use StringSize to store the size of the specified string, including the NULL
379 // terminator.
380 //
381 GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);
382 BlockSize += Offset + StringSize;
383 CurrentStringId++;
384 break;
385
386 case EFI_HII_SIBT_STRING_UCS2_FONT:
387 Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);
388 StringTextPtr = BlockHdr + Offset;
389 //
390 // Use StrSize to store the size of the specified string, including the NULL
391 // terminator.
392 //
393 GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);
394 BlockSize += Offset + StringSize;
395 CurrentStringId++;
396 break;
397
398 case EFI_HII_SIBT_STRINGS_UCS2:
399 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
400 StringTextPtr = BlockHdr + Offset;
401 BlockSize += Offset;
402 CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
403 for (Index = 0; Index < StringCount; Index++) {
404 GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);
405 BlockSize += StringSize;
406 if (CurrentStringId == StringId) {
407 *BlockType = *BlockHdr;
408 *StringBlockAddr = BlockHdr;
409 *StringTextOffset = StringTextPtr - BlockHdr;
410 return EFI_SUCCESS;
411 }
412 StringTextPtr = StringTextPtr + StringSize;
413 CurrentStringId++;
414 }
415 break;
416
417 case EFI_HII_SIBT_STRINGS_UCS2_FONT:
418 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
419 StringTextPtr = BlockHdr + Offset;
420 BlockSize += Offset;
421 CopyMem (
422 &StringCount,
423 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
424 sizeof (UINT16)
425 );
426 for (Index = 0; Index < StringCount; Index++) {
427 GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);
428 BlockSize += StringSize;
429 if (CurrentStringId == StringId) {
430 *BlockType = *BlockHdr;
431 *StringBlockAddr = BlockHdr;
432 *StringTextOffset = StringTextPtr - BlockHdr;
433 return EFI_SUCCESS;
434 }
435 StringTextPtr = StringTextPtr + StringSize;
436 CurrentStringId++;
437 }
438 break;
439
440 case EFI_HII_SIBT_DUPLICATE:
441 if (CurrentStringId == StringId) {
442 //
443 // Incoming StringId is an id of a duplicate string block.
444 // Update the StringId to be the previous string block.
445 // Go back to the header of string block to search.
446 //
447 CopyMem (
448 &StringId,
449 BlockHdr + sizeof (EFI_HII_STRING_BLOCK),
450 sizeof (EFI_STRING_ID)
451 );
452 ASSERT (StringId != CurrentStringId);
453 CurrentStringId = 1;
454 BlockSize = 0;
455 } else {
456 BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
457 CurrentStringId++;
458 }
459 break;
460
461 case EFI_HII_SIBT_SKIP1:
462 SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
463 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
464 BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
465 break;
466
467 case EFI_HII_SIBT_SKIP2:
468 CopyMem (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
469 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
470 BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
471 break;
472
473 case EFI_HII_SIBT_EXT1:
474 CopyMem (
475 &Length8,
476 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
477 sizeof (UINT8)
478 );
479 BlockSize += Length8;
480 break;
481
482 case EFI_HII_SIBT_EXT2:
483 CopyMem (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
484 if (Ext2.BlockType2 == EFI_HII_SIBT_FONT && StringId == (EFI_STRING_ID) (-1)) {
485 //
486 // Find the relationship between global font info and the font info of
487 // this EFI_HII_SIBT_FONT block then backup its information in local package.
488 //
489 BlockHdr += sizeof (EFI_HII_SIBT_EXT2_BLOCK) + sizeof (UINT8);
490 CopyMem (&FontSize, BlockHdr, sizeof (UINT16));
491 BlockHdr += sizeof (UINT16);
492 CopyMem (&FontStyle, BlockHdr, sizeof (EFI_HII_FONT_STYLE));
493 BlockHdr += sizeof (EFI_HII_FONT_STYLE);
494 GetUnicodeStringTextOrSize (NULL, BlockHdr, &StringSize);
495
496 FontInfoSize = sizeof (EFI_FONT_INFO) - sizeof (CHAR16) + StringSize;
497 FontInfo = (EFI_FONT_INFO *) AllocateZeroPool (FontInfoSize);
498 if (FontInfo == NULL) {
499 return EFI_OUT_OF_RESOURCES;
500 }
501 FontInfo->FontStyle = FontStyle;
502 FontInfo->FontSize = FontSize;
503 CopyMem (FontInfo->FontName, BlockHdr, StringSize);
504
505 if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, &GlobalFont)) {
506 //
507 // If find the corresponding global font info, save the relationship.
508 //
509 ReferFontInfoLocally (Private, StringPackage, TRUE, GlobalFont, &LocalFont);
510 }
511
512 //
513 // If can not find, ignore this EFI_HII_SIBT_FONT block.
514 //
515 SafeFreePool (FontInfo);
516 }
517
518 BlockSize += Ext2.Length;
519
520 break;
521
522 case EFI_HII_SIBT_EXT4:
523 CopyMem (
524 &Length32,
525 BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
526 sizeof (UINT32)
527 );
528
529 BlockSize += Length32;
530 break;
531
532 default:
533 break;
534 }
535
536 if (StringId > 0) {
537 if (StringId == CurrentStringId - 1) {
538 *BlockType = *BlockHdr;
539 *StringBlockAddr = BlockHdr;
540 *StringTextOffset = Offset;
541 return EFI_SUCCESS;
542 }
543
544 if (StringId < CurrentStringId - 1) {
545 return EFI_NOT_FOUND;
546 }
547 }
548 BlockHdr = StringPackage->StringBlock + BlockSize;
549
550 }
551
552 if (StringId == (EFI_STRING_ID) (-1)) {
553 return EFI_SUCCESS;
554 }
555
556 if (StringId == 0 && LastStringId != NULL) {
557 *LastStringId = CurrentStringId;
558 return EFI_SUCCESS;
559 }
560
561 return EFI_NOT_FOUND;
562 }
563
564
565 /**
566 Parse all string blocks to get a string specified by StringId.
567
568 @param Private Hii database private structure.
569 @param StringPackage Hii string package instance.
570 @param StringId The string's id, which is unique within
571 PackageList.
572 @param String Points to retrieved null-terminated string.
573 @param StringSize On entry, points to the size of the buffer pointed
574 to by String, in bytes. On return, points to the
575 length of the string, in bytes.
576 @param StringFontInfo If not NULL, allocate a buffer to record the
577 output font info. It's caller's responsibility to
578 free this buffer.
579
580 @retval EFI_SUCCESS The string text and font is retrieved
581 successfully.
582 @retval EFI_NOT_FOUND The specified text or font info can not be found
583 out.
584 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to
585 hold the string.
586
587 **/
588 STATIC
589 EFI_STATUS
590 GetStringWorker (
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
597 )
598 {
599 UINT8 *StringTextPtr;
600 UINT8 BlockType;
601 UINT8 *StringBlockAddr;
602 UINTN StringTextOffset;
603 EFI_STATUS Status;
604 UINT8 FontId;
605
606 ASSERT (StringPackage != NULL && StringSize != NULL);
607 ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
608
609 //
610 // Find the specified string block
611 //
612 Status = FindStringBlock (
613 Private,
614 StringPackage,
615 StringId,
616 &BlockType,
617 &StringBlockAddr,
618 &StringTextOffset,
619 NULL
620 );
621 if (EFI_ERROR (Status)) {
622 return Status;
623 }
624
625 //
626 // Get the string text.
627 //
628 StringTextPtr = StringBlockAddr + StringTextOffset;
629 switch (BlockType) {
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);
635 break;
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);
641 break;
642 default:
643 return EFI_NOT_FOUND;
644 }
645 if (EFI_ERROR (Status)) {
646 return Status;
647 }
648
649 //
650 // Get the string font.
651 //
652 if (StringFontInfo != NULL) {
653 switch (BlockType) {
654 case EFI_HII_SIBT_STRING_SCSU_FONT:
655 case EFI_HII_SIBT_STRINGS_SCSU_FONT:
656 case EFI_HII_SIBT_STRING_UCS2_FONT:
657 case EFI_HII_SIBT_STRINGS_UCS2_FONT:
658 FontId = *(StringBlockAddr + sizeof (EFI_HII_STRING_BLOCK));
659 return GetStringFontInfo (StringPackage, FontId, StringFontInfo);
660 break;
661 default:
662 break;
663 }
664 }
665
666 return EFI_SUCCESS;
667 }
668
669
670 /**
671 Parse all string blocks to set a String specified by StringId.
672
673 @param Private HII database driver private structure.
674 @param StringPackage HII string package instance.
675 @param StringId The string's id, which is unique within
676 PackageList.
677 @param String Points to the new null-terminated string.
678 @param StringFontInfo Points to the input font info.
679
680 @retval EFI_SUCCESS The string was updated successfully.
681 @retval EFI_NOT_FOUND The string specified by StringId is not in the
682 database.
683 @retval EFI_INVALID_PARAMETER The String or Language was NULL.
684 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
685 current database.
686 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
687 task.
688
689 **/
690 STATIC
691 EFI_STATUS
692 SetStringWorker (
693 IN HII_DATABASE_PRIVATE_DATA *Private,
694 IN OUT HII_STRING_PACKAGE_INSTANCE *StringPackage,
695 IN EFI_STRING_ID StringId,
696 IN EFI_STRING String,
697 IN EFI_FONT_INFO *StringFontInfo OPTIONAL
698 )
699 {
700 UINT8 *StringTextPtr;
701 UINT8 BlockType;
702 UINT8 *StringBlockAddr;
703 UINTN StringTextOffset;
704 EFI_STATUS Status;
705 UINT8 *Block;
706 UINT8 *BlockPtr;
707 UINTN BlockSize;
708 UINTN OldBlockSize;
709 HII_FONT_INFO *LocalFont;
710 HII_GLOBAL_FONT_INFO *GlobalFont;
711 BOOLEAN Referred;
712 EFI_HII_SIBT_EXT2_BLOCK Ext2;
713 UINTN StringSize;
714 UINTN TmpSize;
715
716
717 ASSERT (Private != NULL && StringPackage != NULL && String != NULL);
718 ASSERT (Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
719 //
720 // Find the specified string block
721 //
722 Status = FindStringBlock (
723 Private,
724 StringPackage,
725 StringId,
726 &BlockType,
727 &StringBlockAddr,
728 &StringTextOffset,
729 NULL
730 );
731 if (EFI_ERROR (Status)) {
732 return Status;
733 }
734
735 LocalFont = NULL;
736 GlobalFont = NULL;
737 Referred = FALSE;
738
739 //
740 // Set the string font according to input font information.
741 //
742 if (StringFontInfo != NULL) {
743 //
744 // The input StringFontInfo should exist in current database
745 //
746 if (!IsFontInfoExisted (Private, StringFontInfo, NULL, NULL, &GlobalFont)) {
747 return EFI_INVALID_PARAMETER;
748 } else {
749 Referred = ReferFontInfoLocally (Private, StringPackage, FALSE, GlobalFont, &LocalFont);
750 }
751
752 //
753 // Update the FontId of the specified string block
754 //
755 switch (BlockType) {
756 case EFI_HII_SIBT_STRING_SCSU_FONT:
757 case EFI_HII_SIBT_STRINGS_SCSU_FONT:
758 case EFI_HII_SIBT_STRING_UCS2_FONT:
759 case EFI_HII_SIBT_STRINGS_UCS2_FONT:
760 *(StringBlockAddr + sizeof (EFI_HII_STRING_BLOCK)) = LocalFont->FontId;
761 break;
762 default:
763 return EFI_NOT_FOUND;
764 }
765
766 }
767
768 OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;
769
770 //
771 // Set the string text.
772 //
773 StringTextPtr = StringBlockAddr + StringTextOffset;
774 switch (BlockType) {
775 case EFI_HII_SIBT_STRING_SCSU:
776 case EFI_HII_SIBT_STRING_SCSU_FONT:
777 case EFI_HII_SIBT_STRINGS_SCSU:
778 case EFI_HII_SIBT_STRINGS_SCSU_FONT:
779 BlockSize = OldBlockSize + StrLen (String);
780 BlockSize -= AsciiStrLen ((CHAR8 *) StringTextPtr);
781 Block = AllocateZeroPool (BlockSize);
782 if (Block == NULL) {
783 return EFI_OUT_OF_RESOURCES;
784 }
785
786 CopyMem (Block, StringPackage->StringBlock, StringTextPtr - StringPackage->StringBlock);
787 BlockPtr = Block + (StringTextPtr - StringPackage->StringBlock);
788
789 while (*String != 0) {
790 *BlockPtr++ = (CHAR8) *String++;
791 }
792 *BlockPtr++ = 0;
793
794
795 TmpSize = OldBlockSize - (StringTextPtr - StringPackage->StringBlock) - AsciiStrSize ((CHAR8 *) StringTextPtr);
796 CopyMem (
797 BlockPtr,
798 StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr),
799 TmpSize
800 );
801
802 SafeFreePool (StringPackage->StringBlock);
803 StringPackage->StringBlock = Block;
804 StringPackage->StringPkgHdr->Header.Length += (UINT32) (BlockSize - OldBlockSize);
805 break;
806
807 case EFI_HII_SIBT_STRING_UCS2:
808 case EFI_HII_SIBT_STRING_UCS2_FONT:
809 case EFI_HII_SIBT_STRINGS_UCS2:
810 case EFI_HII_SIBT_STRINGS_UCS2_FONT:
811 //
812 // Use StrSize to store the size of the specified string, including the NULL
813 // terminator.
814 //
815 GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);
816
817 BlockSize = OldBlockSize + StrSize (String) - StringSize;
818 Block = AllocateZeroPool (BlockSize);
819 if (Block == NULL) {
820 return EFI_OUT_OF_RESOURCES;
821 }
822
823 CopyMem (Block, StringPackage->StringBlock, StringTextPtr - StringPackage->StringBlock);
824 BlockPtr = Block + (StringTextPtr - StringPackage->StringBlock);
825
826 CopyMem (BlockPtr, String, StrSize (String));
827 BlockPtr += StrSize (String);
828
829 CopyMem (
830 BlockPtr,
831 StringTextPtr + StringSize,
832 OldBlockSize - (StringTextPtr - StringPackage->StringBlock) - StringSize
833 );
834
835 SafeFreePool (StringPackage->StringBlock);
836 StringPackage->StringBlock = Block;
837 StringPackage->StringPkgHdr->Header.Length += (UINT32) (BlockSize - OldBlockSize);
838 break;
839
840 default:
841 return EFI_NOT_FOUND;
842 }
843
844 //
845 // Insert a new EFI_HII_SIBT_FONT_BLOCK to the header of string block, if incoming
846 // StringFontInfo does not exist in current string package.
847 //
848 // This new block does not impact on the value of StringId.
849 //
850 //
851 if (StringFontInfo == NULL || Referred) {
852 return EFI_SUCCESS;
853 }
854
855 OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;
856 BlockSize = OldBlockSize + sizeof (EFI_HII_SIBT_FONT_BLOCK) - sizeof (CHAR16) +
857 StrSize (GlobalFont->FontInfo->FontName);
858
859 Block = AllocateZeroPool (BlockSize);
860 if (Block == NULL) {
861 return EFI_OUT_OF_RESOURCES;
862 }
863
864 BlockPtr = Block;
865 Ext2.Header.BlockType = EFI_HII_SIBT_EXT2;
866 Ext2.BlockType2 = EFI_HII_SIBT_FONT;
867 Ext2.Length = (UINT16) (BlockSize - OldBlockSize);
868 CopyMem (BlockPtr, &Ext2, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
869 BlockPtr += sizeof (EFI_HII_SIBT_EXT2_BLOCK);
870
871 *BlockPtr = LocalFont->FontId;
872 BlockPtr += sizeof (UINT8);
873 CopyMem (BlockPtr, &GlobalFont->FontInfo->FontSize, sizeof (UINT16));
874 BlockPtr += sizeof (UINT16);
875 CopyMem (BlockPtr, &GlobalFont->FontInfo->FontStyle, sizeof (UINT32));
876 BlockPtr += sizeof (UINT32);
877 CopyMem (
878 BlockPtr,
879 GlobalFont->FontInfo->FontName,
880 StrSize (GlobalFont->FontInfo->FontName)
881 );
882 BlockPtr += StrSize (GlobalFont->FontInfo->FontName);
883
884 CopyMem (BlockPtr, StringPackage->StringBlock, OldBlockSize);
885
886 SafeFreePool (StringPackage->StringBlock);
887 StringPackage->StringBlock = Block;
888 StringPackage->StringPkgHdr->Header.Length += Ext2.Length;
889
890 return EFI_SUCCESS;
891
892 }
893
894
895 /**
896 This function adds the string String to the group of strings owned by PackageList, with the
897 specified font information StringFontInfo and returns a new string id.
898
899 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
900 @param PackageList Handle of the package list where this string will
901 be added.
902 @param StringId On return, contains the new strings id, which is
903 unique within PackageList.
904 @param Language Points to the language for the new string.
905 @param LanguageName Points to the printable language name to associate
906 with the passed in Language field.If LanguageName
907 is not NULL and the string package header's
908 LanguageName associated with a given Language is
909 not zero, the LanguageName being passed in will
910 be ignored.
911 @param String Points to the new null-terminated string.
912 @param StringFontInfo Points to the new string's font information or
913 NULL if the string should have the default system
914 font, size and style.
915
916 @retval EFI_SUCCESS The new string was added successfully.
917 @retval EFI_NOT_FOUND The specified PackageList could not be found in
918 database.
919 @retval EFI_OUT_OF_RESOURCES Could not add the string due to lack of resources.
920 @retval EFI_INVALID_PARAMETER String is NULL or StringId is NULL or Language is
921 NULL.
922 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
923 current database.
924
925 **/
926 EFI_STATUS
927 EFIAPI
928 HiiNewString (
929 IN CONST EFI_HII_STRING_PROTOCOL *This,
930 IN EFI_HII_HANDLE PackageList,
931 OUT EFI_STRING_ID *StringId,
932 IN CONST CHAR8 *Language,
933 IN CONST CHAR16 *LanguageName, OPTIONAL
934 IN CONST EFI_STRING String,
935 IN CONST EFI_FONT_INFO *StringFontInfo OPTIONAL
936 )
937 {
938 EFI_STATUS Status;
939 LIST_ENTRY *Link;
940 BOOLEAN Matched;
941 HII_DATABASE_PRIVATE_DATA *Private;
942 HII_DATABASE_RECORD *DatabaseRecord;
943 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;
944 HII_STRING_PACKAGE_INSTANCE *StringPackage;
945 UINT32 HeaderSize;
946 UINT32 BlockSize;
947 UINT32 OldBlockSize;
948 UINT8 *StringBlock;
949 UINT8 *BlockPtr;
950 UINT32 Ucs2BlockSize;
951 UINT32 FontBlockSize;
952 UINT32 Ucs2FontBlockSize;
953 EFI_HII_SIBT_EXT2_BLOCK Ext2;
954 HII_FONT_INFO *LocalFont;
955 HII_GLOBAL_FONT_INFO *GlobalFont;
956
957 if (This == NULL || String == NULL || StringId == NULL || Language == NULL || PackageList == NULL) {
958 return EFI_INVALID_PARAMETER;
959 }
960
961 if (!IsHiiHandleValid (PackageList)) {
962 return EFI_NOT_FOUND;
963 }
964
965 Private = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
966 GlobalFont = NULL;
967
968 //
969 // If StringFontInfo specify a paritcular font, it should exist in current database.
970 //
971 if (StringFontInfo != NULL) {
972 if (!IsFontInfoExisted (Private, (EFI_FONT_INFO *) StringFontInfo, NULL, NULL, &GlobalFont)) {
973 return EFI_INVALID_PARAMETER;
974 }
975 }
976
977 //
978 // Get the matching package list.
979 //
980 PackageListNode = NULL;
981 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
982 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
983 if (DatabaseRecord->Handle == PackageList) {
984 PackageListNode = DatabaseRecord->PackageList;
985 break;
986 }
987 }
988 if (PackageListNode == NULL) {
989 return EFI_NOT_FOUND;
990 }
991
992 //
993 // Try to get the matching string package. Create a new string package when failed.
994 //
995 StringPackage = NULL;
996 Matched = FALSE;
997 for (Link = PackageListNode->StringPkgHdr.ForwardLink;
998 Link != &PackageListNode->StringPkgHdr;
999 Link = Link->ForwardLink
1000 ) {
1001 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
1002 if (R8_EfiLibCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) {
1003 Matched = TRUE;
1004 break;
1005 }
1006 }
1007
1008 if (!Matched) {
1009 //
1010 // LanguageName is required to create a new string package.
1011 //
1012 if (LanguageName == NULL) {
1013 return EFI_INVALID_PARAMETER;
1014 }
1015
1016 StringPackage = AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE));
1017 if (StringPackage == NULL) {
1018 return EFI_OUT_OF_RESOURCES;
1019 }
1020
1021 StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE;
1022 StringPackage->FontId = 0;
1023 InitializeListHead (&StringPackage->FontInfoList);
1024
1025 //
1026 // Fill in the string package header
1027 //
1028 HeaderSize = (UINT32) (AsciiStrSize ((CHAR8 *) Language) - 1 + sizeof (EFI_HII_STRING_PACKAGE_HDR));
1029 StringPackage->StringPkgHdr = AllocateZeroPool (HeaderSize);
1030 if (StringPackage->StringPkgHdr == NULL) {
1031 SafeFreePool (StringPackage);
1032 return EFI_OUT_OF_RESOURCES;
1033 }
1034 StringPackage->StringPkgHdr->Header.Type = EFI_HII_PACKAGE_STRINGS;
1035 StringPackage->StringPkgHdr->HdrSize = HeaderSize;
1036 StringPackage->StringPkgHdr->StringInfoOffset = HeaderSize;
1037 CopyMem (StringPackage->StringPkgHdr->LanguageWindow, mLanguageWindow, 16 * sizeof (CHAR16));;
1038 StringPackage->StringPkgHdr->LanguageName = 1;
1039 AsciiStrCpy (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language);
1040
1041 //
1042 // Calculate the length of the string blocks, including string block to record
1043 // printable language full name and EFI_HII_SIBT_END_BLOCK.
1044 //
1045 Ucs2BlockSize = (UINT32) (StrSize ((CHAR16 *) LanguageName) +
1046 sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK) - sizeof (CHAR16));
1047
1048 BlockSize = Ucs2BlockSize + sizeof (EFI_HII_SIBT_END_BLOCK);
1049 StringPackage->StringBlock = (UINT8 *) AllocateZeroPool (BlockSize);
1050 if (StringPackage->StringBlock == NULL) {
1051 SafeFreePool (StringPackage->StringPkgHdr);
1052 SafeFreePool (StringPackage);
1053 return EFI_OUT_OF_RESOURCES;
1054 }
1055
1056 //
1057 // Insert the string block of printable language full name
1058 //
1059 BlockPtr = StringPackage->StringBlock;
1060 *BlockPtr = EFI_HII_SIBT_STRING_UCS2;
1061 BlockPtr += sizeof (EFI_HII_STRING_BLOCK);
1062 CopyMem (BlockPtr, (EFI_STRING) LanguageName, StrSize ((EFI_STRING) LanguageName));
1063 BlockPtr += StrSize ((EFI_STRING) LanguageName);
1064
1065 //
1066 // Insert the end block
1067 //
1068 *BlockPtr = EFI_HII_SIBT_END;
1069
1070 //
1071 // Append this string package node to string package array in this package list.
1072 //
1073 StringPackage->StringPkgHdr->Header.Length = HeaderSize + BlockSize;
1074 PackageListNode->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length;
1075 InsertTailList (&PackageListNode->StringPkgHdr, &StringPackage->StringEntry);
1076
1077 }
1078
1079 //
1080 // Create a string block and corresponding font block if exists, then append them
1081 // to the end of the string package.
1082 //
1083 Status = FindStringBlock (
1084 Private,
1085 StringPackage,
1086 0,
1087 NULL,
1088 NULL,
1089 NULL,
1090 StringId
1091 );
1092 if (EFI_ERROR (Status)) {
1093 return Status;
1094 }
1095
1096 OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;
1097
1098 if (StringFontInfo == NULL) {
1099 //
1100 // Create a EFI_HII_SIBT_STRING_UCS2_BLOCK since font info is not specified.
1101 //
1102
1103 Ucs2BlockSize = (UINT32) (StrSize (String) + sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK)
1104 - sizeof (CHAR16));
1105
1106 StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Ucs2BlockSize);
1107 if (StringBlock == NULL) {
1108 return EFI_OUT_OF_RESOURCES;
1109 }
1110 //
1111 // Copy original string blocks, except the EFI_HII_SIBT_END.
1112 //
1113 CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));
1114 //
1115 // Create a EFI_HII_SIBT_STRING_UCS2 block
1116 //
1117 BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);
1118 *BlockPtr = EFI_HII_SIBT_STRING_UCS2;
1119 BlockPtr += sizeof (EFI_HII_STRING_BLOCK);
1120 CopyMem (BlockPtr, (EFI_STRING) String, StrSize ((EFI_STRING) String));
1121 BlockPtr += StrSize ((EFI_STRING) String);
1122
1123 //
1124 // Append a EFI_HII_SIBT_END block to the end.
1125 //
1126 *BlockPtr = EFI_HII_SIBT_END;
1127 SafeFreePool (StringPackage->StringBlock);
1128 StringPackage->StringBlock = StringBlock;
1129 StringPackage->StringPkgHdr->Header.Length += Ucs2BlockSize;
1130 PackageListNode->PackageListHdr.PackageLength += Ucs2BlockSize;
1131
1132 } else {
1133 //
1134 // StringFontInfo is specified here. If there is a EFI_HII_SIBT_FONT_BLOCK
1135 // which refers to this font info, create a EFI_HII_SIBT_STRING_UCS2_FONT block
1136 // only. Otherwise create a EFI_HII_SIBT_FONT block with a EFI_HII_SIBT_STRING
1137 // _UCS2_FONT block.
1138 //
1139 Ucs2FontBlockSize = (UINT32) (StrSize (String) + sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) -
1140 sizeof (CHAR16));
1141 if (ReferFontInfoLocally (Private, StringPackage, FALSE, GlobalFont, &LocalFont)) {
1142 //
1143 // Create a EFI_HII_SIBT_STRING_UCS2_FONT block only.
1144 //
1145 StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Ucs2FontBlockSize);
1146 if (StringBlock == NULL) {
1147 return EFI_OUT_OF_RESOURCES;
1148 }
1149 //
1150 // Copy original string blocks, except the EFI_HII_SIBT_END.
1151 //
1152 CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));
1153 //
1154 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
1155 //
1156 BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);
1157 *BlockPtr = EFI_HII_SIBT_STRING_UCS2_FONT;
1158 BlockPtr += sizeof (EFI_HII_STRING_BLOCK);
1159 *BlockPtr = LocalFont->FontId;
1160 BlockPtr += sizeof (UINT8);
1161 CopyMem (BlockPtr, (EFI_STRING) String, StrSize ((EFI_STRING) String));
1162 BlockPtr += StrSize ((EFI_STRING) String);
1163
1164 //
1165 // Append a EFI_HII_SIBT_END block to the end.
1166 //
1167 *BlockPtr = EFI_HII_SIBT_END;
1168 SafeFreePool (StringPackage->StringBlock);
1169 StringPackage->StringBlock = StringBlock;
1170 StringPackage->StringPkgHdr->Header.Length += Ucs2FontBlockSize;
1171 PackageListNode->PackageListHdr.PackageLength += Ucs2FontBlockSize;
1172
1173 } else {
1174 //
1175 // EFI_HII_SIBT_FONT_BLOCK does not exist in current string package, so
1176 // create a EFI_HII_SIBT_FONT block to record the font info, then generate
1177 // a EFI_HII_SIBT_STRING_UCS2_FONT block to record the incoming string.
1178 //
1179 FontBlockSize = (UINT32) (StrSize (((EFI_FONT_INFO *) StringFontInfo)->FontName) +
1180 sizeof (EFI_HII_SIBT_FONT_BLOCK) - sizeof (CHAR16));
1181 StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + FontBlockSize + Ucs2FontBlockSize);
1182 if (StringBlock == NULL) {
1183 return EFI_OUT_OF_RESOURCES;
1184 }
1185 //
1186 // Copy original string blocks, except the EFI_HII_SIBT_END.
1187 //
1188 CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));
1189
1190 //
1191 // Create a EFI_HII_SIBT_FONT block firstly and then backup its info in string
1192 // package instance for future reference.
1193 //
1194 BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);
1195
1196 Ext2.Header.BlockType = EFI_HII_SIBT_EXT2;
1197 Ext2.BlockType2 = EFI_HII_SIBT_FONT;
1198 Ext2.Length = (UINT16) FontBlockSize;
1199 CopyMem (BlockPtr, &Ext2, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
1200 BlockPtr += sizeof (EFI_HII_SIBT_EXT2_BLOCK);
1201
1202 *BlockPtr = LocalFont->FontId;
1203 BlockPtr += sizeof (UINT8);
1204 CopyMem (BlockPtr, &((EFI_FONT_INFO *) StringFontInfo)->FontSize, sizeof (UINT16));
1205 BlockPtr += sizeof (UINT16);
1206 CopyMem (BlockPtr, &((EFI_FONT_INFO *) StringFontInfo)->FontStyle, sizeof (EFI_HII_FONT_STYLE));
1207 BlockPtr += sizeof (EFI_HII_FONT_STYLE);
1208 CopyMem (
1209 BlockPtr,
1210 &((EFI_FONT_INFO *) StringFontInfo)->FontName,
1211 StrSize (((EFI_FONT_INFO *) StringFontInfo)->FontName)
1212 );
1213
1214 //
1215 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
1216 //
1217 *BlockPtr = EFI_HII_SIBT_STRING_UCS2_FONT;
1218 BlockPtr += sizeof (EFI_HII_STRING_BLOCK);
1219 *BlockPtr = LocalFont->FontId;
1220 BlockPtr += sizeof (UINT8);
1221 CopyMem (BlockPtr, (EFI_STRING) String, StrSize ((EFI_STRING) String));
1222 BlockPtr += StrSize ((EFI_STRING) String);
1223
1224 //
1225 // Append a EFI_HII_SIBT_END block to the end.
1226 //
1227 *BlockPtr = EFI_HII_SIBT_END;
1228 SafeFreePool (StringPackage->StringBlock);
1229 StringPackage->StringBlock = StringBlock;
1230 StringPackage->StringPkgHdr->Header.Length += FontBlockSize + Ucs2FontBlockSize;
1231 PackageListNode->PackageListHdr.PackageLength += FontBlockSize + Ucs2FontBlockSize;
1232 }
1233 }
1234
1235 return EFI_SUCCESS;
1236 }
1237
1238
1239 /**
1240 This function retrieves the string specified by StringId which is associated
1241 with the specified PackageList in the language Language and copies it into
1242 the buffer specified by String.
1243
1244 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1245 @param Language Points to the language for the retrieved string.
1246 @param PackageList The package list in the HII database to search for
1247 the specified string.
1248 @param StringId The string's id, which is unique within
1249 PackageList.
1250 @param String Points to the new null-terminated string.
1251 @param StringSize On entry, points to the size of the buffer pointed
1252 to by String, in bytes. On return, points to the
1253 length of the string, in bytes.
1254 @param StringFontInfo If not NULL, points to the string's font
1255 information. It's caller's responsibility to free
1256 this buffer.
1257
1258 @retval EFI_SUCCESS The string was returned successfully.
1259 @retval EFI_NOT_FOUND The string specified by StringId is not available.
1260 @retval EFI_NOT_FOUND The string specified by StringId is available but
1261 not in the specified language.
1262 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to
1263 hold the string.
1264 @retval EFI_INVALID_PARAMETER The String or Language or StringSize was NULL.
1265 @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the
1266 request.
1267
1268 **/
1269 EFI_STATUS
1270 EFIAPI
1271 HiiGetString (
1272 IN CONST EFI_HII_STRING_PROTOCOL *This,
1273 IN CONST CHAR8 *Language,
1274 IN EFI_HII_HANDLE PackageList,
1275 IN EFI_STRING_ID StringId,
1276 OUT EFI_STRING String,
1277 IN OUT UINTN *StringSize,
1278 OUT EFI_FONT_INFO **StringFontInfo OPTIONAL
1279 )
1280 {
1281 EFI_STATUS Status;
1282 LIST_ENTRY *Link;
1283 HII_DATABASE_PRIVATE_DATA *Private;
1284 HII_DATABASE_RECORD *DatabaseRecord;
1285 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;
1286 HII_STRING_PACKAGE_INSTANCE *StringPackage;
1287
1288 if (This == NULL || Language == NULL || StringId < 1 || StringSize == NULL || PackageList == NULL) {
1289 return EFI_INVALID_PARAMETER;
1290 }
1291
1292 if (String == NULL && *StringSize != 0) {
1293 return EFI_INVALID_PARAMETER;
1294 }
1295
1296 if (!IsHiiHandleValid (PackageList)) {
1297 return EFI_NOT_FOUND;
1298 }
1299
1300 Private = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
1301 PackageListNode = NULL;
1302
1303 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
1304 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
1305 if (DatabaseRecord->Handle == PackageList) {
1306 PackageListNode = DatabaseRecord->PackageList;
1307 break;
1308 }
1309 }
1310
1311 if (PackageListNode != NULL) {
1312 for (Link = PackageListNode->StringPkgHdr.ForwardLink;
1313 Link != &PackageListNode->StringPkgHdr;
1314 Link = Link->ForwardLink
1315 ) {
1316 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
1317 if (R8_EfiLibCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) {
1318 Status = GetStringWorker (Private, StringPackage, StringId, String, StringSize, StringFontInfo);
1319 if (Status != EFI_NOT_FOUND) {
1320 return Status;
1321 }
1322 }
1323 }
1324 }
1325
1326 return EFI_NOT_FOUND;
1327 }
1328
1329
1330
1331 /**
1332 This function updates the string specified by StringId in the specified PackageList to the text
1333 specified by String and, optionally, the font information specified by StringFontInfo.
1334
1335 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1336 @param PackageList The package list containing the strings.
1337 @param StringId The string's id, which is unique within
1338 PackageList.
1339 @param Language Points to the language for the updated string.
1340 @param String Points to the new null-terminated string.
1341 @param StringFontInfo Points to the string's font information or NULL if
1342 the string font information is not changed.
1343
1344 @retval EFI_SUCCESS The string was updated successfully.
1345 @retval EFI_NOT_FOUND The string specified by StringId is not in the
1346 database.
1347 @retval EFI_INVALID_PARAMETER The String or Language was NULL.
1348 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in
1349 current database.
1350 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
1351 task.
1352
1353 **/
1354 EFI_STATUS
1355 EFIAPI
1356 HiiSetString (
1357 IN CONST EFI_HII_STRING_PROTOCOL *This,
1358 IN EFI_HII_HANDLE PackageList,
1359 IN EFI_STRING_ID StringId,
1360 IN CONST CHAR8 *Language,
1361 IN CONST EFI_STRING String,
1362 IN CONST EFI_FONT_INFO *StringFontInfo OPTIONAL
1363 )
1364 {
1365 EFI_STATUS Status;
1366 LIST_ENTRY *Link;
1367 HII_DATABASE_PRIVATE_DATA *Private;
1368 HII_DATABASE_RECORD *DatabaseRecord;
1369 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;
1370 HII_STRING_PACKAGE_INSTANCE *StringPackage;
1371 UINT32 OldPackageLen;
1372
1373 if (This == NULL || Language == NULL || StringId < 1 || String == NULL || PackageList == NULL) {
1374 return EFI_INVALID_PARAMETER;
1375 }
1376
1377 if (!IsHiiHandleValid (PackageList)) {
1378 return EFI_NOT_FOUND;
1379 }
1380
1381 Private = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
1382 PackageListNode = NULL;
1383
1384 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
1385 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
1386 if (DatabaseRecord->Handle == PackageList) {
1387 PackageListNode = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (DatabaseRecord->PackageList);
1388 }
1389 }
1390
1391 if (PackageListNode != NULL) {
1392 for (Link = PackageListNode->StringPkgHdr.ForwardLink;
1393 Link != &PackageListNode->StringPkgHdr;
1394 Link = Link->ForwardLink
1395 ) {
1396 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
1397 if (R8_EfiLibCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) {
1398 OldPackageLen = StringPackage->StringPkgHdr->Header.Length;
1399 Status = SetStringWorker (
1400 Private,
1401 StringPackage,
1402 StringId,
1403 (EFI_STRING) String,
1404 (EFI_FONT_INFO *) StringFontInfo
1405 );
1406 if (EFI_ERROR (Status)) {
1407 return Status;
1408 }
1409 PackageListNode->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length - OldPackageLen;
1410 return EFI_SUCCESS;
1411 }
1412 }
1413 }
1414
1415 return EFI_NOT_FOUND;
1416 }
1417
1418
1419
1420 /**
1421 This function returns the list of supported languages, in the format specified
1422 in Appendix M of UEFI 2.1 spec.
1423
1424 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1425 @param PackageList The package list to examine.
1426 @param Languages Points to the buffer to hold the returned string.
1427 @param LanguagesSize On entry, points to the size of the buffer pointed
1428 to by Languages, in bytes. On return, points to
1429 the length of Languages, in bytes.
1430
1431 @retval EFI_SUCCESS The languages were returned successfully.
1432 @retval EFI_INVALID_PARAMETER The Languages or LanguagesSize was NULL.
1433 @retval EFI_BUFFER_TOO_SMALL The LanguagesSize is too small to hold the list of
1434 supported languages. LanguageSize is updated to
1435 contain the required size.
1436 @retval EFI_NOT_FOUND Could not find string package in specified
1437 packagelist.
1438
1439 **/
1440 EFI_STATUS
1441 EFIAPI
1442 HiiGetLanguages (
1443 IN CONST EFI_HII_STRING_PROTOCOL *This,
1444 IN EFI_HII_HANDLE PackageList,
1445 IN OUT CHAR8 *Languages,
1446 IN OUT UINTN *LanguagesSize
1447 )
1448 {
1449 LIST_ENTRY *Link;
1450 HII_DATABASE_PRIVATE_DATA *Private;
1451 HII_DATABASE_RECORD *DatabaseRecord;
1452 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;
1453 HII_STRING_PACKAGE_INSTANCE *StringPackage;
1454 UINTN ResultSize;
1455
1456 if (This == NULL || Languages == NULL || LanguagesSize == NULL || PackageList == NULL) {
1457 return EFI_INVALID_PARAMETER;
1458 }
1459 if (!IsHiiHandleValid (PackageList)) {
1460 return EFI_NOT_FOUND;
1461 }
1462
1463 Private = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
1464
1465 PackageListNode = NULL;
1466 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
1467 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
1468 if (DatabaseRecord->Handle == PackageList) {
1469 PackageListNode = DatabaseRecord->PackageList;
1470 break;
1471 }
1472 }
1473 if (PackageListNode == NULL) {
1474 return EFI_NOT_FOUND;
1475 }
1476
1477 //
1478 // Search the languages in the specified packagelist.
1479 //
1480 ResultSize = 0;
1481 for (Link = PackageListNode->StringPkgHdr.ForwardLink;
1482 Link != &PackageListNode->StringPkgHdr;
1483 Link = Link->ForwardLink
1484 ) {
1485 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
1486 ResultSize += AsciiStrSize (StringPackage->StringPkgHdr->Language);
1487 if (ResultSize < *LanguagesSize) {
1488 AsciiStrCpy (Languages, StringPackage->StringPkgHdr->Language);
1489 Languages += AsciiStrSize (StringPackage->StringPkgHdr->Language);
1490 *(Languages - 1) = L';';
1491 }
1492 }
1493 if (ResultSize == 0) {
1494 return EFI_NOT_FOUND;
1495 }
1496
1497 if (*LanguagesSize < ResultSize) {
1498 *LanguagesSize = ResultSize;
1499 return EFI_BUFFER_TOO_SMALL;
1500 }
1501
1502 *(Languages - 1) = 0;
1503 return EFI_SUCCESS;
1504 }
1505
1506
1507 /**
1508 Each string package has associated with it a single primary language and zero
1509 or more secondary languages. This routine returns the secondary languages
1510 associated with a package list.
1511
1512 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.
1513 @param PackageList The package list to examine.
1514 @param FirstLanguage Points to the primary language.
1515 @param SecondaryLanguages Points to the buffer to hold the returned list of
1516 secondary languages for the specified
1517 FirstLanguage. If there are no secondary
1518 languages, the function returns successfully, but
1519 this is set to NULL.
1520 @param SecondaryLanguageSize On entry, points to the size of the buffer pointed
1521 to by SecondLanguages, in bytes. On return,
1522 points to the length of SecondLanguages in bytes.
1523
1524 @retval EFI_SUCCESS Secondary languages were correctly returned.
1525 @retval EFI_INVALID_PARAMETER FirstLanguage or SecondLanguages or
1526 SecondLanguagesSize was NULL.
1527 @retval EFI_BUFFER_TOO_SMALL The buffer specified by SecondLanguagesSize is
1528 too small to hold the returned information.
1529 SecondLanguageSize is updated to hold the size of
1530 the buffer required.
1531 @retval EFI_NOT_FOUND The language specified by FirstLanguage is not
1532 present in the specified package list.
1533
1534 **/
1535 EFI_STATUS
1536 EFIAPI
1537 HiiGetSecondaryLanguages (
1538 IN CONST EFI_HII_STRING_PROTOCOL *This,
1539 IN EFI_HII_HANDLE PackageList,
1540 IN CONST CHAR8 *FirstLanguage,
1541 IN OUT CHAR8 *SecondLanguages,
1542 IN OUT UINTN *SecondLanguagesSize
1543 )
1544 {
1545 LIST_ENTRY *Link;
1546 LIST_ENTRY *Link1;
1547 HII_DATABASE_PRIVATE_DATA *Private;
1548 HII_DATABASE_RECORD *DatabaseRecord;
1549 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;
1550 HII_STRING_PACKAGE_INSTANCE *StringPackage;
1551 CHAR8 *Languages;
1552 UINTN ResultSize;
1553
1554 if (This == NULL || PackageList == NULL || FirstLanguage == NULL) {
1555 return EFI_INVALID_PARAMETER;
1556 }
1557 if (SecondLanguages == NULL || SecondLanguagesSize == NULL) {
1558 return EFI_INVALID_PARAMETER;
1559 }
1560 if (!IsHiiHandleValid (PackageList)) {
1561 return EFI_NOT_FOUND;
1562 }
1563
1564 Private = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
1565 Languages = NULL;
1566 ResultSize = 0;
1567
1568 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
1569 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
1570 if (DatabaseRecord->Handle == PackageList) {
1571 PackageListNode = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (DatabaseRecord->PackageList);
1572 for (Link1 = PackageListNode->StringPkgHdr.ForwardLink;
1573 Link1 != &PackageListNode->StringPkgHdr;
1574 Link1 = Link1->ForwardLink
1575 ) {
1576 StringPackage = CR (Link1, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
1577 if (R8_EfiLibCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) FirstLanguage)) {
1578 Languages = StringPackage->StringPkgHdr->Language;
1579 //
1580 // Language is a series of ';' terminated strings, first one is primary
1581 // language and following with other secondary languages or NULL if no
1582 // secondary languages any more.
1583 //
1584 Languages = AsciiStrStr (Languages, ";");
1585 if (Languages == NULL) {
1586 break;
1587 }
1588 Languages++;
1589
1590 ResultSize = AsciiStrSize (Languages);
1591 if (ResultSize <= *SecondLanguagesSize) {
1592 AsciiStrCpy (SecondLanguages, Languages);
1593 } else {
1594 *SecondLanguagesSize = ResultSize;
1595 return EFI_BUFFER_TOO_SMALL;
1596 }
1597
1598 return EFI_SUCCESS;
1599 }
1600 }
1601 }
1602 }
1603
1604 return EFI_NOT_FOUND;
1605 }
1606