2 Main file for bcfg shell install1 function.
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
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.
15 #include "UefiShellDebug1CommandsLib.h"
16 #include <Guid/GlobalVariable.h>
17 #include <Library/PrintLib.h>
18 #include <Library/HandleParsingLib.h>
19 #include <Library/DevicePathLib.h>
22 BCFG_TARGET_BOOT_ORDER
= 0,
23 BCFG_TARGET_DRIVER_ORDER
= 1,
25 } BCFG_OPERATION_TARGET
;
36 } BCFG_OPERATION_TYPE
;
39 BCFG_OPERATION_TARGET Target
;
40 BCFG_OPERATION_TYPE Type
;
47 CONST CHAR16
*OptData
;
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
65 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
, *FilePath
, *FileNode
, *DevPath
;
69 EFI_SHELL_FILE_INFO
*Arg
;
70 EFI_SHELL_FILE_INFO
*FileList
;
72 UINTN DescSize
, FilePathSize
;
78 UINTN DriverBindingHandleCount
;
79 UINTN ParentControllerHandleCount
;
80 UINTN ChildControllerHandleCount
;
81 SHELL_STATUS ShellStatus
;
88 ASSERT(HandleNumber
!= 0);
91 ASSERT(Position
<= (OrderCount
+1));
98 ShellStatus
= SHELL_SUCCESS
;
99 TargetLocation
= 0xFFFF;
101 // if (Position > 0) {
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
;
112 //Make sure that the handle should point to a real controller
114 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
116 &DriverBindingHandleCount
,
119 Status
= PARSE_HANDLE_DATABASE_PARENTS (
121 &ParentControllerHandleCount
,
124 Status
= ParseHandleDatabaseForChildControllers (
126 &ChildControllerHandleCount
,
129 if (DriverBindingHandleCount
> 0
130 || ParentControllerHandleCount
> 0
131 || ChildControllerHandleCount
> 0) {
133 Status
= gBS
->HandleProtocol (
135 &gEfiDevicePathProtocolGuid
,
138 if (EFI_ERROR (Status
)) {
139 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_HANDLE
), gShellDebug1HiiHandle
, StrHexToUintn(File
));
140 ShellStatus
= SHELL_INVALID_PARAMETER
;
147 ShellOpenFileMetaArg ((CHAR16
*)File
, EFI_FILE_MODE_READ
, &FileList
);
150 // If filename expanded to multiple names, fail
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
;
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
;
162 // Build FilePath to the filename
166 // get the device path
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
;
174 DevPath
= DevicePath
;
175 while (!IsDevicePathEnd(DevPath
)) {
176 if ((DevicePathType(DevPath
) == MEDIA_DEVICE_PATH
) &&
177 (DevicePathSubType(DevPath
) == MEDIA_HARDDRIVE_DP
)) {
180 // If we find it use it instead
182 DevicePath
= DevPath
;
185 DevPath
= NextDevicePathNode(DevPath
);
190 for(p
=Arg
->FullName
; *p
!= CHAR_NULL
&& *p
!= ':'; p
++);
191 FileNode
= FileDevicePath(NULL
, p
+1);
192 FilePath
= AppendDevicePath(DevicePath
, FileNode
);
195 FilePath
= DuplicateDevicePath(DevicePath
);
198 FreePool(DevicePath
);
205 if (ShellStatus
== SHELL_SUCCESS
) {
207 // Find a free target ,a brute force implementation
210 for (TargetLocation
=1; TargetLocation
< 0xFFFF; TargetLocation
++) {
212 for (Index
=0; Index
< OrderCount
; Index
++) {
213 if (CurrentOrder
[Index
] == TargetLocation
) {
224 if (TargetLocation
== 0xFFFF) {
225 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET_NF
), gShellDebug1HiiHandle
);
227 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET
), gShellDebug1HiiHandle
, TargetLocation
);
231 if (ShellStatus
== SHELL_SUCCESS
) {
235 DescSize
= StrSize(Desc
);
236 FilePathSize
= GetDevicePathSize (FilePath
);
238 p8
= AllocatePool(sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
);
239 *((UINT32
*) p8
) = LOAD_OPTION_ACTIVE
; // Attributes
240 p8
+= sizeof (UINT32
);
242 *((UINT16
*) p8
) = (UINT16
)FilePathSize
; // FilePathListLength
243 p8
+= sizeof (UINT16
);
245 CopyMem (p8
, Desc
, DescSize
);
247 CopyMem (p8
, FilePath
, FilePathSize
);
249 UnicodeSPrint (OptionStr
, sizeof(OptionStr
), L
"%s%04x", Target
== BCFG_TARGET_BOOT_ORDER
?L
"Boot":L
"Driver", TargetLocation
);
250 Status
= gRT
->SetVariable (
252 &gEfiGlobalVariableGuid
,
253 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
254 sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
,
260 if (EFI_ERROR(Status
)) {
261 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellDebug1HiiHandle
, OptionStr
, Status
);
263 NewOrder
= AllocatePool((OrderCount
+1)*sizeof(NewOrder
[0]));
264 ASSERT(NewOrder
!= NULL
);
265 CopyMem(NewOrder
, CurrentOrder
, (OrderCount
)*sizeof(NewOrder
[0]));
268 // Insert target into order list
270 for (Index
=OrderCount
; Index
> Position
; Index
--) {
271 NewOrder
[Index
] = NewOrder
[Index
-1];
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
),
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
;
289 Print (L
"bcfg: Add %s as %x\n", OptionStr
, Position
);
293 if (FileNode
!= NULL
) {
298 //If always Free FilePath, will free devicepath in system when use "addh"
301 if (FilePath
!=NULL
&& !UseHandle
) {
309 if (Handles
!= NULL
) {
313 if (FileList
!= NULL
) {
314 ShellCloseFileMetaArg (&FileList
);
317 return (ShellStatus
);
323 IN CONST BCFG_OPERATION_TARGET Target
,
324 IN CONST UINT16
*CurrentOrder
,
325 IN CONST UINTN OrderCount
,
326 IN CONST UINT16 Location
329 CHAR16 VariableName
[12];
335 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BCFG_TARGET_BOOT_ORDER
?L
"Boot":L
"Driver", Location
);
336 Status
= gRT
->SetVariable(
338 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
339 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
342 if (EFI_ERROR(Status
)) {
343 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellDebug1HiiHandle
, VariableName
, Status
);
344 return (SHELL_INVALID_PARAMETER
);
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]));
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]),
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
);
367 return (SHELL_SUCCESS
);
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
384 NewOrder
= AllocatePool(OrderCount
*sizeof(CurrentOrder
[0]));
385 ASSERT(NewOrder
!= NULL
);
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
;
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]),
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
);
407 return (SHELL_SUCCESS
);
414 IN CONST UINTN OrderCount
,
415 IN CONST BOOLEAN VerboseOutput
421 CHAR16 VariableName
[12];
424 CHAR16
*DevPathString
;
427 for (LoopVar
= 0 ; LoopVar
< OrderCount
; LoopVar
++) {
430 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Op
, LoopVar
);
432 Status
= gRT
->GetVariable(
434 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
438 if (Status
== EFI_BUFFER_TOO_SMALL
) {
439 Buffer
= AllocatePool(BufferSize
);
440 Status
= gRT
->GetVariable(
442 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
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
);
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
);
460 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS
),
461 gShellDebug1HiiHandle
,
465 (StrSize((CHAR16
*)(Buffer
+6)) + *(UINT16
*)(Buffer
+4) + 6) <= BufferSize
?L
'N':L
'Y');
467 for (LoopVar2
= (StrSize((CHAR16
*)(Buffer
+6)) + *(UINT16
*)(Buffer
+4) + 6);LoopVar2
<BufferSize
;LoopVar2
++){
482 if (Buffer
!= NULL
) {
485 if (DevPath
!= NULL
) {
488 if (DevPathString
!= NULL
) {
489 FreePool(DevPathString
);
492 return (SHELL_SUCCESS
);
498 IN BGFG_OPERATION
*Struct
501 ASSERT(Struct
!= NULL
);
502 Struct
->Target
= BCFG_TARGET_MAX
;
503 Struct
->Type
= BCFG_TYPE_MAX
;
506 Struct
->HandleIndex
= 0;
507 Struct
->FileName
= NULL
;
508 Struct
->Description
= NULL
;
509 Struct
->Order
= NULL
;
510 Struct
->OptData
= NULL
;
514 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
516 {L
"-opt", TypeMaxValue
},
521 Function for 'bcfg' command.
523 @param[in] ImageHandle Handle to the Image (NULL if Internal).
524 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
528 ShellCommandRunBcfg (
529 IN EFI_HANDLE ImageHandle
,
530 IN EFI_SYSTEM_TABLE
*SystemTable
535 CHAR16
*ProblemParam
;
536 SHELL_STATUS ShellStatus
;
538 CONST CHAR16
*CurrentParam
;
539 BGFG_OPERATION CurrentOperation
;
545 ShellStatus
= SHELL_SUCCESS
;
547 InitBcfgStruct(&CurrentOperation
);
550 // initialize the shell lib (we must be in non-auto-init...)
552 Status
= ShellInitialize();
553 ASSERT_EFI_ERROR(Status
);
555 Status
= CommandInit();
556 ASSERT_EFI_ERROR(Status
);
559 // parse the command line
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
;
572 // small block to read the target of the operation
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
;
582 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT
), gShellDebug1HiiHandle
);
583 ShellStatus
= SHELL_INVALID_PARAMETER
;
587 // Read in if we are doing -OPT
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
;
595 // Read in the boot or driver order environment variable (not needed for opt)
597 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BCFG_TARGET_MAX
&& CurrentOperation
.Type
!= BCFG_TYPE_OPT
) {
599 Status
= gRT
->GetVariable(
600 CurrentOperation
.Target
== BCFG_TARGET_BOOT_ORDER
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
601 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
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
,
612 CurrentOperation
.Order
);
617 // large block to read the type of operation and verify parameter types for the info.
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
;
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
;
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);
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
;
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
;
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);
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
;
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
;
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
;
678 CurrentOperation
.HandleIndex
= (UINT16
)StrHexToUintn(CurrentParam
);
679 ASSERT(CurrentOperation
.Description
== NULL
);
680 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
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
;
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
;
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
;
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
;
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
;
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
;
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
;
721 CurrentOperation
.Number2
= (UINT16
)StrHexToUintn(CurrentParam
);
723 if (CurrentOperation
.Number2
== CurrentOperation
.Number1
724 ||CurrentOperation
.Number1
> (Length
/ sizeof(CurrentOperation
.Order
[0]))
725 ||CurrentOperation
.Number2
> (Length
/ sizeof(CurrentOperation
.Order
[0]))
727 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellDebug1HiiHandle
, Length
/ sizeof(CurrentOperation
.Order
[0]));
728 ShellStatus
= SHELL_INVALID_PARAMETER
;
732 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, CurrentParam
);
733 ShellStatus
= SHELL_INVALID_PARAMETER
;
737 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BCFG_TARGET_MAX
&& CurrentOperation
.Type
< BCFG_TYPE_MAX
) {
739 // we have all the info. Do the work
741 switch (CurrentOperation
.Type
) {
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"));
749 ShellStatus
= BcfgMove(
750 CurrentOperation
.Target
,
751 CurrentOperation
.Order
,
752 Length
/ sizeof(CurrentOperation
.Order
[0]),
753 CurrentOperation
.Number1
,
754 CurrentOperation
.Number2
);
757 ShellStatus
= BcfgRemove(
758 CurrentOperation
.Target
,
759 CurrentOperation
.Order
,
760 Length
/ sizeof(CurrentOperation
.Order
[0]),
761 CurrentOperation
.Number1
);
766 ShellStatus
= BcfgAdd(
767 CurrentOperation
.Number1
,
768 CurrentOperation
.FileName
,
769 CurrentOperation
.Description
,
770 CurrentOperation
.Order
,
772 CurrentOperation
.Target
,
773 (BOOLEAN
)(CurrentOperation
.Type
== BCFG_TYPE_ADDH
),
774 (BOOLEAN
)(CurrentOperation
.Type
== BCFG_TYPE_ADDP
),
775 CurrentOperation
.HandleIndex
);
784 if (Package
!= NULL
) {
785 ShellCommandLineFreeVarList (Package
);
787 if (CurrentOperation
.FileName
!= NULL
) {
788 FreePool(CurrentOperation
.FileName
);
790 if (CurrentOperation
.Description
!= NULL
) {
791 FreePool(CurrentOperation
.Description
);
793 if (CurrentOperation
.Order
!= NULL
) {
794 FreePool(CurrentOperation
.Order
);
797 return (ShellStatus
);