• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   Main file for devices shell Driver1 function.
3 
4   (C) Copyright 2012-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 /**
19   Get lots of info about a device from its handle.
20 
21   @param[in] TheHandle       The device handle to get info on.
22   @param[in, out] Type       On successful return R, B, or D (root, bus, or
23                              device) will be placed in this buffer.
24   @param[in, out] Cfg        On successful return this buffer will be
25                              TRUE if the handle has configuration, FALSE
26                              otherwise.
27   @param[in, out] Diag       On successful return this buffer will be
28                              TRUE if the handle has disgnostics, FALSE
29                              otherwise.
30   @param[in, out] Parents    On successful return this buffer will be
31                              contain the number of parent handles.
32   @param[in, out] Devices    On successful return this buffer will be
33                              contain the number of devices controlled.
34   @param[in, out] Children   On successful return this buffer will be
35                              contain the number of child handles.
36   @param[out] Name           The pointer to a buffer that will be allocated
37                              and contain the string name of the handle.
38                              The caller must free this memory.
39   @param[in] Language        The language code as defined by the UEFI spec.
40 
41   @retval EFI_SUCCESS           The info is there.
42   @retval EFI_INVALID_PARAMETER A parameter was invalid.
43 **/
44 EFI_STATUS
45 EFIAPI
GetDeviceHandleInfo(IN EFI_HANDLE TheHandle,IN OUT CHAR16 * Type,IN OUT BOOLEAN * Cfg,IN OUT BOOLEAN * Diag,IN OUT UINTN * Parents,IN OUT UINTN * Devices,IN OUT UINTN * Children,OUT CHAR16 ** Name,IN CONST CHAR8 * Language)46 GetDeviceHandleInfo (
47   IN EFI_HANDLE   TheHandle,
48   IN OUT CHAR16   *Type,
49   IN OUT BOOLEAN  *Cfg,
50   IN OUT BOOLEAN  *Diag,
51   IN OUT UINTN    *Parents,
52   IN OUT UINTN    *Devices,
53   IN OUT UINTN    *Children,
54   OUT CHAR16      **Name,
55   IN CONST CHAR8  *Language
56   )
57 {
58   EFI_STATUS    Status;
59   EFI_HANDLE    *HandleBuffer;
60   UINTN         Count;
61 
62   if (TheHandle == NULL
63     || Type == NULL
64     || Cfg == NULL
65     || Diag == NULL
66     || Parents == NULL
67     || Devices == NULL
68     || Children == NULL
69     || Name == NULL ) {
70     return (EFI_INVALID_PARAMETER);
71   }
72 
73   *Cfg          = FALSE;
74   *Diag         = FALSE;
75   *Children     = 0;
76   *Parents      = 0;
77   *Devices      = 0;
78   *Type         = L' ';
79   *Name         = CHAR_NULL;
80   HandleBuffer  = NULL;
81   Status        = EFI_SUCCESS;
82 
83   gEfiShellProtocol->GetDeviceName(TheHandle, EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, Name);
84 
85   Status = ParseHandleDatabaseForChildControllers(TheHandle, Children, NULL);
86 //  if (!EFI_ERROR(Status)) {
87     Status = PARSE_HANDLE_DATABASE_PARENTS(TheHandle, Parents, NULL);
88     if (/*!EFI_ERROR(Status) && */Parents != NULL && Children != NULL) {
89       if (*Parents == 0) {
90         *Type = L'R';
91       } else if (*Children > 0) {
92         *Type = L'B';
93       } else {
94         *Type = L'D';
95       }
96     }
97 //  }
98   Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS(TheHandle, Devices, &HandleBuffer);
99   if (!EFI_ERROR(Status) && Devices != NULL && HandleBuffer != NULL) {
100     for (Count = 0 ; Count < *Devices ; Count++) {
101       if (!EFI_ERROR(gBS->OpenProtocol(HandleBuffer[Count], &gEfiDriverConfigurationProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
102         *Cfg = TRUE;
103       }
104       if (!EFI_ERROR(gBS->OpenProtocol(HandleBuffer[Count], &gEfiDriverDiagnosticsProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
105         *Diag = TRUE;
106       }
107       if (!EFI_ERROR(gBS->OpenProtocol(HandleBuffer[Count], &gEfiDriverDiagnostics2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
108         *Diag = TRUE;
109       }
110     }
111     SHELL_FREE_NON_NULL(HandleBuffer);
112   }
113 
114   return (Status);
115 }
116 
117 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
118   {L"-sfo", TypeFlag},
119   {L"-l", TypeValue},
120   {NULL, TypeMax}
121   };
122 
123 /**
124   Function for 'devices' command.
125 
126   @param[in] ImageHandle  Handle to the Image (NULL if Internal).
127   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
128 **/
129 SHELL_STATUS
130 EFIAPI
ShellCommandRunDevices(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)131 ShellCommandRunDevices (
132   IN EFI_HANDLE        ImageHandle,
133   IN EFI_SYSTEM_TABLE  *SystemTable
134   )
135 {
136   EFI_STATUS          Status;
137   LIST_ENTRY          *Package;
138   CHAR16              *ProblemParam;
139   SHELL_STATUS        ShellStatus;
140   CHAR8               *Language;
141   EFI_HANDLE          *HandleList;
142   EFI_HANDLE          *HandleListWalker;
143   CHAR16              Type;
144   BOOLEAN             Cfg;
145   BOOLEAN             Diag;
146   UINTN               Parents;
147   UINTN               Devices;
148   UINTN               Children;
149   CHAR16              *Name;
150   CONST CHAR16        *Lang;
151   BOOLEAN             SfoFlag;
152 
153   ShellStatus         = SHELL_SUCCESS;
154   Language            = NULL;
155   SfoFlag             = FALSE;
156 
157   //
158   // initialize the shell lib (we must be in non-auto-init...)
159   //
160   Status = ShellInitialize();
161   ASSERT_EFI_ERROR(Status);
162 
163   Status = CommandInit();
164   ASSERT_EFI_ERROR(Status);
165 
166   //
167   // parse the command line
168   //
169   Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
170   if (EFI_ERROR(Status)) {
171     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
172       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"devices", ProblemParam);
173       FreePool(ProblemParam);
174       ShellStatus = SHELL_INVALID_PARAMETER;
175     } else {
176       ASSERT(FALSE);
177     }
178   } else {
179     //
180     // if more than 0 'value' parameters  we have too many parameters
181     //
182     if (ShellCommandLineGetRawValue(Package, 1) != NULL){
183       //
184       // error for too many parameters
185       //
186       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"devices");
187       ShellStatus = SHELL_INVALID_PARAMETER;
188     } else {
189       //
190       // get the language if necessary
191       //
192       Lang = ShellCommandLineGetValue(Package, L"-l");
193       if (Lang != NULL) {
194         Language = AllocateZeroPool(StrSize(Lang));
195         AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
196       } else if (!ShellCommandLineGetFlag(Package, L"-l")){
197         ASSERT(Language == NULL);
198 //        Language = AllocateZeroPool(10);
199 //        AsciiSPrint(Language, 10, "en-us");
200       } else {
201         ASSERT(Language == NULL);
202         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"devices",  L"-l");
203         ShellCommandLineFreeVarList (Package);
204         return (SHELL_INVALID_PARAMETER);
205       }
206 
207 
208       //
209       // Print Header
210 
211       //
212       if (ShellCommandLineGetFlag (Package, L"-sfo")) {
213         ShellPrintHiiEx (-1, -1, Language, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellDriver1HiiHandle, L"devices");
214         SfoFlag = TRUE;
215       } else {
216         ShellPrintHiiEx (-1, -1, Language, STRING_TOKEN (STR_DEVICES_HEADER_LINES), gShellDriver1HiiHandle);
217       }
218 
219       //
220       // loop through each handle
221       //
222       HandleList = GetHandleListByProtocol(NULL);
223       ASSERT(HandleList != NULL);
224       for (HandleListWalker = HandleList
225         ;  HandleListWalker != NULL && *HandleListWalker != NULL /*&& !EFI_ERROR(Status)*/
226         ;  HandleListWalker++
227        ){
228 
229         //
230         // get all the info on each handle
231         //
232         Name = NULL;
233         Status = GetDeviceHandleInfo(*HandleListWalker, &Type, &Cfg, &Diag, &Parents, &Devices, &Children, &Name, Language);
234         if (Name != NULL && (Parents != 0 || Devices != 0 || Children != 0)) {
235           ShellPrintHiiEx (
236             -1,
237             -1,
238             Language,
239             SfoFlag?STRING_TOKEN (STR_DEVICES_ITEM_LINE_SFO):STRING_TOKEN (STR_DEVICES_ITEM_LINE),
240             gShellDriver1HiiHandle,
241             ConvertHandleToHandleIndex (*HandleListWalker),
242             Type,
243             Cfg?(SfoFlag?L'Y':L'X'):(SfoFlag?L'N':L'-'),
244             Diag?(SfoFlag?L'Y':L'X'):(SfoFlag?L'N':L'-'),
245             Parents,
246             Devices,
247             Children,
248             Name!=NULL?Name:L"<UNKNOWN>");
249         }
250         if (Name != NULL) {
251           FreePool(Name);
252         }
253         if (ShellGetExecutionBreakFlag ()) {
254           ShellStatus = SHELL_ABORTED;
255           break;
256         }
257 
258       }
259 
260       if (HandleList != NULL) {
261         FreePool(HandleList);
262       }
263 
264     }
265     SHELL_FREE_NON_NULL(Language);
266     ShellCommandLineFreeVarList (Package);
267   }
268   return (ShellStatus);
269 }
270 
271