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