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