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
13 #include <Guid/GlobalVariable.h>
14 #include <Guid/ShellLibHiiGuid.h>
16 #include <Protocol/Shell.h>
17 #include <Protocol/ShellParameters.h>
18 #include <Protocol/DevicePath.h>
19 #include <Protocol/LoadedImage.h>
20 #include <Protocol/UnicodeCollation.h>
22 #include <Library/BaseLib.h>
23 #include <Library/BaseMemoryLib.h>
24 #include <Library/DebugLib.h>
25 #include <Library/MemoryAllocationLib.h>
26 #include <Library/PcdLib.h>
27 #include <Library/ShellCommandLib.h>
28 #include <Library/ShellLib.h>
29 #include <Library/SortLib.h>
30 #include <Library/UefiLib.h>
31 #include <Library/UefiRuntimeServicesTableLib.h>
32 #include <Library/UefiBootServicesTableLib.h>
33 #include <Library/HiiLib.h>
34 #include <Library/FileHandleLib.h>
35 #include <Library/PrintLib.h>
36 #include <Library/HandleParsingLib.h>
37 #include <Library/DevicePathLib.h>
38 #include <Library/UefiBootManagerLib.h>
40 STATIC CONST CHAR16 mFileName
[] = L
"ShellCommands";
41 STATIC EFI_HANDLE gShellBcfgHiiHandle
= NULL
;
44 BcfgTargetBootOrder
= 0,
45 BcfgTargetDriverOrder
= 1,
47 } BCFG_OPERATION_TARGET
;
62 } BCFG_OPERATION_TYPE
;
65 BCFG_OPERATION_TARGET Target
;
66 BCFG_OPERATION_TYPE Type
;
73 CONST CHAR16
*OptData
;
77 Update the optional data for a boot or driver option.
79 If optional data exists it will be changed.
81 @param[in] Index The boot or driver option index update.
82 @param[in] DataSize The size in bytes of Data.
83 @param[in] Data The buffer for the optioanl data.
84 @param[in] Target The target of the operation.
86 @retval EFI_SUCCESS The data was sucessfully updated.
87 @retval other A error occured.
94 IN CONST BCFG_OPERATION_TARGET Target
98 CHAR16 VariableName
[12];
103 UINTN OriginalOptionDataSize
;
105 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", Index
);
112 Status
= gRT
->GetVariable(
114 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
118 if (Status
== EFI_BUFFER_TOO_SMALL
) {
119 OriginalData
= AllocateZeroPool(OriginalSize
);
120 if (OriginalData
== NULL
) {
121 return (EFI_OUT_OF_RESOURCES
);
123 Status
= gRT
->GetVariable(
125 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
131 if (!EFI_ERROR(Status
)) {
133 // Allocate new struct and discard old optional data.
135 ASSERT (OriginalData
!= NULL
);
136 OriginalOptionDataSize
= sizeof(UINT32
) + sizeof(UINT16
) + StrSize(((CHAR16
*)(OriginalData
+ sizeof(UINT32
) + sizeof(UINT16
))));
137 OriginalOptionDataSize
+= (*(UINT16
*)(OriginalData
+ sizeof(UINT32
)));
138 OriginalOptionDataSize
-= OriginalSize
;
139 NewSize
= OriginalSize
- OriginalOptionDataSize
+ DataSize
;
140 NewData
= AllocatePool(NewSize
);
141 if (NewData
== NULL
) {
142 Status
= EFI_OUT_OF_RESOURCES
;
144 CopyMem (NewData
, OriginalData
, OriginalSize
- OriginalOptionDataSize
);
145 CopyMem(NewData
+ OriginalSize
- OriginalOptionDataSize
, Data
, DataSize
);
149 if (!EFI_ERROR(Status
)) {
151 // put the data back under the variable
153 Status
= gRT
->SetVariable(
155 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
156 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
161 SHELL_FREE_NON_NULL(OriginalData
);
162 SHELL_FREE_NON_NULL(NewData
);
167 This function will get a CRC for a boot option.
169 @param[in, out] Crc The CRC value to return.
170 @param[in] BootIndex The boot option index to CRC.
172 @retval EFI_SUCCESS The CRC was sucessfully returned.
173 @retval other A error occured.
181 CHAR16 VariableName
[12];
190 // Get the data Buffer
192 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%Boot%04x", BootIndex
);
193 Status
= gRT
->GetVariable(
195 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
199 if (Status
== EFI_BUFFER_TOO_SMALL
) {
200 Buffer
= AllocateZeroPool(BufferSize
);
201 Status
= gRT
->GetVariable(
203 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
210 // Get the CRC computed
212 if (!EFI_ERROR(Status
)) {
213 Status
= gBS
->CalculateCrc32 (Buffer
, BufferSize
, Crc
);
216 SHELL_FREE_NON_NULL(Buffer
);
221 This function will populate the device path protocol parameter based on TheHandle.
223 @param[in] TheHandle Driver handle.
224 @param[in, out] FilePath On a sucessful return the device path to the handle.
226 @retval EFI_SUCCESS The device path was sucessfully returned.
227 @retval other A error from gBS->HandleProtocol.
232 GetDevicePathForDriverHandle (
233 IN EFI_HANDLE TheHandle
,
234 IN OUT EFI_DEVICE_PATH_PROTOCOL
**FilePath
238 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
239 EFI_DEVICE_PATH_PROTOCOL
*ImageDevicePath
;
241 Status
= gBS
->OpenProtocol (
243 &gEfiLoadedImageProtocolGuid
,
244 (VOID
**)&LoadedImage
,
247 EFI_OPEN_PROTOCOL_GET_PROTOCOL
249 if (!EFI_ERROR (Status
)) {
250 Status
= gBS
->OpenProtocol (
251 LoadedImage
->DeviceHandle
,
252 &gEfiDevicePathProtocolGuid
,
253 (VOID
**)&ImageDevicePath
,
256 EFI_OPEN_PROTOCOL_GET_PROTOCOL
258 if (!EFI_ERROR (Status
)) {
259 // *DevPath = DuplicateDevicePath (ImageDevicePath);
260 // *FilePath = DuplicateDevicePath (LoadedImage->FilePath);
261 *FilePath
= AppendDevicePath(ImageDevicePath
,LoadedImage
->FilePath
);
263 LoadedImage
->DeviceHandle
,
264 &gEfiDevicePathProtocolGuid
,
270 &gEfiLoadedImageProtocolGuid
,
278 Functino to get Device Path by a handle.
280 @param[in] TheHandle Use it to get DevicePath.
281 @param[in] Target Boot option target.
282 @param[in, out] DevicePath On a sucessful return the device path to the handle.
284 @retval SHELL_INVALID_PARAMETER The handle was NULL.
285 @retval SHELL_NOT_FOUND Not found device path by handle.
286 @retval SHELL_SUCCESS Get device path successfully.
289 GetDevicePathByHandle(
290 IN EFI_HANDLE TheHandle
,
291 IN BCFG_OPERATION_TARGET Target
,
292 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePath
296 SHELL_STATUS ShellStatus
;
298 UINTN DriverBindingHandleCount
;
299 UINTN ParentControllerHandleCount
;
300 UINTN ChildControllerHandleCount
;
302 ShellStatus
= SHELL_SUCCESS
;
304 if (TheHandle
== NULL
) {
305 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Handle Number");
306 return SHELL_INVALID_PARAMETER
;
309 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (TheHandle
, &DriverBindingHandleCount
, NULL
);
310 if (EFI_ERROR(Status
)) {
311 DriverBindingHandleCount
= 0;
314 Status
= PARSE_HANDLE_DATABASE_PARENTS (TheHandle
, &ParentControllerHandleCount
, NULL
);
315 if (EFI_ERROR (Status
)) {
316 ParentControllerHandleCount
= 0;
319 Status
= ParseHandleDatabaseForChildControllers (TheHandle
, &ChildControllerHandleCount
, NULL
);
320 if (EFI_ERROR (Status
)) {
321 ChildControllerHandleCount
= 0;
324 Status
= gBS
->HandleProtocol (TheHandle
, &gEfiDevicePathProtocolGuid
, (VOID
**)DevicePath
);
326 if ( DriverBindingHandleCount
> 0 ||
327 ParentControllerHandleCount
> 0 ||
328 ChildControllerHandleCount
> 0 ||
332 // The handle points to a real controller which has a device path.
334 if (Target
== BcfgTargetDriverOrder
) {
338 NULL
,STRING_TOKEN (STR_GEN_PARAM_INV
),
341 L
"Handle should point to driver image."
343 ShellStatus
= SHELL_NOT_FOUND
;
347 // The handle points to a driver image.
349 if (Target
== BcfgTargetBootOrder
) {
354 STRING_TOKEN (STR_GEN_PARAM_INV
),
357 L
"Handle should point to controller."
359 ShellStatus
= SHELL_NOT_FOUND
;
361 if (EFI_ERROR (GetDevicePathForDriverHandle (TheHandle
, DevicePath
))) {
362 ShellStatus
= SHELL_NOT_FOUND
;
367 return (ShellStatus
);
371 Function to modify an option.
373 @param[in] BcfgOperation Pointer to BCFG operation.
374 @param[in] OrderCount The number if items in CurrentOrder.
376 @retval SHELL_SUCCESS The operation was successful.
377 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
378 @retval SHELL_OUT_OF_RESOUCES A memory allocation failed.
382 IN CONST BGFG_OPERATION
*BcfgOperation
,
383 IN CONST UINTN OrderCount
387 EFI_HANDLE CurHandle
;
388 SHELL_STATUS ShellStatus
;
389 CHAR16 OptionStr
[40];
390 EFI_SHELL_FILE_INFO
*FileList
;
391 EFI_SHELL_FILE_INFO
*Arg
;
392 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
393 EFI_DEVICE_PATH_PROTOCOL
*DevicePathBuffer
;
394 EFI_DEVICE_PATH_PROTOCOL
*DevicePathWalker
;
395 EFI_BOOT_MANAGER_LOAD_OPTION LoadOption
;
397 ShellStatus
= SHELL_SUCCESS
;
400 DevicePathBuffer
= NULL
;
402 ZeroMem (&LoadOption
, sizeof(EFI_BOOT_MANAGER_LOAD_OPTION
));
404 if ( (BcfgOperation
->Type
== BcfgTypeMod
&& BcfgOperation
->Description
== NULL
) ||
405 (BcfgOperation
->Type
== BcfgTypeModf
&& BcfgOperation
->FileName
== NULL
) ||
406 (BcfgOperation
->Type
== BcfgTypeModp
&& BcfgOperation
->FileName
== NULL
) ||
407 (BcfgOperation
->Type
== BcfgTypeModh
&& BcfgOperation
->HandleIndex
== 0) ||
408 (BcfgOperation
->Number1
> OrderCount
)
410 return (SHELL_INVALID_PARAMETER
);
413 if (BcfgOperation
->Type
== BcfgTypeModh
) {
414 CurHandle
= ConvertHandleIndexToHandle (BcfgOperation
->HandleIndex
);
415 ShellStatus
= GetDevicePathByHandle (CurHandle
, BcfgOperation
->Target
, &DevicePathBuffer
);
416 if (ShellStatus
== SHELL_SUCCESS
) {
417 DevicePath
= DuplicateDevicePath (DevicePathBuffer
);
419 } else if (BcfgOperation
->Type
== BcfgTypeModf
|| BcfgOperation
->Type
== BcfgTypeModp
) {
421 // Get Device Path by FileName.
423 ShellOpenFileMetaArg ((CHAR16
*)BcfgOperation
->FileName
, EFI_FILE_MODE_READ
, &FileList
);
424 if (FileList
== NULL
) {
426 // The name of file matched nothing.
428 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", BcfgOperation
->FileName
);
429 ShellStatus
= SHELL_INVALID_PARAMETER
;
431 else if (FileList
->Link
.ForwardLink
!= FileList
->Link
.BackLink
) {
433 // If the name of file expanded to multiple names, it's fail.
435 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE
), gShellBcfgHiiHandle
, L
"bcfg", BcfgOperation
->FileName
);
436 ShellStatus
= SHELL_INVALID_PARAMETER
;
438 Arg
= (EFI_SHELL_FILE_INFO
*)GetFirstNode (&FileList
->Link
);
439 if (EFI_ERROR (Arg
->Status
)) {
440 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_OPEN
), gShellBcfgHiiHandle
, L
"bcfg", BcfgOperation
->FileName
);
441 ShellStatus
= SHELL_INVALID_PARAMETER
;
443 DevicePathBuffer
= gEfiShellProtocol
->GetDevicePathFromFilePath (Arg
->FullName
);
444 if (DevicePathBuffer
== NULL
) {
445 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_DP
), gShellBcfgHiiHandle
, L
"bcfg", Arg
->FullName
);
446 ShellStatus
= SHELL_UNSUPPORTED
;
451 if (ShellStatus
== SHELL_SUCCESS
) {
452 if (BcfgOperation
->Type
== BcfgTypeModp
) {
453 ShellStatus
= SHELL_INVALID_PARAMETER
;
454 DevicePathWalker
= DevicePathBuffer
;
455 while (!IsDevicePathEnd (DevicePathWalker
)) {
456 if ( DevicePathType (DevicePathWalker
) == MEDIA_DEVICE_PATH
&&
457 DevicePathSubType (DevicePathWalker
) == MEDIA_HARDDRIVE_DP
460 // We found the portion of device path starting with the hard driver partition.
462 ShellStatus
= SHELL_SUCCESS
;
463 DevicePath
= DuplicateDevicePath (DevicePathWalker
);
466 DevicePathWalker
= NextDevicePathNode (DevicePathWalker
);
470 DevicePath
= DuplicateDevicePath (DevicePathBuffer
);
473 FreePool (DevicePathBuffer
);
477 if (ShellStatus
== SHELL_SUCCESS
) {
478 if (BcfgOperation
->Target
== BcfgTargetBootOrder
) {
479 UnicodeSPrint (OptionStr
, sizeof (OptionStr
), L
"Boot%04x", BcfgOperation
->Order
[BcfgOperation
->Number1
]);
481 UnicodeSPrint (OptionStr
, sizeof (OptionStr
), L
"Driver%04x", BcfgOperation
->Order
[BcfgOperation
->Number1
]);
483 Status
= EfiBootManagerVariableToLoadOption (OptionStr
, &LoadOption
);
484 if (EFI_ERROR(Status
)) {
485 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NONE
), gShellBcfgHiiHandle
);
486 ShellStatus
= SHELL_NOT_FOUND
;
490 if (ShellStatus
== SHELL_SUCCESS
) {
491 if (BcfgOperation
->Type
== BcfgTypeMod
) {
492 SHELL_FREE_NON_NULL (LoadOption
.Description
);
493 LoadOption
.Description
= AllocateCopyPool (StrSize (BcfgOperation
->Description
), BcfgOperation
->Description
);
495 SHELL_FREE_NON_NULL (LoadOption
.FilePath
);
496 LoadOption
.FilePath
= DuplicateDevicePath (DevicePath
);
499 Status
= EfiBootManagerLoadOptionToVariable (&LoadOption
);
500 if (EFI_ERROR(Status
)) {
501 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", OptionStr
);
502 ShellStatus
= SHELL_INVALID_PARAMETER
;
506 EfiBootManagerFreeLoadOption (&LoadOption
);
508 if (DevicePath
!= NULL
) {
509 FreePool (DevicePath
);
512 if (FileList
!= NULL
) {
513 ShellCloseFileMetaArg (&FileList
);
516 return (ShellStatus
);
520 Function to add a option.
522 @param[in] Position The position to add Target at.
523 @param[in] File The file to make the target.
524 @param[in] Desc The description text.
525 @param[in] CurrentOrder The pointer to the current order of items.
526 @param[in] OrderCount The number if items in CurrentOrder.
527 @param[in] Target The info on the option to add.
528 @param[in] UseHandle TRUE to use HandleNumber, FALSE to use File and Desc.
529 @param[in] UsePath TRUE to convert to devicepath.
530 @param[in] HandleNumber The handle number to add.
532 @retval SHELL_SUCCESS The operation was successful.
533 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
538 IN CONST CHAR16
*File
,
539 IN CONST CHAR16
*Desc
,
540 IN CONST UINT16
*CurrentOrder
,
541 IN CONST UINTN OrderCount
,
542 IN CONST BCFG_OPERATION_TARGET Target
,
543 IN CONST BOOLEAN UseHandle
,
544 IN CONST BOOLEAN UsePath
,
545 IN CONST UINTN HandleNumber
549 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
550 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
551 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
553 UINT8
*TempByteBuffer
;
554 UINT8
*TempByteStart
;
555 EFI_SHELL_FILE_INFO
*Arg
;
556 EFI_SHELL_FILE_INFO
*FileList
;
557 CHAR16 OptionStr
[40];
558 UINTN DescSize
, FilePathSize
;
560 UINTN TargetLocation
;
563 EFI_HANDLE CurHandle
;
564 UINTN DriverBindingHandleCount
;
565 UINTN ParentControllerHandleCount
;
566 UINTN ChildControllerHandleCount
;
567 SHELL_STATUS ShellStatus
;
571 if (File
== NULL
|| Desc
== NULL
) {
572 return (SHELL_INVALID_PARAMETER
);
575 if (HandleNumber
== 0) {
576 return (SHELL_INVALID_PARAMETER
);
580 if (Position
> OrderCount
) {
581 Position
= OrderCount
;
588 ShellStatus
= SHELL_SUCCESS
;
589 TargetLocation
= 0xFFFF;
592 CurHandle
= ConvertHandleIndexToHandle(HandleNumber
);
593 if (CurHandle
== NULL
) {
594 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Handle Number");
595 ShellStatus
= SHELL_INVALID_PARAMETER
;
597 if (Target
== BcfgTargetBootOrder
) {
599 //Make sure that the handle should point to a real controller
601 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
603 &DriverBindingHandleCount
,
606 Status
= PARSE_HANDLE_DATABASE_PARENTS (
608 &ParentControllerHandleCount
,
611 Status
= ParseHandleDatabaseForChildControllers (
613 &ChildControllerHandleCount
,
616 if (DriverBindingHandleCount
> 0
617 || ParentControllerHandleCount
> 0
618 || ChildControllerHandleCount
> 0) {
620 Status
= gBS
->HandleProtocol (
622 &gEfiDevicePathProtocolGuid
,
625 if (EFI_ERROR (Status
)) {
626 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_HANDLE
), gShellBcfgHiiHandle
, L
"bcfg", HandleNumber
);
627 ShellStatus
= SHELL_INVALID_PARAMETER
;
631 //Make sure that the handle should point to driver, not a controller.
633 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
635 &DriverBindingHandleCount
,
638 Status
= PARSE_HANDLE_DATABASE_PARENTS (
640 &ParentControllerHandleCount
,
643 Status
= ParseHandleDatabaseForChildControllers (
645 &ChildControllerHandleCount
,
648 Status
= gBS
->HandleProtocol (
650 &gEfiDevicePathProtocolGuid
,
653 if (DriverBindingHandleCount
> 0
654 || ParentControllerHandleCount
> 0
655 || ChildControllerHandleCount
> 0
656 || !EFI_ERROR(Status
) ) {
657 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Handle Number");
658 ShellStatus
= SHELL_INVALID_PARAMETER
;
661 // Get the DevicePath from the loaded image information.
663 Status
= GetDevicePathForDriverHandle(CurHandle
, &FilePath
);
671 ShellOpenFileMetaArg ((CHAR16
*)File
, EFI_FILE_MODE_READ
, &FileList
);
673 if (FileList
== NULL
) {
675 // If filename matched nothing fail
677 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", File
);
678 ShellStatus
= SHELL_INVALID_PARAMETER
;
679 } else if (FileList
->Link
.ForwardLink
!= FileList
->Link
.BackLink
) {
681 // If filename expanded to multiple names, fail
683 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE
), gShellBcfgHiiHandle
, L
"bcfg", File
);
684 ShellStatus
= SHELL_INVALID_PARAMETER
;
686 Arg
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
);
687 if (EFI_ERROR(Arg
->Status
)) {
688 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_OPEN
), gShellBcfgHiiHandle
, L
"bcfg", File
);
689 ShellStatus
= SHELL_INVALID_PARAMETER
;
692 // Build FilePath to the filename
696 // get the device path
698 DevicePath
= gEfiShellProtocol
->GetDevicePathFromFilePath(Arg
->FullName
);
699 if (DevicePath
== NULL
) {
700 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_DP
), gShellBcfgHiiHandle
, L
"bcfg", Arg
->FullName
);
701 ShellStatus
= SHELL_UNSUPPORTED
;
704 DevPath
= DevicePath
;
705 ShellStatus
= SHELL_INVALID_PARAMETER
;
706 while (!IsDevicePathEnd(DevPath
)) {
707 if ((DevicePathType(DevPath
) == MEDIA_DEVICE_PATH
) &&
708 (DevicePathSubType(DevPath
) == MEDIA_HARDDRIVE_DP
)) {
711 // If we find it use it instead
713 ShellStatus
= SHELL_SUCCESS
;
714 FilePath
= DuplicateDevicePath (DevPath
);
717 DevPath
= NextDevicePathNode(DevPath
);
720 FilePath
= DuplicateDevicePath(DevicePath
);
722 FreePool(DevicePath
);
729 if (ShellStatus
== SHELL_SUCCESS
) {
731 // Find a free target ,a brute force implementation
734 for (TargetLocation
=0; TargetLocation
< 0xFFFF; TargetLocation
++) {
736 for (Index
=0; Index
< OrderCount
; Index
++) {
737 if (CurrentOrder
[Index
] == TargetLocation
) {
748 if (TargetLocation
== 0xFFFF) {
749 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET_NF
), gShellBcfgHiiHandle
, L
"bcfg");
751 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET
), gShellBcfgHiiHandle
, TargetLocation
);
755 if (ShellStatus
== SHELL_SUCCESS
) {
759 DescSize
= StrSize(Desc
);
760 FilePathSize
= GetDevicePathSize (FilePath
);
762 TempByteBuffer
= AllocateZeroPool(sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
);
763 if (TempByteBuffer
!= NULL
) {
764 TempByteStart
= TempByteBuffer
;
765 *((UINT32
*) TempByteBuffer
) = LOAD_OPTION_ACTIVE
; // Attributes
766 TempByteBuffer
+= sizeof (UINT32
);
768 *((UINT16
*) TempByteBuffer
) = (UINT16
)FilePathSize
; // FilePathListLength
769 TempByteBuffer
+= sizeof (UINT16
);
771 CopyMem (TempByteBuffer
, Desc
, DescSize
);
772 TempByteBuffer
+= DescSize
;
773 ASSERT (FilePath
!= NULL
);
774 CopyMem (TempByteBuffer
, FilePath
, FilePathSize
);
776 UnicodeSPrint (OptionStr
, sizeof(OptionStr
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", TargetLocation
);
777 Status
= gRT
->SetVariable (
779 &gEfiGlobalVariableGuid
,
780 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
781 sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
,
785 FreePool(TempByteStart
);
787 Status
= EFI_OUT_OF_RESOURCES
;
790 if (EFI_ERROR(Status
)) {
791 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", OptionStr
);
793 NewOrder
= AllocateZeroPool ((OrderCount
+ 1) * sizeof (NewOrder
[0]));
794 if (NewOrder
!= NULL
) {
795 CopyMem (NewOrder
, CurrentOrder
, (OrderCount
) * sizeof (NewOrder
[0]));
798 // Insert target into order list
800 for (Index
= OrderCount
; Index
> Position
; Index
--) {
801 NewOrder
[Index
] = NewOrder
[Index
- 1];
804 NewOrder
[Position
] = (UINT16
) TargetLocation
;
805 Status
= gRT
->SetVariable (
806 Target
== BcfgTargetBootOrder
? L
"BootOrder" : L
"DriverOrder",
807 &gEfiGlobalVariableGuid
,
808 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
809 (OrderCount
+ 1) * sizeof (UINT16
),
815 if (EFI_ERROR (Status
)) {
816 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
? L
"BootOrder" : L
"DriverOrder");
817 ShellStatus
= SHELL_INVALID_PARAMETER
;
819 Print (L
"bcfg: Add %s as %x\n", OptionStr
, Position
);
826 //If always Free FilePath, will free devicepath in system when use "addh"
828 if (FilePath
!=NULL
&& !UseHandle
) {
836 if (Handles
!= NULL
) {
840 if (FileList
!= NULL
) {
841 ShellCloseFileMetaArg (&FileList
);
844 return (ShellStatus
);
848 Funciton to remove an item.
850 @param[in] Target The target item to move.
851 @param[in] CurrentOrder The pointer to the current order of items.
852 @param[in] OrderCount The number if items in CurrentOrder.
853 @param[in] Location The current location of the Target.
855 @retval SHELL_SUCCESS The operation was successful.
856 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
860 IN CONST BCFG_OPERATION_TARGET Target
,
861 IN CONST UINT16
*CurrentOrder
,
862 IN CONST UINTN OrderCount
,
863 IN CONST UINT16 Location
866 CHAR16 VariableName
[12];
871 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", CurrentOrder
[Location
]);
872 Status
= gRT
->SetVariable(
874 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
875 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
878 if (EFI_ERROR(Status
)) {
879 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
880 return (SHELL_INVALID_PARAMETER
);
882 NewOrder
= AllocateZeroPool(OrderCount
*sizeof(CurrentOrder
[0]));
883 if (NewOrder
!= NULL
) {
884 NewCount
= OrderCount
;
885 CopyMem(NewOrder
, CurrentOrder
, OrderCount
*sizeof(CurrentOrder
[0]));
886 CopyMem(NewOrder
+Location
, NewOrder
+Location
+1, (OrderCount
- Location
- 1)*sizeof(CurrentOrder
[0]));
889 Status
= gRT
->SetVariable(
890 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
891 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
892 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
893 NewCount
*sizeof(NewOrder
[0]),
897 Status
= EFI_OUT_OF_RESOURCES
;
899 if (EFI_ERROR(Status
)) {
900 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder");
901 return (SHELL_INVALID_PARAMETER
);
903 return (SHELL_SUCCESS
);
907 Funciton to move a item to another location.
909 @param[in] Target The target item to move.
910 @param[in] CurrentOrder The pointer to the current order of items.
911 @param[in] OrderCount The number if items in CurrentOrder.
912 @param[in] OldLocation The current location of the Target.
913 @param[in] NewLocation The desired location of the Target.
915 @retval SHELL_SUCCESS The operation was successful.
916 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
920 IN CONST BCFG_OPERATION_TARGET Target
,
921 IN CONST UINT16
*CurrentOrder
,
922 IN CONST UINTN OrderCount
,
923 IN CONST UINT16 OldLocation
,
924 IN UINT16 NewLocation
931 NewOrder
= AllocateCopyPool(OrderCount
*sizeof(CurrentOrder
[0]), CurrentOrder
);
932 if (NewOrder
== NULL
) {
933 return (SHELL_OUT_OF_RESOURCES
);
937 // correct the new location
939 if (NewLocation
>= OrderCount
) {
940 if (OrderCount
> 0) {
941 NewLocation
= (UINT16
)OrderCount
- 1;
947 Temp
= CurrentOrder
[OldLocation
];
948 CopyMem(NewOrder
+OldLocation
, NewOrder
+OldLocation
+1, (OrderCount
- OldLocation
- 1)*sizeof(CurrentOrder
[0]));
949 CopyMem(NewOrder
+NewLocation
+1, NewOrder
+NewLocation
, (OrderCount
- NewLocation
- 1)*sizeof(CurrentOrder
[0]));
950 NewOrder
[NewLocation
] = Temp
;
952 Status
= gRT
->SetVariable(
953 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
954 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
955 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
956 OrderCount
*sizeof(CurrentOrder
[0]),
961 if (EFI_ERROR(Status
)) {
962 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder");
963 return (SHELL_INVALID_PARAMETER
);
965 return (SHELL_SUCCESS
);
969 Function to add optional data to an option.
971 @param[in] OptData The optional data to add.
972 @param[in] CurrentOrder The pointer to the current order of items.
973 @param[in] OrderCount The number if items in CurrentOrder.
974 @param[in] Target The target of the operation.
976 @retval SHELL_SUCCESS The operation was succesful.
980 IN CONST CHAR16
*OptData
,
981 IN CONST UINT16
*CurrentOrder
,
982 IN CONST UINTN OrderCount
,
983 IN CONST BCFG_OPERATION_TARGET Target
986 EFI_KEY_OPTION NewKeyOption
;
987 EFI_KEY_OPTION
*KeyOptionBuffer
;
988 SHELL_STATUS ShellStatus
;
994 CONST CHAR16
*Walker
;
999 CHAR16 VariableName
[12];
1002 SHELL_FILE_HANDLE FileHandle
;
1004 Status
= EFI_SUCCESS
;
1005 ShellStatus
= SHELL_SUCCESS
;
1009 KeyOptionBuffer
= NULL
;
1010 VariableData
= NULL
;
1012 ZeroMem(&NewKeyOption
, sizeof(EFI_KEY_OPTION
));
1013 ZeroMem(VariableName
, sizeof(VariableName
));
1015 while(Walker
[0] == L
' ') {
1020 // Get the index of the variable we are changing.
1022 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, TRUE
, TRUE
);
1023 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
|| ((UINT16
)Intermediate
) > ((UINT16
)OrderCount
)) {
1024 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Option Index");
1025 ShellStatus
= SHELL_INVALID_PARAMETER
;
1026 return (ShellStatus
);
1028 OptionIndex
= (UINT16
)Intermediate
;
1030 Temp
= StrStr(Walker
, L
" ");
1034 while(Walker
[0] == L
' ') {
1039 // determine whether we have file with data, quote delimited information, or a hot-key
1041 if (Walker
[0] == L
'\"') {
1043 // quoted filename or quoted information.
1045 Temp
= StrStr(Walker
+1, L
"\"");
1046 if (Temp
== NULL
|| StrLen(Temp
) != 1) {
1047 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1048 ShellStatus
= SHELL_INVALID_PARAMETER
;
1050 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
+1, 0);
1051 if (FileName
== NULL
) {
1052 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
1053 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1054 return (ShellStatus
);
1056 Temp2
= StrStr(FileName
, L
"\"");
1057 ASSERT(Temp2
!= NULL
);
1058 Temp2
[0] = CHAR_NULL
;
1060 if (StrLen(Temp2
)>0) {
1061 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1062 ShellStatus
= SHELL_INVALID_PARAMETER
;
1064 if (EFI_ERROR(ShellFileExists(Walker
))) {
1066 // Not a file. must be misc information.
1071 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
, 0);
1076 // filename or hot key information.
1078 if (StrStr(Walker
, L
" ") == NULL
) {
1082 if (EFI_ERROR(ShellFileExists(Walker
))) {
1083 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FIND_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1084 ShellStatus
= SHELL_INVALID_PARAMETER
;
1086 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
, 0);
1089 if (Target
!= BcfgTargetBootOrder
) {
1090 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_BOOT_ONLY
), gShellBcfgHiiHandle
, L
"bcfg");
1091 ShellStatus
= SHELL_INVALID_PARAMETER
;
1094 if (ShellStatus
== SHELL_SUCCESS
) {
1096 // Get hot key information
1098 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
1099 if (EFI_ERROR(Status
) || (((UINT32
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
) {
1100 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1101 ShellStatus
= SHELL_INVALID_PARAMETER
;
1103 NewKeyOption
.KeyData
.PackedValue
= (UINT32
)Intermediate
;
1104 Temp
= StrStr(Walker
, L
" ");
1108 while(Walker
[0] == L
' ') {
1113 if (ShellStatus
== SHELL_SUCCESS
) {
1115 // Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.
1116 // Re-allocate with the added information.
1118 KeyOptionBuffer
= AllocatePool (sizeof(EFI_KEY_OPTION
) + (sizeof(EFI_INPUT_KEY
) * NewKeyOption
.KeyData
.Options
.InputKeyCount
));
1119 if (KeyOptionBuffer
== NULL
) {
1120 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
1121 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1124 CopyMem (KeyOptionBuffer
, &NewKeyOption
, sizeof(EFI_KEY_OPTION
));
1126 for (LoopCounter
= 0 ; ShellStatus
== SHELL_SUCCESS
&& LoopCounter
< NewKeyOption
.KeyData
.Options
.InputKeyCount
; LoopCounter
++) {
1130 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
1131 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
) {
1132 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1133 ShellStatus
= SHELL_INVALID_PARAMETER
;
1135 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof(EFI_KEY_OPTION
)))[LoopCounter
].ScanCode
= (UINT16
)Intermediate
;
1136 Temp
= StrStr(Walker
, L
" ");
1140 while(Walker
[0] == L
' ') {
1147 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
1148 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
)) {
1149 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1150 ShellStatus
= SHELL_INVALID_PARAMETER
;
1152 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof(EFI_KEY_OPTION
)))[LoopCounter
].UnicodeChar
= (UINT16
)Intermediate
;
1153 Temp
= StrStr(Walker
, L
" ");
1157 while(Walker
[0] == L
' ') {
1162 if (ShellStatus
== SHELL_SUCCESS
) {
1164 // Now do the BootOption / BootOptionCrc
1166 ASSERT (OptionIndex
<= OrderCount
);
1167 KeyOptionBuffer
->BootOption
= CurrentOrder
[OptionIndex
];
1168 Status
= GetBootOptionCrc(&(KeyOptionBuffer
->BootOptionCrc
), KeyOptionBuffer
->BootOption
);
1169 if (EFI_ERROR(Status
)) {
1170 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Option Index");
1171 ShellStatus
= SHELL_INVALID_PARAMETER
;
1175 if (ShellStatus
== SHELL_SUCCESS
) {
1176 for (Temp2
= NULL
, KeyIndex
= 0 ; KeyIndex
<= 0xFFFF ; KeyIndex
++) {
1177 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"Key%04x", KeyIndex
);
1178 Status
= GetEfiGlobalVariable2 (VariableName
, &VariableData
, NULL
);
1179 if (Status
== EFI_NOT_FOUND
) {
1182 if (!EFI_ERROR(Status
)) {
1183 SHELL_FREE_NON_NULL(VariableData
);
1186 if (KeyIndex
<= 0xFFFF) {
1187 Status
= gRT
->SetVariable(
1189 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1190 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
1191 sizeof(EFI_KEY_OPTION
) + (sizeof(EFI_INPUT_KEY
) * NewKeyOption
.KeyData
.Options
.InputKeyCount
),
1193 if (EFI_ERROR(Status
)) {
1194 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1195 ShellStatus
= SHELL_INVALID_PARAMETER
;
1198 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_VAR_NO_NUM
), gShellBcfgHiiHandle
, L
"bcfg");
1199 ShellStatus
= SHELL_INVALID_PARAMETER
;
1201 ASSERT(FileName
== NULL
&& Data
== NULL
);
1207 // Shouldn't be possible to have have both. Neither is ok though.
1209 ASSERT(FileName
== NULL
|| Data
== NULL
);
1211 if (ShellStatus
== SHELL_SUCCESS
&& (FileName
!= NULL
|| Data
!= NULL
)) {
1212 if (FileName
!= NULL
) {
1214 // Open the file and populate the data buffer.
1216 Status
= ShellOpenFileByName(
1221 if (!EFI_ERROR(Status
)) {
1222 Status
= ShellGetFileSize(FileHandle
, &Intermediate
);
1224 Data
= AllocateZeroPool((UINTN
)Intermediate
);
1226 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
1227 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1229 if (!EFI_ERROR(Status
)) {
1230 Status
= ShellReadFile(FileHandle
, (UINTN
*)&Intermediate
, Data
);
1233 Intermediate
= StrSize(Data
);
1236 if (!EFI_ERROR(Status
) && ShellStatus
== SHELL_SUCCESS
&& Data
!= NULL
) {
1237 Status
= UpdateOptionalData(CurrentOrder
[OptionIndex
], (UINTN
)Intermediate
, (UINT8
*)Data
, Target
);
1238 if (EFI_ERROR(Status
)) {
1239 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1240 ShellStatus
= SHELL_INVALID_PARAMETER
;
1243 if (EFI_ERROR(Status
) && ShellStatus
== SHELL_SUCCESS
) {
1244 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1245 ShellStatus
= SHELL_INVALID_PARAMETER
;
1249 SHELL_FREE_NON_NULL(Data
);
1250 SHELL_FREE_NON_NULL(KeyOptionBuffer
);
1251 SHELL_FREE_NON_NULL(FileName
);
1256 Function to dump the Bcfg information.
1258 @param[in] Op The operation.
1259 @param[in] OrderCount How many to dump.
1260 @param[in] CurrentOrder The pointer to the current order of items.
1261 @param[in] VerboseOutput TRUE for extra output. FALSE otherwise.
1263 @retval SHELL_SUCCESS The dump was successful.
1264 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
1268 IN CONST CHAR16
*Op
,
1269 IN CONST UINTN OrderCount
,
1270 IN CONST UINT16
*CurrentOrder
,
1271 IN CONST BOOLEAN VerboseOutput
1277 CHAR16 VariableName
[12];
1279 CHAR16
*DevPathString
;
1282 EFI_LOAD_OPTION
*LoadOption
;
1283 CHAR16
*Description
;
1284 UINTN DescriptionSize
;
1285 UINTN OptionalDataOffset
;
1287 if (OrderCount
== 0) {
1288 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_BCFG_NONE
), gShellBcfgHiiHandle
, L
"bcfg");
1289 return (SHELL_SUCCESS
);
1294 for (LoopVar
= 0 ; LoopVar
< OrderCount
; LoopVar
++) {
1297 DevPathString
= NULL
;
1299 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Op
, CurrentOrder
[LoopVar
]);
1301 Status
= gRT
->GetVariable(
1303 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1307 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1308 Buffer
= AllocateZeroPool(BufferSize
);
1309 Status
= gRT
->GetVariable(
1311 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1317 if (EFI_ERROR(Status
) || Buffer
== NULL
) {
1318 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_READ_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1324 // We expect the Attributes, FilePathListLength, and L'\0'-terminated
1325 // Description fields to be present.
1327 if (BufferSize
< sizeof *LoadOption
+ sizeof (CHAR16
)) {
1332 STRING_TOKEN (STR_BCFG_VAR_CORRUPT
),
1333 gShellBcfgHiiHandle
,
1341 LoadOption
= (EFI_LOAD_OPTION
*)Buffer
;
1342 Description
= (CHAR16
*)(Buffer
+ sizeof (EFI_LOAD_OPTION
));
1343 DescriptionSize
= StrSize (Description
);
1345 if (LoadOption
->FilePathListLength
!= 0) {
1346 FilePathList
= (UINT8
*)Description
+ DescriptionSize
;
1347 DevPathString
= ConvertDevicePathToText(FilePathList
, TRUE
, FALSE
);
1350 OptionalDataOffset
= sizeof *LoadOption
+ DescriptionSize
+
1351 LoadOption
->FilePathListLength
;
1357 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS
),
1358 gShellBcfgHiiHandle
,
1363 OptionalDataOffset
>= BufferSize
? L
'N' : L
'Y'
1365 if (VerboseOutput
&& (OptionalDataOffset
< BufferSize
)) {
1368 0, // Offset (displayed)
1369 BufferSize
- OptionalDataOffset
, // DataSize
1370 Buffer
+ OptionalDataOffset
// UserData
1375 if (Buffer
!= NULL
) {
1378 if (DevPathString
!= NULL
) {
1379 FreePool(DevPathString
);
1382 return (Errors
> 0) ? SHELL_INVALID_PARAMETER
: SHELL_SUCCESS
;
1386 Function to initialize the BCFG operation structure.
1388 @param[in] Struct The stuct to initialize.
1392 IN BGFG_OPERATION
*Struct
1395 ASSERT(Struct
!= NULL
);
1396 Struct
->Target
= BcfgTargetMax
;
1397 Struct
->Type
= BcfgTypeMax
;
1398 Struct
->Number1
= 0;
1399 Struct
->Number2
= 0;
1400 Struct
->HandleIndex
= 0;
1401 Struct
->FileName
= NULL
;
1402 Struct
->Description
= NULL
;
1403 Struct
->Order
= NULL
;
1404 Struct
->OptData
= NULL
;
1408 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
1410 {L
"-opt", TypeMaxValue
},
1415 Function for 'bcfg' command.
1417 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1418 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1422 ShellCommandRunBcfg (
1423 IN EFI_HANDLE ImageHandle
,
1424 IN EFI_SYSTEM_TABLE
*SystemTable
1428 LIST_ENTRY
*Package
;
1429 CHAR16
*ProblemParam
;
1430 SHELL_STATUS ShellStatus
;
1432 CONST CHAR16
*CurrentParam
;
1433 BGFG_OPERATION CurrentOperation
;
1435 UINT64 Intermediate
;
1439 ProblemParam
= NULL
;
1441 ShellStatus
= SHELL_SUCCESS
;
1443 InitBcfgStruct(&CurrentOperation
);
1446 // initialize the shell lib (we must be in non-auto-init...)
1448 Status
= ShellInitialize();
1449 ASSERT_EFI_ERROR(Status
);
1451 Status
= CommandInit();
1452 ASSERT_EFI_ERROR(Status
);
1455 // parse the command line
1457 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
1458 if (EFI_ERROR(Status
)) {
1459 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
1460 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, L
"bcfg", ProblemParam
);
1461 FreePool(ProblemParam
);
1462 ShellStatus
= SHELL_INVALID_PARAMETER
;
1468 // Read in if we are doing -OPT
1470 if (ShellCommandLineGetFlag(Package
, L
"-opt")) {
1471 CurrentOperation
.OptData
= ShellCommandLineGetValue(Package
, L
"-opt");
1472 if (CurrentOperation
.OptData
== NULL
) {
1473 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellBcfgHiiHandle
, L
"bcfg", L
"-opt");
1474 ShellStatus
= SHELL_INVALID_PARAMETER
;
1476 CurrentOperation
.Type
= BcfgTypeOpt
;
1480 // small block to read the target of the operation
1482 if ((ShellCommandLineGetCount(Package
) < 3 && CurrentOperation
.Type
!= BcfgTypeOpt
) ||
1483 (ShellCommandLineGetCount(Package
) < 2 && CurrentOperation
.Type
== BcfgTypeOpt
)
1485 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1486 ShellStatus
= SHELL_INVALID_PARAMETER
;
1487 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"driver") == 0) {
1488 CurrentOperation
.Target
= BcfgTargetDriverOrder
;
1489 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"boot") == 0) {
1490 CurrentOperation
.Target
= BcfgTargetBootOrder
;
1492 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT
), gShellBcfgHiiHandle
, L
"bcfg");
1493 ShellStatus
= SHELL_INVALID_PARAMETER
;
1498 // Read in the boot or driver order environment variable (not needed for opt)
1500 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
1502 Status
= gRT
->GetVariable(
1503 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
1504 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1507 CurrentOperation
.Order
);
1508 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1509 CurrentOperation
.Order
= AllocateZeroPool(Length
+(4*sizeof(CurrentOperation
.Order
[0])));
1510 if (CurrentOperation
.Order
== NULL
) {
1511 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1513 Status
= gRT
->GetVariable(
1514 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
1515 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1518 CurrentOperation
.Order
);
1523 Count
= (UINT16
) (Length
/ sizeof(CurrentOperation
.Order
[0]));
1526 // large block to read the type of operation and verify parameter types for the info.
1528 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
1529 for (ParamNumber
= 2 ; ParamNumber
< ShellCommandLineGetCount(Package
) && ShellStatus
== SHELL_SUCCESS
; ParamNumber
++) {
1530 CurrentParam
= ShellCommandLineGetRawValue(Package
, ParamNumber
);
1531 if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"dump") == 0) {
1532 CurrentOperation
.Type
= BcfgTypeDump
;
1533 if (ShellCommandLineGetCount(Package
) > 3) {
1534 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellBcfgHiiHandle
, L
"bcfg");
1535 ShellStatus
= SHELL_INVALID_PARAMETER
;
1537 } else if (ShellCommandLineGetFlag(Package
, L
"-v")) {
1538 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"-v (without dump)");
1539 ShellStatus
= SHELL_INVALID_PARAMETER
;
1540 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"add") == 0) {
1541 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1542 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1543 ShellStatus
= SHELL_INVALID_PARAMETER
;
1545 CurrentOperation
.Type
= BcfgTypeAdd
;
1546 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1547 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1548 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1549 ShellStatus
= SHELL_INVALID_PARAMETER
;
1551 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1552 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1553 ASSERT(CurrentOperation
.FileName
== NULL
);
1554 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1555 ASSERT(CurrentOperation
.Description
== NULL
);
1556 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1558 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addp") == 0) {
1559 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1560 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1561 ShellStatus
= SHELL_INVALID_PARAMETER
;
1563 CurrentOperation
.Type
= BcfgTypeAddp
;
1564 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1565 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1566 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1567 ShellStatus
= SHELL_INVALID_PARAMETER
;
1569 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1570 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1571 ASSERT(CurrentOperation
.FileName
== NULL
);
1572 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1573 ASSERT(CurrentOperation
.Description
== NULL
);
1574 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1576 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addh") == 0) {
1577 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1578 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1579 ShellStatus
= SHELL_INVALID_PARAMETER
;
1581 CurrentOperation
.Type
= BcfgTypeAddh
;
1582 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1583 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1584 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1585 ShellStatus
= SHELL_INVALID_PARAMETER
;
1587 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1588 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1589 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1590 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1591 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1592 ShellStatus
= SHELL_INVALID_PARAMETER
;
1594 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1595 CurrentOperation
.HandleIndex
= (UINT16
)Intermediate
;
1596 ASSERT(CurrentOperation
.Description
== NULL
);
1597 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1600 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"rm") == 0) {
1601 if ((ParamNumber
+ 1) >= ShellCommandLineGetCount(Package
)) {
1602 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1603 ShellStatus
= SHELL_INVALID_PARAMETER
;
1605 CurrentOperation
.Type
= BcfgTypeRm
;
1606 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1607 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1608 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1609 ShellStatus
= SHELL_INVALID_PARAMETER
;
1611 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1612 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1613 if (CurrentOperation
.Number1
>= Count
){
1614 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1615 ShellStatus
= SHELL_INVALID_PARAMETER
;
1618 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"mv") == 0) {
1619 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount(Package
)) {
1620 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1621 ShellStatus
= SHELL_INVALID_PARAMETER
;
1623 CurrentOperation
.Type
= BcfgTypeMv
;
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 if (CurrentOperation
.Number1
>= Count
){
1632 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1633 ShellStatus
= SHELL_INVALID_PARAMETER
;
1635 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1636 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1637 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1638 ShellStatus
= SHELL_INVALID_PARAMETER
;
1640 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1641 CurrentOperation
.Number2
= (UINT16
)Intermediate
;
1643 if (CurrentOperation
.Number2
== CurrentOperation
.Number1
1644 ||CurrentOperation
.Number2
>= Count
1646 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1647 ShellStatus
= SHELL_INVALID_PARAMETER
;
1652 else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"mod") == 0) {
1653 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount (Package
)) {
1654 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1655 ShellStatus
= SHELL_INVALID_PARAMETER
;
1657 CurrentOperation
.Type
= BcfgTypeMod
;
1658 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1659 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1660 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1661 ShellStatus
= SHELL_INVALID_PARAMETER
;
1663 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1664 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1665 if (CurrentOperation
.Number1
>= Count
) {
1666 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1667 ShellStatus
= SHELL_INVALID_PARAMETER
;
1669 ASSERT (CurrentOperation
.Description
== NULL
);
1670 CurrentOperation
.Description
= StrnCatGrow (&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue (Package
, ++ParamNumber
), 0);
1674 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"modf") == 0) {
1675 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount (Package
)) {
1676 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1677 ShellStatus
= SHELL_INVALID_PARAMETER
;
1679 CurrentOperation
.Type
= BcfgTypeModf
;
1680 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1681 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1682 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1683 ShellStatus
= SHELL_INVALID_PARAMETER
;
1685 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1686 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1687 if (CurrentOperation
.Number1
>= Count
) {
1688 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1689 ShellStatus
= SHELL_INVALID_PARAMETER
;
1691 ASSERT (CurrentOperation
.FileName
== NULL
);
1692 CurrentOperation
.FileName
= StrnCatGrow (&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue (Package
, ++ParamNumber
), 0);
1696 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"modp") == 0) {
1697 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount (Package
)) {
1698 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1699 ShellStatus
= SHELL_INVALID_PARAMETER
;
1701 CurrentOperation
.Type
= BcfgTypeModp
;
1702 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1703 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1704 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1705 ShellStatus
= SHELL_INVALID_PARAMETER
;
1707 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1708 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1709 if (CurrentOperation
.Number1
>= Count
) {
1710 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1711 ShellStatus
= SHELL_INVALID_PARAMETER
;
1713 ASSERT (CurrentOperation
.FileName
== NULL
);
1714 CurrentOperation
.FileName
= StrnCatGrow (&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue (Package
, ++ParamNumber
), 0);
1718 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"modh") == 0) {
1719 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount (Package
)) {
1720 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1721 ShellStatus
= SHELL_INVALID_PARAMETER
;
1723 CurrentOperation
.Type
= BcfgTypeModh
;
1724 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1725 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1726 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1727 ShellStatus
= SHELL_INVALID_PARAMETER
;
1730 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1731 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1732 if (CurrentOperation
.Number1
>= Count
) {
1733 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1734 ShellStatus
= SHELL_INVALID_PARAMETER
;
1736 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1737 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1738 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1739 ShellStatus
= SHELL_INVALID_PARAMETER
;
1741 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1742 CurrentOperation
.HandleIndex
= (UINT16
)Intermediate
;
1748 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1749 ShellStatus
= SHELL_INVALID_PARAMETER
;
1753 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
&& CurrentOperation
.Type
< BcfgTypeMax
) {
1755 // we have all the info. Do the work
1757 switch (CurrentOperation
.Type
) {
1759 ShellStatus
= BcfgDisplayDump(
1760 CurrentOperation
.Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver",
1762 CurrentOperation
.Order
,
1763 ShellCommandLineGetFlag(Package
, L
"-v"));
1766 ShellStatus
= BcfgMove(
1767 CurrentOperation
.Target
,
1768 CurrentOperation
.Order
,
1770 CurrentOperation
.Number1
,
1771 CurrentOperation
.Number2
);
1774 ShellStatus
= BcfgRemove(
1775 CurrentOperation
.Target
,
1776 CurrentOperation
.Order
,
1778 CurrentOperation
.Number1
);
1783 ShellStatus
= BcfgAdd(
1784 CurrentOperation
.Number1
,
1785 CurrentOperation
.FileName
,
1786 CurrentOperation
.Description
==NULL
?L
"":CurrentOperation
.Description
,
1787 CurrentOperation
.Order
,
1789 CurrentOperation
.Target
,
1790 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddh
),
1791 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddp
),
1792 CurrentOperation
.HandleIndex
);
1798 ShellStatus
= BcfgMod (&CurrentOperation
, Count
);
1801 ShellStatus
= BcfgAddOpt(
1802 CurrentOperation
.OptData
,
1803 CurrentOperation
.Order
,
1805 CurrentOperation
.Target
);
1813 if (Package
!= NULL
) {
1814 ShellCommandLineFreeVarList (Package
);
1816 if (CurrentOperation
.FileName
!= NULL
) {
1817 FreePool(CurrentOperation
.FileName
);
1819 if (CurrentOperation
.Description
!= NULL
) {
1820 FreePool(CurrentOperation
.Description
);
1822 if (CurrentOperation
.Order
!= NULL
) {
1823 FreePool(CurrentOperation
.Order
);
1826 return (ShellStatus
);
1831 Function to get the filename with help context if HII will not be used.
1833 @return The filename with help text in it.
1837 ShellCommandGetManFileNameBcfg (
1845 "Constructor" for the library.
1847 This will register the handler for the bcfg command.
1849 @param[in] ImageHandle the image handle of the process
1850 @param[in] SystemTable the EFI System Table pointer
1851 @param[in] Name the profile name to use
1853 @retval EFI_SUCCESS the shell command handlers were installed sucessfully
1854 @retval EFI_UNSUPPORTED the shell level required was not found.
1858 BcfgLibraryRegisterBcfgCommand (
1859 IN EFI_HANDLE ImageHandle
,
1860 IN EFI_SYSTEM_TABLE
*SystemTable
,
1861 IN CONST CHAR16
*Name
1864 if (gShellBcfgHiiHandle
!= NULL
) {
1865 return (EFI_SUCCESS
);
1868 gShellBcfgHiiHandle
= HiiAddPackages (&gShellBcfgHiiGuid
, gImageHandle
, UefiShellBcfgCommandLibStrings
, NULL
);
1869 if (gShellBcfgHiiHandle
== NULL
) {
1870 return (EFI_DEVICE_ERROR
);
1874 // install our shell command handler
1876 ShellCommandRegisterCommandName(L
"bcfg", ShellCommandRunBcfg
, ShellCommandGetManFileNameBcfg
, 0, Name
, FALSE
, gShellBcfgHiiHandle
, STRING_TOKEN(STR_GET_HELP_BCFG
));
1878 return (EFI_SUCCESS
);
1882 Destructor for the library. free any resources.
1884 @param ImageHandle The image handle of the process.
1885 @param SystemTable The EFI System Table pointer.
1889 BcfgLibraryUnregisterBcfgCommand (
1890 IN EFI_HANDLE ImageHandle
,
1891 IN EFI_SYSTEM_TABLE
*SystemTable
1894 if (gShellBcfgHiiHandle
!= NULL
) {
1895 HiiRemovePackages(gShellBcfgHiiHandle
);
1897 gShellBcfgHiiHandle
= NULL
;
1898 return (EFI_SUCCESS
);