2 Main file for BCFG command.
4 (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include <ShellBase.h>
20 #include <Guid/GlobalVariable.h>
21 #include <Guid/ShellLibHiiGuid.h>
23 #include <Protocol/EfiShell.h>
24 #include <Protocol/EfiShellParameters.h>
25 #include <Protocol/DevicePath.h>
26 #include <Protocol/LoadedImage.h>
27 #include <Protocol/UnicodeCollation.h>
29 #include <Library/BaseLib.h>
30 #include <Library/BaseMemoryLib.h>
31 #include <Library/DebugLib.h>
32 #include <Library/MemoryAllocationLib.h>
33 #include <Library/PcdLib.h>
34 #include <Library/ShellCommandLib.h>
35 #include <Library/ShellLib.h>
36 #include <Library/SortLib.h>
37 #include <Library/UefiLib.h>
38 #include <Library/UefiRuntimeServicesTableLib.h>
39 #include <Library/UefiBootServicesTableLib.h>
40 #include <Library/HiiLib.h>
41 #include <Library/FileHandleLib.h>
42 #include <Library/PrintLib.h>
43 #include <Library/HandleParsingLib.h>
44 #include <Library/DevicePathLib.h>
46 STATIC CONST CHAR16 mFileName
[] = L
"ShellCommands";
47 STATIC EFI_HANDLE gShellBcfgHiiHandle
= NULL
;
50 BcfgTargetBootOrder
= 0,
51 BcfgTargetDriverOrder
= 1,
53 } BCFG_OPERATION_TARGET
;
64 } BCFG_OPERATION_TYPE
;
67 BCFG_OPERATION_TARGET Target
;
68 BCFG_OPERATION_TYPE Type
;
75 CONST CHAR16
*OptData
;
79 Update the optional data for a boot or driver option.
81 If optional data exists it will be changed.
83 @param[in] Index The boot or driver option index update.
84 @param[in] DataSize The size in bytes of Data.
85 @param[in] Data The buffer for the optioanl data.
86 @param[in] Target The target of the operation.
88 @retval EFI_SUCCESS The data was sucessfully updated.
89 @retval other A error occured.
97 IN CONST BCFG_OPERATION_TARGET Target
101 CHAR16 VariableName
[12];
106 UINTN OriginalOptionDataSize
;
108 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", Index
);
115 Status
= gRT
->GetVariable(
117 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
121 if (Status
== EFI_BUFFER_TOO_SMALL
) {
122 OriginalData
= AllocateZeroPool(OriginalSize
);
123 if (OriginalData
== NULL
) {
124 return (EFI_OUT_OF_RESOURCES
);
126 Status
= gRT
->GetVariable(
128 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
134 if (!EFI_ERROR(Status
)) {
136 // Allocate new struct and discard old optional data.
138 ASSERT (OriginalData
!= NULL
);
139 OriginalOptionDataSize
= sizeof(UINT32
) + sizeof(UINT16
) + StrSize(((CHAR16
*)(OriginalData
+ sizeof(UINT32
) + sizeof(UINT16
))));
140 OriginalOptionDataSize
+= (*(UINT16
*)(OriginalData
+ sizeof(UINT32
)));
141 OriginalOptionDataSize
-= OriginalSize
;
142 NewSize
= OriginalSize
- OriginalOptionDataSize
+ DataSize
;
143 NewData
= AllocateCopyPool(NewSize
, OriginalData
);
144 if (NewData
== NULL
) {
145 Status
= EFI_OUT_OF_RESOURCES
;
147 CopyMem(NewData
+ OriginalSize
- OriginalOptionDataSize
, Data
, DataSize
);
151 if (!EFI_ERROR(Status
)) {
153 // put the data back under the variable
155 Status
= gRT
->SetVariable(
157 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
158 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
163 SHELL_FREE_NON_NULL(OriginalData
);
164 SHELL_FREE_NON_NULL(NewData
);
169 This function will get a CRC for a boot option.
171 @param[in, out] Crc The CRC value to return.
172 @param[in] BootIndex The boot option index to CRC.
174 @retval EFI_SUCCESS The CRC was sucessfully returned.
175 @retval other A error occured.
184 CHAR16 VariableName
[12];
193 // Get the data Buffer
195 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%Boot%04x", BootIndex
);
196 Status
= gRT
->GetVariable(
198 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
202 if (Status
== EFI_BUFFER_TOO_SMALL
) {
203 Buffer
= AllocateZeroPool(BufferSize
);
204 Status
= gRT
->GetVariable(
206 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
213 // Get the CRC computed
215 if (!EFI_ERROR(Status
)) {
216 Status
= gBS
->CalculateCrc32 (Buffer
, BufferSize
, Crc
);
219 SHELL_FREE_NON_NULL(Buffer
);
224 This function will populate the device path protocol parameter based on TheHandle.
226 @param[in] TheHandle Driver handle.
227 @param[in, out] FilePath On a sucessful return the device path to the handle.
229 @retval EFI_SUCCESS The device path was sucessfully returned.
230 @retval other A error from gBS->HandleProtocol.
236 GetDevicePathForDriverHandle (
237 IN EFI_HANDLE TheHandle
,
238 IN OUT EFI_DEVICE_PATH_PROTOCOL
**FilePath
242 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
243 EFI_DEVICE_PATH_PROTOCOL
*ImageDevicePath
;
245 Status
= gBS
->OpenProtocol (
247 &gEfiLoadedImageProtocolGuid
,
248 (VOID
**)&LoadedImage
,
251 EFI_OPEN_PROTOCOL_GET_PROTOCOL
253 if (!EFI_ERROR (Status
)) {
254 Status
= gBS
->OpenProtocol (
255 LoadedImage
->DeviceHandle
,
256 &gEfiDevicePathProtocolGuid
,
257 (VOID
**)&ImageDevicePath
,
260 EFI_OPEN_PROTOCOL_GET_PROTOCOL
262 if (!EFI_ERROR (Status
)) {
263 // *DevPath = DuplicateDevicePath (ImageDevicePath);
264 // *FilePath = DuplicateDevicePath (LoadedImage->FilePath);
265 *FilePath
= AppendDevicePath(ImageDevicePath
,LoadedImage
->FilePath
);
267 LoadedImage
->DeviceHandle
,
268 &gEfiDevicePathProtocolGuid
,
274 &gEfiLoadedImageProtocolGuid
,
282 Function to add a option.
284 @param[in] Position The position to add Target at.
285 @param[in] File The file to make the target.
286 @param[in] Desc The description text.
287 @param[in] CurrentOrder The pointer to the current order of items.
288 @param[in] OrderCount The number if items in CurrentOrder.
289 @param[in] Target The info on the option to add.
290 @param[in] UseHandle TRUE to use HandleNumber, FALSE to use File and Desc.
291 @param[in] UsePath TRUE to convert to devicepath.
292 @param[in] HandleNumber The handle number to add.
294 @retval SHELL_SUCCESS The operation was successful.
295 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
301 IN CONST CHAR16
*File
,
302 IN CONST CHAR16
*Desc
,
303 IN CONST UINT16
*CurrentOrder
,
304 IN CONST UINTN OrderCount
,
305 IN CONST BCFG_OPERATION_TARGET Target
,
306 IN CONST BOOLEAN UseHandle
,
307 IN CONST BOOLEAN UsePath
,
308 IN CONST UINTN HandleNumber
312 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
313 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
314 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
316 UINT8
*TempByteBuffer
;
317 UINT8
*TempByteStart
;
318 EFI_SHELL_FILE_INFO
*Arg
;
319 EFI_SHELL_FILE_INFO
*FileList
;
320 CHAR16 OptionStr
[40];
321 UINTN DescSize
, FilePathSize
;
323 UINTN TargetLocation
;
326 EFI_HANDLE CurHandle
;
327 UINTN DriverBindingHandleCount
;
328 UINTN ParentControllerHandleCount
;
329 UINTN ChildControllerHandleCount
;
330 SHELL_STATUS ShellStatus
;
334 if (File
== NULL
|| Desc
== NULL
) {
335 return (SHELL_INVALID_PARAMETER
);
338 if (HandleNumber
== 0) {
339 return (SHELL_INVALID_PARAMETER
);
343 if (Position
> OrderCount
) {
344 Position
= OrderCount
;
351 ShellStatus
= SHELL_SUCCESS
;
352 TargetLocation
= 0xFFFF;
355 CurHandle
= ConvertHandleIndexToHandle(HandleNumber
);
356 if (CurHandle
== NULL
) {
357 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Handle Number");
358 ShellStatus
= SHELL_INVALID_PARAMETER
;
360 if (Target
== BcfgTargetBootOrder
) {
362 //Make sure that the handle should point to a real controller
364 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
366 &DriverBindingHandleCount
,
369 Status
= PARSE_HANDLE_DATABASE_PARENTS (
371 &ParentControllerHandleCount
,
374 Status
= ParseHandleDatabaseForChildControllers (
376 &ChildControllerHandleCount
,
379 if (DriverBindingHandleCount
> 0
380 || ParentControllerHandleCount
> 0
381 || ChildControllerHandleCount
> 0) {
383 Status
= gBS
->HandleProtocol (
385 &gEfiDevicePathProtocolGuid
,
388 if (EFI_ERROR (Status
)) {
389 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_HANDLE
), gShellBcfgHiiHandle
, L
"bcfg", HandleNumber
);
390 ShellStatus
= SHELL_INVALID_PARAMETER
;
394 //Make sure that the handle should point to driver, not a controller.
396 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
398 &DriverBindingHandleCount
,
401 Status
= PARSE_HANDLE_DATABASE_PARENTS (
403 &ParentControllerHandleCount
,
406 Status
= ParseHandleDatabaseForChildControllers (
408 &ChildControllerHandleCount
,
411 Status
= gBS
->HandleProtocol (
413 &gEfiDevicePathProtocolGuid
,
416 if (DriverBindingHandleCount
> 0
417 || ParentControllerHandleCount
> 0
418 || ChildControllerHandleCount
> 0
419 || !EFI_ERROR(Status
) ) {
420 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Handle Number");
421 ShellStatus
= SHELL_INVALID_PARAMETER
;
424 // Get the DevicePath from the loaded image information.
426 Status
= GetDevicePathForDriverHandle(CurHandle
, &FilePath
);
434 ShellOpenFileMetaArg ((CHAR16
*)File
, EFI_FILE_MODE_READ
, &FileList
);
436 if (FileList
== NULL
) {
438 // If filename matched nothing fail
440 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", File
);
441 ShellStatus
= SHELL_INVALID_PARAMETER
;
442 } else if (FileList
->Link
.ForwardLink
!= FileList
->Link
.BackLink
) {
444 // If filename expanded to multiple names, fail
446 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE
), gShellBcfgHiiHandle
, L
"bcfg", File
);
447 ShellStatus
= SHELL_INVALID_PARAMETER
;
449 Arg
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
);
450 if (EFI_ERROR(Arg
->Status
)) {
451 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_OPEN
), gShellBcfgHiiHandle
, L
"bcfg", File
);
452 ShellStatus
= SHELL_INVALID_PARAMETER
;
455 // Build FilePath to the filename
459 // get the device path
461 DevicePath
= gEfiShellProtocol
->GetDevicePathFromFilePath(Arg
->FullName
);
462 if (DevicePath
== NULL
) {
463 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_DP
), gShellBcfgHiiHandle
, L
"bcfg", Arg
->FullName
);
464 ShellStatus
= SHELL_UNSUPPORTED
;
467 DevPath
= DevicePath
;
468 ShellStatus
= SHELL_INVALID_PARAMETER
;
469 while (!IsDevicePathEnd(DevPath
)) {
470 if ((DevicePathType(DevPath
) == MEDIA_DEVICE_PATH
) &&
471 (DevicePathSubType(DevPath
) == MEDIA_HARDDRIVE_DP
)) {
474 // If we find it use it instead
476 ShellStatus
= SHELL_SUCCESS
;
477 FilePath
= DuplicateDevicePath (DevPath
);
480 DevPath
= NextDevicePathNode(DevPath
);
483 FilePath
= DuplicateDevicePath(DevicePath
);
485 FreePool(DevicePath
);
492 if (ShellStatus
== SHELL_SUCCESS
) {
494 // Find a free target ,a brute force implementation
497 for (TargetLocation
=0; TargetLocation
< 0xFFFF; TargetLocation
++) {
499 for (Index
=0; Index
< OrderCount
; Index
++) {
500 if (CurrentOrder
[Index
] == TargetLocation
) {
511 if (TargetLocation
== 0xFFFF) {
512 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET_NF
), gShellBcfgHiiHandle
, L
"bcfg");
514 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET
), gShellBcfgHiiHandle
, TargetLocation
);
518 if (ShellStatus
== SHELL_SUCCESS
) {
522 DescSize
= StrSize(Desc
);
523 FilePathSize
= GetDevicePathSize (FilePath
);
525 TempByteBuffer
= AllocateZeroPool(sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
);
526 if (TempByteBuffer
!= NULL
) {
527 TempByteStart
= TempByteBuffer
;
528 *((UINT32
*) TempByteBuffer
) = LOAD_OPTION_ACTIVE
; // Attributes
529 TempByteBuffer
+= sizeof (UINT32
);
531 *((UINT16
*) TempByteBuffer
) = (UINT16
)FilePathSize
; // FilePathListLength
532 TempByteBuffer
+= sizeof (UINT16
);
534 CopyMem (TempByteBuffer
, Desc
, DescSize
);
535 TempByteBuffer
+= DescSize
;
536 ASSERT (FilePath
!= NULL
);
537 CopyMem (TempByteBuffer
, FilePath
, FilePathSize
);
539 UnicodeSPrint (OptionStr
, sizeof(OptionStr
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", TargetLocation
);
540 Status
= gRT
->SetVariable (
542 &gEfiGlobalVariableGuid
,
543 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
544 sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
,
548 FreePool(TempByteStart
);
550 Status
= EFI_OUT_OF_RESOURCES
;
553 if (EFI_ERROR(Status
)) {
554 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", OptionStr
);
556 NewOrder
= AllocateZeroPool ((OrderCount
+ 1) * sizeof (NewOrder
[0]));
557 if (NewOrder
!= NULL
) {
558 CopyMem (NewOrder
, CurrentOrder
, (OrderCount
) * sizeof (NewOrder
[0]));
561 // Insert target into order list
563 for (Index
= OrderCount
; Index
> Position
; Index
--) {
564 NewOrder
[Index
] = NewOrder
[Index
- 1];
567 NewOrder
[Position
] = (UINT16
) TargetLocation
;
568 Status
= gRT
->SetVariable (
569 Target
== BcfgTargetBootOrder
? L
"BootOrder" : L
"DriverOrder",
570 &gEfiGlobalVariableGuid
,
571 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
572 (OrderCount
+ 1) * sizeof (UINT16
),
578 if (EFI_ERROR (Status
)) {
579 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
? L
"BootOrder" : L
"DriverOrder");
580 ShellStatus
= SHELL_INVALID_PARAMETER
;
582 Print (L
"bcfg: Add %s as %x\n", OptionStr
, Position
);
589 //If always Free FilePath, will free devicepath in system when use "addh"
591 if (FilePath
!=NULL
&& !UseHandle
) {
599 if (Handles
!= NULL
) {
603 if (FileList
!= NULL
) {
604 ShellCloseFileMetaArg (&FileList
);
607 return (ShellStatus
);
611 Funciton to remove an item.
613 @param[in] Target The target item to move.
614 @param[in] CurrentOrder The pointer to the current order of items.
615 @param[in] OrderCount The number if items in CurrentOrder.
616 @param[in] Location The current location of the Target.
618 @retval SHELL_SUCCESS The operation was successful.
619 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
624 IN CONST BCFG_OPERATION_TARGET Target
,
625 IN CONST UINT16
*CurrentOrder
,
626 IN CONST UINTN OrderCount
,
627 IN CONST UINT16 Location
630 CHAR16 VariableName
[12];
635 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", CurrentOrder
[Location
]);
636 Status
= gRT
->SetVariable(
638 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
639 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
642 if (EFI_ERROR(Status
)) {
643 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
644 return (SHELL_INVALID_PARAMETER
);
646 NewOrder
= AllocateZeroPool(OrderCount
*sizeof(CurrentOrder
[0]));
647 if (NewOrder
!= NULL
) {
648 NewCount
= OrderCount
;
649 CopyMem(NewOrder
, CurrentOrder
, OrderCount
*sizeof(CurrentOrder
[0]));
650 CopyMem(NewOrder
+Location
, NewOrder
+Location
+1, (OrderCount
- Location
- 1)*sizeof(CurrentOrder
[0]));
653 Status
= gRT
->SetVariable(
654 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
655 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
656 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
657 NewCount
*sizeof(NewOrder
[0]),
661 Status
= EFI_OUT_OF_RESOURCES
;
663 if (EFI_ERROR(Status
)) {
664 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder");
665 return (SHELL_INVALID_PARAMETER
);
667 return (SHELL_SUCCESS
);
671 Funciton to move a item to another location.
673 @param[in] Target The target item to move.
674 @param[in] CurrentOrder The pointer to the current order of items.
675 @param[in] OrderCount The number if items in CurrentOrder.
676 @param[in] OldLocation The current location of the Target.
677 @param[in] NewLocation The desired location of the Target.
679 @retval SHELL_SUCCESS The operation was successful.
680 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
685 IN CONST BCFG_OPERATION_TARGET Target
,
686 IN CONST UINT16
*CurrentOrder
,
687 IN CONST UINTN OrderCount
,
688 IN CONST UINT16 OldLocation
,
689 IN UINT16 NewLocation
696 NewOrder
= AllocateCopyPool(OrderCount
*sizeof(CurrentOrder
[0]), CurrentOrder
);
697 if (NewOrder
== NULL
) {
698 return (SHELL_OUT_OF_RESOURCES
);
702 // correct the new location
704 if (NewLocation
>= OrderCount
) {
705 if (OrderCount
> 0) {
706 NewLocation
= (UINT16
)OrderCount
- 1;
712 Temp
= CurrentOrder
[OldLocation
];
713 CopyMem(NewOrder
+OldLocation
, NewOrder
+OldLocation
+1, (OrderCount
- OldLocation
- 1)*sizeof(CurrentOrder
[0]));
714 CopyMem(NewOrder
+NewLocation
+1, NewOrder
+NewLocation
, (OrderCount
- NewLocation
- 1)*sizeof(CurrentOrder
[0]));
715 NewOrder
[NewLocation
] = Temp
;
717 Status
= gRT
->SetVariable(
718 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
719 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
720 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
721 OrderCount
*sizeof(CurrentOrder
[0]),
726 if (EFI_ERROR(Status
)) {
727 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder");
728 return (SHELL_INVALID_PARAMETER
);
730 return (SHELL_SUCCESS
);
734 Function to add optional data to an option.
736 @param[in] OptData The optional data to add.
737 @param[in] CurrentOrder The pointer to the current order of items.
738 @param[in] OrderCount The number if items in CurrentOrder.
739 @param[in] Target The target of the operation.
741 @retval SHELL_SUCCESS The operation was succesful.
746 IN CONST CHAR16
*OptData
,
747 IN CONST UINT16
*CurrentOrder
,
748 IN CONST UINTN OrderCount
,
749 IN CONST BCFG_OPERATION_TARGET Target
752 EFI_KEY_OPTION NewKeyOption
;
753 EFI_KEY_OPTION
*KeyOptionBuffer
;
754 SHELL_STATUS ShellStatus
;
760 CONST CHAR16
*Walker
;
765 CHAR16 VariableName
[12];
768 SHELL_FILE_HANDLE FileHandle
;
770 Status
= EFI_SUCCESS
;
771 ShellStatus
= SHELL_SUCCESS
;
775 KeyOptionBuffer
= NULL
;
778 ZeroMem(&NewKeyOption
, sizeof(EFI_KEY_OPTION
));
779 ZeroMem(VariableName
, sizeof(VariableName
));
781 while(Walker
[0] == L
' ') {
786 // Get the index of the variable we are changing.
788 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
789 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
|| ((UINT16
)Intermediate
) > ((UINT16
)OrderCount
)) {
790 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Option Index");
791 ShellStatus
= SHELL_INVALID_PARAMETER
;
792 return (ShellStatus
);
794 OptionIndex
= (UINT16
)Intermediate
;
796 Temp
= StrStr(Walker
, L
" ");
800 while(Walker
[0] == L
' ') {
805 // determine whether we have file with data, quote delimited information, or a hot-key
807 if (Walker
[0] == L
'\"') {
809 // quoted filename or quoted information.
811 Temp
= StrStr(Walker
+1, L
"\"");
812 if (Temp
== NULL
|| StrLen(Temp
) != 1) {
813 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
814 ShellStatus
= SHELL_INVALID_PARAMETER
;
816 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
+1, 0);
817 if (FileName
== NULL
) {
818 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
819 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
820 return (ShellStatus
);
822 Temp2
= StrStr(FileName
, L
"\"");
823 ASSERT(Temp2
!= NULL
);
824 Temp2
[0] = CHAR_NULL
;
826 if (StrLen(Temp2
)>0) {
827 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
828 ShellStatus
= SHELL_INVALID_PARAMETER
;
830 if (EFI_ERROR(ShellFileExists(Walker
))) {
832 // Not a file. must be misc information.
837 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
, 0);
842 // filename or hot key information.
844 if (StrStr(Walker
, L
" ") == NULL
) {
848 if (EFI_ERROR(ShellFileExists(Walker
))) {
849 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FIND_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
850 ShellStatus
= SHELL_INVALID_PARAMETER
;
852 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
, 0);
855 if (Target
!= BcfgTargetBootOrder
) {
856 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_BOOT_ONLY
), gShellBcfgHiiHandle
, L
"bcfg");
857 ShellStatus
= SHELL_INVALID_PARAMETER
;
860 if (ShellStatus
== SHELL_SUCCESS
) {
862 // Get hot key information
864 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
865 if (EFI_ERROR(Status
) || (((UINT32
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
) {
866 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
867 ShellStatus
= SHELL_INVALID_PARAMETER
;
869 NewKeyOption
.KeyData
.PackedValue
= (UINT32
)Intermediate
;
870 Temp
= StrStr(Walker
, L
" ");
874 while(Walker
[0] == L
' ') {
879 if (ShellStatus
== SHELL_SUCCESS
) {
881 // Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.
882 // Re-allocate with the added information.
884 KeyOptionBuffer
= AllocateCopyPool(sizeof(EFI_KEY_OPTION
) + (sizeof(EFI_INPUT_KEY
) * NewKeyOption
.KeyData
.Options
.InputKeyCount
), &NewKeyOption
);
885 if (KeyOptionBuffer
== NULL
) {
886 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
887 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
890 for (LoopCounter
= 0 ; ShellStatus
== SHELL_SUCCESS
&& LoopCounter
< NewKeyOption
.KeyData
.Options
.InputKeyCount
; LoopCounter
++) {
894 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
895 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
) {
896 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
897 ShellStatus
= SHELL_INVALID_PARAMETER
;
899 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof(EFI_KEY_OPTION
)))[LoopCounter
].ScanCode
= (UINT16
)Intermediate
;
900 Temp
= StrStr(Walker
, L
" ");
904 while(Walker
[0] == L
' ') {
911 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
912 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
)) {
913 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
914 ShellStatus
= SHELL_INVALID_PARAMETER
;
916 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof(EFI_KEY_OPTION
)))[LoopCounter
].UnicodeChar
= (UINT16
)Intermediate
;
917 Temp
= StrStr(Walker
, L
" ");
921 while(Walker
[0] == L
' ') {
926 if (ShellStatus
== SHELL_SUCCESS
) {
928 // Now do the BootOption / BootOptionCrc
930 ASSERT (OptionIndex
<= OrderCount
);
931 KeyOptionBuffer
->BootOption
= CurrentOrder
[OptionIndex
];
932 Status
= GetBootOptionCrc(&(KeyOptionBuffer
->BootOptionCrc
), KeyOptionBuffer
->BootOption
);
933 if (EFI_ERROR(Status
)) {
934 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Option Index");
935 ShellStatus
= SHELL_INVALID_PARAMETER
;
939 if (ShellStatus
== SHELL_SUCCESS
) {
940 for (Temp2
= NULL
, KeyIndex
= 0 ; KeyIndex
<= 0xFFFF ; KeyIndex
++) {
941 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"Key%04x", KeyIndex
);
942 Status
= GetEfiGlobalVariable2 (VariableName
, &VariableData
, NULL
);
943 if (Status
== EFI_NOT_FOUND
) {
946 if (!EFI_ERROR(Status
)) {
947 SHELL_FREE_NON_NULL(VariableData
);
950 if (KeyIndex
<= 0xFFFF) {
951 Status
= gRT
->SetVariable(
953 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
954 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
955 sizeof(EFI_KEY_OPTION
) + (sizeof(EFI_INPUT_KEY
) * NewKeyOption
.KeyData
.Options
.InputKeyCount
),
957 if (EFI_ERROR(Status
)) {
958 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
959 ShellStatus
= SHELL_INVALID_PARAMETER
;
962 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_VAR_NO_NUM
), gShellBcfgHiiHandle
, L
"bcfg");
963 ShellStatus
= SHELL_INVALID_PARAMETER
;
965 ASSERT(FileName
== NULL
&& Data
== NULL
);
971 // Shouldn't be possible to have have both. Neither is ok though.
973 ASSERT(FileName
== NULL
|| Data
== NULL
);
975 if (ShellStatus
== SHELL_SUCCESS
&& (FileName
!= NULL
|| Data
!= NULL
)) {
976 if (FileName
!= NULL
) {
978 // Open the file and populate the data buffer.
980 Status
= ShellOpenFileByName(
985 if (!EFI_ERROR(Status
)) {
986 Status
= ShellGetFileSize(FileHandle
, &Intermediate
);
988 Data
= AllocateZeroPool((UINTN
)Intermediate
);
990 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
991 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
993 if (!EFI_ERROR(Status
)) {
994 Status
= ShellReadFile(FileHandle
, (UINTN
*)&Intermediate
, Data
);
997 Intermediate
= StrSize(Data
);
1000 if (!EFI_ERROR(Status
) && ShellStatus
== SHELL_SUCCESS
&& Data
!= NULL
) {
1001 Status
= UpdateOptionalData(CurrentOrder
[OptionIndex
], (UINTN
)Intermediate
, (UINT8
*)Data
, Target
);
1002 if (EFI_ERROR(Status
)) {
1003 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1004 ShellStatus
= SHELL_INVALID_PARAMETER
;
1007 if (EFI_ERROR(Status
) && ShellStatus
== SHELL_SUCCESS
) {
1008 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1009 ShellStatus
= SHELL_INVALID_PARAMETER
;
1013 SHELL_FREE_NON_NULL(Data
);
1014 SHELL_FREE_NON_NULL(KeyOptionBuffer
);
1015 SHELL_FREE_NON_NULL(FileName
);
1020 Function to dump the Bcfg information.
1022 @param[in] Op The operation.
1023 @param[in] OrderCount How many to dump.
1024 @param[in] CurrentOrder The pointer to the current order of items.
1025 @param[in] VerboseOutput TRUE for extra output. FALSE otherwise.
1027 @retval SHELL_SUCCESS The dump was successful.
1028 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
1033 IN CONST CHAR16
*Op
,
1034 IN CONST UINTN OrderCount
,
1035 IN CONST UINT16
*CurrentOrder
,
1036 IN CONST BOOLEAN VerboseOutput
1042 CHAR16 VariableName
[12];
1044 CHAR16
*DevPathString
;
1047 EFI_LOAD_OPTION
*LoadOption
;
1048 CHAR16
*Description
;
1049 UINTN DescriptionSize
;
1050 UINTN OptionalDataOffset
;
1052 if (OrderCount
== 0) {
1053 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_BCFG_NONE
), gShellBcfgHiiHandle
, L
"bcfg");
1054 return (SHELL_SUCCESS
);
1059 for (LoopVar
= 0 ; LoopVar
< OrderCount
; LoopVar
++) {
1062 DevPathString
= NULL
;
1064 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Op
, CurrentOrder
[LoopVar
]);
1066 Status
= gRT
->GetVariable(
1068 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1072 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1073 Buffer
= AllocateZeroPool(BufferSize
);
1074 Status
= gRT
->GetVariable(
1076 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1082 if (EFI_ERROR(Status
) || Buffer
== NULL
) {
1083 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_READ_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1089 // We expect the Attributes, FilePathListLength, and L'\0'-terminated
1090 // Description fields to be present.
1092 if (BufferSize
< sizeof *LoadOption
+ sizeof (CHAR16
)) {
1097 STRING_TOKEN (STR_BCFG_VAR_CORRUPT
),
1098 gShellBcfgHiiHandle
,
1106 LoadOption
= (EFI_LOAD_OPTION
*)Buffer
;
1107 Description
= (CHAR16
*)(Buffer
+ sizeof (EFI_LOAD_OPTION
));
1108 DescriptionSize
= StrSize (Description
);
1110 if (LoadOption
->FilePathListLength
!= 0) {
1111 FilePathList
= (UINT8
*)Description
+ DescriptionSize
;
1112 DevPathString
= ConvertDevicePathToText(FilePathList
, TRUE
, FALSE
);
1115 OptionalDataOffset
= sizeof *LoadOption
+ DescriptionSize
+
1116 LoadOption
->FilePathListLength
;
1122 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS
),
1123 gShellBcfgHiiHandle
,
1128 OptionalDataOffset
>= BufferSize
? L
'N' : L
'Y'
1130 if (VerboseOutput
&& (OptionalDataOffset
< BufferSize
)) {
1133 0, // Offset (displayed)
1134 BufferSize
- OptionalDataOffset
, // DataSize
1135 Buffer
+ OptionalDataOffset
// UserData
1140 if (Buffer
!= NULL
) {
1143 if (DevPathString
!= NULL
) {
1144 FreePool(DevPathString
);
1147 return (Errors
> 0) ? SHELL_INVALID_PARAMETER
: SHELL_SUCCESS
;
1151 Function to initialize the BCFG operation structure.
1153 @param[in] Struct The stuct to initialize.
1158 IN BGFG_OPERATION
*Struct
1161 ASSERT(Struct
!= NULL
);
1162 Struct
->Target
= BcfgTargetMax
;
1163 Struct
->Type
= BcfgTypeMax
;
1164 Struct
->Number1
= 0;
1165 Struct
->Number2
= 0;
1166 Struct
->HandleIndex
= 0;
1167 Struct
->FileName
= NULL
;
1168 Struct
->Description
= NULL
;
1169 Struct
->Order
= NULL
;
1170 Struct
->OptData
= NULL
;
1174 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
1176 {L
"-opt", TypeMaxValue
},
1181 Function for 'bcfg' command.
1183 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1184 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1188 ShellCommandRunBcfg (
1189 IN EFI_HANDLE ImageHandle
,
1190 IN EFI_SYSTEM_TABLE
*SystemTable
1194 LIST_ENTRY
*Package
;
1195 CHAR16
*ProblemParam
;
1196 SHELL_STATUS ShellStatus
;
1198 CONST CHAR16
*CurrentParam
;
1199 BGFG_OPERATION CurrentOperation
;
1201 UINT64 Intermediate
;
1205 ProblemParam
= NULL
;
1207 ShellStatus
= SHELL_SUCCESS
;
1209 InitBcfgStruct(&CurrentOperation
);
1212 // initialize the shell lib (we must be in non-auto-init...)
1214 Status
= ShellInitialize();
1215 ASSERT_EFI_ERROR(Status
);
1217 Status
= CommandInit();
1218 ASSERT_EFI_ERROR(Status
);
1221 // parse the command line
1223 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
1224 if (EFI_ERROR(Status
)) {
1225 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
1226 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, L
"bcfg", ProblemParam
);
1227 FreePool(ProblemParam
);
1228 ShellStatus
= SHELL_INVALID_PARAMETER
;
1234 // Read in if we are doing -OPT
1236 if (ShellCommandLineGetFlag(Package
, L
"-opt")) {
1237 CurrentOperation
.OptData
= ShellCommandLineGetValue(Package
, L
"-opt");
1238 if (CurrentOperation
.OptData
== NULL
) {
1239 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellBcfgHiiHandle
, L
"bcfg", L
"-opt");
1240 ShellStatus
= SHELL_INVALID_PARAMETER
;
1242 CurrentOperation
.Type
= BcfgTypeOpt
;
1246 // small block to read the target of the operation
1248 if ((ShellCommandLineGetCount(Package
) < 3 && CurrentOperation
.Type
!= BcfgTypeOpt
) ||
1249 (ShellCommandLineGetCount(Package
) < 2 && CurrentOperation
.Type
== BcfgTypeOpt
)
1251 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1252 ShellStatus
= SHELL_INVALID_PARAMETER
;
1253 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"driver") == 0) {
1254 CurrentOperation
.Target
= BcfgTargetDriverOrder
;
1255 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"boot") == 0) {
1256 CurrentOperation
.Target
= BcfgTargetBootOrder
;
1258 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT
), gShellBcfgHiiHandle
, L
"bcfg");
1259 ShellStatus
= SHELL_INVALID_PARAMETER
;
1264 // Read in the boot or driver order environment variable (not needed for opt)
1266 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
1268 Status
= gRT
->GetVariable(
1269 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
1270 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1273 CurrentOperation
.Order
);
1274 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1275 CurrentOperation
.Order
= AllocateZeroPool(Length
+(4*sizeof(CurrentOperation
.Order
[0])));
1276 if (CurrentOperation
.Order
== NULL
) {
1277 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1279 Status
= gRT
->GetVariable(
1280 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
1281 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1284 CurrentOperation
.Order
);
1289 Count
= (UINT16
) (Length
/ sizeof(CurrentOperation
.Order
[0]));
1292 // large block to read the type of operation and verify parameter types for the info.
1294 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
1295 for (ParamNumber
= 2 ; ParamNumber
< ShellCommandLineGetCount(Package
) && ShellStatus
== SHELL_SUCCESS
; ParamNumber
++) {
1296 CurrentParam
= ShellCommandLineGetRawValue(Package
, ParamNumber
);
1297 if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"dump") == 0) {
1298 CurrentOperation
.Type
= BcfgTypeDump
;
1299 if (ShellCommandLineGetCount(Package
) > 3) {
1300 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellBcfgHiiHandle
, L
"bcfg");
1301 ShellStatus
= SHELL_INVALID_PARAMETER
;
1303 } else if (ShellCommandLineGetFlag(Package
, L
"-v")) {
1304 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"-v (without dump)");
1305 ShellStatus
= SHELL_INVALID_PARAMETER
;
1306 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"add") == 0) {
1307 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1308 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1309 ShellStatus
= SHELL_INVALID_PARAMETER
;
1311 CurrentOperation
.Type
= BcfgTypeAdd
;
1312 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1313 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1314 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1315 ShellStatus
= SHELL_INVALID_PARAMETER
;
1317 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1318 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1319 ASSERT(CurrentOperation
.FileName
== NULL
);
1320 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1321 ASSERT(CurrentOperation
.Description
== NULL
);
1322 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1324 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addp") == 0) {
1325 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1326 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1327 ShellStatus
= SHELL_INVALID_PARAMETER
;
1329 CurrentOperation
.Type
= BcfgTypeAddp
;
1330 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1331 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1332 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1333 ShellStatus
= SHELL_INVALID_PARAMETER
;
1335 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1336 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1337 ASSERT(CurrentOperation
.FileName
== NULL
);
1338 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1339 ASSERT(CurrentOperation
.Description
== NULL
);
1340 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1342 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addh") == 0) {
1343 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1344 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1345 ShellStatus
= SHELL_INVALID_PARAMETER
;
1347 CurrentOperation
.Type
= BcfgTypeAddh
;
1348 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1349 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1350 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1351 ShellStatus
= SHELL_INVALID_PARAMETER
;
1353 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1354 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1355 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1356 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1357 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1358 ShellStatus
= SHELL_INVALID_PARAMETER
;
1360 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1361 CurrentOperation
.HandleIndex
= (UINT16
)Intermediate
;
1362 ASSERT(CurrentOperation
.Description
== NULL
);
1363 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1366 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"rm") == 0) {
1367 if ((ParamNumber
+ 1) >= ShellCommandLineGetCount(Package
)) {
1368 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1369 ShellStatus
= SHELL_INVALID_PARAMETER
;
1371 CurrentOperation
.Type
= BcfgTypeRm
;
1372 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1373 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1374 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1375 ShellStatus
= SHELL_INVALID_PARAMETER
;
1377 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1378 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1379 if (CurrentOperation
.Number1
>= Count
){
1380 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1381 ShellStatus
= SHELL_INVALID_PARAMETER
;
1384 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"mv") == 0) {
1385 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount(Package
)) {
1386 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1387 ShellStatus
= SHELL_INVALID_PARAMETER
;
1389 CurrentOperation
.Type
= BcfgTypeMv
;
1390 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1391 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1392 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1393 ShellStatus
= SHELL_INVALID_PARAMETER
;
1395 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1396 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1397 if (CurrentOperation
.Number1
>= Count
){
1398 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1399 ShellStatus
= SHELL_INVALID_PARAMETER
;
1401 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1402 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1403 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1404 ShellStatus
= SHELL_INVALID_PARAMETER
;
1406 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1407 CurrentOperation
.Number2
= (UINT16
)Intermediate
;
1409 if (CurrentOperation
.Number2
== CurrentOperation
.Number1
1410 ||CurrentOperation
.Number2
>= Count
1412 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1413 ShellStatus
= SHELL_INVALID_PARAMETER
;
1418 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1419 ShellStatus
= SHELL_INVALID_PARAMETER
;
1423 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
&& CurrentOperation
.Type
< BcfgTypeMax
) {
1425 // we have all the info. Do the work
1427 switch (CurrentOperation
.Type
) {
1429 ShellStatus
= BcfgDisplayDump(
1430 CurrentOperation
.Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver",
1432 CurrentOperation
.Order
,
1433 ShellCommandLineGetFlag(Package
, L
"-v"));
1436 ShellStatus
= BcfgMove(
1437 CurrentOperation
.Target
,
1438 CurrentOperation
.Order
,
1440 CurrentOperation
.Number1
,
1441 CurrentOperation
.Number2
);
1444 ShellStatus
= BcfgRemove(
1445 CurrentOperation
.Target
,
1446 CurrentOperation
.Order
,
1448 CurrentOperation
.Number1
);
1453 ShellStatus
= BcfgAdd(
1454 CurrentOperation
.Number1
,
1455 CurrentOperation
.FileName
,
1456 CurrentOperation
.Description
==NULL
?L
"":CurrentOperation
.Description
,
1457 CurrentOperation
.Order
,
1459 CurrentOperation
.Target
,
1460 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddh
),
1461 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddp
),
1462 CurrentOperation
.HandleIndex
);
1465 ShellStatus
= BcfgAddOpt(
1466 CurrentOperation
.OptData
,
1467 CurrentOperation
.Order
,
1469 CurrentOperation
.Target
);
1477 if (Package
!= NULL
) {
1478 ShellCommandLineFreeVarList (Package
);
1480 if (CurrentOperation
.FileName
!= NULL
) {
1481 FreePool(CurrentOperation
.FileName
);
1483 if (CurrentOperation
.Description
!= NULL
) {
1484 FreePool(CurrentOperation
.Description
);
1486 if (CurrentOperation
.Order
!= NULL
) {
1487 FreePool(CurrentOperation
.Order
);
1490 return (ShellStatus
);
1495 Function to get the filename with help context if HII will not be used.
1497 @return The filename with help text in it.
1501 ShellCommandGetManFileNameBcfg (
1509 "Constructor" for the library.
1511 This will register the handler for the bcfg command.
1513 @param[in] ImageHandle the image handle of the process
1514 @param[in] SystemTable the EFI System Table pointer
1515 @param[in] Name the profile name to use
1517 @retval EFI_SUCCESS the shell command handlers were installed sucessfully
1518 @retval EFI_UNSUPPORTED the shell level required was not found.
1522 BcfgLibraryRegisterBcfgCommand (
1523 IN EFI_HANDLE ImageHandle
,
1524 IN EFI_SYSTEM_TABLE
*SystemTable
,
1525 IN CONST CHAR16
*Name
1528 if (gShellBcfgHiiHandle
!= NULL
) {
1529 return (EFI_SUCCESS
);
1532 gShellBcfgHiiHandle
= HiiAddPackages (&gShellBcfgHiiGuid
, gImageHandle
, UefiShellBcfgCommandLibStrings
, NULL
);
1533 if (gShellBcfgHiiHandle
== NULL
) {
1534 return (EFI_DEVICE_ERROR
);
1538 // install our shell command handler
1540 ShellCommandRegisterCommandName(L
"bcfg", ShellCommandRunBcfg
, ShellCommandGetManFileNameBcfg
, 0, Name
, FALSE
, gShellBcfgHiiHandle
, STRING_TOKEN(STR_GET_HELP_BCFG
));
1542 return (EFI_SUCCESS
);
1546 Destructor for the library. free any resources.
1548 @param ImageHandle The image handle of the process.
1549 @param SystemTable The EFI System Table pointer.
1553 BcfgLibraryUnregisterBcfgCommand (
1554 IN EFI_HANDLE ImageHandle
,
1555 IN EFI_SYSTEM_TABLE
*SystemTable
1558 if (gShellBcfgHiiHandle
!= NULL
) {
1559 HiiRemovePackages(gShellBcfgHiiHandle
);
1561 gShellBcfgHiiHandle
= NULL
;
1562 return (EFI_SUCCESS
);