1 /** @file 2 Main file for Dh shell Driver1 function. 3 4 (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR> 5 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #include "UefiShellDriver1CommandsLib.h" 17 18 STATIC CONST SHELL_PARAM_ITEM ParamList[] = { 19 {L"-p", TypeValue}, 20 {L"-d", TypeFlag}, 21 {L"-v", TypeFlag}, 22 {L"-verbose", TypeFlag}, 23 {L"-sfo", TypeFlag}, 24 {L"-l", TypeValue}, 25 {NULL, TypeMax} 26 }; 27 28 STATIC CONST EFI_GUID *UefiDriverModelProtocolsGuidArray[] = { 29 &gEfiDriverBindingProtocolGuid, 30 &gEfiPlatformDriverOverrideProtocolGuid, 31 &gEfiBusSpecificDriverOverrideProtocolGuid, 32 &gEfiDriverDiagnosticsProtocolGuid, 33 &gEfiDriverDiagnostics2ProtocolGuid, 34 &gEfiComponentNameProtocolGuid, 35 &gEfiComponentName2ProtocolGuid, 36 &gEfiPlatformToDriverConfigurationProtocolGuid, 37 &gEfiDriverSupportedEfiVersionProtocolGuid, 38 &gEfiDriverFamilyOverrideProtocolGuid, 39 &gEfiDriverHealthProtocolGuid, 40 &gEfiLoadedImageProtocolGuid, 41 NULL 42 }; 43 44 /** 45 Get the name of a driver by it's handle. 46 47 If a name is found the memory must be callee freed. 48 49 @param[in] TheHandle The driver's handle. 50 @param[in] Language The language to use. 51 @param[in] NameFound Upon a successful return the name found. 52 53 @retval EFI_SUCCESS The name was found. 54 **/ 55 EFI_STATUS 56 GetDriverName ( 57 IN EFI_HANDLE TheHandle, 58 IN CONST CHAR8 *Language, 59 IN CHAR16 **NameFound 60 ) 61 { 62 CHAR8 *Lang; 63 EFI_STATUS Status; 64 EFI_COMPONENT_NAME2_PROTOCOL *CompName2; 65 CHAR16 *NameToReturn; 66 // 67 // Go through those handles until we get one that passes for GetComponentName 68 // 69 Status = gBS->OpenProtocol( 70 TheHandle, 71 &gEfiComponentName2ProtocolGuid, 72 (VOID**)&CompName2, 73 gImageHandle, 74 NULL, 75 EFI_OPEN_PROTOCOL_GET_PROTOCOL); 76 if (EFI_ERROR(Status)) { 77 Status = gBS->OpenProtocol( 78 TheHandle, 79 &gEfiComponentNameProtocolGuid, 80 (VOID**)&CompName2, 81 gImageHandle, 82 NULL, 83 EFI_OPEN_PROTOCOL_GET_PROTOCOL); 84 } 85 86 if (EFI_ERROR(Status)) { 87 return (EFI_NOT_FOUND); 88 } 89 Lang = GetBestLanguageForDriver (CompName2->SupportedLanguages, Language, FALSE); 90 Status = CompName2->GetDriverName(CompName2, Lang, &NameToReturn); 91 FreePool(Lang); 92 93 if (!EFI_ERROR(Status) && NameToReturn != NULL) { 94 *NameFound = NULL; 95 StrnCatGrow(NameFound, NULL, NameToReturn, 0); 96 } 97 return (Status); 98 } 99 100 /** 101 Discover if a protocol guid is one of the UEFI Driver Model Protocols. 102 103 @param[in] Guid The guid to test. 104 105 @retval TRUE The guid does represent a driver model protocol. 106 @retval FALSE The guid does not represent a driver model protocol. 107 **/ 108 BOOLEAN 109 IsDriverProt ( 110 IN CONST EFI_GUID *Guid 111 ) 112 { 113 CONST EFI_GUID **GuidWalker; 114 BOOLEAN GuidFound; 115 GuidFound = FALSE; 116 for (GuidWalker = UefiDriverModelProtocolsGuidArray 117 ; GuidWalker != NULL && *GuidWalker != NULL 118 ; GuidWalker++ 119 ){ 120 if (CompareGuid(*GuidWalker, Guid)) { 121 GuidFound = TRUE; 122 break; 123 } 124 } 125 return (GuidFound); 126 } 127 128 /** 129 Get information for a handle. 130 131 @param[in] TheHandle The handles to show info on. 132 @param[in] Language Language string per UEFI specification. 133 @param[in] Separator Separator string between information blocks. 134 @param[in] Verbose TRUE for extra info, FALSE otherwise. 135 @param[in] ExtraInfo TRUE for extra info, FALSE otherwise. 136 137 @retval SHELL_SUCCESS The operation was successful. 138 @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid. 139 **/ 140 CHAR16* 141 GetProtocolInfoString( 142 IN CONST EFI_HANDLE TheHandle, 143 IN CONST CHAR8 *Language, 144 IN CONST CHAR16 *Separator, 145 IN CONST BOOLEAN Verbose, 146 IN CONST BOOLEAN ExtraInfo 147 ) 148 { 149 EFI_GUID **ProtocolGuidArray; 150 UINTN ArrayCount; 151 UINTN ProtocolIndex; 152 EFI_STATUS Status; 153 CHAR16 *RetVal; 154 UINTN Size; 155 CHAR16 *Temp; 156 157 ProtocolGuidArray = NULL; 158 RetVal = NULL; 159 Size = 0; 160 161 Status = gBS->ProtocolsPerHandle ( 162 TheHandle, 163 &ProtocolGuidArray, 164 &ArrayCount 165 ); 166 if (!EFI_ERROR (Status)) { 167 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) { 168 Temp = GetStringNameFromGuid(ProtocolGuidArray[ProtocolIndex], Language); 169 if (Temp != NULL) { 170 ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL)); 171 if (Size != 0) { 172 StrnCatGrow(&RetVal, &Size, Separator, 0); 173 } 174 StrnCatGrow(&RetVal, &Size, L"%H", 0); 175 StrnCatGrow(&RetVal, &Size, Temp, 0); 176 StrnCatGrow(&RetVal, &Size, L"%N", 0); 177 FreePool(Temp); 178 } 179 if (ExtraInfo) { 180 Temp = GetProtocolInformationDump(TheHandle, ProtocolGuidArray[ProtocolIndex], Verbose); 181 if (Temp != NULL) { 182 ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL)); 183 if (!Verbose) { 184 StrnCatGrow(&RetVal, &Size, L"(", 0); 185 StrnCatGrow(&RetVal, &Size, Temp, 0); 186 StrnCatGrow(&RetVal, &Size, L")\r\n", 0); 187 } else { 188 StrnCatGrow(&RetVal, &Size, Separator, 0); 189 StrnCatGrow(&RetVal, &Size, Temp, 0); 190 } 191 FreePool(Temp); 192 } 193 } 194 } 195 } 196 197 SHELL_FREE_NON_NULL(ProtocolGuidArray); 198 199 if (RetVal == NULL) { 200 return (NULL); 201 } 202 203 ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL)); 204 StrnCatGrow(&RetVal, &Size, Separator, 0); 205 return (RetVal); 206 } 207 208 /** 209 Gets the name of the loaded image. 210 211 @param[in] TheHandle The handle of the driver to get info on. 212 @param[out] Name The pointer to the pointer. Valid upon a successful return. 213 214 @retval EFI_SUCCESS The operation was successful. 215 **/ 216 EFI_STATUS 217 GetDriverImageName ( 218 IN EFI_HANDLE TheHandle, 219 OUT CHAR16 **Name 220 ) 221 { 222 // get loaded image and devicepathtotext on image->Filepath 223 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; 224 EFI_STATUS Status; 225 EFI_DEVICE_PATH_PROTOCOL *DevicePath; 226 227 if (TheHandle == NULL || Name == NULL) { 228 return (EFI_INVALID_PARAMETER); 229 } 230 231 Status = gBS->OpenProtocol ( 232 TheHandle, 233 &gEfiLoadedImageProtocolGuid, 234 (VOID **) &LoadedImage, 235 gImageHandle, 236 NULL, 237 EFI_OPEN_PROTOCOL_GET_PROTOCOL 238 ); 239 if (EFI_ERROR(Status)) { 240 return (Status); 241 } 242 DevicePath = LoadedImage->FilePath; 243 *Name = ConvertDevicePathToText(DevicePath, TRUE, TRUE); 244 return (EFI_SUCCESS); 245 } 246 247 /** 248 Display driver model information for a given handle. 249 250 @param[in] Handle The handle to display info on. 251 @param[in] BestName Use the best name? 252 @param[in] Language The language to output in. 253 **/ 254 EFI_STATUS 255 DisplayDriverModelHandle ( 256 IN EFI_HANDLE Handle, 257 IN BOOLEAN BestName, 258 IN CONST CHAR8 *Language OPTIONAL 259 ) 260 { 261 EFI_STATUS Status; 262 BOOLEAN ConfigurationStatus; 263 BOOLEAN DiagnosticsStatus; 264 UINTN DriverBindingHandleCount; 265 EFI_HANDLE *DriverBindingHandleBuffer; 266 UINTN ParentControllerHandleCount; 267 EFI_HANDLE *ParentControllerHandleBuffer; 268 UINTN ChildControllerHandleCount; 269 EFI_HANDLE *ChildControllerHandleBuffer; 270 CHAR16 *TempStringPointer; 271 EFI_DEVICE_PATH_PROTOCOL *DevicePath; 272 UINTN Index; 273 CHAR16 *DriverName; 274 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 275 UINTN NumberOfChildren; 276 UINTN HandleIndex; 277 UINTN ControllerHandleCount; 278 EFI_HANDLE *ControllerHandleBuffer; 279 UINTN ChildIndex; 280 BOOLEAN Image; 281 282 DriverName = NULL; 283 284 // 285 // See if Handle is a device handle and display its details. 286 // 287 DriverBindingHandleBuffer = NULL; 288 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS ( 289 Handle, 290 &DriverBindingHandleCount, 291 &DriverBindingHandleBuffer 292 ); 293 294 ParentControllerHandleBuffer = NULL; 295 Status = PARSE_HANDLE_DATABASE_PARENTS ( 296 Handle, 297 &ParentControllerHandleCount, 298 &ParentControllerHandleBuffer 299 ); 300 301 ChildControllerHandleBuffer = NULL; 302 Status = ParseHandleDatabaseForChildControllers ( 303 Handle, 304 &ChildControllerHandleCount, 305 &ChildControllerHandleBuffer 306 ); 307 308 DiagnosticsStatus = FALSE; 309 ConfigurationStatus = FALSE; 310 311 if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverConfigurationProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) { 312 ConfigurationStatus = TRUE; 313 } 314 if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverConfiguration2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) { 315 ConfigurationStatus = TRUE; 316 } 317 if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverDiagnosticsProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) { 318 DiagnosticsStatus = TRUE; 319 } 320 if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverDiagnostics2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) { 321 DiagnosticsStatus = TRUE; 322 } 323 324 Status = EFI_SUCCESS; 325 326 if (DriverBindingHandleCount > 0 || ParentControllerHandleCount > 0 || ChildControllerHandleCount > 0) { 327 328 329 330 DevicePath = NULL; 331 TempStringPointer = NULL; 332 Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID**)&DevicePath); 333 334 Status = gEfiShellProtocol->GetDeviceName(Handle, EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer); 335 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DRIVER1), gShellDriver1HiiHandle, TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"); 336 SHELL_FREE_NON_NULL(TempStringPointer); 337 338 TempStringPointer = ConvertDevicePathToText(DevicePath, TRUE, FALSE); 339 ShellPrintHiiEx( 340 -1, 341 -1, 342 NULL, 343 STRING_TOKEN (STR_DH_OUTPUT_DRIVER2), 344 gShellDriver1HiiHandle, 345 TempStringPointer!=NULL?TempStringPointer:L"<None>", 346 ParentControllerHandleCount == 0?L"ROOT":(ChildControllerHandleCount > 0)?L"BUS":L"DEVICE", 347 ConfigurationStatus?L"YES":L"NO", 348 DiagnosticsStatus?L"YES":L"NO" 349 ); 350 351 SHELL_FREE_NON_NULL(TempStringPointer); 352 353 if (DriverBindingHandleCount == 0) { 354 ShellPrintHiiEx( 355 -1, 356 -1, 357 NULL, 358 STRING_TOKEN (STR_DH_OUTPUT_DRIVER3), 359 gShellDriver1HiiHandle, 360 L"<None>" 361 ); 362 } else { 363 ShellPrintHiiEx( 364 -1, 365 -1, 366 NULL, 367 STRING_TOKEN (STR_DH_OUTPUT_DRIVER3), 368 gShellDriver1HiiHandle, 369 L"" 370 ); 371 for (Index = 0; Index < DriverBindingHandleCount; Index++) { 372 Image = FALSE; 373 Status = GetDriverName ( 374 DriverBindingHandleBuffer[Index], 375 Language, 376 &DriverName 377 ); 378 if (EFI_ERROR (Status)) { 379 Status = GetDriverImageName ( 380 DriverBindingHandleBuffer[Index], 381 &DriverName 382 ); 383 if (EFI_ERROR (Status)) { 384 DriverName = NULL; 385 } 386 } 387 388 if (Image) { 389 ShellPrintHiiEx( 390 -1, 391 -1, 392 NULL, 393 STRING_TOKEN (STR_DH_OUTPUT_DRIVER4A), 394 gShellDriver1HiiHandle, 395 ConvertHandleToHandleIndex (DriverBindingHandleBuffer[Index]), 396 DriverName!=NULL?DriverName:L"<Unknown>" 397 ); 398 } else { 399 ShellPrintHiiEx( 400 -1, 401 -1, 402 NULL, 403 STRING_TOKEN (STR_DH_OUTPUT_DRIVER4B), 404 gShellDriver1HiiHandle, 405 ConvertHandleToHandleIndex (DriverBindingHandleBuffer[Index]), 406 DriverName!=NULL?DriverName:L"<Unknown>" 407 ); 408 } 409 SHELL_FREE_NON_NULL(DriverName); 410 } 411 } 412 413 if (ParentControllerHandleCount == 0) { 414 ShellPrintHiiEx( 415 -1, 416 -1, 417 NULL, 418 STRING_TOKEN (STR_DH_OUTPUT_DRIVER5), 419 gShellDriver1HiiHandle, 420 L"<None>" 421 ); 422 } else { 423 ShellPrintHiiEx( 424 -1, 425 -1, 426 NULL, 427 STRING_TOKEN (STR_DH_OUTPUT_DRIVER5), 428 gShellDriver1HiiHandle, 429 L"" 430 ); 431 for (Index = 0; Index < ParentControllerHandleCount; Index++) { 432 Status = gEfiShellProtocol->GetDeviceName(ParentControllerHandleBuffer[Index], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer); 433 ShellPrintHiiEx( 434 -1, 435 -1, 436 NULL, 437 STRING_TOKEN (STR_DH_OUTPUT_DRIVER5B), 438 gShellDriver1HiiHandle, 439 ConvertHandleToHandleIndex (ParentControllerHandleBuffer[Index]), 440 TempStringPointer!=NULL?TempStringPointer:L"<Unknown>" 441 ); 442 SHELL_FREE_NON_NULL(TempStringPointer); 443 } 444 } 445 446 if (ChildControllerHandleCount == 0) { 447 ShellPrintHiiEx( 448 -1, 449 -1, 450 NULL, 451 STRING_TOKEN (STR_DH_OUTPUT_DRIVER6), 452 gShellDriver1HiiHandle, 453 L"<None>" 454 ); 455 } else { 456 ShellPrintHiiEx( 457 -1, 458 -1, 459 NULL, 460 STRING_TOKEN (STR_DH_OUTPUT_DRIVER6), 461 gShellDriver1HiiHandle, 462 L"" 463 ); 464 for (Index = 0; Index < ChildControllerHandleCount; Index++) { 465 Status = gEfiShellProtocol->GetDeviceName(ChildControllerHandleBuffer[Index], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer); 466 ShellPrintHiiEx( 467 -1, 468 -1, 469 NULL, 470 STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B), 471 gShellDriver1HiiHandle, 472 ConvertHandleToHandleIndex (ChildControllerHandleBuffer[Index]), 473 TempStringPointer!=NULL?TempStringPointer:L"<Unknown>" 474 ); 475 SHELL_FREE_NON_NULL(TempStringPointer); 476 } 477 } 478 } 479 480 SHELL_FREE_NON_NULL(DriverBindingHandleBuffer); 481 482 SHELL_FREE_NON_NULL(ParentControllerHandleBuffer); 483 484 SHELL_FREE_NON_NULL(ChildControllerHandleBuffer); 485 486 if (EFI_ERROR (Status)) { 487 return Status; 488 } 489 // 490 // See if Handle is a driver binding handle and display its details. 491 // 492 Status = gBS->OpenProtocol ( 493 Handle, 494 &gEfiDriverBindingProtocolGuid, 495 (VOID **) &DriverBinding, 496 NULL, 497 NULL, 498 EFI_OPEN_PROTOCOL_GET_PROTOCOL 499 ); 500 if (EFI_ERROR (Status)) { 501 return EFI_SUCCESS; 502 } 503 504 NumberOfChildren = 0; 505 ControllerHandleBuffer = NULL; 506 Status = PARSE_HANDLE_DATABASE_DEVICES ( 507 Handle, 508 &ControllerHandleCount, 509 &ControllerHandleBuffer 510 ); 511 if (ControllerHandleCount > 0) { 512 for (HandleIndex = 0; HandleIndex < ControllerHandleCount; HandleIndex++) { 513 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN ( 514 Handle, 515 ControllerHandleBuffer[HandleIndex], 516 &ChildControllerHandleCount, 517 NULL 518 ); 519 NumberOfChildren += ChildControllerHandleCount; 520 } 521 } 522 523 Status = GetDriverName (Handle, Language, &DriverName); 524 if (EFI_ERROR (Status)) { 525 DriverName = NULL; 526 } 527 528 ShellPrintHiiEx( 529 -1, 530 -1, 531 NULL, 532 STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B), 533 gShellDriver1HiiHandle, 534 ConvertHandleToHandleIndex(Handle), 535 DriverName!=NULL?DriverName:L"<Unknown>" 536 ); 537 SHELL_FREE_NON_NULL(DriverName); 538 Status = GetDriverImageName ( 539 Handle, 540 &DriverName 541 ); 542 if (EFI_ERROR (Status)) { 543 DriverName = NULL; 544 } 545 ShellPrintHiiEx( 546 -1, 547 -1, 548 NULL, 549 STRING_TOKEN (STR_DH_OUTPUT_DRIVER7B), 550 gShellDriver1HiiHandle, 551 DriverName!=NULL?DriverName:L"<Unknown>" 552 ); 553 SHELL_FREE_NON_NULL(DriverName); 554 555 ShellPrintHiiEx( 556 -1, 557 -1, 558 NULL, 559 STRING_TOKEN (STR_DH_OUTPUT_DRIVER8), 560 gShellDriver1HiiHandle, 561 DriverBinding->Version, 562 NumberOfChildren > 0?L"Bus":ControllerHandleCount > 0?L"Device":L"<Unknown>", 563 ConfigurationStatus?L"YES":L"NO", 564 DiagnosticsStatus?L"YES":L"NO" 565 ); 566 567 if (ControllerHandleCount == 0) { 568 ShellPrintHiiEx( 569 -1, 570 -1, 571 NULL, 572 STRING_TOKEN (STR_DH_OUTPUT_DRIVER6), 573 gShellDriver1HiiHandle, 574 L"None" 575 ); 576 } else { 577 ShellPrintHiiEx( 578 -1, 579 -1, 580 NULL, 581 STRING_TOKEN (STR_DH_OUTPUT_DRIVER6), 582 gShellDriver1HiiHandle, 583 L"" 584 ); 585 for (HandleIndex = 0; HandleIndex < ControllerHandleCount; HandleIndex++) { 586 Status = gEfiShellProtocol->GetDeviceName(ControllerHandleBuffer[HandleIndex], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer); 587 588 ShellPrintHiiEx( 589 -1, 590 -1, 591 NULL, 592 STRING_TOKEN (STR_DH_OUTPUT_DRIVER9B), 593 gShellDriver1HiiHandle, 594 ConvertHandleToHandleIndex(ControllerHandleBuffer[HandleIndex]), 595 TempStringPointer!=NULL?TempStringPointer:L"<Unknown>" 596 ); 597 SHELL_FREE_NON_NULL(TempStringPointer); 598 599 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN ( 600 Handle, 601 ControllerHandleBuffer[HandleIndex], 602 &ChildControllerHandleCount, 603 &ChildControllerHandleBuffer 604 ); 605 if (!EFI_ERROR (Status)) { 606 for (ChildIndex = 0; ChildIndex < ChildControllerHandleCount; ChildIndex++) { 607 Status = gEfiShellProtocol->GetDeviceName(ChildControllerHandleBuffer[ChildIndex], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer); 608 609 ShellPrintHiiEx( 610 -1, 611 -1, 612 NULL, 613 STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B), 614 gShellDriver1HiiHandle, 615 ConvertHandleToHandleIndex(ChildControllerHandleBuffer[ChildIndex]), 616 TempStringPointer!=NULL?TempStringPointer:L"<Unknown>" 617 ); 618 SHELL_FREE_NON_NULL(TempStringPointer); 619 } 620 621 SHELL_FREE_NON_NULL (ChildControllerHandleBuffer); 622 } 623 } 624 625 SHELL_FREE_NON_NULL (ControllerHandleBuffer); 626 } 627 628 return EFI_SUCCESS; 629 } 630 631 /** 632 Display information for a handle. 633 634 @param[in] TheHandle The handles to show info on. 635 @param[in] Verbose TRUE for extra info, FALSE otherwise. 636 @param[in] Sfo TRUE to output in standard format output (spec). 637 @param[in] Language Language string per UEFI specification. 638 @param[in] DriverInfo TRUE to show all info about the handle. 639 @param[in] Multiple TRUE indicates more than will be output, 640 FALSE for a single one. 641 642 @retval SHELL_SUCCESS The operation was successful. 643 @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid. 644 **/ 645 SHELL_STATUS 646 DoDhByHandle( 647 IN CONST EFI_HANDLE TheHandle, 648 IN CONST BOOLEAN Verbose, 649 IN CONST BOOLEAN Sfo, 650 IN CONST CHAR8 *Language, 651 IN CONST BOOLEAN DriverInfo, 652 IN CONST BOOLEAN Multiple 653 ) 654 { 655 CHAR16 *ProtocolInfoString; 656 SHELL_STATUS ShellStatus; 657 658 ShellStatus = SHELL_SUCCESS; 659 ProtocolInfoString = NULL; 660 661 if (!Sfo) { 662 if (Multiple) { 663 ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L" ", Verbose, TRUE); 664 ShellPrintHiiEx( 665 -1, 666 -1, 667 NULL, 668 STRING_TOKEN (STR_DH_OUTPUT), 669 gShellDriver1HiiHandle, 670 ConvertHandleToHandleIndex(TheHandle), 671 ProtocolInfoString==NULL?L"":ProtocolInfoString); 672 } else { 673 ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L"\r\n", Verbose, TRUE); 674 ShellPrintHiiEx( 675 -1, 676 -1, 677 NULL, 678 STRING_TOKEN (STR_DH_OUTPUT_SINGLE), 679 gShellDriver1HiiHandle, 680 ConvertHandleToHandleIndex(TheHandle), 681 TheHandle, 682 ProtocolInfoString==NULL?L"":ProtocolInfoString); 683 } 684 685 if (DriverInfo) { 686 DisplayDriverModelHandle ((EFI_HANDLE)TheHandle, TRUE, Language); 687 } 688 } else { 689 ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L";", FALSE, FALSE); 690 ShellPrintHiiEx( 691 -1, 692 -1, 693 NULL, 694 STRING_TOKEN (STR_DH_OUTPUT_SFO), 695 gShellDriver1HiiHandle, 696 Multiple ?L"HandlesInfo":L"HandleInfo", 697 L"DriverName", 698 L"ControllerName", 699 ConvertHandleToHandleIndex(TheHandle), 700 L"DevPath", 701 ProtocolInfoString==NULL?L"":ProtocolInfoString); 702 703 704 } 705 706 707 if (ProtocolInfoString != NULL) { 708 FreePool(ProtocolInfoString); 709 } 710 return (ShellStatus); 711 } 712 713 /** 714 Display information for all handles on a list. 715 716 @param[in] HandleList The NULL-terminated list of handles. 717 @param[in] Verbose TRUE for extra info, FALSE otherwise. 718 @param[in] Sfo TRUE to output in standard format output (spec). 719 @param[in] Language Language string per UEFI specification. 720 @param[in] DriverInfo TRUE to show all info about the handle. 721 722 @retval SHELL_SUCCESS The operation was successful. 723 @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid. 724 **/ 725 SHELL_STATUS 726 DoDhForHandleList( 727 IN CONST EFI_HANDLE *HandleList, 728 IN CONST BOOLEAN Verbose, 729 IN CONST BOOLEAN Sfo, 730 IN CONST CHAR8 *Language, 731 IN CONST BOOLEAN DriverInfo 732 ) 733 { 734 CONST EFI_HANDLE *HandleWalker; 735 SHELL_STATUS ShellStatus; 736 737 ShellStatus = SHELL_SUCCESS; 738 739 for (HandleWalker = HandleList ; HandleWalker != NULL && *HandleWalker != NULL && ShellStatus == SHELL_SUCCESS; HandleWalker++) { 740 ShellStatus = DoDhByHandle( 741 *HandleWalker, 742 Verbose, 743 Sfo, 744 Language, 745 DriverInfo, 746 TRUE 747 ); 748 if (ShellGetExecutionBreakFlag ()) { 749 ShellStatus = SHELL_ABORTED; 750 break; 751 } 752 } 753 return (ShellStatus); 754 } 755 756 /** 757 Display information for all handles. 758 759 @param[in] Sfo TRUE to output in standard format output (spec). 760 @param[in] Verbose TRUE for extra info, FALSE otherwise. 761 @param[in] Language Language string per UEFI specification. 762 @param[in] DriverInfo TRUE to show all info about the handle. 763 764 @retval SHELL_SUCCESS The operation was successful. 765 @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid. 766 **/ 767 SHELL_STATUS 768 DoDhForAll( 769 IN CONST BOOLEAN Sfo, 770 IN CONST BOOLEAN Verbose, 771 IN CONST CHAR8 *Language, 772 IN CONST BOOLEAN DriverInfo 773 ) 774 { 775 EFI_HANDLE *HandleList; 776 SHELL_STATUS ShellStatus; 777 778 HandleList = GetHandleListByProtocol(NULL); 779 780 ShellStatus = DoDhForHandleList( 781 HandleList, 782 Verbose, 783 Sfo, 784 Language, 785 DriverInfo); 786 787 FreePool(HandleList); 788 789 return (ShellStatus); 790 } 791 792 /** 793 Display information for all handles which have a specific protocol. 794 795 @param[in] ProtocolName The pointer to the name of the protocol. 796 @param[in] Verbose TRUE for extra info, FALSE otherwise. 797 @param[in] Sfo TRUE to output in standard format output (spec). 798 @param[in] Language Language string per UEFI specification. 799 @param[in] DriverInfo TRUE to show all info about the handle. 800 801 @retval SHELL_SUCCESS The operation was successful. 802 @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid. 803 **/ 804 SHELL_STATUS 805 DoDhByProtocol( 806 IN CONST CHAR16 *ProtocolName, 807 IN CONST BOOLEAN Verbose, 808 IN CONST BOOLEAN Sfo, 809 IN CONST CHAR8 *Language, 810 IN CONST BOOLEAN DriverInfo 811 ) 812 { 813 EFI_GUID *Guid; 814 EFI_STATUS Status; 815 EFI_HANDLE *HandleList; 816 SHELL_STATUS ShellStatus; 817 818 if (ProtocolName == NULL) { 819 return (SHELL_INVALID_PARAMETER); 820 } 821 822 Status = GetGuidFromStringName(ProtocolName, Language, &Guid); 823 if (EFI_ERROR(Status)) { 824 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DH_NO_GUID_FOUND), gShellDriver1HiiHandle, ProtocolName); 825 return (SHELL_INVALID_PARAMETER); 826 } 827 828 HandleList = GetHandleListByProtocol(Guid); 829 830 ShellStatus = DoDhForHandleList( 831 HandleList, 832 Verbose, 833 Sfo, 834 Language, 835 DriverInfo); 836 837 SHELL_FREE_NON_NULL(HandleList); 838 839 return (ShellStatus); 840 } 841 842 /** 843 Function for 'dh' command. 844 845 @param[in] ImageHandle Handle to the Image (NULL if Internal). 846 @param[in] SystemTable Pointer to the System Table (NULL if Internal). 847 **/ 848 SHELL_STATUS 849 EFIAPI 850 ShellCommandRunDh ( 851 IN EFI_HANDLE ImageHandle, 852 IN EFI_SYSTEM_TABLE *SystemTable 853 ) 854 { 855 EFI_STATUS Status; 856 LIST_ENTRY *Package; 857 CHAR16 *ProblemParam; 858 SHELL_STATUS ShellStatus; 859 CHAR8 *Language; 860 CONST CHAR16 *Lang; 861 CONST CHAR16 *Temp2; 862 BOOLEAN SfoMode; 863 BOOLEAN FlagD; 864 BOOLEAN Verbose; 865 UINT64 Intermediate; 866 867 ShellStatus = SHELL_SUCCESS; 868 Status = EFI_SUCCESS; 869 Language = NULL; 870 871 // 872 // initialize the shell lib (we must be in non-auto-init...) 873 // 874 Status = ShellInitialize(); 875 ASSERT_EFI_ERROR(Status); 876 877 Status = CommandInit(); 878 ASSERT_EFI_ERROR(Status); 879 880 // 881 // parse the command line 882 // 883 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); 884 if (EFI_ERROR(Status)) { 885 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { 886 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"dh", ProblemParam); 887 FreePool(ProblemParam); 888 ShellStatus = SHELL_INVALID_PARAMETER; 889 } else { 890 ASSERT(FALSE); 891 } 892 } else { 893 if (ShellCommandLineGetCount(Package) > 2) { 894 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh"); 895 ShellCommandLineFreeVarList (Package); 896 return (SHELL_INVALID_PARAMETER); 897 } 898 899 Lang = ShellCommandLineGetValue(Package, L"-l"); 900 if (Lang != NULL) { 901 Language = AllocateZeroPool(StrSize(Lang)); 902 AsciiSPrint(Language, StrSize(Lang), "%S", Lang); 903 } else if (!ShellCommandLineGetFlag(Package, L"-l")){ 904 Language = AllocateZeroPool(10); 905 AsciiSPrint(Language, 10, "en-us"); 906 } else { 907 ASSERT(Language == NULL); 908 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", L"-l"); 909 ShellCommandLineFreeVarList (Package); 910 return (SHELL_INVALID_PARAMETER); 911 } 912 913 SfoMode = ShellCommandLineGetFlag(Package, L"-sfo"); 914 FlagD = ShellCommandLineGetFlag(Package, L"-d"); 915 Verbose = (BOOLEAN)(ShellCommandLineGetFlag(Package, L"-v") || ShellCommandLineGetFlag(Package, L"-verbose")); 916 917 if (ShellCommandLineGetFlag(Package, L"-p")) { 918 if (ShellCommandLineGetCount(Package) > 1) { 919 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh"); 920 ShellStatus = SHELL_INVALID_PARAMETER; 921 } else if (ShellCommandLineGetValue(Package, L"-p") == NULL) { 922 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", L"-p"); 923 ShellStatus = SHELL_INVALID_PARAMETER; 924 } else { 925 // 926 // print by protocol 927 // 928 ShellStatus = DoDhByProtocol( 929 ShellCommandLineGetValue(Package, L"-p"), 930 Verbose, 931 SfoMode, 932 Lang==NULL?NULL:Language, 933 FlagD 934 ); 935 } 936 } else { 937 Temp2 = ShellCommandLineGetRawValue(Package, 1); 938 if (Temp2 == NULL) { 939 // 940 // Print everything 941 // 942 ShellStatus = DoDhForAll( 943 SfoMode, 944 Verbose, 945 Lang==NULL?NULL:Language, 946 FlagD 947 ); 948 } else { 949 Status = ShellConvertStringToUint64(Temp2, &Intermediate, TRUE, FALSE); 950 if (EFI_ERROR(Status) || ConvertHandleIndexToHandle((UINTN)Intermediate) == NULL) { 951 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", Temp2); 952 ShellStatus = SHELL_INVALID_PARAMETER; 953 } else { 954 // 955 // print 1 handle 956 // 957 ShellStatus = DoDhByHandle( 958 ConvertHandleIndexToHandle((UINTN)Intermediate), 959 Verbose, 960 SfoMode, 961 Lang==NULL?NULL:Language, 962 FlagD, 963 FALSE 964 ); 965 } 966 } 967 } 968 969 970 ShellCommandLineFreeVarList (Package); 971 SHELL_FREE_NON_NULL(Language); 972 } 973 974 return (ShellStatus); 975 } 976