2 Main file for bcfg shell Debug1 function.
4 Copyright (c) 2010 - 2012, 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 Update the optional data for a boot or driver option.
53 If optional data exists it will be changed.
55 @param[in] Index The boot or driver option index update.
56 @param[in] DataSize The size in bytes of Data.
57 @param[in] Data The buffer for the optioanl data.
58 @param[in] Target The target of the operation.
60 @retval EFI_SUCCESS The data was sucessfully updated.
61 @retval other A error occured.
65 UpdateOptionalDataDebug1(
69 IN CONST BCFG_OPERATION_TARGET Target
73 CHAR16 VariableName
[12];
78 UINTN OriginalOptionDataSize
;
80 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", Index
);
87 Status
= gRT
->GetVariable(
89 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
93 if (Status
== EFI_BUFFER_TOO_SMALL
) {
94 OriginalData
= AllocateZeroPool(OriginalSize
);
95 if (OriginalData
== NULL
) {
96 return (EFI_OUT_OF_RESOURCES
);
98 Status
= gRT
->GetVariable(
100 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
106 if (!EFI_ERROR(Status
)) {
108 // Allocate new struct and discard old optional data.
110 OriginalOptionDataSize
= sizeof(UINT32
) + sizeof(UINT16
) + StrSize(((CHAR16
*)(OriginalData
+ sizeof(UINT32
) + sizeof(UINT16
))));
111 OriginalOptionDataSize
+= (*(UINT16
*)(OriginalData
+ sizeof(UINT32
)));
112 OriginalOptionDataSize
-= OriginalSize
;
113 NewSize
= OriginalSize
- OriginalOptionDataSize
+ DataSize
;
114 NewData
= AllocateCopyPool(NewSize
, OriginalData
);
115 if (NewData
== NULL
) {
116 Status
= EFI_OUT_OF_RESOURCES
;
118 CopyMem(NewData
+ OriginalSize
- OriginalOptionDataSize
, Data
, DataSize
);
122 if (!EFI_ERROR(Status
)) {
124 // put the data back under the variable
126 Status
= gRT
->SetVariable(
128 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
129 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
134 SHELL_FREE_NON_NULL(OriginalData
);
135 SHELL_FREE_NON_NULL(NewData
);
140 This function will get a CRC for a boot option.
142 @param[in, out] Crc The CRC value to return.
143 @param[in] Index The boot option index to CRC.
145 @retval EFI_SUCCESS The CRC was sucessfully returned.
146 @retval other A error occured.
150 GetBootOptionCrcDebug1(
155 CHAR16 VariableName
[12];
164 // Get the data Buffer
166 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%Boot%04x", BootIndex
);
167 Status
= gRT
->GetVariable(
169 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
173 if (Status
== EFI_BUFFER_TOO_SMALL
) {
174 Buffer
= AllocateZeroPool(BufferSize
);
175 Status
= gRT
->GetVariable(
177 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
184 // Get the CRC computed
186 if (!EFI_ERROR(Status
)) {
187 Status
= gBS
->CalculateCrc32 (Buffer
, BufferSize
, Crc
);
190 SHELL_FREE_NON_NULL(Buffer
);
195 This function will populate the device path protocol parameter based on TheHandle.
197 @param[in] TheHandle Driver handle.
198 @param[in, out] FilePath On a sucessful return the device path to the handle.
200 @retval EFI_SUCCESS The device path was sucessfully returned.
201 @retval other A error from gBS->HandleProtocol.
207 GetDevicePathForDriverHandleDebug1 (
208 IN EFI_HANDLE TheHandle
,
209 IN OUT EFI_DEVICE_PATH_PROTOCOL
**FilePath
213 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
214 EFI_DEVICE_PATH_PROTOCOL
*ImageDevicePath
;
216 Status
= gBS
->OpenProtocol (
218 &gEfiLoadedImageProtocolGuid
,
219 (VOID
**)&LoadedImage
,
222 EFI_OPEN_PROTOCOL_GET_PROTOCOL
224 if (!EFI_ERROR (Status
)) {
225 Status
= gBS
->OpenProtocol (
226 LoadedImage
->DeviceHandle
,
227 &gEfiDevicePathProtocolGuid
,
228 (VOID
**)&ImageDevicePath
,
231 EFI_OPEN_PROTOCOL_GET_PROTOCOL
233 if (!EFI_ERROR (Status
)) {
234 // *DevPath = DuplicateDevicePath (ImageDevicePath);
235 // *FilePath = DuplicateDevicePath (LoadedImage->FilePath);
236 *FilePath
= AppendDevicePath(ImageDevicePath
,LoadedImage
->FilePath
);
238 LoadedImage
->DeviceHandle
,
239 &gEfiDevicePathProtocolGuid
,
245 &gEfiLoadedImageProtocolGuid
,
253 Function to add a option.
255 @param[in] Position The position to add Target at.
256 @param[in] File The file to make the target.
257 @param[in] Desc The description text.
258 @param[in] CurrentOrder The pointer to the current order of items.
259 @param[in] OrderCount The number if items in CurrentOrder.
260 @param[in] Target The info on the option to add.
261 @param[in] UseHandle TRUE to use HandleNumber, FALSE to use File and Desc.
262 @param[in] UsePath TRUE to convert to devicepath.
263 @param[in] HandleNumber The handle number to add.
265 @retval SHELL_SUCCESS The operation was successful.
266 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
272 IN CONST CHAR16
*File
,
273 IN CONST CHAR16
*Desc
,
274 IN CONST UINT16
*CurrentOrder
,
275 IN CONST UINTN OrderCount
,
276 IN CONST BCFG_OPERATION_TARGET Target
,
277 IN CONST BOOLEAN UseHandle
,
278 IN CONST BOOLEAN UsePath
,
279 IN CONST UINTN HandleNumber
283 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
284 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
285 EFI_DEVICE_PATH_PROTOCOL
*FileNode
;
287 UINT8
*TempByteBuffer
;
288 UINT8
*TempByteStart
;
289 EFI_SHELL_FILE_INFO
*Arg
;
290 EFI_SHELL_FILE_INFO
*FileList
;
291 CHAR16 OptionStr
[40];
292 UINTN DescSize
, FilePathSize
;
294 UINTN TargetLocation
;
297 EFI_HANDLE CurHandle
;
298 UINTN DriverBindingHandleCount
;
299 UINTN ParentControllerHandleCount
;
300 UINTN ChildControllerHandleCount
;
301 SHELL_STATUS ShellStatus
;
305 if (File
== NULL
|| Desc
== NULL
) {
306 return (SHELL_INVALID_PARAMETER
);
309 if (HandleNumber
== 0) {
310 return (SHELL_INVALID_PARAMETER
);
314 if (Position
> OrderCount
) {
315 Position
= OrderCount
;
323 ShellStatus
= SHELL_SUCCESS
;
324 TargetLocation
= 0xFFFF;
327 CurHandle
= ConvertHandleIndexToHandle(HandleNumber
);
328 if (CurHandle
== NULL
) {
329 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"Handle Number");
330 ShellStatus
= SHELL_INVALID_PARAMETER
;
332 if (Target
== BcfgTargetBootOrder
) {
334 //Make sure that the handle should point to a real controller
336 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
338 &DriverBindingHandleCount
,
341 Status
= PARSE_HANDLE_DATABASE_PARENTS (
343 &ParentControllerHandleCount
,
346 Status
= ParseHandleDatabaseForChildControllers (
348 &ChildControllerHandleCount
,
351 if (DriverBindingHandleCount
> 0
352 || ParentControllerHandleCount
> 0
353 || ChildControllerHandleCount
> 0) {
355 Status
= gBS
->HandleProtocol (
357 &gEfiDevicePathProtocolGuid
,
360 if (EFI_ERROR (Status
)) {
361 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_HANDLE
), gShellDebug1HiiHandle
, HandleNumber
);
362 ShellStatus
= SHELL_INVALID_PARAMETER
;
366 //Make sure that the handle should point to driver, not a controller.
368 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
370 &DriverBindingHandleCount
,
373 Status
= PARSE_HANDLE_DATABASE_PARENTS (
375 &ParentControllerHandleCount
,
378 Status
= ParseHandleDatabaseForChildControllers (
380 &ChildControllerHandleCount
,
383 Status
= gBS
->HandleProtocol (
385 &gEfiDevicePathProtocolGuid
,
388 if (DriverBindingHandleCount
> 0
389 || ParentControllerHandleCount
> 0
390 || ChildControllerHandleCount
> 0
391 || !EFI_ERROR(Status
) ) {
392 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"Handle Number");
393 ShellStatus
= SHELL_INVALID_PARAMETER
;
396 // Get the DevicePath from the loaded image information.
398 Status
= GetDevicePathForDriverHandleDebug1(CurHandle
, &FilePath
);
406 ShellOpenFileMetaArg ((CHAR16
*)File
, EFI_FILE_MODE_READ
, &FileList
);
408 if (FileList
== NULL
) {
410 // If filename matched nothing fail
412 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, File
);
413 ShellStatus
= SHELL_INVALID_PARAMETER
;
414 } else if (FileList
->Link
.ForwardLink
!= FileList
->Link
.BackLink
) {
416 // If filename expanded to multiple names, fail
418 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE
), gShellDebug1HiiHandle
, File
);
419 ShellStatus
= SHELL_INVALID_PARAMETER
;
421 Arg
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
);
422 if (EFI_ERROR(Arg
->Status
)) {
423 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_OPEN
), gShellDebug1HiiHandle
, File
, Arg
->Status
);
424 ShellStatus
= SHELL_INVALID_PARAMETER
;
427 // Build FilePath to the filename
431 // get the device path
433 DevicePath
= gEfiShellProtocol
->GetDevicePathFromFilePath(Arg
->FullName
);
434 if (DevicePath
== NULL
) {
435 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_DP
), gShellDebug1HiiHandle
, Arg
->FullName
);
436 ShellStatus
= SHELL_UNSUPPORTED
;
440 DevPath = DevicePath;
441 while (!IsDevicePathEnd(DevPath)) {
442 if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&
443 (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {
446 // If we find it use it instead
448 DevicePath = DevPath;
451 DevPath = NextDevicePathNode(DevPath);
456 for(StringWalker=Arg->FullName; *StringWalker != CHAR_NULL && *StringWalker != ':'; StringWalker++);
457 FileNode = FileDevicePath(NULL, StringWalker+1);
458 FilePath = AppendDevicePath(DevicePath, FileNode);
462 FilePath
= DuplicateDevicePath(DevicePath
);
466 FreePool(DevicePath
);
473 if (ShellStatus
== SHELL_SUCCESS
) {
475 // Find a free target ,a brute force implementation
478 for (TargetLocation
=0; TargetLocation
< 0xFFFF; TargetLocation
++) {
480 for (Index
=0; Index
< OrderCount
; Index
++) {
481 if (CurrentOrder
[Index
] == TargetLocation
) {
492 if (TargetLocation
== 0xFFFF) {
493 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET_NF
), gShellDebug1HiiHandle
);
495 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET
), gShellDebug1HiiHandle
, TargetLocation
);
499 if (ShellStatus
== SHELL_SUCCESS
) {
503 DescSize
= StrSize(Desc
);
504 FilePathSize
= GetDevicePathSize (FilePath
);
506 TempByteBuffer
= AllocateZeroPool(sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
);
507 if (TempByteBuffer
!= NULL
) {
508 TempByteStart
= TempByteBuffer
;
509 *((UINT32
*) TempByteBuffer
) = LOAD_OPTION_ACTIVE
; // Attributes
510 TempByteBuffer
+= sizeof (UINT32
);
512 *((UINT16
*) TempByteBuffer
) = (UINT16
)FilePathSize
; // FilePathListLength
513 TempByteBuffer
+= sizeof (UINT16
);
515 CopyMem (TempByteBuffer
, Desc
, DescSize
);
516 TempByteBuffer
+= DescSize
;
517 CopyMem (TempByteBuffer
, FilePath
, FilePathSize
);
519 UnicodeSPrint (OptionStr
, sizeof(OptionStr
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", TargetLocation
);
520 Status
= gRT
->SetVariable (
522 &gEfiGlobalVariableGuid
,
523 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
524 sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
,
528 FreePool(TempByteStart
);
530 Status
= EFI_OUT_OF_RESOURCES
;
533 if (EFI_ERROR(Status
)) {
534 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellDebug1HiiHandle
, OptionStr
, Status
);
536 NewOrder
= AllocateZeroPool((OrderCount
+1)*sizeof(NewOrder
[0]));
537 ASSERT(NewOrder
!= NULL
);
538 CopyMem(NewOrder
, CurrentOrder
, (OrderCount
)*sizeof(NewOrder
[0]));
541 // Insert target into order list
543 for (Index
=OrderCount
; Index
> Position
; Index
--) {
544 NewOrder
[Index
] = NewOrder
[Index
-1];
547 NewOrder
[Position
] = (UINT16
) TargetLocation
;
548 Status
= gRT
->SetVariable (
549 Target
== BcfgTargetBootOrder
?L
"BootOrder":L
"DriverOrder",
550 &gEfiGlobalVariableGuid
,
551 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
552 (OrderCount
+1) * sizeof(UINT16
),
558 if (EFI_ERROR(Status
)) {
559 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellDebug1HiiHandle
, Target
== BcfgTargetBootOrder
?L
"BootOrder":L
"DriverOrder", Status
);
560 ShellStatus
= SHELL_INVALID_PARAMETER
;
562 Print (L
"bcfg: Add %s as %x\n", OptionStr
, Position
);
568 //If always Free FilePath, will free devicepath in system when use "addh"
570 if (FilePath
!=NULL
&& !UseHandle
) {
578 if (Handles
!= NULL
) {
582 if (FileList
!= NULL
) {
583 ShellCloseFileMetaArg (&FileList
);
586 return (ShellStatus
);
590 Funciton to remove an item.
592 @param[in] Target The target item to move.
593 @param[in] CurrentOrder The pointer to the current order of items.
594 @param[in] OrderCount The number if items in CurrentOrder.
595 @param[in] Location The current location of the Target.
597 @retval SHELL_SUCCESS The operation was successful.
598 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
603 IN CONST BCFG_OPERATION_TARGET Target
,
604 IN CONST UINT16
*CurrentOrder
,
605 IN CONST UINTN OrderCount
,
606 IN CONST UINT16 Location
609 CHAR16 VariableName
[12];
614 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", CurrentOrder
[Location
]);
615 Status
= gRT
->SetVariable(
617 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
618 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
621 if (EFI_ERROR(Status
)) {
622 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellDebug1HiiHandle
, VariableName
, Status
);
623 return (SHELL_INVALID_PARAMETER
);
625 NewOrder
= AllocateZeroPool(OrderCount
*sizeof(CurrentOrder
[0]));
626 if (NewOrder
!= NULL
) {
627 NewCount
= OrderCount
;
628 CopyMem(NewOrder
, CurrentOrder
, OrderCount
*sizeof(CurrentOrder
[0]));
629 CopyMem(NewOrder
+Location
, NewOrder
+Location
+1, (OrderCount
- Location
- 1)*sizeof(CurrentOrder
[0]));
632 Status
= gRT
->SetVariable(
633 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
634 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
635 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
636 NewCount
*sizeof(NewOrder
[0]),
640 Status
= EFI_OUT_OF_RESOURCES
;
642 if (EFI_ERROR(Status
)) {
643 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellDebug1HiiHandle
, Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder", Status
);
644 return (SHELL_INVALID_PARAMETER
);
646 return (SHELL_SUCCESS
);
650 Funciton to move a item to another location.
652 @param[in] Target The target item to move.
653 @param[in] CurrentOrder The pointer to the current order of items.
654 @param[in] OrderCount The number if items in CurrentOrder.
655 @param[in] OldLocation The current location of the Target.
656 @param[in] NewLocation The desired location of the Target.
658 @retval SHELL_SUCCESS The operation was successful.
659 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
664 IN CONST BCFG_OPERATION_TARGET Target
,
665 IN CONST UINT16
*CurrentOrder
,
666 IN CONST UINTN OrderCount
,
667 IN CONST UINT16 OldLocation
,
668 IN CONST UINT16 NewLocation
675 NewOrder
= AllocateZeroPool(OrderCount
*sizeof(CurrentOrder
[0]));
676 ASSERT(NewOrder
!= NULL
);
678 Temp
= CurrentOrder
[OldLocation
];
679 CopyMem(NewOrder
, CurrentOrder
, OrderCount
*sizeof(CurrentOrder
[0]));
680 CopyMem(NewOrder
+OldLocation
, NewOrder
+OldLocation
+1, (OrderCount
- OldLocation
- 1)*sizeof(CurrentOrder
[0]));
681 CopyMem(NewOrder
+NewLocation
+1, NewOrder
+NewLocation
, (OrderCount
- NewLocation
- 1)*sizeof(CurrentOrder
[0]));
682 NewOrder
[NewLocation
] = Temp
;
685 Status
= gRT
->SetVariable(
686 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
687 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
688 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
689 OrderCount
*sizeof(CurrentOrder
[0]),
694 if (EFI_ERROR(Status
)) {
695 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellDebug1HiiHandle
, Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder", Status
);
696 return (SHELL_INVALID_PARAMETER
);
698 return (SHELL_SUCCESS
);
702 Function to add optional data to an option.
704 @param[in] OptData The optional data to add.
705 @param[in] CurrentOrder The pointer to the current order of items.
706 @param[in] OrderCount The number if items in CurrentOrder.
707 @param[in] Target The target of the operation.
709 @retval SHELL_SUCCESS The operation was succesful.
714 IN CONST CHAR16
*OptData
,
715 IN CONST UINT16
*CurrentOrder
,
716 IN CONST UINTN OrderCount
,
717 IN CONST BCFG_OPERATION_TARGET Target
720 EFI_KEY_OPTION NewKeyOption
;
721 EFI_KEY_OPTION
*KeyOptionBuffer
;
722 SHELL_STATUS ShellStatus
;
728 CONST CHAR16
*Walker
;
733 CHAR16 VariableName
[12];
735 SHELL_FILE_HANDLE FileHandle
;
737 Status
= EFI_SUCCESS
;
738 ShellStatus
= SHELL_SUCCESS
;
742 KeyOptionBuffer
= NULL
;
744 ZeroMem(&NewKeyOption
, sizeof(EFI_KEY_OPTION
));
746 while(Walker
[0] == L
' ') {
751 // Get the index of the variable we are changing.
753 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
754 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
|| ((UINT16
)Intermediate
) > ((UINT16
)OrderCount
)) {
755 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"Option Index");
756 ShellStatus
= SHELL_INVALID_PARAMETER
;
757 return (ShellStatus
);
759 OptionIndex
= (UINT16
)Intermediate
;
761 Temp
= StrStr(Walker
, L
" ");
765 while(Walker
[0] == L
' ') {
770 // determine whether we have file with data, quote delimited information, or a hot-key
772 if (Walker
[0] == L
'\"') {
774 // quoted filename or quoted information.
776 Temp
= StrStr(Walker
+1, L
"\"");
777 if (Temp
== NULL
|| StrLen(Temp
) != 1) {
778 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, Walker
);
779 ShellStatus
= SHELL_INVALID_PARAMETER
;
781 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
+1, 0);
782 Temp2
= StrStr(FileName
, L
"\"");
783 ASSERT(Temp2
!= NULL
);
784 Temp2
[0] = CHAR_NULL
;
786 if (StrLen(Temp2
)>0) {
787 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, Walker
);
788 ShellStatus
= SHELL_INVALID_PARAMETER
;
790 if (EFI_ERROR(ShellFileExists(Walker
))) {
792 // Not a file. must be misc information.
797 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
, 0);
802 // filename or hot key information.
804 if (StrStr(Walker
, L
" ") == NULL
) {
808 if (EFI_ERROR(ShellFileExists(Walker
))) {
809 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FIND_FAIL
), gShellDebug1HiiHandle
, Walker
);
810 ShellStatus
= SHELL_INVALID_PARAMETER
;
812 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
, 0);
815 if (Target
!= BcfgTargetBootOrder
) {
816 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_BOOT_ONLY
), gShellDebug1HiiHandle
);
817 ShellStatus
= SHELL_INVALID_PARAMETER
;
820 if (ShellStatus
== SHELL_SUCCESS
) {
822 // Get hot key information
824 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
825 if (EFI_ERROR(Status
) || (((UINT32
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
) {
826 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, Walker
);
827 ShellStatus
= SHELL_INVALID_PARAMETER
;
829 NewKeyOption
.KeyData
.PackedValue
= (UINT32
)Intermediate
;
830 Temp
= StrStr(Walker
, L
" ");
834 while(Walker
[0] == L
' ') {
839 if (ShellStatus
== SHELL_SUCCESS
) {
841 // Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.
842 // Re-allocate with the added information.
844 KeyOptionBuffer
= AllocateCopyPool(sizeof(EFI_KEY_OPTION
) + (sizeof(EFI_KEY_DATA
) * NewKeyOption
.KeyData
.Options
.InputKeyCount
), &NewKeyOption
);
845 if (KeyOptionBuffer
== NULL
) {
846 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellDebug1HiiHandle
);
847 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
850 for (LoopCounter
= 0 ; ShellStatus
== SHELL_SUCCESS
&& LoopCounter
< KeyOptionBuffer
->KeyData
.Options
.InputKeyCount
; LoopCounter
++) {
854 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
855 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
) {
856 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, Walker
);
857 ShellStatus
= SHELL_INVALID_PARAMETER
;
859 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof(EFI_KEY_OPTION
)))[LoopCounter
].ScanCode
= (UINT16
)Intermediate
;
860 Temp
= StrStr(Walker
, L
" ");
864 while(Walker
[0] == L
' ') {
871 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
872 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
)) {
873 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, Walker
);
874 ShellStatus
= SHELL_INVALID_PARAMETER
;
876 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof(EFI_KEY_OPTION
)))[LoopCounter
].UnicodeChar
= (UINT16
)Intermediate
;
877 Temp
= StrStr(Walker
, L
" ");
881 while(Walker
[0] == L
' ') {
886 if (ShellStatus
== SHELL_SUCCESS
) {
888 // Now do the BootOption / BootOptionCrc
890 ASSERT (OptionIndex
<= OrderCount
);
891 KeyOptionBuffer
->BootOption
= CurrentOrder
[OptionIndex
];
892 Status
= GetBootOptionCrcDebug1(&(KeyOptionBuffer
->BootOptionCrc
), KeyOptionBuffer
->BootOption
);
893 if (EFI_ERROR(Status
)) {
894 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"Option Index");
895 ShellStatus
= SHELL_INVALID_PARAMETER
;
899 if (ShellStatus
== SHELL_SUCCESS
) {
900 for (Temp2
= NULL
, KeyIndex
= 0 ; KeyIndex
< 0xFFFF ; KeyIndex
++) {
901 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"Key%04x", KeyIndex
);
902 Status
= gRT
->GetVariable(
904 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
906 (UINTN
*)&Intermediate
,
908 if (Status
== EFI_NOT_FOUND
) {
912 Status
= gRT
->SetVariable(
914 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
915 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
916 sizeof(EFI_KEY_OPTION
) + (sizeof(EFI_KEY_DATA
) * NewKeyOption
.KeyData
.Options
.InputKeyCount
),
918 if (EFI_ERROR(Status
)) {
919 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellDebug1HiiHandle
, VariableName
, Status
);
920 ShellStatus
= SHELL_INVALID_PARAMETER
;
922 ASSERT(FileName
== NULL
&& Data
== NULL
);
928 // Shouldn't be possible to have have both. Neither is ok though.
930 ASSERT(FileName
== NULL
|| Data
== NULL
);
932 if (ShellStatus
== SHELL_SUCCESS
&& FileName
!= NULL
|| Data
!= NULL
) {
933 if (FileName
!= NULL
) {
935 // Open the file and populate the data buffer.
937 ShellStatus
= ShellOpenFileByName(
942 if (ShellStatus
== SHELL_SUCCESS
) {
943 ShellStatus
= ShellGetFileSize(FileHandle
, &Intermediate
);
945 Data
= AllocateZeroPool((UINTN
)Intermediate
);
947 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellDebug1HiiHandle
);
948 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
950 if (ShellStatus
== SHELL_SUCCESS
) {
951 ShellStatus
= ShellReadFile(FileHandle
, &(UINTN
)Intermediate
, Data
);
954 Intermediate
= StrSize(Data
);
957 if (ShellStatus
== SHELL_SUCCESS
&& Data
!= NULL
) {
958 Status
= UpdateOptionalDataDebug1(CurrentOrder
[OptionIndex
], (UINTN
)Intermediate
, (UINT8
*)Data
, Target
);
959 if (EFI_ERROR(Status
)) {
960 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellDebug1HiiHandle
, VariableName
, Status
);
961 ShellStatus
= SHELL_INVALID_PARAMETER
;
966 SHELL_FREE_NON_NULL(Data
);
967 SHELL_FREE_NON_NULL(KeyOptionBuffer
);
968 SHELL_FREE_NON_NULL(FileName
);
973 Function to dump the Bcfg information.
975 @param[in] Op The operation.
976 @param[in] OrderCount How many to dump.
977 @param[in] CurrentOrder The pointer to the current order of items.
978 @param[in] VerboseOutput TRUE for extra output. FALSE otherwise.
980 @retval SHELL_SUCCESS The dump was successful.
981 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
985 BcfgDisplayDumpDebug1(
987 IN CONST UINTN OrderCount
,
988 IN CONST UINT16
*CurrentOrder
,
989 IN CONST BOOLEAN VerboseOutput
995 CHAR16 VariableName
[12];
998 CHAR16
*DevPathString
;
1001 if (OrderCount
== 0) {
1002 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_BCFG_NONE
), gShellDebug1HiiHandle
);
1003 return (SHELL_SUCCESS
);
1006 for (LoopVar
= 0 ; LoopVar
< OrderCount
; LoopVar
++) {
1009 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Op
, CurrentOrder
[LoopVar
]);
1011 Status
= gRT
->GetVariable(
1013 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1017 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1018 Buffer
= AllocateZeroPool(BufferSize
);
1019 Status
= gRT
->GetVariable(
1021 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1027 if (EFI_ERROR(Status
) || Buffer
== NULL
) {
1028 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_READ_FAIL
), gShellDebug1HiiHandle
, VariableName
, Status
);
1029 return (SHELL_INVALID_PARAMETER
);
1032 if ((*(UINT16
*)(Buffer
+4)) != 0) {
1033 DevPath
= AllocateZeroPool(*(UINT16
*)(Buffer
+4));
1034 CopyMem(DevPath
, Buffer
+6+StrSize((CHAR16
*)(Buffer
+6)), *(UINT16
*)(Buffer
+4));
1035 DevPathString
= gDevPathToText
->ConvertDevicePathToText(DevPath
, TRUE
, FALSE
);
1038 DevPathString
= NULL
;
1044 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS
),
1045 gShellDebug1HiiHandle
,
1048 (CHAR16
*)(Buffer
+6),
1050 (StrSize((CHAR16
*)(Buffer
+6)) + *(UINT16
*)(Buffer
+4) + 6) <= BufferSize
?L
'N':L
'Y');
1051 if (VerboseOutput
) {
1052 for (LoopVar2
= (StrSize((CHAR16
*)(Buffer
+6)) + *(UINT16
*)(Buffer
+4) + 6);LoopVar2
<BufferSize
;LoopVar2
++){
1067 if (Buffer
!= NULL
) {
1070 if (DevPath
!= NULL
) {
1073 if (DevPathString
!= NULL
) {
1074 FreePool(DevPathString
);
1077 return (SHELL_SUCCESS
);
1081 Function to initialize the BCFG operation structure.
1083 @param[in] Struct The stuct to initialize.
1087 InitBcfgStructDebug1(
1088 IN BGFG_OPERATION
*Struct
1091 ASSERT(Struct
!= NULL
);
1092 Struct
->Target
= BcfgTargetMax
;
1093 Struct
->Type
= BcfgTypeMax
;
1094 Struct
->Number1
= 0;
1095 Struct
->Number2
= 0;
1096 Struct
->HandleIndex
= 0;
1097 Struct
->FileName
= NULL
;
1098 Struct
->Description
= NULL
;
1099 Struct
->Order
= NULL
;
1100 Struct
->OptData
= NULL
;
1104 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
1106 {L
"-opt", TypeMaxValue
},
1111 Function for 'bcfg' command.
1113 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1114 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1118 ShellCommandRunBcfg (
1119 IN EFI_HANDLE ImageHandle
,
1120 IN EFI_SYSTEM_TABLE
*SystemTable
1124 LIST_ENTRY
*Package
;
1125 CHAR16
*ProblemParam
;
1126 SHELL_STATUS ShellStatus
;
1128 CONST CHAR16
*CurrentParam
;
1129 BGFG_OPERATION CurrentOperation
;
1131 UINT64 Intermediate
;
1134 ProblemParam
= NULL
;
1136 ShellStatus
= SHELL_SUCCESS
;
1138 InitBcfgStructDebug1(&CurrentOperation
);
1141 // initialize the shell lib (we must be in non-auto-init...)
1143 Status
= ShellInitialize();
1144 ASSERT_EFI_ERROR(Status
);
1146 Status
= CommandInit();
1147 ASSERT_EFI_ERROR(Status
);
1150 // parse the command line
1152 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
1153 if (EFI_ERROR(Status
)) {
1154 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
1155 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, ProblemParam
);
1156 FreePool(ProblemParam
);
1157 ShellStatus
= SHELL_INVALID_PARAMETER
;
1163 // Read in if we are doing -OPT
1165 if (ShellCommandLineGetFlag(Package
, L
"-opt")) {
1166 CurrentOperation
.OptData
= ShellCommandLineGetValue(Package
, L
"-opt");
1167 if (CurrentOperation
.OptData
== NULL
) {
1168 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_VAL
), gShellDebug1HiiHandle
, L
"-opt");
1169 ShellStatus
= SHELL_INVALID_PARAMETER
;
1171 CurrentOperation
.Type
= BcfgTypeOpt
;
1175 // small block to read the target of the operation
1177 if ((ShellCommandLineGetCount(Package
) < 3 && CurrentOperation
.Type
!= BcfgTypeOpt
) ||
1178 (ShellCommandLineGetCount(Package
) < 2 && CurrentOperation
.Type
== BcfgTypeOpt
)
1180 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
);
1181 ShellStatus
= SHELL_INVALID_PARAMETER
;
1182 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"driver") == 0) {
1183 CurrentOperation
.Target
= BcfgTargetDriverOrder
;
1184 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"boot") == 0) {
1185 CurrentOperation
.Target
= BcfgTargetBootOrder
;
1187 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT
), gShellDebug1HiiHandle
);
1188 ShellStatus
= SHELL_INVALID_PARAMETER
;
1193 // Read in the boot or driver order environment variable (not needed for opt)
1195 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
1197 Status
= gRT
->GetVariable(
1198 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
1199 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1202 CurrentOperation
.Order
);
1203 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1204 CurrentOperation
.Order
= AllocateZeroPool(Length
+(4*sizeof(CurrentOperation
.Order
[0])));
1205 Status
= gRT
->GetVariable(
1206 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
1207 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1210 CurrentOperation
.Order
);
1215 // large block to read the type of operation and verify parameter types for the info.
1217 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
1218 for (ParamNumber
= 2 ; ParamNumber
< ShellCommandLineGetCount(Package
) && ShellStatus
== SHELL_SUCCESS
; ParamNumber
++) {
1219 CurrentParam
= ShellCommandLineGetRawValue(Package
, ParamNumber
);
1220 if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"dump") == 0) {
1221 CurrentOperation
.Type
= BcfgTypeDump
;
1222 } else if (ShellCommandLineGetFlag(Package
, L
"-v")) {
1223 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"-v (without dump)");
1224 ShellStatus
= SHELL_INVALID_PARAMETER
;
1225 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"add") == 0) {
1226 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1227 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
);
1228 ShellStatus
= SHELL_INVALID_PARAMETER
;
1230 CurrentOperation
.Type
= BcfgTypeAdd
;
1231 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1232 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1233 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, CurrentParam
);
1234 ShellStatus
= SHELL_INVALID_PARAMETER
;
1236 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1237 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1238 ASSERT(CurrentOperation
.FileName
== NULL
);
1239 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1240 ASSERT(CurrentOperation
.Description
== NULL
);
1241 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1243 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addp") == 0) {
1244 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1245 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
);
1246 ShellStatus
= SHELL_INVALID_PARAMETER
;
1248 CurrentOperation
.Type
= BcfgTypeAddp
;
1249 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1250 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1251 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, CurrentParam
);
1252 ShellStatus
= SHELL_INVALID_PARAMETER
;
1254 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1255 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1256 ASSERT(CurrentOperation
.FileName
== NULL
);
1257 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1258 ASSERT(CurrentOperation
.Description
== NULL
);
1259 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1261 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addh") == 0) {
1262 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1263 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
);
1264 ShellStatus
= SHELL_INVALID_PARAMETER
;
1266 CurrentOperation
.Type
= BcfgTypeAddh
;
1267 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1268 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1269 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, CurrentParam
);
1270 ShellStatus
= SHELL_INVALID_PARAMETER
;
1272 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1273 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1274 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1275 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1276 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, CurrentParam
);
1277 ShellStatus
= SHELL_INVALID_PARAMETER
;
1279 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1280 CurrentOperation
.HandleIndex
= (UINT16
)Intermediate
;
1281 ASSERT(CurrentOperation
.Description
== NULL
);
1282 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1285 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"rm") == 0) {
1286 if ((ParamNumber
+ 1) >= ShellCommandLineGetCount(Package
)) {
1287 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
);
1288 ShellStatus
= SHELL_INVALID_PARAMETER
;
1290 CurrentOperation
.Type
= BcfgTypeRm
;
1291 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1292 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1293 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, CurrentParam
);
1294 ShellStatus
= SHELL_INVALID_PARAMETER
;
1296 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1297 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1298 if (CurrentOperation
.Number1
> (Length
/ sizeof(CurrentOperation
.Order
[0]))){
1299 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellDebug1HiiHandle
, Length
/ sizeof(CurrentOperation
.Order
[0]));
1300 ShellStatus
= SHELL_INVALID_PARAMETER
;
1303 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"mv") == 0) {
1304 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount(Package
)) {
1305 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
);
1306 ShellStatus
= SHELL_INVALID_PARAMETER
;
1308 CurrentOperation
.Type
= BcfgTypeMv
;
1309 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1310 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1311 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, CurrentParam
);
1312 ShellStatus
= SHELL_INVALID_PARAMETER
;
1314 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1315 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1316 if (CurrentOperation
.Number1
> (Length
/ sizeof(CurrentOperation
.Order
[0]))){
1317 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellDebug1HiiHandle
, Length
/ sizeof(CurrentOperation
.Order
[0]));
1318 ShellStatus
= SHELL_INVALID_PARAMETER
;
1320 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1321 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1322 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, CurrentParam
);
1323 ShellStatus
= SHELL_INVALID_PARAMETER
;
1325 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1326 CurrentOperation
.Number2
= (UINT16
)Intermediate
;
1328 if (CurrentOperation
.Number2
== CurrentOperation
.Number1
1329 ||CurrentOperation
.Number1
> (Length
/ sizeof(CurrentOperation
.Order
[0]))
1330 ||CurrentOperation
.Number2
> (Length
/ sizeof(CurrentOperation
.Order
[0]))
1332 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellDebug1HiiHandle
, Length
/ sizeof(CurrentOperation
.Order
[0]));
1333 ShellStatus
= SHELL_INVALID_PARAMETER
;
1337 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, CurrentParam
);
1338 ShellStatus
= SHELL_INVALID_PARAMETER
;
1342 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
&& CurrentOperation
.Type
< BcfgTypeMax
) {
1344 // we have all the info. Do the work
1346 switch (CurrentOperation
.Type
) {
1348 ShellStatus
= BcfgDisplayDumpDebug1(
1349 CurrentOperation
.Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver",
1350 Length
/ sizeof(CurrentOperation
.Order
[0]),
1351 CurrentOperation
.Order
,
1352 ShellCommandLineGetFlag(Package
, L
"-v"));
1355 ShellStatus
= BcfgMoveDebug1(
1356 CurrentOperation
.Target
,
1357 CurrentOperation
.Order
,
1358 Length
/ sizeof(CurrentOperation
.Order
[0]),
1359 CurrentOperation
.Number1
,
1360 CurrentOperation
.Number2
);
1363 ShellStatus
= BcfgRemoveDebug1(
1364 CurrentOperation
.Target
,
1365 CurrentOperation
.Order
,
1366 Length
/ sizeof(CurrentOperation
.Order
[0]),
1367 CurrentOperation
.Number1
);
1372 ShellStatus
= BcfgAddDebug1(
1373 CurrentOperation
.Number1
,
1374 CurrentOperation
.FileName
,
1375 CurrentOperation
.Description
==NULL
?L
"":CurrentOperation
.Description
,
1376 CurrentOperation
.Order
,
1377 Length
/ sizeof(CurrentOperation
.Order
[0]),
1378 CurrentOperation
.Target
,
1379 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddh
),
1380 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddp
),
1381 CurrentOperation
.HandleIndex
);
1384 ShellStatus
= BcfgAddOptDebug1(
1385 CurrentOperation
.OptData
,
1386 CurrentOperation
.Order
,
1387 Length
/ sizeof(CurrentOperation
.Order
[0]),
1388 CurrentOperation
.Target
);
1396 if (Package
!= NULL
) {
1397 ShellCommandLineFreeVarList (Package
);
1399 if (CurrentOperation
.FileName
!= NULL
) {
1400 FreePool(CurrentOperation
.FileName
);
1402 if (CurrentOperation
.Description
!= NULL
) {
1403 FreePool(CurrentOperation
.Description
);
1405 if (CurrentOperation
.Order
!= NULL
) {
1406 FreePool(CurrentOperation
.Order
);
1409 return (ShellStatus
);