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