]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/HiiDatabaseDxe/String.c
1) Add type cast for better coding style.
[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
6e1e5405 5Copyright (c) 2007 - 2014, 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
6e1e5405 338 StringTextPtr = (UINT8*)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8));\r
93e3992d 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
04eb20aa 344 ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);\r
93e3992d 345 *BlockType = *BlockHdr;\r
346 *StringBlockAddr = BlockHdr;\r
347 *StringTextOffset = StringTextPtr - BlockHdr;\r
348 return EFI_SUCCESS;\r
349 }\r
350 StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *) StringTextPtr);\r
351 CurrentStringId++;\r
352 }\r
353 break;\r
354\r
355 case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
356 CopyMem (\r
357 &StringCount,\r
6e1e5405 358 (UINT8*)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),\r
93e3992d 359 sizeof (UINT16)\r
360 );\r
6e1e5405 361 StringTextPtr = (UINT8*)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8));\r
93e3992d 362 BlockSize += StringTextPtr - BlockHdr;\r
363\r
364 for (Index = 0; Index < StringCount; Index++) {\r
365 BlockSize += AsciiStrSize ((CHAR8 *) StringTextPtr);\r
366 if (CurrentStringId == StringId) {\r
04eb20aa 367 ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);\r
93e3992d 368 *BlockType = *BlockHdr;\r
369 *StringBlockAddr = BlockHdr;\r
370 *StringTextOffset = StringTextPtr - BlockHdr;\r
371 return EFI_SUCCESS;\r
372 }\r
373 StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *) StringTextPtr);\r
374 CurrentStringId++;\r
375 }\r
376 break;\r
377\r
378 case EFI_HII_SIBT_STRING_UCS2:\r
379 Offset = sizeof (EFI_HII_STRING_BLOCK);\r
380 StringTextPtr = BlockHdr + Offset;\r
381 //\r
382 // Use StringSize to store the size of the specified string, including the NULL\r
383 // terminator.\r
384 //\r
385 GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);\r
386 BlockSize += Offset + StringSize;\r
387 CurrentStringId++;\r
388 break;\r
389\r
390 case EFI_HII_SIBT_STRING_UCS2_FONT:\r
391 Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);\r
392 StringTextPtr = BlockHdr + Offset;\r
393 //\r
394 // Use StrSize to store the size of the specified string, including the NULL\r
395 // terminator.\r
396 //\r
397 GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);\r
398 BlockSize += Offset + StringSize;\r
399 CurrentStringId++;\r
400 break;\r
401\r
402 case EFI_HII_SIBT_STRINGS_UCS2:\r
403 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);\r
404 StringTextPtr = BlockHdr + Offset;\r
405 BlockSize += Offset;\r
406 CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
407 for (Index = 0; Index < StringCount; Index++) {\r
408 GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);\r
409 BlockSize += StringSize;\r
410 if (CurrentStringId == StringId) {\r
04eb20aa 411 ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);\r
93e3992d 412 *BlockType = *BlockHdr;\r
413 *StringBlockAddr = BlockHdr;\r
414 *StringTextOffset = StringTextPtr - BlockHdr;\r
415 return EFI_SUCCESS;\r
416 }\r
417 StringTextPtr = StringTextPtr + StringSize;\r
418 CurrentStringId++;\r
419 }\r
420 break;\r
421\r
422 case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
423 Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);\r
424 StringTextPtr = BlockHdr + Offset;\r
425 BlockSize += Offset;\r
426 CopyMem (\r
427 &StringCount,\r
6e1e5405 428 (UINT8*)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),\r
93e3992d 429 sizeof (UINT16)\r
430 );\r
431 for (Index = 0; Index < StringCount; Index++) {\r
432 GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);\r
433 BlockSize += StringSize;\r
434 if (CurrentStringId == StringId) {\r
04eb20aa 435 ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);\r
93e3992d 436 *BlockType = *BlockHdr;\r
437 *StringBlockAddr = BlockHdr;\r
438 *StringTextOffset = StringTextPtr - BlockHdr;\r
439 return EFI_SUCCESS;\r
440 }\r
441 StringTextPtr = StringTextPtr + StringSize;\r
442 CurrentStringId++;\r
443 }\r
444 break;\r
445\r
446 case EFI_HII_SIBT_DUPLICATE:\r
447 if (CurrentStringId == StringId) {\r
448 //\r
449 // Incoming StringId is an id of a duplicate string block.\r
450 // Update the StringId to be the previous string block.\r
451 // Go back to the header of string block to search.\r
452 //\r
453 CopyMem (\r
454 &StringId,\r
455 BlockHdr + sizeof (EFI_HII_STRING_BLOCK),\r
456 sizeof (EFI_STRING_ID)\r
457 );\r
458 ASSERT (StringId != CurrentStringId);\r
459 CurrentStringId = 1;\r
460 BlockSize = 0;\r
461 } else {\r
462 BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);\r
463 CurrentStringId++;\r
464 }\r
465 break;\r
466\r
467 case EFI_HII_SIBT_SKIP1:\r
6e1e5405 468 SkipCount = (UINT16) (*(UINT8*)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));\r
93e3992d 469 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);\r
470 BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);\r
471 break;\r
472\r
473 case EFI_HII_SIBT_SKIP2:\r
474 CopyMem (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
475 CurrentStringId = (UINT16) (CurrentStringId + SkipCount);\r
476 BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
477 break;\r
478\r
479 case EFI_HII_SIBT_EXT1:\r
480 CopyMem (\r
481 &Length8,\r
6e1e5405 482 (UINT8*)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),\r
93e3992d 483 sizeof (UINT8)\r
484 );\r
485 BlockSize += Length8;\r
486 break;\r
487\r
488 case EFI_HII_SIBT_EXT2:\r
489 CopyMem (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));\r
490 if (Ext2.BlockType2 == EFI_HII_SIBT_FONT && StringId == (EFI_STRING_ID) (-1)) {\r
491 //\r
492 // Find the relationship between global font info and the font info of\r
493 // this EFI_HII_SIBT_FONT block then backup its information in local package.\r
494 //\r
813acf3a 495 BlockHdr += sizeof (EFI_HII_SIBT_EXT2_BLOCK);\r
496 CopyMem (&FontId, BlockHdr, sizeof (UINT8));\r
6e1e5405 497 BlockHdr ++;\r
93e3992d 498 CopyMem (&FontSize, BlockHdr, sizeof (UINT16));\r
499 BlockHdr += sizeof (UINT16);\r
500 CopyMem (&FontStyle, BlockHdr, sizeof (EFI_HII_FONT_STYLE));\r
501 BlockHdr += sizeof (EFI_HII_FONT_STYLE);\r
502 GetUnicodeStringTextOrSize (NULL, BlockHdr, &StringSize);\r
503\r
504 FontInfoSize = sizeof (EFI_FONT_INFO) - sizeof (CHAR16) + StringSize;\r
505 FontInfo = (EFI_FONT_INFO *) AllocateZeroPool (FontInfoSize);\r
506 if (FontInfo == NULL) {\r
507 return EFI_OUT_OF_RESOURCES;\r
508 }\r
509 FontInfo->FontStyle = FontStyle;\r
510 FontInfo->FontSize = FontSize;\r
511 CopyMem (FontInfo->FontName, BlockHdr, StringSize);\r
512\r
813acf3a 513 //\r
514 // If find the corresponding global font info, save the relationship.\r
515 // Otherwise ignore this EFI_HII_SIBT_FONT block.\r
516 //\r
93e3992d 517 if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, &GlobalFont)) {\r
813acf3a 518 ReferFontInfoLocally (Private, StringPackage, FontId, TRUE, GlobalFont, &LocalFont);\r
93e3992d 519 }\r
520\r
521 //\r
813acf3a 522 // Since string package tool set FontId initially to 0 and increases it\r
523 // progressively by one, StringPackage->FondId always represents an unique\r
524 // and available FontId.\r
525 // \r
526 StringPackage->FontId++;\r
527\r
676df92c 528 FreePool (FontInfo);\r
93e3992d 529 }\r
530\r
531 BlockSize += Ext2.Length;\r
532\r
533 break;\r
534\r
535 case EFI_HII_SIBT_EXT4:\r
536 CopyMem (\r
537 &Length32,\r
6e1e5405 538 (UINT8*)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),\r
93e3992d 539 sizeof (UINT32)\r
540 );\r
541\r
542 BlockSize += Length32;\r
543 break;\r
544\r
545 default:\r
546 break;\r
547 }\r
548\r
e5c861ac
ED
549 if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) {\r
550 ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);\r
551 *BlockType = *BlockHdr;\r
552 *StringBlockAddr = BlockHdr;\r
553 *StringTextOffset = Offset;\r
554\r
93e3992d 555 if (StringId == CurrentStringId - 1) {\r
e5c861ac
ED
556 //\r
557 // if only one skip item, return EFI_NOT_FOUND.\r
558 //\r
559 if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) {\r
560 return EFI_NOT_FOUND;\r
561 } else {\r
562 return EFI_SUCCESS;\r
563 }\r
93e3992d 564 }\r
565\r
566 if (StringId < CurrentStringId - 1) {\r
567 return EFI_NOT_FOUND;\r
568 }\r
569 }\r
570 BlockHdr = StringPackage->StringBlock + BlockSize;\r
e5c861ac
ED
571 if (StartStringId != NULL) {\r
572 *StartStringId = CurrentStringId;\r
573 }\r
93e3992d 574 }\r
d6a82eaf
LG
575 \r
576 //\r
577 // Get last string ID\r
578 //\r
04eb20aa 579 if (StringId == (EFI_STRING_ID) (-1) && LastStringId != NULL) {\r
d7c0e60c 580 *LastStringId = (EFI_STRING_ID) (CurrentStringId - 1);\r
93e3992d 581 return EFI_SUCCESS;\r
582 }\r
583\r
584 return EFI_NOT_FOUND;\r
585}\r
586\r
587\r
588/**\r
589 Parse all string blocks to get a string specified by StringId.\r
590\r
e90b081a 591 This is a internal function.\r
592\r
93e3992d 593 @param Private Hii database private structure.\r
594 @param StringPackage Hii string package instance.\r
ac644614 595 @param StringId The string's id, which is unique within\r
93e3992d 596 PackageList.\r
597 @param String Points to retrieved null-terminated string.\r
598 @param StringSize On entry, points to the size of the buffer pointed\r
599 to by String, in bytes. On return, points to the\r
600 length of the string, in bytes.\r
601 @param StringFontInfo If not NULL, allocate a buffer to record the\r
602 output font info. It's caller's responsibility to\r
603 free this buffer.\r
604\r
605 @retval EFI_SUCCESS The string text and font is retrieved\r
606 successfully.\r
607 @retval EFI_NOT_FOUND The specified text or font info can not be found\r
608 out.\r
609 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to\r
610 hold the string.\r
611\r
612**/\r
93e3992d 613EFI_STATUS\r
614GetStringWorker (\r
615 IN HII_DATABASE_PRIVATE_DATA *Private,\r
616 IN HII_STRING_PACKAGE_INSTANCE *StringPackage,\r
617 IN EFI_STRING_ID StringId,\r
618 OUT EFI_STRING String,\r
b86b413a 619 IN OUT UINTN *StringSize, OPTIONAL\r
93e3992d 620 OUT EFI_FONT_INFO **StringFontInfo OPTIONAL\r
621 )\r
622{\r
623 UINT8 *StringTextPtr;\r
624 UINT8 BlockType;\r
625 UINT8 *StringBlockAddr;\r
626 UINTN StringTextOffset;\r
627 EFI_STATUS Status;\r
628 UINT8 FontId;\r
629\r
b86b413a 630 ASSERT (StringPackage != NULL);\r
93e3992d 631 ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);\r
632\r
633 //\r
634 // Find the specified string block\r
635 //\r
636 Status = FindStringBlock (\r
637 Private,\r
638 StringPackage,\r
639 StringId,\r
640 &BlockType,\r
641 &StringBlockAddr,\r
642 &StringTextOffset,\r
e5c861ac 643 NULL,\r
93e3992d 644 NULL\r
645 );\r
646 if (EFI_ERROR (Status)) {\r
647 return Status;\r
648 }\r
649\r
b86b413a
LG
650 if (StringSize == NULL) {\r
651 //\r
652 // String text buffer is not requested\r
653 //\r
654 return EFI_SUCCESS;\r
655 }\r
656\r
93e3992d 657 //\r
658 // Get the string text.\r
659 //\r
660 StringTextPtr = StringBlockAddr + StringTextOffset;\r
661 switch (BlockType) {\r
662 case EFI_HII_SIBT_STRING_SCSU:\r
663 case EFI_HII_SIBT_STRING_SCSU_FONT:\r
664 case EFI_HII_SIBT_STRINGS_SCSU:\r
665 case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
666 Status = ConvertToUnicodeText (String, (CHAR8 *) StringTextPtr, StringSize);\r
667 break;\r
668 case EFI_HII_SIBT_STRING_UCS2:\r
669 case EFI_HII_SIBT_STRING_UCS2_FONT:\r
670 case EFI_HII_SIBT_STRINGS_UCS2:\r
671 case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
672 Status = GetUnicodeStringTextOrSize (String, StringTextPtr, StringSize);\r
673 break;\r
674 default:\r
675 return EFI_NOT_FOUND;\r
676 }\r
677 if (EFI_ERROR (Status)) {\r
678 return Status;\r
679 }\r
680\r
681 //\r
813acf3a 682 // Get the string font. The FontId 0 is the default font for those string blocks which \r
683 // do not specify a font identifier. If default font is not specified, return NULL.\r
93e3992d 684 //\r
685 if (StringFontInfo != NULL) {\r
686 switch (BlockType) {\r
687 case EFI_HII_SIBT_STRING_SCSU_FONT:\r
688 case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
689 case EFI_HII_SIBT_STRING_UCS2_FONT:\r
690 case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
691 FontId = *(StringBlockAddr + sizeof (EFI_HII_STRING_BLOCK));\r
93e3992d 692 break;\r
693 default:\r
813acf3a 694 FontId = 0;\r
695 }\r
696 Status = GetStringFontInfo (StringPackage, FontId, StringFontInfo);\r
697 if (Status == EFI_NOT_FOUND) {\r
698 *StringFontInfo = NULL;\r
93e3992d 699 }\r
700 }\r
701\r
702 return EFI_SUCCESS;\r
703}\r
704\r
e5c861ac
ED
705/**\r
706 If GetStringBlock find the StringId's string is not saved in the exist string block,\r
707 this function will create the UCS2 string block to save the string; also split the \r
708 skip block into two or one skip block.\r
709\r
710 This is a internal function.\r
711 \r
712 @param StringPackage Hii string package instance.\r
713 @param StartStringId The first id in the skip block which StringId in the block.\r
714 @param StringId The string's id, which is unique within\r
715 PackageList. \r
716 @param BlockType Output the block type of found string block. \r
717 @param StringBlockAddr Output the block address of found string block. \r
718 @param FontBlock whether this string block has font info.\r
719\r
720 @retval EFI_SUCCESS The string font is outputed successfully.\r
721 @retval EFI_OUT_OF_RESOURCES NO resource for the memory to save the new string block.\r
722\r
723**/\r
724EFI_STATUS\r
725InsertLackStringBlock (\r
726 IN OUT HII_STRING_PACKAGE_INSTANCE *StringPackage,\r
727 IN EFI_STRING_ID StartStringId,\r
728 IN EFI_STRING_ID StringId,\r
729 IN OUT UINT8 *BlockType,\r
730 IN OUT UINT8 **StringBlockAddr,\r
731 IN BOOLEAN FontBlock\r
732 )\r
733{\r
734 UINT8 *BlockPtr;\r
735 UINT8 *StringBlock;\r
e33e3417
ED
736 UINT32 SkipLen; \r
737 UINT32 OldBlockSize;\r
738 UINT32 NewBlockSize;\r
739 UINT32 FrontSkipNum;\r
740 UINT32 NewUCSBlockLen;\r
e5c861ac 741 UINT8 *OldStringAddr;\r
e33e3417 742 UINT32 IdCount;\r
e5c861ac
ED
743\r
744 FrontSkipNum = 0;\r
745 SkipLen = 0;\r
746 OldStringAddr = *StringBlockAddr;\r
747 \r
748 ASSERT (*BlockType == EFI_HII_SIBT_SKIP1 || *BlockType == EFI_HII_SIBT_SKIP2);\r
749 //\r
750 // Old skip block size.\r
751 //\r
752 if (*BlockType == EFI_HII_SIBT_SKIP1) {\r
753 SkipLen = sizeof (EFI_HII_SIBT_SKIP1_BLOCK);\r
754 IdCount = *(UINT8*)(OldStringAddr + sizeof (EFI_HII_STRING_BLOCK));\r
755 } else {\r
756 SkipLen = sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
757 IdCount = *(UINT16*)(OldStringAddr + sizeof (EFI_HII_STRING_BLOCK));\r
758 } \r
759\r
760 //\r
761 // New create UCS or UCS2 block size.\r
762 //\r
763 if (FontBlock) {\r
764 NewUCSBlockLen = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK);\r
765 } else {\r
766 NewUCSBlockLen = sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK);\r
767 }\r
768\r
769 OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;\r
770\r
771 if (StartStringId == StringId) {\r
772 //\r
773 // New block + [Skip block]\r
774 //\r
775 if (IdCount > 1) {\r
776 NewBlockSize = OldBlockSize + NewUCSBlockLen;\r
777 } else {\r
778 NewBlockSize = OldBlockSize + NewUCSBlockLen - SkipLen;\r
779 }\r
780 } else if (StartStringId + IdCount - 1 == StringId){\r
781 //\r
782 // Skip block + New block\r
783 //\r
784 NewBlockSize = OldBlockSize + NewUCSBlockLen;\r
785 FrontSkipNum = StringId - StartStringId;\r
786 } else {\r
787 //\r
788 // Skip block + New block + [Skip block]\r
789 //\r
790 NewBlockSize = OldBlockSize + NewUCSBlockLen + SkipLen;\r
791 FrontSkipNum = StringId - StartStringId;\r
792 }\r
793\r
794 StringBlock = (UINT8 *) AllocateZeroPool (NewBlockSize);\r
795 if (StringBlock == NULL) {\r
796 return EFI_OUT_OF_RESOURCES;\r
797 }\r
798\r
799 //\r
800 // Copy old block in front of skip block.\r
801 //\r
802 CopyMem (StringBlock, StringPackage->StringBlock, OldStringAddr - StringPackage->StringBlock); \r
803 BlockPtr = StringBlock + (OldStringAddr - StringPackage->StringBlock);\r
804\r
805 if (FrontSkipNum > 0) {\r
806 *BlockPtr = *BlockType;\r
807 if (*BlockType == EFI_HII_SIBT_SKIP1) {\r
40a69956 808 *(BlockPtr + sizeof (EFI_HII_STRING_BLOCK)) = (UINT8) FrontSkipNum;\r
e5c861ac 809 } else {\r
40a69956 810 *(UINT16 *)(BlockPtr + sizeof (EFI_HII_STRING_BLOCK)) = (UINT16) FrontSkipNum;\r
e5c861ac
ED
811 }\r
812 BlockPtr += SkipLen;\r
813 }\r
814\r
815 //\r
816 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK\r
817 //\r
818 *StringBlockAddr = BlockPtr;\r
819 if (FontBlock) {\r
820 *BlockPtr = EFI_HII_SIBT_STRING_UCS2_FONT;\r
821 } else {\r
822 *BlockPtr = EFI_HII_SIBT_STRING_UCS2;\r
823 }\r
824 BlockPtr += NewUCSBlockLen;\r
825\r
826 if (IdCount > FrontSkipNum + 1) {\r
827 *BlockPtr = *BlockType;\r
828 if (*BlockType == EFI_HII_SIBT_SKIP1) {\r
40a69956 829 *(BlockPtr + sizeof (EFI_HII_STRING_BLOCK)) = (UINT8) (IdCount - FrontSkipNum - 1);\r
e5c861ac 830 } else {\r
40a69956 831 *(UINT16 *)(BlockPtr + sizeof (EFI_HII_STRING_BLOCK)) = (UINT16) (IdCount - FrontSkipNum - 1);\r
e5c861ac
ED
832 }\r
833 BlockPtr += SkipLen;\r
834 }\r
835\r
836 //\r
837 // Append a EFI_HII_SIBT_END block to the end.\r
838 //\r
839 CopyMem (BlockPtr, OldStringAddr + SkipLen, OldBlockSize - (OldStringAddr - StringPackage->StringBlock) - SkipLen); \r
840\r
841 if (FontBlock) {\r
842 *BlockType = EFI_HII_SIBT_STRING_UCS2_FONT;\r
843 } else {\r
844 *BlockType = EFI_HII_SIBT_STRING_UCS2;\r
845 }\r
846 FreePool (StringPackage->StringBlock);\r
847 StringPackage->StringBlock = StringBlock;\r
848 StringPackage->StringPkgHdr->Header.Length += NewBlockSize - OldBlockSize;\r
849\r
850 return EFI_SUCCESS;\r
851}\r
93e3992d 852\r
853/**\r
854 Parse all string blocks to set a String specified by StringId.\r
855\r
e90b081a 856 This is a internal function.\r
857\r
93e3992d 858 @param Private HII database driver private structure.\r
859 @param StringPackage HII string package instance.\r
ac644614 860 @param StringId The string's id, which is unique within\r
93e3992d 861 PackageList.\r
862 @param String Points to the new null-terminated string.\r
863 @param StringFontInfo Points to the input font info.\r
864\r
865 @retval EFI_SUCCESS The string was updated successfully.\r
866 @retval EFI_NOT_FOUND The string specified by StringId is not in the\r
867 database.\r
868 @retval EFI_INVALID_PARAMETER The String or Language was NULL.\r
869 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in\r
870 current database.\r
871 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the\r
872 task.\r
873\r
874**/\r
93e3992d 875EFI_STATUS\r
876SetStringWorker (\r
877 IN HII_DATABASE_PRIVATE_DATA *Private,\r
878 IN OUT HII_STRING_PACKAGE_INSTANCE *StringPackage,\r
879 IN EFI_STRING_ID StringId,\r
880 IN EFI_STRING String,\r
881 IN EFI_FONT_INFO *StringFontInfo OPTIONAL\r
882 )\r
883{\r
884 UINT8 *StringTextPtr;\r
885 UINT8 BlockType;\r
886 UINT8 *StringBlockAddr;\r
887 UINTN StringTextOffset;\r
888 EFI_STATUS Status;\r
889 UINT8 *Block;\r
890 UINT8 *BlockPtr;\r
891 UINTN BlockSize;\r
892 UINTN OldBlockSize;\r
893 HII_FONT_INFO *LocalFont;\r
894 HII_GLOBAL_FONT_INFO *GlobalFont;\r
895 BOOLEAN Referred;\r
896 EFI_HII_SIBT_EXT2_BLOCK Ext2;\r
897 UINTN StringSize;\r
898 UINTN TmpSize;\r
e5c861ac 899 EFI_STRING_ID StartStringId;\r
93e3992d 900\r
e5c861ac 901 StartStringId = 0;\r
05bf16e0 902 StringSize = 0;\r
93e3992d 903 ASSERT (Private != NULL && StringPackage != NULL && String != NULL);\r
904 ASSERT (Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);\r
905 //\r
906 // Find the specified string block\r
907 //\r
908 Status = FindStringBlock (\r
909 Private,\r
910 StringPackage,\r
911 StringId,\r
912 &BlockType,\r
913 &StringBlockAddr,\r
914 &StringTextOffset,\r
e5c861ac
ED
915 NULL,\r
916 &StartStringId\r
93e3992d 917 );\r
e5c861ac
ED
918 if (EFI_ERROR (Status) && (BlockType == EFI_HII_SIBT_SKIP1 || BlockType == EFI_HII_SIBT_SKIP2)) {\r
919 Status = InsertLackStringBlock(StringPackage, \r
920 StartStringId, \r
921 StringId, \r
922 &BlockType,\r
923 &StringBlockAddr,\r
924 (BOOLEAN)(StringFontInfo != NULL)\r
925 );\r
926 if (EFI_ERROR (Status)) {\r
927 return Status;\r
928 }\r
929 if (StringFontInfo != NULL) {\r
930 StringTextOffset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);\r
931 } else {\r
932 StringTextOffset = sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK) - sizeof (CHAR16);\r
933 }\r
93e3992d 934 }\r
935\r
936 LocalFont = NULL;\r
937 GlobalFont = NULL;\r
938 Referred = FALSE;\r
939\r
940 //\r
813acf3a 941 // The input StringFontInfo should exist in current database if specified.\r
93e3992d 942 //\r
943 if (StringFontInfo != NULL) {\r
93e3992d 944 if (!IsFontInfoExisted (Private, StringFontInfo, NULL, NULL, &GlobalFont)) {\r
945 return EFI_INVALID_PARAMETER;\r
946 } else {\r
813acf3a 947 Referred = ReferFontInfoLocally (\r
948 Private, \r
949 StringPackage, \r
950 StringPackage->FontId, \r
951 FALSE, \r
952 GlobalFont, \r
953 &LocalFont\r
954 );\r
955 if (!Referred) {\r
956 StringPackage->FontId++;\r
957 }\r
93e3992d 958 }\r
93e3992d 959 //\r
813acf3a 960 // Update the FontId of the specified string block to input font info.\r
93e3992d 961 //\r
962 switch (BlockType) {\r
813acf3a 963 case EFI_HII_SIBT_STRING_SCSU_FONT: \r
93e3992d 964 case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
965 case EFI_HII_SIBT_STRING_UCS2_FONT:\r
966 case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
967 *(StringBlockAddr + sizeof (EFI_HII_STRING_BLOCK)) = LocalFont->FontId;\r
968 break;\r
969 default:\r
813acf3a 970 //\r
971 // When modify the font info of these blocks, the block type should be updated\r
972 // to contain font info thus the whole structure should be revised.\r
973 // It is recommended to use tool to modify the block type not in the code.\r
974 // \r
975 return EFI_UNSUPPORTED;\r
93e3992d 976 }\r
93e3992d 977 }\r
978\r
979 OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;\r
980\r
981 //\r
813acf3a 982 // Set the string text and font.\r
93e3992d 983 //\r
984 StringTextPtr = StringBlockAddr + StringTextOffset;\r
985 switch (BlockType) {\r
986 case EFI_HII_SIBT_STRING_SCSU:\r
987 case EFI_HII_SIBT_STRING_SCSU_FONT:\r
988 case EFI_HII_SIBT_STRINGS_SCSU:\r
989 case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
990 BlockSize = OldBlockSize + StrLen (String);\r
e5c861ac 991 BlockSize -= AsciiStrSize ((CHAR8 *) StringTextPtr);\r
93e3992d 992 Block = AllocateZeroPool (BlockSize);\r
993 if (Block == NULL) {\r
994 return EFI_OUT_OF_RESOURCES;\r
995 }\r
996\r
997 CopyMem (Block, StringPackage->StringBlock, StringTextPtr - StringPackage->StringBlock);\r
998 BlockPtr = Block + (StringTextPtr - StringPackage->StringBlock);\r
999\r
1000 while (*String != 0) {\r
1001 *BlockPtr++ = (CHAR8) *String++;\r
1002 }\r
1003 *BlockPtr++ = 0;\r
1004\r
1005 \r
1006 TmpSize = OldBlockSize - (StringTextPtr - StringPackage->StringBlock) - AsciiStrSize ((CHAR8 *) StringTextPtr);\r
1007 CopyMem (\r
1008 BlockPtr,\r
1009 StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr),\r
1010 TmpSize\r
1011 );\r
1012\r
676df92c 1013 FreePool (StringPackage->StringBlock);\r
93e3992d 1014 StringPackage->StringBlock = Block;\r
1015 StringPackage->StringPkgHdr->Header.Length += (UINT32) (BlockSize - OldBlockSize);\r
1016 break;\r
1017\r
1018 case EFI_HII_SIBT_STRING_UCS2:\r
1019 case EFI_HII_SIBT_STRING_UCS2_FONT:\r
1020 case EFI_HII_SIBT_STRINGS_UCS2:\r
1021 case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
1022 //\r
1023 // Use StrSize to store the size of the specified string, including the NULL\r
1024 // terminator.\r
1025 //\r
1026 GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);\r
1027\r
1028 BlockSize = OldBlockSize + StrSize (String) - StringSize;\r
1029 Block = AllocateZeroPool (BlockSize);\r
1030 if (Block == NULL) {\r
1031 return EFI_OUT_OF_RESOURCES;\r
1032 }\r
1033\r
1034 CopyMem (Block, StringPackage->StringBlock, StringTextPtr - StringPackage->StringBlock);\r
1035 BlockPtr = Block + (StringTextPtr - StringPackage->StringBlock);\r
1036\r
1037 CopyMem (BlockPtr, String, StrSize (String));\r
1038 BlockPtr += StrSize (String);\r
1039\r
1040 CopyMem (\r
1041 BlockPtr,\r
1042 StringTextPtr + StringSize,\r
1043 OldBlockSize - (StringTextPtr - StringPackage->StringBlock) - StringSize\r
1044 );\r
1045\r
676df92c 1046 FreePool (StringPackage->StringBlock);\r
93e3992d 1047 StringPackage->StringBlock = Block;\r
1048 StringPackage->StringPkgHdr->Header.Length += (UINT32) (BlockSize - OldBlockSize);\r
1049 break;\r
1050\r
1051 default:\r
1052 return EFI_NOT_FOUND;\r
1053 }\r
1054\r
1055 //\r
1056 // Insert a new EFI_HII_SIBT_FONT_BLOCK to the header of string block, if incoming\r
1057 // StringFontInfo does not exist in current string package.\r
1058 //\r
1059 // This new block does not impact on the value of StringId.\r
1060 //\r
1061 //\r
1062 if (StringFontInfo == NULL || Referred) {\r
1063 return EFI_SUCCESS;\r
1064 }\r
1065\r
1066 OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;\r
1067 BlockSize = OldBlockSize + sizeof (EFI_HII_SIBT_FONT_BLOCK) - sizeof (CHAR16) +\r
1068 StrSize (GlobalFont->FontInfo->FontName);\r
1069\r
1070 Block = AllocateZeroPool (BlockSize);\r
1071 if (Block == NULL) {\r
1072 return EFI_OUT_OF_RESOURCES;\r
1073 }\r
1074\r
1075 BlockPtr = Block;\r
1076 Ext2.Header.BlockType = EFI_HII_SIBT_EXT2;\r
1077 Ext2.BlockType2 = EFI_HII_SIBT_FONT;\r
1078 Ext2.Length = (UINT16) (BlockSize - OldBlockSize);\r
1079 CopyMem (BlockPtr, &Ext2, sizeof (EFI_HII_SIBT_EXT2_BLOCK));\r
1080 BlockPtr += sizeof (EFI_HII_SIBT_EXT2_BLOCK);\r
1081\r
1082 *BlockPtr = LocalFont->FontId;\r
6e1e5405 1083 BlockPtr ++;\r
93e3992d 1084 CopyMem (BlockPtr, &GlobalFont->FontInfo->FontSize, sizeof (UINT16));\r
1085 BlockPtr += sizeof (UINT16);\r
1086 CopyMem (BlockPtr, &GlobalFont->FontInfo->FontStyle, sizeof (UINT32));\r
1087 BlockPtr += sizeof (UINT32);\r
1088 CopyMem (\r
1089 BlockPtr,\r
1090 GlobalFont->FontInfo->FontName,\r
1091 StrSize (GlobalFont->FontInfo->FontName)\r
1092 );\r
1093 BlockPtr += StrSize (GlobalFont->FontInfo->FontName);\r
1094\r
1095 CopyMem (BlockPtr, StringPackage->StringBlock, OldBlockSize);\r
1096\r
676df92c 1097 FreePool (StringPackage->StringBlock);\r
93e3992d 1098 StringPackage->StringBlock = Block;\r
1099 StringPackage->StringPkgHdr->Header.Length += Ext2.Length;\r
1100\r
1101 return EFI_SUCCESS;\r
1102\r
1103}\r
1104\r
1105\r
1106/**\r
1107 This function adds the string String to the group of strings owned by PackageList, with the\r
d6a82eaf
LG
1108 specified font information StringFontInfo and returns a new string id. \r
1109 The new string identifier is guaranteed to be unique within the package list. \r
1110 That new string identifier is reserved for all languages in the package list. \r
1111\r
93e3992d 1112\r
1113 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.\r
1114 @param PackageList Handle of the package list where this string will\r
1115 be added.\r
1116 @param StringId On return, contains the new strings id, which is\r
1117 unique within PackageList.\r
1118 @param Language Points to the language for the new string.\r
1119 @param LanguageName Points to the printable language name to associate\r
1120 with the passed in Language field.If LanguageName\r
1121 is not NULL and the string package header's\r
1122 LanguageName associated with a given Language is\r
1123 not zero, the LanguageName being passed in will\r
1124 be ignored.\r
1125 @param String Points to the new null-terminated string.\r
ac644614 1126 @param StringFontInfo Points to the new string's font information or\r
93e3992d 1127 NULL if the string should have the default system\r
1128 font, size and style.\r
1129\r
1130 @retval EFI_SUCCESS The new string was added successfully.\r
1131 @retval EFI_NOT_FOUND The specified PackageList could not be found in\r
1132 database.\r
1133 @retval EFI_OUT_OF_RESOURCES Could not add the string due to lack of resources.\r
1134 @retval EFI_INVALID_PARAMETER String is NULL or StringId is NULL or Language is\r
1135 NULL.\r
1136 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in\r
1137 current database.\r
1138\r
1139**/\r
1140EFI_STATUS\r
1141EFIAPI\r
1142HiiNewString (\r
1143 IN CONST EFI_HII_STRING_PROTOCOL *This,\r
1144 IN EFI_HII_HANDLE PackageList,\r
1145 OUT EFI_STRING_ID *StringId,\r
1146 IN CONST CHAR8 *Language,\r
1147 IN CONST CHAR16 *LanguageName, OPTIONAL\r
1148 IN CONST EFI_STRING String,\r
1149 IN CONST EFI_FONT_INFO *StringFontInfo OPTIONAL\r
1150 )\r
1151{\r
1152 EFI_STATUS Status;\r
1153 LIST_ENTRY *Link;\r
93e3992d 1154 HII_DATABASE_PRIVATE_DATA *Private;\r
1155 HII_DATABASE_RECORD *DatabaseRecord;\r
1156 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;\r
1157 HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
1158 UINT32 HeaderSize;\r
1159 UINT32 BlockSize;\r
1160 UINT32 OldBlockSize;\r
1161 UINT8 *StringBlock;\r
1162 UINT8 *BlockPtr;\r
1163 UINT32 Ucs2BlockSize;\r
1164 UINT32 FontBlockSize;\r
1165 UINT32 Ucs2FontBlockSize;\r
1166 EFI_HII_SIBT_EXT2_BLOCK Ext2;\r
1167 HII_FONT_INFO *LocalFont;\r
1168 HII_GLOBAL_FONT_INFO *GlobalFont;\r
d6a82eaf
LG
1169 EFI_STRING_ID NewStringId;\r
1170 EFI_STRING_ID NextStringId;\r
1171 EFI_STRING_ID Index;\r
1172 HII_STRING_PACKAGE_INSTANCE *MatchStringPackage;\r
1173 BOOLEAN NewStringPackageCreated;\r
1174\r
93e3992d 1175\r
1176 if (This == NULL || String == NULL || StringId == NULL || Language == NULL || PackageList == NULL) {\r
1177 return EFI_INVALID_PARAMETER;\r
1178 }\r
1179\r
1180 if (!IsHiiHandleValid (PackageList)) {\r
1181 return EFI_NOT_FOUND;\r
1182 }\r
1183\r
1184 Private = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
1185 GlobalFont = NULL;\r
1186\r
1187 //\r
1188 // If StringFontInfo specify a paritcular font, it should exist in current database.\r
1189 //\r
1190 if (StringFontInfo != NULL) {\r
1191 if (!IsFontInfoExisted (Private, (EFI_FONT_INFO *) StringFontInfo, NULL, NULL, &GlobalFont)) {\r
1192 return EFI_INVALID_PARAMETER;\r
1193 }\r
1194 }\r
1195\r
1196 //\r
1197 // Get the matching package list.\r
1198 //\r
1199 PackageListNode = NULL;\r
1200 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
1201 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
1202 if (DatabaseRecord->Handle == PackageList) {\r
1203 PackageListNode = DatabaseRecord->PackageList;\r
1204 break;\r
1205 }\r
1206 }\r
1207 if (PackageListNode == NULL) {\r
1208 return EFI_NOT_FOUND;\r
1209 }\r
1210\r
d6a82eaf
LG
1211 Status = EFI_SUCCESS;\r
1212 NewStringPackageCreated = FALSE;\r
1213 NewStringId = 0;\r
1214 NextStringId = 0;\r
93e3992d 1215 StringPackage = NULL;\r
d6a82eaf 1216 MatchStringPackage = NULL;\r
93e3992d 1217 for (Link = PackageListNode->StringPkgHdr.ForwardLink;\r
1218 Link != &PackageListNode->StringPkgHdr;\r
1219 Link = Link->ForwardLink\r
1220 ) {\r
1221 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
d6a82eaf
LG
1222 //\r
1223 // Create a string block and corresponding font block if exists, then append them\r
1224 // to the end of the string package.\r
1225 //\r
1226 Status = FindStringBlock (\r
1227 Private,\r
1228 StringPackage,\r
1229 0,\r
1230 NULL,\r
1231 NULL,\r
1232 NULL,\r
e5c861ac
ED
1233 &NextStringId,\r
1234 NULL\r
d6a82eaf
LG
1235 );\r
1236 if (EFI_ERROR (Status)) {\r
1237 goto Done;\r
1238 }\r
1239 //\r
1240 // Make sure that new StringId is same in all String Packages for the different language.\r
1241 //\r
1242 if (NewStringId != 0 && NewStringId != NextStringId) {\r
1243 ASSERT (FALSE);\r
1244 Status = EFI_INVALID_PARAMETER;\r
1245 goto Done;\r
1246 }\r
1247 NewStringId = NextStringId;\r
1248 //\r
1249 // Get the matched string package with language.\r
1250 //\r
f324bf4d 1251 if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) {\r
d6a82eaf
LG
1252 MatchStringPackage = StringPackage;\r
1253 } else {\r
1254 OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;\r
1255 //\r
1256 // Create a blank EFI_HII_SIBT_STRING_UCS2_BLOCK to reserve new string ID.\r
1257 //\r
1258 Ucs2BlockSize = (UINT32) sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK);\r
1259\r
1260 StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Ucs2BlockSize);\r
1261 if (StringBlock == NULL) {\r
1262 Status = EFI_OUT_OF_RESOURCES;\r
1263 goto Done;\r
1264 }\r
1265 //\r
1266 // Copy original string blocks, except the EFI_HII_SIBT_END.\r
1267 //\r
1268 CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));\r
1269 //\r
1270 // Create a blank EFI_HII_SIBT_STRING_UCS2 block\r
1271 //\r
1272 BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);\r
1273 *BlockPtr = EFI_HII_SIBT_STRING_UCS2;\r
1274 BlockPtr += sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK);\r
1275\r
1276 //\r
1277 // Append a EFI_HII_SIBT_END block to the end.\r
1278 //\r
1279 *BlockPtr = EFI_HII_SIBT_END;\r
1280 FreePool (StringPackage->StringBlock);\r
1281 StringPackage->StringBlock = StringBlock;\r
1282 StringPackage->StringPkgHdr->Header.Length += Ucs2BlockSize;\r
1283 PackageListNode->PackageListHdr.PackageLength += Ucs2BlockSize;\r
93e3992d 1284 }\r
1285 }\r
d6a82eaf
LG
1286 if (NewStringId == 0) {\r
1287 //\r
1288 // No string package is found.\r
1289 // Create new string package. StringId 1 is reserved for Language Name string.\r
1290 //\r
1291 *StringId = 2;\r
1292 } else {\r
1293 //\r
1294 // Set new StringId\r
1295 //\r
d7c0e60c 1296 *StringId = (EFI_STRING_ID) (NewStringId + 1);\r
d6a82eaf 1297 }\r
93e3992d 1298\r
d6a82eaf
LG
1299 if (MatchStringPackage != NULL) {\r
1300 StringPackage = MatchStringPackage;\r
1301 } else {\r
93e3992d 1302 //\r
1303 // LanguageName is required to create a new string package.\r
1304 //\r
1305 if (LanguageName == NULL) {\r
d6a82eaf
LG
1306 Status = EFI_INVALID_PARAMETER;\r
1307 goto Done;\r
93e3992d 1308 }\r
1309\r
1310 StringPackage = AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE));\r
1311 if (StringPackage == NULL) {\r
d6a82eaf
LG
1312 Status = EFI_OUT_OF_RESOURCES;\r
1313 goto Done;\r
93e3992d 1314 }\r
1315\r
d6a82eaf
LG
1316 StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE;\r
1317 StringPackage->MaxStringId = *StringId;\r
1318 StringPackage->FontId = 0;\r
93e3992d 1319 InitializeListHead (&StringPackage->FontInfoList);\r
1320\r
1321 //\r
1322 // Fill in the string package header\r
1323 //\r
1324 HeaderSize = (UINT32) (AsciiStrSize ((CHAR8 *) Language) - 1 + sizeof (EFI_HII_STRING_PACKAGE_HDR));\r
1325 StringPackage->StringPkgHdr = AllocateZeroPool (HeaderSize);\r
1326 if (StringPackage->StringPkgHdr == NULL) {\r
676df92c 1327 FreePool (StringPackage);\r
d6a82eaf
LG
1328 Status = EFI_OUT_OF_RESOURCES;\r
1329 goto Done;\r
93e3992d 1330 }\r
1331 StringPackage->StringPkgHdr->Header.Type = EFI_HII_PACKAGE_STRINGS;\r
1332 StringPackage->StringPkgHdr->HdrSize = HeaderSize;\r
1333 StringPackage->StringPkgHdr->StringInfoOffset = HeaderSize;\r
d6a82eaf 1334 CopyMem (StringPackage->StringPkgHdr->LanguageWindow, mLanguageWindow, 16 * sizeof (CHAR16));\r
93e3992d 1335 StringPackage->StringPkgHdr->LanguageName = 1;\r
1336 AsciiStrCpy (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language);\r
1337\r
1338 //\r
1339 // Calculate the length of the string blocks, including string block to record\r
1340 // printable language full name and EFI_HII_SIBT_END_BLOCK.\r
1341 //\r
d6a82eaf
LG
1342 Ucs2BlockSize = (UINT32) (StrSize ((CHAR16 *) LanguageName) + \r
1343 (*StringId - 1) * sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK) - sizeof (CHAR16));\r
93e3992d 1344\r
1345 BlockSize = Ucs2BlockSize + sizeof (EFI_HII_SIBT_END_BLOCK);\r
1346 StringPackage->StringBlock = (UINT8 *) AllocateZeroPool (BlockSize);\r
1347 if (StringPackage->StringBlock == NULL) {\r
676df92c 1348 FreePool (StringPackage->StringPkgHdr);\r
1349 FreePool (StringPackage);\r
d6a82eaf
LG
1350 Status = EFI_OUT_OF_RESOURCES;\r
1351 goto Done;\r
93e3992d 1352 }\r
1353\r
1354 //\r
1355 // Insert the string block of printable language full name\r
1356 //\r
1357 BlockPtr = StringPackage->StringBlock;\r
1358 *BlockPtr = EFI_HII_SIBT_STRING_UCS2;\r
1359 BlockPtr += sizeof (EFI_HII_STRING_BLOCK);\r
1360 CopyMem (BlockPtr, (EFI_STRING) LanguageName, StrSize ((EFI_STRING) LanguageName));\r
1361 BlockPtr += StrSize ((EFI_STRING) LanguageName);\r
d6a82eaf
LG
1362 for (Index = 2; Index <= *StringId - 1; Index ++) {\r
1363 *BlockPtr = EFI_HII_SIBT_STRING_UCS2;\r
1364 BlockPtr += sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK);\r
1365 }\r
93e3992d 1366 //\r
1367 // Insert the end block\r
1368 //\r
1369 *BlockPtr = EFI_HII_SIBT_END;\r
1370\r
1371 //\r
1372 // Append this string package node to string package array in this package list.\r
1373 //\r
1374 StringPackage->StringPkgHdr->Header.Length = HeaderSize + BlockSize;\r
1375 PackageListNode->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length;\r
1376 InsertTailList (&PackageListNode->StringPkgHdr, &StringPackage->StringEntry);\r
d6a82eaf 1377 NewStringPackageCreated = TRUE;\r
93e3992d 1378 }\r
1379\r
1380 OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;\r
1381\r
1382 if (StringFontInfo == NULL) {\r
1383 //\r
1384 // Create a EFI_HII_SIBT_STRING_UCS2_BLOCK since font info is not specified.\r
1385 //\r
93e3992d 1386 Ucs2BlockSize = (UINT32) (StrSize (String) + sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK)\r
1387 - sizeof (CHAR16));\r
1388\r
1389 StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Ucs2BlockSize);\r
1390 if (StringBlock == NULL) {\r
d6a82eaf
LG
1391 Status = EFI_OUT_OF_RESOURCES;\r
1392 goto Done;\r
93e3992d 1393 }\r
1394 //\r
1395 // Copy original string blocks, except the EFI_HII_SIBT_END.\r
1396 //\r
1397 CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));\r
1398 //\r
1399 // Create a EFI_HII_SIBT_STRING_UCS2 block\r
1400 //\r
1401 BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);\r
1402 *BlockPtr = EFI_HII_SIBT_STRING_UCS2;\r
1403 BlockPtr += sizeof (EFI_HII_STRING_BLOCK);\r
1404 CopyMem (BlockPtr, (EFI_STRING) String, StrSize ((EFI_STRING) String));\r
1405 BlockPtr += StrSize ((EFI_STRING) String);\r
1406\r
1407 //\r
1408 // Append a EFI_HII_SIBT_END block to the end.\r
1409 //\r
1410 *BlockPtr = EFI_HII_SIBT_END;\r
676df92c 1411 FreePool (StringPackage->StringBlock);\r
93e3992d 1412 StringPackage->StringBlock = StringBlock;\r
1413 StringPackage->StringPkgHdr->Header.Length += Ucs2BlockSize;\r
1414 PackageListNode->PackageListHdr.PackageLength += Ucs2BlockSize;\r
1415\r
1416 } else {\r
1417 //\r
1418 // StringFontInfo is specified here. If there is a EFI_HII_SIBT_FONT_BLOCK\r
1419 // which refers to this font info, create a EFI_HII_SIBT_STRING_UCS2_FONT block\r
1420 // only. Otherwise create a EFI_HII_SIBT_FONT block with a EFI_HII_SIBT_STRING\r
1421 // _UCS2_FONT block.\r
1422 //\r
1423 Ucs2FontBlockSize = (UINT32) (StrSize (String) + sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) -\r
1424 sizeof (CHAR16));\r
813acf3a 1425 if (ReferFontInfoLocally (Private, StringPackage, StringPackage->FontId, FALSE, GlobalFont, &LocalFont)) {\r
93e3992d 1426 //\r
1427 // Create a EFI_HII_SIBT_STRING_UCS2_FONT block only.\r
1428 //\r
1429 StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Ucs2FontBlockSize);\r
1430 if (StringBlock == NULL) {\r
d6a82eaf
LG
1431 Status = EFI_OUT_OF_RESOURCES;\r
1432 goto Done;\r
93e3992d 1433 }\r
1434 //\r
1435 // Copy original string blocks, except the EFI_HII_SIBT_END.\r
1436 //\r
1437 CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));\r
1438 //\r
1439 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK\r
1440 //\r
1441 BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);\r
1442 *BlockPtr = EFI_HII_SIBT_STRING_UCS2_FONT;\r
1443 BlockPtr += sizeof (EFI_HII_STRING_BLOCK);\r
1444 *BlockPtr = LocalFont->FontId;\r
6e1e5405 1445 BlockPtr ++;\r
93e3992d 1446 CopyMem (BlockPtr, (EFI_STRING) String, StrSize ((EFI_STRING) String));\r
1447 BlockPtr += StrSize ((EFI_STRING) String);\r
1448\r
1449 //\r
1450 // Append a EFI_HII_SIBT_END block to the end.\r
1451 //\r
1452 *BlockPtr = EFI_HII_SIBT_END;\r
676df92c 1453 FreePool (StringPackage->StringBlock);\r
93e3992d 1454 StringPackage->StringBlock = StringBlock;\r
1455 StringPackage->StringPkgHdr->Header.Length += Ucs2FontBlockSize;\r
1456 PackageListNode->PackageListHdr.PackageLength += Ucs2FontBlockSize;\r
1457\r
1458 } else {\r
1459 //\r
1460 // EFI_HII_SIBT_FONT_BLOCK does not exist in current string package, so\r
1461 // create a EFI_HII_SIBT_FONT block to record the font info, then generate\r
1462 // a EFI_HII_SIBT_STRING_UCS2_FONT block to record the incoming string.\r
1463 //\r
1464 FontBlockSize = (UINT32) (StrSize (((EFI_FONT_INFO *) StringFontInfo)->FontName) +\r
1465 sizeof (EFI_HII_SIBT_FONT_BLOCK) - sizeof (CHAR16));\r
1466 StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + FontBlockSize + Ucs2FontBlockSize);\r
1467 if (StringBlock == NULL) {\r
d6a82eaf
LG
1468 Status = EFI_OUT_OF_RESOURCES;\r
1469 goto Done;\r
93e3992d 1470 }\r
1471 //\r
1472 // Copy original string blocks, except the EFI_HII_SIBT_END.\r
1473 //\r
1474 CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));\r
1475\r
1476 //\r
1477 // Create a EFI_HII_SIBT_FONT block firstly and then backup its info in string\r
1478 // package instance for future reference.\r
1479 //\r
1480 BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);\r
1481\r
1482 Ext2.Header.BlockType = EFI_HII_SIBT_EXT2;\r
1483 Ext2.BlockType2 = EFI_HII_SIBT_FONT;\r
1484 Ext2.Length = (UINT16) FontBlockSize;\r
1485 CopyMem (BlockPtr, &Ext2, sizeof (EFI_HII_SIBT_EXT2_BLOCK));\r
1486 BlockPtr += sizeof (EFI_HII_SIBT_EXT2_BLOCK);\r
1487\r
1488 *BlockPtr = LocalFont->FontId;\r
6e1e5405 1489 BlockPtr ++;\r
93e3992d 1490 CopyMem (BlockPtr, &((EFI_FONT_INFO *) StringFontInfo)->FontSize, sizeof (UINT16));\r
1491 BlockPtr += sizeof (UINT16);\r
1492 CopyMem (BlockPtr, &((EFI_FONT_INFO *) StringFontInfo)->FontStyle, sizeof (EFI_HII_FONT_STYLE));\r
1493 BlockPtr += sizeof (EFI_HII_FONT_STYLE);\r
1494 CopyMem (\r
1495 BlockPtr,\r
1496 &((EFI_FONT_INFO *) StringFontInfo)->FontName,\r
1497 StrSize (((EFI_FONT_INFO *) StringFontInfo)->FontName)\r
1498 );\r
d6a82eaf 1499 BlockPtr += StrSize (((EFI_FONT_INFO *) StringFontInfo)->FontName);\r
93e3992d 1500 //\r
1501 // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK\r
1502 //\r
1503 *BlockPtr = EFI_HII_SIBT_STRING_UCS2_FONT;\r
1504 BlockPtr += sizeof (EFI_HII_STRING_BLOCK);\r
1505 *BlockPtr = LocalFont->FontId;\r
6e1e5405 1506 BlockPtr ++;\r
93e3992d 1507 CopyMem (BlockPtr, (EFI_STRING) String, StrSize ((EFI_STRING) String));\r
1508 BlockPtr += StrSize ((EFI_STRING) String);\r
1509\r
1510 //\r
1511 // Append a EFI_HII_SIBT_END block to the end.\r
1512 //\r
1513 *BlockPtr = EFI_HII_SIBT_END;\r
676df92c 1514 FreePool (StringPackage->StringBlock);\r
93e3992d 1515 StringPackage->StringBlock = StringBlock;\r
1516 StringPackage->StringPkgHdr->Header.Length += FontBlockSize + Ucs2FontBlockSize;\r
1517 PackageListNode->PackageListHdr.PackageLength += FontBlockSize + Ucs2FontBlockSize;\r
813acf3a 1518\r
1519 //\r
1520 // Increase the FontId to make it unique since we already add \r
1521 // a EFI_HII_SIBT_FONT block to this string package.\r
1522 //\r
1523 StringPackage->FontId++;\r
93e3992d 1524 }\r
1525 }\r
1526\r
d6a82eaf
LG
1527Done:\r
1528 if (!EFI_ERROR (Status) && NewStringPackageCreated) {\r
1529 //\r
1530 // Trigger any registered notification function for new string package\r
1531 //\r
1532 Status = InvokeRegisteredFunction (\r
1533 Private,\r
1534 EFI_HII_DATABASE_NOTIFY_NEW_PACK,\r
1535 (VOID *) StringPackage,\r
1536 EFI_HII_PACKAGE_STRINGS,\r
1537 PackageList\r
1538 );\r
8d00a0f1 1539 }\r
1540\r
d6a82eaf
LG
1541 if (!EFI_ERROR (Status)) {\r
1542 //\r
1543 // Update MaxString Id to new StringId\r
1544 //\r
1545 for (Link = PackageListNode->StringPkgHdr.ForwardLink;\r
1546 Link != &PackageListNode->StringPkgHdr;\r
1547 Link = Link->ForwardLink\r
1548 ) {\r
1549 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
1550 StringPackage->MaxStringId = *StringId;\r
1551 }\r
1552 } else if (NewStringPackageCreated) {\r
1553 //\r
1554 // Free the allocated new string Package when new string can't be added.\r
1555 //\r
1556 RemoveEntryList (&StringPackage->StringEntry);\r
1557 FreePool (StringPackage->StringBlock);\r
1558 FreePool (StringPackage->StringPkgHdr);\r
1559 FreePool (StringPackage);\r
1560 }\r
1561\r
1562 return Status;\r
93e3992d 1563}\r
1564\r
1565\r
1566/**\r
1567 This function retrieves the string specified by StringId which is associated\r
1568 with the specified PackageList in the language Language and copies it into\r
1569 the buffer specified by String.\r
1570\r
1571 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.\r
1572 @param Language Points to the language for the retrieved string.\r
1573 @param PackageList The package list in the HII database to search for\r
1574 the specified string.\r
1575 @param StringId The string's id, which is unique within\r
1576 PackageList.\r
1577 @param String Points to the new null-terminated string.\r
1578 @param StringSize On entry, points to the size of the buffer pointed\r
1579 to by String, in bytes. On return, points to the\r
1580 length of the string, in bytes.\r
ac644614 1581 @param StringFontInfo If not NULL, points to the string's font\r
93e3992d 1582 information. It's caller's responsibility to free\r
1583 this buffer.\r
1584\r
1585 @retval EFI_SUCCESS The string was returned successfully.\r
1586 @retval EFI_NOT_FOUND The string specified by StringId is not available.\r
1587 @retval EFI_NOT_FOUND The string specified by StringId is available but\r
813acf3a 1588 not in the specified language.\r
1589 The specified PackageList is not in the database.\r
1590 @retval EFI_INVALID_LANGUAGE - The string specified by StringId is available but\r
93e3992d 1591 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to\r
1592 hold the string.\r
c0a3c3da
ED
1593 @retval EFI_INVALID_PARAMETER The Language or StringSize was NULL.\r
1594 @retval EFI_INVALID_PARAMETER The value referenced by StringSize was not zero and String was NULL.\r
93e3992d 1595 @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the\r
1596 request.\r
1597\r
1598**/\r
1599EFI_STATUS\r
1600EFIAPI\r
1601HiiGetString (\r
1602 IN CONST EFI_HII_STRING_PROTOCOL *This,\r
1603 IN CONST CHAR8 *Language,\r
1604 IN EFI_HII_HANDLE PackageList,\r
1605 IN EFI_STRING_ID StringId,\r
1606 OUT EFI_STRING String,\r
1607 IN OUT UINTN *StringSize,\r
1608 OUT EFI_FONT_INFO **StringFontInfo OPTIONAL\r
1609 )\r
1610{\r
1611 EFI_STATUS Status;\r
1612 LIST_ENTRY *Link;\r
1613 HII_DATABASE_PRIVATE_DATA *Private;\r
1614 HII_DATABASE_RECORD *DatabaseRecord;\r
1615 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;\r
1616 HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
1617\r
1618 if (This == NULL || Language == NULL || StringId < 1 || StringSize == NULL || PackageList == NULL) {\r
1619 return EFI_INVALID_PARAMETER;\r
1620 }\r
1621\r
1622 if (String == NULL && *StringSize != 0) {\r
1623 return EFI_INVALID_PARAMETER;\r
1624 }\r
1625\r
1626 if (!IsHiiHandleValid (PackageList)) {\r
1627 return EFI_NOT_FOUND;\r
1628 }\r
1629\r
1630 Private = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
1631 PackageListNode = NULL;\r
1632\r
1633 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
1634 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
1635 if (DatabaseRecord->Handle == PackageList) {\r
1636 PackageListNode = DatabaseRecord->PackageList;\r
1637 break;\r
1638 }\r
1639 }\r
1640\r
1641 if (PackageListNode != NULL) {\r
813acf3a 1642 //\r
1643 // First search: to match the StringId in the specified language.\r
1644 //\r
93e3992d 1645 for (Link = PackageListNode->StringPkgHdr.ForwardLink;\r
1646 Link != &PackageListNode->StringPkgHdr;\r
1647 Link = Link->ForwardLink\r
1648 ) {\r
813acf3a 1649 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
f324bf4d 1650 if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) {\r
813acf3a 1651 Status = GetStringWorker (Private, StringPackage, StringId, String, StringSize, StringFontInfo);\r
1652 if (Status != EFI_NOT_FOUND) {\r
1653 return Status;\r
1654 }\r
93e3992d 1655 }\r
1656 }\r
813acf3a 1657 //\r
1658 // Second search: to match the StringId in other available languages if exist.\r
1659 //\r
1660 for (Link = PackageListNode->StringPkgHdr.ForwardLink; \r
1661 Link != &PackageListNode->StringPkgHdr;\r
1662 Link = Link->ForwardLink\r
1663 ) {\r
1664 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE); \r
b86b413a 1665 Status = GetStringWorker (Private, StringPackage, StringId, NULL, NULL, NULL);\r
813acf3a 1666 if (!EFI_ERROR (Status)) {\r
1667 return EFI_INVALID_LANGUAGE;\r
1668 }\r
1669 } \r
93e3992d 1670 }\r
1671\r
1672 return EFI_NOT_FOUND;\r
1673}\r
1674\r
1675\r
1676\r
1677/**\r
1678 This function updates the string specified by StringId in the specified PackageList to the text\r
1679 specified by String and, optionally, the font information specified by StringFontInfo.\r
1680\r
1681 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.\r
1682 @param PackageList The package list containing the strings.\r
ac644614 1683 @param StringId The string's id, which is unique within\r
93e3992d 1684 PackageList.\r
1685 @param Language Points to the language for the updated string.\r
1686 @param String Points to the new null-terminated string.\r
ac644614 1687 @param StringFontInfo Points to the string's font information or NULL if\r
93e3992d 1688 the string font information is not changed.\r
1689\r
1690 @retval EFI_SUCCESS The string was updated successfully.\r
1691 @retval EFI_NOT_FOUND The string specified by StringId is not in the\r
1692 database.\r
1693 @retval EFI_INVALID_PARAMETER The String or Language was NULL.\r
1694 @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in\r
1695 current database.\r
1696 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the\r
1697 task.\r
1698\r
1699**/\r
1700EFI_STATUS\r
1701EFIAPI\r
1702HiiSetString (\r
1703 IN CONST EFI_HII_STRING_PROTOCOL *This,\r
1704 IN EFI_HII_HANDLE PackageList,\r
1705 IN EFI_STRING_ID StringId,\r
1706 IN CONST CHAR8 *Language,\r
1707 IN CONST EFI_STRING String,\r
1708 IN CONST EFI_FONT_INFO *StringFontInfo OPTIONAL\r
1709 )\r
1710{\r
1711 EFI_STATUS Status;\r
1712 LIST_ENTRY *Link;\r
1713 HII_DATABASE_PRIVATE_DATA *Private;\r
1714 HII_DATABASE_RECORD *DatabaseRecord;\r
1715 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;\r
1716 HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
1717 UINT32 OldPackageLen;\r
1718\r
1719 if (This == NULL || Language == NULL || StringId < 1 || String == NULL || PackageList == NULL) {\r
1720 return EFI_INVALID_PARAMETER;\r
1721 }\r
1722\r
1723 if (!IsHiiHandleValid (PackageList)) {\r
1724 return EFI_NOT_FOUND;\r
1725 }\r
1726\r
1727 Private = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
1728 PackageListNode = NULL;\r
1729\r
1730 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
1731 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
1732 if (DatabaseRecord->Handle == PackageList) {\r
1733 PackageListNode = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (DatabaseRecord->PackageList);\r
1734 }\r
1735 }\r
1736\r
1737 if (PackageListNode != NULL) {\r
1738 for (Link = PackageListNode->StringPkgHdr.ForwardLink;\r
1739 Link != &PackageListNode->StringPkgHdr;\r
1740 Link = Link->ForwardLink\r
1741 ) {\r
1742 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
f324bf4d 1743 if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) {\r
93e3992d 1744 OldPackageLen = StringPackage->StringPkgHdr->Header.Length;\r
1745 Status = SetStringWorker (\r
1746 Private,\r
1747 StringPackage,\r
1748 StringId,\r
1749 (EFI_STRING) String,\r
1750 (EFI_FONT_INFO *) StringFontInfo\r
1751 );\r
1752 if (EFI_ERROR (Status)) {\r
1753 return Status;\r
1754 }\r
1755 PackageListNode->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length - OldPackageLen;\r
1756 return EFI_SUCCESS;\r
1757 }\r
1758 }\r
1759 }\r
1760\r
1761 return EFI_NOT_FOUND;\r
1762}\r
1763\r
1764\r
1765\r
1766/**\r
1767 This function returns the list of supported languages, in the format specified\r
1768 in Appendix M of UEFI 2.1 spec.\r
1769\r
1770 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.\r
1771 @param PackageList The package list to examine.\r
4f077902
SZ
1772 @param Languages Points to the buffer to hold the returned\r
1773 null-terminated ASCII string.\r
93e3992d 1774 @param LanguagesSize On entry, points to the size of the buffer pointed\r
1775 to by Languages, in bytes. On return, points to\r
1776 the length of Languages, in bytes.\r
1777\r
1778 @retval EFI_SUCCESS The languages were returned successfully.\r
c0a3c3da
ED
1779 @retval EFI_INVALID_PARAMETER The LanguagesSize was NULL.\r
1780 @retval EFI_INVALID_PARAMETER The value referenced by LanguagesSize is not zero and Languages is NULL.\r
93e3992d 1781 @retval EFI_BUFFER_TOO_SMALL The LanguagesSize is too small to hold the list of\r
1782 supported languages. LanguageSize is updated to\r
1783 contain the required size.\r
1784 @retval EFI_NOT_FOUND Could not find string package in specified\r
1785 packagelist.\r
1786\r
1787**/\r
1788EFI_STATUS\r
1789EFIAPI\r
1790HiiGetLanguages (\r
1791 IN CONST EFI_HII_STRING_PROTOCOL *This,\r
1792 IN EFI_HII_HANDLE PackageList,\r
1793 IN OUT CHAR8 *Languages,\r
1794 IN OUT UINTN *LanguagesSize\r
1795 )\r
1796{\r
1797 LIST_ENTRY *Link;\r
1798 HII_DATABASE_PRIVATE_DATA *Private;\r
1799 HII_DATABASE_RECORD *DatabaseRecord;\r
1800 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;\r
1801 HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
1802 UINTN ResultSize;\r
1803\r
c0a3c3da
ED
1804 if (This == NULL || LanguagesSize == NULL || PackageList == NULL) {\r
1805 return EFI_INVALID_PARAMETER;\r
1806 }\r
1807 if (*LanguagesSize != 0 && Languages == NULL) {\r
93e3992d 1808 return EFI_INVALID_PARAMETER;\r
1809 }\r
1810 if (!IsHiiHandleValid (PackageList)) {\r
1811 return EFI_NOT_FOUND;\r
1812 }\r
1813\r
1814 Private = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
1815\r
1816 PackageListNode = NULL;\r
1817 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
1818 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
1819 if (DatabaseRecord->Handle == PackageList) {\r
1820 PackageListNode = DatabaseRecord->PackageList;\r
1821 break;\r
1822 }\r
1823 }\r
1824 if (PackageListNode == NULL) {\r
1825 return EFI_NOT_FOUND;\r
1826 }\r
1827\r
1828 //\r
1829 // Search the languages in the specified packagelist.\r
1830 //\r
1831 ResultSize = 0;\r
1832 for (Link = PackageListNode->StringPkgHdr.ForwardLink;\r
1833 Link != &PackageListNode->StringPkgHdr;\r
1834 Link = Link->ForwardLink\r
1835 ) {\r
1836 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
1837 ResultSize += AsciiStrSize (StringPackage->StringPkgHdr->Language);\r
2fef9e5f 1838 if (ResultSize <= *LanguagesSize) {\r
93e3992d 1839 AsciiStrCpy (Languages, StringPackage->StringPkgHdr->Language);\r
1840 Languages += AsciiStrSize (StringPackage->StringPkgHdr->Language);\r
1841 *(Languages - 1) = L';';\r
1842 }\r
1843 }\r
1844 if (ResultSize == 0) {\r
1845 return EFI_NOT_FOUND;\r
1846 }\r
1847\r
1848 if (*LanguagesSize < ResultSize) {\r
1849 *LanguagesSize = ResultSize;\r
1850 return EFI_BUFFER_TOO_SMALL;\r
1851 }\r
1852\r
1853 *(Languages - 1) = 0;\r
1854 return EFI_SUCCESS;\r
1855}\r
1856\r
1857\r
1858/**\r
1859 Each string package has associated with it a single primary language and zero\r
1860 or more secondary languages. This routine returns the secondary languages\r
1861 associated with a package list.\r
1862\r
1863 @param This A pointer to the EFI_HII_STRING_PROTOCOL instance.\r
1864 @param PackageList The package list to examine.\r
4f077902
SZ
1865 @param PrimaryLanguage Points to the null-terminated ASCII string that specifies\r
1866 the primary language. Languages are specified in the\r
1867 format specified in Appendix M of the UEFI 2.0 specification.\r
1868 @param SecondaryLanguages Points to the buffer to hold the returned null-terminated\r
1869 ASCII string that describes the list of\r
93e3992d 1870 secondary languages for the specified\r
4f077902
SZ
1871 PrimaryLanguage. If there are no secondary\r
1872 languages, the function returns successfully, but\r
93e3992d 1873 this is set to NULL.\r
e90b081a 1874 @param SecondaryLanguagesSize On entry, points to the size of the buffer pointed\r
4f077902 1875 to by SecondaryLanguages, in bytes. On return,\r
e90b081a 1876 points to the length of SecondaryLanguages in bytes.\r
93e3992d 1877\r
1878 @retval EFI_SUCCESS Secondary languages were correctly returned.\r
c0a3c3da
ED
1879 @retval EFI_INVALID_PARAMETER PrimaryLanguage or SecondaryLanguagesSize was NULL.\r
1880 @retval EFI_INVALID_PARAMETER The value referenced by SecondaryLanguagesSize is not\r
1881 zero and SecondaryLanguages is NULL.\r
e90b081a 1882 @retval EFI_BUFFER_TOO_SMALL The buffer specified by SecondaryLanguagesSize is\r
93e3992d 1883 too small to hold the returned information.\r
4f077902 1884 SecondaryLanguageSize is updated to hold the size of\r
93e3992d 1885 the buffer required.\r
4f077902
SZ
1886 @retval EFI_INVALID_LANGUAGE The language specified by PrimaryLanguage is not\r
1887 present in the specified package list.\r
c0a3c3da 1888 @retval EFI_NOT_FOUND The specified PackageList is not in the Database.\r
93e3992d 1889\r
1890**/\r
1891EFI_STATUS\r
1892EFIAPI\r
1893HiiGetSecondaryLanguages (\r
1894 IN CONST EFI_HII_STRING_PROTOCOL *This,\r
1895 IN EFI_HII_HANDLE PackageList,\r
4f077902 1896 IN CONST CHAR8 *PrimaryLanguage,\r
e90b081a 1897 IN OUT CHAR8 *SecondaryLanguages,\r
1898 IN OUT UINTN *SecondaryLanguagesSize\r
93e3992d 1899 )\r
1900{\r
1901 LIST_ENTRY *Link;\r
1902 LIST_ENTRY *Link1;\r
1903 HII_DATABASE_PRIVATE_DATA *Private;\r
1904 HII_DATABASE_RECORD *DatabaseRecord;\r
1905 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;\r
1906 HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
1907 CHAR8 *Languages;\r
1908 UINTN ResultSize;\r
1909\r
c0a3c3da 1910 if (This == NULL || PackageList == NULL || PrimaryLanguage == NULL || SecondaryLanguagesSize == NULL) {\r
93e3992d 1911 return EFI_INVALID_PARAMETER;\r
1912 }\r
c0a3c3da 1913 if (SecondaryLanguages == NULL && *SecondaryLanguagesSize != 0) {\r
93e3992d 1914 return EFI_INVALID_PARAMETER;\r
1915 }\r
1916 if (!IsHiiHandleValid (PackageList)) {\r
1917 return EFI_NOT_FOUND;\r
1918 }\r
1919\r
1920 Private = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
93e3992d 1921\r
813acf3a 1922 PackageListNode = NULL; \r
93e3992d 1923 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
1924 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
1925 if (DatabaseRecord->Handle == PackageList) {\r
1926 PackageListNode = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (DatabaseRecord->PackageList);\r
813acf3a 1927 break;\r
1928 }\r
1929 }\r
1930 if (PackageListNode == NULL) {\r
1931 return EFI_NOT_FOUND;\r
1932 }\r
1933 \r
1934 Languages = NULL;\r
1935 ResultSize = 0;\r
1936 for (Link1 = PackageListNode->StringPkgHdr.ForwardLink;\r
1937 Link1 != &PackageListNode->StringPkgHdr;\r
1938 Link1 = Link1->ForwardLink\r
1939 ) {\r
1940 StringPackage = CR (Link1, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
4f077902 1941 if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) PrimaryLanguage)) {\r
813acf3a 1942 Languages = StringPackage->StringPkgHdr->Language;\r
1943 //\r
1944 // Language is a series of ';' terminated strings, first one is primary\r
1945 // language and following with other secondary languages or NULL if no\r
1946 // secondary languages any more.\r
1947 //\r
1948 Languages = AsciiStrStr (Languages, ";");\r
1949 if (Languages == NULL) {\r
1950 break;\r
1951 }\r
1952 Languages++;\r
93e3992d 1953\r
813acf3a 1954 ResultSize = AsciiStrSize (Languages);\r
e90b081a 1955 if (ResultSize <= *SecondaryLanguagesSize) {\r
1956 AsciiStrCpy (SecondaryLanguages, Languages);\r
813acf3a 1957 } else {\r
e90b081a 1958 *SecondaryLanguagesSize = ResultSize;\r
813acf3a 1959 return EFI_BUFFER_TOO_SMALL;\r
93e3992d 1960 }\r
813acf3a 1961\r
1962 return EFI_SUCCESS;\r
93e3992d 1963 }\r
1964 }\r
1965\r
813acf3a 1966 return EFI_INVALID_LANGUAGE;\r
93e3992d 1967}\r
1968\r
269218a3
ED
1969/**\r
1970 Converts the ascii character of the string from uppercase to lowercase.\r
1971 This is a internal function.\r
1972\r
1973 @param ConfigString String to be converted\r
1974\r
1975**/\r
1976VOID\r
1977EFIAPI\r
1978AsciiHiiToLower (\r
1979 IN CHAR8 *ConfigString\r
1980 )\r
1981{\r
269218a3
ED
1982 ASSERT (ConfigString != NULL);\r
1983\r
1984 //\r
1985 // Convert all hex digits in range [A-F] in the configuration header to [a-f]\r
1986 //\r
90f6df07
ED
1987 for (; *ConfigString != '\0'; ConfigString++) {\r
1988 if ( *ConfigString >= 'A' && *ConfigString <= 'Z') {\r
1989 *ConfigString = (CHAR8) (*ConfigString - 'A' + 'a');\r
269218a3
ED
1990 }\r
1991 }\r
269218a3
ED
1992}\r
1993\r
f324bf4d 1994/**\r
1995 Compare whether two names of languages are identical.\r
1996\r
b0bdc7ba
LG
1997 @param Language1 Name of language 1 from StringPackage\r
1998 @param Language2 Name of language 2 to be compared with language 1.\r
f324bf4d 1999\r
2000 @retval TRUE same\r
2001 @retval FALSE not same\r
2002\r
2003**/\r
2004BOOLEAN\r
2005HiiCompareLanguage (\r
2006 IN CHAR8 *Language1,\r
2007 IN CHAR8 *Language2\r
2008 )\r
2009{\r
4a12dfd4 2010 UINTN Index;\r
269218a3
ED
2011 UINTN StrLen;\r
2012 CHAR8 *Lan1;\r
2013 CHAR8 *Lan2;\r
2014\r
2015 //\r
2016 // Convert to lower to compare.\r
2017 //\r
2018 StrLen = AsciiStrSize (Language1);\r
2019 Lan1 = AllocateZeroPool (StrLen);\r
90f6df07 2020 ASSERT (Lan1 != NULL);\r
269218a3
ED
2021 AsciiStrCpy(Lan1, Language1);\r
2022 AsciiHiiToLower (Lan1);\r
2023\r
2024 StrLen = AsciiStrSize (Language2);\r
2025 Lan2 = AllocateZeroPool (StrLen);\r
90f6df07 2026 ASSERT (Lan2 != NULL);\r
269218a3
ED
2027 AsciiStrCpy(Lan2, Language2);\r
2028 AsciiHiiToLower (Lan2);\r
4a12dfd4
ED
2029\r
2030 //\r
2031 // Compare the Primary Language in Language1 to Language2\r
2032 //\r
269218a3
ED
2033 for (Index = 0; Lan1[Index] != 0 && Lan1[Index] != ';'; Index++) {\r
2034 if (Lan1[Index] != Lan2[Index]) {\r
4a12dfd4
ED
2035 //\r
2036 // Return FALSE if any characters are different.\r
2037 //\r
7c9fbd79
ED
2038 FreePool (Lan1);\r
2039 FreePool (Lan2);\r
4a12dfd4
ED
2040 return FALSE;\r
2041 }\r
2042 }\r
f324bf4d 2043\r
269218a3
ED
2044 FreePool (Lan1);\r
2045 FreePool (Lan2);\r
2046\r
b0bdc7ba 2047 //\r
4a12dfd4
ED
2048 // Only return TRUE if Language2[Index] is a Null-terminator which means\r
2049 // the Primary Language in Language1 is the same length as Language2. If\r
2050 // Language2[Index] is not a Null-terminator, then Language2 is longer than\r
2051 // the Primary Language in Language1, and FALSE must be returned.\r
b0bdc7ba 2052 //\r
dc76cddc 2053 return (BOOLEAN) (Language2[Index] == 0);\r
f324bf4d 2054}\r