2 Main file for BCFG command.
4 (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include <Guid/GlobalVariable.h>
13 #include <Guid/ShellLibHiiGuid.h>
15 #include <Protocol/Shell.h>
16 #include <Protocol/ShellParameters.h>
17 #include <Protocol/DevicePath.h>
18 #include <Protocol/LoadedImage.h>
19 #include <Protocol/UnicodeCollation.h>
21 #include <Library/BaseLib.h>
22 #include <Library/BaseMemoryLib.h>
23 #include <Library/DebugLib.h>
24 #include <Library/MemoryAllocationLib.h>
25 #include <Library/PcdLib.h>
26 #include <Library/ShellCommandLib.h>
27 #include <Library/ShellLib.h>
28 #include <Library/SortLib.h>
29 #include <Library/UefiLib.h>
30 #include <Library/UefiRuntimeServicesTableLib.h>
31 #include <Library/UefiBootServicesTableLib.h>
32 #include <Library/HiiLib.h>
33 #include <Library/FileHandleLib.h>
34 #include <Library/PrintLib.h>
35 #include <Library/HandleParsingLib.h>
36 #include <Library/DevicePathLib.h>
37 #include <Library/UefiBootManagerLib.h>
39 STATIC CONST CHAR16 mFileName
[] = L
"ShellCommands";
40 STATIC EFI_HII_HANDLE gShellBcfgHiiHandle
= NULL
;
43 BcfgTargetBootOrder
= 0,
44 BcfgTargetDriverOrder
= 1,
46 } BCFG_OPERATION_TARGET
;
61 } BCFG_OPERATION_TYPE
;
64 BCFG_OPERATION_TARGET Target
;
65 BCFG_OPERATION_TYPE Type
;
72 CONST CHAR16
*OptData
;
76 Update the optional data for a boot or driver option.
78 If optional data exists it will be changed.
80 @param[in] Index The boot or driver option index update.
81 @param[in] DataSize The size in bytes of Data.
82 @param[in] Data The buffer for the optioanl data.
83 @param[in] Target The target of the operation.
85 @retval EFI_SUCCESS The data was sucessfully updated.
86 @retval other A error occurred.
93 IN CONST BCFG_OPERATION_TARGET Target
97 CHAR16 VariableName
[12];
102 UINTN OriginalOptionDataSize
;
104 UnicodeSPrint (VariableName
, sizeof (VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
? L
"Boot" : L
"Driver", Index
);
111 Status
= gRT
->GetVariable (
113 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
118 if (Status
== EFI_BUFFER_TOO_SMALL
) {
119 OriginalData
= AllocateZeroPool (OriginalSize
);
120 if (OriginalData
== NULL
) {
121 return (EFI_OUT_OF_RESOURCES
);
124 Status
= gRT
->GetVariable (
126 (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
= AllocatePool (NewSize
);
143 if (NewData
== NULL
) {
144 Status
= EFI_OUT_OF_RESOURCES
;
146 CopyMem (NewData
, OriginalData
, OriginalSize
- OriginalOptionDataSize
);
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
,
164 SHELL_FREE_NON_NULL (OriginalData
);
165 SHELL_FREE_NON_NULL (NewData
);
170 This function will get a CRC for a boot option.
172 @param[in, out] Crc The CRC value to return.
173 @param[in] BootIndex The boot option index to CRC.
175 @retval EFI_SUCCESS The CRC was sucessfully returned.
176 @retval other A error occurred.
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
,
203 if (Status
== EFI_BUFFER_TOO_SMALL
) {
204 Buffer
= AllocateZeroPool (BufferSize
);
205 Status
= gRT
->GetVariable (
207 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
215 // Get the CRC computed
217 if (!EFI_ERROR (Status
)) {
218 Status
= gBS
->CalculateCrc32 (Buffer
, BufferSize
, Crc
);
221 SHELL_FREE_NON_NULL (Buffer
);
226 This function will populate the device path protocol parameter based on TheHandle.
228 @param[in] TheHandle Driver handle.
229 @param[in, out] FilePath On a sucessful return the device path to the handle.
231 @retval EFI_SUCCESS The device path was sucessfully returned.
232 @retval other A error from gBS->HandleProtocol.
237 GetDevicePathForDriverHandle (
238 IN EFI_HANDLE TheHandle
,
239 IN OUT EFI_DEVICE_PATH_PROTOCOL
**FilePath
243 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
244 EFI_DEVICE_PATH_PROTOCOL
*ImageDevicePath
;
246 Status
= gBS
->OpenProtocol (
248 &gEfiLoadedImageProtocolGuid
,
249 (VOID
**)&LoadedImage
,
252 EFI_OPEN_PROTOCOL_GET_PROTOCOL
254 if (!EFI_ERROR (Status
)) {
255 Status
= gBS
->OpenProtocol (
256 LoadedImage
->DeviceHandle
,
257 &gEfiDevicePathProtocolGuid
,
258 (VOID
**)&ImageDevicePath
,
261 EFI_OPEN_PROTOCOL_GET_PROTOCOL
263 if (!EFI_ERROR (Status
)) {
264 // *DevPath = DuplicateDevicePath (ImageDevicePath);
265 // *FilePath = DuplicateDevicePath (LoadedImage->FilePath);
266 *FilePath
= AppendDevicePath (ImageDevicePath
, LoadedImage
->FilePath
);
268 LoadedImage
->DeviceHandle
,
269 &gEfiDevicePathProtocolGuid
,
277 &gEfiLoadedImageProtocolGuid
,
287 Functino to get Device Path by a handle.
289 @param[in] TheHandle Use it to get DevicePath.
290 @param[in] Target Boot option target.
291 @param[in, out] DevicePath On a sucessful return the device path to the handle.
293 @retval SHELL_INVALID_PARAMETER The handle was NULL.
294 @retval SHELL_NOT_FOUND Not found device path by handle.
295 @retval SHELL_SUCCESS Get device path successfully.
298 GetDevicePathByHandle (
299 IN EFI_HANDLE TheHandle
,
300 IN BCFG_OPERATION_TARGET Target
,
301 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePath
305 SHELL_STATUS ShellStatus
;
307 UINTN DriverBindingHandleCount
;
308 UINTN ParentControllerHandleCount
;
309 UINTN ChildControllerHandleCount
;
311 ShellStatus
= SHELL_SUCCESS
;
313 if (TheHandle
== NULL
) {
314 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Handle Number");
315 return SHELL_INVALID_PARAMETER
;
318 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (TheHandle
, &DriverBindingHandleCount
, NULL
);
319 if (EFI_ERROR (Status
)) {
320 DriverBindingHandleCount
= 0;
323 Status
= PARSE_HANDLE_DATABASE_PARENTS (TheHandle
, &ParentControllerHandleCount
, NULL
);
324 if (EFI_ERROR (Status
)) {
325 ParentControllerHandleCount
= 0;
328 Status
= ParseHandleDatabaseForChildControllers (TheHandle
, &ChildControllerHandleCount
, NULL
);
329 if (EFI_ERROR (Status
)) {
330 ChildControllerHandleCount
= 0;
333 Status
= gBS
->HandleProtocol (TheHandle
, &gEfiDevicePathProtocolGuid
, (VOID
**)DevicePath
);
335 if ((DriverBindingHandleCount
> 0) ||
336 (ParentControllerHandleCount
> 0) ||
337 (ChildControllerHandleCount
> 0) ||
342 // The handle points to a real controller which has a device path.
344 if (Target
== BcfgTargetDriverOrder
) {
349 STRING_TOKEN (STR_GEN_PARAM_INV
),
352 L
"Handle should point to driver image."
354 ShellStatus
= SHELL_NOT_FOUND
;
358 // The handle points to a driver image.
360 if (Target
== BcfgTargetBootOrder
) {
365 STRING_TOKEN (STR_GEN_PARAM_INV
),
368 L
"Handle should point to controller."
370 ShellStatus
= SHELL_NOT_FOUND
;
372 if (EFI_ERROR (GetDevicePathForDriverHandle (TheHandle
, DevicePath
))) {
373 ShellStatus
= SHELL_NOT_FOUND
;
378 return (ShellStatus
);
382 Function to modify an option.
384 @param[in] BcfgOperation Pointer to BCFG operation.
385 @param[in] OrderCount The number if items in CurrentOrder.
387 @retval SHELL_SUCCESS The operation was successful.
388 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
389 @retval SHELL_OUT_OF_RESOUCES A memory allocation failed.
393 IN CONST BGFG_OPERATION
*BcfgOperation
,
394 IN CONST UINTN OrderCount
398 EFI_HANDLE CurHandle
;
399 SHELL_STATUS ShellStatus
;
400 CHAR16 OptionStr
[40];
401 EFI_SHELL_FILE_INFO
*FileList
;
402 EFI_SHELL_FILE_INFO
*Arg
;
403 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
404 EFI_DEVICE_PATH_PROTOCOL
*DevicePathBuffer
;
405 EFI_DEVICE_PATH_PROTOCOL
*DevicePathWalker
;
406 EFI_BOOT_MANAGER_LOAD_OPTION LoadOption
;
408 ShellStatus
= SHELL_SUCCESS
;
411 DevicePathBuffer
= NULL
;
413 ZeroMem (&LoadOption
, sizeof (EFI_BOOT_MANAGER_LOAD_OPTION
));
415 if (((BcfgOperation
->Type
== BcfgTypeMod
) && (BcfgOperation
->Description
== NULL
)) ||
416 ((BcfgOperation
->Type
== BcfgTypeModf
) && (BcfgOperation
->FileName
== NULL
)) ||
417 ((BcfgOperation
->Type
== BcfgTypeModp
) && (BcfgOperation
->FileName
== NULL
)) ||
418 ((BcfgOperation
->Type
== BcfgTypeModh
) && (BcfgOperation
->HandleIndex
== 0)) ||
419 (BcfgOperation
->Number1
> OrderCount
)
422 return (SHELL_INVALID_PARAMETER
);
425 if (BcfgOperation
->Type
== BcfgTypeModh
) {
426 CurHandle
= ConvertHandleIndexToHandle (BcfgOperation
->HandleIndex
);
427 ShellStatus
= GetDevicePathByHandle (CurHandle
, BcfgOperation
->Target
, &DevicePathBuffer
);
428 if (ShellStatus
== SHELL_SUCCESS
) {
429 DevicePath
= DuplicateDevicePath (DevicePathBuffer
);
431 } else if ((BcfgOperation
->Type
== BcfgTypeModf
) || (BcfgOperation
->Type
== BcfgTypeModp
)) {
433 // Get Device Path by FileName.
435 ShellOpenFileMetaArg ((CHAR16
*)BcfgOperation
->FileName
, EFI_FILE_MODE_READ
, &FileList
);
436 if (FileList
== NULL
) {
438 // The name of file matched nothing.
440 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", BcfgOperation
->FileName
);
441 ShellStatus
= SHELL_INVALID_PARAMETER
;
442 } else if (FileList
->Link
.ForwardLink
!= FileList
->Link
.BackLink
) {
444 // If the name of file expanded to multiple names, it's fail.
446 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE
), gShellBcfgHiiHandle
, L
"bcfg", BcfgOperation
->FileName
);
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", BcfgOperation
->FileName
);
452 ShellStatus
= SHELL_INVALID_PARAMETER
;
454 DevicePathBuffer
= gEfiShellProtocol
->GetDevicePathFromFilePath (Arg
->FullName
);
455 if (DevicePathBuffer
== NULL
) {
456 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_DP
), gShellBcfgHiiHandle
, L
"bcfg", Arg
->FullName
);
457 ShellStatus
= SHELL_UNSUPPORTED
;
462 if (ShellStatus
== SHELL_SUCCESS
) {
463 if (BcfgOperation
->Type
== BcfgTypeModp
) {
464 ShellStatus
= SHELL_INVALID_PARAMETER
;
465 DevicePathWalker
= DevicePathBuffer
;
466 while (!IsDevicePathEnd (DevicePathWalker
)) {
467 if ((DevicePathType (DevicePathWalker
) == MEDIA_DEVICE_PATH
) &&
468 (DevicePathSubType (DevicePathWalker
) == MEDIA_HARDDRIVE_DP
)
472 // We found the portion of device path starting with the hard driver partition.
474 ShellStatus
= SHELL_SUCCESS
;
475 DevicePath
= DuplicateDevicePath (DevicePathWalker
);
478 DevicePathWalker
= NextDevicePathNode (DevicePathWalker
);
482 DevicePath
= DuplicateDevicePath (DevicePathBuffer
);
485 FreePool (DevicePathBuffer
);
489 if (ShellStatus
== SHELL_SUCCESS
) {
490 if (BcfgOperation
->Target
== BcfgTargetBootOrder
) {
491 UnicodeSPrint (OptionStr
, sizeof (OptionStr
), L
"Boot%04x", BcfgOperation
->Order
[BcfgOperation
->Number1
]);
493 UnicodeSPrint (OptionStr
, sizeof (OptionStr
), L
"Driver%04x", BcfgOperation
->Order
[BcfgOperation
->Number1
]);
496 Status
= EfiBootManagerVariableToLoadOption (OptionStr
, &LoadOption
);
497 if (EFI_ERROR (Status
)) {
498 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NONE
), gShellBcfgHiiHandle
);
499 ShellStatus
= SHELL_NOT_FOUND
;
503 if (ShellStatus
== SHELL_SUCCESS
) {
504 if (BcfgOperation
->Type
== BcfgTypeMod
) {
505 SHELL_FREE_NON_NULL (LoadOption
.Description
);
506 LoadOption
.Description
= AllocateCopyPool (StrSize (BcfgOperation
->Description
), BcfgOperation
->Description
);
508 SHELL_FREE_NON_NULL (LoadOption
.FilePath
);
509 LoadOption
.FilePath
= DuplicateDevicePath (DevicePath
);
512 Status
= EfiBootManagerLoadOptionToVariable (&LoadOption
);
513 if (EFI_ERROR (Status
)) {
514 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", OptionStr
);
515 ShellStatus
= SHELL_INVALID_PARAMETER
;
519 EfiBootManagerFreeLoadOption (&LoadOption
);
521 if (DevicePath
!= NULL
) {
522 FreePool (DevicePath
);
525 if (FileList
!= NULL
) {
526 ShellCloseFileMetaArg (&FileList
);
529 return (ShellStatus
);
533 Function to add a option.
535 @param[in] Position The position to add Target at.
536 @param[in] File The file to make the target.
537 @param[in] Desc The description text.
538 @param[in] CurrentOrder The pointer to the current order of items.
539 @param[in] OrderCount The number if items in CurrentOrder.
540 @param[in] Target The info on the option to add.
541 @param[in] UseHandle TRUE to use HandleNumber, FALSE to use File and Desc.
542 @param[in] UsePath TRUE to convert to devicepath.
543 @param[in] HandleNumber The handle number to add.
545 @retval SHELL_SUCCESS The operation was successful.
546 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
551 IN CONST CHAR16
*File
,
552 IN CONST CHAR16
*Desc
,
553 IN CONST UINT16
*CurrentOrder
,
554 IN CONST UINTN OrderCount
,
555 IN CONST BCFG_OPERATION_TARGET Target
,
556 IN CONST BOOLEAN UseHandle
,
557 IN CONST BOOLEAN UsePath
,
558 IN CONST UINTN HandleNumber
562 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
563 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
564 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
566 UINT8
*TempByteBuffer
;
567 UINT8
*TempByteStart
;
568 EFI_SHELL_FILE_INFO
*Arg
;
569 EFI_SHELL_FILE_INFO
*FileList
;
570 CHAR16 OptionStr
[40];
571 UINTN DescSize
, FilePathSize
;
573 UINTN TargetLocation
;
576 EFI_HANDLE CurHandle
;
577 UINTN DriverBindingHandleCount
;
578 UINTN ParentControllerHandleCount
;
579 UINTN ChildControllerHandleCount
;
580 SHELL_STATUS ShellStatus
;
584 if ((File
== NULL
) || (Desc
== NULL
)) {
585 return (SHELL_INVALID_PARAMETER
);
588 if (HandleNumber
== 0) {
589 return (SHELL_INVALID_PARAMETER
);
593 if (Position
> OrderCount
) {
594 Position
= OrderCount
;
601 ShellStatus
= SHELL_SUCCESS
;
602 TargetLocation
= 0xFFFF;
605 CurHandle
= ConvertHandleIndexToHandle (HandleNumber
);
606 if (CurHandle
== NULL
) {
607 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Handle Number");
608 ShellStatus
= SHELL_INVALID_PARAMETER
;
610 if (Target
== BcfgTargetBootOrder
) {
612 // Make sure that the handle should point to a real controller
614 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
616 &DriverBindingHandleCount
,
620 Status
= PARSE_HANDLE_DATABASE_PARENTS (
622 &ParentControllerHandleCount
,
626 Status
= ParseHandleDatabaseForChildControllers (
628 &ChildControllerHandleCount
,
632 if ( (DriverBindingHandleCount
> 0)
633 || (ParentControllerHandleCount
> 0)
634 || (ChildControllerHandleCount
> 0))
637 Status
= gBS
->HandleProtocol (
639 &gEfiDevicePathProtocolGuid
,
644 if (EFI_ERROR (Status
)) {
645 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_HANDLE
), gShellBcfgHiiHandle
, L
"bcfg", HandleNumber
);
646 ShellStatus
= SHELL_INVALID_PARAMETER
;
650 // Make sure that the handle should point to driver, not a controller.
652 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
654 &DriverBindingHandleCount
,
658 Status
= PARSE_HANDLE_DATABASE_PARENTS (
660 &ParentControllerHandleCount
,
664 Status
= ParseHandleDatabaseForChildControllers (
666 &ChildControllerHandleCount
,
670 Status
= gBS
->HandleProtocol (
672 &gEfiDevicePathProtocolGuid
,
676 if ( (DriverBindingHandleCount
> 0)
677 || (ParentControllerHandleCount
> 0)
678 || (ChildControllerHandleCount
> 0)
679 || !EFI_ERROR (Status
))
681 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Handle Number");
682 ShellStatus
= SHELL_INVALID_PARAMETER
;
685 // Get the DevicePath from the loaded image information.
687 Status
= GetDevicePathForDriverHandle (CurHandle
, &FilePath
);
695 ShellOpenFileMetaArg ((CHAR16
*)File
, EFI_FILE_MODE_READ
, &FileList
);
697 if (FileList
== NULL
) {
699 // If filename matched nothing fail
701 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", File
);
702 ShellStatus
= SHELL_INVALID_PARAMETER
;
703 } else if (FileList
->Link
.ForwardLink
!= FileList
->Link
.BackLink
) {
705 // If filename expanded to multiple names, fail
707 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE
), gShellBcfgHiiHandle
, L
"bcfg", File
);
708 ShellStatus
= SHELL_INVALID_PARAMETER
;
710 Arg
= (EFI_SHELL_FILE_INFO
*)GetFirstNode (&FileList
->Link
);
711 if (EFI_ERROR (Arg
->Status
)) {
712 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_OPEN
), gShellBcfgHiiHandle
, L
"bcfg", File
);
713 ShellStatus
= SHELL_INVALID_PARAMETER
;
716 // Build FilePath to the filename
720 // get the device path
722 DevicePath
= gEfiShellProtocol
->GetDevicePathFromFilePath (Arg
->FullName
);
723 if (DevicePath
== NULL
) {
724 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_DP
), gShellBcfgHiiHandle
, L
"bcfg", Arg
->FullName
);
725 ShellStatus
= SHELL_UNSUPPORTED
;
728 DevPath
= DevicePath
;
729 ShellStatus
= SHELL_INVALID_PARAMETER
;
730 while (!IsDevicePathEnd (DevPath
)) {
731 if ((DevicePathType (DevPath
) == MEDIA_DEVICE_PATH
) &&
732 (DevicePathSubType (DevPath
) == MEDIA_HARDDRIVE_DP
))
735 // If we find it use it instead
737 ShellStatus
= SHELL_SUCCESS
;
738 FilePath
= DuplicateDevicePath (DevPath
);
742 DevPath
= NextDevicePathNode (DevPath
);
745 FilePath
= DuplicateDevicePath (DevicePath
);
748 FreePool (DevicePath
);
754 if (ShellStatus
== SHELL_SUCCESS
) {
756 // Find a free target ,a brute force implementation
759 for (TargetLocation
= 0; TargetLocation
< 0xFFFF; TargetLocation
++) {
761 for (Index
= 0; Index
< OrderCount
; Index
++) {
762 if (CurrentOrder
[Index
] == TargetLocation
) {
773 if (TargetLocation
== 0xFFFF) {
774 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET_NF
), gShellBcfgHiiHandle
, L
"bcfg");
776 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET
), gShellBcfgHiiHandle
, TargetLocation
);
780 if (ShellStatus
== SHELL_SUCCESS
) {
784 DescSize
= StrSize (Desc
);
785 FilePathSize
= GetDevicePathSize (FilePath
);
787 TempByteBuffer
= AllocateZeroPool (sizeof (UINT32
) + sizeof (UINT16
) + DescSize
+ FilePathSize
);
788 if (TempByteBuffer
!= NULL
) {
789 TempByteStart
= TempByteBuffer
;
790 *((UINT32
*)TempByteBuffer
) = LOAD_OPTION_ACTIVE
; // Attributes
791 TempByteBuffer
+= sizeof (UINT32
);
793 *((UINT16
*)TempByteBuffer
) = (UINT16
)FilePathSize
; // FilePathListLength
794 TempByteBuffer
+= sizeof (UINT16
);
796 CopyMem (TempByteBuffer
, Desc
, DescSize
);
797 TempByteBuffer
+= DescSize
;
798 ASSERT (FilePath
!= NULL
);
799 CopyMem (TempByteBuffer
, FilePath
, FilePathSize
);
801 UnicodeSPrint (OptionStr
, sizeof (OptionStr
), L
"%s%04x", Target
== BcfgTargetBootOrder
? L
"Boot" : L
"Driver", TargetLocation
);
802 Status
= gRT
->SetVariable (
804 &gEfiGlobalVariableGuid
,
805 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
806 sizeof (UINT32
) + sizeof (UINT16
) + DescSize
+ FilePathSize
,
810 FreePool (TempByteStart
);
812 Status
= EFI_OUT_OF_RESOURCES
;
815 if (EFI_ERROR (Status
)) {
816 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", OptionStr
);
818 NewOrder
= AllocateZeroPool ((OrderCount
+ 1) * sizeof (NewOrder
[0]));
819 if (NewOrder
!= NULL
) {
820 CopyMem (NewOrder
, CurrentOrder
, (OrderCount
) * sizeof (NewOrder
[0]));
823 // Insert target into order list
825 for (Index
= OrderCount
; Index
> Position
; Index
--) {
826 NewOrder
[Index
] = NewOrder
[Index
- 1];
829 NewOrder
[Position
] = (UINT16
)TargetLocation
;
830 Status
= gRT
->SetVariable (
831 Target
== BcfgTargetBootOrder
? L
"BootOrder" : L
"DriverOrder",
832 &gEfiGlobalVariableGuid
,
833 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
834 (OrderCount
+ 1) * sizeof (UINT16
),
840 if (EFI_ERROR (Status
)) {
841 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
? L
"BootOrder" : L
"DriverOrder");
842 ShellStatus
= SHELL_INVALID_PARAMETER
;
844 Print (L
"bcfg: Add %s as %x\n", OptionStr
, Position
);
851 // If always Free FilePath, will free devicepath in system when use "addh"
853 if ((FilePath
!= NULL
) && !UseHandle
) {
861 if (Handles
!= NULL
) {
865 if (FileList
!= NULL
) {
866 ShellCloseFileMetaArg (&FileList
);
869 return (ShellStatus
);
873 Funciton to remove an item.
875 @param[in] Target The target item to move.
876 @param[in] CurrentOrder The pointer to the current order of items.
877 @param[in] OrderCount The number if items in CurrentOrder.
878 @param[in] Location The current location of the Target.
880 @retval SHELL_SUCCESS The operation was successful.
881 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
885 IN CONST BCFG_OPERATION_TARGET Target
,
886 IN CONST UINT16
*CurrentOrder
,
887 IN CONST UINTN OrderCount
,
888 IN CONST UINT16 Location
891 CHAR16 VariableName
[12];
896 UnicodeSPrint (VariableName
, sizeof (VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
? L
"Boot" : L
"Driver", CurrentOrder
[Location
]);
897 Status
= gRT
->SetVariable (
899 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
900 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
904 if (EFI_ERROR (Status
)) {
905 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
906 return (SHELL_INVALID_PARAMETER
);
909 NewOrder
= AllocateZeroPool (OrderCount
*sizeof (CurrentOrder
[0]));
910 if (NewOrder
!= NULL
) {
911 NewCount
= OrderCount
;
912 CopyMem (NewOrder
, CurrentOrder
, OrderCount
*sizeof (CurrentOrder
[0]));
913 CopyMem (NewOrder
+Location
, NewOrder
+Location
+1, (OrderCount
- Location
- 1)*sizeof (CurrentOrder
[0]));
916 Status
= gRT
->SetVariable (
917 Target
== BcfgTargetBootOrder
? (CHAR16
*)L
"BootOrder" : (CHAR16
*)L
"DriverOrder",
918 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
919 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
920 NewCount
*sizeof (NewOrder
[0]),
925 Status
= EFI_OUT_OF_RESOURCES
;
928 if (EFI_ERROR (Status
)) {
929 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
? (CHAR16
*)L
"BootOrder" : (CHAR16
*)L
"DriverOrder");
930 return (SHELL_INVALID_PARAMETER
);
933 return (SHELL_SUCCESS
);
937 Funciton to move a item to another location.
939 @param[in] Target The target item to move.
940 @param[in] CurrentOrder The pointer to the current order of items.
941 @param[in] OrderCount The number if items in CurrentOrder.
942 @param[in] OldLocation The current location of the Target.
943 @param[in] NewLocation The desired location of the Target.
945 @retval SHELL_SUCCESS The operation was successful.
946 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
950 IN CONST BCFG_OPERATION_TARGET Target
,
951 IN CONST UINT16
*CurrentOrder
,
952 IN CONST UINTN OrderCount
,
953 IN CONST UINT16 OldLocation
,
954 IN UINT16 NewLocation
961 NewOrder
= AllocateCopyPool (OrderCount
*sizeof (CurrentOrder
[0]), CurrentOrder
);
962 if (NewOrder
== NULL
) {
963 return (SHELL_OUT_OF_RESOURCES
);
967 // correct the new location
969 if (NewLocation
>= OrderCount
) {
970 if (OrderCount
> 0) {
971 NewLocation
= (UINT16
)OrderCount
- 1;
977 Temp
= CurrentOrder
[OldLocation
];
978 CopyMem (NewOrder
+OldLocation
, NewOrder
+OldLocation
+1, (OrderCount
- OldLocation
- 1)*sizeof (CurrentOrder
[0]));
979 CopyMem (NewOrder
+NewLocation
+1, NewOrder
+NewLocation
, (OrderCount
- NewLocation
- 1)*sizeof (CurrentOrder
[0]));
980 NewOrder
[NewLocation
] = Temp
;
982 Status
= gRT
->SetVariable (
983 Target
== BcfgTargetBootOrder
? (CHAR16
*)L
"BootOrder" : (CHAR16
*)L
"DriverOrder",
984 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
985 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
986 OrderCount
*sizeof (CurrentOrder
[0]),
992 if (EFI_ERROR (Status
)) {
993 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
? (CHAR16
*)L
"BootOrder" : (CHAR16
*)L
"DriverOrder");
994 return (SHELL_INVALID_PARAMETER
);
997 return (SHELL_SUCCESS
);
1001 Function to add optional data to an option.
1003 @param[in] OptData The optional data to add.
1004 @param[in] CurrentOrder The pointer to the current order of items.
1005 @param[in] OrderCount The number if items in CurrentOrder.
1006 @param[in] Target The target of the operation.
1008 @retval SHELL_SUCCESS The operation was succesful.
1012 IN CONST CHAR16
*OptData
,
1013 IN CONST UINT16
*CurrentOrder
,
1014 IN CONST UINTN OrderCount
,
1015 IN CONST BCFG_OPERATION_TARGET Target
1018 EFI_KEY_OPTION NewKeyOption
;
1019 EFI_KEY_OPTION
*KeyOptionBuffer
;
1020 SHELL_STATUS ShellStatus
;
1024 UINT64 Intermediate
;
1026 CONST CHAR16
*Walker
;
1031 CHAR16 VariableName
[12];
1034 SHELL_FILE_HANDLE FileHandle
;
1036 Status
= EFI_SUCCESS
;
1037 ShellStatus
= SHELL_SUCCESS
;
1041 KeyOptionBuffer
= NULL
;
1042 VariableData
= NULL
;
1044 ZeroMem (&NewKeyOption
, sizeof (EFI_KEY_OPTION
));
1045 ZeroMem (VariableName
, sizeof (VariableName
));
1047 while (Walker
[0] == L
' ') {
1052 // Get the index of the variable we are changing.
1054 Status
= ShellConvertStringToUint64 (Walker
, &Intermediate
, TRUE
, TRUE
);
1055 if (EFI_ERROR (Status
) || (((UINT16
)Intermediate
) != Intermediate
) || (StrStr (Walker
, L
" ") == NULL
) || (((UINT16
)Intermediate
) > ((UINT16
)OrderCount
))) {
1056 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Option Index");
1057 ShellStatus
= SHELL_INVALID_PARAMETER
;
1058 return (ShellStatus
);
1061 OptionIndex
= (UINT16
)Intermediate
;
1063 Temp
= StrStr (Walker
, L
" ");
1068 while (Walker
[0] == L
' ') {
1073 // determine whether we have file with data, quote delimited information, or a hot-key
1075 if (Walker
[0] == L
'\"') {
1077 // quoted filename or quoted information.
1079 Temp
= StrStr (Walker
+1, L
"\"");
1080 if ((Temp
== NULL
) || (StrLen (Temp
) != 1)) {
1081 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1082 ShellStatus
= SHELL_INVALID_PARAMETER
;
1084 FileName
= StrnCatGrow (&FileName
, NULL
, Walker
+1, 0);
1085 if (FileName
== NULL
) {
1086 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
1087 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1088 return (ShellStatus
);
1091 Temp2
= StrStr (FileName
, L
"\"");
1092 ASSERT (Temp2
!= NULL
);
1093 Temp2
[0] = CHAR_NULL
;
1095 if (StrLen (Temp2
) > 0) {
1096 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1097 ShellStatus
= SHELL_INVALID_PARAMETER
;
1100 if (EFI_ERROR (ShellFileExists (Walker
))) {
1102 // Not a file. must be misc information.
1107 FileName
= StrnCatGrow (&FileName
, NULL
, Walker
, 0);
1112 // filename or hot key information.
1114 if (StrStr (Walker
, L
" ") == NULL
) {
1118 if (EFI_ERROR (ShellFileExists (Walker
))) {
1119 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FIND_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1120 ShellStatus
= SHELL_INVALID_PARAMETER
;
1122 FileName
= StrnCatGrow (&FileName
, NULL
, Walker
, 0);
1125 if (Target
!= BcfgTargetBootOrder
) {
1126 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_BOOT_ONLY
), gShellBcfgHiiHandle
, L
"bcfg");
1127 ShellStatus
= SHELL_INVALID_PARAMETER
;
1130 if (ShellStatus
== SHELL_SUCCESS
) {
1132 // Get hot key information
1134 Status
= ShellConvertStringToUint64 (Walker
, &Intermediate
, FALSE
, TRUE
);
1135 if (EFI_ERROR (Status
) || (((UINT32
)Intermediate
) != Intermediate
) || (StrStr (Walker
, L
" ") == NULL
)) {
1136 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1137 ShellStatus
= SHELL_INVALID_PARAMETER
;
1140 NewKeyOption
.KeyData
.PackedValue
= (UINT32
)Intermediate
;
1141 Temp
= StrStr (Walker
, L
" ");
1146 while (Walker
[0] == L
' ') {
1151 if (ShellStatus
== SHELL_SUCCESS
) {
1153 // Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.
1154 // Re-allocate with the added information.
1156 KeyOptionBuffer
= AllocatePool (sizeof (EFI_KEY_OPTION
) + (sizeof (EFI_INPUT_KEY
) * NewKeyOption
.KeyData
.Options
.InputKeyCount
));
1157 if (KeyOptionBuffer
== NULL
) {
1158 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
1159 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1163 CopyMem (KeyOptionBuffer
, &NewKeyOption
, sizeof (EFI_KEY_OPTION
));
1166 for (LoopCounter
= 0; ShellStatus
== SHELL_SUCCESS
&& LoopCounter
< NewKeyOption
.KeyData
.Options
.InputKeyCount
; LoopCounter
++) {
1170 Status
= ShellConvertStringToUint64 (Walker
, &Intermediate
, FALSE
, TRUE
);
1171 if (EFI_ERROR (Status
) || (((UINT16
)Intermediate
) != Intermediate
) || (StrStr (Walker
, L
" ") == NULL
)) {
1172 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1173 ShellStatus
= SHELL_INVALID_PARAMETER
;
1176 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof (EFI_KEY_OPTION
)))[LoopCounter
].ScanCode
= (UINT16
)Intermediate
;
1177 Temp
= StrStr (Walker
, L
" ");
1182 while (Walker
[0] == L
' ') {
1189 Status
= ShellConvertStringToUint64 (Walker
, &Intermediate
, FALSE
, TRUE
);
1190 if (EFI_ERROR (Status
) || (((UINT16
)Intermediate
) != Intermediate
)) {
1191 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1192 ShellStatus
= SHELL_INVALID_PARAMETER
;
1195 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof (EFI_KEY_OPTION
)))[LoopCounter
].UnicodeChar
= (UINT16
)Intermediate
;
1196 Temp
= StrStr (Walker
, L
" ");
1201 while (Walker
[0] == L
' ') {
1206 if (ShellStatus
== SHELL_SUCCESS
) {
1208 // Now do the BootOption / BootOptionCrc
1210 ASSERT (OptionIndex
<= OrderCount
);
1211 KeyOptionBuffer
->BootOption
= CurrentOrder
[OptionIndex
];
1212 Status
= GetBootOptionCrc (&(KeyOptionBuffer
->BootOptionCrc
), KeyOptionBuffer
->BootOption
);
1213 if (EFI_ERROR (Status
)) {
1214 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Option Index");
1215 ShellStatus
= SHELL_INVALID_PARAMETER
;
1219 if (ShellStatus
== SHELL_SUCCESS
) {
1220 for (Temp2
= NULL
, KeyIndex
= 0; KeyIndex
<= 0xFFFF; KeyIndex
++) {
1221 UnicodeSPrint (VariableName
, sizeof (VariableName
), L
"Key%04x", KeyIndex
);
1222 Status
= GetEfiGlobalVariable2 (VariableName
, &VariableData
, NULL
);
1223 if (Status
== EFI_NOT_FOUND
) {
1227 if (!EFI_ERROR (Status
)) {
1228 SHELL_FREE_NON_NULL (VariableData
);
1232 if (KeyIndex
<= 0xFFFF) {
1233 Status
= gRT
->SetVariable (
1235 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1236 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
1237 sizeof (EFI_KEY_OPTION
) + (sizeof (EFI_INPUT_KEY
) * NewKeyOption
.KeyData
.Options
.InputKeyCount
),
1240 if (EFI_ERROR (Status
)) {
1241 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1242 ShellStatus
= SHELL_INVALID_PARAMETER
;
1245 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_VAR_NO_NUM
), gShellBcfgHiiHandle
, L
"bcfg");
1246 ShellStatus
= SHELL_INVALID_PARAMETER
;
1249 ASSERT (FileName
== NULL
&& Data
== NULL
);
1255 // Shouldn't be possible to have have both. Neither is ok though.
1257 ASSERT (FileName
== NULL
|| Data
== NULL
);
1259 if ((ShellStatus
== SHELL_SUCCESS
) && ((FileName
!= NULL
) || (Data
!= NULL
))) {
1260 if (FileName
!= NULL
) {
1262 // Open the file and populate the data buffer.
1264 Status
= ShellOpenFileByName (
1270 if (!EFI_ERROR (Status
)) {
1271 Status
= ShellGetFileSize (FileHandle
, &Intermediate
);
1274 Data
= AllocateZeroPool ((UINTN
)Intermediate
);
1276 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
1277 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1280 if (!EFI_ERROR (Status
)) {
1281 Status
= ShellReadFile (FileHandle
, (UINTN
*)&Intermediate
, Data
);
1284 Intermediate
= StrSize (Data
);
1287 if (!EFI_ERROR (Status
) && (ShellStatus
== SHELL_SUCCESS
) && (Data
!= NULL
)) {
1288 Status
= UpdateOptionalData (CurrentOrder
[OptionIndex
], (UINTN
)Intermediate
, (UINT8
*)Data
, Target
);
1289 if (EFI_ERROR (Status
)) {
1290 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1291 ShellStatus
= SHELL_INVALID_PARAMETER
;
1295 if (EFI_ERROR (Status
) && (ShellStatus
== SHELL_SUCCESS
)) {
1296 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1297 ShellStatus
= SHELL_INVALID_PARAMETER
;
1301 SHELL_FREE_NON_NULL (Data
);
1302 SHELL_FREE_NON_NULL (KeyOptionBuffer
);
1303 SHELL_FREE_NON_NULL (FileName
);
1308 Function to dump the Bcfg information.
1310 @param[in] Op The operation.
1311 @param[in] OrderCount How many to dump.
1312 @param[in] CurrentOrder The pointer to the current order of items.
1313 @param[in] VerboseOutput TRUE for extra output. FALSE otherwise.
1315 @retval SHELL_SUCCESS The dump was successful.
1316 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
1320 IN CONST CHAR16
*Op
,
1321 IN CONST UINTN OrderCount
,
1322 IN CONST UINT16
*CurrentOrder
,
1323 IN CONST BOOLEAN VerboseOutput
1329 CHAR16 VariableName
[12];
1331 CHAR16
*DevPathString
;
1334 EFI_LOAD_OPTION
*LoadOption
;
1335 CHAR16
*Description
;
1336 UINTN DescriptionSize
;
1337 UINTN OptionalDataOffset
;
1339 if (OrderCount
== 0) {
1340 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NONE
), gShellBcfgHiiHandle
, L
"bcfg");
1341 return (SHELL_SUCCESS
);
1346 for (LoopVar
= 0; LoopVar
< OrderCount
; LoopVar
++) {
1349 DevPathString
= NULL
;
1351 UnicodeSPrint (VariableName
, sizeof (VariableName
), L
"%s%04x", Op
, CurrentOrder
[LoopVar
]);
1353 Status
= gRT
->GetVariable (
1355 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1360 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1361 Buffer
= AllocateZeroPool (BufferSize
);
1362 Status
= gRT
->GetVariable (
1364 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1371 if (EFI_ERROR (Status
) || (Buffer
== NULL
)) {
1372 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_READ_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1378 // We expect the Attributes, FilePathListLength, and L'\0'-terminated
1379 // Description fields to be present.
1381 if (BufferSize
< sizeof *LoadOption
+ sizeof (CHAR16
)) {
1386 STRING_TOKEN (STR_BCFG_VAR_CORRUPT
),
1387 gShellBcfgHiiHandle
,
1395 LoadOption
= (EFI_LOAD_OPTION
*)Buffer
;
1396 Description
= (CHAR16
*)(Buffer
+ sizeof (EFI_LOAD_OPTION
));
1397 DescriptionSize
= StrSize (Description
);
1399 if (LoadOption
->FilePathListLength
!= 0) {
1400 FilePathList
= (UINT8
*)Description
+ DescriptionSize
;
1401 DevPathString
= ConvertDevicePathToText (FilePathList
, TRUE
, FALSE
);
1404 OptionalDataOffset
= sizeof *LoadOption
+ DescriptionSize
+
1405 LoadOption
->FilePathListLength
;
1411 STRING_TOKEN (STR_BCFG_LOAD_OPTIONS
),
1412 gShellBcfgHiiHandle
,
1417 OptionalDataOffset
>= BufferSize
? L
'N' : L
'Y'
1419 if (VerboseOutput
&& (OptionalDataOffset
< BufferSize
)) {
1422 0, // Offset (displayed)
1423 BufferSize
- OptionalDataOffset
, // DataSize
1424 Buffer
+ OptionalDataOffset
// UserData
1429 if (Buffer
!= NULL
) {
1433 if (DevPathString
!= NULL
) {
1434 FreePool (DevPathString
);
1438 return (Errors
> 0) ? SHELL_INVALID_PARAMETER
: SHELL_SUCCESS
;
1442 Function to initialize the BCFG operation structure.
1444 @param[in] Struct The stuct to initialize.
1448 IN BGFG_OPERATION
*Struct
1451 ASSERT (Struct
!= NULL
);
1452 Struct
->Target
= BcfgTargetMax
;
1453 Struct
->Type
= BcfgTypeMax
;
1454 Struct
->Number1
= 0;
1455 Struct
->Number2
= 0;
1456 Struct
->HandleIndex
= 0;
1457 Struct
->FileName
= NULL
;
1458 Struct
->Description
= NULL
;
1459 Struct
->Order
= NULL
;
1460 Struct
->OptData
= NULL
;
1463 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
1464 { L
"-v", TypeFlag
},
1465 { L
"-opt", TypeMaxValue
},
1470 Function for 'bcfg' command.
1472 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1473 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1477 ShellCommandRunBcfg (
1478 IN EFI_HANDLE ImageHandle
,
1479 IN EFI_SYSTEM_TABLE
*SystemTable
1483 LIST_ENTRY
*Package
;
1484 CHAR16
*ProblemParam
;
1485 SHELL_STATUS ShellStatus
;
1487 CONST CHAR16
*CurrentParam
;
1488 BGFG_OPERATION CurrentOperation
;
1490 UINT64 Intermediate
;
1494 ProblemParam
= NULL
;
1496 ShellStatus
= SHELL_SUCCESS
;
1498 InitBcfgStruct (&CurrentOperation
);
1501 // initialize the shell lib (we must be in non-auto-init...)
1503 Status
= ShellInitialize ();
1504 ASSERT_EFI_ERROR (Status
);
1506 Status
= CommandInit ();
1507 ASSERT_EFI_ERROR (Status
);
1510 // parse the command line
1512 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
1513 if (EFI_ERROR (Status
)) {
1514 if ((Status
== EFI_VOLUME_CORRUPTED
) && (ProblemParam
!= NULL
)) {
1515 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, L
"bcfg", ProblemParam
);
1516 FreePool (ProblemParam
);
1517 ShellStatus
= SHELL_INVALID_PARAMETER
;
1523 // Read in if we are doing -OPT
1525 if (ShellCommandLineGetFlag (Package
, L
"-opt")) {
1526 CurrentOperation
.OptData
= ShellCommandLineGetValue (Package
, L
"-opt");
1527 if (CurrentOperation
.OptData
== NULL
) {
1528 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellBcfgHiiHandle
, L
"bcfg", L
"-opt");
1529 ShellStatus
= SHELL_INVALID_PARAMETER
;
1532 CurrentOperation
.Type
= BcfgTypeOpt
;
1536 // small block to read the target of the operation
1538 if (((ShellCommandLineGetCount (Package
) < 3) && (CurrentOperation
.Type
!= BcfgTypeOpt
)) ||
1539 ((ShellCommandLineGetCount (Package
) < 2) && (CurrentOperation
.Type
== BcfgTypeOpt
))
1542 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1543 ShellStatus
= SHELL_INVALID_PARAMETER
;
1544 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue (Package
, 1), L
"driver") == 0) {
1545 CurrentOperation
.Target
= BcfgTargetDriverOrder
;
1546 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue (Package
, 1), L
"boot") == 0) {
1547 CurrentOperation
.Target
= BcfgTargetBootOrder
;
1549 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT
), gShellBcfgHiiHandle
, L
"bcfg");
1550 ShellStatus
= SHELL_INVALID_PARAMETER
;
1554 // Read in the boot or driver order environment variable (not needed for opt)
1556 if ((ShellStatus
== SHELL_SUCCESS
) && (CurrentOperation
.Target
< BcfgTargetMax
)) {
1558 Status
= gRT
->GetVariable (
1559 CurrentOperation
.Target
== BcfgTargetBootOrder
? (CHAR16
*)L
"BootOrder" : (CHAR16
*)L
"DriverOrder",
1560 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1563 CurrentOperation
.Order
1565 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1566 CurrentOperation
.Order
= AllocateZeroPool (Length
+(4*sizeof (CurrentOperation
.Order
[0])));
1567 if (CurrentOperation
.Order
== NULL
) {
1568 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1570 Status
= gRT
->GetVariable (
1571 CurrentOperation
.Target
== BcfgTargetBootOrder
? (CHAR16
*)L
"BootOrder" : (CHAR16
*)L
"DriverOrder",
1572 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1575 CurrentOperation
.Order
1581 Count
= (UINT16
)(Length
/ sizeof (CurrentOperation
.Order
[0]));
1584 // large block to read the type of operation and verify parameter types for the info.
1586 if ((ShellStatus
== SHELL_SUCCESS
) && (CurrentOperation
.Target
< BcfgTargetMax
)) {
1587 for (ParamNumber
= 2; ParamNumber
< ShellCommandLineGetCount (Package
) && ShellStatus
== SHELL_SUCCESS
; ParamNumber
++) {
1588 CurrentParam
= ShellCommandLineGetRawValue (Package
, ParamNumber
);
1589 if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"dump") == 0) {
1590 CurrentOperation
.Type
= BcfgTypeDump
;
1591 if (ShellCommandLineGetCount (Package
) > 3) {
1592 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellBcfgHiiHandle
, L
"bcfg");
1593 ShellStatus
= SHELL_INVALID_PARAMETER
;
1595 } else if (ShellCommandLineGetFlag (Package
, L
"-v")) {
1596 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"-v (without dump)");
1597 ShellStatus
= SHELL_INVALID_PARAMETER
;
1598 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"add") == 0) {
1599 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount (Package
)) {
1600 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1601 ShellStatus
= SHELL_INVALID_PARAMETER
;
1604 CurrentOperation
.Type
= BcfgTypeAdd
;
1605 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1606 if ((CurrentParam
== NULL
) || !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1607 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1608 ShellStatus
= SHELL_INVALID_PARAMETER
;
1610 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1611 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1612 ASSERT (CurrentOperation
.FileName
== NULL
);
1613 CurrentOperation
.FileName
= StrnCatGrow (&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue (Package
, ++ParamNumber
), 0);
1614 ASSERT (CurrentOperation
.Description
== NULL
);
1615 CurrentOperation
.Description
= StrnCatGrow (&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue (Package
, ++ParamNumber
), 0);
1617 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addp") == 0) {
1618 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount (Package
)) {
1619 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1620 ShellStatus
= SHELL_INVALID_PARAMETER
;
1623 CurrentOperation
.Type
= BcfgTypeAddp
;
1624 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1625 if ((CurrentParam
== NULL
) || !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1626 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1627 ShellStatus
= SHELL_INVALID_PARAMETER
;
1629 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1630 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1631 ASSERT (CurrentOperation
.FileName
== NULL
);
1632 CurrentOperation
.FileName
= StrnCatGrow (&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue (Package
, ++ParamNumber
), 0);
1633 ASSERT (CurrentOperation
.Description
== NULL
);
1634 CurrentOperation
.Description
= StrnCatGrow (&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue (Package
, ++ParamNumber
), 0);
1636 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addh") == 0) {
1637 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount (Package
)) {
1638 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1639 ShellStatus
= SHELL_INVALID_PARAMETER
;
1642 CurrentOperation
.Type
= BcfgTypeAddh
;
1643 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1644 if ((CurrentParam
== NULL
) || !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1645 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1646 ShellStatus
= SHELL_INVALID_PARAMETER
;
1648 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1649 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1650 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1651 if ((CurrentParam
== NULL
) || !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1652 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1653 ShellStatus
= SHELL_INVALID_PARAMETER
;
1655 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1656 CurrentOperation
.HandleIndex
= (UINT16
)Intermediate
;
1657 ASSERT (CurrentOperation
.Description
== NULL
);
1658 CurrentOperation
.Description
= StrnCatGrow (&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue (Package
, ++ParamNumber
), 0);
1661 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"rm") == 0) {
1662 if ((ParamNumber
+ 1) >= ShellCommandLineGetCount (Package
)) {
1663 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1664 ShellStatus
= SHELL_INVALID_PARAMETER
;
1667 CurrentOperation
.Type
= BcfgTypeRm
;
1668 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1669 if ((CurrentParam
== NULL
) || !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1670 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1671 ShellStatus
= SHELL_INVALID_PARAMETER
;
1673 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1674 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1675 if (CurrentOperation
.Number1
>= Count
) {
1676 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1677 ShellStatus
= SHELL_INVALID_PARAMETER
;
1680 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"mv") == 0) {
1681 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount (Package
)) {
1682 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1683 ShellStatus
= SHELL_INVALID_PARAMETER
;
1686 CurrentOperation
.Type
= BcfgTypeMv
;
1687 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1688 if ((CurrentParam
== NULL
) || !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1689 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1690 ShellStatus
= SHELL_INVALID_PARAMETER
;
1692 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1693 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1694 if (CurrentOperation
.Number1
>= Count
) {
1695 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1696 ShellStatus
= SHELL_INVALID_PARAMETER
;
1698 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1699 if ((CurrentParam
== NULL
) || !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1700 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1701 ShellStatus
= SHELL_INVALID_PARAMETER
;
1703 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1704 CurrentOperation
.Number2
= (UINT16
)Intermediate
;
1707 if ( (CurrentOperation
.Number2
== CurrentOperation
.Number1
)
1708 || (CurrentOperation
.Number2
>= Count
)
1711 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1712 ShellStatus
= SHELL_INVALID_PARAMETER
;
1716 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"mod") == 0) {
1717 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount (Package
)) {
1718 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1719 ShellStatus
= SHELL_INVALID_PARAMETER
;
1721 CurrentOperation
.Type
= BcfgTypeMod
;
1722 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1723 if ((CurrentParam
== NULL
) || !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1724 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1725 ShellStatus
= SHELL_INVALID_PARAMETER
;
1727 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1728 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1729 if (CurrentOperation
.Number1
>= Count
) {
1730 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1731 ShellStatus
= SHELL_INVALID_PARAMETER
;
1733 ASSERT (CurrentOperation
.Description
== NULL
);
1734 CurrentOperation
.Description
= StrnCatGrow (&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue (Package
, ++ParamNumber
), 0);
1738 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"modf") == 0) {
1739 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount (Package
)) {
1740 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1741 ShellStatus
= SHELL_INVALID_PARAMETER
;
1743 CurrentOperation
.Type
= BcfgTypeModf
;
1744 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1745 if ((CurrentParam
== NULL
) || !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1746 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1747 ShellStatus
= SHELL_INVALID_PARAMETER
;
1749 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1750 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1751 if (CurrentOperation
.Number1
>= Count
) {
1752 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1753 ShellStatus
= SHELL_INVALID_PARAMETER
;
1755 ASSERT (CurrentOperation
.FileName
== NULL
);
1756 CurrentOperation
.FileName
= StrnCatGrow (&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue (Package
, ++ParamNumber
), 0);
1760 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"modp") == 0) {
1761 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount (Package
)) {
1762 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1763 ShellStatus
= SHELL_INVALID_PARAMETER
;
1765 CurrentOperation
.Type
= BcfgTypeModp
;
1766 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1767 if ((CurrentParam
== NULL
) || !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1768 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1769 ShellStatus
= SHELL_INVALID_PARAMETER
;
1771 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1772 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1773 if (CurrentOperation
.Number1
>= Count
) {
1774 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1775 ShellStatus
= SHELL_INVALID_PARAMETER
;
1777 ASSERT (CurrentOperation
.FileName
== NULL
);
1778 CurrentOperation
.FileName
= StrnCatGrow (&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue (Package
, ++ParamNumber
), 0);
1782 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"modh") == 0) {
1783 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount (Package
)) {
1784 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1785 ShellStatus
= SHELL_INVALID_PARAMETER
;
1787 CurrentOperation
.Type
= BcfgTypeModh
;
1788 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1789 if ((CurrentParam
== NULL
) || !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1790 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1791 ShellStatus
= SHELL_INVALID_PARAMETER
;
1793 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1794 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1795 if (CurrentOperation
.Number1
>= Count
) {
1796 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1797 ShellStatus
= SHELL_INVALID_PARAMETER
;
1799 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1800 if ((CurrentParam
== NULL
) || !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1801 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1802 ShellStatus
= SHELL_INVALID_PARAMETER
;
1804 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1805 CurrentOperation
.HandleIndex
= (UINT16
)Intermediate
;
1811 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1812 ShellStatus
= SHELL_INVALID_PARAMETER
;
1817 if ((ShellStatus
== SHELL_SUCCESS
) && (CurrentOperation
.Target
< BcfgTargetMax
) && (CurrentOperation
.Type
< BcfgTypeMax
)) {
1819 // we have all the info. Do the work
1821 switch (CurrentOperation
.Type
) {
1823 ShellStatus
= BcfgDisplayDump (
1824 CurrentOperation
.Target
== BcfgTargetBootOrder
? L
"Boot" : L
"Driver",
1826 CurrentOperation
.Order
,
1827 ShellCommandLineGetFlag (Package
, L
"-v")
1831 ShellStatus
= BcfgMove (
1832 CurrentOperation
.Target
,
1833 CurrentOperation
.Order
,
1835 CurrentOperation
.Number1
,
1836 CurrentOperation
.Number2
1840 ShellStatus
= BcfgRemove (
1841 CurrentOperation
.Target
,
1842 CurrentOperation
.Order
,
1844 CurrentOperation
.Number1
1850 ShellStatus
= BcfgAdd (
1851 CurrentOperation
.Number1
,
1852 CurrentOperation
.FileName
,
1853 CurrentOperation
.Description
== NULL
? L
"" : CurrentOperation
.Description
,
1854 CurrentOperation
.Order
,
1856 CurrentOperation
.Target
,
1857 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddh
),
1858 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddp
),
1859 CurrentOperation
.HandleIndex
1866 ShellStatus
= BcfgMod (&CurrentOperation
, Count
);
1869 ShellStatus
= BcfgAddOpt (
1870 CurrentOperation
.OptData
,
1871 CurrentOperation
.Order
,
1873 CurrentOperation
.Target
1882 if (Package
!= NULL
) {
1883 ShellCommandLineFreeVarList (Package
);
1886 if (CurrentOperation
.FileName
!= NULL
) {
1887 FreePool (CurrentOperation
.FileName
);
1890 if (CurrentOperation
.Description
!= NULL
) {
1891 FreePool (CurrentOperation
.Description
);
1894 if (CurrentOperation
.Order
!= NULL
) {
1895 FreePool (CurrentOperation
.Order
);
1898 return (ShellStatus
);
1902 Function to get the filename with help context if HII will not be used.
1904 @return The filename with help text in it.
1908 ShellCommandGetManFileNameBcfg (
1916 "Constructor" for the library.
1918 This will register the handler for the bcfg command.
1920 @param[in] ImageHandle the image handle of the process
1921 @param[in] SystemTable the EFI System Table pointer
1922 @param[in] Name the profile name to use
1924 @retval EFI_SUCCESS the shell command handlers were installed sucessfully
1925 @retval EFI_UNSUPPORTED the shell level required was not found.
1929 BcfgLibraryRegisterBcfgCommand (
1930 IN EFI_HANDLE ImageHandle
,
1931 IN EFI_SYSTEM_TABLE
*SystemTable
,
1932 IN CONST CHAR16
*Name
1935 if (gShellBcfgHiiHandle
!= NULL
) {
1936 return (EFI_SUCCESS
);
1939 gShellBcfgHiiHandle
= HiiAddPackages (&gShellBcfgHiiGuid
, gImageHandle
, UefiShellBcfgCommandLibStrings
, NULL
);
1940 if (gShellBcfgHiiHandle
== NULL
) {
1941 return (EFI_DEVICE_ERROR
);
1945 // install our shell command handler
1947 ShellCommandRegisterCommandName (L
"bcfg", ShellCommandRunBcfg
, ShellCommandGetManFileNameBcfg
, 0, Name
, FALSE
, gShellBcfgHiiHandle
, STRING_TOKEN (STR_GET_HELP_BCFG
));
1949 return (EFI_SUCCESS
);
1953 Destructor for the library. free any resources.
1955 @param ImageHandle The image handle of the process.
1956 @param SystemTable The EFI System Table pointer.
1960 BcfgLibraryUnregisterBcfgCommand (
1961 IN EFI_HANDLE ImageHandle
,
1962 IN EFI_SYSTEM_TABLE
*SystemTable
1965 if (gShellBcfgHiiHandle
!= NULL
) {
1966 HiiRemovePackages (gShellBcfgHiiHandle
);
1969 gShellBcfgHiiHandle
= NULL
;
1970 return (EFI_SUCCESS
);