]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c
ShellPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / ShellPkg / Library / UefiShellDriver1CommandsLib / Dh.c
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 - 2018, Intel Corporation. All rights reserved.<BR>
6 (C) Copyright 2017 Hewlett Packard Enterprise Development LP<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #include "UefiShellDriver1CommandsLib.h"
12
13 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
14 {L"-p", TypeValue},
15 {L"-d", TypeFlag},
16 {L"-v", TypeFlag},
17 {L"-verbose", TypeFlag},
18 {L"-sfo", TypeFlag},
19 {L"-l", TypeValue},
20 {NULL, TypeMax}
21 };
22
23 STATIC CONST EFI_GUID *UefiDriverModelProtocolsGuidArray[] = {
24 &gEfiDriverBindingProtocolGuid,
25 &gEfiPlatformDriverOverrideProtocolGuid,
26 &gEfiBusSpecificDriverOverrideProtocolGuid,
27 &gEfiDriverDiagnosticsProtocolGuid,
28 &gEfiDriverDiagnostics2ProtocolGuid,
29 &gEfiComponentNameProtocolGuid,
30 &gEfiComponentName2ProtocolGuid,
31 &gEfiPlatformToDriverConfigurationProtocolGuid,
32 &gEfiDriverSupportedEfiVersionProtocolGuid,
33 &gEfiDriverFamilyOverrideProtocolGuid,
34 &gEfiDriverHealthProtocolGuid,
35 &gEfiLoadedImageProtocolGuid,
36 NULL
37 };
38
39 UINTN mGuidDataLen[] = {8, 4, 4, 4, 12};
40 /**
41 Function to determine if the string can convert to a GUID.
42 The string must be restricted as "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" format.
43
44 @param[in] String The string to test.
45
46 @retval TRUE The string can convert to a GUID.
47 @retval FALSE The string can't convert to a GUID.
48 **/
49 BOOLEAN
50 IsValidGuidString(
51 IN CONST CHAR16 *String
52 )
53 {
54 CONST CHAR16 *Walker;
55 CONST CHAR16 *PrevWalker;
56 UINTN Index;
57
58 if (String == NULL) {
59 return FALSE;
60 }
61
62 Walker = String;
63 PrevWalker = String;
64 Index = 0;
65
66 while (Walker != NULL && *Walker != CHAR_NULL) {
67 if ( (*Walker >= '0' && *Walker <= '9') ||
68 (*Walker >= 'a' && *Walker <= 'f') ||
69 (*Walker >= 'A' && *Walker <= 'F')
70 ) {
71 Walker++;
72 } else {
73 if (*Walker == L'-' && (((UINTN)Walker - (UINTN)PrevWalker) / sizeof (CHAR16)) == mGuidDataLen[Index]) {
74 Walker++;
75 PrevWalker = Walker;
76 Index++;
77 } else {
78 return FALSE;
79 }
80 }
81 }
82
83 if ((((UINTN)Walker - (UINTN)PrevWalker) / sizeof (CHAR16)) == mGuidDataLen[Index]) {
84 return TRUE;
85 } else {
86 return FALSE;
87 }
88 }
89
90 /**
91 Convert a hex-character to decimal value.
92
93 This internal function only deal with Unicode character
94 which maps to a valid hexadecimal ASII character, i.e.
95 L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other
96 Unicode character, the value returned does not make sense.
97
98 @param[in] Char The character to convert.
99
100 @retval The numerical value converted.
101 **/
102 UINTN
103 HexCharToDecimal(
104 IN CHAR16 Char
105 )
106 {
107 if (Char >= '0' && Char <= '9') {
108 return Char - L'0';
109 } else if (Char >= 'a' && Char <= 'f') {
110 return Char - L'a' + 10;
111 } else {
112 return Char - L'A' + 10;
113 }
114 }
115
116 /**
117 Function try to convert a string to GUID format.
118
119 @param[in] String The string will be converted.
120 @param[out] Guid Save the result convert from string.
121
122 @retval EFI_SUCCESS The string was successfully converted to a GUID.
123 @retval EFI_UNSUPPORTED The input string is not in registry format.
124 **/
125 EFI_STATUS
126 ConvertStrToGuid(
127 IN CONST CHAR16 *String,
128 OUT GUID *Guid
129 )
130 {
131 CONST CHAR16 *Walker;
132 UINT8 TempValue;
133 UINTN Index;
134
135 if (String == NULL || !IsValidGuidString (String)) {
136 return EFI_UNSUPPORTED;
137 }
138
139 Index = 0;
140
141 Walker = String;
142 Guid->Data1 = (UINT32)StrHexToUint64 (Walker);
143
144 Walker += 9;
145 Guid->Data2 = (UINT16)StrHexToUint64 (Walker);
146
147 Walker += 5;
148 Guid->Data3 = (UINT16)StrHexToUint64 (Walker);
149
150 Walker += 5;
151 while (Walker != NULL && *Walker != CHAR_NULL) {
152 if (*Walker == L'-') {
153 Walker++;
154 } else {
155 TempValue = (UINT8)HexCharToDecimal (*Walker);
156 TempValue = (UINT8)LShiftU64 (TempValue, 4);
157 Walker++;
158
159 TempValue += (UINT8)HexCharToDecimal (*Walker);
160 Walker++;
161
162 Guid->Data4[Index] = TempValue;
163 Index++;
164 }
165 }
166
167 return EFI_SUCCESS;
168 }
169
170 /**
171 Get the name of a driver by it's handle.
172
173 If a name is found the memory must be callee freed.
174
175 @param[in] TheHandle The driver's handle.
176 @param[in] Language The language to use.
177 @param[in] NameFound Upon a successful return the name found.
178
179 @retval EFI_SUCCESS The name was found.
180 **/
181 EFI_STATUS
182 GetDriverName (
183 IN EFI_HANDLE TheHandle,
184 IN CONST CHAR8 *Language,
185 IN CHAR16 **NameFound
186 )
187 {
188 CHAR8 *Lang;
189 EFI_STATUS Status;
190 EFI_COMPONENT_NAME2_PROTOCOL *CompName2;
191 CHAR16 *NameToReturn;
192 //
193 // Go through those handles until we get one that passes for GetComponentName
194 //
195 Status = gBS->OpenProtocol(
196 TheHandle,
197 &gEfiComponentName2ProtocolGuid,
198 (VOID**)&CompName2,
199 gImageHandle,
200 NULL,
201 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
202 if (EFI_ERROR(Status)) {
203 Status = gBS->OpenProtocol(
204 TheHandle,
205 &gEfiComponentNameProtocolGuid,
206 (VOID**)&CompName2,
207 gImageHandle,
208 NULL,
209 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
210 }
211
212 if (EFI_ERROR(Status)) {
213 return (EFI_NOT_FOUND);
214 }
215 Lang = GetBestLanguageForDriver (CompName2->SupportedLanguages, Language, FALSE);
216 Status = CompName2->GetDriverName(CompName2, Lang, &NameToReturn);
217 FreePool(Lang);
218
219 if (!EFI_ERROR(Status) && NameToReturn != NULL) {
220 *NameFound = NULL;
221 StrnCatGrow(NameFound, NULL, NameToReturn, 0);
222 }
223 return (Status);
224 }
225
226 /**
227 Discover if a protocol guid is one of the UEFI Driver Model Protocols.
228
229 @param[in] Guid The guid to test.
230
231 @retval TRUE The guid does represent a driver model protocol.
232 @retval FALSE The guid does not represent a driver model protocol.
233 **/
234 BOOLEAN
235 IsDriverProt (
236 IN CONST EFI_GUID *Guid
237 )
238 {
239 CONST EFI_GUID **GuidWalker;
240 BOOLEAN GuidFound;
241 GuidFound = FALSE;
242 for (GuidWalker = UefiDriverModelProtocolsGuidArray
243 ; GuidWalker != NULL && *GuidWalker != NULL
244 ; GuidWalker++
245 ){
246 if (CompareGuid(*GuidWalker, Guid)) {
247 GuidFound = TRUE;
248 break;
249 }
250 }
251 return (GuidFound);
252 }
253
254 /**
255 Get information for a handle.
256
257 @param[in] TheHandle The handles to show info on.
258 @param[in] Language Language string per UEFI specification.
259 @param[in] Separator Separator string between information blocks.
260 @param[in] Verbose TRUE for extra info, FALSE otherwise.
261 @param[in] ExtraInfo TRUE for extra info, FALSE otherwise.
262
263 @retval SHELL_SUCCESS The operation was successful.
264 @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
265 **/
266 CHAR16*
267 GetProtocolInfoString(
268 IN CONST EFI_HANDLE TheHandle,
269 IN CONST CHAR8 *Language,
270 IN CONST CHAR16 *Separator,
271 IN CONST BOOLEAN Verbose,
272 IN CONST BOOLEAN ExtraInfo
273 )
274 {
275 EFI_GUID **ProtocolGuidArray;
276 UINTN ArrayCount;
277 UINTN ProtocolIndex;
278 EFI_STATUS Status;
279 CHAR16 *RetVal;
280 UINTN Size;
281 CHAR16 *Temp;
282 CHAR16 GuidStr[40];
283 VOID *Instance;
284 CHAR16 InstanceStr[17];
285
286 ProtocolGuidArray = NULL;
287 RetVal = NULL;
288 Size = 0;
289
290 Status = gBS->ProtocolsPerHandle (
291 TheHandle,
292 &ProtocolGuidArray,
293 &ArrayCount
294 );
295 if (!EFI_ERROR (Status)) {
296 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
297 Temp = GetStringNameFromGuid(ProtocolGuidArray[ProtocolIndex], Language);
298 ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
299 if (Size != 0) {
300 StrnCatGrow(&RetVal, &Size, Separator, 0);
301 }
302 StrnCatGrow(&RetVal, &Size, L"%H", 0);
303 if (Temp == NULL) {
304 UnicodeSPrint (GuidStr, sizeof (GuidStr), L"%g", ProtocolGuidArray[ProtocolIndex]);
305 StrnCatGrow (&RetVal, &Size, GuidStr, 0);
306 } else {
307 StrnCatGrow(&RetVal, &Size, Temp, 0);
308 FreePool(Temp);
309 }
310 StrnCatGrow(&RetVal, &Size, L"%N", 0);
311
312 if(Verbose) {
313 Status = gBS->HandleProtocol (TheHandle, ProtocolGuidArray[ProtocolIndex], &Instance);
314 if (!EFI_ERROR (Status)) {
315 StrnCatGrow (&RetVal, &Size, L"(%H", 0);
316 UnicodeSPrint (InstanceStr, sizeof (InstanceStr), L"%x", Instance);
317 StrnCatGrow (&RetVal, &Size, InstanceStr, 0);
318 StrnCatGrow (&RetVal, &Size, L"%N)", 0);
319 }
320 }
321
322 if (ExtraInfo) {
323 Temp = GetProtocolInformationDump(TheHandle, ProtocolGuidArray[ProtocolIndex], Verbose);
324 if (Temp != NULL) {
325 ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
326 if (!Verbose) {
327 StrnCatGrow(&RetVal, &Size, L"(", 0);
328 StrnCatGrow(&RetVal, &Size, Temp, 0);
329 StrnCatGrow(&RetVal, &Size, L")", 0);
330 } else {
331 StrnCatGrow(&RetVal, &Size, Separator, 0);
332 StrnCatGrow(&RetVal, &Size, Temp, 0);
333 }
334 FreePool(Temp);
335 }
336 }
337 }
338 }
339
340 SHELL_FREE_NON_NULL(ProtocolGuidArray);
341
342 if (RetVal == NULL) {
343 return (NULL);
344 }
345
346 ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
347 StrnCatGrow(&RetVal, &Size, Separator, 0);
348 return (RetVal);
349 }
350
351 /**
352 Gets the name of the loaded image.
353
354 @param[in] TheHandle The handle of the driver to get info on.
355 @param[out] Name The pointer to the pointer. Valid upon a successful return.
356
357 @retval EFI_SUCCESS The operation was successful.
358 **/
359 EFI_STATUS
360 GetDriverImageName (
361 IN EFI_HANDLE TheHandle,
362 OUT CHAR16 **Name
363 )
364 {
365 // get loaded image and devicepathtotext on image->Filepath
366 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
367 EFI_STATUS Status;
368 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
369
370 if (TheHandle == NULL || Name == NULL) {
371 return (EFI_INVALID_PARAMETER);
372 }
373
374 Status = gBS->OpenProtocol (
375 TheHandle,
376 &gEfiLoadedImageProtocolGuid,
377 (VOID **) &LoadedImage,
378 gImageHandle,
379 NULL,
380 EFI_OPEN_PROTOCOL_GET_PROTOCOL
381 );
382 if (EFI_ERROR(Status)) {
383 return (Status);
384 }
385 DevicePath = LoadedImage->FilePath;
386 *Name = ConvertDevicePathToText(DevicePath, TRUE, TRUE);
387 return (EFI_SUCCESS);
388 }
389
390 /**
391 Display driver model information for a given handle.
392
393 @param[in] Handle The handle to display info on.
394 @param[in] BestName Use the best name?
395 @param[in] Language The language to output in.
396 **/
397 EFI_STATUS
398 DisplayDriverModelHandle (
399 IN EFI_HANDLE Handle,
400 IN BOOLEAN BestName,
401 IN CONST CHAR8 *Language OPTIONAL
402 )
403 {
404 EFI_STATUS Status;
405 BOOLEAN ConfigurationStatus;
406 BOOLEAN DiagnosticsStatus;
407 UINTN DriverBindingHandleCount;
408 EFI_HANDLE *DriverBindingHandleBuffer;
409 UINTN ParentControllerHandleCount;
410 EFI_HANDLE *ParentControllerHandleBuffer;
411 UINTN ChildControllerHandleCount;
412 EFI_HANDLE *ChildControllerHandleBuffer;
413 CHAR16 *TempStringPointer;
414 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
415 UINTN Index;
416 CHAR16 *DriverName;
417 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
418 UINTN NumberOfChildren;
419 UINTN HandleIndex;
420 UINTN ControllerHandleCount;
421 EFI_HANDLE *ControllerHandleBuffer;
422 UINTN ChildIndex;
423 BOOLEAN Image;
424
425 DriverName = NULL;
426
427 //
428 // See if Handle is a device handle and display its details.
429 //
430 DriverBindingHandleBuffer = NULL;
431 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
432 Handle,
433 &DriverBindingHandleCount,
434 &DriverBindingHandleBuffer
435 );
436
437 ParentControllerHandleBuffer = NULL;
438 Status = PARSE_HANDLE_DATABASE_PARENTS (
439 Handle,
440 &ParentControllerHandleCount,
441 &ParentControllerHandleBuffer
442 );
443
444 ChildControllerHandleBuffer = NULL;
445 Status = ParseHandleDatabaseForChildControllers (
446 Handle,
447 &ChildControllerHandleCount,
448 &ChildControllerHandleBuffer
449 );
450
451 DiagnosticsStatus = FALSE;
452 ConfigurationStatus = FALSE;
453
454 if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverConfigurationProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
455 ConfigurationStatus = TRUE;
456 }
457 if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverConfiguration2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
458 ConfigurationStatus = TRUE;
459 }
460 if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverDiagnosticsProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
461 DiagnosticsStatus = TRUE;
462 }
463 if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverDiagnostics2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
464 DiagnosticsStatus = TRUE;
465 }
466
467 Status = EFI_SUCCESS;
468
469 if (DriverBindingHandleCount > 0 || ParentControllerHandleCount > 0 || ChildControllerHandleCount > 0) {
470
471
472
473 DevicePath = NULL;
474 TempStringPointer = NULL;
475 Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID**)&DevicePath);
476
477 Status = gEfiShellProtocol->GetDeviceName(Handle, EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
478 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DRIVER1), gShellDriver1HiiHandle, TempStringPointer!=NULL?TempStringPointer:L"<Unknown>");
479 SHELL_FREE_NON_NULL(TempStringPointer);
480
481 TempStringPointer = ConvertDevicePathToText(DevicePath, TRUE, FALSE);
482 ShellPrintHiiEx(
483 -1,
484 -1,
485 NULL,
486 STRING_TOKEN (STR_DH_OUTPUT_DRIVER2),
487 gShellDriver1HiiHandle,
488 TempStringPointer!=NULL?TempStringPointer:L"<None>",
489 ParentControllerHandleCount == 0?L"ROOT":(ChildControllerHandleCount > 0)?L"BUS":L"DEVICE",
490 ConfigurationStatus?L"YES":L"NO",
491 DiagnosticsStatus?L"YES":L"NO"
492 );
493
494 SHELL_FREE_NON_NULL(TempStringPointer);
495
496 if (DriverBindingHandleCount == 0) {
497 ShellPrintHiiEx(
498 -1,
499 -1,
500 NULL,
501 STRING_TOKEN (STR_DH_OUTPUT_DRIVER3),
502 gShellDriver1HiiHandle,
503 L"<None>"
504 );
505 } else {
506 ShellPrintHiiEx(
507 -1,
508 -1,
509 NULL,
510 STRING_TOKEN (STR_DH_OUTPUT_DRIVER3),
511 gShellDriver1HiiHandle,
512 L""
513 );
514 for (Index = 0; Index < DriverBindingHandleCount; Index++) {
515 Image = FALSE;
516 Status = GetDriverName (
517 DriverBindingHandleBuffer[Index],
518 Language,
519 &DriverName
520 );
521 if (EFI_ERROR (Status)) {
522 Status = GetDriverImageName (
523 DriverBindingHandleBuffer[Index],
524 &DriverName
525 );
526 if (EFI_ERROR (Status)) {
527 DriverName = NULL;
528 }
529 }
530
531 if (Image) {
532 ShellPrintHiiEx(
533 -1,
534 -1,
535 NULL,
536 STRING_TOKEN (STR_DH_OUTPUT_DRIVER4A),
537 gShellDriver1HiiHandle,
538 ConvertHandleToHandleIndex (DriverBindingHandleBuffer[Index]),
539 DriverName!=NULL?DriverName:L"<Unknown>"
540 );
541 } else {
542 ShellPrintHiiEx(
543 -1,
544 -1,
545 NULL,
546 STRING_TOKEN (STR_DH_OUTPUT_DRIVER4B),
547 gShellDriver1HiiHandle,
548 ConvertHandleToHandleIndex (DriverBindingHandleBuffer[Index]),
549 DriverName!=NULL?DriverName:L"<Unknown>"
550 );
551 }
552 SHELL_FREE_NON_NULL(DriverName);
553 }
554 }
555
556 if (ParentControllerHandleCount == 0) {
557 ShellPrintHiiEx(
558 -1,
559 -1,
560 NULL,
561 STRING_TOKEN (STR_DH_OUTPUT_DRIVER5),
562 gShellDriver1HiiHandle,
563 L"<None>"
564 );
565 } else {
566 ShellPrintHiiEx(
567 -1,
568 -1,
569 NULL,
570 STRING_TOKEN (STR_DH_OUTPUT_DRIVER5),
571 gShellDriver1HiiHandle,
572 L""
573 );
574 for (Index = 0; Index < ParentControllerHandleCount; Index++) {
575 Status = gEfiShellProtocol->GetDeviceName(ParentControllerHandleBuffer[Index], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
576 ShellPrintHiiEx(
577 -1,
578 -1,
579 NULL,
580 STRING_TOKEN (STR_DH_OUTPUT_DRIVER5B),
581 gShellDriver1HiiHandle,
582 ConvertHandleToHandleIndex (ParentControllerHandleBuffer[Index]),
583 TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
584 );
585 SHELL_FREE_NON_NULL(TempStringPointer);
586 }
587 }
588
589 if (ChildControllerHandleCount == 0) {
590 ShellPrintHiiEx(
591 -1,
592 -1,
593 NULL,
594 STRING_TOKEN (STR_DH_OUTPUT_DRIVER6),
595 gShellDriver1HiiHandle,
596 L"<None>"
597 );
598 } else {
599 ShellPrintHiiEx(
600 -1,
601 -1,
602 NULL,
603 STRING_TOKEN (STR_DH_OUTPUT_DRIVER6),
604 gShellDriver1HiiHandle,
605 L""
606 );
607 for (Index = 0; Index < ChildControllerHandleCount; Index++) {
608 Status = gEfiShellProtocol->GetDeviceName(ChildControllerHandleBuffer[Index], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
609 ShellPrintHiiEx(
610 -1,
611 -1,
612 NULL,
613 STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B),
614 gShellDriver1HiiHandle,
615 ConvertHandleToHandleIndex (ChildControllerHandleBuffer[Index]),
616 TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
617 );
618 SHELL_FREE_NON_NULL(TempStringPointer);
619 }
620 }
621 }
622
623 SHELL_FREE_NON_NULL(DriverBindingHandleBuffer);
624
625 SHELL_FREE_NON_NULL(ParentControllerHandleBuffer);
626
627 SHELL_FREE_NON_NULL(ChildControllerHandleBuffer);
628
629 if (EFI_ERROR (Status)) {
630 return Status;
631 }
632 //
633 // See if Handle is a driver binding handle and display its details.
634 //
635 Status = gBS->OpenProtocol (
636 Handle,
637 &gEfiDriverBindingProtocolGuid,
638 (VOID **) &DriverBinding,
639 NULL,
640 NULL,
641 EFI_OPEN_PROTOCOL_GET_PROTOCOL
642 );
643 if (EFI_ERROR (Status)) {
644 return EFI_SUCCESS;
645 }
646
647 NumberOfChildren = 0;
648 ControllerHandleBuffer = NULL;
649 Status = PARSE_HANDLE_DATABASE_DEVICES (
650 Handle,
651 &ControllerHandleCount,
652 &ControllerHandleBuffer
653 );
654 if (ControllerHandleCount > 0) {
655 for (HandleIndex = 0; HandleIndex < ControllerHandleCount; HandleIndex++) {
656 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
657 Handle,
658 ControllerHandleBuffer[HandleIndex],
659 &ChildControllerHandleCount,
660 NULL
661 );
662 NumberOfChildren += ChildControllerHandleCount;
663 }
664 }
665
666 Status = GetDriverName (Handle, Language, &DriverName);
667 if (EFI_ERROR (Status)) {
668 DriverName = NULL;
669 }
670
671 ShellPrintHiiEx(
672 -1,
673 -1,
674 NULL,
675 STRING_TOKEN (STR_DH_OUTPUT_DRIVER7),
676 gShellDriver1HiiHandle,
677 ConvertHandleToHandleIndex(Handle),
678 DriverName!=NULL?DriverName:L"<Unknown>"
679 );
680 SHELL_FREE_NON_NULL(DriverName);
681 Status = GetDriverImageName (
682 Handle,
683 &DriverName
684 );
685 if (EFI_ERROR (Status)) {
686 DriverName = NULL;
687 }
688 ShellPrintHiiEx(
689 -1,
690 -1,
691 NULL,
692 STRING_TOKEN (STR_DH_OUTPUT_DRIVER7B),
693 gShellDriver1HiiHandle,
694 DriverName!=NULL?DriverName:L"<Unknown>"
695 );
696 SHELL_FREE_NON_NULL(DriverName);
697
698 ShellPrintHiiEx(
699 -1,
700 -1,
701 NULL,
702 STRING_TOKEN (STR_DH_OUTPUT_DRIVER8),
703 gShellDriver1HiiHandle,
704 DriverBinding->Version,
705 NumberOfChildren > 0?L"Bus":ControllerHandleCount > 0?L"Device":L"<Unknown>",
706 ConfigurationStatus?L"YES":L"NO",
707 DiagnosticsStatus?L"YES":L"NO"
708 );
709
710 if (ControllerHandleCount == 0) {
711 ShellPrintHiiEx(
712 -1,
713 -1,
714 NULL,
715 STRING_TOKEN (STR_DH_OUTPUT_DRIVER9),
716 gShellDriver1HiiHandle,
717 L"None"
718 );
719 } else {
720 ShellPrintHiiEx(
721 -1,
722 -1,
723 NULL,
724 STRING_TOKEN (STR_DH_OUTPUT_DRIVER9),
725 gShellDriver1HiiHandle,
726 L""
727 );
728 for (HandleIndex = 0; HandleIndex < ControllerHandleCount; HandleIndex++) {
729 Status = gEfiShellProtocol->GetDeviceName(ControllerHandleBuffer[HandleIndex], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
730
731 ShellPrintHiiEx(
732 -1,
733 -1,
734 NULL,
735 STRING_TOKEN (STR_DH_OUTPUT_DRIVER9B),
736 gShellDriver1HiiHandle,
737 ConvertHandleToHandleIndex(ControllerHandleBuffer[HandleIndex]),
738 TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
739 );
740 SHELL_FREE_NON_NULL(TempStringPointer);
741
742 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
743 Handle,
744 ControllerHandleBuffer[HandleIndex],
745 &ChildControllerHandleCount,
746 &ChildControllerHandleBuffer
747 );
748 if (!EFI_ERROR (Status)) {
749 for (ChildIndex = 0; ChildIndex < ChildControllerHandleCount; ChildIndex++) {
750 Status = gEfiShellProtocol->GetDeviceName(ChildControllerHandleBuffer[ChildIndex], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
751
752 ShellPrintHiiEx(
753 -1,
754 -1,
755 NULL,
756 STRING_TOKEN (STR_DH_OUTPUT_DRIVER6C),
757 gShellDriver1HiiHandle,
758 ConvertHandleToHandleIndex(ChildControllerHandleBuffer[ChildIndex]),
759 TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
760 );
761 SHELL_FREE_NON_NULL(TempStringPointer);
762 }
763
764 SHELL_FREE_NON_NULL (ChildControllerHandleBuffer);
765 }
766 }
767
768 SHELL_FREE_NON_NULL (ControllerHandleBuffer);
769 }
770
771 return EFI_SUCCESS;
772 }
773
774 /**
775 Display information for a handle.
776
777 @param[in] TheHandle The handles to show info on.
778 @param[in] Verbose TRUE for extra info, FALSE otherwise.
779 @param[in] Sfo TRUE to output in standard format output (spec).
780 @param[in] Language Language string per UEFI specification.
781 @param[in] DriverInfo TRUE to show all info about the handle.
782 @param[in] Multiple TRUE indicates more than will be output,
783 FALSE for a single one.
784 **/
785 VOID
786 DoDhByHandle(
787 IN CONST EFI_HANDLE TheHandle,
788 IN CONST BOOLEAN Verbose,
789 IN CONST BOOLEAN Sfo,
790 IN CONST CHAR8 *Language,
791 IN CONST BOOLEAN DriverInfo,
792 IN CONST BOOLEAN Multiple
793 )
794 {
795 CHAR16 *ProtocolInfoString;
796
797 ProtocolInfoString = NULL;
798
799 if (!Sfo) {
800 if (Multiple) {
801 ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L" ", Verbose, TRUE);
802 ShellPrintHiiEx(
803 -1,
804 -1,
805 NULL,
806 STRING_TOKEN (STR_DH_OUTPUT),
807 gShellDriver1HiiHandle,
808 ConvertHandleToHandleIndex(TheHandle),
809 ProtocolInfoString==NULL?L"":ProtocolInfoString
810 );
811 } else {
812 ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, Verbose ? L"\r\n" : L" ", Verbose, TRUE);
813 if (Verbose) {
814 ShellPrintHiiEx(
815 -1,
816 -1,
817 NULL,
818 STRING_TOKEN (STR_DH_OUTPUT_SINGLE),
819 gShellDriver1HiiHandle,
820 ConvertHandleToHandleIndex(TheHandle),
821 TheHandle,
822 ProtocolInfoString==NULL?L"":ProtocolInfoString
823 );
824 } else {
825 ShellPrintHiiEx(
826 -1,
827 -1,
828 NULL,
829 STRING_TOKEN (STR_DH_OUTPUT_SINGLE_D),
830 gShellDriver1HiiHandle,
831 ConvertHandleToHandleIndex(TheHandle),
832 ProtocolInfoString==NULL?L"":ProtocolInfoString
833 );
834 }
835 }
836
837 if (DriverInfo) {
838 DisplayDriverModelHandle ((EFI_HANDLE)TheHandle, TRUE, Language);
839 }
840 } else {
841 ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L";", FALSE, FALSE);
842 ShellPrintHiiEx(
843 -1,
844 -1,
845 NULL,
846 STRING_TOKEN (STR_DH_OUTPUT_SFO),
847 gShellDriver1HiiHandle,
848 Multiple ?L"HandlesInfo":L"HandleInfo",
849 L"DriverName",
850 L"ControllerName",
851 ConvertHandleToHandleIndex(TheHandle),
852 L"DevPath",
853 ProtocolInfoString==NULL?L"":ProtocolInfoString
854 );
855 }
856
857 if (ProtocolInfoString != NULL) {
858 FreePool(ProtocolInfoString);
859 }
860 }
861
862 /**
863 Display information for all handles on a list.
864
865 @param[in] HandleList The NULL-terminated list of handles.
866 @param[in] Verbose TRUE for extra info, FALSE otherwise.
867 @param[in] Sfo TRUE to output in standard format output (spec).
868 @param[in] Language Language string per UEFI specification.
869 @param[in] DriverInfo TRUE to show all info about the handle.
870
871 @retval SHELL_SUCCESS The operation was successful.
872 @retval SHELL_ABORTED The operation was aborted.
873 **/
874 SHELL_STATUS
875 DoDhForHandleList(
876 IN CONST EFI_HANDLE *HandleList,
877 IN CONST BOOLEAN Verbose,
878 IN CONST BOOLEAN Sfo,
879 IN CONST CHAR8 *Language,
880 IN CONST BOOLEAN DriverInfo
881 )
882 {
883 CONST EFI_HANDLE *HandleWalker;
884 SHELL_STATUS ShellStatus;
885
886 ShellStatus = SHELL_SUCCESS;
887 for (HandleWalker = HandleList; HandleWalker != NULL && *HandleWalker != NULL; HandleWalker++) {
888 DoDhByHandle (*HandleWalker, Verbose, Sfo, Language, DriverInfo, TRUE);
889 if (ShellGetExecutionBreakFlag ()) {
890 ShellStatus = SHELL_ABORTED;
891 break;
892 }
893 }
894 return (ShellStatus);
895 }
896
897 /**
898 Display information for a GUID of protocol.
899
900 @param[in] Guid The pointer to the name of the protocol.
901 @param[in] Verbose TRUE for extra info, FALSE otherwise.
902 @param[in] Sfo TRUE to output in standard format output (spec).
903 @param[in] Language Language string per UEFI specification.
904 @param[in] DriverInfo TRUE to show all info about the handle.
905
906 @retval SHELL_SUCCESS The operation was successful.
907 @retval SHELL_NOT_FOUND The GUID was not found.
908 @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
909 **/
910 SHELL_STATUS
911 DoDhByProtocolGuid(
912 IN CONST GUID *Guid,
913 IN CONST BOOLEAN Verbose,
914 IN CONST BOOLEAN Sfo,
915 IN CONST CHAR8 *Language,
916 IN CONST BOOLEAN DriverInfo
917 )
918 {
919 CHAR16 *Name;
920 SHELL_STATUS ShellStatus;
921 EFI_HANDLE *HandleList;
922
923 if (!Sfo) {
924 if (Guid == NULL) {
925 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_ALL_HEADER), gShellDriver1HiiHandle);
926 } else {
927 Name = GetStringNameFromGuid (Guid, NULL);
928 if (Name == NULL) {
929 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_GUID_HEADER), gShellDriver1HiiHandle, Guid);
930 } else {
931 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_NAME_HEADER), gShellDriver1HiiHandle, Name);
932 }
933 }
934 }
935 HandleList = GetHandleListByProtocol(Guid);
936 ShellStatus = DoDhForHandleList(HandleList, Verbose, Sfo, Language, DriverInfo);
937 SHELL_FREE_NON_NULL(HandleList);
938
939 return ShellStatus;
940 }
941
942 /**
943 Function to determine use which method to print information.
944 If Protocol is NULL, The function will print all information.
945
946 @param[in] Protocol The pointer to the name or GUID of protocol or NULL.
947 @param[in] Verbose TRUE for extra info, FALSE otherwise.
948 @param[in] Sfo TRUE to output in standard format output (spec).
949 @param[in] Language Language string per UEFI specification.
950 @param[in] DriverInfo TRUE to show all info about the handle.
951
952 @retval SHELL_SUCCESS The operation was successful.
953 @retval SHELL_NOT_FOUND The protocol was not found.
954 @retval SHELL_INVALID_PARAMETER Protocol is invalid parameter.
955 **/
956 SHELL_STATUS
957 DoDhByProtocol (
958 IN CONST CHAR16 *Protocol,
959 IN CONST BOOLEAN Verbose,
960 IN CONST BOOLEAN Sfo,
961 IN CONST CHAR8 *Language,
962 IN CONST BOOLEAN DriverInfo
963 )
964 {
965 EFI_GUID Guid;
966 EFI_GUID *GuidPtr;
967 EFI_STATUS Status;
968
969 if (Protocol == NULL) {
970 return DoDhByProtocolGuid (NULL, Verbose, Sfo, Language, DriverInfo);
971 } else {
972 Status = ConvertStrToGuid (Protocol, &Guid);
973 if (!EFI_ERROR (Status)) {
974 GuidPtr = &Guid;
975 } else {
976 //
977 // Protocol is a Name, convert it to GUID
978 //
979 Status = GetGuidFromStringName (Protocol, Language, &GuidPtr);
980 if (EFI_ERROR(Status)) {
981 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_NAME_FOUND), gShellDriver1HiiHandle, Protocol);
982 return (SHELL_NOT_FOUND);
983 }
984 }
985
986 return DoDhByProtocolGuid (GuidPtr, Verbose, Sfo, Language, DriverInfo);
987 }
988 }
989
990 /**
991 Function to display decode information by Protocol.
992 The parameter Protocol is either a GUID or the name of protocol.
993 If the parameter Protocol is NULL, the function will print all
994 decode information.
995
996 @param[in] Protocol The pointer to the name or GUID of protocol.
997 @param[in] Language Language string per UEFI specification.
998
999 @retval SHELL_SUCCESS The operation was successful.
1000 @retval SHELL_OUT_OT_RESOURCES A memory allocation failed.
1001 **/
1002 SHELL_STATUS
1003 DoDecodeByProtocol(
1004 IN CONST CHAR16 *Protocol,
1005 IN CONST CHAR8 *Language
1006 )
1007 {
1008 EFI_STATUS Status;
1009 EFI_GUID *Guids;
1010 EFI_GUID Guid;
1011 UINTN Counts;
1012 UINTN Index;
1013 CHAR16 *Name;
1014
1015 if (Protocol == NULL) {
1016 Counts = 0;
1017 Status = GetAllMappingGuids (NULL, &Counts);
1018 if (Status == EFI_BUFFER_TOO_SMALL) {
1019 Guids = AllocatePool (Counts * sizeof(EFI_GUID));
1020 if (Guids == NULL) {
1021 return SHELL_OUT_OF_RESOURCES;
1022 }
1023
1024 Status = GetAllMappingGuids (Guids, &Counts);
1025 if (Status == EFI_SUCCESS) {
1026 for (Index = 0; Index < Counts; Index++) {
1027 Name = GetStringNameFromGuid (&Guids[Index], Language);
1028 if (Name != NULL) {
1029 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DECODE), gShellDriver1HiiHandle, Name, &Guids[Index]);
1030 } else {
1031 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_GUID_FOUND), gShellDriver1HiiHandle, &Guids[Index]);
1032 }
1033 SHELL_FREE_NON_NULL (Name);
1034 }
1035 }
1036 FreePool (Guids);
1037 }
1038 } else {
1039 if (ConvertStrToGuid (Protocol, &Guid) == EFI_SUCCESS) {
1040 Name = GetStringNameFromGuid (&Guid, Language);
1041 if (Name != NULL) {
1042 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DECODE), gShellDriver1HiiHandle, Name, &Guid);
1043 } else {
1044 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_GUID_FOUND), gShellDriver1HiiHandle, &Guid);
1045 }
1046 SHELL_FREE_NON_NULL(Name);
1047 } else {
1048 Status = GetGuidFromStringName (Protocol, Language, &Guids);
1049 if (Status == EFI_SUCCESS) {
1050 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DECODE), gShellDriver1HiiHandle, Protocol, Guids);
1051 } else {
1052 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_NAME_FOUND), gShellDriver1HiiHandle, Protocol);
1053 }
1054 }
1055 }
1056
1057 return SHELL_SUCCESS;
1058 }
1059
1060 /**
1061 Function for 'dh' command.
1062
1063 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1064 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1065 **/
1066 SHELL_STATUS
1067 EFIAPI
1068 ShellCommandRunDh (
1069 IN EFI_HANDLE ImageHandle,
1070 IN EFI_SYSTEM_TABLE *SystemTable
1071 )
1072 {
1073 EFI_STATUS Status;
1074 LIST_ENTRY *Package;
1075 CHAR16 *ProblemParam;
1076 SHELL_STATUS ShellStatus;
1077 CHAR8 *Language;
1078 CONST CHAR16 *Lang;
1079 CONST CHAR16 *RawValue;
1080 CONST CHAR16 *ProtocolVal;
1081 BOOLEAN SfoFlag;
1082 BOOLEAN DriverFlag;
1083 BOOLEAN VerboseFlag;
1084 UINT64 Intermediate;
1085 EFI_HANDLE Handle;
1086
1087 ShellStatus = SHELL_SUCCESS;
1088 Status = EFI_SUCCESS;
1089 Language = NULL;
1090
1091 //
1092 // initialize the shell lib (we must be in non-auto-init...)
1093 //
1094 Status = ShellInitialize();
1095 ASSERT_EFI_ERROR(Status);
1096
1097 Status = CommandInit();
1098 ASSERT_EFI_ERROR(Status);
1099
1100 //
1101 // parse the command line
1102 //
1103 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
1104 if (EFI_ERROR(Status)) {
1105 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
1106 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"dh", ProblemParam);
1107 FreePool(ProblemParam);
1108 ShellStatus = SHELL_INVALID_PARAMETER;
1109 } else {
1110 ASSERT(FALSE);
1111 }
1112 } else {
1113 if (ShellCommandLineGetCount(Package) > 2) {
1114 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh");
1115 ShellCommandLineFreeVarList (Package);
1116 return (SHELL_INVALID_PARAMETER);
1117 }
1118
1119 if (ShellCommandLineGetFlag(Package, L"-l")) {
1120 Lang = ShellCommandLineGetValue(Package, L"-l");
1121 if (Lang != NULL) {
1122 Language = AllocateZeroPool(StrSize(Lang));
1123 AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
1124 } else {
1125 ASSERT(Language == NULL);
1126 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", L"-l");
1127 ShellCommandLineFreeVarList(Package);
1128 return (SHELL_INVALID_PARAMETER);
1129 }
1130 } else {
1131 Language = AllocateZeroPool(10);
1132 AsciiSPrint(Language, 10, "en-us");
1133 }
1134
1135 SfoFlag = ShellCommandLineGetFlag (Package, L"-sfo");
1136 DriverFlag = ShellCommandLineGetFlag (Package, L"-d");
1137 VerboseFlag = (BOOLEAN)(ShellCommandLineGetFlag (Package, L"-v") || ShellCommandLineGetFlag (Package, L"-verbose"));
1138 RawValue = ShellCommandLineGetRawValue (Package, 1);
1139 ProtocolVal = ShellCommandLineGetValue (Package, L"-p");
1140
1141 if (RawValue == NULL) {
1142 if (ShellCommandLineGetFlag (Package, L"-p") && (ProtocolVal == NULL)) {
1143 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", L"-p");
1144 ShellStatus = SHELL_INVALID_PARAMETER;
1145 } else {
1146 //
1147 // Print information by protocol, The ProtocolVal maybe is name or GUID or NULL.
1148 //
1149 ShellStatus = DoDhByProtocol (ProtocolVal, VerboseFlag, SfoFlag, Language, DriverFlag);
1150 }
1151 } else if ((RawValue != NULL) &&
1152 (gUnicodeCollation->StriColl(gUnicodeCollation, L"decode", (CHAR16 *) RawValue) == 0)) {
1153 if (ShellCommandLineGetFlag (Package, L"-p") && (ProtocolVal == NULL)) {
1154 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", L"-p");
1155 ShellStatus = SHELL_INVALID_PARAMETER;
1156 } else {
1157 //
1158 // Print decode informatino by protocol.
1159 //
1160 ShellStatus = DoDecodeByProtocol (ProtocolVal, Language);
1161 }
1162 } else {
1163 if (ShellCommandLineGetFlag (Package, L"-p")) {
1164 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh");
1165 ShellStatus = SHELL_INVALID_PARAMETER;
1166 } else {
1167 Status = ShellConvertStringToUint64 (RawValue, &Intermediate, TRUE, FALSE);
1168 if (EFI_ERROR(Status)) {
1169 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", RawValue);
1170 ShellStatus = SHELL_INVALID_PARAMETER;
1171 } else {
1172 Handle = ConvertHandleIndexToHandle ((UINTN) Intermediate);
1173 if (Handle == NULL) {
1174 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", RawValue);
1175 ShellStatus = SHELL_INVALID_PARAMETER;
1176 } else {
1177 //
1178 // Print information by handle.
1179 //
1180 DoDhByHandle (Handle, VerboseFlag, SfoFlag, Language, DriverFlag, FALSE);
1181 }
1182 }
1183 }
1184 }
1185
1186 ShellCommandLineFreeVarList (Package);
1187 SHELL_FREE_NON_NULL(Language);
1188 }
1189
1190 return (ShellStatus);
1191 }