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