]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/Bcfg.c
Add "Debug1" profile (all but Edit and HexEdit commands)
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / Bcfg.c
CommitLineData
5d73d92f 1/** @file\r
2 Main file for bcfg shell install1 function.\r
3\r
4 Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
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 "UefiShellDebug1CommandsLib.h"\r
16#include <Guid/GlobalVariable.h>\r
17#include <Library/PrintLib.h>\r
18#include <Library/HandleParsingLib.h>\r
19#include <Library/DevicePathLib.h>\r
20\r
21typedef enum {\r
22 BCFG_TARGET_BOOT_ORDER = 0,\r
23 BCFG_TARGET_DRIVER_ORDER = 1,\r
24 BCFG_TARGET_MAX = 2\r
25} BCFG_OPERATION_TARGET;\r
26\r
27typedef enum {\r
28 BCFG_TYPE_DUMP = 0,\r
29 BCFG_TYPE_ADD = 1,\r
30 BCFG_TYPE_ADDP = 2,\r
31 BCFG_TYPE_ADDH = 3,\r
32 BCFG_TYPE_RM = 4,\r
33 BCFG_TYPE_MV = 5,\r
34 BCFG_TYPE_OPT = 6,\r
35 BCFG_TYPE_MAX = 7\r
36} BCFG_OPERATION_TYPE;\r
37\r
38typedef struct {\r
39 BCFG_OPERATION_TARGET Target;\r
40 BCFG_OPERATION_TYPE Type;\r
41 UINT16 Number1;\r
42 UINT16 Number2;\r
43 UINTN HandleIndex;\r
44 CHAR16 *FileName;\r
45 CHAR16 *Description;\r
46 UINT16 *Order;\r
47 CONST CHAR16 *OptData;\r
48} BGFG_OPERATION;\r
49\r
50SHELL_STATUS\r
51EFIAPI\r
52BcfgAdd (\r
53 IN UINTN Position,\r
54 IN CONST CHAR16 *File,\r
55 IN CONST CHAR16 *Desc,\r
56 IN CONST UINT16 *CurrentOrder,\r
57 IN CONST UINTN OrderCount,\r
58 IN CONST BCFG_OPERATION_TARGET Target,\r
59 IN CONST BOOLEAN UseHandle,\r
60 IN CONST BOOLEAN UsePath,\r
61 IN CONST UINTN HandleNumber\r
62 )\r
63{\r
64 EFI_STATUS Status;\r
65 EFI_DEVICE_PATH_PROTOCOL *DevicePath, *FilePath, *FileNode, *DevPath;\r
66 CHAR16 *Str;\r
67 CONST CHAR16 *p;\r
68 UINT8 *p8;\r
69 EFI_SHELL_FILE_INFO *Arg;\r
70 EFI_SHELL_FILE_INFO *FileList;\r
71 CHAR16 OptionStr[40];\r
72 UINTN DescSize, FilePathSize;\r
73 BOOLEAN Found;\r
74 UINTN TargetLocation;\r
75 UINTN Index;\r
76 EFI_HANDLE *Handles;\r
77 EFI_HANDLE CurHandle;\r
78 UINTN DriverBindingHandleCount;\r
79 UINTN ParentControllerHandleCount;\r
80 UINTN ChildControllerHandleCount;\r
81 SHELL_STATUS ShellStatus;\r
82 UINT16 *NewOrder;\r
83\r
84 if (!UseHandle) {\r
85 ASSERT(File != NULL);\r
86 ASSERT(Desc != NULL);\r
87 } else {\r
88 ASSERT(HandleNumber != 0);\r
89 }\r
90\r
91 ASSERT(Position <= (OrderCount+1));\r
92\r
93 Str = NULL;\r
94 FilePath = NULL;\r
95 FileNode = NULL;\r
96 FileList = NULL;\r
97 Handles = NULL;\r
98 ShellStatus = SHELL_SUCCESS;\r
99 TargetLocation = 0xFFFF;\r
100\r
101// if (Position > 0) {\r
102// Position--;\r
103// }\r
104\r
105 if (UseHandle) {\r
106 CurHandle = ConvertHandleIndexToHandle(StrHexToUintn(File));\r
107 if (CurHandle == NULL) {\r
108 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, File);\r
109 ShellStatus = SHELL_INVALID_PARAMETER;\r
110 } else {\r
111 //\r
112 //Make sure that the handle should point to a real controller\r
113 //\r
114 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (\r
115 CurHandle,\r
116 &DriverBindingHandleCount,\r
117 NULL);\r
118\r
119 Status = PARSE_HANDLE_DATABASE_PARENTS (\r
120 CurHandle,\r
121 &ParentControllerHandleCount,\r
122 NULL);\r
123\r
124 Status = ParseHandleDatabaseForChildControllers (\r
125 CurHandle,\r
126 &ChildControllerHandleCount,\r
127 NULL);\r
128\r
129 if (DriverBindingHandleCount > 0\r
130 || ParentControllerHandleCount > 0\r
131 || ChildControllerHandleCount > 0) {\r
132 FilePath = NULL;\r
133 Status = gBS->HandleProtocol (\r
134 CurHandle,\r
135 &gEfiDevicePathProtocolGuid,\r
136 (VOID**)&FilePath);\r
137 }\r
138 if (EFI_ERROR (Status)) {\r
139 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_HANDLE), gShellDebug1HiiHandle, StrHexToUintn(File));\r
140 ShellStatus = SHELL_INVALID_PARAMETER;\r
141 }\r
142 }\r
143 } else {\r
144 //\r
145 // Get file info\r
146 //\r
147 ShellOpenFileMetaArg ((CHAR16*)File, EFI_FILE_MODE_READ, &FileList);\r
148\r
149 //\r
150 // If filename expanded to multiple names, fail\r
151 //\r
152 if (FileList == NULL || FileList->Link.ForwardLink != FileList->Link.BackLink) {\r
153 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellDebug1HiiHandle, File);\r
154 ShellStatus = SHELL_INVALID_PARAMETER;\r
155 } else {\r
156 Arg = (EFI_SHELL_FILE_INFO*)GetFirstNode(&FileList->Link);\r
157 if (EFI_ERROR(Arg->Status)) {\r
158 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellDebug1HiiHandle, File, Arg->Status);\r
159 ShellStatus = SHELL_INVALID_PARAMETER;\r
160 } else {\r
161 //\r
162 // Build FilePath to the filename\r
163 //\r
164\r
165 //\r
166 // get the device path\r
167 //\r
168 DevicePath = mEfiShellProtocol->GetDevicePathFromFilePath(Arg->FullName);\r
169 if (DevicePath != NULL) {\r
170 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellDebug1HiiHandle, Arg->FullName);\r
171 ShellStatus = SHELL_UNSUPPORTED;\r
172 } else {\r
173 if (UsePath) {\r
174 DevPath = DevicePath;\r
175 while (!IsDevicePathEnd(DevPath)) {\r
176 if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&\r
177 (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {\r
178\r
179 //\r
180 // If we find it use it instead\r
181 //\r
182 DevicePath = DevPath;\r
183 break;\r
184 }\r
185 DevPath = NextDevicePathNode(DevPath);\r
186 }\r
187 //\r
188 // append the file\r
189 //\r
190 for(p=Arg->FullName; *p != CHAR_NULL && *p != ':'; p++);\r
191 FileNode = FileDevicePath(NULL, p+1);\r
192 FilePath = AppendDevicePath(DevicePath, FileNode);\r
193 FreePool(FileNode);\r
194 } else {\r
195 FilePath = DuplicateDevicePath(DevicePath);\r
196 }\r
197\r
198 FreePool(DevicePath);\r
199 }\r
200 }\r
201 }\r
202 }\r
203\r
204\r
205 if (ShellStatus == SHELL_SUCCESS) {\r
206 //\r
207 // Find a free target ,a brute force implementation\r
208 //\r
209 Found = FALSE;\r
210 for (TargetLocation=1; TargetLocation < 0xFFFF; TargetLocation++) {\r
211 Found = TRUE;\r
212 for (Index=0; Index < OrderCount; Index++) {\r
213 if (CurrentOrder[Index] == TargetLocation) {\r
214 Found = FALSE;\r
215 break;\r
216 }\r
217 }\r
218\r
219 if (Found) {\r
220 break;\r
221 }\r
222 }\r
223\r
224 if (TargetLocation == 0xFFFF) {\r
225 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET_NF), gShellDebug1HiiHandle);\r
226 } else {\r
227 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET), gShellDebug1HiiHandle, TargetLocation);\r
228 }\r
229 }\r
230\r
231 if (ShellStatus == SHELL_SUCCESS) {\r
232 //\r
233 // Add the option\r
234 //\r
235 DescSize = StrSize(Desc);\r
236 FilePathSize = GetDevicePathSize (FilePath);\r
237\r
238 p8 = AllocatePool(sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize);\r
239 *((UINT32 *) p8) = LOAD_OPTION_ACTIVE; // Attributes\r
240 p8 += sizeof (UINT32);\r
241\r
242 *((UINT16 *) p8) = (UINT16)FilePathSize; // FilePathListLength\r
243 p8 += sizeof (UINT16);\r
244\r
245 CopyMem (p8, Desc, DescSize);\r
246 p8 += DescSize;\r
247 CopyMem (p8, FilePath, FilePathSize);\r
248\r
249 UnicodeSPrint (OptionStr, sizeof(OptionStr), L"%s%04x", Target == BCFG_TARGET_BOOT_ORDER?L"Boot":L"Driver", TargetLocation);\r
250 Status = gRT->SetVariable (\r
251 OptionStr,\r
252 &gEfiGlobalVariableGuid,\r
253 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
254 sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize,\r
255 p8\r
256 );\r
257\r
258 FreePool(p8);\r
259\r
260 if (EFI_ERROR(Status)) {\r
261 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellDebug1HiiHandle, OptionStr, Status);\r
262 } else {\r
263 NewOrder = AllocatePool((OrderCount+1)*sizeof(NewOrder[0]));\r
264 ASSERT(NewOrder != NULL);\r
265 CopyMem(NewOrder, CurrentOrder, (OrderCount)*sizeof(NewOrder[0]));\r
266\r
267 //\r
268 // Insert target into order list\r
269 //\r
270 for (Index=OrderCount; Index > Position; Index--) {\r
271 NewOrder[Index] = NewOrder[Index-1];\r
272 }\r
273\r
274 NewOrder[Position] = (UINT16) TargetLocation;\r
275 Status = gRT->SetVariable (\r
276 Target == BCFG_TARGET_BOOT_ORDER?L"BootOrder":L"DriverOrder",\r
277 &gEfiGlobalVariableGuid,\r
278 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
279 (OrderCount+1) * sizeof(UINT16),\r
280 NewOrder\r
281 );\r
282\r
283 FreePool(NewOrder);\r
284\r
285 if (EFI_ERROR(Status)) {\r
286 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellDebug1HiiHandle, Target == BCFG_TARGET_BOOT_ORDER?L"BootOrder":L"DriverOrder", Status);\r
287 ShellStatus = SHELL_INVALID_PARAMETER;\r
288 } else {\r
289 Print (L"bcfg: Add %s as %x\n", OptionStr, Position);\r
290 }\r
291 }\r
292 }\r
293 if (FileNode != NULL) {\r
294 FreePool (FileNode);\r
295 }\r
296\r
297//\r
298//If always Free FilePath, will free devicepath in system when use "addh"\r
299//\r
300\r
301 if (FilePath!=NULL && !UseHandle) {\r
302 FreePool (FilePath);\r
303 }\r
304\r
305 if (Str != NULL) {\r
306 FreePool(Str);\r
307 }\r
308\r
309 if (Handles != NULL) {\r
310 FreePool (Handles);\r
311 }\r
312\r
313 if (FileList != NULL) {\r
314 ShellCloseFileMetaArg (&FileList);\r
315 }\r
316\r
317 return (ShellStatus);\r
318}\r
319\r
320SHELL_STATUS\r
321EFIAPI\r
322BcfgRemove(\r
323 IN CONST BCFG_OPERATION_TARGET Target,\r
324 IN CONST UINT16 *CurrentOrder,\r
325 IN CONST UINTN OrderCount,\r
326 IN CONST UINT16 Location\r
327 )\r
328{\r
329 CHAR16 VariableName[12];\r
330 UINT16 *NewOrder;\r
331 EFI_STATUS Status;\r
332 UINTN LoopVar;\r
333 UINTN NewCount;\r
334\r
335 UnicodeSPrint(VariableName, sizeof(VariableName), L"%s%04x", Target == BCFG_TARGET_BOOT_ORDER?L"Boot":L"Driver", Location);\r
336 Status = gRT->SetVariable(\r
337 VariableName,\r
338 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
339 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
340 0,\r
341 NULL);\r
342 if (EFI_ERROR(Status)) {\r
343 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellDebug1HiiHandle, VariableName, Status);\r
344 return (SHELL_INVALID_PARAMETER);\r
345 }\r
346 NewOrder = AllocatePool(OrderCount*sizeof(CurrentOrder[0]));\r
347 NewCount = OrderCount;\r
348 CopyMem(NewOrder, CurrentOrder, OrderCount*sizeof(CurrentOrder[0]));\r
349 for (LoopVar = 0 ; LoopVar < OrderCount ; LoopVar++){\r
350 if (NewOrder[LoopVar] == Location) {\r
351 CopyMem(NewOrder+LoopVar, NewOrder+LoopVar+1, (OrderCount - LoopVar - 1)*sizeof(CurrentOrder[0]));\r
352 NewCount--;\r
353 }\r
354 }\r
355 Status = gRT->SetVariable(\r
356 Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",\r
357 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
358 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
359 NewCount*sizeof(NewOrder[0]),\r
360 NewOrder);\r
361 FreePool(NewOrder);\r
362\r
363 if (EFI_ERROR(Status)) {\r
364 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellDebug1HiiHandle, Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder", Status);\r
365 return (SHELL_INVALID_PARAMETER);\r
366 }\r
367 return (SHELL_SUCCESS);\r
368}\r
369\r
370SHELL_STATUS\r
371EFIAPI\r
372BcfgMove(\r
373 IN CONST BCFG_OPERATION_TARGET Target,\r
374 IN CONST UINT16 *CurrentOrder,\r
375 IN CONST UINTN OrderCount,\r
376 IN CONST UINT16 OldLocation,\r
377 IN CONST UINT16 NewLocation\r
378 )\r
379{\r
380 UINT16 *NewOrder;\r
381 EFI_STATUS Status;\r
382 UINT16 Temp;\r
383\r
384 NewOrder = AllocatePool(OrderCount*sizeof(CurrentOrder[0]));\r
385 ASSERT(NewOrder != NULL);\r
386\r
387 Temp = CurrentOrder[OldLocation];\r
388 CopyMem(NewOrder, CurrentOrder, OrderCount*sizeof(CurrentOrder[0]));\r
389 CopyMem(NewOrder+OldLocation, NewOrder+OldLocation+1, (OrderCount - OldLocation - 1)*sizeof(CurrentOrder[0]));\r
390 CopyMem(NewOrder+NewLocation+1, NewOrder+NewLocation, (OrderCount - NewLocation - 1)*sizeof(CurrentOrder[0]));\r
391 NewOrder[NewLocation] = Temp;\r
392\r
393\r
394 Status = gRT->SetVariable(\r
395 Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",\r
396 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
397 EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
398 OrderCount*sizeof(CurrentOrder[0]),\r
399 NewOrder);\r
400\r
401 FreePool(NewOrder);\r
402\r
403 if (EFI_ERROR(Status)) {\r
404 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellDebug1HiiHandle, Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder", Status);\r
405 return (SHELL_INVALID_PARAMETER);\r
406 }\r
407 return (SHELL_SUCCESS);\r
408}\r
409\r
410SHELL_STATUS\r
411EFIAPI\r
412BcfgDisplayDump(\r
413 IN CONST CHAR16 *Op,\r
414 IN CONST UINTN OrderCount,\r
415 IN CONST BOOLEAN VerboseOutput\r
416 )\r
417{\r
418 EFI_STATUS Status;\r
419 UINT8 *Buffer;\r
420 UINTN BufferSize;\r
421 CHAR16 VariableName[12];\r
422 UINTN LoopVar;\r
423 UINTN LoopVar2;\r
424 CHAR16 *DevPathString;\r
425 VOID *DevPath;\r
426\r
427 for (LoopVar = 0 ; LoopVar < OrderCount ; LoopVar++) {\r
428 Buffer = NULL;\r
429 BufferSize = 0;\r
430 UnicodeSPrint(VariableName, sizeof(VariableName), L"%s%04x", Op, LoopVar);\r
431\r
432 Status = gRT->GetVariable(\r
433 VariableName,\r
434 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
435 NULL,\r
436 &BufferSize,\r
437 Buffer);\r
438 if (Status == EFI_BUFFER_TOO_SMALL) {\r
439 Buffer = AllocatePool(BufferSize);\r
440 Status = gRT->GetVariable(\r
441 VariableName,\r
442 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
443 NULL,\r
444 &BufferSize,\r
445 Buffer);\r
446 }\r
447\r
448 if (EFI_ERROR(Status) || Buffer == NULL) {\r
449 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_READ_FAIL), gShellDebug1HiiHandle, VariableName, Status);\r
450 return (SHELL_INVALID_PARAMETER);\r
451 }\r
452\r
453 DevPath = AllocatePool(*(UINT16*)(Buffer+4));\r
454 CopyMem(DevPath, Buffer+6+StrSize((CHAR16*)(Buffer+6)), *(UINT16*)(Buffer+4));\r
455 DevPathString = gDevPathToText->ConvertDevicePathToText(DevPath, TRUE, FALSE);\r
456 ShellPrintHiiEx(\r
457 -1,\r
458 -1,\r
459 NULL,\r
460 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS),\r
461 gShellDebug1HiiHandle,\r
462 VariableName,\r
463 (CHAR16*)(Buffer+6),\r
464 DevPathString,\r
465 (StrSize((CHAR16*)(Buffer+6)) + *(UINT16*)(Buffer+4) + 6) <= BufferSize?L'N':L'Y');\r
466 if (VerboseOutput) {\r
467 for (LoopVar2 = (StrSize((CHAR16*)(Buffer+6)) + *(UINT16*)(Buffer+4) + 6);LoopVar2<BufferSize;LoopVar2++){\r
468 ShellPrintEx(\r
469 -1,\r
470 -1,\r
471 NULL,\r
472 L"%02x",\r
473 Buffer[LoopVar2]);\r
474 }\r
475 ShellPrintEx(\r
476 -1,\r
477 -1,\r
478 NULL,\r
479 L"\r\n");\r
480 }\r
481\r
482 if (Buffer != NULL) {\r
483 FreePool(Buffer);\r
484 }\r
485 if (DevPath != NULL) {\r
486 FreePool(DevPath);\r
487 }\r
488 if (DevPathString != NULL) {\r
489 FreePool(DevPathString);\r
490 }\r
491 }\r
492 return (SHELL_SUCCESS);\r
493}\r
494\r
495VOID\r
496EFIAPI\r
497InitBcfgStruct(\r
498 IN BGFG_OPERATION *Struct\r
499 )\r
500{\r
501 ASSERT(Struct != NULL);\r
502 Struct->Target = BCFG_TARGET_MAX;\r
503 Struct->Type = BCFG_TYPE_MAX;\r
504 Struct->Number1 = 0;\r
505 Struct->Number2 = 0;\r
506 Struct->HandleIndex = 0;\r
507 Struct->FileName = NULL;\r
508 Struct->Description = NULL;\r
509 Struct->Order = NULL;\r
510 Struct->OptData = NULL;\r
511}\r
512\r
513\r
514STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
515 {L"-v", TypeFlag},\r
516 {L"-opt", TypeMaxValue},\r
517 {NULL, TypeMax}\r
518 };\r
519\r
520/**\r
521 Function for 'bcfg' command.\r
522\r
523 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
524 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
525**/\r
526SHELL_STATUS\r
527EFIAPI\r
528ShellCommandRunBcfg (\r
529 IN EFI_HANDLE ImageHandle,\r
530 IN EFI_SYSTEM_TABLE *SystemTable\r
531 )\r
532{\r
533 EFI_STATUS Status;\r
534 LIST_ENTRY *Package;\r
535 CHAR16 *ProblemParam;\r
536 SHELL_STATUS ShellStatus;\r
537 UINTN ParamNumber;\r
538 CONST CHAR16 *CurrentParam;\r
539 BGFG_OPERATION CurrentOperation;\r
540 UINTN Length;\r
541\r
542 Length = 0;\r
543 ProblemParam = NULL;\r
544 Package = NULL;\r
545 ShellStatus = SHELL_SUCCESS;\r
546\r
547 InitBcfgStruct(&CurrentOperation);\r
548\r
549 //\r
550 // initialize the shell lib (we must be in non-auto-init...)\r
551 //\r
552 Status = ShellInitialize();\r
553 ASSERT_EFI_ERROR(Status);\r
554\r
555 Status = CommandInit();\r
556 ASSERT_EFI_ERROR(Status);\r
557\r
558 //\r
559 // parse the command line\r
560 //\r
561 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
562 if (EFI_ERROR(Status)) {\r
563 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
564 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam);\r
565 FreePool(ProblemParam);\r
566 ShellStatus = SHELL_INVALID_PARAMETER;\r
567 } else {\r
568 ASSERT(FALSE);\r
569 }\r
570 } else {\r
571 //\r
572 // small block to read the target of the operation\r
573 //\r
574 if (ShellCommandLineGetCount(Package) < 3) {\r
575 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);\r
576 ShellStatus = SHELL_INVALID_PARAMETER;\r
577 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"driver") == 0) {\r
578 CurrentOperation.Target = BCFG_TARGET_DRIVER_ORDER;\r
579 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"boot") == 0) {\r
580 CurrentOperation.Target = BCFG_TARGET_BOOT_ORDER;\r
581 } else {\r
582 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT), gShellDebug1HiiHandle);\r
583 ShellStatus = SHELL_INVALID_PARAMETER;\r
584 }\r
585\r
586 //\r
587 // Read in if we are doing -OPT\r
588 //\r
589 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BCFG_TARGET_MAX && ShellCommandLineGetFlag(Package, L"-opt")) {\r
590 CurrentOperation.OptData = ShellCommandLineGetValue(Package, L"-opt");\r
591 CurrentOperation.Type = BCFG_TYPE_OPT;\r
592 }\r
593\r
594 //\r
595 // Read in the boot or driver order environment variable (not needed for opt)\r
596 //\r
597 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BCFG_TARGET_MAX && CurrentOperation.Type != BCFG_TYPE_OPT) {\r
598 Length = 0;\r
599 Status = gRT->GetVariable(\r
600 CurrentOperation.Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",\r
601 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
602 NULL,\r
603 &Length,\r
604 CurrentOperation.Order);\r
605 if (Status == EFI_BUFFER_TOO_SMALL) {\r
606 CurrentOperation.Order = AllocatePool(Length+(4*sizeof(CurrentOperation.Order[0])));\r
607 Status = gRT->GetVariable(\r
608 CurrentOperation.Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",\r
609 (EFI_GUID*)&gEfiGlobalVariableGuid,\r
610 NULL,\r
611 &Length,\r
612 CurrentOperation.Order);\r
613 }\r
614 }\r
615\r
616 //\r
617 // large block to read the type of operation and verify parameter types for the info.\r
618 //\r
619 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BCFG_TARGET_MAX) {\r
620 for (ParamNumber = 2 ; ParamNumber < ShellCommandLineGetCount(Package) && ShellStatus == SHELL_SUCCESS; ParamNumber++) {\r
621 CurrentParam = ShellCommandLineGetRawValue(Package, ParamNumber);\r
622 if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"dump") == 0) {\r
623 CurrentOperation.Type = BCFG_TYPE_DUMP;\r
624 } else if (ShellCommandLineGetFlag(Package, L"-v")) {\r
625 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"-v (without dump)");\r
626 ShellStatus = SHELL_INVALID_PARAMETER;\r
627 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"add") == 0) {\r
628 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {\r
629 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);\r
630 ShellStatus = SHELL_INVALID_PARAMETER;\r
631 }\r
632 CurrentOperation.Type = BCFG_TYPE_ADD;\r
633 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
634 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
635 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, CurrentParam);\r
636 ShellStatus = SHELL_INVALID_PARAMETER;\r
637 } else {\r
638 CurrentOperation.Number1 = (UINT16)StrHexToUintn(CurrentParam);\r
639 ASSERT(CurrentOperation.FileName == NULL);\r
640 CurrentOperation.FileName = StrnCatGrow(&CurrentOperation.FileName , NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
641 ASSERT(CurrentOperation.Description == NULL);\r
642 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
643 }\r
644 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addp") == 0) {\r
645 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {\r
646 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);\r
647 ShellStatus = SHELL_INVALID_PARAMETER;\r
648 }\r
649 CurrentOperation.Type = BCFG_TYPE_ADDP;\r
650 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
651 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
652 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, CurrentParam);\r
653 ShellStatus = SHELL_INVALID_PARAMETER;\r
654 } else {\r
655 CurrentOperation.Number1 = (UINT16)StrHexToUintn(CurrentParam);\r
656 ASSERT(CurrentOperation.FileName == NULL);\r
657 CurrentOperation.FileName = StrnCatGrow(&CurrentOperation.FileName , NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
658 ASSERT(CurrentOperation.Description == NULL);\r
659 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
660 }\r
661 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addh") == 0) {\r
662 if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {\r
663 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);\r
664 ShellStatus = SHELL_INVALID_PARAMETER;\r
665 }\r
666 CurrentOperation.Type = BCFG_TYPE_ADDH;\r
667 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
668 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
669 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, CurrentParam);\r
670 ShellStatus = SHELL_INVALID_PARAMETER;\r
671 } else {\r
672 CurrentOperation.Number1 = (UINT16)StrHexToUintn(CurrentParam);\r
673 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
674 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
675 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, CurrentParam);\r
676 ShellStatus = SHELL_INVALID_PARAMETER;\r
677 } else {\r
678 CurrentOperation.HandleIndex = (UINT16)StrHexToUintn(CurrentParam);\r
679 ASSERT(CurrentOperation.Description == NULL);\r
680 CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
681 }\r
682 }\r
683 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"rm") == 0) {\r
684 if ((ParamNumber + 1) >= ShellCommandLineGetCount(Package)) {\r
685 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);\r
686 ShellStatus = SHELL_INVALID_PARAMETER;\r
687 }\r
688 CurrentOperation.Type = BCFG_TYPE_RM;\r
689 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
690 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
691 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, CurrentParam);\r
692 ShellStatus = SHELL_INVALID_PARAMETER;\r
693 } else {\r
694 CurrentOperation.Number1 = (UINT16)StrHexToUintn(CurrentParam);\r
695 if (CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))){\r
696 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellDebug1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));\r
697 ShellStatus = SHELL_INVALID_PARAMETER;\r
698 }\r
699 }\r
700 } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"mv") == 0) {\r
701 if ((ParamNumber + 2) >= ShellCommandLineGetCount(Package)) {\r
702 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);\r
703 ShellStatus = SHELL_INVALID_PARAMETER;\r
704 }\r
705 CurrentOperation.Type = BCFG_TYPE_MV;\r
706 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
707 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
708 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, CurrentParam);\r
709 ShellStatus = SHELL_INVALID_PARAMETER;\r
710 } else {\r
711 CurrentOperation.Number1 = (UINT16)StrHexToUintn(CurrentParam);\r
712 if (CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))){\r
713 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellDebug1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));\r
714 ShellStatus = SHELL_INVALID_PARAMETER;\r
715 }\r
716 CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
717 if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
718 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, CurrentParam);\r
719 ShellStatus = SHELL_INVALID_PARAMETER;\r
720 } else {\r
721 CurrentOperation.Number2 = (UINT16)StrHexToUintn(CurrentParam);\r
722 }\r
723 if (CurrentOperation.Number2 == CurrentOperation.Number1\r
724 ||CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))\r
725 ||CurrentOperation.Number2 > (Length / sizeof(CurrentOperation.Order[0]))\r
726 ){\r
727 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellDebug1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));\r
728 ShellStatus = SHELL_INVALID_PARAMETER;\r
729 }\r
730 }\r
731 } else {\r
732 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, CurrentParam);\r
733 ShellStatus = SHELL_INVALID_PARAMETER;\r
734 }\r
735 }\r
736 }\r
737 if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BCFG_TARGET_MAX && CurrentOperation.Type < BCFG_TYPE_MAX) {\r
738 //\r
739 // we have all the info. Do the work\r
740 //\r
741 switch (CurrentOperation.Type) {\r
742 case BCFG_TYPE_DUMP:\r
743 ShellStatus = BcfgDisplayDump(\r
744 CurrentOperation.Target == BCFG_TARGET_BOOT_ORDER?L"Boot":L"Driver",\r
745 Length / sizeof(CurrentOperation.Order[0]),\r
746 ShellCommandLineGetFlag(Package, L"-v"));\r
747 break;\r
748 case BCFG_TYPE_MV:\r
749 ShellStatus = BcfgMove(\r
750 CurrentOperation.Target,\r
751 CurrentOperation.Order,\r
752 Length / sizeof(CurrentOperation.Order[0]),\r
753 CurrentOperation.Number1,\r
754 CurrentOperation.Number2);\r
755 break;\r
756 case BCFG_TYPE_RM:\r
757 ShellStatus = BcfgRemove(\r
758 CurrentOperation.Target,\r
759 CurrentOperation.Order,\r
760 Length / sizeof(CurrentOperation.Order[0]),\r
761 CurrentOperation.Number1);\r
762 break;\r
763 case BCFG_TYPE_ADD:\r
764 case BCFG_TYPE_ADDP:\r
765 case BCFG_TYPE_ADDH:\r
766 ShellStatus = BcfgAdd(\r
767 CurrentOperation.Number1,\r
768 CurrentOperation.FileName,\r
769 CurrentOperation.Description,\r
770 CurrentOperation.Order,\r
771 Length,\r
772 CurrentOperation.Target,\r
773 (BOOLEAN)(CurrentOperation.Type == BCFG_TYPE_ADDH),\r
774 (BOOLEAN)(CurrentOperation.Type == BCFG_TYPE_ADDP),\r
775 CurrentOperation.HandleIndex);\r
776 break;\r
777 case BCFG_TYPE_OPT:\r
778 default:\r
779 ASSERT(FALSE);\r
780 }\r
781 }\r
782 }\r
783\r
784 if (Package != NULL) {\r
785 ShellCommandLineFreeVarList (Package);\r
786 }\r
787 if (CurrentOperation.FileName != NULL) {\r
788 FreePool(CurrentOperation.FileName);\r
789 }\r
790 if (CurrentOperation.Description != NULL) {\r
791 FreePool(CurrentOperation.Description);\r
792 }\r
793 if (CurrentOperation.Order != NULL) {\r
794 FreePool(CurrentOperation.Order);\r
795 }\r
796\r
797 return (ShellStatus);\r
798}\r