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