]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDriver1CommandsLib/Drivers.c
ShellPkg: Clean up source files
[mirror_edk2.git] / ShellPkg / Library / UefiShellDriver1CommandsLib / Drivers.c
1 /** @file
2 Main file for Drivers shell Driver1 function.
3
4 (C) Copyright 2012-2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010 - 2018, 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 #define MAX_LEN_DRIVER_NAME 35
19
20 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
21 {L"-sfo", TypeFlag},
22 {L"-l", TypeValue},
23 {NULL, TypeMax}
24 };
25
26 /**
27 Get a device path (in text format) for a given handle.
28
29 @param[in] TheHandle The handle to get the device path for.
30
31 @retval NULL An error occured.
32 @return A pointer to the driver path as a string. The callee must
33 free this memory.
34 **/
35 CHAR16*
36 GetDevicePathTextForHandle(
37 IN EFI_HANDLE TheHandle
38 )
39 {
40 EFI_STATUS Status;
41 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
42 EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
43 EFI_DEVICE_PATH_PROTOCOL *FinalPath;
44 CHAR16 *RetVal;
45
46 FinalPath = NULL;
47
48 Status = gBS->OpenProtocol (
49 TheHandle,
50 &gEfiLoadedImageProtocolGuid,
51 (VOID**)&LoadedImage,
52 gImageHandle,
53 NULL,
54 EFI_OPEN_PROTOCOL_GET_PROTOCOL
55 );
56 if (!EFI_ERROR (Status)) {
57 Status = gBS->OpenProtocol (
58 LoadedImage->DeviceHandle,
59 &gEfiDevicePathProtocolGuid,
60 (VOID**)&ImageDevicePath,
61 gImageHandle,
62 NULL,
63 EFI_OPEN_PROTOCOL_GET_PROTOCOL
64 );
65 if (!EFI_ERROR (Status)) {
66 FinalPath = AppendDevicePath (ImageDevicePath, LoadedImage->FilePath);
67 gBS->CloseProtocol(
68 LoadedImage->DeviceHandle,
69 &gEfiDevicePathProtocolGuid,
70 gImageHandle,
71 NULL);
72 }
73 gBS->CloseProtocol(
74 TheHandle,
75 &gEfiLoadedImageProtocolGuid,
76 gImageHandle,
77 NULL);
78 }
79
80 if (FinalPath == NULL) {
81 return (NULL);
82 }
83 RetVal = gEfiShellProtocol->GetFilePathFromDevicePath(FinalPath);
84 if (RetVal == NULL) {
85 RetVal = ConvertDevicePathToText(FinalPath, TRUE, TRUE);
86 }
87 FreePool(FinalPath);
88 return (RetVal);
89 }
90
91 /**
92 Determine if the given handle has Driver Configuration protocol.
93
94 @param[in] TheHandle The handle to the driver to test.
95
96 @retval TRUE The driver does have Driver Configuration.
97 @retval FALSE The driver does not have Driver Configuration.
98 **/
99 BOOLEAN
100 ReturnDriverConfig(
101 IN CONST EFI_HANDLE TheHandle
102 )
103 {
104 EFI_STATUS Status;
105 Status = gBS->OpenProtocol((EFI_HANDLE)TheHandle, &gEfiDriverConfigurationProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
106 if (EFI_ERROR(Status)) {
107 return (FALSE);
108 }
109 return (TRUE);
110 }
111
112 /**
113 Determine if the given handle has DriverDiagnostics protocol.
114
115 @param[in] TheHandle The handle to the driver to test.
116
117 @retval TRUE The driver does have Driver Diasgnostics.
118 @retval FALSE The driver does not have Driver Diagnostics.
119 **/
120 BOOLEAN
121 ReturnDriverDiag(
122 IN CONST EFI_HANDLE TheHandle
123 )
124 {
125 EFI_STATUS Status;
126 Status = gBS->OpenProtocol((EFI_HANDLE)TheHandle, &gEfiDriverDiagnostics2ProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
127 if (EFI_ERROR(Status)) {
128 Status = gBS->OpenProtocol((EFI_HANDLE)TheHandle, &gEfiDriverDiagnosticsProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
129 if (EFI_ERROR(Status)) {
130 return (FALSE);
131 }
132 }
133 return (TRUE);
134 }
135
136 /**
137 Finds and returns the version of the driver specified by TheHandle.
138
139 @param[in] TheHandle The driver handle to get the version of.
140
141 @return The version of the driver.
142 @retval 0xFFFFFFFF An error ocurred.
143 **/
144 UINT32
145 ReturnDriverVersion(
146 IN CONST EFI_HANDLE TheHandle
147 )
148 {
149 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
150 EFI_STATUS Status;
151 UINT32 RetVal;
152
153 RetVal = (UINT32)-1;
154
155 Status = gBS->OpenProtocol((EFI_HANDLE)TheHandle, &gEfiDriverBindingProtocolGuid, (VOID**)&DriverBinding, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
156 if (!EFI_ERROR(Status)) {
157 RetVal = DriverBinding->Version;
158 gBS->CloseProtocol(TheHandle, &gEfiDriverBindingProtocolGuid, gImageHandle, NULL);
159 }
160 return (RetVal);
161 }
162
163 /**
164 Get image name from Image Handle.
165
166 @param[in] Handle Image Handle
167
168 @return A pointer to the image name as a string.
169 **/
170 CHAR16 *
171 GetImageNameFromHandle (
172 IN CONST EFI_HANDLE Handle
173 )
174 {
175 EFI_STATUS Status;
176 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
177 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
178 EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
179 EFI_GUID *NameGuid;
180 CHAR16 *ImageName;
181 UINTN BufferSize;
182 UINT32 AuthenticationStatus;
183 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv2;
184
185 LoadedImage = NULL;
186 DriverBinding = NULL;
187 ImageName = NULL;
188
189 Status = gBS->OpenProtocol (
190 Handle,
191 &gEfiDriverBindingProtocolGuid,
192 (VOID **) &DriverBinding,
193 NULL,
194 NULL,
195 EFI_OPEN_PROTOCOL_GET_PROTOCOL
196 );
197 if (EFI_ERROR (Status)) {
198 return NULL;
199 }
200 Status = gBS->OpenProtocol (
201 DriverBinding->ImageHandle,
202 &gEfiLoadedImageProtocolGuid,
203 (VOID**)&LoadedImage,
204 gImageHandle,
205 NULL,
206 EFI_OPEN_PROTOCOL_GET_PROTOCOL
207 );
208 if (!EFI_ERROR (Status)) {
209 DevPathNode = LoadedImage->FilePath;
210 if (DevPathNode == NULL) {
211 return NULL;
212 }
213 while (!IsDevicePathEnd (DevPathNode)) {
214 NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)DevPathNode);
215 if (NameGuid != NULL) {
216 Status = gBS->HandleProtocol (
217 LoadedImage->DeviceHandle,
218 &gEfiFirmwareVolume2ProtocolGuid,
219 (VOID **)&Fv2
220 );
221 if (!EFI_ERROR (Status)) {
222 Status = Fv2->ReadSection (
223 Fv2,
224 NameGuid,
225 EFI_SECTION_USER_INTERFACE,
226 0,
227 (VOID **)&ImageName,
228 &BufferSize,
229 &AuthenticationStatus
230 );
231 if (!EFI_ERROR (Status)) {
232 break;
233 }
234 ImageName = NULL;
235 }
236 }
237 //
238 // Next device path node
239 //
240 DevPathNode = NextDevicePathNode (DevPathNode);
241 }
242 if (ImageName == NULL) {
243 ImageName = ConvertDevicePathToText (LoadedImage->FilePath, TRUE, TRUE);
244 }
245 }
246 return ImageName;
247 }
248
249 /**
250 Function for 'drivers' command.
251
252 @param[in] ImageHandle Handle to the Image (NULL if Internal).
253 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
254 **/
255 SHELL_STATUS
256 EFIAPI
257 ShellCommandRunDrivers (
258 IN EFI_HANDLE ImageHandle,
259 IN EFI_SYSTEM_TABLE *SystemTable
260 )
261 {
262 EFI_STATUS Status;
263 LIST_ENTRY *Package;
264 CHAR16 *ProblemParam;
265 SHELL_STATUS ShellStatus;
266 CHAR8 *Language;
267 CONST CHAR16 *Lang;
268 EFI_HANDLE *HandleList;
269 EFI_HANDLE *HandleWalker;
270 UINTN ChildCount;
271 UINTN DeviceCount;
272 CHAR16 ChildCountStr[3];
273 CHAR16 DeviceCountStr[3];
274 CHAR16 *Temp2;
275 CONST CHAR16 *FullDriverName;
276 CHAR16 *TruncatedDriverName;
277 CHAR16 *ImageName;
278 CHAR16 *FormatString;
279 UINT32 DriverVersion;
280 BOOLEAN DriverConfig;
281 BOOLEAN DriverDiag;
282 BOOLEAN SfoFlag;
283
284 ShellStatus = SHELL_SUCCESS;
285 Status = EFI_SUCCESS;
286 Language = NULL;
287 FormatString = NULL;
288 SfoFlag = FALSE;
289
290 //
291 // initialize the shell lib (we must be in non-auto-init...)
292 //
293 Status = ShellInitialize();
294 ASSERT_EFI_ERROR(Status);
295
296 Status = CommandInit();
297 ASSERT_EFI_ERROR(Status);
298
299 //
300 // parse the command line
301 //
302 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
303 if (EFI_ERROR(Status)) {
304 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
305 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"drivers", ProblemParam);
306 FreePool(ProblemParam);
307 ShellStatus = SHELL_INVALID_PARAMETER;
308 } else {
309 ASSERT(FALSE);
310 }
311 } else {
312 if (ShellCommandLineGetCount(Package) > 1) {
313 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"drivers");
314 ShellStatus = SHELL_INVALID_PARAMETER;
315 } else {
316 if (ShellCommandLineGetFlag(Package, L"-l")){
317 Lang = ShellCommandLineGetValue(Package, L"-l");
318 if (Lang != NULL) {
319 Language = AllocateZeroPool(StrSize(Lang));
320 AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
321 } else {
322 ASSERT(Language == NULL);
323 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drivers", L"-l");
324 ShellCommandLineFreeVarList (Package);
325 return (SHELL_INVALID_PARAMETER);
326 }
327 }
328
329 if (ShellCommandLineGetFlag (Package, L"-sfo")) {
330 SfoFlag = TRUE;
331 FormatString = HiiGetString (gShellDriver1HiiHandle, STRING_TOKEN (STR_DRIVERS_ITEM_LINE_SFO), Language);
332 //
333 // print the SFO header
334 //
335 ShellPrintHiiEx (
336 -1,
337 -1,
338 Language,
339 STRING_TOKEN (STR_GEN_SFO_HEADER),
340 gShellDriver1HiiHandle,
341 L"drivers");
342 } else {
343 FormatString = HiiGetString (gShellDriver1HiiHandle, STRING_TOKEN (STR_DRIVERS_ITEM_LINE), Language);
344 //
345 // print the header row
346 //
347 ShellPrintHiiEx(
348 -1,
349 -1,
350 Language,
351 STRING_TOKEN (STR_DRIVERS_HEADER_LINES),
352 gShellDriver1HiiHandle);
353 }
354
355 HandleList = GetHandleListByProtocol(&gEfiDriverBindingProtocolGuid);
356 for (HandleWalker = HandleList ; HandleWalker != NULL && *HandleWalker != NULL ; HandleWalker++){
357 ChildCount = 0;
358 DeviceCount = 0;
359 Status = ParseHandleDatabaseForChildDevices (*HandleWalker, &ChildCount , NULL);
360 Status = PARSE_HANDLE_DATABASE_DEVICES (*HandleWalker, &DeviceCount, NULL);
361 Temp2 = GetDevicePathTextForHandle(*HandleWalker);
362 DriverVersion = ReturnDriverVersion(*HandleWalker);
363 DriverConfig = ReturnDriverConfig(*HandleWalker);
364 DriverDiag = ReturnDriverDiag (*HandleWalker);
365 FullDriverName = GetStringNameFromHandle(*HandleWalker, Language);
366 ImageName = GetImageNameFromHandle (*HandleWalker);
367
368 UnicodeValueToStringS (ChildCountStr, sizeof (ChildCountStr), 0, ChildCount, 0);
369 UnicodeValueToStringS (DeviceCountStr, sizeof (DeviceCountStr), 0, DeviceCount, 0);
370 TruncatedDriverName = NULL;
371 if (!SfoFlag && (FullDriverName != NULL)) {
372 TruncatedDriverName = AllocateZeroPool ((MAX_LEN_DRIVER_NAME + 1) * sizeof (CHAR16));
373 StrnCpyS (TruncatedDriverName, MAX_LEN_DRIVER_NAME + 1, FullDriverName, MAX_LEN_DRIVER_NAME);
374 }
375
376 if (!SfoFlag) {
377 ShellPrintEx (
378 -1,
379 -1,
380 FormatString,
381 ConvertHandleToHandleIndex (*HandleWalker),
382 DriverVersion,
383 ChildCount > 0 ? L'B' : (DeviceCount > 0 ? L'D' : L'?'),
384 DriverConfig ? L'X' : L'-',
385 DriverDiag ? L'X' : L'-',
386 DeviceCount > 0 ? DeviceCountStr : L"-",
387 ChildCount > 0 ? ChildCountStr : L"-",
388 TruncatedDriverName,
389 ImageName == NULL ? L"" : ImageName
390 );
391 } else {
392 ShellPrintEx (
393 -1,
394 -1,
395 FormatString,
396 ConvertHandleToHandleIndex (*HandleWalker),
397 DriverVersion,
398 ChildCount > 0 ? L'B' : (DeviceCount > 0 ? L'D' : L'?'),
399 DriverConfig ? L'Y' : L'N',
400 DriverDiag ? L'Y' : L'N',
401 DeviceCount,
402 ChildCount,
403 FullDriverName,
404 Temp2 == NULL ? L"" : Temp2
405 );
406 }
407 if (TruncatedDriverName != NULL) {
408 FreePool (TruncatedDriverName);
409 }
410 if (Temp2 != NULL) {
411 FreePool(Temp2);
412 }
413 if (ImageName != NULL) {
414 FreePool (ImageName);
415 }
416
417 if (ShellGetExecutionBreakFlag ()) {
418 ShellStatus = SHELL_ABORTED;
419 break;
420 }
421 }
422 }
423 SHELL_FREE_NON_NULL(Language);
424 ShellCommandLineFreeVarList (Package);
425 SHELL_FREE_NON_NULL(FormatString);
426 }
427
428 return (ShellStatus);
429 }