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 - 2015, 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*
GetDevicePathTextForHandle(IN EFI_HANDLE TheHandle)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
ReturnDriverConfig(IN CONST EFI_HANDLE TheHandle)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
ReturnDriverDiag(IN CONST EFI_HANDLE TheHandle)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
ReturnDriverVersion(IN CONST EFI_HANDLE TheHandle)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 Function for 'drivers' command.
165
166 @param[in] ImageHandle Handle to the Image (NULL if Internal).
167 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
168 **/
169 SHELL_STATUS
170 EFIAPI
ShellCommandRunDrivers(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)171 ShellCommandRunDrivers (
172 IN EFI_HANDLE ImageHandle,
173 IN EFI_SYSTEM_TABLE *SystemTable
174 )
175 {
176 EFI_STATUS Status;
177 LIST_ENTRY *Package;
178 CHAR16 *ProblemParam;
179 SHELL_STATUS ShellStatus;
180 CHAR8 *Language;
181 CONST CHAR16 *Lang;
182 EFI_HANDLE *HandleList;
183 EFI_HANDLE *HandleWalker;
184 UINTN ChildCount;
185 UINTN DeviceCount;
186 CHAR16 *Temp2;
187 CONST CHAR16 *FullDriverName;
188 CHAR16 *TruncatedDriverName;
189 CHAR16 *FormatString;
190 UINT32 DriverVersion;
191 BOOLEAN DriverConfig;
192 BOOLEAN DriverDiag;
193 BOOLEAN SfoFlag;
194
195 ShellStatus = SHELL_SUCCESS;
196 Status = EFI_SUCCESS;
197 Language = NULL;
198 FormatString = NULL;
199 SfoFlag = FALSE;
200
201 //
202 // initialize the shell lib (we must be in non-auto-init...)
203 //
204 Status = ShellInitialize();
205 ASSERT_EFI_ERROR(Status);
206
207 Status = CommandInit();
208 ASSERT_EFI_ERROR(Status);
209
210 //
211 // parse the command line
212 //
213 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
214 if (EFI_ERROR(Status)) {
215 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
216 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"drivers", ProblemParam);
217 FreePool(ProblemParam);
218 ShellStatus = SHELL_INVALID_PARAMETER;
219 } else {
220 ASSERT(FALSE);
221 }
222 } else {
223 if (ShellCommandLineGetCount(Package) > 1) {
224 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"drivers");
225 ShellStatus = SHELL_INVALID_PARAMETER;
226 } else {
227 if (ShellCommandLineGetFlag(Package, L"-l")){
228 Lang = ShellCommandLineGetValue(Package, L"-l");
229 if (Lang != NULL) {
230 Language = AllocateZeroPool(StrSize(Lang));
231 AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
232 } else {
233 ASSERT(Language == NULL);
234 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drivers", L"-l");
235 ShellCommandLineFreeVarList (Package);
236 return (SHELL_INVALID_PARAMETER);
237 }
238 }
239
240 if (ShellCommandLineGetFlag (Package, L"-sfo")) {
241 SfoFlag = TRUE;
242 FormatString = HiiGetString (gShellDriver1HiiHandle, STRING_TOKEN (STR_DRIVERS_ITEM_LINE_SFO), Language);
243 //
244 // print the SFO header
245 //
246 ShellPrintHiiEx (
247 -1,
248 -1,
249 Language,
250 STRING_TOKEN (STR_GEN_SFO_HEADER),
251 gShellDriver1HiiHandle,
252 L"drivers");
253 } else {
254 FormatString = HiiGetString (gShellDriver1HiiHandle, STRING_TOKEN (STR_DRIVERS_ITEM_LINE), Language);
255 //
256 // print the header row
257 //
258 ShellPrintHiiEx(
259 -1,
260 -1,
261 Language,
262 STRING_TOKEN (STR_DRIVERS_HEADER_LINES),
263 gShellDriver1HiiHandle);
264 }
265
266 HandleList = GetHandleListByProtocol(&gEfiDriverBindingProtocolGuid);
267 for (HandleWalker = HandleList ; HandleWalker != NULL && *HandleWalker != NULL ; HandleWalker++){
268 ChildCount = 0;
269 DeviceCount = 0;
270 Status = ParseHandleDatabaseForChildDevices (*HandleWalker, &ChildCount , NULL);
271 Status = PARSE_HANDLE_DATABASE_DEVICES (*HandleWalker, &DeviceCount, NULL);
272 Temp2 = GetDevicePathTextForHandle(*HandleWalker);
273 DriverVersion = ReturnDriverVersion(*HandleWalker);
274 DriverConfig = ReturnDriverConfig(*HandleWalker);
275 DriverDiag = ReturnDriverDiag (*HandleWalker);
276 FullDriverName = GetStringNameFromHandle(*HandleWalker, Language);
277
278 TruncatedDriverName = NULL;
279 if (!SfoFlag && (FullDriverName != NULL)) {
280 TruncatedDriverName = AllocateZeroPool ((MAX_LEN_DRIVER_NAME + 1) * sizeof (CHAR16));
281 StrnCpyS (TruncatedDriverName, MAX_LEN_DRIVER_NAME + 1, FullDriverName, MAX_LEN_DRIVER_NAME);
282 }
283
284 ShellPrintEx(
285 -1,
286 -1,
287 FormatString,
288 ConvertHandleToHandleIndex(*HandleWalker),
289 DriverVersion,
290 ChildCount > 0?L'B':(DeviceCount > 0?L'D':L'?'),
291 DriverConfig?L'Y':L'N',
292 DriverDiag?L'Y':L'N',
293 DeviceCount,
294 ChildCount,
295 SfoFlag?FullDriverName:TruncatedDriverName,
296 Temp2==NULL?L"":Temp2
297 );
298 if (TruncatedDriverName != NULL) {
299 FreePool (TruncatedDriverName);
300 }
301 if (Temp2 != NULL) {
302 FreePool(Temp2);
303 }
304
305 if (ShellGetExecutionBreakFlag ()) {
306 ShellStatus = SHELL_ABORTED;
307 break;
308 }
309 }
310 }
311 SHELL_FREE_NON_NULL(Language);
312 ShellCommandLineFreeVarList (Package);
313 SHELL_FREE_NON_NULL(FormatString);
314 }
315
316 return (ShellStatus);
317 }
318