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