2 Main file for BCFG command.
4 (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include <Guid/GlobalVariable.h>
20 #include <Guid/ShellLibHiiGuid.h>
22 #include <Protocol/Shell.h>
23 #include <Protocol/ShellParameters.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>
44 #include <Library/UefiBootManagerLib.h>
46 STATIC CONST CHAR16 mFileName
[] = L
"ShellCommands";
47 STATIC EFI_HANDLE gShellBcfgHiiHandle
= NULL
;
50 BcfgTargetBootOrder
= 0,
51 BcfgTargetDriverOrder
= 1,
53 } BCFG_OPERATION_TARGET
;
68 } BCFG_OPERATION_TYPE
;
71 BCFG_OPERATION_TARGET Target
;
72 BCFG_OPERATION_TYPE Type
;
79 CONST CHAR16
*OptData
;
83 Update the optional data for a boot or driver option.
85 If optional data exists it will be changed.
87 @param[in] Index The boot or driver option index update.
88 @param[in] DataSize The size in bytes of Data.
89 @param[in] Data The buffer for the optioanl data.
90 @param[in] Target The target of the operation.
92 @retval EFI_SUCCESS The data was sucessfully updated.
93 @retval other A error occured.
100 IN CONST BCFG_OPERATION_TARGET Target
104 CHAR16 VariableName
[12];
109 UINTN OriginalOptionDataSize
;
111 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", Index
);
118 Status
= gRT
->GetVariable(
120 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
124 if (Status
== EFI_BUFFER_TOO_SMALL
) {
125 OriginalData
= AllocateZeroPool(OriginalSize
);
126 if (OriginalData
== NULL
) {
127 return (EFI_OUT_OF_RESOURCES
);
129 Status
= gRT
->GetVariable(
131 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
137 if (!EFI_ERROR(Status
)) {
139 // Allocate new struct and discard old optional data.
141 ASSERT (OriginalData
!= NULL
);
142 OriginalOptionDataSize
= sizeof(UINT32
) + sizeof(UINT16
) + StrSize(((CHAR16
*)(OriginalData
+ sizeof(UINT32
) + sizeof(UINT16
))));
143 OriginalOptionDataSize
+= (*(UINT16
*)(OriginalData
+ sizeof(UINT32
)));
144 OriginalOptionDataSize
-= OriginalSize
;
145 NewSize
= OriginalSize
- OriginalOptionDataSize
+ DataSize
;
146 NewData
= AllocatePool(NewSize
);
147 if (NewData
== NULL
) {
148 Status
= EFI_OUT_OF_RESOURCES
;
150 CopyMem (NewData
, OriginalData
, OriginalSize
- OriginalOptionDataSize
);
151 CopyMem(NewData
+ OriginalSize
- OriginalOptionDataSize
, Data
, DataSize
);
155 if (!EFI_ERROR(Status
)) {
157 // put the data back under the variable
159 Status
= gRT
->SetVariable(
161 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
162 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
167 SHELL_FREE_NON_NULL(OriginalData
);
168 SHELL_FREE_NON_NULL(NewData
);
173 This function will get a CRC for a boot option.
175 @param[in, out] Crc The CRC value to return.
176 @param[in] BootIndex The boot option index to CRC.
178 @retval EFI_SUCCESS The CRC was sucessfully returned.
179 @retval other A error occured.
187 CHAR16 VariableName
[12];
196 // Get the data Buffer
198 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%Boot%04x", BootIndex
);
199 Status
= gRT
->GetVariable(
201 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
205 if (Status
== EFI_BUFFER_TOO_SMALL
) {
206 Buffer
= AllocateZeroPool(BufferSize
);
207 Status
= gRT
->GetVariable(
209 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
216 // Get the CRC computed
218 if (!EFI_ERROR(Status
)) {
219 Status
= gBS
->CalculateCrc32 (Buffer
, BufferSize
, Crc
);
222 SHELL_FREE_NON_NULL(Buffer
);
227 This function will populate the device path protocol parameter based on TheHandle.
229 @param[in] TheHandle Driver handle.
230 @param[in, out] FilePath On a sucessful return the device path to the handle.
232 @retval EFI_SUCCESS The device path was sucessfully returned.
233 @retval other A error from gBS->HandleProtocol.
238 GetDevicePathForDriverHandle (
239 IN EFI_HANDLE TheHandle
,
240 IN OUT EFI_DEVICE_PATH_PROTOCOL
**FilePath
244 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
245 EFI_DEVICE_PATH_PROTOCOL
*ImageDevicePath
;
247 Status
= gBS
->OpenProtocol (
249 &gEfiLoadedImageProtocolGuid
,
250 (VOID
**)&LoadedImage
,
253 EFI_OPEN_PROTOCOL_GET_PROTOCOL
255 if (!EFI_ERROR (Status
)) {
256 Status
= gBS
->OpenProtocol (
257 LoadedImage
->DeviceHandle
,
258 &gEfiDevicePathProtocolGuid
,
259 (VOID
**)&ImageDevicePath
,
262 EFI_OPEN_PROTOCOL_GET_PROTOCOL
264 if (!EFI_ERROR (Status
)) {
265 // *DevPath = DuplicateDevicePath (ImageDevicePath);
266 // *FilePath = DuplicateDevicePath (LoadedImage->FilePath);
267 *FilePath
= AppendDevicePath(ImageDevicePath
,LoadedImage
->FilePath
);
269 LoadedImage
->DeviceHandle
,
270 &gEfiDevicePathProtocolGuid
,
276 &gEfiLoadedImageProtocolGuid
,
284 Functino to get Device Path by a handle.
286 @param[in] TheHandle Use it to get DevicePath.
287 @param[in] Target Boot option target.
288 @param[in, out] DevicePath On a sucessful return the device path to the handle.
290 @retval SHELL_INVALID_PARAMETER The handle was NULL.
291 @retval SHELL_NOT_FOUND Not found device path by handle.
292 @retval SHELL_SUCCESS Get device path successfully.
295 GetDevicePathByHandle(
296 IN EFI_HANDLE TheHandle
,
297 IN BCFG_OPERATION_TARGET Target
,
298 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePath
302 SHELL_STATUS ShellStatus
;
304 UINTN DriverBindingHandleCount
;
305 UINTN ParentControllerHandleCount
;
306 UINTN ChildControllerHandleCount
;
308 ShellStatus
= SHELL_SUCCESS
;
310 if (TheHandle
== NULL
) {
311 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Handle Number");
312 return SHELL_INVALID_PARAMETER
;
315 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (TheHandle
, &DriverBindingHandleCount
, NULL
);
316 if (EFI_ERROR(Status
)) {
317 DriverBindingHandleCount
= 0;
320 Status
= PARSE_HANDLE_DATABASE_PARENTS (TheHandle
, &ParentControllerHandleCount
, NULL
);
321 if (EFI_ERROR (Status
)) {
322 ParentControllerHandleCount
= 0;
325 Status
= ParseHandleDatabaseForChildControllers (TheHandle
, &ChildControllerHandleCount
, NULL
);
326 if (EFI_ERROR (Status
)) {
327 ChildControllerHandleCount
= 0;
330 Status
= gBS
->HandleProtocol (TheHandle
, &gEfiDevicePathProtocolGuid
, (VOID
**)DevicePath
);
332 if ( DriverBindingHandleCount
> 0 ||
333 ParentControllerHandleCount
> 0 ||
334 ChildControllerHandleCount
> 0 ||
338 // The handle points to a real controller which has a device path.
340 if (Target
== BcfgTargetDriverOrder
) {
344 NULL
,STRING_TOKEN (STR_GEN_PARAM_INV
),
347 L
"Handle should point to driver image."
349 ShellStatus
= SHELL_NOT_FOUND
;
353 // The handle points to a driver image.
355 if (Target
== BcfgTargetBootOrder
) {
360 STRING_TOKEN (STR_GEN_PARAM_INV
),
363 L
"Handle should point to controller."
365 ShellStatus
= SHELL_NOT_FOUND
;
367 if (EFI_ERROR (GetDevicePathForDriverHandle (TheHandle
, DevicePath
))) {
368 ShellStatus
= SHELL_NOT_FOUND
;
373 return (ShellStatus
);
377 Function to modify an option.
379 @param[in] BcfgOperation Pointer to BCFG operation.
380 @param[in] OrderCount The number if items in CurrentOrder.
382 @retval SHELL_SUCCESS The operation was successful.
383 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
384 @retval SHELL_OUT_OF_RESOUCES A memory allocation failed.
388 IN CONST BGFG_OPERATION
*BcfgOperation
,
389 IN CONST UINTN OrderCount
393 EFI_HANDLE CurHandle
;
394 SHELL_STATUS ShellStatus
;
395 CHAR16 OptionStr
[40];
396 EFI_SHELL_FILE_INFO
*FileList
;
397 EFI_SHELL_FILE_INFO
*Arg
;
398 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
399 EFI_DEVICE_PATH_PROTOCOL
*DevicePathBuffer
;
400 EFI_DEVICE_PATH_PROTOCOL
*DevicePathWalker
;
401 EFI_BOOT_MANAGER_LOAD_OPTION LoadOption
;
403 ShellStatus
= SHELL_SUCCESS
;
406 DevicePathBuffer
= NULL
;
408 ZeroMem (&LoadOption
, sizeof(EFI_BOOT_MANAGER_LOAD_OPTION
));
410 if ( (BcfgOperation
->Type
== BcfgTypeMod
&& BcfgOperation
->Description
== NULL
) ||
411 (BcfgOperation
->Type
== BcfgTypeModf
&& BcfgOperation
->FileName
== NULL
) ||
412 (BcfgOperation
->Type
== BcfgTypeModp
&& BcfgOperation
->FileName
== NULL
) ||
413 (BcfgOperation
->Type
== BcfgTypeModh
&& BcfgOperation
->HandleIndex
== 0) ||
414 (BcfgOperation
->Number1
> OrderCount
)
416 return (SHELL_INVALID_PARAMETER
);
419 if (BcfgOperation
->Type
== BcfgTypeModh
) {
420 CurHandle
= ConvertHandleIndexToHandle (BcfgOperation
->HandleIndex
);
421 ShellStatus
= GetDevicePathByHandle (CurHandle
, BcfgOperation
->Target
, &DevicePathBuffer
);
422 if (ShellStatus
== SHELL_SUCCESS
) {
423 DevicePath
= DuplicateDevicePath (DevicePathBuffer
);
425 } else if (BcfgOperation
->Type
== BcfgTypeModf
|| BcfgOperation
->Type
== BcfgTypeModp
) {
427 // Get Device Path by FileName.
429 ShellOpenFileMetaArg ((CHAR16
*)BcfgOperation
->FileName
, EFI_FILE_MODE_READ
, &FileList
);
430 if (FileList
== NULL
) {
432 // The name of file matched nothing.
434 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", BcfgOperation
->FileName
);
435 ShellStatus
= SHELL_INVALID_PARAMETER
;
437 else if (FileList
->Link
.ForwardLink
!= FileList
->Link
.BackLink
) {
439 // If the name of file expanded to multiple names, it's fail.
441 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE
), gShellBcfgHiiHandle
, L
"bcfg", BcfgOperation
->FileName
);
442 ShellStatus
= SHELL_INVALID_PARAMETER
;
444 Arg
= (EFI_SHELL_FILE_INFO
*)GetFirstNode (&FileList
->Link
);
445 if (EFI_ERROR (Arg
->Status
)) {
446 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_OPEN
), gShellBcfgHiiHandle
, L
"bcfg", BcfgOperation
->FileName
);
447 ShellStatus
= SHELL_INVALID_PARAMETER
;
449 DevicePathBuffer
= gEfiShellProtocol
->GetDevicePathFromFilePath (Arg
->FullName
);
450 if (DevicePathBuffer
== NULL
) {
451 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_DP
), gShellBcfgHiiHandle
, L
"bcfg", Arg
->FullName
);
452 ShellStatus
= SHELL_UNSUPPORTED
;
457 if (ShellStatus
== SHELL_SUCCESS
) {
458 if (BcfgOperation
->Type
== BcfgTypeModp
) {
459 ShellStatus
= SHELL_INVALID_PARAMETER
;
460 DevicePathWalker
= DevicePathBuffer
;
461 while (!IsDevicePathEnd (DevicePathWalker
)) {
462 if ( DevicePathType (DevicePathWalker
) == MEDIA_DEVICE_PATH
&&
463 DevicePathSubType (DevicePathWalker
) == MEDIA_HARDDRIVE_DP
466 // We found the portion of device path starting with the hard driver partition.
468 ShellStatus
= SHELL_SUCCESS
;
469 DevicePath
= DuplicateDevicePath (DevicePathWalker
);
472 DevicePathWalker
= NextDevicePathNode (DevicePathWalker
);
476 DevicePath
= DuplicateDevicePath (DevicePathBuffer
);
479 FreePool (DevicePathBuffer
);
483 if (ShellStatus
== SHELL_SUCCESS
) {
484 if (BcfgOperation
->Target
== BcfgTargetBootOrder
) {
485 UnicodeSPrint (OptionStr
, sizeof (OptionStr
), L
"Boot%04x", BcfgOperation
->Order
[BcfgOperation
->Number1
]);
487 UnicodeSPrint (OptionStr
, sizeof (OptionStr
), L
"Driver%04x", BcfgOperation
->Order
[BcfgOperation
->Number1
]);
489 Status
= EfiBootManagerVariableToLoadOption (OptionStr
, &LoadOption
);
490 if (EFI_ERROR(Status
)) {
491 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NONE
), gShellBcfgHiiHandle
);
492 ShellStatus
= SHELL_NOT_FOUND
;
496 if (ShellStatus
== SHELL_SUCCESS
) {
497 if (BcfgOperation
->Type
== BcfgTypeMod
) {
498 SHELL_FREE_NON_NULL (LoadOption
.Description
);
499 LoadOption
.Description
= AllocateCopyPool (StrSize (BcfgOperation
->Description
), BcfgOperation
->Description
);
501 SHELL_FREE_NON_NULL (LoadOption
.FilePath
);
502 LoadOption
.FilePath
= DuplicateDevicePath (DevicePath
);
505 Status
= EfiBootManagerLoadOptionToVariable (&LoadOption
);
506 if (EFI_ERROR(Status
)) {
507 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", OptionStr
);
508 ShellStatus
= SHELL_INVALID_PARAMETER
;
512 EfiBootManagerFreeLoadOption (&LoadOption
);
514 if (DevicePath
!= NULL
) {
515 FreePool (DevicePath
);
518 if (FileList
!= NULL
) {
519 ShellCloseFileMetaArg (&FileList
);
522 return (ShellStatus
);
526 Function to add a option.
528 @param[in] Position The position to add Target at.
529 @param[in] File The file to make the target.
530 @param[in] Desc The description text.
531 @param[in] CurrentOrder The pointer to the current order of items.
532 @param[in] OrderCount The number if items in CurrentOrder.
533 @param[in] Target The info on the option to add.
534 @param[in] UseHandle TRUE to use HandleNumber, FALSE to use File and Desc.
535 @param[in] UsePath TRUE to convert to devicepath.
536 @param[in] HandleNumber The handle number to add.
538 @retval SHELL_SUCCESS The operation was successful.
539 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
544 IN CONST CHAR16
*File
,
545 IN CONST CHAR16
*Desc
,
546 IN CONST UINT16
*CurrentOrder
,
547 IN CONST UINTN OrderCount
,
548 IN CONST BCFG_OPERATION_TARGET Target
,
549 IN CONST BOOLEAN UseHandle
,
550 IN CONST BOOLEAN UsePath
,
551 IN CONST UINTN HandleNumber
555 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
556 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
557 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
559 UINT8
*TempByteBuffer
;
560 UINT8
*TempByteStart
;
561 EFI_SHELL_FILE_INFO
*Arg
;
562 EFI_SHELL_FILE_INFO
*FileList
;
563 CHAR16 OptionStr
[40];
564 UINTN DescSize
, FilePathSize
;
566 UINTN TargetLocation
;
569 EFI_HANDLE CurHandle
;
570 UINTN DriverBindingHandleCount
;
571 UINTN ParentControllerHandleCount
;
572 UINTN ChildControllerHandleCount
;
573 SHELL_STATUS ShellStatus
;
577 if (File
== NULL
|| Desc
== NULL
) {
578 return (SHELL_INVALID_PARAMETER
);
581 if (HandleNumber
== 0) {
582 return (SHELL_INVALID_PARAMETER
);
586 if (Position
> OrderCount
) {
587 Position
= OrderCount
;
594 ShellStatus
= SHELL_SUCCESS
;
595 TargetLocation
= 0xFFFF;
598 CurHandle
= ConvertHandleIndexToHandle(HandleNumber
);
599 if (CurHandle
== NULL
) {
600 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Handle Number");
601 ShellStatus
= SHELL_INVALID_PARAMETER
;
603 if (Target
== BcfgTargetBootOrder
) {
605 //Make sure that the handle should point to a real controller
607 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
609 &DriverBindingHandleCount
,
612 Status
= PARSE_HANDLE_DATABASE_PARENTS (
614 &ParentControllerHandleCount
,
617 Status
= ParseHandleDatabaseForChildControllers (
619 &ChildControllerHandleCount
,
622 if (DriverBindingHandleCount
> 0
623 || ParentControllerHandleCount
> 0
624 || ChildControllerHandleCount
> 0) {
626 Status
= gBS
->HandleProtocol (
628 &gEfiDevicePathProtocolGuid
,
631 if (EFI_ERROR (Status
)) {
632 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_HANDLE
), gShellBcfgHiiHandle
, L
"bcfg", HandleNumber
);
633 ShellStatus
= SHELL_INVALID_PARAMETER
;
637 //Make sure that the handle should point to driver, not a controller.
639 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
641 &DriverBindingHandleCount
,
644 Status
= PARSE_HANDLE_DATABASE_PARENTS (
646 &ParentControllerHandleCount
,
649 Status
= ParseHandleDatabaseForChildControllers (
651 &ChildControllerHandleCount
,
654 Status
= gBS
->HandleProtocol (
656 &gEfiDevicePathProtocolGuid
,
659 if (DriverBindingHandleCount
> 0
660 || ParentControllerHandleCount
> 0
661 || ChildControllerHandleCount
> 0
662 || !EFI_ERROR(Status
) ) {
663 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Handle Number");
664 ShellStatus
= SHELL_INVALID_PARAMETER
;
667 // Get the DevicePath from the loaded image information.
669 Status
= GetDevicePathForDriverHandle(CurHandle
, &FilePath
);
677 ShellOpenFileMetaArg ((CHAR16
*)File
, EFI_FILE_MODE_READ
, &FileList
);
679 if (FileList
== NULL
) {
681 // If filename matched nothing fail
683 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", File
);
684 ShellStatus
= SHELL_INVALID_PARAMETER
;
685 } else if (FileList
->Link
.ForwardLink
!= FileList
->Link
.BackLink
) {
687 // If filename expanded to multiple names, fail
689 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE
), gShellBcfgHiiHandle
, L
"bcfg", File
);
690 ShellStatus
= SHELL_INVALID_PARAMETER
;
692 Arg
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
);
693 if (EFI_ERROR(Arg
->Status
)) {
694 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_OPEN
), gShellBcfgHiiHandle
, L
"bcfg", File
);
695 ShellStatus
= SHELL_INVALID_PARAMETER
;
698 // Build FilePath to the filename
702 // get the device path
704 DevicePath
= gEfiShellProtocol
->GetDevicePathFromFilePath(Arg
->FullName
);
705 if (DevicePath
== NULL
) {
706 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_DP
), gShellBcfgHiiHandle
, L
"bcfg", Arg
->FullName
);
707 ShellStatus
= SHELL_UNSUPPORTED
;
710 DevPath
= DevicePath
;
711 ShellStatus
= SHELL_INVALID_PARAMETER
;
712 while (!IsDevicePathEnd(DevPath
)) {
713 if ((DevicePathType(DevPath
) == MEDIA_DEVICE_PATH
) &&
714 (DevicePathSubType(DevPath
) == MEDIA_HARDDRIVE_DP
)) {
717 // If we find it use it instead
719 ShellStatus
= SHELL_SUCCESS
;
720 FilePath
= DuplicateDevicePath (DevPath
);
723 DevPath
= NextDevicePathNode(DevPath
);
726 FilePath
= DuplicateDevicePath(DevicePath
);
728 FreePool(DevicePath
);
735 if (ShellStatus
== SHELL_SUCCESS
) {
737 // Find a free target ,a brute force implementation
740 for (TargetLocation
=0; TargetLocation
< 0xFFFF; TargetLocation
++) {
742 for (Index
=0; Index
< OrderCount
; Index
++) {
743 if (CurrentOrder
[Index
] == TargetLocation
) {
754 if (TargetLocation
== 0xFFFF) {
755 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET_NF
), gShellBcfgHiiHandle
, L
"bcfg");
757 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET
), gShellBcfgHiiHandle
, TargetLocation
);
761 if (ShellStatus
== SHELL_SUCCESS
) {
765 DescSize
= StrSize(Desc
);
766 FilePathSize
= GetDevicePathSize (FilePath
);
768 TempByteBuffer
= AllocateZeroPool(sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
);
769 if (TempByteBuffer
!= NULL
) {
770 TempByteStart
= TempByteBuffer
;
771 *((UINT32
*) TempByteBuffer
) = LOAD_OPTION_ACTIVE
; // Attributes
772 TempByteBuffer
+= sizeof (UINT32
);
774 *((UINT16
*) TempByteBuffer
) = (UINT16
)FilePathSize
; // FilePathListLength
775 TempByteBuffer
+= sizeof (UINT16
);
777 CopyMem (TempByteBuffer
, Desc
, DescSize
);
778 TempByteBuffer
+= DescSize
;
779 ASSERT (FilePath
!= NULL
);
780 CopyMem (TempByteBuffer
, FilePath
, FilePathSize
);
782 UnicodeSPrint (OptionStr
, sizeof(OptionStr
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", TargetLocation
);
783 Status
= gRT
->SetVariable (
785 &gEfiGlobalVariableGuid
,
786 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
787 sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
,
791 FreePool(TempByteStart
);
793 Status
= EFI_OUT_OF_RESOURCES
;
796 if (EFI_ERROR(Status
)) {
797 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", OptionStr
);
799 NewOrder
= AllocateZeroPool ((OrderCount
+ 1) * sizeof (NewOrder
[0]));
800 if (NewOrder
!= NULL
) {
801 CopyMem (NewOrder
, CurrentOrder
, (OrderCount
) * sizeof (NewOrder
[0]));
804 // Insert target into order list
806 for (Index
= OrderCount
; Index
> Position
; Index
--) {
807 NewOrder
[Index
] = NewOrder
[Index
- 1];
810 NewOrder
[Position
] = (UINT16
) TargetLocation
;
811 Status
= gRT
->SetVariable (
812 Target
== BcfgTargetBootOrder
? L
"BootOrder" : L
"DriverOrder",
813 &gEfiGlobalVariableGuid
,
814 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
815 (OrderCount
+ 1) * sizeof (UINT16
),
821 if (EFI_ERROR (Status
)) {
822 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
? L
"BootOrder" : L
"DriverOrder");
823 ShellStatus
= SHELL_INVALID_PARAMETER
;
825 Print (L
"bcfg: Add %s as %x\n", OptionStr
, Position
);
832 //If always Free FilePath, will free devicepath in system when use "addh"
834 if (FilePath
!=NULL
&& !UseHandle
) {
842 if (Handles
!= NULL
) {
846 if (FileList
!= NULL
) {
847 ShellCloseFileMetaArg (&FileList
);
850 return (ShellStatus
);
854 Funciton to remove an item.
856 @param[in] Target The target item to move.
857 @param[in] CurrentOrder The pointer to the current order of items.
858 @param[in] OrderCount The number if items in CurrentOrder.
859 @param[in] Location The current location of the Target.
861 @retval SHELL_SUCCESS The operation was successful.
862 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
866 IN CONST BCFG_OPERATION_TARGET Target
,
867 IN CONST UINT16
*CurrentOrder
,
868 IN CONST UINTN OrderCount
,
869 IN CONST UINT16 Location
872 CHAR16 VariableName
[12];
877 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", CurrentOrder
[Location
]);
878 Status
= gRT
->SetVariable(
880 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
881 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
884 if (EFI_ERROR(Status
)) {
885 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
886 return (SHELL_INVALID_PARAMETER
);
888 NewOrder
= AllocateZeroPool(OrderCount
*sizeof(CurrentOrder
[0]));
889 if (NewOrder
!= NULL
) {
890 NewCount
= OrderCount
;
891 CopyMem(NewOrder
, CurrentOrder
, OrderCount
*sizeof(CurrentOrder
[0]));
892 CopyMem(NewOrder
+Location
, NewOrder
+Location
+1, (OrderCount
- Location
- 1)*sizeof(CurrentOrder
[0]));
895 Status
= gRT
->SetVariable(
896 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
897 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
898 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
899 NewCount
*sizeof(NewOrder
[0]),
903 Status
= EFI_OUT_OF_RESOURCES
;
905 if (EFI_ERROR(Status
)) {
906 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder");
907 return (SHELL_INVALID_PARAMETER
);
909 return (SHELL_SUCCESS
);
913 Funciton to move a item to another location.
915 @param[in] Target The target item to move.
916 @param[in] CurrentOrder The pointer to the current order of items.
917 @param[in] OrderCount The number if items in CurrentOrder.
918 @param[in] OldLocation The current location of the Target.
919 @param[in] NewLocation The desired location of the Target.
921 @retval SHELL_SUCCESS The operation was successful.
922 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
926 IN CONST BCFG_OPERATION_TARGET Target
,
927 IN CONST UINT16
*CurrentOrder
,
928 IN CONST UINTN OrderCount
,
929 IN CONST UINT16 OldLocation
,
930 IN UINT16 NewLocation
937 NewOrder
= AllocateCopyPool(OrderCount
*sizeof(CurrentOrder
[0]), CurrentOrder
);
938 if (NewOrder
== NULL
) {
939 return (SHELL_OUT_OF_RESOURCES
);
943 // correct the new location
945 if (NewLocation
>= OrderCount
) {
946 if (OrderCount
> 0) {
947 NewLocation
= (UINT16
)OrderCount
- 1;
953 Temp
= CurrentOrder
[OldLocation
];
954 CopyMem(NewOrder
+OldLocation
, NewOrder
+OldLocation
+1, (OrderCount
- OldLocation
- 1)*sizeof(CurrentOrder
[0]));
955 CopyMem(NewOrder
+NewLocation
+1, NewOrder
+NewLocation
, (OrderCount
- NewLocation
- 1)*sizeof(CurrentOrder
[0]));
956 NewOrder
[NewLocation
] = Temp
;
958 Status
= gRT
->SetVariable(
959 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
960 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
961 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
962 OrderCount
*sizeof(CurrentOrder
[0]),
967 if (EFI_ERROR(Status
)) {
968 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder");
969 return (SHELL_INVALID_PARAMETER
);
971 return (SHELL_SUCCESS
);
975 Function to add optional data to an option.
977 @param[in] OptData The optional data to add.
978 @param[in] CurrentOrder The pointer to the current order of items.
979 @param[in] OrderCount The number if items in CurrentOrder.
980 @param[in] Target The target of the operation.
982 @retval SHELL_SUCCESS The operation was succesful.
986 IN CONST CHAR16
*OptData
,
987 IN CONST UINT16
*CurrentOrder
,
988 IN CONST UINTN OrderCount
,
989 IN CONST BCFG_OPERATION_TARGET Target
992 EFI_KEY_OPTION NewKeyOption
;
993 EFI_KEY_OPTION
*KeyOptionBuffer
;
994 SHELL_STATUS ShellStatus
;
1000 CONST CHAR16
*Walker
;
1005 CHAR16 VariableName
[12];
1008 SHELL_FILE_HANDLE FileHandle
;
1010 Status
= EFI_SUCCESS
;
1011 ShellStatus
= SHELL_SUCCESS
;
1015 KeyOptionBuffer
= NULL
;
1016 VariableData
= NULL
;
1018 ZeroMem(&NewKeyOption
, sizeof(EFI_KEY_OPTION
));
1019 ZeroMem(VariableName
, sizeof(VariableName
));
1021 while(Walker
[0] == L
' ') {
1026 // Get the index of the variable we are changing.
1028 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
1029 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
|| ((UINT16
)Intermediate
) > ((UINT16
)OrderCount
)) {
1030 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Option Index");
1031 ShellStatus
= SHELL_INVALID_PARAMETER
;
1032 return (ShellStatus
);
1034 OptionIndex
= (UINT16
)Intermediate
;
1036 Temp
= StrStr(Walker
, L
" ");
1040 while(Walker
[0] == L
' ') {
1045 // determine whether we have file with data, quote delimited information, or a hot-key
1047 if (Walker
[0] == L
'\"') {
1049 // quoted filename or quoted information.
1051 Temp
= StrStr(Walker
+1, L
"\"");
1052 if (Temp
== NULL
|| StrLen(Temp
) != 1) {
1053 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1054 ShellStatus
= SHELL_INVALID_PARAMETER
;
1056 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
+1, 0);
1057 if (FileName
== NULL
) {
1058 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
1059 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1060 return (ShellStatus
);
1062 Temp2
= StrStr(FileName
, L
"\"");
1063 ASSERT(Temp2
!= NULL
);
1064 Temp2
[0] = CHAR_NULL
;
1066 if (StrLen(Temp2
)>0) {
1067 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1068 ShellStatus
= SHELL_INVALID_PARAMETER
;
1070 if (EFI_ERROR(ShellFileExists(Walker
))) {
1072 // Not a file. must be misc information.
1077 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
, 0);
1082 // filename or hot key information.
1084 if (StrStr(Walker
, L
" ") == NULL
) {
1088 if (EFI_ERROR(ShellFileExists(Walker
))) {
1089 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FIND_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1090 ShellStatus
= SHELL_INVALID_PARAMETER
;
1092 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
, 0);
1095 if (Target
!= BcfgTargetBootOrder
) {
1096 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_BOOT_ONLY
), gShellBcfgHiiHandle
, L
"bcfg");
1097 ShellStatus
= SHELL_INVALID_PARAMETER
;
1100 if (ShellStatus
== SHELL_SUCCESS
) {
1102 // Get hot key information
1104 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
1105 if (EFI_ERROR(Status
) || (((UINT32
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
) {
1106 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1107 ShellStatus
= SHELL_INVALID_PARAMETER
;
1109 NewKeyOption
.KeyData
.PackedValue
= (UINT32
)Intermediate
;
1110 Temp
= StrStr(Walker
, L
" ");
1114 while(Walker
[0] == L
' ') {
1119 if (ShellStatus
== SHELL_SUCCESS
) {
1121 // Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.
1122 // Re-allocate with the added information.
1124 KeyOptionBuffer
= AllocatePool (sizeof(EFI_KEY_OPTION
) + (sizeof(EFI_INPUT_KEY
) * NewKeyOption
.KeyData
.Options
.InputKeyCount
));
1125 if (KeyOptionBuffer
== NULL
) {
1126 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
1127 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1130 CopyMem (KeyOptionBuffer
, &NewKeyOption
, sizeof(EFI_KEY_OPTION
));
1132 for (LoopCounter
= 0 ; ShellStatus
== SHELL_SUCCESS
&& LoopCounter
< NewKeyOption
.KeyData
.Options
.InputKeyCount
; LoopCounter
++) {
1136 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
1137 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
) {
1138 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1139 ShellStatus
= SHELL_INVALID_PARAMETER
;
1141 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof(EFI_KEY_OPTION
)))[LoopCounter
].ScanCode
= (UINT16
)Intermediate
;
1142 Temp
= StrStr(Walker
, L
" ");
1146 while(Walker
[0] == L
' ') {
1153 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
1154 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
)) {
1155 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1156 ShellStatus
= SHELL_INVALID_PARAMETER
;
1158 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof(EFI_KEY_OPTION
)))[LoopCounter
].UnicodeChar
= (UINT16
)Intermediate
;
1159 Temp
= StrStr(Walker
, L
" ");
1163 while(Walker
[0] == L
' ') {
1168 if (ShellStatus
== SHELL_SUCCESS
) {
1170 // Now do the BootOption / BootOptionCrc
1172 ASSERT (OptionIndex
<= OrderCount
);
1173 KeyOptionBuffer
->BootOption
= CurrentOrder
[OptionIndex
];
1174 Status
= GetBootOptionCrc(&(KeyOptionBuffer
->BootOptionCrc
), KeyOptionBuffer
->BootOption
);
1175 if (EFI_ERROR(Status
)) {
1176 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Option Index");
1177 ShellStatus
= SHELL_INVALID_PARAMETER
;
1181 if (ShellStatus
== SHELL_SUCCESS
) {
1182 for (Temp2
= NULL
, KeyIndex
= 0 ; KeyIndex
<= 0xFFFF ; KeyIndex
++) {
1183 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"Key%04x", KeyIndex
);
1184 Status
= GetEfiGlobalVariable2 (VariableName
, &VariableData
, NULL
);
1185 if (Status
== EFI_NOT_FOUND
) {
1188 if (!EFI_ERROR(Status
)) {
1189 SHELL_FREE_NON_NULL(VariableData
);
1192 if (KeyIndex
<= 0xFFFF) {
1193 Status
= gRT
->SetVariable(
1195 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1196 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
1197 sizeof(EFI_KEY_OPTION
) + (sizeof(EFI_INPUT_KEY
) * NewKeyOption
.KeyData
.Options
.InputKeyCount
),
1199 if (EFI_ERROR(Status
)) {
1200 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1201 ShellStatus
= SHELL_INVALID_PARAMETER
;
1204 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_VAR_NO_NUM
), gShellBcfgHiiHandle
, L
"bcfg");
1205 ShellStatus
= SHELL_INVALID_PARAMETER
;
1207 ASSERT(FileName
== NULL
&& Data
== NULL
);
1213 // Shouldn't be possible to have have both. Neither is ok though.
1215 ASSERT(FileName
== NULL
|| Data
== NULL
);
1217 if (ShellStatus
== SHELL_SUCCESS
&& (FileName
!= NULL
|| Data
!= NULL
)) {
1218 if (FileName
!= NULL
) {
1220 // Open the file and populate the data buffer.
1222 Status
= ShellOpenFileByName(
1227 if (!EFI_ERROR(Status
)) {
1228 Status
= ShellGetFileSize(FileHandle
, &Intermediate
);
1230 Data
= AllocateZeroPool((UINTN
)Intermediate
);
1232 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
1233 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1235 if (!EFI_ERROR(Status
)) {
1236 Status
= ShellReadFile(FileHandle
, (UINTN
*)&Intermediate
, Data
);
1239 Intermediate
= StrSize(Data
);
1242 if (!EFI_ERROR(Status
) && ShellStatus
== SHELL_SUCCESS
&& Data
!= NULL
) {
1243 Status
= UpdateOptionalData(CurrentOrder
[OptionIndex
], (UINTN
)Intermediate
, (UINT8
*)Data
, Target
);
1244 if (EFI_ERROR(Status
)) {
1245 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1246 ShellStatus
= SHELL_INVALID_PARAMETER
;
1249 if (EFI_ERROR(Status
) && ShellStatus
== SHELL_SUCCESS
) {
1250 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1251 ShellStatus
= SHELL_INVALID_PARAMETER
;
1255 SHELL_FREE_NON_NULL(Data
);
1256 SHELL_FREE_NON_NULL(KeyOptionBuffer
);
1257 SHELL_FREE_NON_NULL(FileName
);
1262 Function to dump the Bcfg information.
1264 @param[in] Op The operation.
1265 @param[in] OrderCount How many to dump.
1266 @param[in] CurrentOrder The pointer to the current order of items.
1267 @param[in] VerboseOutput TRUE for extra output. FALSE otherwise.
1269 @retval SHELL_SUCCESS The dump was successful.
1270 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
1274 IN CONST CHAR16
*Op
,
1275 IN CONST UINTN OrderCount
,
1276 IN CONST UINT16
*CurrentOrder
,
1277 IN CONST BOOLEAN VerboseOutput
1283 CHAR16 VariableName
[12];
1285 CHAR16
*DevPathString
;
1288 EFI_LOAD_OPTION
*LoadOption
;
1289 CHAR16
*Description
;
1290 UINTN DescriptionSize
;
1291 UINTN OptionalDataOffset
;
1293 if (OrderCount
== 0) {
1294 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_BCFG_NONE
), gShellBcfgHiiHandle
, L
"bcfg");
1295 return (SHELL_SUCCESS
);
1300 for (LoopVar
= 0 ; LoopVar
< OrderCount
; LoopVar
++) {
1303 DevPathString
= NULL
;
1305 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Op
, CurrentOrder
[LoopVar
]);
1307 Status
= gRT
->GetVariable(
1309 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1313 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1314 Buffer
= AllocateZeroPool(BufferSize
);
1315 Status
= gRT
->GetVariable(
1317 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1323 if (EFI_ERROR(Status
) || Buffer
== NULL
) {
1324 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_READ_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1330 // We expect the Attributes, FilePathListLength, and L'\0'-terminated
1331 // Description fields to be present.
1333 if (BufferSize
< sizeof *LoadOption
+ sizeof (CHAR16
)) {
1338 STRING_TOKEN (STR_BCFG_VAR_CORRUPT
),
1339 gShellBcfgHiiHandle
,
1347 LoadOption
= (EFI_LOAD_OPTION
*)Buffer
;
1348 Description
= (CHAR16
*)(Buffer
+ sizeof (EFI_LOAD_OPTION
));
1349 DescriptionSize
= StrSize (Description
);
1351 if (LoadOption
->FilePathListLength
!= 0) {
1352 FilePathList
= (UINT8
*)Description
+ DescriptionSize
;
1353 DevPathString
= ConvertDevicePathToText(FilePathList
, TRUE
, FALSE
);
1356 OptionalDataOffset
= sizeof *LoadOption
+ DescriptionSize
+
1357 LoadOption
->FilePathListLength
;
1363 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS
),
1364 gShellBcfgHiiHandle
,
1369 OptionalDataOffset
>= BufferSize
? L
'N' : L
'Y'
1371 if (VerboseOutput
&& (OptionalDataOffset
< BufferSize
)) {
1374 0, // Offset (displayed)
1375 BufferSize
- OptionalDataOffset
, // DataSize
1376 Buffer
+ OptionalDataOffset
// UserData
1381 if (Buffer
!= NULL
) {
1384 if (DevPathString
!= NULL
) {
1385 FreePool(DevPathString
);
1388 return (Errors
> 0) ? SHELL_INVALID_PARAMETER
: SHELL_SUCCESS
;
1392 Function to initialize the BCFG operation structure.
1394 @param[in] Struct The stuct to initialize.
1398 IN BGFG_OPERATION
*Struct
1401 ASSERT(Struct
!= NULL
);
1402 Struct
->Target
= BcfgTargetMax
;
1403 Struct
->Type
= BcfgTypeMax
;
1404 Struct
->Number1
= 0;
1405 Struct
->Number2
= 0;
1406 Struct
->HandleIndex
= 0;
1407 Struct
->FileName
= NULL
;
1408 Struct
->Description
= NULL
;
1409 Struct
->Order
= NULL
;
1410 Struct
->OptData
= NULL
;
1414 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
1416 {L
"-opt", TypeMaxValue
},
1421 Function for 'bcfg' command.
1423 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1424 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1428 ShellCommandRunBcfg (
1429 IN EFI_HANDLE ImageHandle
,
1430 IN EFI_SYSTEM_TABLE
*SystemTable
1434 LIST_ENTRY
*Package
;
1435 CHAR16
*ProblemParam
;
1436 SHELL_STATUS ShellStatus
;
1438 CONST CHAR16
*CurrentParam
;
1439 BGFG_OPERATION CurrentOperation
;
1441 UINT64 Intermediate
;
1445 ProblemParam
= NULL
;
1447 ShellStatus
= SHELL_SUCCESS
;
1449 InitBcfgStruct(&CurrentOperation
);
1452 // initialize the shell lib (we must be in non-auto-init...)
1454 Status
= ShellInitialize();
1455 ASSERT_EFI_ERROR(Status
);
1457 Status
= CommandInit();
1458 ASSERT_EFI_ERROR(Status
);
1461 // parse the command line
1463 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
1464 if (EFI_ERROR(Status
)) {
1465 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
1466 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, L
"bcfg", ProblemParam
);
1467 FreePool(ProblemParam
);
1468 ShellStatus
= SHELL_INVALID_PARAMETER
;
1474 // Read in if we are doing -OPT
1476 if (ShellCommandLineGetFlag(Package
, L
"-opt")) {
1477 CurrentOperation
.OptData
= ShellCommandLineGetValue(Package
, L
"-opt");
1478 if (CurrentOperation
.OptData
== NULL
) {
1479 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellBcfgHiiHandle
, L
"bcfg", L
"-opt");
1480 ShellStatus
= SHELL_INVALID_PARAMETER
;
1482 CurrentOperation
.Type
= BcfgTypeOpt
;
1486 // small block to read the target of the operation
1488 if ((ShellCommandLineGetCount(Package
) < 3 && CurrentOperation
.Type
!= BcfgTypeOpt
) ||
1489 (ShellCommandLineGetCount(Package
) < 2 && CurrentOperation
.Type
== BcfgTypeOpt
)
1491 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1492 ShellStatus
= SHELL_INVALID_PARAMETER
;
1493 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"driver") == 0) {
1494 CurrentOperation
.Target
= BcfgTargetDriverOrder
;
1495 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"boot") == 0) {
1496 CurrentOperation
.Target
= BcfgTargetBootOrder
;
1498 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT
), gShellBcfgHiiHandle
, L
"bcfg");
1499 ShellStatus
= SHELL_INVALID_PARAMETER
;
1504 // Read in the boot or driver order environment variable (not needed for opt)
1506 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
1508 Status
= gRT
->GetVariable(
1509 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
1510 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1513 CurrentOperation
.Order
);
1514 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1515 CurrentOperation
.Order
= AllocateZeroPool(Length
+(4*sizeof(CurrentOperation
.Order
[0])));
1516 if (CurrentOperation
.Order
== NULL
) {
1517 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1519 Status
= gRT
->GetVariable(
1520 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
1521 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1524 CurrentOperation
.Order
);
1529 Count
= (UINT16
) (Length
/ sizeof(CurrentOperation
.Order
[0]));
1532 // large block to read the type of operation and verify parameter types for the info.
1534 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
1535 for (ParamNumber
= 2 ; ParamNumber
< ShellCommandLineGetCount(Package
) && ShellStatus
== SHELL_SUCCESS
; ParamNumber
++) {
1536 CurrentParam
= ShellCommandLineGetRawValue(Package
, ParamNumber
);
1537 if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"dump") == 0) {
1538 CurrentOperation
.Type
= BcfgTypeDump
;
1539 if (ShellCommandLineGetCount(Package
) > 3) {
1540 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellBcfgHiiHandle
, L
"bcfg");
1541 ShellStatus
= SHELL_INVALID_PARAMETER
;
1543 } else if (ShellCommandLineGetFlag(Package
, L
"-v")) {
1544 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"-v (without dump)");
1545 ShellStatus
= SHELL_INVALID_PARAMETER
;
1546 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"add") == 0) {
1547 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1548 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1549 ShellStatus
= SHELL_INVALID_PARAMETER
;
1551 CurrentOperation
.Type
= BcfgTypeAdd
;
1552 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1553 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1554 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1555 ShellStatus
= SHELL_INVALID_PARAMETER
;
1557 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1558 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1559 ASSERT(CurrentOperation
.FileName
== NULL
);
1560 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1561 ASSERT(CurrentOperation
.Description
== NULL
);
1562 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1564 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addp") == 0) {
1565 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1566 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1567 ShellStatus
= SHELL_INVALID_PARAMETER
;
1569 CurrentOperation
.Type
= BcfgTypeAddp
;
1570 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1571 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1572 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1573 ShellStatus
= SHELL_INVALID_PARAMETER
;
1575 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1576 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1577 ASSERT(CurrentOperation
.FileName
== NULL
);
1578 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1579 ASSERT(CurrentOperation
.Description
== NULL
);
1580 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1582 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addh") == 0) {
1583 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1584 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1585 ShellStatus
= SHELL_INVALID_PARAMETER
;
1587 CurrentOperation
.Type
= BcfgTypeAddh
;
1588 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1589 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1590 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1591 ShellStatus
= SHELL_INVALID_PARAMETER
;
1593 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1594 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1595 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1596 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1597 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1598 ShellStatus
= SHELL_INVALID_PARAMETER
;
1600 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1601 CurrentOperation
.HandleIndex
= (UINT16
)Intermediate
;
1602 ASSERT(CurrentOperation
.Description
== NULL
);
1603 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1606 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"rm") == 0) {
1607 if ((ParamNumber
+ 1) >= ShellCommandLineGetCount(Package
)) {
1608 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1609 ShellStatus
= SHELL_INVALID_PARAMETER
;
1611 CurrentOperation
.Type
= BcfgTypeRm
;
1612 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1613 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1614 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1615 ShellStatus
= SHELL_INVALID_PARAMETER
;
1617 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1618 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1619 if (CurrentOperation
.Number1
>= Count
){
1620 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1621 ShellStatus
= SHELL_INVALID_PARAMETER
;
1624 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"mv") == 0) {
1625 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount(Package
)) {
1626 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1627 ShellStatus
= SHELL_INVALID_PARAMETER
;
1629 CurrentOperation
.Type
= BcfgTypeMv
;
1630 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1631 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1632 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1633 ShellStatus
= SHELL_INVALID_PARAMETER
;
1635 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1636 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1637 if (CurrentOperation
.Number1
>= Count
){
1638 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1639 ShellStatus
= SHELL_INVALID_PARAMETER
;
1641 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1642 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1643 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1644 ShellStatus
= SHELL_INVALID_PARAMETER
;
1646 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1647 CurrentOperation
.Number2
= (UINT16
)Intermediate
;
1649 if (CurrentOperation
.Number2
== CurrentOperation
.Number1
1650 ||CurrentOperation
.Number2
>= Count
1652 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1653 ShellStatus
= SHELL_INVALID_PARAMETER
;
1658 else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"mod") == 0) {
1659 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount (Package
)) {
1660 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1661 ShellStatus
= SHELL_INVALID_PARAMETER
;
1663 CurrentOperation
.Type
= BcfgTypeMod
;
1664 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1665 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1666 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1667 ShellStatus
= SHELL_INVALID_PARAMETER
;
1669 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1670 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1671 if (CurrentOperation
.Number1
>= Count
) {
1672 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1673 ShellStatus
= SHELL_INVALID_PARAMETER
;
1675 ASSERT (CurrentOperation
.Description
== NULL
);
1676 CurrentOperation
.Description
= StrnCatGrow (&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue (Package
, ++ParamNumber
), 0);
1680 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"modf") == 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
;
1685 CurrentOperation
.Type
= BcfgTypeModf
;
1686 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1687 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1688 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1689 ShellStatus
= SHELL_INVALID_PARAMETER
;
1691 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1692 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1693 if (CurrentOperation
.Number1
>= Count
) {
1694 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1695 ShellStatus
= SHELL_INVALID_PARAMETER
;
1697 ASSERT (CurrentOperation
.FileName
== NULL
);
1698 CurrentOperation
.FileName
= StrnCatGrow (&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue (Package
, ++ParamNumber
), 0);
1702 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"modp") == 0) {
1703 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount (Package
)) {
1704 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1705 ShellStatus
= SHELL_INVALID_PARAMETER
;
1707 CurrentOperation
.Type
= BcfgTypeModp
;
1708 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1709 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1710 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1711 ShellStatus
= SHELL_INVALID_PARAMETER
;
1713 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1714 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1715 if (CurrentOperation
.Number1
>= Count
) {
1716 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1717 ShellStatus
= SHELL_INVALID_PARAMETER
;
1719 ASSERT (CurrentOperation
.FileName
== NULL
);
1720 CurrentOperation
.FileName
= StrnCatGrow (&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue (Package
, ++ParamNumber
), 0);
1724 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"modh") == 0) {
1725 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount (Package
)) {
1726 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1727 ShellStatus
= SHELL_INVALID_PARAMETER
;
1729 CurrentOperation
.Type
= BcfgTypeModh
;
1730 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1731 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1732 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1733 ShellStatus
= SHELL_INVALID_PARAMETER
;
1736 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1737 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1738 if (CurrentOperation
.Number1
>= Count
) {
1739 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1740 ShellStatus
= SHELL_INVALID_PARAMETER
;
1742 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1743 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1744 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1745 ShellStatus
= SHELL_INVALID_PARAMETER
;
1747 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1748 CurrentOperation
.HandleIndex
= (UINT16
)Intermediate
;
1754 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1755 ShellStatus
= SHELL_INVALID_PARAMETER
;
1759 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
&& CurrentOperation
.Type
< BcfgTypeMax
) {
1761 // we have all the info. Do the work
1763 switch (CurrentOperation
.Type
) {
1765 ShellStatus
= BcfgDisplayDump(
1766 CurrentOperation
.Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver",
1768 CurrentOperation
.Order
,
1769 ShellCommandLineGetFlag(Package
, L
"-v"));
1772 ShellStatus
= BcfgMove(
1773 CurrentOperation
.Target
,
1774 CurrentOperation
.Order
,
1776 CurrentOperation
.Number1
,
1777 CurrentOperation
.Number2
);
1780 ShellStatus
= BcfgRemove(
1781 CurrentOperation
.Target
,
1782 CurrentOperation
.Order
,
1784 CurrentOperation
.Number1
);
1789 ShellStatus
= BcfgAdd(
1790 CurrentOperation
.Number1
,
1791 CurrentOperation
.FileName
,
1792 CurrentOperation
.Description
==NULL
?L
"":CurrentOperation
.Description
,
1793 CurrentOperation
.Order
,
1795 CurrentOperation
.Target
,
1796 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddh
),
1797 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddp
),
1798 CurrentOperation
.HandleIndex
);
1804 ShellStatus
= BcfgMod (&CurrentOperation
, Count
);
1807 ShellStatus
= BcfgAddOpt(
1808 CurrentOperation
.OptData
,
1809 CurrentOperation
.Order
,
1811 CurrentOperation
.Target
);
1819 if (Package
!= NULL
) {
1820 ShellCommandLineFreeVarList (Package
);
1822 if (CurrentOperation
.FileName
!= NULL
) {
1823 FreePool(CurrentOperation
.FileName
);
1825 if (CurrentOperation
.Description
!= NULL
) {
1826 FreePool(CurrentOperation
.Description
);
1828 if (CurrentOperation
.Order
!= NULL
) {
1829 FreePool(CurrentOperation
.Order
);
1832 return (ShellStatus
);
1837 Function to get the filename with help context if HII will not be used.
1839 @return The filename with help text in it.
1843 ShellCommandGetManFileNameBcfg (
1851 "Constructor" for the library.
1853 This will register the handler for the bcfg command.
1855 @param[in] ImageHandle the image handle of the process
1856 @param[in] SystemTable the EFI System Table pointer
1857 @param[in] Name the profile name to use
1859 @retval EFI_SUCCESS the shell command handlers were installed sucessfully
1860 @retval EFI_UNSUPPORTED the shell level required was not found.
1864 BcfgLibraryRegisterBcfgCommand (
1865 IN EFI_HANDLE ImageHandle
,
1866 IN EFI_SYSTEM_TABLE
*SystemTable
,
1867 IN CONST CHAR16
*Name
1870 if (gShellBcfgHiiHandle
!= NULL
) {
1871 return (EFI_SUCCESS
);
1874 gShellBcfgHiiHandle
= HiiAddPackages (&gShellBcfgHiiGuid
, gImageHandle
, UefiShellBcfgCommandLibStrings
, NULL
);
1875 if (gShellBcfgHiiHandle
== NULL
) {
1876 return (EFI_DEVICE_ERROR
);
1880 // install our shell command handler
1882 ShellCommandRegisterCommandName(L
"bcfg", ShellCommandRunBcfg
, ShellCommandGetManFileNameBcfg
, 0, Name
, FALSE
, gShellBcfgHiiHandle
, STRING_TOKEN(STR_GET_HELP_BCFG
));
1884 return (EFI_SUCCESS
);
1888 Destructor for the library. free any resources.
1890 @param ImageHandle The image handle of the process.
1891 @param SystemTable The EFI System Table pointer.
1895 BcfgLibraryUnregisterBcfgCommand (
1896 IN EFI_HANDLE ImageHandle
,
1897 IN EFI_SYSTEM_TABLE
*SystemTable
1900 if (gShellBcfgHiiHandle
!= NULL
) {
1901 HiiRemovePackages(gShellBcfgHiiHandle
);
1903 gShellBcfgHiiHandle
= NULL
;
1904 return (EFI_SUCCESS
);