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