1 /** @file 2 Implementation for EFI_HII_DATABASE_PROTOCOL. 3 4 Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 16 #include "HiiDatabase.h" 17 18 /** 19 This function generates a HII_DATABASE_RECORD node and adds into hii database. 20 This is a internal function. 21 22 @param Private hii database private structure 23 @param DatabaseNode HII_DATABASE_RECORD node which is used to store a 24 package list 25 26 @retval EFI_SUCCESS A database record is generated successfully. 27 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new 28 database contents. 29 @retval EFI_INVALID_PARAMETER Private is NULL or DatabaseRecord is NULL. 30 31 **/ 32 EFI_STATUS 33 GenerateHiiDatabaseRecord ( 34 IN HII_DATABASE_PRIVATE_DATA *Private, 35 OUT HII_DATABASE_RECORD **DatabaseNode 36 ) 37 { 38 HII_DATABASE_RECORD *DatabaseRecord; 39 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList; 40 HII_HANDLE *HiiHandle; 41 42 if (Private == NULL || DatabaseNode == NULL) { 43 return EFI_INVALID_PARAMETER; 44 } 45 46 DatabaseRecord = (HII_DATABASE_RECORD *) AllocateZeroPool (sizeof (HII_DATABASE_RECORD)); 47 if (DatabaseRecord == NULL) { 48 return EFI_OUT_OF_RESOURCES; 49 } 50 DatabaseRecord->Signature = HII_DATABASE_RECORD_SIGNATURE; 51 52 DatabaseRecord->PackageList = AllocateZeroPool (sizeof (HII_DATABASE_PACKAGE_LIST_INSTANCE)); 53 if (DatabaseRecord->PackageList == NULL) { 54 FreePool (DatabaseRecord); 55 return EFI_OUT_OF_RESOURCES; 56 } 57 58 PackageList = DatabaseRecord->PackageList; 59 60 InitializeListHead (&PackageList->GuidPkgHdr); 61 InitializeListHead (&PackageList->FormPkgHdr); 62 InitializeListHead (&PackageList->KeyboardLayoutHdr); 63 InitializeListHead (&PackageList->StringPkgHdr); 64 InitializeListHead (&PackageList->FontPkgHdr); 65 InitializeListHead (&PackageList->SimpleFontPkgHdr); 66 PackageList->ImagePkg = NULL; 67 PackageList->DevicePathPkg = NULL; 68 69 // 70 // Create a new hii handle 71 // 72 HiiHandle = (HII_HANDLE *) AllocateZeroPool (sizeof (HII_HANDLE)); 73 if (HiiHandle == NULL) { 74 FreePool (DatabaseRecord->PackageList); 75 FreePool (DatabaseRecord); 76 return EFI_OUT_OF_RESOURCES; 77 } 78 HiiHandle->Signature = HII_HANDLE_SIGNATURE; 79 // 80 // Backup the number of Hii handles 81 // 82 Private->HiiHandleCount++; 83 HiiHandle->Key = (UINTN) Private->HiiHandleCount; 84 // 85 // Insert the handle to hii handle list of the whole database. 86 // 87 InsertTailList (&Private->HiiHandleList, &HiiHandle->Handle); 88 89 DatabaseRecord->Handle = (EFI_HII_HANDLE) HiiHandle; 90 91 // 92 // Insert the Package List node to Package List link of the whole database. 93 // 94 InsertTailList (&Private->DatabaseList, &DatabaseRecord->DatabaseEntry); 95 96 *DatabaseNode = DatabaseRecord; 97 98 return EFI_SUCCESS; 99 100 } 101 102 103 /** 104 This function checks whether a handle is a valid EFI_HII_HANDLE 105 This is a internal function. 106 107 @param Handle Pointer to a EFI_HII_HANDLE 108 109 @retval TRUE Valid 110 @retval FALSE Invalid 111 112 **/ 113 BOOLEAN 114 IsHiiHandleValid ( 115 EFI_HII_HANDLE Handle 116 ) 117 { 118 HII_HANDLE *HiiHandle; 119 120 HiiHandle = (HII_HANDLE *) Handle; 121 122 if (HiiHandle == NULL) { 123 return FALSE; 124 } 125 126 if (HiiHandle->Signature != HII_HANDLE_SIGNATURE) { 127 return FALSE; 128 } 129 130 return TRUE; 131 } 132 133 134 /** 135 This function invokes the matching registered function. 136 This is a internal function. 137 138 @param Private HII Database driver private structure. 139 @param NotifyType The type of change concerning the database. 140 @param PackageInstance Points to the package referred to by the 141 notification. 142 @param PackageType Package type 143 @param Handle The handle of the package list which contains the 144 specified package. 145 146 @retval EFI_SUCCESS Already checked all registered function and 147 invoked if matched. 148 @retval EFI_INVALID_PARAMETER Any input parameter is not valid. 149 150 **/ 151 EFI_STATUS 152 InvokeRegisteredFunction ( 153 IN HII_DATABASE_PRIVATE_DATA *Private, 154 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, 155 IN VOID *PackageInstance, 156 IN UINT8 PackageType, 157 IN EFI_HII_HANDLE Handle 158 ) 159 { 160 HII_DATABASE_NOTIFY *Notify; 161 LIST_ENTRY *Link; 162 EFI_HII_PACKAGE_HEADER *Package; 163 UINT8 *Buffer; 164 UINT32 BufferSize; 165 UINT32 HeaderSize; 166 UINT32 ImageBlockSize; 167 UINT32 PaletteInfoSize; 168 169 if (Private == NULL || (NotifyType & 0xF) == 0 || PackageInstance == NULL) { 170 return EFI_INVALID_PARAMETER; 171 } 172 if (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) { 173 return EFI_INVALID_PARAMETER; 174 } 175 if (!IsHiiHandleValid (Handle)) { 176 return EFI_INVALID_PARAMETER; 177 } 178 179 Buffer = NULL; 180 Package = NULL; 181 182 // 183 // Convert the incoming package from hii database storage format to UEFI 184 // storage format. e.g. HII_GUID_PACKAGE_INSTANCE to EFI_HII_GUID_PACKAGE_HDR. 185 // 186 switch (PackageType) { 187 case EFI_HII_PACKAGE_TYPE_GUID: 188 Package = (EFI_HII_PACKAGE_HEADER *) (((HII_GUID_PACKAGE_INSTANCE *) PackageInstance)->GuidPkg); 189 break; 190 191 case EFI_HII_PACKAGE_FORMS: 192 BufferSize = ((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->FormPkgHdr.Length; 193 Buffer = (UINT8 *) AllocateZeroPool (BufferSize); 194 ASSERT (Buffer != NULL); 195 CopyMem ( 196 Buffer, 197 &((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->FormPkgHdr, 198 sizeof (EFI_HII_PACKAGE_HEADER) 199 ); 200 CopyMem ( 201 Buffer + sizeof (EFI_HII_PACKAGE_HEADER), 202 ((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->IfrData, 203 BufferSize - sizeof (EFI_HII_PACKAGE_HEADER) 204 ); 205 Package = (EFI_HII_PACKAGE_HEADER *) Buffer; 206 break; 207 208 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT: 209 Package = (EFI_HII_PACKAGE_HEADER *) (((HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *) PackageInstance)->KeyboardPkg); 210 break; 211 212 case EFI_HII_PACKAGE_STRINGS: 213 BufferSize = ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr->Header.Length; 214 HeaderSize = ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr->HdrSize; 215 Buffer = (UINT8 *) AllocateZeroPool (BufferSize); 216 ASSERT (Buffer != NULL); 217 CopyMem ( 218 Buffer, 219 ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr, 220 HeaderSize 221 ); 222 CopyMem ( 223 Buffer + HeaderSize, 224 ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringBlock, 225 BufferSize - HeaderSize 226 ); 227 Package = (EFI_HII_PACKAGE_HEADER *) Buffer; 228 break; 229 230 case EFI_HII_PACKAGE_FONTS: 231 BufferSize = ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr->Header.Length; 232 HeaderSize = ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr->HdrSize; 233 Buffer = (UINT8 *) AllocateZeroPool (BufferSize); 234 ASSERT (Buffer != NULL); 235 CopyMem ( 236 Buffer, 237 ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr, 238 HeaderSize 239 ); 240 CopyMem ( 241 Buffer + HeaderSize, 242 ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->GlyphBlock, 243 BufferSize - HeaderSize 244 ); 245 Package = (EFI_HII_PACKAGE_HEADER *) Buffer; 246 break; 247 248 case EFI_HII_PACKAGE_IMAGES: 249 BufferSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImagePkgHdr.Header.Length; 250 HeaderSize = sizeof (EFI_HII_IMAGE_PACKAGE_HDR); 251 Buffer = (UINT8 *) AllocateZeroPool (BufferSize); 252 ASSERT (Buffer != NULL); 253 254 CopyMem ( 255 Buffer, 256 &((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImagePkgHdr, 257 HeaderSize 258 ); 259 CopyMem ( 260 Buffer + sizeof (EFI_HII_PACKAGE_HEADER), 261 &HeaderSize, 262 sizeof (UINT32) 263 ); 264 265 ImageBlockSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImageBlockSize; 266 if (ImageBlockSize != 0) { 267 CopyMem ( 268 Buffer + HeaderSize, 269 ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImageBlock, 270 ImageBlockSize 271 ); 272 } 273 274 PaletteInfoSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->PaletteInfoSize; 275 if (PaletteInfoSize != 0) { 276 CopyMem ( 277 Buffer + HeaderSize + ImageBlockSize, 278 ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->PaletteBlock, 279 PaletteInfoSize 280 ); 281 HeaderSize += ImageBlockSize; 282 CopyMem ( 283 Buffer + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT32), 284 &HeaderSize, 285 sizeof (UINT32) 286 ); 287 } 288 Package = (EFI_HII_PACKAGE_HEADER *) Buffer; 289 break; 290 291 case EFI_HII_PACKAGE_SIMPLE_FONTS: 292 BufferSize = ((HII_SIMPLE_FONT_PACKAGE_INSTANCE *) PackageInstance)->SimpleFontPkgHdr->Header.Length; 293 Buffer = (UINT8 *) AllocateZeroPool (BufferSize); 294 ASSERT (Buffer != NULL); 295 CopyMem ( 296 Buffer, 297 ((HII_SIMPLE_FONT_PACKAGE_INSTANCE *) PackageInstance)->SimpleFontPkgHdr, 298 BufferSize 299 ); 300 Package = (EFI_HII_PACKAGE_HEADER *) Buffer; 301 break; 302 303 case EFI_HII_PACKAGE_DEVICE_PATH: 304 Package = (EFI_HII_PACKAGE_HEADER *) PackageInstance; 305 break; 306 307 default: 308 return EFI_INVALID_PARAMETER; 309 } 310 311 for (Link = Private->DatabaseNotifyList.ForwardLink; 312 Link != &Private->DatabaseNotifyList; 313 Link = Link->ForwardLink 314 ) { 315 Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE); 316 if (Notify->NotifyType == NotifyType && Notify->PackageType == PackageType) { 317 // 318 // Check in case PackageGuid is not NULL when Package is GUID package 319 // 320 if (PackageType != EFI_HII_PACKAGE_TYPE_GUID) { 321 Notify->PackageGuid = NULL; 322 } 323 // 324 // Status of Registered Function is unknown so did not check it 325 // 326 Notify->PackageNotifyFn ( 327 Notify->PackageType, 328 Notify->PackageGuid, 329 Package, 330 Handle, 331 NotifyType 332 ); 333 } 334 } 335 336 if (Buffer != NULL) { 337 FreePool (Buffer); 338 } 339 340 return EFI_SUCCESS; 341 } 342 343 344 /** 345 This function insert a GUID package to a package list node. 346 This is a internal function. 347 348 @param PackageHdr Pointer to a buffer stored with GUID package 349 information. 350 @param NotifyType The type of change concerning the database. 351 @param PackageList Pointer to a package list which will be inserted 352 to. 353 @param Package Created GUID pacakge 354 355 @retval EFI_SUCCESS Guid Package is inserted successfully. 356 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new 357 Guid package. 358 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL. 359 360 **/ 361 EFI_STATUS 362 InsertGuidPackage ( 363 IN VOID *PackageHdr, 364 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, 365 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, 366 OUT HII_GUID_PACKAGE_INSTANCE **Package 367 ) 368 { 369 HII_GUID_PACKAGE_INSTANCE *GuidPackage; 370 EFI_HII_PACKAGE_HEADER PackageHeader; 371 372 if (PackageHdr == NULL || PackageList == NULL) { 373 return EFI_INVALID_PARAMETER; 374 } 375 376 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER)); 377 378 // 379 // Create a GUID package node 380 // 381 GuidPackage = (HII_GUID_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_GUID_PACKAGE_INSTANCE)); 382 if (GuidPackage == NULL) { 383 return EFI_OUT_OF_RESOURCES; 384 } 385 GuidPackage->GuidPkg = (UINT8 *) AllocateZeroPool (PackageHeader.Length); 386 if (GuidPackage->GuidPkg == NULL) { 387 FreePool (GuidPackage); 388 return EFI_OUT_OF_RESOURCES; 389 } 390 391 GuidPackage->Signature = HII_GUID_PACKAGE_SIGNATURE; 392 CopyMem (GuidPackage->GuidPkg, PackageHdr, PackageHeader.Length); 393 InsertTailList (&PackageList->GuidPkgHdr, &GuidPackage->GuidEntry); 394 *Package = GuidPackage; 395 396 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) { 397 PackageList->PackageListHdr.PackageLength += PackageHeader.Length; 398 } 399 400 return EFI_SUCCESS; 401 } 402 403 404 /** 405 This function exports GUID packages to a buffer. 406 This is a internal function. 407 408 @param Private Hii database private structure. 409 @param Handle Identification of a package list. 410 @param PackageList Pointer to a package list which will be exported. 411 @param UsedSize The length of buffer be used. 412 @param BufferSize Length of the Buffer. 413 @param Buffer Allocated space for storing exported data. 414 @param ResultSize The size of the already exported content of this 415 package list. 416 417 @retval EFI_SUCCESS Guid Packages are exported successfully. 418 @retval EFI_INVALID_PARAMETER Any input parameter is invalid. 419 420 **/ 421 EFI_STATUS 422 ExportGuidPackages ( 423 IN HII_DATABASE_PRIVATE_DATA *Private, 424 IN EFI_HII_HANDLE Handle, 425 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, 426 IN UINTN UsedSize, 427 IN UINTN BufferSize, 428 IN OUT VOID *Buffer, 429 IN OUT UINTN *ResultSize 430 ) 431 { 432 HII_GUID_PACKAGE_INSTANCE *GuidPackage; 433 LIST_ENTRY *Link; 434 UINTN PackageLength; 435 EFI_HII_PACKAGE_HEADER PackageHeader; 436 EFI_STATUS Status; 437 438 if (PackageList == NULL || ResultSize == NULL) { 439 return EFI_INVALID_PARAMETER; 440 } 441 442 if (BufferSize > 0 && Buffer == NULL ) { 443 return EFI_INVALID_PARAMETER; 444 } 445 446 PackageLength = 0; 447 Status = EFI_SUCCESS; 448 449 for (Link = PackageList->GuidPkgHdr.ForwardLink; Link != &PackageList->GuidPkgHdr; Link = Link->ForwardLink) { 450 GuidPackage = CR (Link, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE); 451 CopyMem (&PackageHeader, GuidPackage->GuidPkg, sizeof (EFI_HII_PACKAGE_HEADER)); 452 PackageLength += PackageHeader.Length; 453 if (PackageLength + *ResultSize + UsedSize <= BufferSize) { 454 Status = InvokeRegisteredFunction ( 455 Private, 456 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK, 457 (VOID *) GuidPackage, 458 EFI_HII_PACKAGE_TYPE_GUID, 459 Handle 460 ); 461 ASSERT_EFI_ERROR (Status); 462 CopyMem (Buffer, GuidPackage->GuidPkg, PackageHeader.Length); 463 Buffer = (UINT8 *) Buffer + PackageHeader.Length; 464 } 465 } 466 467 *ResultSize += PackageLength; 468 return EFI_SUCCESS; 469 } 470 471 472 /** 473 This function deletes all GUID packages from a package list node. 474 This is a internal function. 475 476 @param Private Hii database private data. 477 @param Handle Handle of the package list which contains the to 478 be removed GUID packages. 479 @param PackageList Pointer to a package list that contains removing 480 packages. 481 482 @retval EFI_SUCCESS GUID Package(s) is deleted successfully. 483 @retval EFI_INVALID_PARAMETER Any input parameter is not valid. 484 485 **/ 486 EFI_STATUS 487 RemoveGuidPackages ( 488 IN HII_DATABASE_PRIVATE_DATA *Private, 489 IN EFI_HII_HANDLE Handle, 490 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList 491 ) 492 { 493 LIST_ENTRY *ListHead; 494 HII_GUID_PACKAGE_INSTANCE *Package; 495 EFI_STATUS Status; 496 EFI_HII_PACKAGE_HEADER PackageHeader; 497 498 ListHead = &PackageList->GuidPkgHdr; 499 500 while (!IsListEmpty (ListHead)) { 501 Package = CR ( 502 ListHead->ForwardLink, 503 HII_GUID_PACKAGE_INSTANCE, 504 GuidEntry, 505 HII_GUID_PACKAGE_SIGNATURE 506 ); 507 Status = InvokeRegisteredFunction ( 508 Private, 509 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK, 510 (VOID *) Package, 511 EFI_HII_PACKAGE_TYPE_GUID, 512 Handle 513 ); 514 if (EFI_ERROR (Status)) { 515 return Status; 516 } 517 518 RemoveEntryList (&Package->GuidEntry); 519 CopyMem (&PackageHeader, Package->GuidPkg, sizeof (EFI_HII_PACKAGE_HEADER)); 520 PackageList->PackageListHdr.PackageLength -= PackageHeader.Length; 521 FreePool (Package->GuidPkg); 522 FreePool (Package); 523 } 524 525 return EFI_SUCCESS; 526 } 527 528 529 /** 530 This function insert a Form package to a package list node. 531 This is a internal function. 532 533 @param PackageHdr Pointer to a buffer stored with Form package 534 information. 535 @param NotifyType The type of change concerning the database. 536 @param PackageList Pointer to a package list which will be inserted 537 to. 538 @param Package Created Form package 539 540 @retval EFI_SUCCESS Form Package is inserted successfully. 541 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new 542 Form package. 543 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL. 544 545 **/ 546 EFI_STATUS 547 InsertFormPackage ( 548 IN VOID *PackageHdr, 549 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, 550 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, 551 OUT HII_IFR_PACKAGE_INSTANCE **Package 552 ) 553 { 554 HII_IFR_PACKAGE_INSTANCE *FormPackage; 555 EFI_HII_PACKAGE_HEADER PackageHeader; 556 557 if (PackageHdr == NULL || PackageList == NULL) { 558 return EFI_INVALID_PARAMETER; 559 } 560 561 // 562 // Get the length of the package, including package header itself 563 // 564 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER)); 565 566 // 567 // Create a Form package node 568 // 569 FormPackage = (HII_IFR_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_IFR_PACKAGE_INSTANCE)); 570 if (FormPackage == NULL) { 571 return EFI_OUT_OF_RESOURCES; 572 } 573 574 FormPackage->IfrData = (UINT8 *) AllocateZeroPool (PackageHeader.Length - sizeof (EFI_HII_PACKAGE_HEADER)); 575 if (FormPackage->IfrData == NULL) { 576 FreePool (FormPackage); 577 return EFI_OUT_OF_RESOURCES; 578 } 579 580 FormPackage->Signature = HII_IFR_PACKAGE_SIGNATURE; 581 // 582 // Copy Package Header 583 // 584 CopyMem (&FormPackage->FormPkgHdr, &PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER)); 585 586 // 587 // Copy Ifr contents 588 // 589 CopyMem ( 590 FormPackage->IfrData, 591 (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER), 592 PackageHeader.Length - sizeof (EFI_HII_PACKAGE_HEADER) 593 ); 594 595 InsertTailList (&PackageList->FormPkgHdr, &FormPackage->IfrEntry); 596 *Package = FormPackage; 597 598 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) { 599 PackageList->PackageListHdr.PackageLength += FormPackage->FormPkgHdr.Length; 600 } 601 return EFI_SUCCESS; 602 } 603 604 605 /** 606 This function exports Form packages to a buffer. 607 This is a internal function. 608 609 @param Private Hii database private structure. 610 @param Handle Identification of a package list. 611 @param PackageList Pointer to a package list which will be exported. 612 @param UsedSize The length of buffer be used. 613 @param BufferSize Length of the Buffer. 614 @param Buffer Allocated space for storing exported data. 615 @param ResultSize The size of the already exported content of this 616 package list. 617 618 @retval EFI_SUCCESS Form Packages are exported successfully. 619 @retval EFI_INVALID_PARAMETER Any input parameter is invalid. 620 621 **/ 622 EFI_STATUS 623 ExportFormPackages ( 624 IN HII_DATABASE_PRIVATE_DATA *Private, 625 IN EFI_HII_HANDLE Handle, 626 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, 627 IN UINTN UsedSize, 628 IN UINTN BufferSize, 629 IN OUT VOID *Buffer, 630 IN OUT UINTN *ResultSize 631 ) 632 { 633 HII_IFR_PACKAGE_INSTANCE *FormPackage; 634 UINTN PackageLength; 635 LIST_ENTRY *Link; 636 EFI_STATUS Status; 637 638 if (Private == NULL || PackageList == NULL || ResultSize == NULL) { 639 return EFI_INVALID_PARAMETER; 640 } 641 642 if (BufferSize > 0 && Buffer == NULL ) { 643 return EFI_INVALID_PARAMETER; 644 } 645 646 PackageLength = 0; 647 Status = EFI_SUCCESS; 648 649 // 650 // Export Form packages. 651 // 652 for (Link = PackageList->FormPkgHdr.ForwardLink; Link != &PackageList->FormPkgHdr; Link = Link->ForwardLink) { 653 FormPackage = CR (Link, HII_IFR_PACKAGE_INSTANCE, IfrEntry, HII_IFR_PACKAGE_SIGNATURE); 654 PackageLength += FormPackage->FormPkgHdr.Length; 655 if ((Buffer != NULL) && (PackageLength + *ResultSize + UsedSize <= BufferSize)) { 656 // 657 // Invoke registered notification if exists 658 // 659 Status = InvokeRegisteredFunction ( 660 Private, 661 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK, 662 (VOID *) FormPackage, 663 EFI_HII_PACKAGE_FORMS, 664 Handle 665 ); 666 ASSERT_EFI_ERROR (Status); 667 // 668 // Copy the Form package content. 669 // 670 CopyMem (Buffer, (VOID *) (&FormPackage->FormPkgHdr), sizeof (EFI_HII_PACKAGE_HEADER)); 671 Buffer = (UINT8 *) Buffer + sizeof (EFI_HII_PACKAGE_HEADER); 672 CopyMem ( 673 Buffer, 674 (VOID *) FormPackage->IfrData, 675 FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER) 676 ); 677 Buffer = (UINT8 *) Buffer + FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER); 678 } 679 } 680 681 *ResultSize += PackageLength; 682 683 return EFI_SUCCESS; 684 685 } 686 687 688 /** 689 This function deletes all Form packages from a package list node. 690 This is a internal function. 691 692 @param Private Hii database private data. 693 @param Handle Handle of the package list which contains the to 694 be removed Form packages. 695 @param PackageList Pointer to a package list that contains removing 696 packages. 697 698 @retval EFI_SUCCESS Form Package(s) is deleted successfully. 699 @retval EFI_INVALID_PARAMETER Any input parameter is not valid. 700 701 **/ 702 EFI_STATUS 703 RemoveFormPackages ( 704 IN HII_DATABASE_PRIVATE_DATA *Private, 705 IN EFI_HII_HANDLE Handle, 706 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList 707 ) 708 { 709 LIST_ENTRY *ListHead; 710 HII_IFR_PACKAGE_INSTANCE *Package; 711 EFI_STATUS Status; 712 713 ListHead = &PackageList->FormPkgHdr; 714 715 while (!IsListEmpty (ListHead)) { 716 Package = CR ( 717 ListHead->ForwardLink, 718 HII_IFR_PACKAGE_INSTANCE, 719 IfrEntry, 720 HII_IFR_PACKAGE_SIGNATURE 721 ); 722 Status = InvokeRegisteredFunction ( 723 Private, 724 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK, 725 (VOID *) Package, 726 EFI_HII_PACKAGE_FORMS, 727 Handle 728 ); 729 if (EFI_ERROR (Status)) { 730 return Status; 731 } 732 733 RemoveEntryList (&Package->IfrEntry); 734 PackageList->PackageListHdr.PackageLength -= Package->FormPkgHdr.Length; 735 FreePool (Package->IfrData); 736 FreePool (Package); 737 738 } 739 740 return EFI_SUCCESS; 741 } 742 743 744 745 /** 746 This function insert a String package to a package list node. 747 This is a internal function. 748 749 @param Private Hii database private structure. 750 @param PackageHdr Pointer to a buffer stored with String package 751 information. 752 @param NotifyType The type of change concerning the database. 753 @param PackageList Pointer to a package list which will be inserted 754 to. 755 @param Package Created String package 756 757 @retval EFI_SUCCESS String Package is inserted successfully. 758 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new 759 String package. 760 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL. 761 @retval EFI_UNSUPPORTED A string package with the same language already 762 exists in current package list. 763 764 **/ 765 EFI_STATUS 766 InsertStringPackage ( 767 IN HII_DATABASE_PRIVATE_DATA *Private, 768 IN VOID *PackageHdr, 769 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, 770 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, 771 OUT HII_STRING_PACKAGE_INSTANCE **Package 772 ) 773 { 774 HII_STRING_PACKAGE_INSTANCE *StringPackage; 775 UINT32 HeaderSize; 776 EFI_STATUS Status; 777 EFI_HII_PACKAGE_HEADER PackageHeader; 778 CHAR8 *Language; 779 UINT32 LanguageSize; 780 LIST_ENTRY *Link; 781 782 if (Private == NULL || PackageHdr == NULL || PackageList == NULL) { 783 return EFI_INVALID_PARAMETER; 784 } 785 if (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) { 786 return EFI_INVALID_PARAMETER; 787 } 788 789 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER)); 790 CopyMem (&HeaderSize, (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER), sizeof (UINT32)); 791 792 // 793 // It is illegal to have two string packages with same language within one packagelist 794 // since the stringid will be duplicate if so. Check it to avoid this potential issue. 795 // 796 LanguageSize = HeaderSize - sizeof (EFI_HII_STRING_PACKAGE_HDR) + sizeof (CHAR8); 797 Language = (CHAR8 *) AllocateZeroPool (LanguageSize); 798 if (Language == NULL) { 799 return EFI_OUT_OF_RESOURCES; 800 } 801 AsciiStrCpyS (Language, LanguageSize / sizeof (CHAR8), (CHAR8 *) PackageHdr + HeaderSize - LanguageSize); 802 for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) { 803 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE); 804 if (HiiCompareLanguage (Language, StringPackage->StringPkgHdr->Language)) { 805 FreePool (Language); 806 return EFI_UNSUPPORTED; 807 } 808 } 809 FreePool (Language); 810 811 // 812 // Create a String package node 813 // 814 StringPackage = (HII_STRING_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE)); 815 if (StringPackage == NULL) { 816 Status = EFI_OUT_OF_RESOURCES; 817 goto Error; 818 } 819 820 StringPackage->StringPkgHdr = (EFI_HII_STRING_PACKAGE_HDR *) AllocateZeroPool (HeaderSize); 821 if (StringPackage->StringPkgHdr == NULL) { 822 Status = EFI_OUT_OF_RESOURCES; 823 goto Error; 824 } 825 826 StringPackage->StringBlock = (UINT8 *) AllocateZeroPool (PackageHeader.Length - HeaderSize); 827 if (StringPackage->StringBlock == NULL) { 828 Status = EFI_OUT_OF_RESOURCES; 829 goto Error; 830 } 831 832 StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE; 833 StringPackage->FontId = 0; 834 InitializeListHead (&StringPackage->FontInfoList); 835 836 // 837 // Copy the String package header. 838 // 839 CopyMem (StringPackage->StringPkgHdr, PackageHdr, HeaderSize); 840 841 // 842 // Copy the String blocks 843 // 844 CopyMem ( 845 StringPackage->StringBlock, 846 (UINT8 *) PackageHdr + HeaderSize, 847 PackageHeader.Length - HeaderSize 848 ); 849 850 // 851 // Collect all font block info 852 // 853 Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID) (-1), NULL, NULL, NULL, &StringPackage->MaxStringId, NULL); 854 if (EFI_ERROR (Status)) { 855 return Status; 856 } 857 858 // 859 // Insert to String package array 860 // 861 InsertTailList (&PackageList->StringPkgHdr, &StringPackage->StringEntry); 862 *Package = StringPackage; 863 864 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) { 865 PackageList->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length; 866 } 867 868 return EFI_SUCCESS; 869 870 Error: 871 872 if (StringPackage != NULL) { 873 if (StringPackage->StringBlock != NULL) { 874 FreePool (StringPackage->StringBlock); 875 } 876 if (StringPackage->StringPkgHdr != NULL) { 877 FreePool (StringPackage->StringPkgHdr); 878 } 879 FreePool (StringPackage); 880 } 881 return Status; 882 883 } 884 885 /** 886 Adjust all string packages in a single package list to have the same max string ID. 887 888 @param PackageList Pointer to a package list which will be adjusted. 889 890 @retval EFI_SUCCESS Adjust all string packages successfully. 891 @retval others Can't adjust string packges. 892 893 **/ 894 EFI_STATUS 895 AdjustStringPackage ( 896 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList 897 ) 898 { 899 LIST_ENTRY *Link; 900 HII_STRING_PACKAGE_INSTANCE *StringPackage; 901 UINT32 Skip2BlockSize; 902 UINT32 OldBlockSize; 903 UINT8 *StringBlock; 904 UINT8 *BlockPtr; 905 EFI_STRING_ID MaxStringId; 906 UINT16 SkipCount; 907 908 MaxStringId = 0; 909 for (Link = PackageList->StringPkgHdr.ForwardLink; 910 Link != &PackageList->StringPkgHdr; 911 Link = Link->ForwardLink 912 ) { 913 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE); 914 if (MaxStringId < StringPackage->MaxStringId) { 915 MaxStringId = StringPackage->MaxStringId; 916 } 917 } 918 919 for (Link = PackageList->StringPkgHdr.ForwardLink; 920 Link != &PackageList->StringPkgHdr; 921 Link = Link->ForwardLink 922 ) { 923 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE); 924 if (StringPackage->MaxStringId < MaxStringId) { 925 OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize; 926 // 927 // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCKs to reserve the missing string IDs. 928 // 929 SkipCount = (UINT16) (MaxStringId - StringPackage->MaxStringId); 930 Skip2BlockSize = (UINT32) sizeof (EFI_HII_SIBT_SKIP2_BLOCK); 931 932 StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Skip2BlockSize); 933 if (StringBlock == NULL) { 934 return EFI_OUT_OF_RESOURCES; 935 } 936 // 937 // Copy original string blocks, except the EFI_HII_SIBT_END. 938 // 939 CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK)); 940 // 941 // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCK blocks 942 // 943 BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK); 944 *BlockPtr = EFI_HII_SIBT_SKIP2; 945 CopyMem (BlockPtr + 1, &SkipCount, sizeof (UINT16)); 946 BlockPtr += sizeof (EFI_HII_SIBT_SKIP2_BLOCK); 947 948 // 949 // Append a EFI_HII_SIBT_END block to the end. 950 // 951 *BlockPtr = EFI_HII_SIBT_END; 952 FreePool (StringPackage->StringBlock); 953 StringPackage->StringBlock = StringBlock; 954 StringPackage->StringPkgHdr->Header.Length += Skip2BlockSize; 955 PackageList->PackageListHdr.PackageLength += Skip2BlockSize; 956 StringPackage->MaxStringId = MaxStringId; 957 } 958 } 959 960 return EFI_SUCCESS; 961 } 962 963 /** 964 This function exports String packages to a buffer. 965 This is a internal function. 966 967 @param Private Hii database private structure. 968 @param Handle Identification of a package list. 969 @param PackageList Pointer to a package list which will be exported. 970 @param UsedSize The length of buffer be used. 971 @param BufferSize Length of the Buffer. 972 @param Buffer Allocated space for storing exported data. 973 @param ResultSize The size of the already exported content of this 974 package list. 975 976 @retval EFI_SUCCESS String Packages are exported successfully. 977 @retval EFI_INVALID_PARAMETER Any input parameter is invalid. 978 979 **/ 980 EFI_STATUS 981 ExportStringPackages ( 982 IN HII_DATABASE_PRIVATE_DATA *Private, 983 IN EFI_HII_HANDLE Handle, 984 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, 985 IN UINTN UsedSize, 986 IN UINTN BufferSize, 987 IN OUT VOID *Buffer, 988 IN OUT UINTN *ResultSize 989 ) 990 { 991 LIST_ENTRY *Link; 992 UINTN PackageLength; 993 EFI_STATUS Status; 994 HII_STRING_PACKAGE_INSTANCE *StringPackage; 995 996 if (Private == NULL || PackageList == NULL || ResultSize == NULL) { 997 return EFI_INVALID_PARAMETER; 998 } 999 1000 if (BufferSize > 0 && Buffer == NULL ) { 1001 return EFI_INVALID_PARAMETER; 1002 } 1003 1004 PackageLength = 0; 1005 Status = EFI_SUCCESS; 1006 1007 for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) { 1008 StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE); 1009 PackageLength += StringPackage->StringPkgHdr->Header.Length; 1010 if (PackageLength + *ResultSize + UsedSize <= BufferSize) { 1011 // 1012 // Invoke registered notification function with EXPORT_PACK notify type 1013 // 1014 Status = InvokeRegisteredFunction ( 1015 Private, 1016 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK, 1017 (VOID *) StringPackage, 1018 EFI_HII_PACKAGE_STRINGS, 1019 Handle 1020 ); 1021 ASSERT_EFI_ERROR (Status); 1022 // 1023 // Copy String package header 1024 // 1025 CopyMem (Buffer, StringPackage->StringPkgHdr, StringPackage->StringPkgHdr->HdrSize); 1026 Buffer = (UINT8 *) Buffer + StringPackage->StringPkgHdr->HdrSize; 1027 1028 // 1029 // Copy String blocks information 1030 // 1031 CopyMem ( 1032 Buffer, 1033 StringPackage->StringBlock, 1034 StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize 1035 ); 1036 Buffer = (UINT8 *) Buffer + StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize; 1037 } 1038 } 1039 1040 *ResultSize += PackageLength; 1041 return EFI_SUCCESS; 1042 } 1043 1044 1045 /** 1046 This function deletes all String packages from a package list node. 1047 This is a internal function. 1048 1049 @param Private Hii database private data. 1050 @param Handle Handle of the package list which contains the to 1051 be removed String packages. 1052 @param PackageList Pointer to a package list that contains removing 1053 packages. 1054 1055 @retval EFI_SUCCESS String Package(s) is deleted successfully. 1056 @retval EFI_INVALID_PARAMETER Any input parameter is not valid. 1057 1058 **/ 1059 EFI_STATUS 1060 RemoveStringPackages ( 1061 IN HII_DATABASE_PRIVATE_DATA *Private, 1062 IN EFI_HII_HANDLE Handle, 1063 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList 1064 ) 1065 { 1066 LIST_ENTRY *ListHead; 1067 HII_STRING_PACKAGE_INSTANCE *Package; 1068 HII_FONT_INFO *FontInfo; 1069 EFI_STATUS Status; 1070 1071 ListHead = &PackageList->StringPkgHdr; 1072 1073 while (!IsListEmpty (ListHead)) { 1074 Package = CR ( 1075 ListHead->ForwardLink, 1076 HII_STRING_PACKAGE_INSTANCE, 1077 StringEntry, 1078 HII_STRING_PACKAGE_SIGNATURE 1079 ); 1080 Status = InvokeRegisteredFunction ( 1081 Private, 1082 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK, 1083 (VOID *) Package, 1084 EFI_HII_PACKAGE_STRINGS, 1085 Handle 1086 ); 1087 if (EFI_ERROR (Status)) { 1088 return Status; 1089 } 1090 1091 RemoveEntryList (&Package->StringEntry); 1092 PackageList->PackageListHdr.PackageLength -= Package->StringPkgHdr->Header.Length; 1093 FreePool (Package->StringBlock); 1094 FreePool (Package->StringPkgHdr); 1095 // 1096 // Delete font information 1097 // 1098 while (!IsListEmpty (&Package->FontInfoList)) { 1099 FontInfo = CR ( 1100 Package->FontInfoList.ForwardLink, 1101 HII_FONT_INFO, 1102 Entry, 1103 HII_FONT_INFO_SIGNATURE 1104 ); 1105 RemoveEntryList (&FontInfo->Entry); 1106 FreePool (FontInfo); 1107 } 1108 1109 FreePool (Package); 1110 } 1111 1112 return EFI_SUCCESS; 1113 } 1114 1115 1116 /** 1117 This function insert a Font package to a package list node. 1118 This is a internal function. 1119 1120 @param Private Hii database private structure. 1121 @param PackageHdr Pointer to a buffer stored with Font package 1122 information. 1123 @param NotifyType The type of change concerning the database. 1124 @param PackageList Pointer to a package list which will be inserted 1125 to. 1126 @param Package Created Font package 1127 1128 @retval EFI_SUCCESS Font Package is inserted successfully. 1129 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new 1130 Font package. 1131 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL. 1132 @retval EFI_UNSUPPORTED A font package with same EFI_FONT_INFO already 1133 exists in current hii database. 1134 1135 **/ 1136 EFI_STATUS 1137 InsertFontPackage ( 1138 IN HII_DATABASE_PRIVATE_DATA *Private, 1139 IN VOID *PackageHdr, 1140 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, 1141 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, 1142 OUT HII_FONT_PACKAGE_INSTANCE **Package 1143 ) 1144 { 1145 HII_FONT_PACKAGE_INSTANCE *FontPackage; 1146 EFI_HII_FONT_PACKAGE_HDR *FontPkgHdr; 1147 UINT32 HeaderSize; 1148 EFI_STATUS Status; 1149 EFI_HII_PACKAGE_HEADER PackageHeader; 1150 EFI_FONT_INFO *FontInfo; 1151 UINT32 FontInfoSize; 1152 HII_GLOBAL_FONT_INFO *GlobalFont; 1153 1154 if (Private == NULL || PackageHdr == NULL || PackageList == NULL) { 1155 return EFI_INVALID_PARAMETER; 1156 } 1157 1158 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER)); 1159 CopyMem (&HeaderSize, (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER), sizeof (UINT32)); 1160 1161 FontInfo = NULL; 1162 FontPackage = NULL; 1163 GlobalFont = NULL; 1164 1165 // 1166 // It is illegal to have two font packages with same EFI_FONT_INFO within hii 1167 // database. EFI_FONT_INFO (FontName, FontSize, FontStyle) describes font's 1168 // attributes and identify a font uniquely. 1169 // 1170 FontPkgHdr = (EFI_HII_FONT_PACKAGE_HDR *) AllocateZeroPool (HeaderSize); 1171 if (FontPkgHdr == NULL) { 1172 Status = EFI_OUT_OF_RESOURCES; 1173 goto Error; 1174 } 1175 CopyMem (FontPkgHdr, PackageHdr, HeaderSize); 1176 1177 FontInfoSize = sizeof (EFI_FONT_INFO) + HeaderSize - sizeof (EFI_HII_FONT_PACKAGE_HDR); 1178 FontInfo = (EFI_FONT_INFO *) AllocateZeroPool (FontInfoSize); 1179 if (FontInfo == NULL) { 1180 Status = EFI_OUT_OF_RESOURCES; 1181 goto Error; 1182 } 1183 FontInfo->FontStyle = FontPkgHdr->FontStyle; 1184 FontInfo->FontSize = FontPkgHdr->Cell.Height; 1185 StrCpyS (FontInfo->FontName, (FontInfoSize - OFFSET_OF(EFI_FONT_INFO,FontName)) / sizeof (CHAR16), FontPkgHdr->FontFamily); 1186 1187 if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, NULL)) { 1188 Status = EFI_UNSUPPORTED; 1189 goto Error; 1190 } 1191 1192 // 1193 // Create a Font package node 1194 // 1195 FontPackage = (HII_FONT_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_FONT_PACKAGE_INSTANCE)); 1196 if (FontPackage == NULL) { 1197 Status = EFI_OUT_OF_RESOURCES; 1198 goto Error; 1199 } 1200 FontPackage->Signature = HII_FONT_PACKAGE_SIGNATURE; 1201 FontPackage->FontPkgHdr = FontPkgHdr; 1202 InitializeListHead (&FontPackage->GlyphInfoList); 1203 1204 FontPackage->GlyphBlock = (UINT8 *) AllocateZeroPool (PackageHeader.Length - HeaderSize); 1205 if (FontPackage->GlyphBlock == NULL) { 1206 Status = EFI_OUT_OF_RESOURCES; 1207 goto Error; 1208 } 1209 CopyMem (FontPackage->GlyphBlock, (UINT8 *) PackageHdr + HeaderSize, PackageHeader.Length - HeaderSize); 1210 1211 // 1212 // Collect all default character cell information and backup in GlyphInfoList. 1213 // 1214 Status = FindGlyphBlock (FontPackage, (CHAR16) (-1), NULL, NULL, NULL); 1215 if (EFI_ERROR (Status)) { 1216 goto Error; 1217 } 1218 1219 // 1220 // This font package describes an unique EFI_FONT_INFO. Backup it in global 1221 // font info list. 1222 // 1223 GlobalFont = (HII_GLOBAL_FONT_INFO *) AllocateZeroPool (sizeof (HII_GLOBAL_FONT_INFO)); 1224 if (GlobalFont == NULL) { 1225 Status = EFI_OUT_OF_RESOURCES; 1226 goto Error; 1227 } 1228 GlobalFont->Signature = HII_GLOBAL_FONT_INFO_SIGNATURE; 1229 GlobalFont->FontPackage = FontPackage; 1230 GlobalFont->FontInfoSize = FontInfoSize; 1231 GlobalFont->FontInfo = FontInfo; 1232 InsertTailList (&Private->FontInfoList, &GlobalFont->Entry); 1233 1234 // 1235 // Insert this font package to Font package array 1236 // 1237 InsertTailList (&PackageList->FontPkgHdr, &FontPackage->FontEntry); 1238 *Package = FontPackage; 1239 1240 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) { 1241 PackageList->PackageListHdr.PackageLength += FontPackage->FontPkgHdr->Header.Length; 1242 } 1243 1244 return EFI_SUCCESS; 1245 1246 Error: 1247 1248 if (FontPkgHdr != NULL) { 1249 FreePool (FontPkgHdr); 1250 } 1251 if (FontInfo != NULL) { 1252 FreePool (FontInfo); 1253 } 1254 if (FontPackage != NULL) { 1255 if (FontPackage->GlyphBlock != NULL) { 1256 FreePool (FontPackage->GlyphBlock); 1257 } 1258 FreePool (FontPackage); 1259 } 1260 if (GlobalFont != NULL) { 1261 FreePool (GlobalFont); 1262 } 1263 1264 return Status; 1265 1266 } 1267 1268 1269 /** 1270 This function exports Font packages to a buffer. 1271 This is a internal function. 1272 1273 @param Private Hii database private structure. 1274 @param Handle Identification of a package list. 1275 @param PackageList Pointer to a package list which will be exported. 1276 @param UsedSize The length of buffer be used. 1277 @param BufferSize Length of the Buffer. 1278 @param Buffer Allocated space for storing exported data. 1279 @param ResultSize The size of the already exported content of this 1280 package list. 1281 1282 @retval EFI_SUCCESS Font Packages are exported successfully. 1283 @retval EFI_INVALID_PARAMETER Any input parameter is invalid. 1284 1285 **/ 1286 EFI_STATUS 1287 ExportFontPackages ( 1288 IN HII_DATABASE_PRIVATE_DATA *Private, 1289 IN EFI_HII_HANDLE Handle, 1290 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, 1291 IN UINTN UsedSize, 1292 IN UINTN BufferSize, 1293 IN OUT VOID *Buffer, 1294 IN OUT UINTN *ResultSize 1295 ) 1296 { 1297 LIST_ENTRY *Link; 1298 UINTN PackageLength; 1299 EFI_STATUS Status; 1300 HII_FONT_PACKAGE_INSTANCE *Package; 1301 1302 1303 if (Private == NULL || PackageList == NULL || ResultSize == NULL) { 1304 return EFI_INVALID_PARAMETER; 1305 } 1306 1307 if (BufferSize > 0 && Buffer == NULL ) { 1308 return EFI_INVALID_PARAMETER; 1309 } 1310 1311 PackageLength = 0; 1312 Status = EFI_SUCCESS; 1313 1314 for (Link = PackageList->FontPkgHdr.ForwardLink; Link != &PackageList->FontPkgHdr; Link = Link->ForwardLink) { 1315 Package = CR (Link, HII_FONT_PACKAGE_INSTANCE, FontEntry, HII_FONT_PACKAGE_SIGNATURE); 1316 PackageLength += Package->FontPkgHdr->Header.Length; 1317 if (PackageLength + *ResultSize + UsedSize <= BufferSize) { 1318 // 1319 // Invoke registered notification function with EXPORT_PACK notify type 1320 // 1321 Status = InvokeRegisteredFunction ( 1322 Private, 1323 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK, 1324 (VOID *) Package, 1325 EFI_HII_PACKAGE_FONTS, 1326 Handle 1327 ); 1328 ASSERT_EFI_ERROR (Status); 1329 // 1330 // Copy Font package header 1331 // 1332 CopyMem (Buffer, Package->FontPkgHdr, Package->FontPkgHdr->HdrSize); 1333 Buffer = (UINT8 *) Buffer + Package->FontPkgHdr->HdrSize; 1334 1335 // 1336 // Copy Glyph blocks information 1337 // 1338 CopyMem ( 1339 Buffer, 1340 Package->GlyphBlock, 1341 Package->FontPkgHdr->Header.Length - Package->FontPkgHdr->HdrSize 1342 ); 1343 Buffer = (UINT8 *) Buffer + Package->FontPkgHdr->Header.Length - Package->FontPkgHdr->HdrSize; 1344 } 1345 } 1346 1347 *ResultSize += PackageLength; 1348 return EFI_SUCCESS; 1349 } 1350 1351 1352 /** 1353 This function deletes all Font packages from a package list node. 1354 This is a internal function. 1355 1356 @param Private Hii database private data. 1357 @param Handle Handle of the package list which contains the to 1358 be removed Font packages. 1359 @param PackageList Pointer to a package list that contains removing 1360 packages. 1361 1362 @retval EFI_SUCCESS Font Package(s) is deleted successfully. 1363 @retval EFI_INVALID_PARAMETER Any input parameter is not valid. 1364 1365 **/ 1366 EFI_STATUS 1367 RemoveFontPackages ( 1368 IN HII_DATABASE_PRIVATE_DATA *Private, 1369 IN EFI_HII_HANDLE Handle, 1370 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList 1371 ) 1372 { 1373 LIST_ENTRY *ListHead; 1374 HII_FONT_PACKAGE_INSTANCE *Package; 1375 EFI_STATUS Status; 1376 HII_GLYPH_INFO *GlyphInfo; 1377 LIST_ENTRY *Link; 1378 HII_GLOBAL_FONT_INFO *GlobalFont; 1379 1380 ListHead = &PackageList->FontPkgHdr; 1381 1382 while (!IsListEmpty (ListHead)) { 1383 Package = CR ( 1384 ListHead->ForwardLink, 1385 HII_FONT_PACKAGE_INSTANCE, 1386 FontEntry, 1387 HII_FONT_PACKAGE_SIGNATURE 1388 ); 1389 Status = InvokeRegisteredFunction ( 1390 Private, 1391 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK, 1392 (VOID *) Package, 1393 EFI_HII_PACKAGE_FONTS, 1394 Handle 1395 ); 1396 if (EFI_ERROR (Status)) { 1397 return Status; 1398 } 1399 1400 RemoveEntryList (&Package->FontEntry); 1401 PackageList->PackageListHdr.PackageLength -= Package->FontPkgHdr->Header.Length; 1402 1403 if (Package->GlyphBlock != NULL) { 1404 FreePool (Package->GlyphBlock); 1405 } 1406 FreePool (Package->FontPkgHdr); 1407 // 1408 // Delete default character cell information 1409 // 1410 while (!IsListEmpty (&Package->GlyphInfoList)) { 1411 GlyphInfo = CR ( 1412 Package->GlyphInfoList.ForwardLink, 1413 HII_GLYPH_INFO, 1414 Entry, 1415 HII_GLYPH_INFO_SIGNATURE 1416 ); 1417 RemoveEntryList (&GlyphInfo->Entry); 1418 FreePool (GlyphInfo); 1419 } 1420 1421 // 1422 // Remove corresponding global font info 1423 // 1424 for (Link = Private->FontInfoList.ForwardLink; Link != &Private->FontInfoList; Link = Link->ForwardLink) { 1425 GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE); 1426 if (GlobalFont->FontPackage == Package) { 1427 RemoveEntryList (&GlobalFont->Entry); 1428 FreePool (GlobalFont->FontInfo); 1429 FreePool (GlobalFont); 1430 break; 1431 } 1432 } 1433 1434 FreePool (Package); 1435 } 1436 1437 return EFI_SUCCESS; 1438 } 1439 1440 1441 /** 1442 This function insert a Image package to a package list node. 1443 This is a internal function. 1444 1445 @param PackageHdr Pointer to a buffer stored with Image package 1446 information. 1447 @param NotifyType The type of change concerning the database. 1448 @param PackageList Pointer to a package list which will be inserted 1449 to. 1450 @param Package Created Image package 1451 1452 @retval EFI_SUCCESS Image Package is inserted successfully. 1453 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new 1454 Image package. 1455 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL. 1456 1457 **/ 1458 EFI_STATUS 1459 InsertImagePackage ( 1460 IN VOID *PackageHdr, 1461 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, 1462 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, 1463 OUT HII_IMAGE_PACKAGE_INSTANCE **Package 1464 ) 1465 { 1466 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage; 1467 UINT32 PaletteSize; 1468 UINT32 ImageSize; 1469 UINT16 Index; 1470 EFI_HII_IMAGE_PALETTE_INFO_HEADER *PaletteHdr; 1471 EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo; 1472 UINT32 PaletteInfoOffset; 1473 UINT32 ImageInfoOffset; 1474 UINT16 CurrentSize; 1475 1476 if (PackageHdr == NULL || PackageList == NULL) { 1477 return EFI_INVALID_PARAMETER; 1478 } 1479 1480 // 1481 // Less than one image package is allowed in one package list. 1482 // 1483 if (PackageList->ImagePkg != NULL) { 1484 return EFI_INVALID_PARAMETER; 1485 } 1486 1487 // 1488 // Create a Image package node 1489 // 1490 ImagePackage = (HII_IMAGE_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE)); 1491 if (ImagePackage == NULL) { 1492 return EFI_OUT_OF_RESOURCES; 1493 } 1494 1495 // 1496 // Copy the Image package header. 1497 // 1498 CopyMem (&ImagePackage->ImagePkgHdr, PackageHdr, sizeof (EFI_HII_IMAGE_PACKAGE_HDR)); 1499 1500 PaletteInfoOffset = ImagePackage->ImagePkgHdr.PaletteInfoOffset; 1501 ImageInfoOffset = ImagePackage->ImagePkgHdr.ImageInfoOffset; 1502 1503 // 1504 // If PaletteInfoOffset is zero, there are no palettes in this image package. 1505 // 1506 PaletteSize = 0; 1507 ImagePackage->PaletteBlock = NULL; 1508 if (PaletteInfoOffset != 0) { 1509 PaletteHdr = (EFI_HII_IMAGE_PALETTE_INFO_HEADER *) ((UINT8 *) PackageHdr + PaletteInfoOffset); 1510 PaletteSize = sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER); 1511 PaletteInfo = (EFI_HII_IMAGE_PALETTE_INFO *) ((UINT8 *) PaletteHdr + PaletteSize); 1512 1513 for (Index = 0; Index < PaletteHdr->PaletteCount; Index++) { 1514 CopyMem (&CurrentSize, PaletteInfo, sizeof (UINT16)); 1515 CurrentSize += sizeof (UINT16); 1516 PaletteSize += (UINT32) CurrentSize; 1517 PaletteInfo = (EFI_HII_IMAGE_PALETTE_INFO *) ((UINT8 *) PaletteInfo + CurrentSize); 1518 } 1519 1520 ImagePackage->PaletteBlock = (UINT8 *) AllocateZeroPool (PaletteSize); 1521 if (ImagePackage->PaletteBlock == NULL) { 1522 FreePool (ImagePackage); 1523 return EFI_OUT_OF_RESOURCES; 1524 } 1525 CopyMem ( 1526 ImagePackage->PaletteBlock, 1527 (UINT8 *) PackageHdr + PaletteInfoOffset, 1528 PaletteSize 1529 ); 1530 } 1531 1532 // 1533 // If ImageInfoOffset is zero, there are no images in this package. 1534 // 1535 ImageSize = 0; 1536 ImagePackage->ImageBlock = NULL; 1537 if (ImageInfoOffset != 0) { 1538 ImageSize = ImagePackage->ImagePkgHdr.Header.Length - 1539 sizeof (EFI_HII_IMAGE_PACKAGE_HDR) - PaletteSize; 1540 ImagePackage->ImageBlock = (UINT8 *) AllocateZeroPool (ImageSize); 1541 if (ImagePackage->ImageBlock == NULL) { 1542 FreePool (ImagePackage->PaletteBlock); 1543 FreePool (ImagePackage); 1544 return EFI_OUT_OF_RESOURCES; 1545 } 1546 CopyMem ( 1547 ImagePackage->ImageBlock, 1548 (UINT8 *) PackageHdr + ImageInfoOffset, 1549 ImageSize 1550 ); 1551 } 1552 1553 ImagePackage->ImageBlockSize = ImageSize; 1554 ImagePackage->PaletteInfoSize = PaletteSize; 1555 PackageList->ImagePkg = ImagePackage; 1556 *Package = ImagePackage; 1557 1558 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) { 1559 PackageList->PackageListHdr.PackageLength += ImagePackage->ImagePkgHdr.Header.Length; 1560 } 1561 1562 return EFI_SUCCESS; 1563 } 1564 1565 1566 /** 1567 This function exports Image packages to a buffer. 1568 This is a internal function. 1569 1570 @param Private Hii database private structure. 1571 @param Handle Identification of a package list. 1572 @param PackageList Pointer to a package list which will be exported. 1573 @param UsedSize The length of buffer be used. 1574 @param BufferSize Length of the Buffer. 1575 @param Buffer Allocated space for storing exported data. 1576 @param ResultSize The size of the already exported content of this 1577 package list. 1578 1579 @retval EFI_SUCCESS Image Packages are exported successfully. 1580 @retval EFI_INVALID_PARAMETER Any input parameter is invalid. 1581 1582 **/ 1583 EFI_STATUS 1584 ExportImagePackages ( 1585 IN HII_DATABASE_PRIVATE_DATA *Private, 1586 IN EFI_HII_HANDLE Handle, 1587 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, 1588 IN UINTN UsedSize, 1589 IN UINTN BufferSize, 1590 IN OUT VOID *Buffer, 1591 IN OUT UINTN *ResultSize 1592 ) 1593 { 1594 UINTN PackageLength; 1595 EFI_STATUS Status; 1596 HII_IMAGE_PACKAGE_INSTANCE *Package; 1597 1598 1599 if (Private == NULL || PackageList == NULL || ResultSize == NULL) { 1600 return EFI_INVALID_PARAMETER; 1601 } 1602 1603 if (BufferSize > 0 && Buffer == NULL ) { 1604 return EFI_INVALID_PARAMETER; 1605 } 1606 1607 Package = PackageList->ImagePkg; 1608 1609 if (Package == NULL) { 1610 return EFI_SUCCESS; 1611 } 1612 1613 PackageLength = Package->ImagePkgHdr.Header.Length; 1614 1615 if (PackageLength + *ResultSize + UsedSize <= BufferSize) { 1616 // 1617 // Invoke registered notification function with EXPORT_PACK notify type 1618 // 1619 Status = InvokeRegisteredFunction ( 1620 Private, 1621 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK, 1622 (VOID *) Package, 1623 EFI_HII_PACKAGE_IMAGES, 1624 Handle 1625 ); 1626 ASSERT_EFI_ERROR (Status); 1627 ASSERT (Package->ImagePkgHdr.Header.Length == 1628 sizeof (EFI_HII_IMAGE_PACKAGE_HDR) + Package->ImageBlockSize + Package->PaletteInfoSize); 1629 // 1630 // Copy Image package header, 1631 // then justify the offset for image info and palette info in the header. 1632 // 1633 CopyMem (Buffer, &Package->ImagePkgHdr, sizeof (EFI_HII_IMAGE_PACKAGE_HDR)); 1634 Buffer = (UINT8 *) Buffer + sizeof (EFI_HII_IMAGE_PACKAGE_HDR); 1635 1636 // 1637 // Copy Image blocks information 1638 // 1639 if (Package->ImageBlockSize != 0) { 1640 CopyMem (Buffer, Package->ImageBlock, Package->ImageBlockSize); 1641 Buffer = (UINT8 *) Buffer + Package->ImageBlockSize; 1642 } 1643 // 1644 // Copy Palette information 1645 // 1646 if (Package->PaletteInfoSize != 0) { 1647 CopyMem (Buffer, Package->PaletteBlock, Package->PaletteInfoSize); 1648 Buffer = (UINT8 *) Buffer + Package->PaletteInfoSize; 1649 } 1650 } 1651 1652 *ResultSize += PackageLength; 1653 return EFI_SUCCESS; 1654 } 1655 1656 1657 /** 1658 This function deletes Image package from a package list node. 1659 This is a internal function. 1660 1661 @param Private Hii database private data. 1662 @param Handle Handle of the package list which contains the to 1663 be removed Image packages. 1664 @param PackageList Package List which contains the to be removed 1665 Image package. 1666 1667 @retval EFI_SUCCESS Image Package(s) is deleted successfully. 1668 @retval EFI_INVALID_PARAMETER Any input parameter is not valid. 1669 1670 **/ 1671 EFI_STATUS 1672 RemoveImagePackages ( 1673 IN HII_DATABASE_PRIVATE_DATA *Private, 1674 IN EFI_HII_HANDLE Handle, 1675 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList 1676 ) 1677 { 1678 HII_IMAGE_PACKAGE_INSTANCE *Package; 1679 EFI_STATUS Status; 1680 1681 Package = PackageList->ImagePkg; 1682 1683 // 1684 // Image package does not exist, return directly. 1685 // 1686 if (Package == NULL) { 1687 return EFI_SUCCESS; 1688 } 1689 1690 Status = InvokeRegisteredFunction ( 1691 Private, 1692 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK, 1693 (VOID *) Package, 1694 EFI_HII_PACKAGE_IMAGES, 1695 Handle 1696 ); 1697 if (EFI_ERROR (Status)) { 1698 return Status; 1699 } 1700 1701 PackageList->PackageListHdr.PackageLength -= Package->ImagePkgHdr.Header.Length; 1702 1703 FreePool (Package->ImageBlock); 1704 if (Package->PaletteBlock != NULL) { 1705 FreePool (Package->PaletteBlock); 1706 } 1707 FreePool (Package); 1708 1709 PackageList->ImagePkg = NULL; 1710 1711 return EFI_SUCCESS; 1712 } 1713 1714 1715 /** 1716 This function insert a Simple Font package to a package list node. 1717 This is a internal function. 1718 1719 @param PackageHdr Pointer to a buffer stored with Simple Font 1720 package information. 1721 @param NotifyType The type of change concerning the database. 1722 @param PackageList Pointer to a package list which will be inserted 1723 to. 1724 @param Package Created Simple Font package 1725 1726 @retval EFI_SUCCESS Simple Font Package is inserted successfully. 1727 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new 1728 Simple Font package. 1729 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL. 1730 1731 **/ 1732 EFI_STATUS 1733 InsertSimpleFontPackage ( 1734 IN VOID *PackageHdr, 1735 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, 1736 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, 1737 OUT HII_SIMPLE_FONT_PACKAGE_INSTANCE **Package 1738 ) 1739 { 1740 HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFontPackage; 1741 EFI_STATUS Status; 1742 EFI_HII_PACKAGE_HEADER Header; 1743 1744 if (PackageHdr == NULL || PackageList == NULL) { 1745 return EFI_INVALID_PARAMETER; 1746 } 1747 1748 // 1749 // Create a Simple Font package node 1750 // 1751 SimpleFontPackage = AllocateZeroPool (sizeof (HII_SIMPLE_FONT_PACKAGE_INSTANCE)); 1752 if (SimpleFontPackage == NULL) { 1753 Status = EFI_OUT_OF_RESOURCES; 1754 goto Error; 1755 } 1756 SimpleFontPackage->Signature = HII_S_FONT_PACKAGE_SIGNATURE; 1757 1758 // 1759 // Copy the Simple Font package. 1760 // 1761 CopyMem (&Header, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER)); 1762 1763 SimpleFontPackage->SimpleFontPkgHdr = AllocateZeroPool (Header.Length); 1764 if (SimpleFontPackage->SimpleFontPkgHdr == NULL) { 1765 Status = EFI_OUT_OF_RESOURCES; 1766 goto Error; 1767 } 1768 1769 CopyMem (SimpleFontPackage->SimpleFontPkgHdr, PackageHdr, Header.Length); 1770 1771 // 1772 // Insert to Simple Font package array 1773 // 1774 InsertTailList (&PackageList->SimpleFontPkgHdr, &SimpleFontPackage->SimpleFontEntry); 1775 *Package = SimpleFontPackage; 1776 1777 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) { 1778 PackageList->PackageListHdr.PackageLength += Header.Length; 1779 } 1780 1781 return EFI_SUCCESS; 1782 1783 Error: 1784 1785 if (SimpleFontPackage != NULL) { 1786 if (SimpleFontPackage->SimpleFontPkgHdr != NULL) { 1787 FreePool (SimpleFontPackage->SimpleFontPkgHdr); 1788 } 1789 FreePool (SimpleFontPackage); 1790 } 1791 return Status; 1792 } 1793 1794 1795 /** 1796 This function exports SimpleFont packages to a buffer. 1797 This is a internal function. 1798 1799 @param Private Hii database private structure. 1800 @param Handle Identification of a package list. 1801 @param PackageList Pointer to a package list which will be exported. 1802 @param UsedSize The length of buffer be used. 1803 @param BufferSize Length of the Buffer. 1804 @param Buffer Allocated space for storing exported data. 1805 @param ResultSize The size of the already exported content of this 1806 package list. 1807 1808 @retval EFI_SUCCESS SimpleFont Packages are exported successfully. 1809 @retval EFI_INVALID_PARAMETER Any input parameter is invalid. 1810 1811 **/ 1812 EFI_STATUS 1813 ExportSimpleFontPackages ( 1814 IN HII_DATABASE_PRIVATE_DATA *Private, 1815 IN EFI_HII_HANDLE Handle, 1816 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, 1817 IN UINTN UsedSize, 1818 IN UINTN BufferSize, 1819 IN OUT VOID *Buffer, 1820 IN OUT UINTN *ResultSize 1821 ) 1822 { 1823 LIST_ENTRY *Link; 1824 UINTN PackageLength; 1825 EFI_STATUS Status; 1826 HII_SIMPLE_FONT_PACKAGE_INSTANCE *Package; 1827 1828 if (Private == NULL || PackageList == NULL || ResultSize == NULL) { 1829 return EFI_INVALID_PARAMETER; 1830 } 1831 1832 if (BufferSize > 0 && Buffer == NULL ) { 1833 return EFI_INVALID_PARAMETER; 1834 } 1835 1836 PackageLength = 0; 1837 Status = EFI_SUCCESS; 1838 1839 for (Link = PackageList->SimpleFontPkgHdr.ForwardLink; Link != &PackageList->SimpleFontPkgHdr; Link = Link->ForwardLink) { 1840 Package = CR (Link, HII_SIMPLE_FONT_PACKAGE_INSTANCE, SimpleFontEntry, HII_S_FONT_PACKAGE_SIGNATURE); 1841 PackageLength += Package->SimpleFontPkgHdr->Header.Length; 1842 if (PackageLength + *ResultSize + UsedSize <= BufferSize) { 1843 // 1844 // Invoke registered notification function with EXPORT_PACK notify type 1845 // 1846 Status = InvokeRegisteredFunction ( 1847 Private, 1848 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK, 1849 (VOID *) Package, 1850 EFI_HII_PACKAGE_SIMPLE_FONTS, 1851 Handle 1852 ); 1853 ASSERT_EFI_ERROR (Status); 1854 1855 // 1856 // Copy SimpleFont package 1857 // 1858 CopyMem (Buffer, Package->SimpleFontPkgHdr, Package->SimpleFontPkgHdr->Header.Length); 1859 Buffer = (UINT8 *) Buffer + Package->SimpleFontPkgHdr->Header.Length; 1860 } 1861 } 1862 1863 *ResultSize += PackageLength; 1864 return EFI_SUCCESS; 1865 } 1866 1867 1868 /** 1869 This function deletes all Simple Font packages from a package list node. 1870 This is a internal function. 1871 1872 @param Private Hii database private data. 1873 @param Handle Handle of the package list which contains the to 1874 be removed Simple Font packages. 1875 @param PackageList Pointer to a package list that contains removing 1876 packages. 1877 1878 @retval EFI_SUCCESS Simple Font Package(s) is deleted successfully. 1879 @retval EFI_INVALID_PARAMETER Any input parameter is not valid. 1880 1881 **/ 1882 EFI_STATUS 1883 RemoveSimpleFontPackages ( 1884 IN HII_DATABASE_PRIVATE_DATA *Private, 1885 IN EFI_HII_HANDLE Handle, 1886 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList 1887 ) 1888 { 1889 LIST_ENTRY *ListHead; 1890 HII_SIMPLE_FONT_PACKAGE_INSTANCE *Package; 1891 EFI_STATUS Status; 1892 1893 ListHead = &PackageList->SimpleFontPkgHdr; 1894 1895 while (!IsListEmpty (ListHead)) { 1896 Package = CR ( 1897 ListHead->ForwardLink, 1898 HII_SIMPLE_FONT_PACKAGE_INSTANCE, 1899 SimpleFontEntry, 1900 HII_S_FONT_PACKAGE_SIGNATURE 1901 ); 1902 Status = InvokeRegisteredFunction ( 1903 Private, 1904 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK, 1905 (VOID *) Package, 1906 EFI_HII_PACKAGE_SIMPLE_FONTS, 1907 Handle 1908 ); 1909 if (EFI_ERROR (Status)) { 1910 return Status; 1911 } 1912 1913 RemoveEntryList (&Package->SimpleFontEntry); 1914 PackageList->PackageListHdr.PackageLength -= Package->SimpleFontPkgHdr->Header.Length; 1915 FreePool (Package->SimpleFontPkgHdr); 1916 FreePool (Package); 1917 } 1918 1919 return EFI_SUCCESS; 1920 } 1921 1922 1923 /** 1924 This function insert a Device path package to a package list node. 1925 This is a internal function. 1926 1927 @param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol 1928 instance 1929 @param NotifyType The type of change concerning the database. 1930 @param PackageList Pointer to a package list which will be inserted 1931 to. 1932 1933 @retval EFI_SUCCESS Device path Package is inserted successfully. 1934 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new 1935 Device path package. 1936 @retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL. 1937 1938 **/ 1939 EFI_STATUS 1940 InsertDevicePathPackage ( 1941 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, 1942 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, 1943 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList 1944 ) 1945 { 1946 UINT32 PackageLength; 1947 EFI_HII_PACKAGE_HEADER Header; 1948 1949 if (DevicePath == NULL || PackageList == NULL) { 1950 return EFI_INVALID_PARAMETER; 1951 } 1952 // 1953 // Less than one device path package is allowed in one package list. 1954 // 1955 if (PackageList->DevicePathPkg != NULL) { 1956 return EFI_INVALID_PARAMETER; 1957 } 1958 1959 PackageLength = (UINT32) GetDevicePathSize (DevicePath) + sizeof (EFI_HII_PACKAGE_HEADER); 1960 PackageList->DevicePathPkg = (UINT8 *) AllocateZeroPool (PackageLength); 1961 if (PackageList->DevicePathPkg == NULL) { 1962 return EFI_OUT_OF_RESOURCES; 1963 } 1964 1965 Header.Length = PackageLength; 1966 Header.Type = EFI_HII_PACKAGE_DEVICE_PATH; 1967 CopyMem (PackageList->DevicePathPkg, &Header, sizeof (EFI_HII_PACKAGE_HEADER)); 1968 CopyMem ( 1969 PackageList->DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER), 1970 DevicePath, 1971 PackageLength - sizeof (EFI_HII_PACKAGE_HEADER) 1972 ); 1973 1974 // 1975 // Since Device Path package is created by NewPackageList, either NEW_PACK 1976 // or ADD_PACK should increase the length of package list. 1977 // 1978 PackageList->PackageListHdr.PackageLength += PackageLength; 1979 return EFI_SUCCESS; 1980 } 1981 1982 1983 /** 1984 This function exports device path package to a buffer. 1985 This is a internal function. 1986 1987 @param Private Hii database private structure. 1988 @param Handle Identification of a package list. 1989 @param PackageList Pointer to a package list which will be exported. 1990 @param UsedSize The length of buffer be used. 1991 @param BufferSize Length of the Buffer. 1992 @param Buffer Allocated space for storing exported data. 1993 @param ResultSize The size of the already exported content of this 1994 package list. 1995 1996 @retval EFI_SUCCESS Device path Package is exported successfully. 1997 @retval EFI_INVALID_PARAMETER Any input parameter is invalid. 1998 1999 **/ 2000 EFI_STATUS 2001 ExportDevicePathPackage ( 2002 IN HII_DATABASE_PRIVATE_DATA *Private, 2003 IN EFI_HII_HANDLE Handle, 2004 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, 2005 IN UINTN UsedSize, 2006 IN UINTN BufferSize, 2007 IN OUT VOID *Buffer, 2008 IN OUT UINTN *ResultSize 2009 ) 2010 { 2011 EFI_STATUS Status; 2012 UINT8 *Package; 2013 EFI_HII_PACKAGE_HEADER Header; 2014 2015 if (Private == NULL || PackageList == NULL || ResultSize == NULL) { 2016 return EFI_INVALID_PARAMETER; 2017 } 2018 if (BufferSize > 0 && Buffer == NULL ) { 2019 return EFI_INVALID_PARAMETER; 2020 } 2021 2022 Package = PackageList->DevicePathPkg; 2023 2024 if (Package == NULL) { 2025 return EFI_SUCCESS; 2026 } 2027 2028 CopyMem (&Header, Package, sizeof (EFI_HII_PACKAGE_HEADER)); 2029 2030 if (Header.Length + *ResultSize + UsedSize <= BufferSize) { 2031 // 2032 // Invoke registered notification function with EXPORT_PACK notify type 2033 // 2034 Status = InvokeRegisteredFunction ( 2035 Private, 2036 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK, 2037 (VOID *) Package, 2038 EFI_HII_PACKAGE_DEVICE_PATH, 2039 Handle 2040 ); 2041 ASSERT_EFI_ERROR (Status); 2042 2043 // 2044 // Copy Device path package 2045 // 2046 CopyMem (Buffer, Package, Header.Length); 2047 } 2048 2049 *ResultSize += Header.Length; 2050 return EFI_SUCCESS; 2051 } 2052 2053 2054 /** 2055 This function deletes Device Path package from a package list node. 2056 This is a internal function. 2057 2058 @param Private Hii database private data. 2059 @param Handle Handle of the package list. 2060 @param PackageList Package List which contains the to be removed 2061 Device Path package. 2062 2063 @retval EFI_SUCCESS Device Path Package is deleted successfully. 2064 @retval EFI_INVALID_PARAMETER Any input parameter is not valid. 2065 2066 **/ 2067 EFI_STATUS 2068 RemoveDevicePathPackage ( 2069 IN HII_DATABASE_PRIVATE_DATA *Private, 2070 IN EFI_HII_HANDLE Handle, 2071 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList 2072 ) 2073 { 2074 EFI_STATUS Status; 2075 UINT8 *Package; 2076 EFI_HII_PACKAGE_HEADER Header; 2077 2078 Package = PackageList->DevicePathPkg; 2079 2080 // 2081 // No device path, return directly. 2082 // 2083 if (Package == NULL) { 2084 return EFI_SUCCESS; 2085 } 2086 2087 Status = InvokeRegisteredFunction ( 2088 Private, 2089 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK, 2090 (VOID *) Package, 2091 EFI_HII_PACKAGE_DEVICE_PATH, 2092 Handle 2093 ); 2094 if (EFI_ERROR (Status)) { 2095 return Status; 2096 } 2097 2098 CopyMem (&Header, Package, sizeof (EFI_HII_PACKAGE_HEADER)); 2099 PackageList->PackageListHdr.PackageLength -= Header.Length; 2100 2101 FreePool (Package); 2102 2103 PackageList->DevicePathPkg = NULL; 2104 2105 return EFI_SUCCESS; 2106 } 2107 2108 2109 /** 2110 This function will insert a device path package to package list firstly then 2111 invoke notification functions if any. 2112 This is a internal function. 2113 2114 @param Private Hii database private structure. 2115 @param NotifyType The type of change concerning the database. 2116 @param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol 2117 instance 2118 @param DatabaseRecord Pointer to a database record contains a package 2119 list which will be inserted to. 2120 2121 @retval EFI_SUCCESS Device path Package is inserted successfully. 2122 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new 2123 Device path package. 2124 @retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL. 2125 2126 **/ 2127 EFI_STATUS 2128 AddDevicePathPackage ( 2129 IN HII_DATABASE_PRIVATE_DATA *Private, 2130 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, 2131 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, 2132 IN OUT HII_DATABASE_RECORD *DatabaseRecord 2133 ) 2134 { 2135 EFI_STATUS Status; 2136 2137 if (DevicePath == NULL) { 2138 return EFI_SUCCESS; 2139 } 2140 2141 ASSERT (Private != NULL); 2142 ASSERT (DatabaseRecord != NULL); 2143 2144 // 2145 // Create a device path package and insert to packagelist 2146 // 2147 Status = InsertDevicePathPackage ( 2148 DevicePath, 2149 NotifyType, 2150 DatabaseRecord->PackageList 2151 ); 2152 if (EFI_ERROR (Status)) { 2153 return Status; 2154 } 2155 2156 return InvokeRegisteredFunction ( 2157 Private, 2158 NotifyType, 2159 (VOID *) DatabaseRecord->PackageList->DevicePathPkg, 2160 EFI_HII_PACKAGE_DEVICE_PATH, 2161 DatabaseRecord->Handle 2162 ); 2163 } 2164 2165 2166 /** 2167 This function insert a Keyboard Layout package to a package list node. 2168 This is a internal function. 2169 2170 @param PackageHdr Pointer to a buffer stored with Keyboard Layout 2171 package information. 2172 @param NotifyType The type of change concerning the database. 2173 @param PackageList Pointer to a package list which will be inserted 2174 to. 2175 @param Package Created Keyboard Layout package 2176 2177 @retval EFI_SUCCESS Keyboard Layout Package is inserted successfully. 2178 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new 2179 Keyboard Layout package. 2180 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL. 2181 2182 **/ 2183 EFI_STATUS 2184 InsertKeyboardLayoutPackage ( 2185 IN VOID *PackageHdr, 2186 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, 2187 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, 2188 OUT HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE **Package 2189 ) 2190 { 2191 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *KeyboardLayoutPackage; 2192 EFI_HII_PACKAGE_HEADER PackageHeader; 2193 EFI_STATUS Status; 2194 2195 if (PackageHdr == NULL || PackageList == NULL) { 2196 return EFI_INVALID_PARAMETER; 2197 } 2198 2199 CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER)); 2200 2201 // 2202 // Create a Keyboard Layout package node 2203 // 2204 KeyboardLayoutPackage = AllocateZeroPool (sizeof (HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE)); 2205 if (KeyboardLayoutPackage == NULL) { 2206 Status = EFI_OUT_OF_RESOURCES; 2207 goto Error; 2208 } 2209 KeyboardLayoutPackage->Signature = HII_KB_LAYOUT_PACKAGE_SIGNATURE; 2210 2211 KeyboardLayoutPackage->KeyboardPkg = (UINT8 *) AllocateZeroPool (PackageHeader.Length); 2212 if (KeyboardLayoutPackage->KeyboardPkg == NULL) { 2213 Status = EFI_OUT_OF_RESOURCES; 2214 goto Error; 2215 } 2216 2217 CopyMem (KeyboardLayoutPackage->KeyboardPkg, PackageHdr, PackageHeader.Length); 2218 InsertTailList (&PackageList->KeyboardLayoutHdr, &KeyboardLayoutPackage->KeyboardEntry); 2219 2220 *Package = KeyboardLayoutPackage; 2221 2222 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) { 2223 PackageList->PackageListHdr.PackageLength += PackageHeader.Length; 2224 } 2225 2226 return EFI_SUCCESS; 2227 2228 Error: 2229 2230 2231 if (KeyboardLayoutPackage != NULL) { 2232 if (KeyboardLayoutPackage->KeyboardPkg != NULL) { 2233 FreePool (KeyboardLayoutPackage->KeyboardPkg); 2234 } 2235 FreePool (KeyboardLayoutPackage); 2236 } 2237 2238 return Status; 2239 } 2240 2241 2242 /** 2243 This function exports Keyboard Layout packages to a buffer. 2244 This is a internal function. 2245 2246 @param Private Hii database private structure. 2247 @param Handle Identification of a package list. 2248 @param PackageList Pointer to a package list which will be exported. 2249 @param UsedSize The length of buffer be used. 2250 @param BufferSize Length of the Buffer. 2251 @param Buffer Allocated space for storing exported data. 2252 @param ResultSize The size of the already exported content of this 2253 package list. 2254 2255 @retval EFI_SUCCESS Keyboard Layout Packages are exported 2256 successfully. 2257 @retval EFI_INVALID_PARAMETER Any input parameter is invalid. 2258 2259 **/ 2260 EFI_STATUS 2261 ExportKeyboardLayoutPackages ( 2262 IN HII_DATABASE_PRIVATE_DATA *Private, 2263 IN EFI_HII_HANDLE Handle, 2264 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, 2265 IN UINTN UsedSize, 2266 IN UINTN BufferSize, 2267 IN OUT VOID *Buffer, 2268 IN OUT UINTN *ResultSize 2269 ) 2270 { 2271 LIST_ENTRY *Link; 2272 UINTN PackageLength; 2273 EFI_STATUS Status; 2274 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package; 2275 EFI_HII_PACKAGE_HEADER PackageHeader; 2276 2277 if (Private == NULL || PackageList == NULL || ResultSize == NULL) { 2278 return EFI_INVALID_PARAMETER; 2279 } 2280 2281 if (BufferSize > 0 && Buffer == NULL ) { 2282 return EFI_INVALID_PARAMETER; 2283 } 2284 2285 PackageLength = 0; 2286 Status = EFI_SUCCESS; 2287 2288 for (Link = PackageList->KeyboardLayoutHdr.ForwardLink; Link != &PackageList->KeyboardLayoutHdr; Link = Link->ForwardLink) { 2289 Package = CR (Link, HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE, KeyboardEntry, HII_KB_LAYOUT_PACKAGE_SIGNATURE); 2290 CopyMem (&PackageHeader, Package->KeyboardPkg, sizeof (EFI_HII_PACKAGE_HEADER)); 2291 PackageLength += PackageHeader.Length; 2292 if (PackageLength + *ResultSize + UsedSize <= BufferSize) { 2293 // 2294 // Invoke registered notification function with EXPORT_PACK notify type 2295 // 2296 Status = InvokeRegisteredFunction ( 2297 Private, 2298 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK, 2299 (EFI_HII_PACKAGE_HEADER *) Package, 2300 EFI_HII_PACKAGE_KEYBOARD_LAYOUT, 2301 Handle 2302 ); 2303 ASSERT_EFI_ERROR (Status); 2304 2305 // 2306 // Copy Keyboard Layout package 2307 // 2308 CopyMem (Buffer, Package->KeyboardPkg, PackageHeader.Length); 2309 Buffer = (UINT8 *) Buffer + PackageHeader.Length; 2310 } 2311 } 2312 2313 *ResultSize += PackageLength; 2314 return EFI_SUCCESS; 2315 } 2316 2317 2318 /** 2319 This function deletes all Keyboard Layout packages from a package list node. 2320 This is a internal function. 2321 2322 @param Private Hii database private data. 2323 @param Handle Handle of the package list which contains the to 2324 be removed Keyboard Layout packages. 2325 @param PackageList Pointer to a package list that contains removing 2326 packages. 2327 2328 @retval EFI_SUCCESS Keyboard Layout Package(s) is deleted 2329 successfully. 2330 @retval EFI_INVALID_PARAMETER Any input parameter is not valid. 2331 2332 **/ 2333 EFI_STATUS 2334 RemoveKeyboardLayoutPackages ( 2335 IN HII_DATABASE_PRIVATE_DATA *Private, 2336 IN EFI_HII_HANDLE Handle, 2337 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList 2338 ) 2339 { 2340 LIST_ENTRY *ListHead; 2341 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package; 2342 EFI_HII_PACKAGE_HEADER PackageHeader; 2343 EFI_STATUS Status; 2344 2345 ListHead = &PackageList->KeyboardLayoutHdr; 2346 2347 while (!IsListEmpty (ListHead)) { 2348 Package = CR ( 2349 ListHead->ForwardLink, 2350 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE, 2351 KeyboardEntry, 2352 HII_KB_LAYOUT_PACKAGE_SIGNATURE 2353 ); 2354 Status = InvokeRegisteredFunction ( 2355 Private, 2356 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK, 2357 (VOID *) Package, 2358 EFI_HII_PACKAGE_KEYBOARD_LAYOUT, 2359 Handle 2360 ); 2361 if (EFI_ERROR (Status)) { 2362 return Status; 2363 } 2364 2365 RemoveEntryList (&Package->KeyboardEntry); 2366 CopyMem (&PackageHeader, Package->KeyboardPkg, sizeof (EFI_HII_PACKAGE_HEADER)); 2367 PackageList->PackageListHdr.PackageLength -= PackageHeader.Length; 2368 FreePool (Package->KeyboardPkg); 2369 FreePool (Package); 2370 } 2371 2372 return EFI_SUCCESS; 2373 } 2374 2375 2376 /** 2377 This function will insert a package list to hii database firstly then 2378 invoke notification functions if any. It is the worker function of 2379 HiiNewPackageList and HiiUpdatePackageList. 2380 2381 This is a internal function. 2382 2383 @param Private Hii database private structure. 2384 @param NotifyType The type of change concerning the database. 2385 @param PackageList Pointer to a package list. 2386 @param DatabaseRecord Pointer to a database record contains a package 2387 list instance which will be inserted to. 2388 2389 @retval EFI_SUCCESS All incoming packages are inserted to current 2390 database. 2391 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new 2392 Device path package. 2393 @retval EFI_INVALID_PARAMETER Any input parameter is invalid. 2394 2395 **/ 2396 EFI_STATUS 2397 AddPackages ( 2398 IN HII_DATABASE_PRIVATE_DATA *Private, 2399 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, 2400 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList, 2401 IN OUT HII_DATABASE_RECORD *DatabaseRecord 2402 ) 2403 { 2404 EFI_STATUS Status; 2405 HII_GUID_PACKAGE_INSTANCE *GuidPackage; 2406 HII_IFR_PACKAGE_INSTANCE *FormPackage; 2407 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *KeyboardLayoutPackage; 2408 HII_STRING_PACKAGE_INSTANCE *StringPackage; 2409 HII_FONT_PACKAGE_INSTANCE *FontPackage; 2410 HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFontPackage; 2411 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage; 2412 EFI_HII_PACKAGE_HEADER *PackageHdrPtr; 2413 EFI_HII_PACKAGE_HEADER PackageHeader; 2414 UINT32 OldPackageListLen; 2415 BOOLEAN StringPkgIsAdd; 2416 2417 // 2418 // Initialize Variables 2419 // 2420 StringPkgIsAdd = FALSE; 2421 FontPackage = NULL; 2422 StringPackage = NULL; 2423 GuidPackage = NULL; 2424 FormPackage = NULL; 2425 ImagePackage = NULL; 2426 SimpleFontPackage = NULL; 2427 KeyboardLayoutPackage = NULL; 2428 2429 // 2430 // Process the package list header 2431 // 2432 OldPackageListLen = DatabaseRecord->PackageList->PackageListHdr.PackageLength; 2433 CopyMem ( 2434 &DatabaseRecord->PackageList->PackageListHdr, 2435 (VOID *) PackageList, 2436 sizeof (EFI_HII_PACKAGE_LIST_HEADER) 2437 ); 2438 if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) { 2439 DatabaseRecord->PackageList->PackageListHdr.PackageLength = OldPackageListLen; 2440 } 2441 2442 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER)); 2443 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER)); 2444 2445 Status = EFI_SUCCESS; 2446 2447 while (PackageHeader.Type != EFI_HII_PACKAGE_END) { 2448 switch (PackageHeader.Type) { 2449 case EFI_HII_PACKAGE_TYPE_GUID: 2450 Status = InsertGuidPackage ( 2451 PackageHdrPtr, 2452 NotifyType, 2453 DatabaseRecord->PackageList, 2454 &GuidPackage 2455 ); 2456 if (EFI_ERROR (Status)) { 2457 return Status; 2458 } 2459 Status = InvokeRegisteredFunction ( 2460 Private, 2461 NotifyType, 2462 (VOID *) GuidPackage, 2463 (UINT8) (PackageHeader.Type), 2464 DatabaseRecord->Handle 2465 ); 2466 break; 2467 case EFI_HII_PACKAGE_FORMS: 2468 Status = InsertFormPackage ( 2469 PackageHdrPtr, 2470 NotifyType, 2471 DatabaseRecord->PackageList, 2472 &FormPackage 2473 ); 2474 if (EFI_ERROR (Status)) { 2475 return Status; 2476 } 2477 Status = InvokeRegisteredFunction ( 2478 Private, 2479 NotifyType, 2480 (VOID *) FormPackage, 2481 (UINT8) (PackageHeader.Type), 2482 DatabaseRecord->Handle 2483 ); 2484 break; 2485 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT: 2486 Status = InsertKeyboardLayoutPackage ( 2487 PackageHdrPtr, 2488 NotifyType, 2489 DatabaseRecord->PackageList, 2490 &KeyboardLayoutPackage 2491 ); 2492 if (EFI_ERROR (Status)) { 2493 return Status; 2494 } 2495 Status = InvokeRegisteredFunction ( 2496 Private, 2497 NotifyType, 2498 (VOID *) KeyboardLayoutPackage, 2499 (UINT8) (PackageHeader.Type), 2500 DatabaseRecord->Handle 2501 ); 2502 break; 2503 case EFI_HII_PACKAGE_STRINGS: 2504 Status = InsertStringPackage ( 2505 Private, 2506 PackageHdrPtr, 2507 NotifyType, 2508 DatabaseRecord->PackageList, 2509 &StringPackage 2510 ); 2511 if (EFI_ERROR (Status)) { 2512 return Status; 2513 } 2514 ASSERT (StringPackage != NULL); 2515 Status = InvokeRegisteredFunction ( 2516 Private, 2517 NotifyType, 2518 (VOID *) StringPackage, 2519 (UINT8) (PackageHeader.Type), 2520 DatabaseRecord->Handle 2521 ); 2522 StringPkgIsAdd = TRUE; 2523 break; 2524 case EFI_HII_PACKAGE_FONTS: 2525 Status = InsertFontPackage ( 2526 Private, 2527 PackageHdrPtr, 2528 NotifyType, 2529 DatabaseRecord->PackageList, 2530 &FontPackage 2531 ); 2532 if (EFI_ERROR (Status)) { 2533 return Status; 2534 } 2535 Status = InvokeRegisteredFunction ( 2536 Private, 2537 NotifyType, 2538 (VOID *) FontPackage, 2539 (UINT8) (PackageHeader.Type), 2540 DatabaseRecord->Handle 2541 ); 2542 break; 2543 case EFI_HII_PACKAGE_IMAGES: 2544 Status = InsertImagePackage ( 2545 PackageHdrPtr, 2546 NotifyType, 2547 DatabaseRecord->PackageList, 2548 &ImagePackage 2549 ); 2550 if (EFI_ERROR (Status)) { 2551 return Status; 2552 } 2553 Status = InvokeRegisteredFunction ( 2554 Private, 2555 NotifyType, 2556 (VOID *) ImagePackage, 2557 (UINT8) (PackageHeader.Type), 2558 DatabaseRecord->Handle 2559 ); 2560 break; 2561 case EFI_HII_PACKAGE_SIMPLE_FONTS: 2562 Status = InsertSimpleFontPackage ( 2563 PackageHdrPtr, 2564 NotifyType, 2565 DatabaseRecord->PackageList, 2566 &SimpleFontPackage 2567 ); 2568 if (EFI_ERROR (Status)) { 2569 return Status; 2570 } 2571 Status = InvokeRegisteredFunction ( 2572 Private, 2573 NotifyType, 2574 (VOID *) SimpleFontPackage, 2575 (UINT8) (PackageHeader.Type), 2576 DatabaseRecord->Handle 2577 ); 2578 break; 2579 case EFI_HII_PACKAGE_DEVICE_PATH: 2580 Status = AddDevicePathPackage ( 2581 Private, 2582 NotifyType, 2583 (EFI_DEVICE_PATH_PROTOCOL *) ((UINT8 *) PackageHdrPtr + sizeof (EFI_HII_PACKAGE_HEADER)), 2584 DatabaseRecord 2585 ); 2586 break; 2587 default: 2588 break; 2589 } 2590 2591 if (EFI_ERROR (Status)) { 2592 return Status; 2593 } 2594 // 2595 // goto header of next package 2596 // 2597 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length); 2598 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER)); 2599 } 2600 2601 // 2602 // Adjust String Package to make sure all string packages have the same max string ID. 2603 // 2604 if (!EFI_ERROR (Status) && StringPkgIsAdd) { 2605 Status = AdjustStringPackage (DatabaseRecord->PackageList); 2606 } 2607 2608 return Status; 2609 } 2610 2611 2612 /** 2613 This function exports a package list to a buffer. It is the worker function 2614 of HiiExportPackageList. 2615 2616 This is a internal function. 2617 2618 @param Private Hii database private structure. 2619 @param Handle Identification of a package list. 2620 @param PackageList Pointer to a package list which will be exported. 2621 @param UsedSize The length of buffer has been used by exporting 2622 package lists when Handle is NULL. 2623 @param BufferSize Length of the Buffer. 2624 @param Buffer Allocated space for storing exported data. 2625 2626 @retval EFI_SUCCESS Keyboard Layout Packages are exported 2627 successfully. 2628 @retval EFI_INVALID_PARAMETER Any input parameter is invalid. 2629 2630 **/ 2631 EFI_STATUS 2632 ExportPackageList ( 2633 IN HII_DATABASE_PRIVATE_DATA *Private, 2634 IN EFI_HII_HANDLE Handle, 2635 IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, 2636 IN OUT UINTN *UsedSize, 2637 IN UINTN BufferSize, 2638 OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer 2639 ) 2640 { 2641 EFI_STATUS Status; 2642 UINTN ResultSize; 2643 EFI_HII_PACKAGE_HEADER EndofPackageList; 2644 2645 ASSERT (Private != NULL && PackageList != NULL && UsedSize != NULL); 2646 ASSERT (Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE); 2647 ASSERT (IsHiiHandleValid (Handle)); 2648 2649 if (BufferSize > 0 && Buffer == NULL ) { 2650 return EFI_INVALID_PARAMETER; 2651 } 2652 2653 // 2654 // Copy the package list header 2655 // ResultSize indicates the length of the exported bytes of this package list 2656 // 2657 ResultSize = sizeof (EFI_HII_PACKAGE_LIST_HEADER); 2658 if (ResultSize + *UsedSize <= BufferSize) { 2659 CopyMem ((VOID *) Buffer, PackageList, ResultSize); 2660 } 2661 // 2662 // Copy the packages and invoke EXPORT_PACK notify functions if exists. 2663 // 2664 Status = ExportGuidPackages ( 2665 Private, 2666 Handle, 2667 PackageList, 2668 *UsedSize, 2669 BufferSize, 2670 (VOID *) ((UINT8 *) Buffer + ResultSize), 2671 &ResultSize 2672 ); 2673 if (EFI_ERROR (Status)) { 2674 return Status; 2675 } 2676 Status = ExportFormPackages ( 2677 Private, 2678 Handle, 2679 PackageList, 2680 *UsedSize, 2681 BufferSize, 2682 (VOID *) ((UINT8 *) Buffer + ResultSize), 2683 &ResultSize 2684 ); 2685 if (EFI_ERROR (Status)) { 2686 return Status; 2687 } 2688 Status = ExportKeyboardLayoutPackages ( 2689 Private, 2690 Handle, 2691 PackageList, 2692 *UsedSize, 2693 BufferSize, 2694 (VOID *) ((UINT8 *) Buffer + ResultSize), 2695 &ResultSize 2696 ); 2697 if (EFI_ERROR (Status)) { 2698 return Status; 2699 } 2700 Status = ExportStringPackages ( 2701 Private, 2702 Handle, 2703 PackageList, 2704 *UsedSize, 2705 BufferSize, 2706 (VOID *) ((UINT8 *) Buffer + ResultSize), 2707 &ResultSize 2708 ); 2709 if (EFI_ERROR (Status)) { 2710 return Status; 2711 } 2712 Status = ExportFontPackages ( 2713 Private, 2714 Handle, 2715 PackageList, 2716 *UsedSize, 2717 BufferSize, 2718 (VOID *) ((UINT8 *) Buffer + ResultSize), 2719 &ResultSize 2720 ); 2721 if (EFI_ERROR (Status)) { 2722 return Status; 2723 } 2724 Status = ExportImagePackages ( 2725 Private, 2726 Handle, 2727 PackageList, 2728 *UsedSize, 2729 BufferSize, 2730 (VOID *) ((UINT8 *) Buffer + ResultSize), 2731 &ResultSize 2732 ); 2733 if (EFI_ERROR (Status)) { 2734 return Status; 2735 } 2736 Status = ExportSimpleFontPackages ( 2737 Private, 2738 Handle, 2739 PackageList, 2740 *UsedSize, 2741 BufferSize, 2742 (VOID *) ((UINT8 *) Buffer + ResultSize), 2743 &ResultSize 2744 ); 2745 if (EFI_ERROR (Status)) { 2746 return Status; 2747 } 2748 Status = ExportDevicePathPackage ( 2749 Private, 2750 Handle, 2751 PackageList, 2752 *UsedSize, 2753 BufferSize, 2754 (VOID *) ((UINT8 *) Buffer + ResultSize), 2755 &ResultSize 2756 ); 2757 if (EFI_ERROR (Status)) { 2758 return Status; 2759 } 2760 // 2761 // Append the package list end. 2762 // 2763 EndofPackageList.Length = sizeof (EFI_HII_PACKAGE_HEADER); 2764 EndofPackageList.Type = EFI_HII_PACKAGE_END; 2765 if (ResultSize + *UsedSize + sizeof (EFI_HII_PACKAGE_HEADER) <= BufferSize) { 2766 CopyMem ( 2767 (VOID *) ((UINT8 *) Buffer + ResultSize), 2768 (VOID *) &EndofPackageList, 2769 sizeof (EFI_HII_PACKAGE_HEADER) 2770 ); 2771 } 2772 2773 *UsedSize += ResultSize + sizeof (EFI_HII_PACKAGE_HEADER); 2774 2775 return EFI_SUCCESS; 2776 } 2777 2778 2779 /** 2780 This function adds the packages in the package list to the database and returns a handle. If there is a 2781 EFI_DEVICE_PATH_PROTOCOL associated with the DriverHandle, then this function will 2782 create a package of type EFI_PACKAGE_TYPE_DEVICE_PATH and add it to the package list. 2783 2784 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL 2785 instance. 2786 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER 2787 structure. 2788 @param DriverHandle Associate the package list with this EFI handle. 2789 If a NULL is specified, this data will not be associate 2790 with any drivers and cannot have a callback induced. 2791 @param Handle A pointer to the EFI_HII_HANDLE instance. 2792 2793 @retval EFI_SUCCESS The package list associated with the Handle was 2794 added to the HII database. 2795 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new 2796 database contents. 2797 @retval EFI_INVALID_PARAMETER PackageList is NULL or Handle is NULL. 2798 @retval EFI_INVALID_PARAMETER PackageListGuid already exists in database. 2799 2800 **/ 2801 EFI_STATUS 2802 EFIAPI 2803 HiiNewPackageList ( 2804 IN CONST EFI_HII_DATABASE_PROTOCOL *This, 2805 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList, 2806 IN CONST EFI_HANDLE DriverHandle, OPTIONAL 2807 OUT EFI_HII_HANDLE *Handle 2808 ) 2809 { 2810 EFI_STATUS Status; 2811 HII_DATABASE_PRIVATE_DATA *Private; 2812 HII_DATABASE_RECORD *DatabaseRecord; 2813 EFI_DEVICE_PATH_PROTOCOL *DevicePath; 2814 LIST_ENTRY *Link; 2815 EFI_GUID PackageListGuid; 2816 2817 if (This == NULL || PackageList == NULL || Handle == NULL) { 2818 return EFI_INVALID_PARAMETER; 2819 } 2820 2821 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This); 2822 CopyMem (&PackageListGuid, (VOID *) PackageList, sizeof (EFI_GUID)); 2823 2824 // 2825 // Check the Package list GUID to guarantee this GUID is unique in database. 2826 // 2827 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) { 2828 DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE); 2829 if (CompareGuid ( 2830 &(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid), 2831 &PackageListGuid) && 2832 DatabaseRecord->DriverHandle == DriverHandle) { 2833 return EFI_INVALID_PARAMETER; 2834 } 2835 } 2836 2837 // 2838 // Build a PackageList node 2839 // 2840 Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord); 2841 if (EFI_ERROR (Status)) { 2842 return Status; 2843 } 2844 2845 // 2846 // Fill in information of the created Package List node 2847 // according to incoming package list. 2848 // 2849 Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, PackageList, DatabaseRecord); 2850 if (EFI_ERROR (Status)) { 2851 return Status; 2852 } 2853 2854 DatabaseRecord->DriverHandle = DriverHandle; 2855 2856 // 2857 // Create a Device path package and add into the package list if exists. 2858 // 2859 Status = gBS->HandleProtocol ( 2860 DriverHandle, 2861 &gEfiDevicePathProtocolGuid, 2862 (VOID **) &DevicePath 2863 ); 2864 if (!EFI_ERROR (Status)) { 2865 Status = AddDevicePathPackage (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, DevicePath, DatabaseRecord); 2866 ASSERT_EFI_ERROR (Status); 2867 } 2868 2869 *Handle = DatabaseRecord->Handle; 2870 return EFI_SUCCESS; 2871 } 2872 2873 2874 /** 2875 This function removes the package list that is associated with a handle Handle 2876 from the HII database. Before removing the package, any registered functions 2877 with the notification type REMOVE_PACK and the same package type will be called. 2878 2879 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL 2880 instance. 2881 @param Handle The handle that was registered to the data that is 2882 requested for removal. 2883 2884 @retval EFI_SUCCESS The data associated with the Handle was removed 2885 from the HII database. 2886 @retval EFI_NOT_FOUND The specified andle is not in database. 2887 @retval EFI_INVALID_PARAMETER The Handle was not valid. 2888 2889 **/ 2890 EFI_STATUS 2891 EFIAPI 2892 HiiRemovePackageList ( 2893 IN CONST EFI_HII_DATABASE_PROTOCOL *This, 2894 IN EFI_HII_HANDLE Handle 2895 ) 2896 { 2897 EFI_STATUS Status; 2898 HII_DATABASE_PRIVATE_DATA *Private; 2899 LIST_ENTRY *Link; 2900 HII_DATABASE_RECORD *Node; 2901 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList; 2902 HII_HANDLE *HiiHandle; 2903 2904 if (This == NULL) { 2905 return EFI_INVALID_PARAMETER; 2906 } 2907 2908 if (!IsHiiHandleValid (Handle)) { 2909 return EFI_NOT_FOUND; 2910 } 2911 2912 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This); 2913 2914 // 2915 // Get the packagelist to be removed. 2916 // 2917 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) { 2918 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE); 2919 if (Node->Handle == Handle) { 2920 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList); 2921 ASSERT (PackageList != NULL); 2922 2923 // 2924 // Call registered functions with REMOVE_PACK before removing packages 2925 // then remove them. 2926 // 2927 Status = RemoveGuidPackages (Private, Handle, PackageList); 2928 if (EFI_ERROR (Status)) { 2929 return Status; 2930 } 2931 Status = RemoveFormPackages (Private, Handle, PackageList); 2932 if (EFI_ERROR (Status)) { 2933 return Status; 2934 } 2935 Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList); 2936 if (EFI_ERROR (Status)) { 2937 return Status; 2938 } 2939 Status = RemoveStringPackages (Private, Handle, PackageList); 2940 if (EFI_ERROR (Status)) { 2941 return Status; 2942 } 2943 Status = RemoveFontPackages (Private, Handle, PackageList); 2944 if (EFI_ERROR (Status)) { 2945 return Status; 2946 } 2947 Status = RemoveImagePackages (Private, Handle, PackageList); 2948 if (EFI_ERROR (Status)) { 2949 return Status; 2950 } 2951 Status = RemoveSimpleFontPackages (Private, Handle, PackageList); 2952 if (EFI_ERROR (Status)) { 2953 return Status; 2954 } 2955 Status = RemoveDevicePathPackage (Private, Handle, PackageList); 2956 if (EFI_ERROR (Status)) { 2957 return Status; 2958 } 2959 2960 // 2961 // Free resources of the package list 2962 // 2963 RemoveEntryList (&Node->DatabaseEntry); 2964 2965 HiiHandle = (HII_HANDLE *) Handle; 2966 RemoveEntryList (&HiiHandle->Handle); 2967 Private->HiiHandleCount--; 2968 ASSERT (Private->HiiHandleCount >= 0); 2969 2970 HiiHandle->Signature = 0; 2971 FreePool (HiiHandle); 2972 FreePool (Node->PackageList); 2973 FreePool (Node); 2974 2975 return EFI_SUCCESS; 2976 } 2977 } 2978 2979 return EFI_NOT_FOUND; 2980 } 2981 2982 2983 /** 2984 This function updates the existing package list (which has the specified Handle) 2985 in the HII databases, using the new package list specified by PackageList. 2986 2987 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL 2988 instance. 2989 @param Handle The handle that was registered to the data that is 2990 requested to be updated. 2991 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER 2992 package. 2993 2994 @retval EFI_SUCCESS The HII database was successfully updated. 2995 @retval EFI_OUT_OF_RESOURCES Unable to allocate enough memory for the updated 2996 database. 2997 @retval EFI_INVALID_PARAMETER PackageList was NULL. 2998 @retval EFI_NOT_FOUND The specified Handle is not in database. 2999 3000 **/ 3001 EFI_STATUS 3002 EFIAPI 3003 HiiUpdatePackageList ( 3004 IN CONST EFI_HII_DATABASE_PROTOCOL *This, 3005 IN EFI_HII_HANDLE Handle, 3006 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList 3007 ) 3008 { 3009 EFI_STATUS Status; 3010 HII_DATABASE_PRIVATE_DATA *Private; 3011 LIST_ENTRY *Link; 3012 HII_DATABASE_RECORD *Node; 3013 EFI_HII_PACKAGE_HEADER *PackageHdrPtr; 3014 HII_DATABASE_PACKAGE_LIST_INSTANCE *OldPackageList; 3015 EFI_HII_PACKAGE_HEADER PackageHeader; 3016 3017 if (This == NULL || PackageList == NULL) { 3018 return EFI_INVALID_PARAMETER; 3019 } 3020 3021 if (!IsHiiHandleValid (Handle)) { 3022 return EFI_NOT_FOUND; 3023 } 3024 3025 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This); 3026 3027 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER)); 3028 3029 Status = EFI_SUCCESS; 3030 3031 // 3032 // Get original packagelist to be updated 3033 // 3034 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) { 3035 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE); 3036 if (Node->Handle == Handle) { 3037 OldPackageList = Node->PackageList; 3038 // 3039 // Remove the package if its type matches one of the package types which is 3040 // contained in the new package list. 3041 // 3042 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER)); 3043 while (PackageHeader.Type != EFI_HII_PACKAGE_END) { 3044 switch (PackageHeader.Type) { 3045 case EFI_HII_PACKAGE_TYPE_GUID: 3046 Status = RemoveGuidPackages (Private, Handle, OldPackageList); 3047 break; 3048 case EFI_HII_PACKAGE_FORMS: 3049 Status = RemoveFormPackages (Private, Handle, OldPackageList); 3050 break; 3051 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT: 3052 Status = RemoveKeyboardLayoutPackages (Private, Handle, OldPackageList); 3053 break; 3054 case EFI_HII_PACKAGE_STRINGS: 3055 Status = RemoveStringPackages (Private, Handle, OldPackageList); 3056 break; 3057 case EFI_HII_PACKAGE_FONTS: 3058 Status = RemoveFontPackages (Private, Handle, OldPackageList); 3059 break; 3060 case EFI_HII_PACKAGE_IMAGES: 3061 Status = RemoveImagePackages (Private, Handle, OldPackageList); 3062 break; 3063 case EFI_HII_PACKAGE_SIMPLE_FONTS: 3064 Status = RemoveSimpleFontPackages (Private, Handle, OldPackageList); 3065 break; 3066 case EFI_HII_PACKAGE_DEVICE_PATH: 3067 Status = RemoveDevicePathPackage (Private, Handle, OldPackageList); 3068 break; 3069 } 3070 3071 if (EFI_ERROR (Status)) { 3072 return Status; 3073 } 3074 3075 PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length); 3076 CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER)); 3077 } 3078 3079 // 3080 // Add all of the packages within the new package list 3081 // 3082 return AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node); 3083 } 3084 } 3085 3086 return EFI_NOT_FOUND; 3087 } 3088 3089 3090 /** 3091 This function returns a list of the package handles of the specified type 3092 that are currently active in the database. The pseudo-type 3093 EFI_HII_PACKAGE_TYPE_ALL will cause all package handles to be listed. 3094 3095 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL 3096 instance. 3097 @param PackageType Specifies the package type of the packages to list 3098 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be 3099 listed. 3100 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then 3101 this is the pointer to the GUID which must match 3102 the Guid field of EFI_HII_GUID_PACKAGE_GUID_HDR. 3103 Otherwise, it must be NULL. 3104 @param HandleBufferLength On input, a pointer to the length of the handle 3105 buffer. On output, the length of the handle 3106 buffer that is required for the handles found. 3107 @param Handle An array of EFI_HII_HANDLE instances returned. 3108 3109 @retval EFI_SUCCESS The matching handles are outputed successfully. 3110 HandleBufferLength is updated with the actual length. 3111 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that 3112 Handle is too small to support the number of 3113 handles. HandleBufferLength is updated with a 3114 value that will enable the data to fit. 3115 @retval EFI_NOT_FOUND No matching handle could not be found in database. 3116 @retval EFI_INVALID_PARAMETER HandleBufferLength was NULL. 3117 @retval EFI_INVALID_PARAMETER The value referenced by HandleBufferLength was not 3118 zero and Handle was NULL. 3119 @retval EFI_INVALID_PARAMETER PackageType is not a EFI_HII_PACKAGE_TYPE_GUID but 3120 PackageGuid is not NULL, PackageType is a EFI_HII_ 3121 PACKAGE_TYPE_GUID but PackageGuid is NULL. 3122 3123 **/ 3124 EFI_STATUS 3125 EFIAPI 3126 HiiListPackageLists ( 3127 IN CONST EFI_HII_DATABASE_PROTOCOL *This, 3128 IN UINT8 PackageType, 3129 IN CONST EFI_GUID *PackageGuid, 3130 IN OUT UINTN *HandleBufferLength, 3131 OUT EFI_HII_HANDLE *Handle 3132 ) 3133 { 3134 HII_GUID_PACKAGE_INSTANCE *GuidPackage; 3135 HII_DATABASE_PRIVATE_DATA *Private; 3136 HII_DATABASE_RECORD *Node; 3137 LIST_ENTRY *Link; 3138 BOOLEAN Matched; 3139 HII_HANDLE **Result; 3140 UINTN ResultSize; 3141 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList; 3142 LIST_ENTRY *Link1; 3143 3144 // 3145 // Check input parameters 3146 // 3147 if (This == NULL || HandleBufferLength == NULL) { 3148 return EFI_INVALID_PARAMETER; 3149 } 3150 if (*HandleBufferLength > 0 && Handle == NULL) { 3151 return EFI_INVALID_PARAMETER; 3152 } 3153 if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) || 3154 (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) { 3155 return EFI_INVALID_PARAMETER; 3156 } 3157 3158 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This); 3159 Matched = FALSE; 3160 Result = (HII_HANDLE **) Handle; 3161 ResultSize = 0; 3162 3163 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) { 3164 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE); 3165 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList); 3166 switch (PackageType) { 3167 case EFI_HII_PACKAGE_TYPE_GUID: 3168 for (Link1 = PackageList->GuidPkgHdr.ForwardLink; Link1 != &PackageList->GuidPkgHdr; Link1 = Link1->ForwardLink) { 3169 GuidPackage = CR (Link1, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE); 3170 if (CompareGuid ( 3171 (EFI_GUID *) PackageGuid, 3172 (EFI_GUID *) (GuidPackage->GuidPkg + sizeof (EFI_HII_PACKAGE_HEADER)) 3173 )) { 3174 Matched = TRUE; 3175 break; 3176 } 3177 } 3178 break; 3179 case EFI_HII_PACKAGE_FORMS: 3180 if (!IsListEmpty (&PackageList->FormPkgHdr)) { 3181 Matched = TRUE; 3182 } 3183 break; 3184 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT: 3185 if (!IsListEmpty (&PackageList->KeyboardLayoutHdr)) { 3186 Matched = TRUE; 3187 } 3188 break; 3189 case EFI_HII_PACKAGE_STRINGS: 3190 if (!IsListEmpty (&PackageList->StringPkgHdr)) { 3191 Matched = TRUE; 3192 } 3193 break; 3194 case EFI_HII_PACKAGE_FONTS: 3195 if (!IsListEmpty (&PackageList->FontPkgHdr)) { 3196 Matched = TRUE; 3197 } 3198 break; 3199 case EFI_HII_PACKAGE_IMAGES: 3200 if (PackageList->ImagePkg != NULL) { 3201 Matched = TRUE; 3202 } 3203 break; 3204 case EFI_HII_PACKAGE_SIMPLE_FONTS: 3205 if (!IsListEmpty (&PackageList->SimpleFontPkgHdr)) { 3206 Matched = TRUE; 3207 } 3208 break; 3209 case EFI_HII_PACKAGE_DEVICE_PATH: 3210 if (PackageList->DevicePathPkg != NULL) { 3211 Matched = TRUE; 3212 } 3213 break; 3214 // 3215 // Pesudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package handles 3216 // to be listed. 3217 // 3218 case EFI_HII_PACKAGE_TYPE_ALL: 3219 Matched = TRUE; 3220 break; 3221 default: 3222 break; 3223 } 3224 3225 // 3226 // This active package list has the specified package type, list it. 3227 // 3228 if (Matched) { 3229 ResultSize += sizeof (EFI_HII_HANDLE); 3230 if (ResultSize <= *HandleBufferLength) { 3231 *Result++ = Node->Handle; 3232 } 3233 } 3234 Matched = FALSE; 3235 } 3236 3237 if (ResultSize == 0) { 3238 return EFI_NOT_FOUND; 3239 } 3240 3241 if (*HandleBufferLength < ResultSize) { 3242 *HandleBufferLength = ResultSize; 3243 return EFI_BUFFER_TOO_SMALL; 3244 } 3245 3246 *HandleBufferLength = ResultSize; 3247 return EFI_SUCCESS; 3248 } 3249 3250 3251 /** 3252 This function will export one or all package lists in the database to a buffer. 3253 For each package list exported, this function will call functions registered 3254 with EXPORT_PACK and then copy the package list to the buffer. 3255 3256 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL 3257 instance. 3258 @param Handle An EFI_HII_HANDLE that corresponds to the desired 3259 package list in the HII database to export or NULL 3260 to indicate all package lists should be exported. 3261 @param BufferSize On input, a pointer to the length of the buffer. 3262 On output, the length of the buffer that is 3263 required for the exported data. 3264 @param Buffer A pointer to a buffer that will contain the 3265 results of the export function. 3266 3267 @retval EFI_SUCCESS Package exported. 3268 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that 3269 Handle is too small to support the number of 3270 handles. HandleBufferLength is updated with a 3271 value that will enable the data to fit. 3272 @retval EFI_NOT_FOUND The specifiecd Handle could not be found in the 3273 current database. 3274 @retval EFI_INVALID_PARAMETER BufferSize was NULL. 3275 @retval EFI_INVALID_PARAMETER The value referenced by BufferSize was not zero 3276 and Buffer was NULL. 3277 3278 **/ 3279 EFI_STATUS 3280 EFIAPI 3281 HiiExportPackageLists ( 3282 IN CONST EFI_HII_DATABASE_PROTOCOL *This, 3283 IN EFI_HII_HANDLE Handle, 3284 IN OUT UINTN *BufferSize, 3285 OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer 3286 ) 3287 { 3288 LIST_ENTRY *Link; 3289 EFI_STATUS Status; 3290 HII_DATABASE_PRIVATE_DATA *Private; 3291 HII_DATABASE_RECORD *Node; 3292 UINTN UsedSize; 3293 3294 if (This == NULL || BufferSize == NULL) { 3295 return EFI_INVALID_PARAMETER; 3296 } 3297 if (*BufferSize > 0 && Buffer == NULL) { 3298 return EFI_INVALID_PARAMETER; 3299 } 3300 if ((Handle != NULL) && (!IsHiiHandleValid (Handle))) { 3301 return EFI_NOT_FOUND; 3302 } 3303 3304 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This); 3305 UsedSize = 0; 3306 3307 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) { 3308 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE); 3309 if (Handle == NULL) { 3310 // 3311 // Export all package lists in current hii database. 3312 // 3313 Status = ExportPackageList ( 3314 Private, 3315 Node->Handle, 3316 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList), 3317 &UsedSize, 3318 *BufferSize, 3319 (EFI_HII_PACKAGE_LIST_HEADER *)((UINT8 *) Buffer + UsedSize) 3320 ); 3321 ASSERT_EFI_ERROR (Status); 3322 } else if (Handle != NULL && Node->Handle == Handle) { 3323 Status = ExportPackageList ( 3324 Private, 3325 Handle, 3326 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList), 3327 &UsedSize, 3328 *BufferSize, 3329 Buffer 3330 ); 3331 ASSERT_EFI_ERROR (Status); 3332 if (*BufferSize < UsedSize) { 3333 *BufferSize = UsedSize; 3334 return EFI_BUFFER_TOO_SMALL; 3335 } 3336 return EFI_SUCCESS; 3337 } 3338 } 3339 3340 if (Handle == NULL && UsedSize != 0) { 3341 if (*BufferSize < UsedSize) { 3342 *BufferSize = UsedSize; 3343 return EFI_BUFFER_TOO_SMALL; 3344 } 3345 return EFI_SUCCESS; 3346 } 3347 3348 return EFI_NOT_FOUND; 3349 } 3350 3351 3352 /** 3353 This function registers a function which will be called when specified actions related to packages of 3354 the specified type occur in the HII database. By registering a function, other HII-related drivers are 3355 notified when specific package types are added, removed or updated in the HII database. 3356 Each driver or application which registers a notification should use 3357 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify() before exiting. 3358 3359 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL 3360 instance. 3361 @param PackageType Specifies the package type of the packages to list 3362 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be 3363 listed. 3364 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then 3365 this is the pointer to the GUID which must match 3366 the Guid field of 3367 EFI_HII_GUID_PACKAGE_GUID_HDR. Otherwise, it must 3368 be NULL. 3369 @param PackageNotifyFn Points to the function to be called when the event 3370 specified by 3371 NotificationType occurs. 3372 @param NotifyType Describes the types of notification which this 3373 function will be receiving. 3374 @param NotifyHandle Points to the unique handle assigned to the 3375 registered notification. Can be used in 3376 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify() 3377 to stop notifications. 3378 3379 @retval EFI_SUCCESS Notification registered successfully. 3380 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures 3381 @retval EFI_INVALID_PARAMETER NotifyHandle is NULL. 3382 @retval EFI_INVALID_PARAMETER PackageGuid is not NULL when PackageType is not 3383 EFI_HII_PACKAGE_TYPE_GUID. 3384 @retval EFI_INVALID_PARAMETER PackageGuid is NULL when PackageType is 3385 EFI_HII_PACKAGE_TYPE_GUID. 3386 3387 **/ 3388 EFI_STATUS 3389 EFIAPI 3390 HiiRegisterPackageNotify ( 3391 IN CONST EFI_HII_DATABASE_PROTOCOL *This, 3392 IN UINT8 PackageType, 3393 IN CONST EFI_GUID *PackageGuid, 3394 IN CONST EFI_HII_DATABASE_NOTIFY PackageNotifyFn, 3395 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, 3396 OUT EFI_HANDLE *NotifyHandle 3397 ) 3398 { 3399 HII_DATABASE_PRIVATE_DATA *Private; 3400 HII_DATABASE_NOTIFY *Notify; 3401 EFI_STATUS Status; 3402 3403 if (This == NULL || NotifyHandle == NULL) { 3404 return EFI_INVALID_PARAMETER; 3405 } 3406 if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) || 3407 (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) { 3408 return EFI_INVALID_PARAMETER; 3409 } 3410 3411 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This); 3412 3413 // 3414 // Allocate a notification node 3415 // 3416 Notify = (HII_DATABASE_NOTIFY *) AllocateZeroPool (sizeof (HII_DATABASE_NOTIFY)); 3417 if (Notify == NULL) { 3418 return EFI_OUT_OF_RESOURCES; 3419 } 3420 3421 // 3422 // Generate a notify handle 3423 // 3424 Status = gBS->InstallMultipleProtocolInterfaces ( 3425 &Notify->NotifyHandle, 3426 &gEfiCallerIdGuid, 3427 NULL, 3428 NULL 3429 ); 3430 ASSERT_EFI_ERROR (Status); 3431 3432 // 3433 // Fill in the information to the notification node 3434 // 3435 Notify->Signature = HII_DATABASE_NOTIFY_SIGNATURE; 3436 Notify->PackageType = PackageType; 3437 Notify->PackageGuid = (EFI_GUID *) PackageGuid; 3438 Notify->PackageNotifyFn = (EFI_HII_DATABASE_NOTIFY) PackageNotifyFn; 3439 Notify->NotifyType = NotifyType; 3440 3441 InsertTailList (&Private->DatabaseNotifyList, &Notify->DatabaseNotifyEntry); 3442 *NotifyHandle = Notify->NotifyHandle; 3443 3444 return EFI_SUCCESS; 3445 } 3446 3447 3448 /** 3449 Removes the specified HII database package-related notification. 3450 3451 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL 3452 instance. 3453 @param NotificationHandle The handle of the notification function being 3454 unregistered. 3455 3456 @retval EFI_SUCCESS Notification is unregistered successfully. 3457 @retval EFI_INVALID_PARAMETER The Handle is invalid. 3458 @retval EFI_NOT_FOUND The incoming notification handle does not exist 3459 in current hii database. 3460 3461 **/ 3462 EFI_STATUS 3463 EFIAPI 3464 HiiUnregisterPackageNotify ( 3465 IN CONST EFI_HII_DATABASE_PROTOCOL *This, 3466 IN EFI_HANDLE NotificationHandle 3467 ) 3468 { 3469 HII_DATABASE_PRIVATE_DATA *Private; 3470 HII_DATABASE_NOTIFY *Notify; 3471 LIST_ENTRY *Link; 3472 EFI_STATUS Status; 3473 3474 if (This == NULL) { 3475 return EFI_INVALID_PARAMETER; 3476 } 3477 3478 if (NotificationHandle == NULL) { 3479 return EFI_NOT_FOUND; 3480 } 3481 3482 Status = gBS->OpenProtocol ( 3483 NotificationHandle, 3484 &gEfiCallerIdGuid, 3485 NULL, 3486 NULL, 3487 NULL, 3488 EFI_OPEN_PROTOCOL_TEST_PROTOCOL 3489 ); 3490 if (EFI_ERROR (Status)) { 3491 return EFI_NOT_FOUND; 3492 } 3493 3494 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This); 3495 3496 for (Link = Private->DatabaseNotifyList.ForwardLink; Link != &Private->DatabaseNotifyList; Link = Link->ForwardLink) { 3497 Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE); 3498 if (Notify->NotifyHandle == NotificationHandle) { 3499 // 3500 // Remove the matching notification node 3501 // 3502 RemoveEntryList (&Notify->DatabaseNotifyEntry); 3503 Status = gBS->UninstallMultipleProtocolInterfaces ( 3504 Notify->NotifyHandle, 3505 &gEfiCallerIdGuid, 3506 NULL, 3507 NULL 3508 ); 3509 ASSERT_EFI_ERROR (Status); 3510 FreePool (Notify); 3511 3512 return EFI_SUCCESS; 3513 } 3514 } 3515 3516 return EFI_NOT_FOUND; 3517 } 3518 3519 3520 /** 3521 This routine retrieves an array of GUID values for each keyboard layout that 3522 was previously registered in the system. 3523 3524 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL 3525 instance. 3526 @param KeyGuidBufferLength On input, a pointer to the length of the keyboard 3527 GUID buffer. On output, the length of the handle 3528 buffer that is required for the handles found. 3529 @param KeyGuidBuffer An array of keyboard layout GUID instances 3530 returned. 3531 3532 @retval EFI_SUCCESS KeyGuidBuffer was updated successfully. 3533 @retval EFI_BUFFER_TOO_SMALL The KeyGuidBufferLength parameter indicates 3534 that KeyGuidBuffer is too small to support the 3535 number of GUIDs. KeyGuidBufferLength is 3536 updated with a value that will enable the data to 3537 fit. 3538 @retval EFI_INVALID_PARAMETER The KeyGuidBufferLength is NULL. 3539 @retval EFI_INVALID_PARAMETER The value referenced by KeyGuidBufferLength is not 3540 zero and KeyGuidBuffer is NULL. 3541 @retval EFI_NOT_FOUND There was no keyboard layout. 3542 3543 **/ 3544 EFI_STATUS 3545 EFIAPI 3546 HiiFindKeyboardLayouts ( 3547 IN CONST EFI_HII_DATABASE_PROTOCOL *This, 3548 IN OUT UINT16 *KeyGuidBufferLength, 3549 OUT EFI_GUID *KeyGuidBuffer 3550 ) 3551 { 3552 HII_DATABASE_PRIVATE_DATA *Private; 3553 HII_DATABASE_RECORD *Node; 3554 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList; 3555 LIST_ENTRY *Link; 3556 LIST_ENTRY *Link1; 3557 UINT16 ResultSize; 3558 UINTN Index; 3559 UINT16 LayoutCount; 3560 UINT16 LayoutLength; 3561 UINT8 *Layout; 3562 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package; 3563 3564 if (This == NULL || KeyGuidBufferLength == NULL) { 3565 return EFI_INVALID_PARAMETER; 3566 } 3567 3568 if (*KeyGuidBufferLength > 0 && KeyGuidBuffer == NULL) { 3569 return EFI_INVALID_PARAMETER; 3570 } 3571 3572 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This); 3573 ResultSize = 0; 3574 3575 // 3576 // Search all package lists in whole database to retrieve keyboard layout. 3577 // 3578 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) { 3579 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE); 3580 PackageList = Node->PackageList; 3581 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink; 3582 Link1 != &PackageList->KeyboardLayoutHdr; 3583 Link1 = Link1->ForwardLink 3584 ) { 3585 // 3586 // Find out all Keyboard Layout packages in this package list. 3587 // 3588 Package = CR ( 3589 Link1, 3590 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE, 3591 KeyboardEntry, 3592 HII_KB_LAYOUT_PACKAGE_SIGNATURE 3593 ); 3594 Layout = (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16); 3595 CopyMem ( 3596 &LayoutCount, 3597 (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER), 3598 sizeof (UINT16) 3599 ); 3600 for (Index = 0; Index < LayoutCount; Index++) { 3601 ResultSize += sizeof (EFI_GUID); 3602 if (ResultSize <= *KeyGuidBufferLength) { 3603 CopyMem (KeyGuidBuffer + (ResultSize / sizeof (EFI_GUID) - 1), Layout + sizeof (UINT16), sizeof (EFI_GUID)); 3604 CopyMem (&LayoutLength, Layout, sizeof (UINT16)); 3605 Layout = Layout + LayoutLength; 3606 } 3607 } 3608 } 3609 } 3610 3611 if (ResultSize == 0) { 3612 return EFI_NOT_FOUND; 3613 } 3614 3615 if (*KeyGuidBufferLength < ResultSize) { 3616 *KeyGuidBufferLength = ResultSize; 3617 return EFI_BUFFER_TOO_SMALL; 3618 } 3619 3620 *KeyGuidBufferLength = ResultSize; 3621 return EFI_SUCCESS; 3622 } 3623 3624 3625 /** 3626 This routine retrieves the requested keyboard layout. The layout is a physical description of the keys 3627 on a keyboard and the character(s) that are associated with a particular set of key strokes. 3628 3629 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL 3630 instance. 3631 @param KeyGuid A pointer to the unique ID associated with a given 3632 keyboard layout. If KeyGuid is NULL then the 3633 current layout will be retrieved. 3634 @param KeyboardLayoutLength On input, a pointer to the length of the 3635 KeyboardLayout buffer. On output, the length of 3636 the data placed into KeyboardLayout. 3637 @param KeyboardLayout A pointer to a buffer containing the retrieved 3638 keyboard layout. 3639 3640 @retval EFI_SUCCESS The keyboard layout was retrieved successfully. 3641 @retval EFI_NOT_FOUND The requested keyboard layout was not found. 3642 @retval EFI_INVALID_PARAMETER The KeyboardLayout or KeyboardLayoutLength was 3643 NULL. 3644 @retval EFI_BUFFER_TOO_SMALL The KeyboardLayoutLength parameter indicates 3645 that KeyboardLayout is too small to support the 3646 requested keyboard layout. KeyboardLayoutLength is 3647 updated with a value that will enable the 3648 data to fit. 3649 3650 **/ 3651 EFI_STATUS 3652 EFIAPI 3653 HiiGetKeyboardLayout ( 3654 IN CONST EFI_HII_DATABASE_PROTOCOL *This, 3655 IN CONST EFI_GUID *KeyGuid, 3656 IN OUT UINT16 *KeyboardLayoutLength, 3657 OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout 3658 ) 3659 { 3660 HII_DATABASE_PRIVATE_DATA *Private; 3661 HII_DATABASE_RECORD *Node; 3662 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList; 3663 LIST_ENTRY *Link; 3664 LIST_ENTRY *Link1; 3665 UINTN Index; 3666 UINT8 *Layout; 3667 UINT16 LayoutCount; 3668 UINT16 LayoutLength; 3669 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package; 3670 3671 if (This == NULL || KeyboardLayoutLength == NULL) { 3672 return EFI_INVALID_PARAMETER; 3673 } 3674 if (*KeyboardLayoutLength > 0 && KeyboardLayout == NULL) { 3675 return EFI_INVALID_PARAMETER; 3676 } 3677 3678 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This); 3679 // 3680 // Retrieve the current keyboard layout. 3681 // 3682 if (KeyGuid == NULL) { 3683 if (Private->CurrentLayout == NULL) { 3684 return EFI_NOT_FOUND; 3685 } 3686 CopyMem (&LayoutLength, Private->CurrentLayout, sizeof (UINT16)); 3687 if (*KeyboardLayoutLength < LayoutLength) { 3688 *KeyboardLayoutLength = LayoutLength; 3689 return EFI_BUFFER_TOO_SMALL; 3690 } 3691 CopyMem (KeyboardLayout, Private->CurrentLayout, LayoutLength); 3692 return EFI_SUCCESS; 3693 } 3694 3695 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) { 3696 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE); 3697 PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList); 3698 for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink; 3699 Link1 != &PackageList->KeyboardLayoutHdr; 3700 Link1 = Link1->ForwardLink 3701 ) { 3702 Package = CR ( 3703 Link1, 3704 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE, 3705 KeyboardEntry, 3706 HII_KB_LAYOUT_PACKAGE_SIGNATURE 3707 ); 3708 3709 Layout = (UINT8 *) Package->KeyboardPkg + 3710 sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16); 3711 CopyMem (&LayoutCount, Layout - sizeof (UINT16), sizeof (UINT16)); 3712 for (Index = 0; Index < LayoutCount; Index++) { 3713 CopyMem (&LayoutLength, Layout, sizeof (UINT16)); 3714 if (CompareMem (Layout + sizeof (UINT16), KeyGuid, sizeof (EFI_GUID)) == 0) { 3715 if (LayoutLength <= *KeyboardLayoutLength) { 3716 CopyMem (KeyboardLayout, Layout, LayoutLength); 3717 return EFI_SUCCESS; 3718 } else { 3719 *KeyboardLayoutLength = LayoutLength; 3720 return EFI_BUFFER_TOO_SMALL; 3721 } 3722 } 3723 Layout = Layout + LayoutLength; 3724 } 3725 } 3726 } 3727 3728 return EFI_NOT_FOUND; 3729 } 3730 3731 3732 /** 3733 This routine sets the default keyboard layout to the one referenced by KeyGuid. When this routine 3734 is called, an event will be signaled of the EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID 3735 group type. This is so that agents which are sensitive to the current keyboard layout being changed 3736 can be notified of this change. 3737 3738 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL 3739 instance. 3740 @param KeyGuid A pointer to the unique ID associated with a given 3741 keyboard layout. 3742 3743 @retval EFI_SUCCESS The current keyboard layout was successfully set. 3744 @retval EFI_NOT_FOUND The referenced keyboard layout was not found, so 3745 action was taken. 3746 @retval EFI_INVALID_PARAMETER The KeyGuid was NULL. 3747 3748 **/ 3749 EFI_STATUS 3750 EFIAPI 3751 HiiSetKeyboardLayout ( 3752 IN CONST EFI_HII_DATABASE_PROTOCOL *This, 3753 IN CONST EFI_GUID *KeyGuid 3754 ) 3755 { 3756 HII_DATABASE_PRIVATE_DATA *Private; 3757 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout; 3758 UINT16 KeyboardLayoutLength; 3759 EFI_STATUS Status; 3760 3761 if (This == NULL || KeyGuid == NULL) { 3762 return EFI_INVALID_PARAMETER; 3763 } 3764 3765 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This); 3766 3767 // 3768 // The specified GUID equals the current keyboard layout GUID, 3769 // return directly. 3770 // 3771 if (CompareGuid (&Private->CurrentLayoutGuid, KeyGuid)) { 3772 return EFI_SUCCESS; 3773 } 3774 3775 // 3776 // Try to find the incoming keyboard layout data in current database. 3777 // 3778 KeyboardLayoutLength = 0; 3779 KeyboardLayout = NULL; 3780 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout); 3781 if (Status != EFI_BUFFER_TOO_SMALL) { 3782 return Status; 3783 } 3784 3785 KeyboardLayout = (EFI_HII_KEYBOARD_LAYOUT *) AllocateZeroPool (KeyboardLayoutLength); 3786 ASSERT (KeyboardLayout != NULL); 3787 Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout); 3788 ASSERT_EFI_ERROR (Status); 3789 3790 // 3791 // Backup current keyboard layout. 3792 // 3793 CopyMem (&Private->CurrentLayoutGuid, KeyGuid, sizeof (EFI_GUID)); 3794 if (Private->CurrentLayout != NULL) { 3795 FreePool(Private->CurrentLayout); 3796 } 3797 Private->CurrentLayout = KeyboardLayout; 3798 3799 // 3800 // Signal EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group to notify 3801 // current keyboard layout is changed. 3802 // 3803 Status = gBS->SignalEvent (gHiiKeyboardLayoutChanged); 3804 ASSERT_EFI_ERROR (Status); 3805 3806 return EFI_SUCCESS; 3807 } 3808 3809 3810 /** 3811 Return the EFI handle associated with a package list. 3812 3813 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL 3814 instance. 3815 @param PackageListHandle An EFI_HII_HANDLE that corresponds to the desired 3816 package list in the HIIdatabase. 3817 @param DriverHandle On return, contains the EFI_HANDLE which was 3818 registered with the package list in 3819 NewPackageList(). 3820 3821 @retval EFI_SUCCESS The DriverHandle was returned successfully. 3822 @retval EFI_INVALID_PARAMETER The PackageListHandle was not valid or 3823 DriverHandle was NULL. 3824 @retval EFI_NOT_FOUND This PackageList handle can not be found in 3825 current database. 3826 3827 **/ 3828 EFI_STATUS 3829 EFIAPI 3830 HiiGetPackageListHandle ( 3831 IN CONST EFI_HII_DATABASE_PROTOCOL *This, 3832 IN EFI_HII_HANDLE PackageListHandle, 3833 OUT EFI_HANDLE *DriverHandle 3834 ) 3835 { 3836 HII_DATABASE_PRIVATE_DATA *Private; 3837 HII_DATABASE_RECORD *Node; 3838 LIST_ENTRY *Link; 3839 3840 if (This == NULL || DriverHandle == NULL) { 3841 return EFI_INVALID_PARAMETER; 3842 } 3843 3844 if (!IsHiiHandleValid (PackageListHandle)) { 3845 return EFI_INVALID_PARAMETER; 3846 } 3847 3848 Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This); 3849 3850 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) { 3851 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE); 3852 if (Node->Handle == PackageListHandle) { 3853 *DriverHandle = Node->DriverHandle; 3854 return EFI_SUCCESS; 3855 } 3856 } 3857 3858 return EFI_NOT_FOUND; 3859 } 3860 3861