2 Main file for bcfg shell Install1 function.
4 Copyright (c) 2010 - 2013, 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 Get the actual number of entries in EFI_KEY_OPTION.Keys, from 0-3.
53 @param KeyOption Pointer to the EFI_KEY_OPTION structure.
55 @return Actual number of entries in EFI_KEY_OPTION.Keys.
57 #define KEY_OPTION_INPUT_KEY_COUNT(KeyOption) \
58 (((KeyOption)->KeyData & EFI_KEY_OPTION_INPUT_KEY_COUNT_MASK) >> LowBitSet32 (EFI_KEY_OPTION_INPUT_KEY_COUNT_MASK))
61 Update the optional data for a boot or driver option.
63 If optional data exists it will be changed.
65 @param[in] Index The boot or driver option index update.
66 @param[in] DataSize The size in bytes of Data.
67 @param[in] Data The buffer for the optioanl data.
68 @param[in] Target The target of the operation.
70 @retval EFI_SUCCESS The data was sucessfully updated.
71 @retval other A error occured.
79 IN CONST BCFG_OPERATION_TARGET Target
83 CHAR16 VariableName
[12];
88 UINTN OriginalOptionDataSize
;
90 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", Index
);
97 Status
= gRT
->GetVariable(
99 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
103 if (Status
== EFI_BUFFER_TOO_SMALL
) {
104 OriginalData
= AllocateZeroPool(OriginalSize
);
105 if (OriginalData
== NULL
) {
106 return (EFI_OUT_OF_RESOURCES
);
108 Status
= gRT
->GetVariable(
110 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
116 if (!EFI_ERROR(Status
)) {
118 // Allocate new struct and discard old optional data.
120 ASSERT (OriginalData
!= NULL
);
121 OriginalOptionDataSize
= sizeof(UINT32
) + sizeof(UINT16
) + StrSize(((CHAR16
*)(OriginalData
+ sizeof(UINT32
) + sizeof(UINT16
))));
122 OriginalOptionDataSize
+= (*(UINT16
*)(OriginalData
+ sizeof(UINT32
)));
123 OriginalOptionDataSize
-= OriginalSize
;
124 NewSize
= OriginalSize
- OriginalOptionDataSize
+ DataSize
;
125 NewData
= AllocateCopyPool(NewSize
, OriginalData
);
126 if (NewData
== NULL
) {
127 Status
= EFI_OUT_OF_RESOURCES
;
129 CopyMem(NewData
+ OriginalSize
- OriginalOptionDataSize
, Data
, DataSize
);
133 if (!EFI_ERROR(Status
)) {
135 // put the data back under the variable
137 Status
= gRT
->SetVariable(
139 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
140 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
145 SHELL_FREE_NON_NULL(OriginalData
);
146 SHELL_FREE_NON_NULL(NewData
);
151 This function will get a CRC for a boot option.
153 @param[in, out] Crc The CRC value to return.
154 @param[in] BootIndex The boot option index to CRC.
156 @retval EFI_SUCCESS The CRC was sucessfully returned.
157 @retval other A error occured.
166 CHAR16 VariableName
[12];
175 // Get the data Buffer
177 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%Boot%04x", BootIndex
);
178 Status
= gRT
->GetVariable(
180 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
184 if (Status
== EFI_BUFFER_TOO_SMALL
) {
185 Buffer
= AllocateZeroPool(BufferSize
);
186 Status
= gRT
->GetVariable(
188 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
195 // Get the CRC computed
197 if (!EFI_ERROR(Status
)) {
198 Status
= gBS
->CalculateCrc32 (Buffer
, BufferSize
, Crc
);
201 SHELL_FREE_NON_NULL(Buffer
);
206 This function will populate the device path protocol parameter based on TheHandle.
208 @param[in] TheHandle Driver handle.
209 @param[in, out] FilePath On a sucessful return the device path to the handle.
211 @retval EFI_SUCCESS The device path was sucessfully returned.
212 @retval other A error from gBS->HandleProtocol.
218 GetDevicePathForDriverHandleInstall1 (
219 IN EFI_HANDLE TheHandle
,
220 IN OUT EFI_DEVICE_PATH_PROTOCOL
**FilePath
224 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
225 EFI_DEVICE_PATH_PROTOCOL
*ImageDevicePath
;
227 Status
= gBS
->OpenProtocol (
229 &gEfiLoadedImageProtocolGuid
,
230 (VOID
**)&LoadedImage
,
233 EFI_OPEN_PROTOCOL_GET_PROTOCOL
235 if (!EFI_ERROR (Status
)) {
236 Status
= gBS
->OpenProtocol (
237 LoadedImage
->DeviceHandle
,
238 &gEfiDevicePathProtocolGuid
,
239 (VOID
**)&ImageDevicePath
,
242 EFI_OPEN_PROTOCOL_GET_PROTOCOL
244 if (!EFI_ERROR (Status
)) {
245 // *DevPath = DuplicateDevicePath (ImageDevicePath);
246 // *FilePath = DuplicateDevicePath (LoadedImage->FilePath);
247 *FilePath
= AppendDevicePath(ImageDevicePath
,LoadedImage
->FilePath
);
249 LoadedImage
->DeviceHandle
,
250 &gEfiDevicePathProtocolGuid
,
256 &gEfiLoadedImageProtocolGuid
,
264 Function to add a option.
266 @param[in] Position The position to add Target at.
267 @param[in] File The file to make the target.
268 @param[in] Desc The description text.
269 @param[in] CurrentOrder The pointer to the current order of items.
270 @param[in] OrderCount The number if items in CurrentOrder.
271 @param[in] Target The info on the option to add.
272 @param[in] UseHandle TRUE to use HandleNumber, FALSE to use File and Desc.
273 @param[in] UsePath TRUE to convert to devicepath.
274 @param[in] HandleNumber The handle number to add.
276 @retval SHELL_SUCCESS The operation was successful.
277 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
283 IN CONST CHAR16
*File
,
284 IN CONST CHAR16
*Desc
,
285 IN CONST UINT16
*CurrentOrder
,
286 IN CONST UINTN OrderCount
,
287 IN CONST BCFG_OPERATION_TARGET Target
,
288 IN CONST BOOLEAN UseHandle
,
289 IN CONST BOOLEAN UsePath
,
290 IN CONST UINTN HandleNumber
294 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
295 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
297 UINT8
*TempByteBuffer
;
298 UINT8
*TempByteStart
;
299 EFI_SHELL_FILE_INFO
*Arg
;
300 EFI_SHELL_FILE_INFO
*FileList
;
301 CHAR16 OptionStr
[40];
302 UINTN DescSize
, FilePathSize
;
304 UINTN TargetLocation
;
307 EFI_HANDLE CurHandle
;
308 UINTN DriverBindingHandleCount
;
309 UINTN ParentControllerHandleCount
;
310 UINTN ChildControllerHandleCount
;
311 SHELL_STATUS ShellStatus
;
315 if (File
== NULL
|| Desc
== NULL
) {
316 return (SHELL_INVALID_PARAMETER
);
319 if (HandleNumber
== 0) {
320 return (SHELL_INVALID_PARAMETER
);
324 if (Position
> OrderCount
) {
325 Position
= OrderCount
;
332 ShellStatus
= SHELL_SUCCESS
;
333 TargetLocation
= 0xFFFF;
336 CurHandle
= ConvertHandleIndexToHandle(HandleNumber
);
337 if (CurHandle
== NULL
) {
338 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, L
"Handle Number");
339 ShellStatus
= SHELL_INVALID_PARAMETER
;
341 if (Target
== BcfgTargetBootOrder
) {
343 //Make sure that the handle should point to a real controller
345 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
347 &DriverBindingHandleCount
,
350 Status
= PARSE_HANDLE_DATABASE_PARENTS (
352 &ParentControllerHandleCount
,
355 Status
= ParseHandleDatabaseForChildControllers (
357 &ChildControllerHandleCount
,
360 if (DriverBindingHandleCount
> 0
361 || ParentControllerHandleCount
> 0
362 || ChildControllerHandleCount
> 0) {
364 Status
= gBS
->HandleProtocol (
366 &gEfiDevicePathProtocolGuid
,
369 if (EFI_ERROR (Status
)) {
370 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_HANDLE
), gShellInstall1HiiHandle
, HandleNumber
);
371 ShellStatus
= SHELL_INVALID_PARAMETER
;
375 //Make sure that the handle should point to driver, not a controller.
377 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
379 &DriverBindingHandleCount
,
382 Status
= PARSE_HANDLE_DATABASE_PARENTS (
384 &ParentControllerHandleCount
,
387 Status
= ParseHandleDatabaseForChildControllers (
389 &ChildControllerHandleCount
,
392 Status
= gBS
->HandleProtocol (
394 &gEfiDevicePathProtocolGuid
,
397 if (DriverBindingHandleCount
> 0
398 || ParentControllerHandleCount
> 0
399 || ChildControllerHandleCount
> 0
400 || !EFI_ERROR(Status
) ) {
401 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, L
"Handle Number");
402 ShellStatus
= SHELL_INVALID_PARAMETER
;
405 // Get the DevicePath from the loaded image information.
407 Status
= GetDevicePathForDriverHandleInstall1(CurHandle
, &FilePath
);
415 ShellOpenFileMetaArg ((CHAR16
*)File
, EFI_FILE_MODE_READ
, &FileList
);
417 if (FileList
== NULL
) {
419 // If filename matched nothing fail
421 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellInstall1HiiHandle
, File
);
422 ShellStatus
= SHELL_INVALID_PARAMETER
;
423 } else if (FileList
->Link
.ForwardLink
!= FileList
->Link
.BackLink
) {
425 // If filename expanded to multiple names, fail
427 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE
), gShellInstall1HiiHandle
, File
);
428 ShellStatus
= SHELL_INVALID_PARAMETER
;
430 Arg
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
);
431 if (EFI_ERROR(Arg
->Status
)) {
432 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_OPEN
), gShellInstall1HiiHandle
, File
, Arg
->Status
);
433 ShellStatus
= SHELL_INVALID_PARAMETER
;
436 // Build FilePath to the filename
440 // get the device path
442 DevicePath
= gEfiShellProtocol
->GetDevicePathFromFilePath(Arg
->FullName
);
443 if (DevicePath
== NULL
) {
444 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_DP
), gShellInstall1HiiHandle
, Arg
->FullName
);
445 ShellStatus
= SHELL_UNSUPPORTED
;
449 DevPath = DevicePath;
450 while (!IsDevicePathEnd(DevPath)) {
451 if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&
452 (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {
455 // If we find it use it instead
457 DevicePath = DevPath;
460 DevPath = NextDevicePathNode(DevPath);
465 for(StringWalker=Arg->FullName; *StringWalker != CHAR_NULL && *StringWalker != ':'; StringWalker++);
466 FileNode = FileDevicePath(NULL, StringWalker+1);
467 FilePath = AppendDevicePath(DevicePath, FileNode);
471 FilePath
= DuplicateDevicePath(DevicePath
);
475 FreePool(DevicePath
);
482 if (ShellStatus
== SHELL_SUCCESS
) {
484 // Find a free target ,a brute force implementation
487 for (TargetLocation
=0; TargetLocation
< 0xFFFF; TargetLocation
++) {
489 for (Index
=0; Index
< OrderCount
; Index
++) {
490 if (CurrentOrder
[Index
] == TargetLocation
) {
501 if (TargetLocation
== 0xFFFF) {
502 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET_NF
), gShellInstall1HiiHandle
);
504 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET
), gShellInstall1HiiHandle
, TargetLocation
);
508 if (ShellStatus
== SHELL_SUCCESS
) {
512 DescSize
= StrSize(Desc
);
513 FilePathSize
= GetDevicePathSize (FilePath
);
515 TempByteBuffer
= AllocateZeroPool(sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
);
516 if (TempByteBuffer
!= NULL
) {
517 TempByteStart
= TempByteBuffer
;
518 *((UINT32
*) TempByteBuffer
) = LOAD_OPTION_ACTIVE
; // Attributes
519 TempByteBuffer
+= sizeof (UINT32
);
521 *((UINT16
*) TempByteBuffer
) = (UINT16
)FilePathSize
; // FilePathListLength
522 TempByteBuffer
+= sizeof (UINT16
);
524 CopyMem (TempByteBuffer
, Desc
, DescSize
);
525 TempByteBuffer
+= DescSize
;
526 ASSERT (FilePath
!= NULL
);
527 CopyMem (TempByteBuffer
, FilePath
, FilePathSize
);
529 UnicodeSPrint (OptionStr
, sizeof(OptionStr
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", TargetLocation
);
530 Status
= gRT
->SetVariable (
532 &gEfiGlobalVariableGuid
,
533 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
534 sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
,
538 FreePool(TempByteStart
);
540 Status
= EFI_OUT_OF_RESOURCES
;
543 if (EFI_ERROR(Status
)) {
544 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellInstall1HiiHandle
, OptionStr
, Status
);
546 NewOrder
= AllocateZeroPool((OrderCount
+1)*sizeof(NewOrder
[0]));
547 ASSERT(NewOrder
!= NULL
);
548 CopyMem(NewOrder
, CurrentOrder
, (OrderCount
)*sizeof(NewOrder
[0]));
551 // Insert target into order list
553 for (Index
=OrderCount
; Index
> Position
; Index
--) {
554 NewOrder
[Index
] = NewOrder
[Index
-1];
557 NewOrder
[Position
] = (UINT16
) TargetLocation
;
558 Status
= gRT
->SetVariable (
559 Target
== BcfgTargetBootOrder
?L
"BootOrder":L
"DriverOrder",
560 &gEfiGlobalVariableGuid
,
561 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
562 (OrderCount
+1) * sizeof(UINT16
),
568 if (EFI_ERROR(Status
)) {
569 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellInstall1HiiHandle
, Target
== BcfgTargetBootOrder
?L
"BootOrder":L
"DriverOrder", Status
);
570 ShellStatus
= SHELL_INVALID_PARAMETER
;
572 Print (L
"bcfg: Add %s as %x\n", OptionStr
, Position
);
578 //If always Free FilePath, will free devicepath in system when use "addh"
580 if (FilePath
!=NULL
&& !UseHandle
) {
588 if (Handles
!= NULL
) {
592 if (FileList
!= NULL
) {
593 ShellCloseFileMetaArg (&FileList
);
596 return (ShellStatus
);
600 Funciton to remove an item.
602 @param[in] Target The target item to move.
603 @param[in] CurrentOrder The pointer to the current order of items.
604 @param[in] OrderCount The number if items in CurrentOrder.
605 @param[in] Location The current location of the Target.
607 @retval SHELL_SUCCESS The operation was successful.
608 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
613 IN CONST BCFG_OPERATION_TARGET Target
,
614 IN CONST UINT16
*CurrentOrder
,
615 IN CONST UINTN OrderCount
,
616 IN CONST UINT16 Location
619 CHAR16 VariableName
[12];
624 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", CurrentOrder
[Location
]);
625 Status
= gRT
->SetVariable(
627 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
628 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
631 if (EFI_ERROR(Status
)) {
632 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellInstall1HiiHandle
, VariableName
, Status
);
633 return (SHELL_INVALID_PARAMETER
);
635 NewOrder
= AllocateZeroPool(OrderCount
*sizeof(CurrentOrder
[0]));
636 if (NewOrder
!= NULL
) {
637 NewCount
= OrderCount
;
638 CopyMem(NewOrder
, CurrentOrder
, OrderCount
*sizeof(CurrentOrder
[0]));
639 CopyMem(NewOrder
+Location
, NewOrder
+Location
+1, (OrderCount
- Location
- 1)*sizeof(CurrentOrder
[0]));
642 Status
= gRT
->SetVariable(
643 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
644 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
645 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
646 NewCount
*sizeof(NewOrder
[0]),
650 Status
= EFI_OUT_OF_RESOURCES
;
652 if (EFI_ERROR(Status
)) {
653 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellInstall1HiiHandle
, Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder", Status
);
654 return (SHELL_INVALID_PARAMETER
);
656 return (SHELL_SUCCESS
);
660 Funciton to move a item to another location.
662 @param[in] Target The target item to move.
663 @param[in] CurrentOrder The pointer to the current order of items.
664 @param[in] OrderCount The number if items in CurrentOrder.
665 @param[in] OldLocation The current location of the Target.
666 @param[in] NewLocation The desired location of the Target.
668 @retval SHELL_SUCCESS The operation was successful.
669 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
674 IN CONST BCFG_OPERATION_TARGET Target
,
675 IN CONST UINT16
*CurrentOrder
,
676 IN CONST UINTN OrderCount
,
677 IN CONST UINT16 OldLocation
,
678 IN CONST UINT16 NewLocation
685 NewOrder
= AllocateZeroPool(OrderCount
*sizeof(CurrentOrder
[0]));
686 ASSERT(NewOrder
!= NULL
);
688 Temp
= CurrentOrder
[OldLocation
];
689 CopyMem(NewOrder
, CurrentOrder
, OrderCount
*sizeof(CurrentOrder
[0]));
690 CopyMem(NewOrder
+OldLocation
, NewOrder
+OldLocation
+1, (OrderCount
- OldLocation
- 1)*sizeof(CurrentOrder
[0]));
691 CopyMem(NewOrder
+NewLocation
+1, NewOrder
+NewLocation
, (OrderCount
- NewLocation
- 1)*sizeof(CurrentOrder
[0]));
692 NewOrder
[NewLocation
] = Temp
;
695 Status
= gRT
->SetVariable(
696 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
697 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
698 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
699 OrderCount
*sizeof(CurrentOrder
[0]),
704 if (EFI_ERROR(Status
)) {
705 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellInstall1HiiHandle
, Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder", Status
);
706 return (SHELL_INVALID_PARAMETER
);
708 return (SHELL_SUCCESS
);
712 Function to add optional data to an option.
714 @param[in] OptData The optional data to add.
715 @param[in] CurrentOrder The pointer to the current order of items.
716 @param[in] OrderCount The number if items in CurrentOrder.
717 @param[in] Target The target of the operation.
719 @retval SHELL_SUCCESS The operation was succesful.
724 IN CONST CHAR16
*OptData
,
725 IN CONST UINT16
*CurrentOrder
,
726 IN CONST UINTN OrderCount
,
727 IN CONST BCFG_OPERATION_TARGET Target
730 EFI_KEY_OPTION NewKeyOption
;
731 EFI_KEY_OPTION
*KeyOptionBuffer
;
732 SHELL_STATUS ShellStatus
;
738 CONST CHAR16
*Walker
;
743 CHAR16 VariableName
[12];
745 SHELL_FILE_HANDLE FileHandle
;
747 Status
= EFI_SUCCESS
;
748 ShellStatus
= SHELL_SUCCESS
;
752 KeyOptionBuffer
= NULL
;
754 ZeroMem(&NewKeyOption
, sizeof(EFI_KEY_OPTION
));
756 while(Walker
[0] == L
' ') {
761 // Get the index of the variable we are changing.
763 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
764 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
|| ((UINT16
)Intermediate
) > ((UINT16
)OrderCount
)) {
765 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, L
"Option Index");
766 ShellStatus
= SHELL_INVALID_PARAMETER
;
767 return (ShellStatus
);
769 OptionIndex
= (UINT16
)Intermediate
;
771 Temp
= StrStr(Walker
, L
" ");
775 while(Walker
[0] == L
' ') {
780 // determine whether we have file with data, quote delimited information, or a hot-key
782 if (Walker
[0] == L
'\"') {
784 // quoted filename or quoted information.
786 Temp
= StrStr(Walker
+1, L
"\"");
787 if (Temp
== NULL
|| StrLen(Temp
) != 1) {
788 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, Walker
);
789 ShellStatus
= SHELL_INVALID_PARAMETER
;
791 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
+1, 0);
792 if (FileName
== NULL
) {
793 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellInstall1HiiHandle
);
794 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
795 return (ShellStatus
);
797 Temp2
= StrStr(FileName
, L
"\"");
798 ASSERT(Temp2
!= NULL
);
799 Temp2
[0] = CHAR_NULL
;
801 if (StrLen(Temp2
)>0) {
802 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, Walker
);
803 ShellStatus
= SHELL_INVALID_PARAMETER
;
805 if (EFI_ERROR(ShellFileExists(Walker
))) {
807 // Not a file. must be misc information.
812 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
, 0);
817 // filename or hot key information.
819 if (StrStr(Walker
, L
" ") == NULL
) {
823 if (EFI_ERROR(ShellFileExists(Walker
))) {
824 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FIND_FAIL
), gShellInstall1HiiHandle
, Walker
);
825 ShellStatus
= SHELL_INVALID_PARAMETER
;
827 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
, 0);
830 if (Target
!= BcfgTargetBootOrder
) {
831 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_BOOT_ONLY
), gShellInstall1HiiHandle
);
832 ShellStatus
= SHELL_INVALID_PARAMETER
;
835 if (ShellStatus
== SHELL_SUCCESS
) {
837 // Get hot key information
839 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
840 if (EFI_ERROR(Status
) || (((UINT32
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
) {
841 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, Walker
);
842 ShellStatus
= SHELL_INVALID_PARAMETER
;
844 NewKeyOption
.KeyData
= (UINT32
)Intermediate
;
845 Temp
= StrStr(Walker
, L
" ");
849 while(Walker
[0] == L
' ') {
854 if (ShellStatus
== SHELL_SUCCESS
) {
856 // Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.
857 // Re-allocate with the added information.
859 KeyOptionBuffer
= AllocateCopyPool(sizeof(EFI_KEY_OPTION
) + (sizeof(EFI_INPUT_KEY
) * KEY_OPTION_INPUT_KEY_COUNT (&NewKeyOption
)), &NewKeyOption
);
860 if (KeyOptionBuffer
== NULL
) {
861 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellInstall1HiiHandle
);
862 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
865 for (LoopCounter
= 0 ; ShellStatus
== SHELL_SUCCESS
&& LoopCounter
< KEY_OPTION_INPUT_KEY_COUNT (&NewKeyOption
); LoopCounter
++) {
869 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
870 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
) {
871 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, Walker
);
872 ShellStatus
= SHELL_INVALID_PARAMETER
;
874 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof(EFI_KEY_OPTION
)))[LoopCounter
].ScanCode
= (UINT16
)Intermediate
;
875 Temp
= StrStr(Walker
, L
" ");
879 while(Walker
[0] == L
' ') {
886 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
887 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
)) {
888 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, Walker
);
889 ShellStatus
= SHELL_INVALID_PARAMETER
;
891 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof(EFI_KEY_OPTION
)))[LoopCounter
].UnicodeChar
= (UINT16
)Intermediate
;
892 Temp
= StrStr(Walker
, L
" ");
896 while(Walker
[0] == L
' ') {
901 if (ShellStatus
== SHELL_SUCCESS
) {
903 // Now do the BootOption / BootOptionCrc
905 ASSERT (OptionIndex
<= OrderCount
);
906 KeyOptionBuffer
->BootOption
= CurrentOrder
[OptionIndex
];
907 Status
= GetBootOptionCrc(&(KeyOptionBuffer
->BootOptionCrc
), KeyOptionBuffer
->BootOption
);
908 if (EFI_ERROR(Status
)) {
909 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, L
"Option Index");
910 ShellStatus
= SHELL_INVALID_PARAMETER
;
914 if (ShellStatus
== SHELL_SUCCESS
) {
915 for (Temp2
= NULL
, KeyIndex
= 0 ; KeyIndex
< 0xFFFF ; KeyIndex
++) {
916 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"Key%04x", KeyIndex
);
917 Status
= gRT
->GetVariable(
919 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
921 (UINTN
*)&Intermediate
,
923 if (Status
== EFI_NOT_FOUND
) {
927 Status
= gRT
->SetVariable(
929 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
930 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
931 sizeof(EFI_KEY_OPTION
) + (sizeof(EFI_INPUT_KEY
) * KEY_OPTION_INPUT_KEY_COUNT (&NewKeyOption
)),
933 if (EFI_ERROR(Status
)) {
934 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellInstall1HiiHandle
, VariableName
, Status
);
935 ShellStatus
= SHELL_INVALID_PARAMETER
;
937 ASSERT(FileName
== NULL
&& Data
== NULL
);
943 // Shouldn't be possible to have have both. Neither is ok though.
945 ASSERT(FileName
== NULL
|| Data
== NULL
);
947 if (ShellStatus
== SHELL_SUCCESS
&& (FileName
!= NULL
|| Data
!= NULL
)) {
948 if (FileName
!= NULL
) {
950 // Open the file and populate the data buffer.
952 Status
= ShellOpenFileByName(
957 if (!EFI_ERROR(Status
)) {
958 Status
= ShellGetFileSize(FileHandle
, &Intermediate
);
960 Data
= AllocateZeroPool((UINTN
)Intermediate
);
962 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellInstall1HiiHandle
);
963 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
965 if (!EFI_ERROR(Status
)) {
966 Status
= ShellReadFile(FileHandle
, (UINTN
*)&Intermediate
, Data
);
969 Intermediate
= StrSize(Data
);
972 if (!EFI_ERROR(Status
) && ShellStatus
== SHELL_SUCCESS
&& Data
!= NULL
) {
973 Status
= UpdateOptionalData(CurrentOrder
[OptionIndex
], (UINTN
)Intermediate
, (UINT8
*)Data
, Target
);
974 if (EFI_ERROR(Status
)) {
975 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellInstall1HiiHandle
, VariableName
, Status
);
976 ShellStatus
= SHELL_INVALID_PARAMETER
;
979 if (EFI_ERROR(Status
) && ShellStatus
== SHELL_SUCCESS
) {
980 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellInstall1HiiHandle
, VariableName
, Status
);
981 ShellStatus
= SHELL_INVALID_PARAMETER
;
985 SHELL_FREE_NON_NULL(Data
);
986 SHELL_FREE_NON_NULL(KeyOptionBuffer
);
987 SHELL_FREE_NON_NULL(FileName
);
992 Function to dump the Bcfg information.
994 @param[in] Op The operation.
995 @param[in] OrderCount How many to dump.
996 @param[in] CurrentOrder The pointer to the current order of items.
997 @param[in] VerboseOutput TRUE for extra output. FALSE otherwise.
999 @retval SHELL_SUCCESS The dump was successful.
1000 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
1004 BcfgDisplayDumpInstall1(
1005 IN CONST CHAR16
*Op
,
1006 IN CONST UINTN OrderCount
,
1007 IN CONST UINT16
*CurrentOrder
,
1008 IN CONST BOOLEAN VerboseOutput
1014 CHAR16 VariableName
[12];
1017 CHAR16
*DevPathString
;
1020 if (OrderCount
== 0) {
1021 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_BCFG_NONE
), gShellInstall1HiiHandle
);
1022 return (SHELL_SUCCESS
);
1025 for (LoopVar
= 0 ; LoopVar
< OrderCount
; LoopVar
++) {
1028 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Op
, CurrentOrder
[LoopVar
]);
1030 Status
= gRT
->GetVariable(
1032 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1036 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1037 Buffer
= AllocateZeroPool(BufferSize
);
1038 Status
= gRT
->GetVariable(
1040 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1046 if (EFI_ERROR(Status
) || Buffer
== NULL
) {
1047 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_READ_FAIL
), gShellInstall1HiiHandle
, VariableName
, Status
);
1048 return (SHELL_INVALID_PARAMETER
);
1051 if ((*(UINT16
*)(Buffer
+4)) != 0) {
1052 DevPath
= AllocateZeroPool(*(UINT16
*)(Buffer
+4));
1053 CopyMem(DevPath
, Buffer
+6+StrSize((CHAR16
*)(Buffer
+6)), *(UINT16
*)(Buffer
+4));
1054 DevPathString
= ConvertDevicePathToText(DevPath
, TRUE
, FALSE
);
1057 DevPathString
= NULL
;
1063 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS
),
1064 gShellInstall1HiiHandle
,
1067 (CHAR16
*)(Buffer
+6),
1069 (StrSize((CHAR16
*)(Buffer
+6)) + *(UINT16
*)(Buffer
+4) + 6) <= BufferSize
?L
'N':L
'Y');
1070 if (VerboseOutput
) {
1071 for (LoopVar2
= (StrSize((CHAR16
*)(Buffer
+6)) + *(UINT16
*)(Buffer
+4) + 6);LoopVar2
<BufferSize
;LoopVar2
++){
1086 if (Buffer
!= NULL
) {
1089 if (DevPath
!= NULL
) {
1092 if (DevPathString
!= NULL
) {
1093 FreePool(DevPathString
);
1096 return (SHELL_SUCCESS
);
1100 Function to initialize the BCFG operation structure.
1102 @param[in] Struct The stuct to initialize.
1106 InitBcfgStructInstall1(
1107 IN BGFG_OPERATION
*Struct
1110 ASSERT(Struct
!= NULL
);
1111 Struct
->Target
= BcfgTargetMax
;
1112 Struct
->Type
= BcfgTypeMax
;
1113 Struct
->Number1
= 0;
1114 Struct
->Number2
= 0;
1115 Struct
->HandleIndex
= 0;
1116 Struct
->FileName
= NULL
;
1117 Struct
->Description
= NULL
;
1118 Struct
->Order
= NULL
;
1119 Struct
->OptData
= NULL
;
1123 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
1125 {L
"-opt", TypeMaxValue
},
1130 Function for 'bcfg' command.
1132 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1133 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1137 ShellCommandRunBcfgInstall (
1138 IN EFI_HANDLE ImageHandle
,
1139 IN EFI_SYSTEM_TABLE
*SystemTable
1143 LIST_ENTRY
*Package
;
1144 CHAR16
*ProblemParam
;
1145 SHELL_STATUS ShellStatus
;
1147 CONST CHAR16
*CurrentParam
;
1148 BGFG_OPERATION CurrentOperation
;
1150 UINT64 Intermediate
;
1153 ProblemParam
= NULL
;
1155 ShellStatus
= SHELL_SUCCESS
;
1157 InitBcfgStructInstall1(&CurrentOperation
);
1160 // initialize the shell lib (we must be in non-auto-init...)
1162 Status
= ShellInitialize();
1163 ASSERT_EFI_ERROR(Status
);
1165 Status
= CommandInit();
1166 ASSERT_EFI_ERROR(Status
);
1169 // parse the command line
1171 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
1172 if (EFI_ERROR(Status
)) {
1173 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
1174 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, ProblemParam
);
1175 FreePool(ProblemParam
);
1176 ShellStatus
= SHELL_INVALID_PARAMETER
;
1182 // Read in if we are doing -OPT
1184 if (ShellCommandLineGetFlag(Package
, L
"-opt")) {
1185 CurrentOperation
.OptData
= ShellCommandLineGetValue(Package
, L
"-opt");
1186 if (CurrentOperation
.OptData
== NULL
) {
1187 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_VAL
), gShellInstall1HiiHandle
, L
"-opt");
1188 ShellStatus
= SHELL_INVALID_PARAMETER
;
1190 CurrentOperation
.Type
= BcfgTypeOpt
;
1194 // small block to read the target of the operation
1196 if ((ShellCommandLineGetCount(Package
) < 3 && CurrentOperation
.Type
!= BcfgTypeOpt
) ||
1197 (ShellCommandLineGetCount(Package
) < 2 && CurrentOperation
.Type
== BcfgTypeOpt
)
1199 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellInstall1HiiHandle
);
1200 ShellStatus
= SHELL_INVALID_PARAMETER
;
1201 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"driver") == 0) {
1202 CurrentOperation
.Target
= BcfgTargetDriverOrder
;
1203 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"boot") == 0) {
1204 CurrentOperation
.Target
= BcfgTargetBootOrder
;
1206 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT
), gShellInstall1HiiHandle
);
1207 ShellStatus
= SHELL_INVALID_PARAMETER
;
1212 // Read in the boot or driver order environment variable (not needed for opt)
1214 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
1216 Status
= gRT
->GetVariable(
1217 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
1218 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1221 CurrentOperation
.Order
);
1222 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1223 CurrentOperation
.Order
= AllocateZeroPool(Length
+(4*sizeof(CurrentOperation
.Order
[0])));
1224 Status
= gRT
->GetVariable(
1225 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
1226 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1229 CurrentOperation
.Order
);
1234 // large block to read the type of operation and verify parameter types for the info.
1236 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
1237 for (ParamNumber
= 2 ; ParamNumber
< ShellCommandLineGetCount(Package
) && ShellStatus
== SHELL_SUCCESS
; ParamNumber
++) {
1238 CurrentParam
= ShellCommandLineGetRawValue(Package
, ParamNumber
);
1239 if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"dump") == 0) {
1240 CurrentOperation
.Type
= BcfgTypeDump
;
1241 } else if (ShellCommandLineGetFlag(Package
, L
"-v")) {
1242 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, L
"-v (without dump)");
1243 ShellStatus
= SHELL_INVALID_PARAMETER
;
1244 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"add") == 0) {
1245 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1246 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellInstall1HiiHandle
);
1247 ShellStatus
= SHELL_INVALID_PARAMETER
;
1249 CurrentOperation
.Type
= BcfgTypeAdd
;
1250 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1251 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1252 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, CurrentParam
);
1253 ShellStatus
= SHELL_INVALID_PARAMETER
;
1255 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1256 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1257 ASSERT(CurrentOperation
.FileName
== NULL
);
1258 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1259 ASSERT(CurrentOperation
.Description
== NULL
);
1260 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1262 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addp") == 0) {
1263 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1264 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellInstall1HiiHandle
);
1265 ShellStatus
= SHELL_INVALID_PARAMETER
;
1267 CurrentOperation
.Type
= BcfgTypeAddp
;
1268 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1269 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1270 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, CurrentParam
);
1271 ShellStatus
= SHELL_INVALID_PARAMETER
;
1273 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1274 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1275 ASSERT(CurrentOperation
.FileName
== NULL
);
1276 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1277 ASSERT(CurrentOperation
.Description
== NULL
);
1278 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1280 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addh") == 0) {
1281 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1282 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellInstall1HiiHandle
);
1283 ShellStatus
= SHELL_INVALID_PARAMETER
;
1285 CurrentOperation
.Type
= BcfgTypeAddh
;
1286 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1287 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1288 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, CurrentParam
);
1289 ShellStatus
= SHELL_INVALID_PARAMETER
;
1291 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1292 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1293 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1294 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1295 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, CurrentParam
);
1296 ShellStatus
= SHELL_INVALID_PARAMETER
;
1298 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1299 CurrentOperation
.HandleIndex
= (UINT16
)Intermediate
;
1300 ASSERT(CurrentOperation
.Description
== NULL
);
1301 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1304 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"rm") == 0) {
1305 if ((ParamNumber
+ 1) >= ShellCommandLineGetCount(Package
)) {
1306 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellInstall1HiiHandle
);
1307 ShellStatus
= SHELL_INVALID_PARAMETER
;
1309 CurrentOperation
.Type
= BcfgTypeRm
;
1310 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1311 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1312 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, CurrentParam
);
1313 ShellStatus
= SHELL_INVALID_PARAMETER
;
1315 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1316 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1317 if (CurrentOperation
.Number1
> (Length
/ sizeof(CurrentOperation
.Order
[0]))){
1318 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellInstall1HiiHandle
, Length
/ sizeof(CurrentOperation
.Order
[0]));
1319 ShellStatus
= SHELL_INVALID_PARAMETER
;
1322 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"mv") == 0) {
1323 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount(Package
)) {
1324 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellInstall1HiiHandle
);
1325 ShellStatus
= SHELL_INVALID_PARAMETER
;
1327 CurrentOperation
.Type
= BcfgTypeMv
;
1328 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1329 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1330 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, CurrentParam
);
1331 ShellStatus
= SHELL_INVALID_PARAMETER
;
1333 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1334 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1335 if (CurrentOperation
.Number1
> (Length
/ sizeof(CurrentOperation
.Order
[0]))){
1336 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellInstall1HiiHandle
, Length
/ sizeof(CurrentOperation
.Order
[0]));
1337 ShellStatus
= SHELL_INVALID_PARAMETER
;
1339 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1340 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1341 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, CurrentParam
);
1342 ShellStatus
= SHELL_INVALID_PARAMETER
;
1344 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1345 CurrentOperation
.Number2
= (UINT16
)Intermediate
;
1347 if (CurrentOperation
.Number2
== CurrentOperation
.Number1
1348 ||CurrentOperation
.Number1
> (Length
/ sizeof(CurrentOperation
.Order
[0]))
1349 ||CurrentOperation
.Number2
> (Length
/ sizeof(CurrentOperation
.Order
[0]))
1351 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellInstall1HiiHandle
, Length
/ sizeof(CurrentOperation
.Order
[0]));
1352 ShellStatus
= SHELL_INVALID_PARAMETER
;
1356 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellInstall1HiiHandle
, CurrentParam
);
1357 ShellStatus
= SHELL_INVALID_PARAMETER
;
1361 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
&& CurrentOperation
.Type
< BcfgTypeMax
) {
1363 // we have all the info. Do the work
1365 switch (CurrentOperation
.Type
) {
1367 ShellStatus
= BcfgDisplayDumpInstall1(
1368 CurrentOperation
.Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver",
1369 Length
/ sizeof(CurrentOperation
.Order
[0]),
1370 CurrentOperation
.Order
,
1371 ShellCommandLineGetFlag(Package
, L
"-v"));
1374 ShellStatus
= BcfgMoveInstall1(
1375 CurrentOperation
.Target
,
1376 CurrentOperation
.Order
,
1377 Length
/ sizeof(CurrentOperation
.Order
[0]),
1378 CurrentOperation
.Number1
,
1379 CurrentOperation
.Number2
);
1382 ShellStatus
= BcfgRemoveInstall1(
1383 CurrentOperation
.Target
,
1384 CurrentOperation
.Order
,
1385 Length
/ sizeof(CurrentOperation
.Order
[0]),
1386 CurrentOperation
.Number1
);
1391 ShellStatus
= BcfgAddInstall1(
1392 CurrentOperation
.Number1
,
1393 CurrentOperation
.FileName
,
1394 CurrentOperation
.Description
==NULL
?L
"":CurrentOperation
.Description
,
1395 CurrentOperation
.Order
,
1396 Length
/ sizeof(CurrentOperation
.Order
[0]),
1397 CurrentOperation
.Target
,
1398 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddh
),
1399 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddp
),
1400 CurrentOperation
.HandleIndex
);
1403 ShellStatus
= BcfgAddOptInstall1(
1404 CurrentOperation
.OptData
,
1405 CurrentOperation
.Order
,
1406 Length
/ sizeof(CurrentOperation
.Order
[0]),
1407 CurrentOperation
.Target
);
1415 if (Package
!= NULL
) {
1416 ShellCommandLineFreeVarList (Package
);
1418 if (CurrentOperation
.FileName
!= NULL
) {
1419 FreePool(CurrentOperation
.FileName
);
1421 if (CurrentOperation
.Description
!= NULL
) {
1422 FreePool(CurrentOperation
.Description
);
1424 if (CurrentOperation
.Order
!= NULL
) {
1425 FreePool(CurrentOperation
.Order
);
1428 return (ShellStatus
);