2 Main file for bcfg shell Debug1 function.
4 Copyright (c) 2010 - 2011, 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 BcfgTargetBootOrder
= 0,
23 BcfgTargetDriverOrder
= 1,
25 } BCFG_OPERATION_TARGET
;
36 } BCFG_OPERATION_TYPE
;
39 BCFG_OPERATION_TARGET Target
;
40 BCFG_OPERATION_TYPE Type
;
47 CONST CHAR16
*OptData
;
51 This function will populate the device path protocol parameter based on TheHandle.
53 @param[in,out] DevPath On a sucessful return the device path to the handle.
55 @retval EFI_SUCCESS The device path was sucessfully returned.
56 @retval other A error from gBS->HandleProtocol.
62 GetDevicePathForDriverHandleDebug1 (
63 IN EFI_HANDLE TheHandle
,
64 IN OUT EFI_DEVICE_PATH_PROTOCOL
**FilePath
68 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
69 EFI_DEVICE_PATH_PROTOCOL
*ImageDevicePath
;
71 Status
= gBS
->OpenProtocol (
73 &gEfiLoadedImageProtocolGuid
,
77 EFI_OPEN_PROTOCOL_GET_PROTOCOL
79 if (!EFI_ERROR (Status
)) {
80 Status
= gBS
->OpenProtocol (
81 LoadedImage
->DeviceHandle
,
82 &gEfiDevicePathProtocolGuid
,
83 (VOID
**)&ImageDevicePath
,
86 EFI_OPEN_PROTOCOL_GET_PROTOCOL
88 if (!EFI_ERROR (Status
)) {
89 // *DevPath = DuplicateDevicePath (ImageDevicePath);
90 // *FilePath = DuplicateDevicePath (LoadedImage->FilePath);
91 *FilePath
= AppendDevicePath(ImageDevicePath
,LoadedImage
->FilePath
);
93 LoadedImage
->DeviceHandle
,
94 &gEfiDevicePathProtocolGuid
,
100 &gEfiLoadedImageProtocolGuid
,
108 Function to add a option.
110 @param[in] Position The position to add Target at.
111 @param[in] File The file to make the target.
112 @param[in] Desc The description text.
113 @param[in] CurrentOrder The pointer to the current order of items.
114 @param[in] OrderCount The number if items in CurrentOrder.
115 @param[in] Target The info on the option to add.
116 @param[in] UseHandle TRUE to use HandleNumber, FALSE to use File and Desc.
117 @param[in] UsePath TRUE to convert to devicepath.
118 @param[in] HandleNumber The handle number to add.
120 @retval SHELL_SUCCESS The operation was successful.
121 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
127 IN CONST CHAR16
*File
,
128 IN CONST CHAR16
*Desc
,
129 IN CONST UINT16
*CurrentOrder
,
130 IN CONST UINTN OrderCount
,
131 IN CONST BCFG_OPERATION_TARGET Target
,
132 IN CONST BOOLEAN UseHandle
,
133 IN CONST BOOLEAN UsePath
,
134 IN CONST UINTN HandleNumber
138 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
139 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
140 EFI_DEVICE_PATH_PROTOCOL
*FileNode
;
141 // EFI_DEVICE_PATH_PROTOCOL *DevPath;
143 // CONST CHAR16 *StringWalker;
144 UINT8
*TempByteBuffer
;
145 UINT8
*TempByteStart
;
146 EFI_SHELL_FILE_INFO
*Arg
;
147 EFI_SHELL_FILE_INFO
*FileList
;
148 CHAR16 OptionStr
[40];
149 UINTN DescSize
, FilePathSize
;
151 UINTN TargetLocation
;
154 EFI_HANDLE CurHandle
;
155 UINTN DriverBindingHandleCount
;
156 UINTN ParentControllerHandleCount
;
157 UINTN ChildControllerHandleCount
;
158 SHELL_STATUS ShellStatus
;
162 if (File
== NULL
|| Desc
== NULL
) {
163 return (SHELL_INVALID_PARAMETER
);
166 if (HandleNumber
== 0) {
167 return (SHELL_INVALID_PARAMETER
);
171 if (Position
> OrderCount
) {
172 Position
= OrderCount
;
180 ShellStatus
= SHELL_SUCCESS
;
181 TargetLocation
= 0xFFFF;
184 CurHandle
= ConvertHandleIndexToHandle(HandleNumber
);
185 if (CurHandle
== NULL
) {
186 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"Handle Number");
187 ShellStatus
= SHELL_INVALID_PARAMETER
;
189 if (Target
== BcfgTargetBootOrder
) {
191 //Make sure that the handle should point to a real controller
193 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
195 &DriverBindingHandleCount
,
198 Status
= PARSE_HANDLE_DATABASE_PARENTS (
200 &ParentControllerHandleCount
,
203 Status
= ParseHandleDatabaseForChildControllers (
205 &ChildControllerHandleCount
,
208 if (DriverBindingHandleCount
> 0
209 || ParentControllerHandleCount
> 0
210 || ChildControllerHandleCount
> 0) {
212 Status
= gBS
->HandleProtocol (
214 &gEfiDevicePathProtocolGuid
,
217 if (EFI_ERROR (Status
)) {
218 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_HANDLE
), gShellDebug1HiiHandle
, HandleNumber
);
219 ShellStatus
= SHELL_INVALID_PARAMETER
;
223 //Make sure that the handle should point to driver, not a controller.
225 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
227 &DriverBindingHandleCount
,
230 Status
= PARSE_HANDLE_DATABASE_PARENTS (
232 &ParentControllerHandleCount
,
235 Status
= ParseHandleDatabaseForChildControllers (
237 &ChildControllerHandleCount
,
240 Status
= gBS
->HandleProtocol (
242 &gEfiDevicePathProtocolGuid
,
245 if (DriverBindingHandleCount
> 0
246 || ParentControllerHandleCount
> 0
247 || ChildControllerHandleCount
> 0
248 || !EFI_ERROR(Status
) ) {
249 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"Handle Number");
250 ShellStatus
= SHELL_INVALID_PARAMETER
;
253 // Get the DevicePath from the loaded image information.
255 Status
= GetDevicePathForDriverHandleDebug1(CurHandle
, &FilePath
);
263 ShellOpenFileMetaArg ((CHAR16
*)File
, EFI_FILE_MODE_READ
, &FileList
);
265 if (FileList
== NULL
) {
267 // If filename matched nothing fail
269 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, File
);
270 ShellStatus
= SHELL_INVALID_PARAMETER
;
271 } else if (FileList
->Link
.ForwardLink
!= FileList
->Link
.BackLink
) {
273 // If filename expanded to multiple names, fail
275 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE
), gShellDebug1HiiHandle
, File
);
276 ShellStatus
= SHELL_INVALID_PARAMETER
;
278 Arg
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
);
279 if (EFI_ERROR(Arg
->Status
)) {
280 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_OPEN
), gShellDebug1HiiHandle
, File
, Arg
->Status
);
281 ShellStatus
= SHELL_INVALID_PARAMETER
;
284 // Build FilePath to the filename
288 // get the device path
290 DevicePath
= gEfiShellProtocol
->GetDevicePathFromFilePath(Arg
->FullName
);
291 if (DevicePath
== NULL
) {
292 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_DP
), gShellDebug1HiiHandle
, Arg
->FullName
);
293 ShellStatus
= SHELL_UNSUPPORTED
;
297 DevPath = DevicePath;
298 while (!IsDevicePathEnd(DevPath)) {
299 if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&
300 (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {
303 // If we find it use it instead
305 DevicePath = DevPath;
308 DevPath = NextDevicePathNode(DevPath);
313 for(StringWalker=Arg->FullName; *StringWalker != CHAR_NULL && *StringWalker != ':'; StringWalker++);
314 FileNode = FileDevicePath(NULL, StringWalker+1);
315 FilePath = AppendDevicePath(DevicePath, FileNode);
319 FilePath
= DuplicateDevicePath(DevicePath
);
323 FreePool(DevicePath
);
330 if (ShellStatus
== SHELL_SUCCESS
) {
332 // Find a free target ,a brute force implementation
335 for (TargetLocation
=0; TargetLocation
< 0xFFFF; TargetLocation
++) {
337 for (Index
=0; Index
< OrderCount
; Index
++) {
338 if (CurrentOrder
[Index
] == TargetLocation
) {
349 if (TargetLocation
== 0xFFFF) {
350 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET_NF
), gShellDebug1HiiHandle
);
352 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET
), gShellDebug1HiiHandle
, TargetLocation
);
356 if (ShellStatus
== SHELL_SUCCESS
) {
360 DescSize
= StrSize(Desc
);
361 FilePathSize
= GetDevicePathSize (FilePath
);
363 TempByteBuffer
= AllocateZeroPool(sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
);
364 if (TempByteBuffer
!= NULL
) {
365 TempByteStart
= TempByteBuffer
;
366 *((UINT32
*) TempByteBuffer
) = LOAD_OPTION_ACTIVE
; // Attributes
367 TempByteBuffer
+= sizeof (UINT32
);
369 *((UINT16
*) TempByteBuffer
) = (UINT16
)FilePathSize
; // FilePathListLength
370 TempByteBuffer
+= sizeof (UINT16
);
372 CopyMem (TempByteBuffer
, Desc
, DescSize
);
373 TempByteBuffer
+= DescSize
;
374 CopyMem (TempByteBuffer
, FilePath
, FilePathSize
);
376 UnicodeSPrint (OptionStr
, sizeof(OptionStr
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", TargetLocation
);
377 Status
= gRT
->SetVariable (
379 &gEfiGlobalVariableGuid
,
380 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
381 sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
,
385 FreePool(TempByteStart
);
387 Status
= EFI_OUT_OF_RESOURCES
;
390 if (EFI_ERROR(Status
)) {
391 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellDebug1HiiHandle
, OptionStr
, Status
);
393 NewOrder
= AllocateZeroPool((OrderCount
+1)*sizeof(NewOrder
[0]));
394 ASSERT(NewOrder
!= NULL
);
395 CopyMem(NewOrder
, CurrentOrder
, (OrderCount
)*sizeof(NewOrder
[0]));
398 // Insert target into order list
400 for (Index
=OrderCount
; Index
> Position
; Index
--) {
401 NewOrder
[Index
] = NewOrder
[Index
-1];
404 NewOrder
[Position
] = (UINT16
) TargetLocation
;
405 Status
= gRT
->SetVariable (
406 Target
== BcfgTargetBootOrder
?L
"BootOrder":L
"DriverOrder",
407 &gEfiGlobalVariableGuid
,
408 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
409 (OrderCount
+1) * sizeof(UINT16
),
415 if (EFI_ERROR(Status
)) {
416 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellDebug1HiiHandle
, Target
== BcfgTargetBootOrder
?L
"BootOrder":L
"DriverOrder", Status
);
417 ShellStatus
= SHELL_INVALID_PARAMETER
;
419 Print (L
"bcfg: Add %s as %x\n", OptionStr
, Position
);
425 //If always Free FilePath, will free devicepath in system when use "addh"
427 if (FilePath
!=NULL
&& !UseHandle
) {
435 if (Handles
!= NULL
) {
439 if (FileList
!= NULL
) {
440 ShellCloseFileMetaArg (&FileList
);
443 return (ShellStatus
);
447 Funciton to remove an item.
449 @param[in] Target The target item to move.
450 @param[in] CurrentOrder The pointer to the current order of items.
451 @param[in] OrderCount The number if items in CurrentOrder.
452 @param[in] Location The current location of the Target.
454 @retval SHELL_SUCCESS The operation was successful.
455 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
460 IN CONST BCFG_OPERATION_TARGET Target
,
461 IN CONST UINT16
*CurrentOrder
,
462 IN CONST UINTN OrderCount
,
463 IN CONST UINT16 Location
466 CHAR16 VariableName
[12];
471 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", CurrentOrder
[Location
]);
472 Status
= gRT
->SetVariable(
474 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
475 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
478 if (EFI_ERROR(Status
)) {
479 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellDebug1HiiHandle
, VariableName
, Status
);
480 return (SHELL_INVALID_PARAMETER
);
482 NewOrder
= AllocateZeroPool(OrderCount
*sizeof(CurrentOrder
[0]));
483 if (NewOrder
!= NULL
) {
484 NewCount
= OrderCount
;
485 CopyMem(NewOrder
, CurrentOrder
, OrderCount
*sizeof(CurrentOrder
[0]));
486 CopyMem(NewOrder
+Location
, NewOrder
+Location
+1, (OrderCount
- Location
- 1)*sizeof(CurrentOrder
[0]));
489 Status
= gRT
->SetVariable(
490 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
491 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
492 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
493 NewCount
*sizeof(NewOrder
[0]),
497 Status
= EFI_OUT_OF_RESOURCES
;
499 if (EFI_ERROR(Status
)) {
500 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellDebug1HiiHandle
, Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder", Status
);
501 return (SHELL_INVALID_PARAMETER
);
503 return (SHELL_SUCCESS
);
507 Funciton to move a item to another location.
509 @param[in] Target The target item to move.
510 @param[in] CurrentOrder The pointer to the current order of items.
511 @param[in] OrderCount The number if items in CurrentOrder.
512 @param[in] OldLocation The current location of the Target.
513 @param[in] NewLocation The desired location of the Target.
515 @retval SHELL_SUCCESS The operation was successful.
516 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
521 IN CONST BCFG_OPERATION_TARGET Target
,
522 IN CONST UINT16
*CurrentOrder
,
523 IN CONST UINTN OrderCount
,
524 IN CONST UINT16 OldLocation
,
525 IN CONST UINT16 NewLocation
532 NewOrder
= AllocateZeroPool(OrderCount
*sizeof(CurrentOrder
[0]));
533 ASSERT(NewOrder
!= NULL
);
535 Temp
= CurrentOrder
[OldLocation
];
536 CopyMem(NewOrder
, CurrentOrder
, OrderCount
*sizeof(CurrentOrder
[0]));
537 CopyMem(NewOrder
+OldLocation
, NewOrder
+OldLocation
+1, (OrderCount
- OldLocation
- 1)*sizeof(CurrentOrder
[0]));
538 CopyMem(NewOrder
+NewLocation
+1, NewOrder
+NewLocation
, (OrderCount
- NewLocation
- 1)*sizeof(CurrentOrder
[0]));
539 NewOrder
[NewLocation
] = Temp
;
542 Status
= gRT
->SetVariable(
543 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
544 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
545 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
546 OrderCount
*sizeof(CurrentOrder
[0]),
551 if (EFI_ERROR(Status
)) {
552 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellDebug1HiiHandle
, Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder", Status
);
553 return (SHELL_INVALID_PARAMETER
);
555 return (SHELL_SUCCESS
);
559 Function to add optional data to an option.
561 @param[in] OptData The optional data to add.
562 @param[in] Target The target of the operation.
564 @retval SHELL_SUCCESS The operation was succesful.
569 IN CONST CHAR16
*OptData
,
570 IN CONST BCFG_OPERATION_TARGET Target
573 ASSERT(OptData
!= NULL
);
574 return SHELL_SUCCESS
;
578 Function to dump the Bcfg information.
580 @param[in] Op The operation.
581 @param[in] OrderCount How many to dump.
582 @param[in] CurrentOrder The pointer to the current order of items.
583 @param[in] VerboseOutput TRUE for extra output. FALSE otherwise.
585 @retval SHELL_SUCCESS The dump was successful.
586 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
590 BcfgDisplayDumpDebug1(
592 IN CONST UINTN OrderCount
,
593 IN CONST UINT16
*CurrentOrder
,
594 IN CONST BOOLEAN VerboseOutput
600 CHAR16 VariableName
[12];
603 CHAR16
*DevPathString
;
606 if (OrderCount
== 0) {
607 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_BCFG_NONE
), gShellDebug1HiiHandle
);
608 return (SHELL_SUCCESS
);
611 for (LoopVar
= 0 ; LoopVar
< OrderCount
; LoopVar
++) {
614 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Op
, CurrentOrder
[LoopVar
]);
616 Status
= gRT
->GetVariable(
618 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
622 if (Status
== EFI_BUFFER_TOO_SMALL
) {
623 Buffer
= AllocateZeroPool(BufferSize
);
624 Status
= gRT
->GetVariable(
626 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
632 if (EFI_ERROR(Status
) || Buffer
== NULL
) {
633 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_READ_FAIL
), gShellDebug1HiiHandle
, VariableName
, Status
);
634 return (SHELL_INVALID_PARAMETER
);
637 if ((*(UINT16
*)(Buffer
+4)) != 0) {
638 DevPath
= AllocateZeroPool(*(UINT16
*)(Buffer
+4));
639 CopyMem(DevPath
, Buffer
+6+StrSize((CHAR16
*)(Buffer
+6)), *(UINT16
*)(Buffer
+4));
640 DevPathString
= gDevPathToText
->ConvertDevicePathToText(DevPath
, TRUE
, FALSE
);
643 DevPathString
= NULL
;
649 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS
),
650 gShellDebug1HiiHandle
,
655 (StrSize((CHAR16
*)(Buffer
+6)) + *(UINT16
*)(Buffer
+4) + 6) <= BufferSize
?L
'N':L
'Y');
657 for (LoopVar2
= (StrSize((CHAR16
*)(Buffer
+6)) + *(UINT16
*)(Buffer
+4) + 6);LoopVar2
<BufferSize
;LoopVar2
++){
672 if (Buffer
!= NULL
) {
675 if (DevPath
!= NULL
) {
678 if (DevPathString
!= NULL
) {
679 FreePool(DevPathString
);
682 return (SHELL_SUCCESS
);
686 Function to initialize the BCFG operation structure.
688 @param[in] Struct The stuct to initialize.
692 InitBcfgStructDebug1(
693 IN BGFG_OPERATION
*Struct
696 ASSERT(Struct
!= NULL
);
697 Struct
->Target
= BcfgTargetMax
;
698 Struct
->Type
= BcfgTypeMax
;
701 Struct
->HandleIndex
= 0;
702 Struct
->FileName
= NULL
;
703 Struct
->Description
= NULL
;
704 Struct
->Order
= NULL
;
705 Struct
->OptData
= NULL
;
709 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
711 {L
"-opt", TypeMaxValue
},
716 Function for 'bcfg' command.
718 @param[in] ImageHandle Handle to the Image (NULL if Internal).
719 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
723 ShellCommandRunBcfg (
724 IN EFI_HANDLE ImageHandle
,
725 IN EFI_SYSTEM_TABLE
*SystemTable
730 CHAR16
*ProblemParam
;
731 SHELL_STATUS ShellStatus
;
733 CONST CHAR16
*CurrentParam
;
734 BGFG_OPERATION CurrentOperation
;
741 ShellStatus
= SHELL_SUCCESS
;
743 InitBcfgStructDebug1(&CurrentOperation
);
746 // initialize the shell lib (we must be in non-auto-init...)
748 Status
= ShellInitialize();
749 ASSERT_EFI_ERROR(Status
);
751 Status
= CommandInit();
752 ASSERT_EFI_ERROR(Status
);
755 // parse the command line
757 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
758 if (EFI_ERROR(Status
)) {
759 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
760 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, ProblemParam
);
761 FreePool(ProblemParam
);
762 ShellStatus
= SHELL_INVALID_PARAMETER
;
768 // Read in if we are doing -OPT
770 if (ShellCommandLineGetFlag(Package
, L
"-opt")) {
771 CurrentOperation
.OptData
= ShellCommandLineGetValue(Package
, L
"-opt");
772 if (CurrentOperation
.OptData
== NULL
) {
773 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_VAL
), gShellDebug1HiiHandle
, L
"-opt");
774 ShellStatus
= SHELL_INVALID_PARAMETER
;
776 CurrentOperation
.Type
= BcfgTypeOpt
;
780 // small block to read the target of the operation
782 if ((ShellCommandLineGetCount(Package
) < 3 && CurrentOperation
.Type
!= BcfgTypeOpt
) ||
783 (ShellCommandLineGetCount(Package
) < 2 && CurrentOperation
.Type
== BcfgTypeOpt
)
785 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
);
786 ShellStatus
= SHELL_INVALID_PARAMETER
;
787 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"driver") == 0) {
788 CurrentOperation
.Target
= BcfgTargetDriverOrder
;
789 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"boot") == 0) {
790 CurrentOperation
.Target
= BcfgTargetBootOrder
;
792 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT
), gShellDebug1HiiHandle
);
793 ShellStatus
= SHELL_INVALID_PARAMETER
;
798 // Read in the boot or driver order environment variable (not needed for opt)
800 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
&& CurrentOperation
.Type
!= BcfgTypeOpt
) {
802 Status
= gRT
->GetVariable(
803 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
804 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
807 CurrentOperation
.Order
);
808 if (Status
== EFI_BUFFER_TOO_SMALL
) {
809 CurrentOperation
.Order
= AllocateZeroPool(Length
+(4*sizeof(CurrentOperation
.Order
[0])));
810 Status
= gRT
->GetVariable(
811 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
812 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
815 CurrentOperation
.Order
);
820 // large block to read the type of operation and verify parameter types for the info.
822 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
823 for (ParamNumber
= 2 ; ParamNumber
< ShellCommandLineGetCount(Package
) && ShellStatus
== SHELL_SUCCESS
; ParamNumber
++) {
824 CurrentParam
= ShellCommandLineGetRawValue(Package
, ParamNumber
);
825 if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"dump") == 0) {
826 CurrentOperation
.Type
= BcfgTypeDump
;
827 } else if (ShellCommandLineGetFlag(Package
, L
"-v")) {
828 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"-v (without dump)");
829 ShellStatus
= SHELL_INVALID_PARAMETER
;
830 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"add") == 0) {
831 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
832 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
);
833 ShellStatus
= SHELL_INVALID_PARAMETER
;
835 CurrentOperation
.Type
= BcfgTypeAdd
;
836 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
837 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
838 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, CurrentParam
);
839 ShellStatus
= SHELL_INVALID_PARAMETER
;
841 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
842 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
843 ASSERT(CurrentOperation
.FileName
== NULL
);
844 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
845 ASSERT(CurrentOperation
.Description
== NULL
);
846 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
848 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addp") == 0) {
849 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
850 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
);
851 ShellStatus
= SHELL_INVALID_PARAMETER
;
853 CurrentOperation
.Type
= BcfgTypeAddp
;
854 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
855 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
856 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, CurrentParam
);
857 ShellStatus
= SHELL_INVALID_PARAMETER
;
859 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
860 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
861 ASSERT(CurrentOperation
.FileName
== NULL
);
862 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
863 ASSERT(CurrentOperation
.Description
== NULL
);
864 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
866 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addh") == 0) {
867 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
868 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
);
869 ShellStatus
= SHELL_INVALID_PARAMETER
;
871 CurrentOperation
.Type
= BcfgTypeAddh
;
872 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
873 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
874 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, CurrentParam
);
875 ShellStatus
= SHELL_INVALID_PARAMETER
;
877 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
878 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
879 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
880 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
881 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, CurrentParam
);
882 ShellStatus
= SHELL_INVALID_PARAMETER
;
884 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
885 CurrentOperation
.HandleIndex
= (UINT16
)Intermediate
;
886 ASSERT(CurrentOperation
.Description
== NULL
);
887 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
890 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"rm") == 0) {
891 if ((ParamNumber
+ 1) >= ShellCommandLineGetCount(Package
)) {
892 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
);
893 ShellStatus
= SHELL_INVALID_PARAMETER
;
895 CurrentOperation
.Type
= BcfgTypeRm
;
896 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
897 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
898 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, CurrentParam
);
899 ShellStatus
= SHELL_INVALID_PARAMETER
;
901 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
902 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
903 if (CurrentOperation
.Number1
> (Length
/ sizeof(CurrentOperation
.Order
[0]))){
904 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellDebug1HiiHandle
, Length
/ sizeof(CurrentOperation
.Order
[0]));
905 ShellStatus
= SHELL_INVALID_PARAMETER
;
908 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"mv") == 0) {
909 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount(Package
)) {
910 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
);
911 ShellStatus
= SHELL_INVALID_PARAMETER
;
913 CurrentOperation
.Type
= BcfgTypeMv
;
914 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
915 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
916 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, CurrentParam
);
917 ShellStatus
= SHELL_INVALID_PARAMETER
;
919 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
920 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
921 if (CurrentOperation
.Number1
> (Length
/ sizeof(CurrentOperation
.Order
[0]))){
922 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellDebug1HiiHandle
, Length
/ sizeof(CurrentOperation
.Order
[0]));
923 ShellStatus
= SHELL_INVALID_PARAMETER
;
925 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
926 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
927 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, CurrentParam
);
928 ShellStatus
= SHELL_INVALID_PARAMETER
;
930 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
931 CurrentOperation
.Number2
= (UINT16
)Intermediate
;
933 if (CurrentOperation
.Number2
== CurrentOperation
.Number1
934 ||CurrentOperation
.Number1
> (Length
/ sizeof(CurrentOperation
.Order
[0]))
935 ||CurrentOperation
.Number2
> (Length
/ sizeof(CurrentOperation
.Order
[0]))
937 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellDebug1HiiHandle
, Length
/ sizeof(CurrentOperation
.Order
[0]));
938 ShellStatus
= SHELL_INVALID_PARAMETER
;
942 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, CurrentParam
);
943 ShellStatus
= SHELL_INVALID_PARAMETER
;
947 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
&& CurrentOperation
.Type
< BcfgTypeMax
) {
949 // we have all the info. Do the work
951 switch (CurrentOperation
.Type
) {
953 ShellStatus
= BcfgDisplayDumpDebug1(
954 CurrentOperation
.Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver",
955 Length
/ sizeof(CurrentOperation
.Order
[0]),
956 CurrentOperation
.Order
,
957 ShellCommandLineGetFlag(Package
, L
"-v"));
960 ShellStatus
= BcfgMoveDebug1(
961 CurrentOperation
.Target
,
962 CurrentOperation
.Order
,
963 Length
/ sizeof(CurrentOperation
.Order
[0]),
964 CurrentOperation
.Number1
,
965 CurrentOperation
.Number2
);
968 ShellStatus
= BcfgRemoveDebug1(
969 CurrentOperation
.Target
,
970 CurrentOperation
.Order
,
971 Length
/ sizeof(CurrentOperation
.Order
[0]),
972 CurrentOperation
.Number1
);
977 ShellStatus
= BcfgAddDebug1(
978 CurrentOperation
.Number1
,
979 CurrentOperation
.FileName
,
980 CurrentOperation
.Description
,
981 CurrentOperation
.Order
,
982 Length
/ sizeof(CurrentOperation
.Order
[0]),
983 CurrentOperation
.Target
,
984 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddh
),
985 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddp
),
986 CurrentOperation
.HandleIndex
);
989 ShellStatus
= BcfgAddOptDebug1(
990 CurrentOperation
.OptData
,
991 CurrentOperation
.Target
);
999 if (Package
!= NULL
) {
1000 ShellCommandLineFreeVarList (Package
);
1002 if (CurrentOperation
.FileName
!= NULL
) {
1003 FreePool(CurrentOperation
.FileName
);
1005 if (CurrentOperation
.Description
!= NULL
) {
1006 FreePool(CurrentOperation
.Description
);
1008 if (CurrentOperation
.Order
!= NULL
) {
1009 FreePool(CurrentOperation
.Order
);
1012 return (ShellStatus
);