2 Main file for BCFG command.
4 Copyright (c) 2010 - 2014, 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.
17 #include <ShellBase.h>
19 #include <Guid/GlobalVariable.h>
20 #include <Guid/ShellLibHiiGuid.h>
22 #include <Protocol/EfiShell.h>
23 #include <Protocol/EfiShellParameters.h>
24 #include <Protocol/DevicePath.h>
25 #include <Protocol/LoadedImage.h>
26 #include <Protocol/UnicodeCollation.h>
28 #include <Library/BaseLib.h>
29 #include <Library/BaseMemoryLib.h>
30 #include <Library/DebugLib.h>
31 #include <Library/MemoryAllocationLib.h>
32 #include <Library/PcdLib.h>
33 #include <Library/ShellCommandLib.h>
34 #include <Library/ShellLib.h>
35 #include <Library/SortLib.h>
36 #include <Library/UefiLib.h>
37 #include <Library/UefiRuntimeServicesTableLib.h>
38 #include <Library/UefiBootServicesTableLib.h>
39 #include <Library/HiiLib.h>
40 #include <Library/FileHandleLib.h>
41 #include <Library/PrintLib.h>
42 #include <Library/HandleParsingLib.h>
43 #include <Library/DevicePathLib.h>
45 STATIC CONST CHAR16 mFileName
[] = L
"ShellCommands";
46 STATIC EFI_HANDLE gShellBcfgHiiHandle
= NULL
;
49 BcfgTargetBootOrder
= 0,
50 BcfgTargetDriverOrder
= 1,
52 } BCFG_OPERATION_TARGET
;
63 } BCFG_OPERATION_TYPE
;
66 BCFG_OPERATION_TARGET Target
;
67 BCFG_OPERATION_TYPE Type
;
74 CONST CHAR16
*OptData
;
78 Update the optional data for a boot or driver option.
80 If optional data exists it will be changed.
82 @param[in] Index The boot or driver option index update.
83 @param[in] DataSize The size in bytes of Data.
84 @param[in] Data The buffer for the optioanl data.
85 @param[in] Target The target of the operation.
87 @retval EFI_SUCCESS The data was sucessfully updated.
88 @retval other A error occured.
96 IN CONST BCFG_OPERATION_TARGET Target
100 CHAR16 VariableName
[12];
105 UINTN OriginalOptionDataSize
;
107 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", Index
);
114 Status
= gRT
->GetVariable(
116 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
120 if (Status
== EFI_BUFFER_TOO_SMALL
) {
121 OriginalData
= AllocateZeroPool(OriginalSize
);
122 if (OriginalData
== NULL
) {
123 return (EFI_OUT_OF_RESOURCES
);
125 Status
= gRT
->GetVariable(
127 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
133 if (!EFI_ERROR(Status
)) {
135 // Allocate new struct and discard old optional data.
137 ASSERT (OriginalData
!= NULL
);
138 OriginalOptionDataSize
= sizeof(UINT32
) + sizeof(UINT16
) + StrSize(((CHAR16
*)(OriginalData
+ sizeof(UINT32
) + sizeof(UINT16
))));
139 OriginalOptionDataSize
+= (*(UINT16
*)(OriginalData
+ sizeof(UINT32
)));
140 OriginalOptionDataSize
-= OriginalSize
;
141 NewSize
= OriginalSize
- OriginalOptionDataSize
+ DataSize
;
142 NewData
= AllocateCopyPool(NewSize
, OriginalData
);
143 if (NewData
== NULL
) {
144 Status
= EFI_OUT_OF_RESOURCES
;
146 CopyMem(NewData
+ OriginalSize
- OriginalOptionDataSize
, Data
, DataSize
);
150 if (!EFI_ERROR(Status
)) {
152 // put the data back under the variable
154 Status
= gRT
->SetVariable(
156 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
157 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
162 SHELL_FREE_NON_NULL(OriginalData
);
163 SHELL_FREE_NON_NULL(NewData
);
168 This function will get a CRC for a boot option.
170 @param[in, out] Crc The CRC value to return.
171 @param[in] BootIndex The boot option index to CRC.
173 @retval EFI_SUCCESS The CRC was sucessfully returned.
174 @retval other A error occured.
183 CHAR16 VariableName
[12];
192 // Get the data Buffer
194 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%Boot%04x", BootIndex
);
195 Status
= gRT
->GetVariable(
197 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
201 if (Status
== EFI_BUFFER_TOO_SMALL
) {
202 Buffer
= AllocateZeroPool(BufferSize
);
203 Status
= gRT
->GetVariable(
205 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
212 // Get the CRC computed
214 if (!EFI_ERROR(Status
)) {
215 Status
= gBS
->CalculateCrc32 (Buffer
, BufferSize
, Crc
);
218 SHELL_FREE_NON_NULL(Buffer
);
223 This function will populate the device path protocol parameter based on TheHandle.
225 @param[in] TheHandle Driver handle.
226 @param[in, out] FilePath On a sucessful return the device path to the handle.
228 @retval EFI_SUCCESS The device path was sucessfully returned.
229 @retval other A error from gBS->HandleProtocol.
235 GetDevicePathForDriverHandle (
236 IN EFI_HANDLE TheHandle
,
237 IN OUT EFI_DEVICE_PATH_PROTOCOL
**FilePath
241 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
242 EFI_DEVICE_PATH_PROTOCOL
*ImageDevicePath
;
244 Status
= gBS
->OpenProtocol (
246 &gEfiLoadedImageProtocolGuid
,
247 (VOID
**)&LoadedImage
,
250 EFI_OPEN_PROTOCOL_GET_PROTOCOL
252 if (!EFI_ERROR (Status
)) {
253 Status
= gBS
->OpenProtocol (
254 LoadedImage
->DeviceHandle
,
255 &gEfiDevicePathProtocolGuid
,
256 (VOID
**)&ImageDevicePath
,
259 EFI_OPEN_PROTOCOL_GET_PROTOCOL
261 if (!EFI_ERROR (Status
)) {
262 // *DevPath = DuplicateDevicePath (ImageDevicePath);
263 // *FilePath = DuplicateDevicePath (LoadedImage->FilePath);
264 *FilePath
= AppendDevicePath(ImageDevicePath
,LoadedImage
->FilePath
);
266 LoadedImage
->DeviceHandle
,
267 &gEfiDevicePathProtocolGuid
,
273 &gEfiLoadedImageProtocolGuid
,
281 Function to add a option.
283 @param[in] Position The position to add Target at.
284 @param[in] File The file to make the target.
285 @param[in] Desc The description text.
286 @param[in] CurrentOrder The pointer to the current order of items.
287 @param[in] OrderCount The number if items in CurrentOrder.
288 @param[in] Target The info on the option to add.
289 @param[in] UseHandle TRUE to use HandleNumber, FALSE to use File and Desc.
290 @param[in] UsePath TRUE to convert to devicepath.
291 @param[in] HandleNumber The handle number to add.
293 @retval SHELL_SUCCESS The operation was successful.
294 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
300 IN CONST CHAR16
*File
,
301 IN CONST CHAR16
*Desc
,
302 IN CONST UINT16
*CurrentOrder
,
303 IN CONST UINTN OrderCount
,
304 IN CONST BCFG_OPERATION_TARGET Target
,
305 IN CONST BOOLEAN UseHandle
,
306 IN CONST BOOLEAN UsePath
,
307 IN CONST UINTN HandleNumber
311 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
312 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
314 UINT8
*TempByteBuffer
;
315 UINT8
*TempByteStart
;
316 EFI_SHELL_FILE_INFO
*Arg
;
317 EFI_SHELL_FILE_INFO
*FileList
;
318 CHAR16 OptionStr
[40];
319 UINTN DescSize
, FilePathSize
;
321 UINTN TargetLocation
;
324 EFI_HANDLE CurHandle
;
325 UINTN DriverBindingHandleCount
;
326 UINTN ParentControllerHandleCount
;
327 UINTN ChildControllerHandleCount
;
328 SHELL_STATUS ShellStatus
;
332 if (File
== NULL
|| Desc
== NULL
) {
333 return (SHELL_INVALID_PARAMETER
);
336 if (HandleNumber
== 0) {
337 return (SHELL_INVALID_PARAMETER
);
341 if (Position
> OrderCount
) {
342 Position
= OrderCount
;
349 ShellStatus
= SHELL_SUCCESS
;
350 TargetLocation
= 0xFFFF;
353 CurHandle
= ConvertHandleIndexToHandle(HandleNumber
);
354 if (CurHandle
== NULL
) {
355 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, L
"Handle Number");
356 ShellStatus
= SHELL_INVALID_PARAMETER
;
358 if (Target
== BcfgTargetBootOrder
) {
360 //Make sure that the handle should point to a real controller
362 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
364 &DriverBindingHandleCount
,
367 Status
= PARSE_HANDLE_DATABASE_PARENTS (
369 &ParentControllerHandleCount
,
372 Status
= ParseHandleDatabaseForChildControllers (
374 &ChildControllerHandleCount
,
377 if (DriverBindingHandleCount
> 0
378 || ParentControllerHandleCount
> 0
379 || ChildControllerHandleCount
> 0) {
381 Status
= gBS
->HandleProtocol (
383 &gEfiDevicePathProtocolGuid
,
386 if (EFI_ERROR (Status
)) {
387 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_HANDLE
), gShellBcfgHiiHandle
, HandleNumber
);
388 ShellStatus
= SHELL_INVALID_PARAMETER
;
392 //Make sure that the handle should point to driver, not a controller.
394 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
396 &DriverBindingHandleCount
,
399 Status
= PARSE_HANDLE_DATABASE_PARENTS (
401 &ParentControllerHandleCount
,
404 Status
= ParseHandleDatabaseForChildControllers (
406 &ChildControllerHandleCount
,
409 Status
= gBS
->HandleProtocol (
411 &gEfiDevicePathProtocolGuid
,
414 if (DriverBindingHandleCount
> 0
415 || ParentControllerHandleCount
> 0
416 || ChildControllerHandleCount
> 0
417 || !EFI_ERROR(Status
) ) {
418 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, L
"Handle Number");
419 ShellStatus
= SHELL_INVALID_PARAMETER
;
422 // Get the DevicePath from the loaded image information.
424 Status
= GetDevicePathForDriverHandle(CurHandle
, &FilePath
);
432 ShellOpenFileMetaArg ((CHAR16
*)File
, EFI_FILE_MODE_READ
, &FileList
);
434 if (FileList
== NULL
) {
436 // If filename matched nothing fail
438 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellBcfgHiiHandle
, File
);
439 ShellStatus
= SHELL_INVALID_PARAMETER
;
440 } else if (FileList
->Link
.ForwardLink
!= FileList
->Link
.BackLink
) {
442 // If filename expanded to multiple names, fail
444 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE
), gShellBcfgHiiHandle
, File
);
445 ShellStatus
= SHELL_INVALID_PARAMETER
;
447 Arg
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
);
448 if (EFI_ERROR(Arg
->Status
)) {
449 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_OPEN
), gShellBcfgHiiHandle
, File
, Arg
->Status
);
450 ShellStatus
= SHELL_INVALID_PARAMETER
;
453 // Build FilePath to the filename
457 // get the device path
459 DevicePath
= gEfiShellProtocol
->GetDevicePathFromFilePath(Arg
->FullName
);
460 if (DevicePath
== NULL
) {
461 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_DP
), gShellBcfgHiiHandle
, Arg
->FullName
);
462 ShellStatus
= SHELL_UNSUPPORTED
;
466 DevPath = DevicePath;
467 while (!IsDevicePathEnd(DevPath)) {
468 if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&
469 (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {
472 // If we find it use it instead
474 DevicePath = DevPath;
477 DevPath = NextDevicePathNode(DevPath);
482 for(StringWalker=Arg->FullName; *StringWalker != CHAR_NULL && *StringWalker != ':'; StringWalker++);
483 FileNode = FileDevicePath(NULL, StringWalker+1);
484 FilePath = AppendDevicePath(DevicePath, FileNode);
488 FilePath
= DuplicateDevicePath(DevicePath
);
492 FreePool(DevicePath
);
499 if (ShellStatus
== SHELL_SUCCESS
) {
501 // Find a free target ,a brute force implementation
504 for (TargetLocation
=0; TargetLocation
< 0xFFFF; TargetLocation
++) {
506 for (Index
=0; Index
< OrderCount
; Index
++) {
507 if (CurrentOrder
[Index
] == TargetLocation
) {
518 if (TargetLocation
== 0xFFFF) {
519 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET_NF
), gShellBcfgHiiHandle
);
521 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET
), gShellBcfgHiiHandle
, TargetLocation
);
525 if (ShellStatus
== SHELL_SUCCESS
) {
529 DescSize
= StrSize(Desc
);
530 FilePathSize
= GetDevicePathSize (FilePath
);
532 TempByteBuffer
= AllocateZeroPool(sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
);
533 if (TempByteBuffer
!= NULL
) {
534 TempByteStart
= TempByteBuffer
;
535 *((UINT32
*) TempByteBuffer
) = LOAD_OPTION_ACTIVE
; // Attributes
536 TempByteBuffer
+= sizeof (UINT32
);
538 *((UINT16
*) TempByteBuffer
) = (UINT16
)FilePathSize
; // FilePathListLength
539 TempByteBuffer
+= sizeof (UINT16
);
541 CopyMem (TempByteBuffer
, Desc
, DescSize
);
542 TempByteBuffer
+= DescSize
;
543 ASSERT (FilePath
!= NULL
);
544 CopyMem (TempByteBuffer
, FilePath
, FilePathSize
);
546 UnicodeSPrint (OptionStr
, sizeof(OptionStr
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", TargetLocation
);
547 Status
= gRT
->SetVariable (
549 &gEfiGlobalVariableGuid
,
550 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
551 sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
,
555 FreePool(TempByteStart
);
557 Status
= EFI_OUT_OF_RESOURCES
;
560 if (EFI_ERROR(Status
)) {
561 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, OptionStr
, Status
);
563 NewOrder
= AllocateZeroPool((OrderCount
+1)*sizeof(NewOrder
[0]));
564 ASSERT(NewOrder
!= NULL
);
565 CopyMem(NewOrder
, CurrentOrder
, (OrderCount
)*sizeof(NewOrder
[0]));
568 // Insert target into order list
570 for (Index
=OrderCount
; Index
> Position
; Index
--) {
571 NewOrder
[Index
] = NewOrder
[Index
-1];
574 NewOrder
[Position
] = (UINT16
) TargetLocation
;
575 Status
= gRT
->SetVariable (
576 Target
== BcfgTargetBootOrder
?L
"BootOrder":L
"DriverOrder",
577 &gEfiGlobalVariableGuid
,
578 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
579 (OrderCount
+1) * sizeof(UINT16
),
585 if (EFI_ERROR(Status
)) {
586 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, Target
== BcfgTargetBootOrder
?L
"BootOrder":L
"DriverOrder", Status
);
587 ShellStatus
= SHELL_INVALID_PARAMETER
;
589 Print (L
"bcfg: Add %s as %x\n", OptionStr
, Position
);
595 //If always Free FilePath, will free devicepath in system when use "addh"
597 if (FilePath
!=NULL
&& !UseHandle
) {
605 if (Handles
!= NULL
) {
609 if (FileList
!= NULL
) {
610 ShellCloseFileMetaArg (&FileList
);
613 return (ShellStatus
);
617 Funciton to remove an item.
619 @param[in] Target The target item to move.
620 @param[in] CurrentOrder The pointer to the current order of items.
621 @param[in] OrderCount The number if items in CurrentOrder.
622 @param[in] Location The current location of the Target.
624 @retval SHELL_SUCCESS The operation was successful.
625 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
630 IN CONST BCFG_OPERATION_TARGET Target
,
631 IN CONST UINT16
*CurrentOrder
,
632 IN CONST UINTN OrderCount
,
633 IN CONST UINT16 Location
636 CHAR16 VariableName
[12];
641 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", CurrentOrder
[Location
]);
642 Status
= gRT
->SetVariable(
644 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
645 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
648 if (EFI_ERROR(Status
)) {
649 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, VariableName
, Status
);
650 return (SHELL_INVALID_PARAMETER
);
652 NewOrder
= AllocateZeroPool(OrderCount
*sizeof(CurrentOrder
[0]));
653 if (NewOrder
!= NULL
) {
654 NewCount
= OrderCount
;
655 CopyMem(NewOrder
, CurrentOrder
, OrderCount
*sizeof(CurrentOrder
[0]));
656 CopyMem(NewOrder
+Location
, NewOrder
+Location
+1, (OrderCount
- Location
- 1)*sizeof(CurrentOrder
[0]));
659 Status
= gRT
->SetVariable(
660 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
661 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
662 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
663 NewCount
*sizeof(NewOrder
[0]),
667 Status
= EFI_OUT_OF_RESOURCES
;
669 if (EFI_ERROR(Status
)) {
670 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder", Status
);
671 return (SHELL_INVALID_PARAMETER
);
673 return (SHELL_SUCCESS
);
677 Funciton to move a item to another location.
679 @param[in] Target The target item to move.
680 @param[in] CurrentOrder The pointer to the current order of items.
681 @param[in] OrderCount The number if items in CurrentOrder.
682 @param[in] OldLocation The current location of the Target.
683 @param[in] NewLocation The desired location of the Target.
685 @retval SHELL_SUCCESS The operation was successful.
686 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
691 IN CONST BCFG_OPERATION_TARGET Target
,
692 IN CONST UINT16
*CurrentOrder
,
693 IN CONST UINTN OrderCount
,
694 IN CONST UINT16 OldLocation
,
695 IN UINT16 NewLocation
702 NewOrder
= AllocateCopyPool(OrderCount
*sizeof(CurrentOrder
[0]), CurrentOrder
);
703 if (NewOrder
== NULL
) {
704 return (SHELL_OUT_OF_RESOURCES
);
708 // correct the new location
710 if (NewLocation
>= OrderCount
) {
711 if (OrderCount
> 0) {
712 NewLocation
= (UINT16
)OrderCount
- 1;
718 Temp
= CurrentOrder
[OldLocation
];
719 CopyMem(NewOrder
+OldLocation
, NewOrder
+OldLocation
+1, (OrderCount
- OldLocation
- 1)*sizeof(CurrentOrder
[0]));
720 CopyMem(NewOrder
+NewLocation
+1, NewOrder
+NewLocation
, (OrderCount
- NewLocation
- 1)*sizeof(CurrentOrder
[0]));
721 NewOrder
[NewLocation
] = Temp
;
723 Status
= gRT
->SetVariable(
724 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
725 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
726 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
727 OrderCount
*sizeof(CurrentOrder
[0]),
732 if (EFI_ERROR(Status
)) {
733 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder", Status
);
734 return (SHELL_INVALID_PARAMETER
);
736 return (SHELL_SUCCESS
);
740 Function to add optional data to an option.
742 @param[in] OptData The optional data to add.
743 @param[in] CurrentOrder The pointer to the current order of items.
744 @param[in] OrderCount The number if items in CurrentOrder.
745 @param[in] Target The target of the operation.
747 @retval SHELL_SUCCESS The operation was succesful.
752 IN CONST CHAR16
*OptData
,
753 IN CONST UINT16
*CurrentOrder
,
754 IN CONST UINTN OrderCount
,
755 IN CONST BCFG_OPERATION_TARGET Target
758 EFI_KEY_OPTION NewKeyOption
;
759 EFI_KEY_OPTION
*KeyOptionBuffer
;
760 SHELL_STATUS ShellStatus
;
766 CONST CHAR16
*Walker
;
771 CHAR16 VariableName
[12];
773 SHELL_FILE_HANDLE FileHandle
;
775 Status
= EFI_SUCCESS
;
776 ShellStatus
= SHELL_SUCCESS
;
780 KeyOptionBuffer
= NULL
;
782 ZeroMem(&NewKeyOption
, sizeof(EFI_KEY_OPTION
));
784 while(Walker
[0] == L
' ') {
789 // Get the index of the variable we are changing.
791 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
792 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
|| ((UINT16
)Intermediate
) > ((UINT16
)OrderCount
)) {
793 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, L
"Option Index");
794 ShellStatus
= SHELL_INVALID_PARAMETER
;
795 return (ShellStatus
);
797 OptionIndex
= (UINT16
)Intermediate
;
799 Temp
= StrStr(Walker
, L
" ");
803 while(Walker
[0] == L
' ') {
808 // determine whether we have file with data, quote delimited information, or a hot-key
810 if (Walker
[0] == L
'\"') {
812 // quoted filename or quoted information.
814 Temp
= StrStr(Walker
+1, L
"\"");
815 if (Temp
== NULL
|| StrLen(Temp
) != 1) {
816 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, Walker
);
817 ShellStatus
= SHELL_INVALID_PARAMETER
;
819 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
+1, 0);
820 if (FileName
== NULL
) {
821 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellBcfgHiiHandle
);
822 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
823 return (ShellStatus
);
825 Temp2
= StrStr(FileName
, L
"\"");
826 ASSERT(Temp2
!= NULL
);
827 Temp2
[0] = CHAR_NULL
;
829 if (StrLen(Temp2
)>0) {
830 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, Walker
);
831 ShellStatus
= SHELL_INVALID_PARAMETER
;
833 if (EFI_ERROR(ShellFileExists(Walker
))) {
835 // Not a file. must be misc information.
840 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
, 0);
845 // filename or hot key information.
847 if (StrStr(Walker
, L
" ") == NULL
) {
851 if (EFI_ERROR(ShellFileExists(Walker
))) {
852 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FIND_FAIL
), gShellBcfgHiiHandle
, Walker
);
853 ShellStatus
= SHELL_INVALID_PARAMETER
;
855 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
, 0);
858 if (Target
!= BcfgTargetBootOrder
) {
859 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_BOOT_ONLY
), gShellBcfgHiiHandle
);
860 ShellStatus
= SHELL_INVALID_PARAMETER
;
863 if (ShellStatus
== SHELL_SUCCESS
) {
865 // Get hot key information
867 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
868 if (EFI_ERROR(Status
) || (((UINT32
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
) {
869 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, Walker
);
870 ShellStatus
= SHELL_INVALID_PARAMETER
;
872 NewKeyOption
.KeyData
.PackedValue
= (UINT32
)Intermediate
;
873 Temp
= StrStr(Walker
, L
" ");
877 while(Walker
[0] == L
' ') {
882 if (ShellStatus
== SHELL_SUCCESS
) {
884 // Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.
885 // Re-allocate with the added information.
887 KeyOptionBuffer
= AllocateCopyPool(sizeof(EFI_KEY_OPTION
) + (sizeof(EFI_INPUT_KEY
) * NewKeyOption
.KeyData
.Options
.InputKeyCount
), &NewKeyOption
);
888 if (KeyOptionBuffer
== NULL
) {
889 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellBcfgHiiHandle
);
890 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
893 for (LoopCounter
= 0 ; ShellStatus
== SHELL_SUCCESS
&& LoopCounter
< NewKeyOption
.KeyData
.Options
.InputKeyCount
; LoopCounter
++) {
897 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
898 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
) {
899 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, Walker
);
900 ShellStatus
= SHELL_INVALID_PARAMETER
;
902 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof(EFI_KEY_OPTION
)))[LoopCounter
].ScanCode
= (UINT16
)Intermediate
;
903 Temp
= StrStr(Walker
, L
" ");
907 while(Walker
[0] == L
' ') {
914 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
915 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
)) {
916 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, Walker
);
917 ShellStatus
= SHELL_INVALID_PARAMETER
;
919 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof(EFI_KEY_OPTION
)))[LoopCounter
].UnicodeChar
= (UINT16
)Intermediate
;
920 Temp
= StrStr(Walker
, L
" ");
924 while(Walker
[0] == L
' ') {
929 if (ShellStatus
== SHELL_SUCCESS
) {
931 // Now do the BootOption / BootOptionCrc
933 ASSERT (OptionIndex
<= OrderCount
);
934 KeyOptionBuffer
->BootOption
= CurrentOrder
[OptionIndex
];
935 Status
= GetBootOptionCrc(&(KeyOptionBuffer
->BootOptionCrc
), KeyOptionBuffer
->BootOption
);
936 if (EFI_ERROR(Status
)) {
937 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, L
"Option Index");
938 ShellStatus
= SHELL_INVALID_PARAMETER
;
942 if (ShellStatus
== SHELL_SUCCESS
) {
943 for (Temp2
= NULL
, KeyIndex
= 0 ; KeyIndex
< 0xFFFF ; KeyIndex
++) {
944 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"Key%04x", KeyIndex
);
945 Status
= gRT
->GetVariable(
947 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
949 (UINTN
*)&Intermediate
,
951 if (Status
== EFI_NOT_FOUND
) {
955 Status
= gRT
->SetVariable(
957 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
958 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
959 sizeof(EFI_KEY_OPTION
) + (sizeof(EFI_INPUT_KEY
) * NewKeyOption
.KeyData
.Options
.InputKeyCount
),
961 if (EFI_ERROR(Status
)) {
962 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, VariableName
, Status
);
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
);
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
, VariableName
, Status
);
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
, VariableName
, Status
);
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];
1045 CHAR16
*DevPathString
;
1048 if (OrderCount
== 0) {
1049 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_BCFG_NONE
), gShellBcfgHiiHandle
);
1050 return (SHELL_SUCCESS
);
1053 for (LoopVar
= 0 ; LoopVar
< OrderCount
; LoopVar
++) {
1056 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Op
, CurrentOrder
[LoopVar
]);
1058 Status
= gRT
->GetVariable(
1060 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1064 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1065 Buffer
= AllocateZeroPool(BufferSize
);
1066 Status
= gRT
->GetVariable(
1068 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1074 if (EFI_ERROR(Status
) || Buffer
== NULL
) {
1075 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_READ_FAIL
), gShellBcfgHiiHandle
, VariableName
, Status
);
1076 return (SHELL_INVALID_PARAMETER
);
1079 if ((*(UINT16
*)(Buffer
+4)) != 0) {
1080 DevPath
= AllocateZeroPool(*(UINT16
*)(Buffer
+4));
1081 if (DevPath
== NULL
) {
1082 DevPathString
= NULL
;
1084 CopyMem(DevPath
, Buffer
+6+StrSize((CHAR16
*)(Buffer
+6)), *(UINT16
*)(Buffer
+4));
1085 DevPathString
= ConvertDevicePathToText(DevPath
, TRUE
, FALSE
);
1089 DevPathString
= NULL
;
1095 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS
),
1096 gShellBcfgHiiHandle
,
1099 (CHAR16
*)(Buffer
+6),
1101 (StrSize((CHAR16
*)(Buffer
+6)) + *(UINT16
*)(Buffer
+4) + 6) <= BufferSize
?L
'N':L
'Y');
1102 if (VerboseOutput
) {
1103 for (LoopVar2
= (StrSize((CHAR16
*)(Buffer
+6)) + *(UINT16
*)(Buffer
+4) + 6);LoopVar2
<BufferSize
;LoopVar2
++){
1118 if (Buffer
!= NULL
) {
1121 if (DevPath
!= NULL
) {
1124 if (DevPathString
!= NULL
) {
1125 FreePool(DevPathString
);
1128 return (SHELL_SUCCESS
);
1132 Function to initialize the BCFG operation structure.
1134 @param[in] Struct The stuct to initialize.
1139 IN BGFG_OPERATION
*Struct
1142 ASSERT(Struct
!= NULL
);
1143 Struct
->Target
= BcfgTargetMax
;
1144 Struct
->Type
= BcfgTypeMax
;
1145 Struct
->Number1
= 0;
1146 Struct
->Number2
= 0;
1147 Struct
->HandleIndex
= 0;
1148 Struct
->FileName
= NULL
;
1149 Struct
->Description
= NULL
;
1150 Struct
->Order
= NULL
;
1151 Struct
->OptData
= NULL
;
1155 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
1157 {L
"-opt", TypeMaxValue
},
1162 Function for 'bcfg' command.
1164 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1165 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1169 ShellCommandRunBcfg (
1170 IN EFI_HANDLE ImageHandle
,
1171 IN EFI_SYSTEM_TABLE
*SystemTable
1175 LIST_ENTRY
*Package
;
1176 CHAR16
*ProblemParam
;
1177 SHELL_STATUS ShellStatus
;
1179 CONST CHAR16
*CurrentParam
;
1180 BGFG_OPERATION CurrentOperation
;
1182 UINT64 Intermediate
;
1186 ProblemParam
= NULL
;
1188 ShellStatus
= SHELL_SUCCESS
;
1190 InitBcfgStruct(&CurrentOperation
);
1193 // initialize the shell lib (we must be in non-auto-init...)
1195 Status
= ShellInitialize();
1196 ASSERT_EFI_ERROR(Status
);
1198 Status
= CommandInit();
1199 ASSERT_EFI_ERROR(Status
);
1202 // parse the command line
1204 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
1205 if (EFI_ERROR(Status
)) {
1206 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
1207 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, ProblemParam
);
1208 FreePool(ProblemParam
);
1209 ShellStatus
= SHELL_INVALID_PARAMETER
;
1215 // Read in if we are doing -OPT
1217 if (ShellCommandLineGetFlag(Package
, L
"-opt")) {
1218 CurrentOperation
.OptData
= ShellCommandLineGetValue(Package
, L
"-opt");
1219 if (CurrentOperation
.OptData
== NULL
) {
1220 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_VAL
), gShellBcfgHiiHandle
, L
"-opt");
1221 ShellStatus
= SHELL_INVALID_PARAMETER
;
1223 CurrentOperation
.Type
= BcfgTypeOpt
;
1227 // small block to read the target of the operation
1229 if ((ShellCommandLineGetCount(Package
) < 3 && CurrentOperation
.Type
!= BcfgTypeOpt
) ||
1230 (ShellCommandLineGetCount(Package
) < 2 && CurrentOperation
.Type
== BcfgTypeOpt
)
1232 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
);
1233 ShellStatus
= SHELL_INVALID_PARAMETER
;
1234 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"driver") == 0) {
1235 CurrentOperation
.Target
= BcfgTargetDriverOrder
;
1236 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"boot") == 0) {
1237 CurrentOperation
.Target
= BcfgTargetBootOrder
;
1239 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT
), gShellBcfgHiiHandle
);
1240 ShellStatus
= SHELL_INVALID_PARAMETER
;
1245 // Read in the boot or driver order environment variable (not needed for opt)
1247 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
1249 Status
= gRT
->GetVariable(
1250 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
1251 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1254 CurrentOperation
.Order
);
1255 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1256 CurrentOperation
.Order
= AllocateZeroPool(Length
+(4*sizeof(CurrentOperation
.Order
[0])));
1257 if (CurrentOperation
.Order
== NULL
) {
1258 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1260 Status
= gRT
->GetVariable(
1261 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
1262 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1265 CurrentOperation
.Order
);
1270 Count
= (UINT16
) (Length
/ sizeof(CurrentOperation
.Order
[0]));
1273 // large block to read the type of operation and verify parameter types for the info.
1275 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
1276 for (ParamNumber
= 2 ; ParamNumber
< ShellCommandLineGetCount(Package
) && ShellStatus
== SHELL_SUCCESS
; ParamNumber
++) {
1277 CurrentParam
= ShellCommandLineGetRawValue(Package
, ParamNumber
);
1278 if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"dump") == 0) {
1279 CurrentOperation
.Type
= BcfgTypeDump
;
1280 } else if (ShellCommandLineGetFlag(Package
, L
"-v")) {
1281 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, L
"-v (without dump)");
1282 ShellStatus
= SHELL_INVALID_PARAMETER
;
1283 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"add") == 0) {
1284 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1285 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
);
1286 ShellStatus
= SHELL_INVALID_PARAMETER
;
1288 CurrentOperation
.Type
= BcfgTypeAdd
;
1289 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1290 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1291 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, CurrentParam
);
1292 ShellStatus
= SHELL_INVALID_PARAMETER
;
1294 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1295 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1296 ASSERT(CurrentOperation
.FileName
== NULL
);
1297 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1298 ASSERT(CurrentOperation
.Description
== NULL
);
1299 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1301 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addp") == 0) {
1302 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1303 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
);
1304 ShellStatus
= SHELL_INVALID_PARAMETER
;
1306 CurrentOperation
.Type
= BcfgTypeAddp
;
1307 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1308 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1309 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, CurrentParam
);
1310 ShellStatus
= SHELL_INVALID_PARAMETER
;
1312 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1313 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1314 ASSERT(CurrentOperation
.FileName
== NULL
);
1315 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1316 ASSERT(CurrentOperation
.Description
== NULL
);
1317 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1319 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addh") == 0) {
1320 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1321 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
);
1322 ShellStatus
= SHELL_INVALID_PARAMETER
;
1324 CurrentOperation
.Type
= BcfgTypeAddh
;
1325 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1326 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1327 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, CurrentParam
);
1328 ShellStatus
= SHELL_INVALID_PARAMETER
;
1330 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1331 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1332 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1333 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1334 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, CurrentParam
);
1335 ShellStatus
= SHELL_INVALID_PARAMETER
;
1337 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1338 CurrentOperation
.HandleIndex
= (UINT16
)Intermediate
;
1339 ASSERT(CurrentOperation
.Description
== NULL
);
1340 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1343 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"rm") == 0) {
1344 if ((ParamNumber
+ 1) >= ShellCommandLineGetCount(Package
)) {
1345 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
);
1346 ShellStatus
= SHELL_INVALID_PARAMETER
;
1348 CurrentOperation
.Type
= BcfgTypeRm
;
1349 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1350 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1351 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, CurrentParam
);
1352 ShellStatus
= SHELL_INVALID_PARAMETER
;
1354 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1355 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1356 if (CurrentOperation
.Number1
> Count
){
1357 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, Count
);
1358 ShellStatus
= SHELL_INVALID_PARAMETER
;
1361 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"mv") == 0) {
1362 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount(Package
)) {
1363 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
);
1364 ShellStatus
= SHELL_INVALID_PARAMETER
;
1366 CurrentOperation
.Type
= BcfgTypeMv
;
1367 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1368 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1369 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, CurrentParam
);
1370 ShellStatus
= SHELL_INVALID_PARAMETER
;
1372 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1373 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1374 if (CurrentOperation
.Number1
> Count
){
1375 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, Count
);
1376 ShellStatus
= SHELL_INVALID_PARAMETER
;
1378 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1379 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1380 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, CurrentParam
);
1381 ShellStatus
= SHELL_INVALID_PARAMETER
;
1383 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1384 CurrentOperation
.Number2
= (UINT16
)Intermediate
;
1386 if (CurrentOperation
.Number2
== CurrentOperation
.Number1
1387 ||CurrentOperation
.Number2
>= Count
1389 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, Count
);
1390 ShellStatus
= SHELL_INVALID_PARAMETER
;
1395 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, CurrentParam
);
1396 ShellStatus
= SHELL_INVALID_PARAMETER
;
1400 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
&& CurrentOperation
.Type
< BcfgTypeMax
) {
1402 // we have all the info. Do the work
1404 switch (CurrentOperation
.Type
) {
1406 ShellStatus
= BcfgDisplayDump(
1407 CurrentOperation
.Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver",
1409 CurrentOperation
.Order
,
1410 ShellCommandLineGetFlag(Package
, L
"-v"));
1413 ShellStatus
= BcfgMove(
1414 CurrentOperation
.Target
,
1415 CurrentOperation
.Order
,
1417 CurrentOperation
.Number1
,
1418 CurrentOperation
.Number2
);
1421 ShellStatus
= BcfgRemove(
1422 CurrentOperation
.Target
,
1423 CurrentOperation
.Order
,
1425 CurrentOperation
.Number1
);
1430 ShellStatus
= BcfgAdd(
1431 CurrentOperation
.Number1
,
1432 CurrentOperation
.FileName
,
1433 CurrentOperation
.Description
==NULL
?L
"":CurrentOperation
.Description
,
1434 CurrentOperation
.Order
,
1436 CurrentOperation
.Target
,
1437 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddh
),
1438 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddp
),
1439 CurrentOperation
.HandleIndex
);
1442 ShellStatus
= BcfgAddOpt(
1443 CurrentOperation
.OptData
,
1444 CurrentOperation
.Order
,
1446 CurrentOperation
.Target
);
1454 if (Package
!= NULL
) {
1455 ShellCommandLineFreeVarList (Package
);
1457 if (CurrentOperation
.FileName
!= NULL
) {
1458 FreePool(CurrentOperation
.FileName
);
1460 if (CurrentOperation
.Description
!= NULL
) {
1461 FreePool(CurrentOperation
.Description
);
1463 if (CurrentOperation
.Order
!= NULL
) {
1464 FreePool(CurrentOperation
.Order
);
1467 return (ShellStatus
);
1472 Function to get the filename with help context if HII will not be used.
1474 @return The filename with help text in it.
1478 ShellCommandGetManFileNameBcfg (
1486 "Constructor" for the library.
1488 This will register the handler for the bcfg command.
1490 @param[in] ImageHandle the image handle of the process
1491 @param[in] SystemTable the EFI System Table pointer
1492 @param[in] Name the profile name to use
1494 @retval EFI_SUCCESS the shell command handlers were installed sucessfully
1495 @retval EFI_UNSUPPORTED the shell level required was not found.
1499 BcfgLibraryRegisterBcfgCommand (
1500 IN EFI_HANDLE ImageHandle
,
1501 IN EFI_SYSTEM_TABLE
*SystemTable
,
1502 IN CONST CHAR16
*Name
1505 if (gShellBcfgHiiHandle
) {
1506 return (EFI_SUCCESS
);
1509 gShellBcfgHiiHandle
= HiiAddPackages (&gShellBcfgHiiGuid
, gImageHandle
, UefiShellBcfgCommandLibStrings
, NULL
);
1510 if (gShellBcfgHiiHandle
== NULL
) {
1511 return (EFI_DEVICE_ERROR
);
1515 // install our shell command handler
1517 ShellCommandRegisterCommandName(L
"bcfg", ShellCommandRunBcfg
, ShellCommandGetManFileNameBcfg
, 0, Name
, FALSE
, gShellBcfgHiiHandle
, STRING_TOKEN(STR_GET_HELP_BCFG
));
1519 return (EFI_SUCCESS
);
1523 Destructor for the library. free any resources.
1525 @param ImageHandle The image handle of the process.
1526 @param SystemTable The EFI System Table pointer.
1530 BcfgLibraryUnregisterBcfgCommand (
1531 IN EFI_HANDLE ImageHandle
,
1532 IN EFI_SYSTEM_TABLE
*SystemTable
1535 if (gShellBcfgHiiHandle
!= NULL
) {
1536 HiiRemovePackages(gShellBcfgHiiHandle
);
1538 gShellBcfgHiiHandle
= NULL
;
1539 return (EFI_SUCCESS
);