]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c
ShellPkg/for: Fix potential null pointer deference
[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 VOID *Instance;
290 CHAR16 InstanceStr[17];
291
292 ProtocolGuidArray = NULL;
293 RetVal = NULL;
294 Size = 0;
295
296 Status = gBS->ProtocolsPerHandle (
297 TheHandle,
298 &ProtocolGuidArray,
299 &ArrayCount
300 );
301 if (!EFI_ERROR (Status)) {
302 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
303 Temp = GetStringNameFromGuid(ProtocolGuidArray[ProtocolIndex], Language);
304 ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
305 if (Size != 0) {
306 StrnCatGrow(&RetVal, &Size, Separator, 0);
307 }
308 StrnCatGrow(&RetVal, &Size, L"%H", 0);
309 if (Temp == NULL) {
310 UnicodeSPrint (GuidStr, sizeof (GuidStr), L"%g", ProtocolGuidArray[ProtocolIndex]);
311 StrnCatGrow (&RetVal, &Size, GuidStr, 0);
312 } else {
313 StrnCatGrow(&RetVal, &Size, Temp, 0);
314 FreePool(Temp);
315 }
316 StrnCatGrow(&RetVal, &Size, L"%N", 0);
317
318 if(Verbose) {
319 Status = gBS->HandleProtocol (TheHandle, ProtocolGuidArray[ProtocolIndex], &Instance);
320 if (!EFI_ERROR (Status)) {
321 StrnCatGrow (&RetVal, &Size, L"(%H", 0);
322 UnicodeSPrint (InstanceStr, sizeof (InstanceStr), L"%x", Instance);
323 StrnCatGrow (&RetVal, &Size, InstanceStr, 0);
324 StrnCatGrow (&RetVal, &Size, L"%N)", 0);
325 }
326 }
327
328 if (ExtraInfo) {
329 Temp = GetProtocolInformationDump(TheHandle, ProtocolGuidArray[ProtocolIndex], Verbose);
330 if (Temp != NULL) {
331 ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
332 if (!Verbose) {
333 StrnCatGrow(&RetVal, &Size, L"(", 0);
334 StrnCatGrow(&RetVal, &Size, Temp, 0);
335 StrnCatGrow(&RetVal, &Size, L")", 0);
336 } else {
337 StrnCatGrow(&RetVal, &Size, Separator, 0);
338 StrnCatGrow(&RetVal, &Size, Temp, 0);
339 }
340 FreePool(Temp);
341 }
342 }
343 }
344 }
345
346 SHELL_FREE_NON_NULL(ProtocolGuidArray);
347
348 if (RetVal == NULL) {
349 return (NULL);
350 }
351
352 ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
353 StrnCatGrow(&RetVal, &Size, Separator, 0);
354 return (RetVal);
355 }
356
357 /**
358 Gets the name of the loaded image.
359
360 @param[in] TheHandle The handle of the driver to get info on.
361 @param[out] Name The pointer to the pointer. Valid upon a successful return.
362
363 @retval EFI_SUCCESS The operation was successful.
364 **/
365 EFI_STATUS
366 GetDriverImageName (
367 IN EFI_HANDLE TheHandle,
368 OUT CHAR16 **Name
369 )
370 {
371 // get loaded image and devicepathtotext on image->Filepath
372 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
373 EFI_STATUS Status;
374 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
375
376 if (TheHandle == NULL || Name == NULL) {
377 return (EFI_INVALID_PARAMETER);
378 }
379
380 Status = gBS->OpenProtocol (
381 TheHandle,
382 &gEfiLoadedImageProtocolGuid,
383 (VOID **) &LoadedImage,
384 gImageHandle,
385 NULL,
386 EFI_OPEN_PROTOCOL_GET_PROTOCOL
387 );
388 if (EFI_ERROR(Status)) {
389 return (Status);
390 }
391 DevicePath = LoadedImage->FilePath;
392 *Name = ConvertDevicePathToText(DevicePath, TRUE, TRUE);
393 return (EFI_SUCCESS);
394 }
395
396 /**
397 Display driver model information for a given handle.
398
399 @param[in] Handle The handle to display info on.
400 @param[in] BestName Use the best name?
401 @param[in] Language The language to output in.
402 **/
403 EFI_STATUS
404 DisplayDriverModelHandle (
405 IN EFI_HANDLE Handle,
406 IN BOOLEAN BestName,
407 IN CONST CHAR8 *Language OPTIONAL
408 )
409 {
410 EFI_STATUS Status;
411 BOOLEAN ConfigurationStatus;
412 BOOLEAN DiagnosticsStatus;
413 UINTN DriverBindingHandleCount;
414 EFI_HANDLE *DriverBindingHandleBuffer;
415 UINTN ParentControllerHandleCount;
416 EFI_HANDLE *ParentControllerHandleBuffer;
417 UINTN ChildControllerHandleCount;
418 EFI_HANDLE *ChildControllerHandleBuffer;
419 CHAR16 *TempStringPointer;
420 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
421 UINTN Index;
422 CHAR16 *DriverName;
423 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
424 UINTN NumberOfChildren;
425 UINTN HandleIndex;
426 UINTN ControllerHandleCount;
427 EFI_HANDLE *ControllerHandleBuffer;
428 UINTN ChildIndex;
429 BOOLEAN Image;
430
431 DriverName = NULL;
432
433 //
434 // See if Handle is a device handle and display its details.
435 //
436 DriverBindingHandleBuffer = NULL;
437 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
438 Handle,
439 &DriverBindingHandleCount,
440 &DriverBindingHandleBuffer
441 );
442
443 ParentControllerHandleBuffer = NULL;
444 Status = PARSE_HANDLE_DATABASE_PARENTS (
445 Handle,
446 &ParentControllerHandleCount,
447 &ParentControllerHandleBuffer
448 );
449
450 ChildControllerHandleBuffer = NULL;
451 Status = ParseHandleDatabaseForChildControllers (
452 Handle,
453 &ChildControllerHandleCount,
454 &ChildControllerHandleBuffer
455 );
456
457 DiagnosticsStatus = FALSE;
458 ConfigurationStatus = FALSE;
459
460 if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverConfigurationProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
461 ConfigurationStatus = TRUE;
462 }
463 if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverConfiguration2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
464 ConfigurationStatus = TRUE;
465 }
466 if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverDiagnosticsProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
467 DiagnosticsStatus = TRUE;
468 }
469 if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverDiagnostics2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
470 DiagnosticsStatus = TRUE;
471 }
472
473 Status = EFI_SUCCESS;
474
475 if (DriverBindingHandleCount > 0 || ParentControllerHandleCount > 0 || ChildControllerHandleCount > 0) {
476
477
478
479 DevicePath = NULL;
480 TempStringPointer = NULL;
481 Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID**)&DevicePath);
482
483 Status = gEfiShellProtocol->GetDeviceName(Handle, EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
484 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DRIVER1), gShellDriver1HiiHandle, TempStringPointer!=NULL?TempStringPointer:L"<Unknown>");
485 SHELL_FREE_NON_NULL(TempStringPointer);
486
487 TempStringPointer = ConvertDevicePathToText(DevicePath, TRUE, FALSE);
488 ShellPrintHiiEx(
489 -1,
490 -1,
491 NULL,
492 STRING_TOKEN (STR_DH_OUTPUT_DRIVER2),
493 gShellDriver1HiiHandle,
494 TempStringPointer!=NULL?TempStringPointer:L"<None>",
495 ParentControllerHandleCount == 0?L"ROOT":(ChildControllerHandleCount > 0)?L"BUS":L"DEVICE",
496 ConfigurationStatus?L"YES":L"NO",
497 DiagnosticsStatus?L"YES":L"NO"
498 );
499
500 SHELL_FREE_NON_NULL(TempStringPointer);
501
502 if (DriverBindingHandleCount == 0) {
503 ShellPrintHiiEx(
504 -1,
505 -1,
506 NULL,
507 STRING_TOKEN (STR_DH_OUTPUT_DRIVER3),
508 gShellDriver1HiiHandle,
509 L"<None>"
510 );
511 } else {
512 ShellPrintHiiEx(
513 -1,
514 -1,
515 NULL,
516 STRING_TOKEN (STR_DH_OUTPUT_DRIVER3),
517 gShellDriver1HiiHandle,
518 L""
519 );
520 for (Index = 0; Index < DriverBindingHandleCount; Index++) {
521 Image = FALSE;
522 Status = GetDriverName (
523 DriverBindingHandleBuffer[Index],
524 Language,
525 &DriverName
526 );
527 if (EFI_ERROR (Status)) {
528 Status = GetDriverImageName (
529 DriverBindingHandleBuffer[Index],
530 &DriverName
531 );
532 if (EFI_ERROR (Status)) {
533 DriverName = NULL;
534 }
535 }
536
537 if (Image) {
538 ShellPrintHiiEx(
539 -1,
540 -1,
541 NULL,
542 STRING_TOKEN (STR_DH_OUTPUT_DRIVER4A),
543 gShellDriver1HiiHandle,
544 ConvertHandleToHandleIndex (DriverBindingHandleBuffer[Index]),
545 DriverName!=NULL?DriverName:L"<Unknown>"
546 );
547 } else {
548 ShellPrintHiiEx(
549 -1,
550 -1,
551 NULL,
552 STRING_TOKEN (STR_DH_OUTPUT_DRIVER4B),
553 gShellDriver1HiiHandle,
554 ConvertHandleToHandleIndex (DriverBindingHandleBuffer[Index]),
555 DriverName!=NULL?DriverName:L"<Unknown>"
556 );
557 }
558 SHELL_FREE_NON_NULL(DriverName);
559 }
560 }
561
562 if (ParentControllerHandleCount == 0) {
563 ShellPrintHiiEx(
564 -1,
565 -1,
566 NULL,
567 STRING_TOKEN (STR_DH_OUTPUT_DRIVER5),
568 gShellDriver1HiiHandle,
569 L"<None>"
570 );
571 } else {
572 ShellPrintHiiEx(
573 -1,
574 -1,
575 NULL,
576 STRING_TOKEN (STR_DH_OUTPUT_DRIVER5),
577 gShellDriver1HiiHandle,
578 L""
579 );
580 for (Index = 0; Index < ParentControllerHandleCount; Index++) {
581 Status = gEfiShellProtocol->GetDeviceName(ParentControllerHandleBuffer[Index], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
582 ShellPrintHiiEx(
583 -1,
584 -1,
585 NULL,
586 STRING_TOKEN (STR_DH_OUTPUT_DRIVER5B),
587 gShellDriver1HiiHandle,
588 ConvertHandleToHandleIndex (ParentControllerHandleBuffer[Index]),
589 TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
590 );
591 SHELL_FREE_NON_NULL(TempStringPointer);
592 }
593 }
594
595 if (ChildControllerHandleCount == 0) {
596 ShellPrintHiiEx(
597 -1,
598 -1,
599 NULL,
600 STRING_TOKEN (STR_DH_OUTPUT_DRIVER6),
601 gShellDriver1HiiHandle,
602 L"<None>"
603 );
604 } else {
605 ShellPrintHiiEx(
606 -1,
607 -1,
608 NULL,
609 STRING_TOKEN (STR_DH_OUTPUT_DRIVER6),
610 gShellDriver1HiiHandle,
611 L""
612 );
613 for (Index = 0; Index < ChildControllerHandleCount; Index++) {
614 Status = gEfiShellProtocol->GetDeviceName(ChildControllerHandleBuffer[Index], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
615 ShellPrintHiiEx(
616 -1,
617 -1,
618 NULL,
619 STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B),
620 gShellDriver1HiiHandle,
621 ConvertHandleToHandleIndex (ChildControllerHandleBuffer[Index]),
622 TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
623 );
624 SHELL_FREE_NON_NULL(TempStringPointer);
625 }
626 }
627 }
628
629 SHELL_FREE_NON_NULL(DriverBindingHandleBuffer);
630
631 SHELL_FREE_NON_NULL(ParentControllerHandleBuffer);
632
633 SHELL_FREE_NON_NULL(ChildControllerHandleBuffer);
634
635 if (EFI_ERROR (Status)) {
636 return Status;
637 }
638 //
639 // See if Handle is a driver binding handle and display its details.
640 //
641 Status = gBS->OpenProtocol (
642 Handle,
643 &gEfiDriverBindingProtocolGuid,
644 (VOID **) &DriverBinding,
645 NULL,
646 NULL,
647 EFI_OPEN_PROTOCOL_GET_PROTOCOL
648 );
649 if (EFI_ERROR (Status)) {
650 return EFI_SUCCESS;
651 }
652
653 NumberOfChildren = 0;
654 ControllerHandleBuffer = NULL;
655 Status = PARSE_HANDLE_DATABASE_DEVICES (
656 Handle,
657 &ControllerHandleCount,
658 &ControllerHandleBuffer
659 );
660 if (ControllerHandleCount > 0) {
661 for (HandleIndex = 0; HandleIndex < ControllerHandleCount; HandleIndex++) {
662 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
663 Handle,
664 ControllerHandleBuffer[HandleIndex],
665 &ChildControllerHandleCount,
666 NULL
667 );
668 NumberOfChildren += ChildControllerHandleCount;
669 }
670 }
671
672 Status = GetDriverName (Handle, Language, &DriverName);
673 if (EFI_ERROR (Status)) {
674 DriverName = NULL;
675 }
676
677 ShellPrintHiiEx(
678 -1,
679 -1,
680 NULL,
681 STRING_TOKEN (STR_DH_OUTPUT_DRIVER7),
682 gShellDriver1HiiHandle,
683 ConvertHandleToHandleIndex(Handle),
684 DriverName!=NULL?DriverName:L"<Unknown>"
685 );
686 SHELL_FREE_NON_NULL(DriverName);
687 Status = GetDriverImageName (
688 Handle,
689 &DriverName
690 );
691 if (EFI_ERROR (Status)) {
692 DriverName = NULL;
693 }
694 ShellPrintHiiEx(
695 -1,
696 -1,
697 NULL,
698 STRING_TOKEN (STR_DH_OUTPUT_DRIVER7B),
699 gShellDriver1HiiHandle,
700 DriverName!=NULL?DriverName:L"<Unknown>"
701 );
702 SHELL_FREE_NON_NULL(DriverName);
703
704 ShellPrintHiiEx(
705 -1,
706 -1,
707 NULL,
708 STRING_TOKEN (STR_DH_OUTPUT_DRIVER8),
709 gShellDriver1HiiHandle,
710 DriverBinding->Version,
711 NumberOfChildren > 0?L"Bus":ControllerHandleCount > 0?L"Device":L"<Unknown>",
712 ConfigurationStatus?L"YES":L"NO",
713 DiagnosticsStatus?L"YES":L"NO"
714 );
715
716 if (ControllerHandleCount == 0) {
717 ShellPrintHiiEx(
718 -1,
719 -1,
720 NULL,
721 STRING_TOKEN (STR_DH_OUTPUT_DRIVER9),
722 gShellDriver1HiiHandle,
723 L"None"
724 );
725 } else {
726 ShellPrintHiiEx(
727 -1,
728 -1,
729 NULL,
730 STRING_TOKEN (STR_DH_OUTPUT_DRIVER9),
731 gShellDriver1HiiHandle,
732 L""
733 );
734 for (HandleIndex = 0; HandleIndex < ControllerHandleCount; HandleIndex++) {
735 Status = gEfiShellProtocol->GetDeviceName(ControllerHandleBuffer[HandleIndex], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
736
737 ShellPrintHiiEx(
738 -1,
739 -1,
740 NULL,
741 STRING_TOKEN (STR_DH_OUTPUT_DRIVER9B),
742 gShellDriver1HiiHandle,
743 ConvertHandleToHandleIndex(ControllerHandleBuffer[HandleIndex]),
744 TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
745 );
746 SHELL_FREE_NON_NULL(TempStringPointer);
747
748 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
749 Handle,
750 ControllerHandleBuffer[HandleIndex],
751 &ChildControllerHandleCount,
752 &ChildControllerHandleBuffer
753 );
754 if (!EFI_ERROR (Status)) {
755 for (ChildIndex = 0; ChildIndex < ChildControllerHandleCount; ChildIndex++) {
756 Status = gEfiShellProtocol->GetDeviceName(ChildControllerHandleBuffer[ChildIndex], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
757
758 ShellPrintHiiEx(
759 -1,
760 -1,
761 NULL,
762 STRING_TOKEN (STR_DH_OUTPUT_DRIVER6C),
763 gShellDriver1HiiHandle,
764 ConvertHandleToHandleIndex(ChildControllerHandleBuffer[ChildIndex]),
765 TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
766 );
767 SHELL_FREE_NON_NULL(TempStringPointer);
768 }
769
770 SHELL_FREE_NON_NULL (ChildControllerHandleBuffer);
771 }
772 }
773
774 SHELL_FREE_NON_NULL (ControllerHandleBuffer);
775 }
776
777 return EFI_SUCCESS;
778 }
779
780 /**
781 Display information for a handle.
782
783 @param[in] TheHandle The handles to show info on.
784 @param[in] Verbose TRUE for extra info, FALSE otherwise.
785 @param[in] Sfo TRUE to output in standard format output (spec).
786 @param[in] Language Language string per UEFI specification.
787 @param[in] DriverInfo TRUE to show all info about the handle.
788 @param[in] Multiple TRUE indicates more than will be output,
789 FALSE for a single one.
790 **/
791 VOID
792 DoDhByHandle(
793 IN CONST EFI_HANDLE TheHandle,
794 IN CONST BOOLEAN Verbose,
795 IN CONST BOOLEAN Sfo,
796 IN CONST CHAR8 *Language,
797 IN CONST BOOLEAN DriverInfo,
798 IN CONST BOOLEAN Multiple
799 )
800 {
801 CHAR16 *ProtocolInfoString;
802
803 ProtocolInfoString = NULL;
804
805 if (!Sfo) {
806 if (Multiple) {
807 ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L" ", Verbose, TRUE);
808 ShellPrintHiiEx(
809 -1,
810 -1,
811 NULL,
812 STRING_TOKEN (STR_DH_OUTPUT),
813 gShellDriver1HiiHandle,
814 ConvertHandleToHandleIndex(TheHandle),
815 ProtocolInfoString==NULL?L"":ProtocolInfoString
816 );
817 } else {
818 ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, Verbose ? L"\r\n" : L" ", Verbose, TRUE);
819 if (Verbose) {
820 ShellPrintHiiEx(
821 -1,
822 -1,
823 NULL,
824 STRING_TOKEN (STR_DH_OUTPUT_SINGLE),
825 gShellDriver1HiiHandle,
826 ConvertHandleToHandleIndex(TheHandle),
827 TheHandle,
828 ProtocolInfoString==NULL?L"":ProtocolInfoString
829 );
830 } else {
831 ShellPrintHiiEx(
832 -1,
833 -1,
834 NULL,
835 STRING_TOKEN (STR_DH_OUTPUT_SINGLE_D),
836 gShellDriver1HiiHandle,
837 ConvertHandleToHandleIndex(TheHandle),
838 ProtocolInfoString==NULL?L"":ProtocolInfoString
839 );
840 }
841 }
842
843 if (DriverInfo) {
844 DisplayDriverModelHandle ((EFI_HANDLE)TheHandle, TRUE, Language);
845 }
846 } else {
847 ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L";", FALSE, FALSE);
848 ShellPrintHiiEx(
849 -1,
850 -1,
851 NULL,
852 STRING_TOKEN (STR_DH_OUTPUT_SFO),
853 gShellDriver1HiiHandle,
854 Multiple ?L"HandlesInfo":L"HandleInfo",
855 L"DriverName",
856 L"ControllerName",
857 ConvertHandleToHandleIndex(TheHandle),
858 L"DevPath",
859 ProtocolInfoString==NULL?L"":ProtocolInfoString
860 );
861 }
862
863 if (ProtocolInfoString != NULL) {
864 FreePool(ProtocolInfoString);
865 }
866 }
867
868 /**
869 Display information for all handles on a list.
870
871 @param[in] HandleList The NULL-terminated list of handles.
872 @param[in] Verbose TRUE for extra info, FALSE otherwise.
873 @param[in] Sfo TRUE to output in standard format output (spec).
874 @param[in] Language Language string per UEFI specification.
875 @param[in] DriverInfo TRUE to show all info about the handle.
876
877 @retval SHELL_SUCCESS The operation was successful.
878 @retval SHELL_ABORTED The operation was aborted.
879 **/
880 SHELL_STATUS
881 DoDhForHandleList(
882 IN CONST EFI_HANDLE *HandleList,
883 IN CONST BOOLEAN Verbose,
884 IN CONST BOOLEAN Sfo,
885 IN CONST CHAR8 *Language,
886 IN CONST BOOLEAN DriverInfo
887 )
888 {
889 CONST EFI_HANDLE *HandleWalker;
890 SHELL_STATUS ShellStatus;
891
892 ShellStatus = SHELL_SUCCESS;
893 for (HandleWalker = HandleList; HandleWalker != NULL && *HandleWalker != NULL; HandleWalker++) {
894 DoDhByHandle (*HandleWalker, Verbose, Sfo, Language, DriverInfo, TRUE);
895 if (ShellGetExecutionBreakFlag ()) {
896 ShellStatus = SHELL_ABORTED;
897 break;
898 }
899 }
900 return (ShellStatus);
901 }
902
903 /**
904 Display information for a GUID of protocol.
905
906 @param[in] Guid The pointer to the name of the protocol.
907 @param[in] Verbose TRUE for extra info, FALSE otherwise.
908 @param[in] Sfo TRUE to output in standard format output (spec).
909 @param[in] Language Language string per UEFI specification.
910 @param[in] DriverInfo TRUE to show all info about the handle.
911
912 @retval SHELL_SUCCESS The operation was successful.
913 @retval SHELL_NOT_FOUND The GUID was not found.
914 @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
915 **/
916 SHELL_STATUS
917 DoDhByProtocolGuid(
918 IN CONST GUID *Guid,
919 IN CONST BOOLEAN Verbose,
920 IN CONST BOOLEAN Sfo,
921 IN CONST CHAR8 *Language,
922 IN CONST BOOLEAN DriverInfo
923 )
924 {
925 CHAR16 *Name;
926 SHELL_STATUS ShellStatus;
927 EFI_HANDLE *HandleList;
928
929 if (!Sfo) {
930 if (Guid == NULL) {
931 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_ALL_HEADER), gShellDriver1HiiHandle);
932 } else {
933 Name = GetStringNameFromGuid (Guid, NULL);
934 if (Name == NULL) {
935 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_GUID_HEADER), gShellDriver1HiiHandle, Guid);
936 } else {
937 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_NAME_HEADER), gShellDriver1HiiHandle, Name);
938 }
939 }
940 }
941 HandleList = GetHandleListByProtocol(Guid);
942 ShellStatus = DoDhForHandleList(HandleList, Verbose, Sfo, Language, DriverInfo);
943 SHELL_FREE_NON_NULL(HandleList);
944
945 return ShellStatus;
946 }
947
948 /**
949 Function to determine use which method to print information.
950 If Protocol is NULL, The function will print all information.
951
952 @param[in] Protocol The pointer to the name or GUID of protocol or NULL.
953 @param[in] Verbose TRUE for extra info, FALSE otherwise.
954 @param[in] Sfo TRUE to output in standard format output (spec).
955 @param[in] Language Language string per UEFI specification.
956 @param[in] DriverInfo TRUE to show all info about the handle.
957
958 @retval SHELL_SUCCESS The operation was successful.
959 @retval SHELL_NOT_FOUND The protocol was not found.
960 @retval SHELL_INVALID_PARAMETER Protocol is invalid parameter.
961 **/
962 SHELL_STATUS
963 DoDhByProtocol (
964 IN CONST CHAR16 *Protocol,
965 IN CONST BOOLEAN Verbose,
966 IN CONST BOOLEAN Sfo,
967 IN CONST CHAR8 *Language,
968 IN CONST BOOLEAN DriverInfo
969 )
970 {
971 EFI_GUID Guid;
972 EFI_GUID *GuidPtr;
973 EFI_STATUS Status;
974
975 if (Protocol == NULL) {
976 return DoDhByProtocolGuid (NULL, Verbose, Sfo, Language, DriverInfo);
977 } else {
978 Status = ConvertStrToGuid (Protocol, &Guid);
979 if (!EFI_ERROR (Status)) {
980 GuidPtr = &Guid;
981 } else {
982 //
983 // Protocol is a Name, convert it to GUID
984 //
985 Status = GetGuidFromStringName (Protocol, Language, &GuidPtr);
986 if (EFI_ERROR(Status)) {
987 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_NAME_FOUND), gShellDriver1HiiHandle, Protocol);
988 return (SHELL_NOT_FOUND);
989 }
990 }
991
992 return DoDhByProtocolGuid (GuidPtr, Verbose, Sfo, Language, DriverInfo);
993 }
994 }
995
996 /**
997 Function to display decode information by Protocol.
998 The parameter Protocol is either a GUID or the name of protocol.
999 If the parameter Protocol is NULL, the function will print all
1000 decode information.
1001
1002 @param[in] Protocol The pointer to the name or GUID of protocol.
1003 @param[in] Language Language string per UEFI specification.
1004
1005 @retval SHELL_SUCCESS The operation was successful.
1006 @retval SHELL_OUT_OT_RESOURCES A memory allocation failed.
1007 **/
1008 SHELL_STATUS
1009 DoDecodeByProtocol(
1010 IN CONST CHAR16 *Protocol,
1011 IN CONST CHAR8 *Language
1012 )
1013 {
1014 EFI_STATUS Status;
1015 EFI_GUID *Guids;
1016 EFI_GUID Guid;
1017 UINTN Counts;
1018 UINTN Index;
1019 CHAR16 *Name;
1020
1021 if (Protocol == NULL) {
1022 Counts = 0;
1023 Status = GetAllMappingGuids (NULL, &Counts);
1024 if (Status == EFI_BUFFER_TOO_SMALL) {
1025 Guids = AllocatePool (Counts * sizeof(EFI_GUID));
1026 if (Guids == NULL) {
1027 return SHELL_OUT_OF_RESOURCES;
1028 }
1029
1030 Status = GetAllMappingGuids (Guids, &Counts);
1031 if (Status == EFI_SUCCESS) {
1032 for (Index = 0; Index < Counts; Index++) {
1033 Name = GetStringNameFromGuid (&Guids[Index], Language);
1034 if (Name != NULL) {
1035 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DECODE), gShellDriver1HiiHandle, Name, &Guids[Index]);
1036 } else {
1037 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_GUID_FOUND), gShellDriver1HiiHandle, &Guids[Index]);
1038 }
1039 SHELL_FREE_NON_NULL (Name);
1040 }
1041 }
1042 FreePool (Guids);
1043 }
1044 } else {
1045 if (ConvertStrToGuid (Protocol, &Guid) == EFI_SUCCESS) {
1046 Name = GetStringNameFromGuid (&Guid, Language);
1047 if (Name != NULL) {
1048 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DECODE), gShellDriver1HiiHandle, Name, &Guid);
1049 } else {
1050 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_GUID_FOUND), gShellDriver1HiiHandle, &Guid);
1051 }
1052 SHELL_FREE_NON_NULL(Name);
1053 } else {
1054 Status = GetGuidFromStringName (Protocol, Language, &Guids);
1055 if (Status == EFI_SUCCESS) {
1056 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DECODE), gShellDriver1HiiHandle, Protocol, Guids);
1057 } else {
1058 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_NAME_FOUND), gShellDriver1HiiHandle, Protocol);
1059 }
1060 }
1061 }
1062
1063 return SHELL_SUCCESS;
1064 }
1065
1066 /**
1067 Function for 'dh' command.
1068
1069 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1070 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1071 **/
1072 SHELL_STATUS
1073 EFIAPI
1074 ShellCommandRunDh (
1075 IN EFI_HANDLE ImageHandle,
1076 IN EFI_SYSTEM_TABLE *SystemTable
1077 )
1078 {
1079 EFI_STATUS Status;
1080 LIST_ENTRY *Package;
1081 CHAR16 *ProblemParam;
1082 SHELL_STATUS ShellStatus;
1083 CHAR8 *Language;
1084 CONST CHAR16 *Lang;
1085 CONST CHAR16 *RawValue;
1086 CONST CHAR16 *ProtocolVal;
1087 BOOLEAN SfoFlag;
1088 BOOLEAN DriverFlag;
1089 BOOLEAN VerboseFlag;
1090 UINT64 Intermediate;
1091 EFI_HANDLE Handle;
1092
1093 ShellStatus = SHELL_SUCCESS;
1094 Status = EFI_SUCCESS;
1095 Language = NULL;
1096
1097 //
1098 // initialize the shell lib (we must be in non-auto-init...)
1099 //
1100 Status = ShellInitialize();
1101 ASSERT_EFI_ERROR(Status);
1102
1103 Status = CommandInit();
1104 ASSERT_EFI_ERROR(Status);
1105
1106 //
1107 // parse the command line
1108 //
1109 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
1110 if (EFI_ERROR(Status)) {
1111 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
1112 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"dh", ProblemParam);
1113 FreePool(ProblemParam);
1114 ShellStatus = SHELL_INVALID_PARAMETER;
1115 } else {
1116 ASSERT(FALSE);
1117 }
1118 } else {
1119 if (ShellCommandLineGetCount(Package) > 2) {
1120 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh");
1121 ShellCommandLineFreeVarList (Package);
1122 return (SHELL_INVALID_PARAMETER);
1123 }
1124
1125 if (ShellCommandLineGetFlag(Package, L"-l")) {
1126 Lang = ShellCommandLineGetValue(Package, L"-l");
1127 if (Lang != NULL) {
1128 Language = AllocateZeroPool(StrSize(Lang));
1129 AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
1130 } else {
1131 ASSERT(Language == NULL);
1132 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", L"-l");
1133 ShellCommandLineFreeVarList(Package);
1134 return (SHELL_INVALID_PARAMETER);
1135 }
1136 } else {
1137 Language = AllocateZeroPool(10);
1138 AsciiSPrint(Language, 10, "en-us");
1139 }
1140
1141 SfoFlag = ShellCommandLineGetFlag (Package, L"-sfo");
1142 DriverFlag = ShellCommandLineGetFlag (Package, L"-d");
1143 VerboseFlag = (BOOLEAN)(ShellCommandLineGetFlag (Package, L"-v") || ShellCommandLineGetFlag (Package, L"-verbose"));
1144 RawValue = ShellCommandLineGetRawValue (Package, 1);
1145 ProtocolVal = ShellCommandLineGetValue (Package, L"-p");
1146
1147 if (RawValue == NULL) {
1148 if (ShellCommandLineGetFlag (Package, L"-p") && (ProtocolVal == NULL)) {
1149 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", L"-p");
1150 ShellStatus = SHELL_INVALID_PARAMETER;
1151 } else {
1152 //
1153 // Print information by protocol, The ProtocolVal maybe is name or GUID or NULL.
1154 //
1155 ShellStatus = DoDhByProtocol (ProtocolVal, VerboseFlag, SfoFlag, Language, DriverFlag);
1156 }
1157 } else if ((RawValue != NULL) &&
1158 (gUnicodeCollation->StriColl(gUnicodeCollation, L"decode", (CHAR16 *) RawValue) == 0)) {
1159 if (ShellCommandLineGetFlag (Package, L"-p") && (ProtocolVal == NULL)) {
1160 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", L"-p");
1161 ShellStatus = SHELL_INVALID_PARAMETER;
1162 } else {
1163 //
1164 // Print decode informatino by protocol.
1165 //
1166 ShellStatus = DoDecodeByProtocol (ProtocolVal, Language);
1167 }
1168 } else {
1169 if (ShellCommandLineGetFlag (Package, L"-p")) {
1170 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh");
1171 ShellStatus = SHELL_INVALID_PARAMETER;
1172 } else {
1173 Status = ShellConvertStringToUint64 (RawValue, &Intermediate, TRUE, FALSE);
1174 if (EFI_ERROR(Status)) {
1175 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", RawValue);
1176 ShellStatus = SHELL_INVALID_PARAMETER;
1177 } else {
1178 Handle = ConvertHandleIndexToHandle ((UINTN) Intermediate);
1179 if (Handle == NULL) {
1180 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", RawValue);
1181 ShellStatus = SHELL_INVALID_PARAMETER;
1182 } else {
1183 //
1184 // Print information by handle.
1185 //
1186 DoDhByHandle (Handle, VerboseFlag, SfoFlag, Language, DriverFlag, FALSE);
1187 }
1188 }
1189 }
1190 }
1191
1192 ShellCommandLineFreeVarList (Package);
1193 SHELL_FREE_NON_NULL(Language);
1194 }
1195
1196 return (ShellStatus);
1197 }