]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDriver1CommandsLib/DrvCfg.c
pointer verification (not NULL) and buffer overrun fixes.
[mirror_edk2.git] / ShellPkg / Library / UefiShellDriver1CommandsLib / DrvCfg.c
CommitLineData
4ba49616 1/** @file\r
2 Main file for DrvCfg shell Driver1 function.\r
3\r
361a8267 4 Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
4ba49616 5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "UefiShellDriver1CommandsLib.h"\r
16#include <Protocol/HiiConfigAccess.h>\r
17#include <Protocol/HiiDatabase.h>\r
18\r
19/**\r
20 Function to validate configuration information on a configurable handle.\r
21\r
22 @param[in] Handle The handle to validate info on.\r
23 @param[in] HiiDb A pointer to the HII Database protocol.\r
24\r
25 @retval EFI_SUCCESS The operation was successful.\r
26**/\r
27EFI_STATUS\r
28EFIAPI\r
29ValidateConfigInfoOnSingleHandleHii(\r
30 IN CONST EFI_HANDLE Handle,\r
31 IN EFI_HII_DATABASE_PROTOCOL *HiiDb\r
32 )\r
33{\r
34 EFI_STATUS Status;\r
35 UINTN Size;\r
36 EFI_HII_HANDLE *HiiHandle;\r
37 EFI_HII_HANDLE *CurrentHandle;\r
38 EFI_HANDLE NormalHandle;\r
39\r
40 if (HiiDb == NULL || Handle == NULL) {\r
41 return (EFI_INVALID_PARAMETER);\r
42 }\r
43\r
44 Size = 0;\r
45 HiiHandle = NULL;\r
46\r
47 Status = HiiDb->ListPackageLists(\r
48 HiiDb,\r
49 EFI_HII_PACKAGE_TYPE_ALL,\r
50 NULL,\r
51 &Size,\r
52 HiiHandle);\r
53\r
54 if (Status == EFI_BUFFER_TOO_SMALL) {\r
55 HiiHandle = AllocateZeroPool(Size);\r
56 if (HiiHandle == NULL) {\r
57 return (EFI_OUT_OF_RESOURCES);\r
58 }\r
59 Status = HiiDb->ListPackageLists(\r
60 HiiDb,\r
61 EFI_HII_PACKAGE_TYPE_ALL,\r
62 NULL,\r
63 &Size,\r
64 HiiHandle);\r
65 }\r
66 if (EFI_ERROR(Status)) {\r
67 SHELL_FREE_NON_NULL(HiiHandle);\r
68 return (Status);\r
69 }\r
70\r
71 for (CurrentHandle = HiiHandle ; CurrentHandle != NULL && *CurrentHandle != NULL ; CurrentHandle++) {\r
72 NormalHandle = NULL;\r
73 Status = HiiDb->GetPackageListHandle(\r
74 HiiDb,\r
75 *CurrentHandle,\r
76 &NormalHandle);\r
77 if (NormalHandle == Handle) {\r
78 break;\r
79 }\r
80 }\r
81\r
82\r
83\r
84\r
85\r
86 SHELL_FREE_NON_NULL(HiiHandle);\r
87 return (Status);\r
88}\r
89\r
90/**\r
91 Function to validate configuration information on all configurable handles.\r
92\r
93 @param[in] ChildrenToo TRUE to tewst for children.\r
94\r
95 @retval SHELL_SUCCESS The operation was successful.\r
96**/\r
97SHELL_STATUS\r
98EFIAPI\r
99ValidOptionsOnAll(\r
100 IN CONST BOOLEAN ChildrenToo\r
101 )\r
102{\r
103 EFI_HANDLE *HandleList;\r
104 EFI_HANDLE *CurrentHandle;\r
105 SHELL_STATUS ShellStatus;\r
106 EFI_STATUS Status;\r
107 BOOLEAN Found;\r
108 EFI_HII_DATABASE_PROTOCOL *HiiDb;\r
109\r
110 Found = FALSE;\r
111 HandleList = NULL;\r
112 ShellStatus = SHELL_SUCCESS;\r
113 Status = EFI_SUCCESS;\r
114\r
115 Status = gBS->LocateProtocol(&gEfiHiiDatabaseProtocolGuid, NULL, (VOID**)&HiiDb);\r
116 if (EFI_ERROR(Status)) {\r
117 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROTOCOL_NF), gShellDriver1HiiHandle, L"gEfiHiiDatabaseProtocolGuid", &gEfiHiiDatabaseProtocolGuid);\r
a12e31e6 118 return (SHELL_NOT_FOUND);\r
4ba49616 119 }\r
120\r
121 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_HEADER), gShellDriver1HiiHandle);\r
122\r
123 //\r
124 // First do HII method\r
125 //\r
126 HandleList = GetHandleListByProtocol(&gEfiHiiConfigAccessProtocolGuid);\r
127 for (CurrentHandle = HandleList ; CurrentHandle != NULL && *CurrentHandle != NULL && ShellStatus == SHELL_SUCCESS; CurrentHandle++){\r
128 Found = TRUE;\r
129 ///@todo VALIDATE\r
130 }\r
131 SHELL_FREE_NON_NULL(HandleList);\r
132\r
133 //\r
134 // Now do EFI 1.10 & UEFI 2.0 drivers\r
135 //\r
136 HandleList = GetHandleListByProtocol(&gEfiDriverConfigurationProtocolGuid);\r
137 for (CurrentHandle = HandleList ; CurrentHandle != NULL && *CurrentHandle != NULL && ShellStatus == SHELL_SUCCESS; CurrentHandle++){\r
138 Found = TRUE;\r
139 ///@todo VALIDATE\r
140 }\r
141\r
142 if (!Found) {\r
143 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NONE), gShellDriver1HiiHandle);\r
144 return (SHELL_SUCCESS);\r
145 }\r
146\r
147 SHELL_FREE_NON_NULL(HandleList);\r
148 return (ShellStatus);\r
149}\r
150\r
151/**\r
152 Function to print out configuration information on a configurable handle.\r
153\r
154 @param[in] DriverHandle The driver handle to print info on.\r
155 @param[in] ControllerHandle The controllerHandle to print on.\r
156 @param[in] ChildrenToo TRUE to tewst for children.\r
157 @param[in] ProtocolMask BIT0 for HII, BIT1 for DirverConfiguration.\r
158\r
159 @retval SHELL_SUCCESS The operation was successful.\r
160**/\r
161SHELL_STATUS\r
162EFIAPI\r
163PrintConfigInfoOnSingleHandle(\r
164 IN CONST EFI_HANDLE DriverHandle,\r
165 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,\r
166 IN CONST BOOLEAN ChildrenToo,\r
167 IN CONST UINT8 ProtocolMask // BIT0 - HII, BIT1 - DriverConfiguration\r
168 )\r
169{\r
170 UINTN Index1;\r
171 UINTN Index2;\r
172 EFI_HANDLE *ChildHandleList;\r
173 UINTN Count;\r
174 UINTN LoopVar;\r
175\r
176 Index1 = DriverHandle == NULL ? 0 : ConvertHandleToHandleIndex(DriverHandle );\r
177 Index2 = ControllerHandle == NULL ? 0 : ConvertHandleToHandleIndex(ControllerHandle);\r
178\r
179 if ((ProtocolMask & BIT0) == BIT0) {\r
180 ASSERT(Index1 == 0);\r
181 ShellPrintHiiEx(\r
182 -1, \r
183 -1, \r
184 NULL, \r
185 STRING_TOKEN (STR_DRVCFG_LINE_HII), \r
186 gShellDriver1HiiHandle, \r
187 Index2\r
188 );\r
189 }\r
190 if ((ProtocolMask & BIT1) == BIT1) {\r
191 PARSE_HANDLE_DATABASE_MANAGED_CHILDREN(DriverHandle, ControllerHandle, &Count, &ChildHandleList);\r
192 for (LoopVar = 0 ; LoopVar <= Count ; LoopVar++) {\r
193 ShellPrintHiiEx(\r
194 -1, \r
195 -1, \r
196 NULL, \r
197 STRING_TOKEN (STR_DRVCFG_LINE_DRV), \r
198 gShellDriver1HiiHandle, \r
199 Index1,\r
200 Index2,\r
201 Count != 0 ? ChildHandleList[LoopVar] : 0\r
202 );\r
203 }\r
204 }\r
205 return (SHELL_SUCCESS);\r
206}\r
207\r
208/**\r
209 Function to print out configuration information on all configurable handles.\r
210\r
211 @param[in] ChildrenToo TRUE to tewst for children.\r
212\r
213 @retval SHELL_SUCCESS The operation was successful.\r
214**/\r
215SHELL_STATUS\r
216EFIAPI\r
217PrintConfigInfoOnAll(\r
218 IN CONST BOOLEAN ChildrenToo\r
219 )\r
220{\r
221// lcoate all the HII_CONFIG_ACCESS_PROTOCOL - those are all configurable\r
222// then cross reference with EFI_DRIVER_CONFIGURATION_PROTOCOL - those are legacy configurable\r
223// can be on chlid, but that is ok... just find the driver\r
224 EFI_HANDLE *HandleList;\r
225 EFI_HANDLE *CurrentHandle;\r
226 EFI_HANDLE *DriverHandleList;\r
227 EFI_HANDLE *ParentHandleList;\r
228 EFI_HANDLE *CurrentDriver;\r
229 UINTN Count;\r
230 SHELL_STATUS ShellStatus;\r
231 EFI_STATUS Status;\r
232 UINTN LoopVar;\r
233 BOOLEAN Found;\r
234\r
235 Found = FALSE;\r
236 Count = 0;\r
237 HandleList = NULL;\r
238 CurrentHandle = NULL;\r
239 DriverHandleList = NULL;\r
240 CurrentDriver = NULL;\r
241 ShellStatus = SHELL_SUCCESS;\r
242\r
243 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_HEADER), gShellDriver1HiiHandle);\r
244 //\r
245 // First do HII method\r
246 //\r
247 HandleList = GetHandleListByProtocol(&gEfiHiiConfigAccessProtocolGuid);\r
248 for (CurrentHandle = HandleList ; CurrentHandle != NULL && *CurrentHandle != NULL && ShellStatus == SHELL_SUCCESS; CurrentHandle++){\r
249 // is this a driver handle itself? if yes print options for it.\r
250 if (!EFI_ERROR(gBS->OpenProtocol(*CurrentHandle, &gEfiDriverBindingProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {\r
251 ShellStatus = PrintConfigInfoOnSingleHandle(*CurrentHandle, NULL, ChildrenToo, BIT0);\r
252 } else {\r
253 // get its driver and print options for it.\r
254 Count = 0;\r
255 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS(*CurrentHandle, &Count, &DriverHandleList);\r
256 if (EFI_ERROR(Status)) {\r
257 Status = PARSE_HANDLE_DATABASE_PARENTS(*CurrentHandle, &Count, &ParentHandleList);\r
258 if (!EFI_ERROR(Status)) {\r
259 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS(*ParentHandleList, &Count, &DriverHandleList);\r
260 }\r
261 }\r
262 if (Count == 0) {\r
263 Found = TRUE;\r
264 ShellStatus = PrintConfigInfoOnSingleHandle(NULL, *CurrentHandle, ChildrenToo, BIT0);\r
265 } else if (DriverHandleList != NULL) {\r
266 for (LoopVar = 0 ; LoopVar < Count ; LoopVar++) {\r
267 Found = TRUE;\r
268 ShellStatus = PrintConfigInfoOnSingleHandle(DriverHandleList[LoopVar], *CurrentHandle, ChildrenToo, BIT0);\r
269 }\r
270 }\r
271 SHELL_FREE_NON_NULL(DriverHandleList);\r
272 }\r
273 }\r
274 SHELL_FREE_NON_NULL(HandleList);\r
275\r
276 //\r
277 // Now do EFI 1.10 & UEFI 2.0 drivers\r
278 //\r
279 HandleList = GetHandleListByProtocol(&gEfiDriverConfigurationProtocolGuid);\r
280 for (CurrentHandle = HandleList ; CurrentHandle != NULL && *CurrentHandle != NULL && ShellStatus == SHELL_SUCCESS; CurrentHandle++){\r
281 Found = TRUE;\r
282 ShellStatus = PrintConfigInfoOnSingleHandle(*CurrentHandle, NULL, ChildrenToo, BIT1);\r
283 }\r
284 SHELL_FREE_NON_NULL(HandleList);\r
285 if (!Found) {\r
286 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NONE), gShellDriver1HiiHandle);\r
287 return (SHELL_SUCCESS);\r
288 }\r
289 return (ShellStatus);\r
290}\r
291\r
292STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
293 {L"-c", TypeFlag},\r
294 {L"-s", TypeFlag},\r
295 {L"-v", TypeFlag},\r
296 {L"-l", TypeValue},\r
297 {L"-f", TypeValue},\r
298 {L"-o", TypeValue},\r
299 {L"-i", TypeValue},\r
300 {NULL, TypeMax}\r
301 };\r
302\r
361a8267 303/**\r
304 Function for 'drvcfg' command.\r
305\r
306 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
307 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
308**/\r
4ba49616 309SHELL_STATUS\r
310EFIAPI\r
311ShellCommandRunDrvCfg (\r
312 IN EFI_HANDLE ImageHandle,\r
313 IN EFI_SYSTEM_TABLE *SystemTable\r
314 )\r
315{\r
316 EFI_STATUS Status;\r
317 LIST_ENTRY *Package;\r
318 CHAR16 *ProblemParam;\r
319 SHELL_STATUS ShellStatus;\r
320 CHAR8 *Language;\r
321 CONST CHAR16 *Lang;\r
322 CONST CHAR16 *Temp2;\r
323\r
324 ShellStatus = SHELL_SUCCESS;\r
325 Status = EFI_SUCCESS;\r
326 Language = NULL;\r
327\r
328 //\r
329 // initialize the shell lib (we must be in non-auto-init...)\r
330 //\r
331 Status = ShellInitialize();\r
332 ASSERT_EFI_ERROR(Status);\r
333\r
334 Status = CommandInit();\r
335 ASSERT_EFI_ERROR(Status);\r
336\r
337 //\r
338 // parse the command line\r
339 //\r
340 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
341 if (EFI_ERROR(Status)) {\r
342 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
343 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, ProblemParam);\r
344 FreePool(ProblemParam);\r
345 ShellStatus = SHELL_INVALID_PARAMETER;\r
346 } else {\r
347 ASSERT(FALSE);\r
348 }\r
349 } else {\r
350 Lang = ShellCommandLineGetValue(Package, L"-l");\r
351 if (Lang != NULL) {\r
352 Language = AllocateZeroPool(StrSize(Lang));\r
353 AsciiSPrint(Language, StrSize(Lang), "%S", Lang);\r
354 } else if (!ShellCommandLineGetFlag(Package, L"-l")){\r
355 Language = AllocateZeroPool(10);\r
356 AsciiSPrint(Language, 10, "en-us");\r
357 } else {\r
358 ASSERT(Language == NULL);\r
359 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"-l");\r
360 ShellCommandLineFreeVarList (Package);\r
361 return (SHELL_INVALID_PARAMETER);\r
362 }\r
363\r
364 //\r
365 // Should be DriverHandle\r
366 //\r
367 Temp2 = ShellCommandLineGetRawValue(Package, 1);\r
368 if (Temp2 == NULL) {\r
369 //\r
370 // no driver specified. cannot be export, inport, or set (and no specified language)\r
371 //\r
372 if (ShellCommandLineGetFlag(Package, L"-s")\r
373 ||ShellCommandLineGetFlag(Package, L"-l")\r
374 ||ShellCommandLineGetFlag(Package, L"-o")\r
375 ||ShellCommandLineGetFlag(Package, L"-i")) {\r
376 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_HANDLE_REQ), gShellDriver1HiiHandle);\r
377 ShellStatus = SHELL_INVALID_PARAMETER;\r
378 } else {\r
379 //\r
380 // do a loop for validation, forcing, or printing\r
381 //\r
382 if (ShellCommandLineGetFlag(Package, L"-v") && ShellCommandLineGetFlag(Package, L"-f")) {\r
383 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONF), gShellDriver1HiiHandle, L"-v", L"-f");\r
384 ShellStatus = SHELL_INVALID_PARAMETER;\r
385 } else if (ShellCommandLineGetFlag(Package, L"-v")){\r
386 //\r
387 // validate\r
388 //\r
389 ShellStatus = ValidOptionsOnAll(ShellCommandLineGetFlag(Package, L"-c"));\r
390 } else if (ShellCommandLineGetFlag(Package, L"-f")){\r
391 //\r
392 // force\r
393 //\r
394ASSERT(FALSE);// ShellStatus = ForceOptionsOnAll(ShellCommandLineGetFlag(Package, L"-c"));\r
395 } else {\r
396 //\r
397 // display all that are configurable\r
398 //\r
399 ShellStatus = PrintConfigInfoOnAll(ShellCommandLineGetFlag(Package, L"-c"));\r
400 }\r
401 }\r
402 } else {\r
403 //\r
404 // we have a driver handle, make sure it's valid then process it...\r
405 //\r
406 ASSERT(FALSE);\r
407 }\r
408 }\r
409 ShellCommandLineFreeVarList (Package);\r
410 SHELL_FREE_NON_NULL(Language);\r
411 return (ShellStatus);\r
412}\r