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