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