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