2 Main file for bcfg shell Install1 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 "UefiShellInstall1CommandsLib.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] TheHandle Driver handle.
54 @param[in, out] FilePath On a sucessful return the device path to the handle.
56 @retval EFI_SUCCESS The device path was sucessfully returned.
57 @retval other A error from gBS->HandleProtocol.
63 GetDevicePathForDriverHandleInstall1 (
64 IN EFI_HANDLE TheHandle
,
65 IN OUT EFI_DEVICE_PATH_PROTOCOL
**FilePath
69 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
70 EFI_DEVICE_PATH_PROTOCOL
*ImageDevicePath
;
72 Status
= gBS
->OpenProtocol (
74 &gEfiLoadedImageProtocolGuid
,
78 EFI_OPEN_PROTOCOL_GET_PROTOCOL
80 if (!EFI_ERROR (Status
)) {
81 Status
= gBS
->OpenProtocol (
82 LoadedImage
->DeviceHandle
,
83 &gEfiDevicePathProtocolGuid
,
84 (VOID
**)&ImageDevicePath
,
87 EFI_OPEN_PROTOCOL_GET_PROTOCOL
89 if (!EFI_ERROR (Status
)) {
90 // *DevPath = DuplicateDevicePath (ImageDevicePath);
91 // *FilePath = DuplicateDevicePath (LoadedImage->FilePath);
92 *FilePath
= AppendDevicePath(ImageDevicePath
,LoadedImage
->FilePath
);
94 LoadedImage
->DeviceHandle
,
95 &gEfiDevicePathProtocolGuid
,
101 &gEfiLoadedImageProtocolGuid
,
109 Function to add a option.
111 @param[in] Position The position to add Target at.
112 @param[in] File The file to make the target.
113 @param[in] Desc The description text.
114 @param[in] CurrentOrder The pointer to the current order of items.
115 @param[in] OrderCount The number if items in CurrentOrder.
116 @param[in] Target The info on the option to add.
117 @param[in] UseHandle TRUE to use HandleNumber, FALSE to use File and Desc.
118 @param[in] UsePath TRUE to convert to devicepath.
119 @param[in] HandleNumber The handle number to add.
121 @retval SHELL_SUCCESS The operation was successful.
122 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
128 IN CONST CHAR16
*File
,
129 IN CONST CHAR16
*Desc
,
130 IN CONST UINT16
*CurrentOrder
,
131 IN CONST UINTN OrderCount
,
132 IN CONST BCFG_OPERATION_TARGET Target
,
133 IN CONST BOOLEAN UseHandle
,
134 IN CONST BOOLEAN UsePath
,
135 IN CONST UINTN HandleNumber
139 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
140 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
141 EFI_DEVICE_PATH_PROTOCOL
*FileNode
;
142 // EFI_DEVICE_PATH_PROTOCOL *DevPath;
144 // CONST CHAR16 *StringWalker;
145 UINT8
*TempByteBuffer
;
146 UINT8
*TempByteStart
;
147 EFI_SHELL_FILE_INFO
*Arg
;
148 EFI_SHELL_FILE_INFO
*FileList
;
149 CHAR16 OptionStr
[40];
150 UINTN DescSize
, FilePathSize
;
152 UINTN TargetLocation
;
155 EFI_HANDLE CurHandle
;
156 UINTN DriverBindingHandleCount
;
157 UINTN ParentControllerHandleCount
;
158 UINTN ChildControllerHandleCount
;
159 SHELL_STATUS ShellStatus
;
163 if (File
== NULL
|| Desc
== NULL
) {
164 return (SHELL_INVALID_PARAMETER
);
167 if (HandleNumber
== 0) {
168 return (SHELL_INVALID_PARAMETER
);
172 if (Position
> OrderCount
) {
173 Position
= OrderCount
;
181 ShellStatus
= SHELL_SUCCESS
;
182 TargetLocation
= 0xFFFF;
185 CurHandle
= ConvertHandleIndexToHandle(HandleNumber
);
186 if (CurHandle
== NULL
) {
187 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, L
"Handle Number");
188 ShellStatus
= SHELL_INVALID_PARAMETER
;
190 if (Target
== BcfgTargetBootOrder
) {
192 //Make sure that the handle should point to a real controller
194 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
196 &DriverBindingHandleCount
,
199 Status
= PARSE_HANDLE_DATABASE_PARENTS (
201 &ParentControllerHandleCount
,
204 Status
= ParseHandleDatabaseForChildControllers (
206 &ChildControllerHandleCount
,
209 if (DriverBindingHandleCount
> 0
210 || ParentControllerHandleCount
> 0
211 || ChildControllerHandleCount
> 0) {
213 Status
= gBS
->HandleProtocol (
215 &gEfiDevicePathProtocolGuid
,
218 if (EFI_ERROR (Status
)) {
219 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_HANDLE
), gShellInstall1HiiHandle
, HandleNumber
);
220 ShellStatus
= SHELL_INVALID_PARAMETER
;
224 //Make sure that the handle should point to driver, not a controller.
226 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
228 &DriverBindingHandleCount
,
231 Status
= PARSE_HANDLE_DATABASE_PARENTS (
233 &ParentControllerHandleCount
,
236 Status
= ParseHandleDatabaseForChildControllers (
238 &ChildControllerHandleCount
,
241 Status
= gBS
->HandleProtocol (
243 &gEfiDevicePathProtocolGuid
,
246 if (DriverBindingHandleCount
> 0
247 || ParentControllerHandleCount
> 0
248 || ChildControllerHandleCount
> 0
249 || !EFI_ERROR(Status
) ) {
250 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, L
"Handle Number");
251 ShellStatus
= SHELL_INVALID_PARAMETER
;
254 // Get the DevicePath from the loaded image information.
256 Status
= GetDevicePathForDriverHandleInstall1(CurHandle
, &FilePath
);
264 ShellOpenFileMetaArg ((CHAR16
*)File
, EFI_FILE_MODE_READ
, &FileList
);
266 if (FileList
== NULL
) {
268 // If filename matched nothing fail
270 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellInstall1HiiHandle
, File
);
271 ShellStatus
= SHELL_INVALID_PARAMETER
;
272 } else if (FileList
->Link
.ForwardLink
!= FileList
->Link
.BackLink
) {
274 // If filename expanded to multiple names, fail
276 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE
), gShellInstall1HiiHandle
, File
);
277 ShellStatus
= SHELL_INVALID_PARAMETER
;
279 Arg
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
);
280 if (EFI_ERROR(Arg
->Status
)) {
281 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_OPEN
), gShellInstall1HiiHandle
, File
, Arg
->Status
);
282 ShellStatus
= SHELL_INVALID_PARAMETER
;
285 // Build FilePath to the filename
289 // get the device path
291 DevicePath
= gEfiShellProtocol
->GetDevicePathFromFilePath(Arg
->FullName
);
292 if (DevicePath
== NULL
) {
293 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_DP
), gShellInstall1HiiHandle
, Arg
->FullName
);
294 ShellStatus
= SHELL_UNSUPPORTED
;
298 DevPath = DevicePath;
299 while (!IsDevicePathEnd(DevPath)) {
300 if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&
301 (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {
304 // If we find it use it instead
306 DevicePath = DevPath;
309 DevPath = NextDevicePathNode(DevPath);
314 for(StringWalker=Arg->FullName; *StringWalker != CHAR_NULL && *StringWalker != ':'; StringWalker++);
315 FileNode = FileDevicePath(NULL, StringWalker+1);
316 FilePath = AppendDevicePath(DevicePath, FileNode);
320 FilePath
= DuplicateDevicePath(DevicePath
);
324 FreePool(DevicePath
);
331 if (ShellStatus
== SHELL_SUCCESS
) {
333 // Find a free target ,a brute force implementation
336 for (TargetLocation
=0; TargetLocation
< 0xFFFF; TargetLocation
++) {
338 for (Index
=0; Index
< OrderCount
; Index
++) {
339 if (CurrentOrder
[Index
] == TargetLocation
) {
350 if (TargetLocation
== 0xFFFF) {
351 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET_NF
), gShellInstall1HiiHandle
);
353 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET
), gShellInstall1HiiHandle
, TargetLocation
);
357 if (ShellStatus
== SHELL_SUCCESS
) {
361 DescSize
= StrSize(Desc
);
362 FilePathSize
= GetDevicePathSize (FilePath
);
364 TempByteBuffer
= AllocateZeroPool(sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
);
365 if (TempByteBuffer
!= NULL
) {
366 TempByteStart
= TempByteBuffer
;
367 *((UINT32
*) TempByteBuffer
) = LOAD_OPTION_ACTIVE
; // Attributes
368 TempByteBuffer
+= sizeof (UINT32
);
370 *((UINT16
*) TempByteBuffer
) = (UINT16
)FilePathSize
; // FilePathListLength
371 TempByteBuffer
+= sizeof (UINT16
);
373 CopyMem (TempByteBuffer
, Desc
, DescSize
);
374 TempByteBuffer
+= DescSize
;
375 CopyMem (TempByteBuffer
, FilePath
, FilePathSize
);
377 UnicodeSPrint (OptionStr
, sizeof(OptionStr
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", TargetLocation
);
378 Status
= gRT
->SetVariable (
380 &gEfiGlobalVariableGuid
,
381 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
382 sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
,
386 FreePool(TempByteStart
);
388 Status
= EFI_OUT_OF_RESOURCES
;
391 if (EFI_ERROR(Status
)) {
392 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellInstall1HiiHandle
, OptionStr
, Status
);
394 NewOrder
= AllocateZeroPool((OrderCount
+1)*sizeof(NewOrder
[0]));
395 ASSERT(NewOrder
!= NULL
);
396 CopyMem(NewOrder
, CurrentOrder
, (OrderCount
)*sizeof(NewOrder
[0]));
399 // Insert target into order list
401 for (Index
=OrderCount
; Index
> Position
; Index
--) {
402 NewOrder
[Index
] = NewOrder
[Index
-1];
405 NewOrder
[Position
] = (UINT16
) TargetLocation
;
406 Status
= gRT
->SetVariable (
407 Target
== BcfgTargetBootOrder
?L
"BootOrder":L
"DriverOrder",
408 &gEfiGlobalVariableGuid
,
409 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
410 (OrderCount
+1) * sizeof(UINT16
),
416 if (EFI_ERROR(Status
)) {
417 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellInstall1HiiHandle
, Target
== BcfgTargetBootOrder
?L
"BootOrder":L
"DriverOrder", Status
);
418 ShellStatus
= SHELL_INVALID_PARAMETER
;
420 Print (L
"bcfg: Add %s as %x\n", OptionStr
, Position
);
426 //If always Free FilePath, will free devicepath in system when use "addh"
428 if (FilePath
!=NULL
&& !UseHandle
) {
436 if (Handles
!= NULL
) {
440 if (FileList
!= NULL
) {
441 ShellCloseFileMetaArg (&FileList
);
444 return (ShellStatus
);
448 Funciton to remove an item.
450 @param[in] Target The target item to move.
451 @param[in] CurrentOrder The pointer to the current order of items.
452 @param[in] OrderCount The number if items in CurrentOrder.
453 @param[in] Location The current location of the Target.
455 @retval SHELL_SUCCESS The operation was successful.
456 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
461 IN CONST BCFG_OPERATION_TARGET Target
,
462 IN CONST UINT16
*CurrentOrder
,
463 IN CONST UINTN OrderCount
,
464 IN CONST UINT16 Location
467 CHAR16 VariableName
[12];
472 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", CurrentOrder
[Location
]);
473 Status
= gRT
->SetVariable(
475 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
476 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
479 if (EFI_ERROR(Status
)) {
480 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellInstall1HiiHandle
, VariableName
, Status
);
481 return (SHELL_INVALID_PARAMETER
);
483 NewOrder
= AllocateZeroPool(OrderCount
*sizeof(CurrentOrder
[0]));
484 if (NewOrder
!= NULL
) {
485 NewCount
= OrderCount
;
486 CopyMem(NewOrder
, CurrentOrder
, OrderCount
*sizeof(CurrentOrder
[0]));
487 CopyMem(NewOrder
+Location
, NewOrder
+Location
+1, (OrderCount
- Location
- 1)*sizeof(CurrentOrder
[0]));
490 Status
= gRT
->SetVariable(
491 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
492 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
493 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
494 NewCount
*sizeof(NewOrder
[0]),
498 Status
= EFI_OUT_OF_RESOURCES
;
500 if (EFI_ERROR(Status
)) {
501 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellInstall1HiiHandle
, Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder", Status
);
502 return (SHELL_INVALID_PARAMETER
);
504 return (SHELL_SUCCESS
);
508 Funciton to move a item to another location.
510 @param[in] Target The target item to move.
511 @param[in] CurrentOrder The pointer to the current order of items.
512 @param[in] OrderCount The number if items in CurrentOrder.
513 @param[in] OldLocation The current location of the Target.
514 @param[in] NewLocation The desired location of the Target.
516 @retval SHELL_SUCCESS The operation was successful.
517 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
522 IN CONST BCFG_OPERATION_TARGET Target
,
523 IN CONST UINT16
*CurrentOrder
,
524 IN CONST UINTN OrderCount
,
525 IN CONST UINT16 OldLocation
,
526 IN CONST UINT16 NewLocation
533 NewOrder
= AllocateZeroPool(OrderCount
*sizeof(CurrentOrder
[0]));
534 ASSERT(NewOrder
!= NULL
);
536 Temp
= CurrentOrder
[OldLocation
];
537 CopyMem(NewOrder
, CurrentOrder
, OrderCount
*sizeof(CurrentOrder
[0]));
538 CopyMem(NewOrder
+OldLocation
, NewOrder
+OldLocation
+1, (OrderCount
- OldLocation
- 1)*sizeof(CurrentOrder
[0]));
539 CopyMem(NewOrder
+NewLocation
+1, NewOrder
+NewLocation
, (OrderCount
- NewLocation
- 1)*sizeof(CurrentOrder
[0]));
540 NewOrder
[NewLocation
] = Temp
;
543 Status
= gRT
->SetVariable(
544 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
545 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
546 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
547 OrderCount
*sizeof(CurrentOrder
[0]),
552 if (EFI_ERROR(Status
)) {
553 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellInstall1HiiHandle
, Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder", Status
);
554 return (SHELL_INVALID_PARAMETER
);
556 return (SHELL_SUCCESS
);
560 Function to add optional data to an option.
562 @param[in] OptData The optional data to add.
563 @param[in] Target The target of the operation.
565 @retval SHELL_SUCCESS The operation was succesful.
570 IN CONST CHAR16
*OptData
,
571 IN CONST BCFG_OPERATION_TARGET Target
574 ASSERT(OptData
!= NULL
);
575 return SHELL_SUCCESS
;
579 Function to dump the Bcfg information.
581 @param[in] Op The operation.
582 @param[in] OrderCount How many to dump.
583 @param[in] CurrentOrder The pointer to the current order of items.
584 @param[in] VerboseOutput TRUE for extra output. FALSE otherwise.
586 @retval SHELL_SUCCESS The dump was successful.
587 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
591 BcfgDisplayDumpInstall1(
593 IN CONST UINTN OrderCount
,
594 IN CONST UINT16
*CurrentOrder
,
595 IN CONST BOOLEAN VerboseOutput
601 CHAR16 VariableName
[12];
604 CHAR16
*DevPathString
;
607 if (OrderCount
== 0) {
608 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_BCFG_NONE
), gShellInstall1HiiHandle
);
609 return (SHELL_SUCCESS
);
612 for (LoopVar
= 0 ; LoopVar
< OrderCount
; LoopVar
++) {
615 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Op
, CurrentOrder
[LoopVar
]);
617 Status
= gRT
->GetVariable(
619 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
623 if (Status
== EFI_BUFFER_TOO_SMALL
) {
624 Buffer
= AllocateZeroPool(BufferSize
);
625 Status
= gRT
->GetVariable(
627 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
633 if (EFI_ERROR(Status
) || Buffer
== NULL
) {
634 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_READ_FAIL
), gShellInstall1HiiHandle
, VariableName
, Status
);
635 return (SHELL_INVALID_PARAMETER
);
638 if ((*(UINT16
*)(Buffer
+4)) != 0) {
639 DevPath
= AllocateZeroPool(*(UINT16
*)(Buffer
+4));
640 CopyMem(DevPath
, Buffer
+6+StrSize((CHAR16
*)(Buffer
+6)), *(UINT16
*)(Buffer
+4));
641 DevPathString
= gDevPathToText
->ConvertDevicePathToText(DevPath
, TRUE
, FALSE
);
644 DevPathString
= NULL
;
650 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS
),
651 gShellInstall1HiiHandle
,
656 (StrSize((CHAR16
*)(Buffer
+6)) + *(UINT16
*)(Buffer
+4) + 6) <= BufferSize
?L
'N':L
'Y');
658 for (LoopVar2
= (StrSize((CHAR16
*)(Buffer
+6)) + *(UINT16
*)(Buffer
+4) + 6);LoopVar2
<BufferSize
;LoopVar2
++){
673 if (Buffer
!= NULL
) {
676 if (DevPath
!= NULL
) {
679 if (DevPathString
!= NULL
) {
680 FreePool(DevPathString
);
683 return (SHELL_SUCCESS
);
687 Function to initialize the BCFG operation structure.
689 @param[in] Struct The stuct to initialize.
693 InitBcfgStructInstall1(
694 IN BGFG_OPERATION
*Struct
697 ASSERT(Struct
!= NULL
);
698 Struct
->Target
= BcfgTargetMax
;
699 Struct
->Type
= BcfgTypeMax
;
702 Struct
->HandleIndex
= 0;
703 Struct
->FileName
= NULL
;
704 Struct
->Description
= NULL
;
705 Struct
->Order
= NULL
;
706 Struct
->OptData
= NULL
;
710 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
712 {L
"-opt", TypeMaxValue
},
717 Function for 'bcfg' command.
719 @param[in] ImageHandle Handle to the Image (NULL if Internal).
720 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
724 ShellCommandRunBcfgInstall (
725 IN EFI_HANDLE ImageHandle
,
726 IN EFI_SYSTEM_TABLE
*SystemTable
731 CHAR16
*ProblemParam
;
732 SHELL_STATUS ShellStatus
;
734 CONST CHAR16
*CurrentParam
;
735 BGFG_OPERATION CurrentOperation
;
742 ShellStatus
= SHELL_SUCCESS
;
744 InitBcfgStructInstall1(&CurrentOperation
);
747 // initialize the shell lib (we must be in non-auto-init...)
749 Status
= ShellInitialize();
750 ASSERT_EFI_ERROR(Status
);
752 Status
= CommandInit();
753 ASSERT_EFI_ERROR(Status
);
756 // parse the command line
758 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
759 if (EFI_ERROR(Status
)) {
760 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
761 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, ProblemParam
);
762 FreePool(ProblemParam
);
763 ShellStatus
= SHELL_INVALID_PARAMETER
;
769 // Read in if we are doing -OPT
771 if (ShellCommandLineGetFlag(Package
, L
"-opt")) {
772 CurrentOperation
.OptData
= ShellCommandLineGetValue(Package
, L
"-opt");
773 if (CurrentOperation
.OptData
== NULL
) {
774 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_VAL
), gShellInstall1HiiHandle
, L
"-opt");
775 ShellStatus
= SHELL_INVALID_PARAMETER
;
777 CurrentOperation
.Type
= BcfgTypeOpt
;
781 // small block to read the target of the operation
783 if ((ShellCommandLineGetCount(Package
) < 3 && CurrentOperation
.Type
!= BcfgTypeOpt
) ||
784 (ShellCommandLineGetCount(Package
) < 2 && CurrentOperation
.Type
== BcfgTypeOpt
)
786 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellInstall1HiiHandle
);
787 ShellStatus
= SHELL_INVALID_PARAMETER
;
788 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"driver") == 0) {
789 CurrentOperation
.Target
= BcfgTargetDriverOrder
;
790 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"boot") == 0) {
791 CurrentOperation
.Target
= BcfgTargetBootOrder
;
793 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT
), gShellInstall1HiiHandle
);
794 ShellStatus
= SHELL_INVALID_PARAMETER
;
799 // Read in the boot or driver order environment variable (not needed for opt)
801 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
&& CurrentOperation
.Type
!= BcfgTypeOpt
) {
803 Status
= gRT
->GetVariable(
804 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
805 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
808 CurrentOperation
.Order
);
809 if (Status
== EFI_BUFFER_TOO_SMALL
) {
810 CurrentOperation
.Order
= AllocateZeroPool(Length
+(4*sizeof(CurrentOperation
.Order
[0])));
811 Status
= gRT
->GetVariable(
812 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
813 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
816 CurrentOperation
.Order
);
821 // large block to read the type of operation and verify parameter types for the info.
823 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
824 for (ParamNumber
= 2 ; ParamNumber
< ShellCommandLineGetCount(Package
) && ShellStatus
== SHELL_SUCCESS
; ParamNumber
++) {
825 CurrentParam
= ShellCommandLineGetRawValue(Package
, ParamNumber
);
826 if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"dump") == 0) {
827 CurrentOperation
.Type
= BcfgTypeDump
;
828 } else if (ShellCommandLineGetFlag(Package
, L
"-v")) {
829 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, L
"-v (without dump)");
830 ShellStatus
= SHELL_INVALID_PARAMETER
;
831 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"add") == 0) {
832 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
833 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellInstall1HiiHandle
);
834 ShellStatus
= SHELL_INVALID_PARAMETER
;
836 CurrentOperation
.Type
= BcfgTypeAdd
;
837 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
838 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
839 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, CurrentParam
);
840 ShellStatus
= SHELL_INVALID_PARAMETER
;
842 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
843 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
844 ASSERT(CurrentOperation
.FileName
== NULL
);
845 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
846 ASSERT(CurrentOperation
.Description
== NULL
);
847 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
849 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addp") == 0) {
850 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
851 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellInstall1HiiHandle
);
852 ShellStatus
= SHELL_INVALID_PARAMETER
;
854 CurrentOperation
.Type
= BcfgTypeAddp
;
855 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
856 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
857 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, CurrentParam
);
858 ShellStatus
= SHELL_INVALID_PARAMETER
;
860 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
861 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
862 ASSERT(CurrentOperation
.FileName
== NULL
);
863 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
864 ASSERT(CurrentOperation
.Description
== NULL
);
865 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
867 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addh") == 0) {
868 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
869 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellInstall1HiiHandle
);
870 ShellStatus
= SHELL_INVALID_PARAMETER
;
872 CurrentOperation
.Type
= BcfgTypeAddh
;
873 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
874 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
875 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, CurrentParam
);
876 ShellStatus
= SHELL_INVALID_PARAMETER
;
878 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
879 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
880 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
881 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
882 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, CurrentParam
);
883 ShellStatus
= SHELL_INVALID_PARAMETER
;
885 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
886 CurrentOperation
.HandleIndex
= (UINT16
)Intermediate
;
887 ASSERT(CurrentOperation
.Description
== NULL
);
888 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
891 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"rm") == 0) {
892 if ((ParamNumber
+ 1) >= ShellCommandLineGetCount(Package
)) {
893 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellInstall1HiiHandle
);
894 ShellStatus
= SHELL_INVALID_PARAMETER
;
896 CurrentOperation
.Type
= BcfgTypeRm
;
897 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
898 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
899 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, CurrentParam
);
900 ShellStatus
= SHELL_INVALID_PARAMETER
;
902 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
903 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
904 if (CurrentOperation
.Number1
> (Length
/ sizeof(CurrentOperation
.Order
[0]))){
905 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellInstall1HiiHandle
, Length
/ sizeof(CurrentOperation
.Order
[0]));
906 ShellStatus
= SHELL_INVALID_PARAMETER
;
909 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"mv") == 0) {
910 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount(Package
)) {
911 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellInstall1HiiHandle
);
912 ShellStatus
= SHELL_INVALID_PARAMETER
;
914 CurrentOperation
.Type
= BcfgTypeMv
;
915 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
916 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
917 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, CurrentParam
);
918 ShellStatus
= SHELL_INVALID_PARAMETER
;
920 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
921 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
922 if (CurrentOperation
.Number1
> (Length
/ sizeof(CurrentOperation
.Order
[0]))){
923 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellInstall1HiiHandle
, Length
/ sizeof(CurrentOperation
.Order
[0]));
924 ShellStatus
= SHELL_INVALID_PARAMETER
;
926 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
927 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
928 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, CurrentParam
);
929 ShellStatus
= SHELL_INVALID_PARAMETER
;
931 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
932 CurrentOperation
.Number2
= (UINT16
)Intermediate
;
934 if (CurrentOperation
.Number2
== CurrentOperation
.Number1
935 ||CurrentOperation
.Number1
> (Length
/ sizeof(CurrentOperation
.Order
[0]))
936 ||CurrentOperation
.Number2
> (Length
/ sizeof(CurrentOperation
.Order
[0]))
938 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellInstall1HiiHandle
, Length
/ sizeof(CurrentOperation
.Order
[0]));
939 ShellStatus
= SHELL_INVALID_PARAMETER
;
943 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, CurrentParam
);
944 ShellStatus
= SHELL_INVALID_PARAMETER
;
948 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
&& CurrentOperation
.Type
< BcfgTypeMax
) {
950 // we have all the info. Do the work
952 switch (CurrentOperation
.Type
) {
954 ShellStatus
= BcfgDisplayDumpInstall1(
955 CurrentOperation
.Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver",
956 Length
/ sizeof(CurrentOperation
.Order
[0]),
957 CurrentOperation
.Order
,
958 ShellCommandLineGetFlag(Package
, L
"-v"));
961 ShellStatus
= BcfgMoveInstall1(
962 CurrentOperation
.Target
,
963 CurrentOperation
.Order
,
964 Length
/ sizeof(CurrentOperation
.Order
[0]),
965 CurrentOperation
.Number1
,
966 CurrentOperation
.Number2
);
969 ShellStatus
= BcfgRemoveInstall1(
970 CurrentOperation
.Target
,
971 CurrentOperation
.Order
,
972 Length
/ sizeof(CurrentOperation
.Order
[0]),
973 CurrentOperation
.Number1
);
978 ShellStatus
= BcfgAddInstall1(
979 CurrentOperation
.Number1
,
980 CurrentOperation
.FileName
,
981 CurrentOperation
.Description
==NULL
?L
"":CurrentOperation
.Description
,
982 CurrentOperation
.Order
,
983 Length
/ sizeof(CurrentOperation
.Order
[0]),
984 CurrentOperation
.Target
,
985 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddh
),
986 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddp
),
987 CurrentOperation
.HandleIndex
);
990 ShellStatus
= BcfgAddOptInstall1(
991 CurrentOperation
.OptData
,
992 CurrentOperation
.Target
);
1000 if (Package
!= NULL
) {
1001 ShellCommandLineFreeVarList (Package
);
1003 if (CurrentOperation
.FileName
!= NULL
) {
1004 FreePool(CurrentOperation
.FileName
);
1006 if (CurrentOperation
.Description
!= NULL
) {
1007 FreePool(CurrentOperation
.Description
);
1009 if (CurrentOperation
.Order
!= NULL
) {
1010 FreePool(CurrentOperation
.Order
);
1013 return (ShellStatus
);