• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 - 2014, 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 /**
45   Get the name of a driver by it's handle.
46 
47   If a name is found the memory must be callee freed.
48 
49   @param[in] TheHandle    The driver's handle.
50   @param[in] Language     The language to use.
51   @param[in] NameFound    Upon a successful return the name found.
52 
53   @retval EFI_SUCCESS     The name was found.
54 **/
55 EFI_STATUS
56 EFIAPI
GetDriverName(IN EFI_HANDLE TheHandle,IN CONST CHAR8 * Language,IN CHAR16 ** NameFound)57 GetDriverName (
58   IN EFI_HANDLE   TheHandle,
59   IN CONST CHAR8  *Language,
60   IN CHAR16       **NameFound
61   )
62 {
63   CHAR8                             *Lang;
64   EFI_STATUS                        Status;
65   EFI_COMPONENT_NAME2_PROTOCOL      *CompName2;
66   CHAR16                            *NameToReturn;
67   //
68   // Go through those handles until we get one that passes for GetComponentName
69   //
70   Status = gBS->OpenProtocol(
71     TheHandle,
72     &gEfiComponentName2ProtocolGuid,
73     (VOID**)&CompName2,
74     gImageHandle,
75     NULL,
76     EFI_OPEN_PROTOCOL_GET_PROTOCOL);
77   if (EFI_ERROR(Status)) {
78     Status = gBS->OpenProtocol(
79       TheHandle,
80       &gEfiComponentNameProtocolGuid,
81       (VOID**)&CompName2,
82       gImageHandle,
83       NULL,
84       EFI_OPEN_PROTOCOL_GET_PROTOCOL);
85   }
86 
87   if (EFI_ERROR(Status)) {
88     return (EFI_NOT_FOUND);
89   }
90   Lang = GetBestLanguageForDriver (CompName2->SupportedLanguages, Language, FALSE);
91   Status = CompName2->GetDriverName(CompName2, Lang, &NameToReturn);
92   FreePool(Lang);
93 
94   if (!EFI_ERROR(Status) && NameToReturn != NULL) {
95     *NameFound = NULL;
96     StrnCatGrow(NameFound, NULL, NameToReturn, 0);
97   }
98   return (Status);
99 }
100 
101 /**
102   Discover if a protocol guid is one of the UEFI Driver Model Protocols.
103 
104   @param[in] Guid   The guid to test.
105 
106   @retval TRUE      The guid does represent a driver model protocol.
107   @retval FALSE     The guid does not represent a driver model protocol.
108 **/
109 BOOLEAN
110 EFIAPI
IsDriverProt(IN CONST EFI_GUID * Guid)111 IsDriverProt (
112   IN CONST EFI_GUID *Guid
113   )
114 {
115   CONST EFI_GUID            **GuidWalker;
116   BOOLEAN                   GuidFound;
117   GuidFound = FALSE;
118   for (GuidWalker = UefiDriverModelProtocolsGuidArray
119     ;  GuidWalker != NULL && *GuidWalker != NULL
120     ;  GuidWalker++
121    ){
122     if (CompareGuid(*GuidWalker, Guid)) {
123       GuidFound = TRUE;
124       break;
125     }
126   }
127   return (GuidFound);
128 }
129 
130 /**
131   Get information for a handle.
132 
133   @param[in] TheHandle        The handles to show info on.
134   @param[in] Language         Language string per UEFI specification.
135   @param[in] Seperator        Separator string between information blocks.
136   @param[in] Verbose          TRUE for extra info, FALSE otherwise.
137   @param[in] ExtraInfo        TRUE for extra info, FALSE otherwise.
138 
139   @retval SHELL_SUCCESS           The operation was successful.
140   @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
141 **/
142 CHAR16*
143 EFIAPI
GetProtocolInfoString(IN CONST EFI_HANDLE TheHandle,IN CONST CHAR8 * Language,IN CONST CHAR16 * Seperator,IN CONST BOOLEAN Verbose,IN CONST BOOLEAN ExtraInfo)144 GetProtocolInfoString(
145   IN CONST EFI_HANDLE TheHandle,
146   IN CONST CHAR8      *Language,
147   IN CONST CHAR16     *Seperator,
148   IN CONST BOOLEAN    Verbose,
149   IN CONST BOOLEAN    ExtraInfo
150   )
151 {
152   EFI_GUID                  **ProtocolGuidArray;
153   UINTN                     ArrayCount;
154   UINTN                     ProtocolIndex;
155   EFI_STATUS                Status;
156   CHAR16                    *RetVal;
157   UINTN                     Size;
158   CHAR16                    *Temp;
159 
160   ProtocolGuidArray = NULL;
161   RetVal            = NULL;
162   Size              = 0;
163 
164   Status = gBS->ProtocolsPerHandle (
165                 TheHandle,
166                 &ProtocolGuidArray,
167                 &ArrayCount
168                );
169   if (!EFI_ERROR (Status)) {
170     for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
171       Temp = GetStringNameFromGuid(ProtocolGuidArray[ProtocolIndex], Language);
172       if (Temp != NULL) {
173         ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
174         if (Size != 0) {
175           StrnCatGrow(&RetVal, &Size, Seperator, 0);
176         }
177         StrnCatGrow(&RetVal, &Size, L"%H", 0);
178         StrnCatGrow(&RetVal, &Size, Temp, 0);
179         StrnCatGrow(&RetVal, &Size, L"%N", 0);
180         FreePool(Temp);
181       }
182       if (ExtraInfo) {
183         Temp = GetProtocolInformationDump(TheHandle, ProtocolGuidArray[ProtocolIndex], Verbose);
184         if (Temp != NULL) {
185           ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
186           if (!Verbose) {
187             StrnCatGrow(&RetVal, &Size, L"(", 0);
188             StrnCatGrow(&RetVal, &Size, Temp, 0);
189             StrnCatGrow(&RetVal, &Size, L")\r\n", 0);
190           } else {
191             StrnCatGrow(&RetVal, &Size, Seperator, 0);
192             StrnCatGrow(&RetVal, &Size, Temp, 0);
193           }
194           FreePool(Temp);
195         }
196       }
197     }
198   }
199 
200   SHELL_FREE_NON_NULL(ProtocolGuidArray);
201 
202   if (RetVal == NULL) {
203     return (NULL);
204   }
205 
206   ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
207   StrnCatGrow(&RetVal, &Size, Seperator, 0);
208   return (RetVal);
209 }
210 
211 /**
212   Gets the name of the loaded image.
213 
214   @param[in] TheHandle    The handle of the driver to get info on.
215   @param[out] Name        The pointer to the pointer.  Valid upon a successful return.
216 
217   @retval EFI_SUCCESS     The operation was successful.
218 **/
219 EFI_STATUS
220 EFIAPI
GetDriverImageName(IN EFI_HANDLE TheHandle,OUT CHAR16 ** Name)221 GetDriverImageName (
222   IN EFI_HANDLE   TheHandle,
223   OUT CHAR16      **Name
224   )
225 {
226   // get loaded image and devicepathtotext on image->Filepath
227   EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
228   EFI_STATUS                Status;
229   EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
230 
231   if (TheHandle == NULL || Name == NULL) {
232     return (EFI_INVALID_PARAMETER);
233   }
234 
235   Status = gBS->OpenProtocol (
236                 TheHandle,
237                 &gEfiLoadedImageProtocolGuid,
238                 (VOID **) &LoadedImage,
239                 gImageHandle,
240                 NULL,
241                 EFI_OPEN_PROTOCOL_GET_PROTOCOL
242                );
243   if (EFI_ERROR(Status)) {
244     return (Status);
245   }
246   DevicePath = LoadedImage->FilePath;
247   *Name = ConvertDevicePathToText(DevicePath, TRUE, TRUE);
248   return (EFI_SUCCESS);
249 }
250 
251 /**
252   Display driver model information for a given handle.
253 
254   @param[in] Handle     The handle to display info on.
255   @param[in] BestName   Use the best name?
256   @param[in] Language   The language to output in.
257 **/
258 EFI_STATUS
259 EFIAPI
DisplayDriverModelHandle(IN EFI_HANDLE Handle,IN BOOLEAN BestName,IN CONST CHAR8 * Language OPTIONAL)260 DisplayDriverModelHandle (
261   IN EFI_HANDLE  Handle,
262   IN BOOLEAN     BestName,
263   IN CONST CHAR8 *Language OPTIONAL
264   )
265 {
266   EFI_STATUS                  Status;
267   BOOLEAN                     ConfigurationStatus;
268   BOOLEAN                     DiagnosticsStatus;
269   UINTN                       DriverBindingHandleCount;
270   EFI_HANDLE                  *DriverBindingHandleBuffer;
271   UINTN                       ParentControllerHandleCount;
272   EFI_HANDLE                  *ParentControllerHandleBuffer;
273   UINTN                       ChildControllerHandleCount;
274   EFI_HANDLE                  *ChildControllerHandleBuffer;
275   CHAR16                      *TempStringPointer;
276   EFI_DEVICE_PATH_PROTOCOL    *DevicePath;
277   UINTN                       Index;
278   CHAR16                      *DriverName;
279   EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
280   UINTN                       NumberOfChildren;
281   UINTN                       HandleIndex;
282   UINTN                       ControllerHandleCount;
283   EFI_HANDLE                  *ControllerHandleBuffer;
284   UINTN                       ChildIndex;
285   BOOLEAN                     Image;
286 
287   DriverName = NULL;
288 
289   //
290   // See if Handle is a device handle and display its details.
291   //
292   DriverBindingHandleBuffer = NULL;
293   Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
294             Handle,
295             &DriverBindingHandleCount,
296             &DriverBindingHandleBuffer
297             );
298 
299   ParentControllerHandleBuffer = NULL;
300   Status = PARSE_HANDLE_DATABASE_PARENTS (
301             Handle,
302             &ParentControllerHandleCount,
303             &ParentControllerHandleBuffer
304             );
305 
306   ChildControllerHandleBuffer = NULL;
307   Status = ParseHandleDatabaseForChildControllers (
308             Handle,
309             &ChildControllerHandleCount,
310             &ChildControllerHandleBuffer
311             );
312 
313   DiagnosticsStatus = FALSE;
314   ConfigurationStatus = FALSE;
315 
316   if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverConfigurationProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
317     ConfigurationStatus = TRUE;
318   }
319   if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverConfiguration2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
320     ConfigurationStatus = TRUE;
321   }
322   if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverDiagnosticsProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
323     DiagnosticsStatus = TRUE;
324   }
325   if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverDiagnostics2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
326     DiagnosticsStatus = TRUE;
327   }
328 
329   Status = EFI_SUCCESS;
330 
331   if (DriverBindingHandleCount > 0 || ParentControllerHandleCount > 0 || ChildControllerHandleCount > 0) {
332 
333 
334 
335     DevicePath          = NULL;
336     TempStringPointer   = NULL;
337     Status              = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID**)&DevicePath);
338 
339     Status = gEfiShellProtocol->GetDeviceName(Handle, EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
340     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DRIVER1), gShellDriver1HiiHandle, TempStringPointer!=NULL?TempStringPointer:L"<Unknown>");
341     SHELL_FREE_NON_NULL(TempStringPointer);
342 
343     TempStringPointer = ConvertDevicePathToText(DevicePath, TRUE, FALSE);
344     ShellPrintHiiEx(
345       -1,
346       -1,
347       NULL,
348       STRING_TOKEN (STR_DH_OUTPUT_DRIVER2),
349       gShellDriver1HiiHandle,
350       TempStringPointer!=NULL?TempStringPointer:L"<None>",
351       ParentControllerHandleCount == 0?L"ROOT":(ChildControllerHandleCount > 0)?L"BUS":L"DEVICE",
352       ConfigurationStatus?L"YES":L"NO",
353       DiagnosticsStatus?L"YES":L"NO"
354       );
355 
356     SHELL_FREE_NON_NULL(TempStringPointer);
357 
358     if (DriverBindingHandleCount == 0) {
359       ShellPrintHiiEx(
360         -1,
361         -1,
362         NULL,
363         STRING_TOKEN (STR_DH_OUTPUT_DRIVER3),
364         gShellDriver1HiiHandle,
365         L"<None>"
366         );
367     } else {
368       ShellPrintHiiEx(
369         -1,
370         -1,
371         NULL,
372         STRING_TOKEN (STR_DH_OUTPUT_DRIVER3),
373         gShellDriver1HiiHandle,
374         L""
375         );
376       for (Index = 0; Index < DriverBindingHandleCount; Index++) {
377         Image = FALSE;
378         Status = GetDriverName (
379                   DriverBindingHandleBuffer[Index],
380                   Language,
381                   &DriverName
382                   );
383         if (EFI_ERROR (Status)) {
384           Status = GetDriverImageName (
385                     DriverBindingHandleBuffer[Index],
386                     &DriverName
387                     );
388           if (EFI_ERROR (Status)) {
389             DriverName = NULL;
390           }
391         }
392 
393         if (Image) {
394           ShellPrintHiiEx(
395             -1,
396             -1,
397             NULL,
398             STRING_TOKEN (STR_DH_OUTPUT_DRIVER4A),
399             gShellDriver1HiiHandle,
400             ConvertHandleToHandleIndex (DriverBindingHandleBuffer[Index]),
401             DriverName!=NULL?DriverName:L"<Unknown>"
402             );
403         } else {
404           ShellPrintHiiEx(
405             -1,
406             -1,
407             NULL,
408             STRING_TOKEN (STR_DH_OUTPUT_DRIVER4B),
409             gShellDriver1HiiHandle,
410             ConvertHandleToHandleIndex (DriverBindingHandleBuffer[Index]),
411             DriverName!=NULL?DriverName:L"<Unknown>"
412             );
413         }
414         SHELL_FREE_NON_NULL(DriverName);
415       }
416     }
417 
418     if (ParentControllerHandleCount == 0) {
419       ShellPrintHiiEx(
420         -1,
421         -1,
422         NULL,
423         STRING_TOKEN (STR_DH_OUTPUT_DRIVER5),
424         gShellDriver1HiiHandle,
425         L"<None>"
426         );
427     } else {
428       ShellPrintHiiEx(
429         -1,
430         -1,
431         NULL,
432         STRING_TOKEN (STR_DH_OUTPUT_DRIVER5),
433         gShellDriver1HiiHandle,
434         L""
435         );
436       for (Index = 0; Index < ParentControllerHandleCount; Index++) {
437         Status = gEfiShellProtocol->GetDeviceName(ParentControllerHandleBuffer[Index], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
438         ShellPrintHiiEx(
439           -1,
440           -1,
441           NULL,
442           STRING_TOKEN (STR_DH_OUTPUT_DRIVER5B),
443           gShellDriver1HiiHandle,
444           ConvertHandleToHandleIndex (ParentControllerHandleBuffer[Index]),
445           TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
446           );
447         SHELL_FREE_NON_NULL(TempStringPointer);
448       }
449     }
450 
451     if (ChildControllerHandleCount == 0) {
452       ShellPrintHiiEx(
453         -1,
454         -1,
455         NULL,
456         STRING_TOKEN (STR_DH_OUTPUT_DRIVER6),
457         gShellDriver1HiiHandle,
458         L"<None>"
459         );
460     } else {
461       ShellPrintHiiEx(
462         -1,
463         -1,
464         NULL,
465         STRING_TOKEN (STR_DH_OUTPUT_DRIVER6),
466         gShellDriver1HiiHandle,
467         L""
468         );
469       for (Index = 0; Index < ChildControllerHandleCount; Index++) {
470         Status = gEfiShellProtocol->GetDeviceName(ChildControllerHandleBuffer[Index], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
471         ShellPrintHiiEx(
472           -1,
473           -1,
474           NULL,
475           STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B),
476           gShellDriver1HiiHandle,
477           ConvertHandleToHandleIndex (ChildControllerHandleBuffer[Index]),
478           TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
479           );
480         SHELL_FREE_NON_NULL(TempStringPointer);
481       }
482     }
483   }
484 
485   SHELL_FREE_NON_NULL(DriverBindingHandleBuffer);
486 
487   SHELL_FREE_NON_NULL(ParentControllerHandleBuffer);
488 
489   SHELL_FREE_NON_NULL(ChildControllerHandleBuffer);
490 
491   if (EFI_ERROR (Status)) {
492     return Status;
493   }
494   //
495   // See if Handle is a driver binding handle and display its details.
496   //
497   Status = gBS->OpenProtocol (
498                 Handle,
499                 &gEfiDriverBindingProtocolGuid,
500                 (VOID **) &DriverBinding,
501                 NULL,
502                 NULL,
503                 EFI_OPEN_PROTOCOL_GET_PROTOCOL
504                 );
505   if (EFI_ERROR (Status)) {
506     return EFI_SUCCESS;
507   }
508 
509   NumberOfChildren        = 0;
510   ControllerHandleBuffer  = NULL;
511   Status = PARSE_HANDLE_DATABASE_DEVICES (
512             Handle,
513             &ControllerHandleCount,
514             &ControllerHandleBuffer
515             );
516   if (ControllerHandleCount > 0) {
517     for (HandleIndex = 0; HandleIndex < ControllerHandleCount; HandleIndex++) {
518       Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
519                 Handle,
520                 ControllerHandleBuffer[HandleIndex],
521                 &ChildControllerHandleCount,
522                 NULL
523                 );
524       NumberOfChildren += ChildControllerHandleCount;
525     }
526   }
527 
528   Status = GetDriverName (Handle, Language, &DriverName);
529   if (EFI_ERROR (Status)) {
530     DriverName = NULL;
531   }
532 
533   ShellPrintHiiEx(
534     -1,
535     -1,
536     NULL,
537     STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B),
538     gShellDriver1HiiHandle,
539     ConvertHandleToHandleIndex(Handle),
540     DriverName!=NULL?DriverName:L"<Unknown>"
541     );
542   SHELL_FREE_NON_NULL(DriverName);
543   Status = GetDriverImageName (
544             Handle,
545             &DriverName
546             );
547   if (EFI_ERROR (Status)) {
548     DriverName = NULL;
549   }
550   ShellPrintHiiEx(
551     -1,
552     -1,
553     NULL,
554     STRING_TOKEN (STR_DH_OUTPUT_DRIVER7B),
555     gShellDriver1HiiHandle,
556     DriverName!=NULL?DriverName:L"<Unknown>"
557     );
558   SHELL_FREE_NON_NULL(DriverName);
559 
560   ShellPrintHiiEx(
561     -1,
562     -1,
563     NULL,
564     STRING_TOKEN (STR_DH_OUTPUT_DRIVER8),
565     gShellDriver1HiiHandle,
566     DriverBinding->Version,
567     NumberOfChildren > 0?L"Bus":ControllerHandleCount > 0?L"Device":L"<Unknown>",
568     ConfigurationStatus?L"YES":L"NO",
569     DiagnosticsStatus?L"YES":L"NO"
570     );
571 
572   if (ControllerHandleCount == 0) {
573       ShellPrintHiiEx(
574         -1,
575         -1,
576         NULL,
577         STRING_TOKEN (STR_DH_OUTPUT_DRIVER6),
578         gShellDriver1HiiHandle,
579         L"None"
580         );
581   } else {
582     ShellPrintHiiEx(
583       -1,
584       -1,
585       NULL,
586       STRING_TOKEN (STR_DH_OUTPUT_DRIVER6),
587       gShellDriver1HiiHandle,
588       L""
589       );
590     for (HandleIndex = 0; HandleIndex < ControllerHandleCount; HandleIndex++) {
591       Status = gEfiShellProtocol->GetDeviceName(ControllerHandleBuffer[HandleIndex], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
592 
593       ShellPrintHiiEx(
594         -1,
595         -1,
596         NULL,
597         STRING_TOKEN (STR_DH_OUTPUT_DRIVER9B),
598         gShellDriver1HiiHandle,
599         ConvertHandleToHandleIndex(ControllerHandleBuffer[HandleIndex]),
600         TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
601         );
602       SHELL_FREE_NON_NULL(TempStringPointer);
603 
604       Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
605                 Handle,
606                 ControllerHandleBuffer[HandleIndex],
607                 &ChildControllerHandleCount,
608                 &ChildControllerHandleBuffer
609                 );
610       if (!EFI_ERROR (Status)) {
611         for (ChildIndex = 0; ChildIndex < ChildControllerHandleCount; ChildIndex++) {
612           Status = gEfiShellProtocol->GetDeviceName(ChildControllerHandleBuffer[ChildIndex], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
613 
614           ShellPrintHiiEx(
615             -1,
616             -1,
617             NULL,
618             STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B),
619             gShellDriver1HiiHandle,
620             ConvertHandleToHandleIndex(ChildControllerHandleBuffer[ChildIndex]),
621             TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
622             );
623           SHELL_FREE_NON_NULL(TempStringPointer);
624         }
625 
626         SHELL_FREE_NON_NULL (ChildControllerHandleBuffer);
627       }
628     }
629 
630     SHELL_FREE_NON_NULL (ControllerHandleBuffer);
631   }
632 
633   return EFI_SUCCESS;
634 }
635 
636 /**
637   Display information for a handle.
638 
639   @param[in] TheHandle        The handles to show info on.
640   @param[in] Verbose          TRUE for extra info, FALSE otherwise.
641   @param[in] Sfo              TRUE to output in standard format output (spec).
642   @param[in] Language         Language string per UEFI specification.
643   @param[in] DriverInfo       TRUE to show all info about the handle.
644   @param[in] Multiple         TRUE indicates more than  will be output,
645                               FALSE for a single one.
646 
647   @retval SHELL_SUCCESS           The operation was successful.
648   @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
649 **/
650 SHELL_STATUS
651 EFIAPI
DoDhByHandle(IN CONST EFI_HANDLE TheHandle,IN CONST BOOLEAN Verbose,IN CONST BOOLEAN Sfo,IN CONST CHAR8 * Language,IN CONST BOOLEAN DriverInfo,IN CONST BOOLEAN Multiple)652 DoDhByHandle(
653   IN CONST EFI_HANDLE TheHandle,
654   IN CONST BOOLEAN    Verbose,
655   IN CONST BOOLEAN    Sfo,
656   IN CONST CHAR8      *Language,
657   IN CONST BOOLEAN    DriverInfo,
658   IN CONST BOOLEAN    Multiple
659   )
660 {
661   CHAR16              *ProtocolInfoString;
662   SHELL_STATUS        ShellStatus;
663 
664   ShellStatus         = SHELL_SUCCESS;
665   ProtocolInfoString  = NULL;
666 
667   if (!Sfo) {
668     if (Multiple) {
669       ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L" ", Verbose, TRUE);
670       ShellPrintHiiEx(
671         -1,
672         -1,
673         NULL,
674         STRING_TOKEN (STR_DH_OUTPUT),
675         gShellDriver1HiiHandle,
676         ConvertHandleToHandleIndex(TheHandle),
677         ProtocolInfoString==NULL?L"":ProtocolInfoString);
678     } else {
679       ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L"\r\n", Verbose, TRUE);
680       ShellPrintHiiEx(
681         -1,
682         -1,
683         NULL,
684         STRING_TOKEN (STR_DH_OUTPUT_SINGLE),
685         gShellDriver1HiiHandle,
686         ConvertHandleToHandleIndex(TheHandle),
687         TheHandle,
688         ProtocolInfoString==NULL?L"":ProtocolInfoString);
689     }
690 
691     if (DriverInfo) {
692       DisplayDriverModelHandle ((EFI_HANDLE)TheHandle, TRUE, Language);
693     }
694   } else {
695       ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L";", FALSE, FALSE);
696       ShellPrintHiiEx(
697         -1,
698         -1,
699         NULL,
700         STRING_TOKEN (STR_DH_OUTPUT_SFO),
701         gShellDriver1HiiHandle,
702         Multiple ?L"HandlesInfo":L"HandleInfo",
703         L"DriverName",
704         L"ControllerName",
705         ConvertHandleToHandleIndex(TheHandle),
706         L"DevPath",
707         ProtocolInfoString==NULL?L"":ProtocolInfoString);
708 
709 
710   }
711 
712 
713   if (ProtocolInfoString != NULL) {
714     FreePool(ProtocolInfoString);
715   }
716   return (ShellStatus);
717 }
718 
719 /**
720   Display information for all handles on a list.
721 
722   @param[in] HandleList       The NULL-terminated list of handles.
723   @param[in] Verbose          TRUE for extra info, FALSE otherwise.
724   @param[in] Sfo              TRUE to output in standard format output (spec).
725   @param[in] Language         Language string per UEFI specification.
726   @param[in] DriverInfo       TRUE to show all info about the handle.
727 
728   @retval SHELL_SUCCESS           The operation was successful.
729   @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
730 **/
731 SHELL_STATUS
732 EFIAPI
DoDhForHandleList(IN CONST EFI_HANDLE * HandleList,IN CONST BOOLEAN Verbose,IN CONST BOOLEAN Sfo,IN CONST CHAR8 * Language,IN CONST BOOLEAN DriverInfo)733 DoDhForHandleList(
734   IN CONST EFI_HANDLE *HandleList,
735   IN CONST BOOLEAN    Verbose,
736   IN CONST BOOLEAN    Sfo,
737   IN CONST CHAR8      *Language,
738   IN CONST BOOLEAN    DriverInfo
739   )
740 {
741   CONST EFI_HANDLE  *HandleWalker;
742   SHELL_STATUS      ShellStatus;
743 
744   ShellStatus       = SHELL_SUCCESS;
745 
746   for (HandleWalker = HandleList ; HandleWalker != NULL && *HandleWalker != NULL && ShellStatus == SHELL_SUCCESS; HandleWalker++) {
747     ShellStatus = DoDhByHandle(
748           *HandleWalker,
749           Verbose,
750           Sfo,
751           Language,
752           DriverInfo,
753           TRUE
754          );
755     if (ShellGetExecutionBreakFlag ()) {
756       ShellStatus = SHELL_ABORTED;
757       break;
758     }
759   }
760   return (ShellStatus);
761 }
762 
763 /**
764   Display information for all handles.
765 
766   @param[in] Sfo              TRUE to output in standard format output (spec).
767   @param[in] Verbose          TRUE for extra info, FALSE otherwise.
768   @param[in] Language         Language string per UEFI specification.
769   @param[in] DriverInfo       TRUE to show all info about the handle.
770 
771   @retval SHELL_SUCCESS           The operation was successful.
772   @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
773 **/
774 SHELL_STATUS
775 EFIAPI
DoDhForAll(IN CONST BOOLEAN Sfo,IN CONST BOOLEAN Verbose,IN CONST CHAR8 * Language,IN CONST BOOLEAN DriverInfo)776 DoDhForAll(
777   IN CONST BOOLEAN  Sfo,
778   IN CONST BOOLEAN  Verbose,
779   IN CONST CHAR8    *Language,
780   IN CONST BOOLEAN  DriverInfo
781   )
782 {
783   EFI_HANDLE    *HandleList;
784   SHELL_STATUS  ShellStatus;
785 
786   HandleList = GetHandleListByProtocol(NULL);
787 
788   ShellStatus = DoDhForHandleList(
789     HandleList,
790     Verbose,
791     Sfo,
792     Language,
793     DriverInfo);
794 
795   FreePool(HandleList);
796 
797   return (ShellStatus);
798 }
799 
800 /**
801   Display information for all handles which have a specific protocol.
802 
803   @param[in] ProtocolName     The pointer to the name of the protocol.
804   @param[in] Verbose          TRUE for extra info, FALSE otherwise.
805   @param[in] Sfo              TRUE to output in standard format output (spec).
806   @param[in] Language         Language string per UEFI specification.
807   @param[in] DriverInfo       TRUE to show all info about the handle.
808 
809   @retval SHELL_SUCCESS           The operation was successful.
810   @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
811 **/
812 SHELL_STATUS
813 EFIAPI
DoDhByProtocol(IN CONST CHAR16 * ProtocolName,IN CONST BOOLEAN Verbose,IN CONST BOOLEAN Sfo,IN CONST CHAR8 * Language,IN CONST BOOLEAN DriverInfo)814 DoDhByProtocol(
815   IN CONST CHAR16   *ProtocolName,
816   IN CONST BOOLEAN  Verbose,
817   IN CONST BOOLEAN  Sfo,
818   IN CONST CHAR8    *Language,
819   IN CONST BOOLEAN  DriverInfo
820   )
821 {
822   EFI_GUID      *Guid;
823   EFI_STATUS    Status;
824   EFI_HANDLE    *HandleList;
825   SHELL_STATUS  ShellStatus;
826 
827   if (ProtocolName == NULL) {
828     return (SHELL_INVALID_PARAMETER);
829   }
830 
831   Status = GetGuidFromStringName(ProtocolName, Language, &Guid);
832   if (EFI_ERROR(Status)) {
833     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DH_NO_GUID_FOUND), gShellDriver1HiiHandle, ProtocolName);
834     return (SHELL_INVALID_PARAMETER);
835   }
836 
837   HandleList = GetHandleListByProtocol(Guid);
838 
839   ShellStatus = DoDhForHandleList(
840     HandleList,
841     Verbose,
842     Sfo,
843     Language,
844     DriverInfo);
845 
846   SHELL_FREE_NON_NULL(HandleList);
847 
848   return (ShellStatus);
849 }
850 
851 /**
852   Function for 'dh' command.
853 
854   @param[in] ImageHandle  Handle to the Image (NULL if Internal).
855   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
856 **/
857 SHELL_STATUS
858 EFIAPI
ShellCommandRunDh(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)859 ShellCommandRunDh (
860   IN EFI_HANDLE        ImageHandle,
861   IN EFI_SYSTEM_TABLE  *SystemTable
862   )
863 {
864   EFI_STATUS          Status;
865   LIST_ENTRY          *Package;
866   CHAR16              *ProblemParam;
867   SHELL_STATUS        ShellStatus;
868   CHAR8               *Language;
869   CONST CHAR16        *Lang;
870   CONST CHAR16        *Temp2;
871   BOOLEAN             SfoMode;
872   BOOLEAN             FlagD;
873   BOOLEAN             Verbose;
874   UINT64              Intermediate;
875 
876   ShellStatus         = SHELL_SUCCESS;
877   Status              = EFI_SUCCESS;
878   Language            = NULL;
879 
880   //
881   // initialize the shell lib (we must be in non-auto-init...)
882   //
883   Status = ShellInitialize();
884   ASSERT_EFI_ERROR(Status);
885 
886   Status = CommandInit();
887   ASSERT_EFI_ERROR(Status);
888 
889   //
890   // parse the command line
891   //
892   Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
893   if (EFI_ERROR(Status)) {
894     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
895       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"dh", ProblemParam);
896       FreePool(ProblemParam);
897       ShellStatus = SHELL_INVALID_PARAMETER;
898     } else {
899       ASSERT(FALSE);
900     }
901   } else {
902     if (ShellCommandLineGetCount(Package) > 2) {
903       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh");
904       ShellCommandLineFreeVarList (Package);
905       return (SHELL_INVALID_PARAMETER);
906     }
907 
908     Lang = ShellCommandLineGetValue(Package, L"-l");
909     if (Lang != NULL) {
910       Language = AllocateZeroPool(StrSize(Lang));
911       AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
912     } else if (!ShellCommandLineGetFlag(Package, L"-l")){
913       Language = AllocateZeroPool(10);
914       AsciiSPrint(Language, 10, "en-us");
915     } else {
916       ASSERT(Language == NULL);
917       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh",  L"-l");
918       ShellCommandLineFreeVarList (Package);
919       return (SHELL_INVALID_PARAMETER);
920     }
921 
922     SfoMode = ShellCommandLineGetFlag(Package, L"-sfo");
923     FlagD   = ShellCommandLineGetFlag(Package, L"-d");
924     Verbose = (BOOLEAN)(ShellCommandLineGetFlag(Package, L"-v") || ShellCommandLineGetFlag(Package, L"-verbose"));
925 
926     if (ShellCommandLineGetFlag(Package, L"-p")) {
927       if (ShellCommandLineGetCount(Package) > 1) {
928         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh");
929         ShellStatus = SHELL_INVALID_PARAMETER;
930       } else if (ShellCommandLineGetValue(Package, L"-p") == NULL) {
931         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh",  L"-p");
932         ShellStatus = SHELL_INVALID_PARAMETER;
933       } else {
934         //
935         // print by protocol
936         //
937         ShellStatus = DoDhByProtocol(
938           ShellCommandLineGetValue(Package, L"-p"),
939           Verbose,
940           SfoMode,
941           Lang==NULL?NULL:Language,
942           FlagD
943          );
944       }
945     } else {
946       Temp2 = ShellCommandLineGetRawValue(Package, 1);
947       if (Temp2 == NULL) {
948         //
949         // Print everything
950         //
951         ShellStatus = DoDhForAll(
952           SfoMode,
953           Verbose,
954           Lang==NULL?NULL:Language,
955           FlagD
956          );
957       } else {
958         Status = ShellConvertStringToUint64(Temp2, &Intermediate, TRUE, FALSE);
959         if (EFI_ERROR(Status) || ConvertHandleIndexToHandle((UINTN)Intermediate) == NULL) {
960           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", Temp2);
961           ShellStatus = SHELL_INVALID_PARAMETER;
962         } else {
963           //
964           // print 1 handle
965           //
966           ShellStatus = DoDhByHandle(
967             ConvertHandleIndexToHandle((UINTN)Intermediate),
968             Verbose,
969             SfoMode,
970             Lang==NULL?NULL:Language,
971             FlagD,
972             FALSE
973            );
974         }
975       }
976     }
977 
978 
979     ShellCommandLineFreeVarList (Package);
980     SHELL_FREE_NON_NULL(Language);
981   }
982 
983   return (ShellStatus);
984 }
985