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
= AllocateCopyPool(NewSize
, OriginalData
);
147 if (NewData
== NULL
) {
148 Status
= EFI_OUT_OF_RESOURCES
;
150 CopyMem(NewData
+ OriginalSize
- OriginalOptionDataSize
, Data
, DataSize
);
154 if (!EFI_ERROR(Status
)) {
156 // put the data back under the variable
158 Status
= gRT
->SetVariable(
160 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
161 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
166 SHELL_FREE_NON_NULL(OriginalData
);
167 SHELL_FREE_NON_NULL(NewData
);
172 This function will get a CRC for a boot option.
174 @param[in, out] Crc The CRC value to return.
175 @param[in] BootIndex The boot option index to CRC.
177 @retval EFI_SUCCESS The CRC was sucessfully returned.
178 @retval other A error occured.
186 CHAR16 VariableName
[12];
195 // Get the data Buffer
197 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%Boot%04x", BootIndex
);
198 Status
= gRT
->GetVariable(
200 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
204 if (Status
== EFI_BUFFER_TOO_SMALL
) {
205 Buffer
= AllocateZeroPool(BufferSize
);
206 Status
= gRT
->GetVariable(
208 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
215 // Get the CRC computed
217 if (!EFI_ERROR(Status
)) {
218 Status
= gBS
->CalculateCrc32 (Buffer
, BufferSize
, Crc
);
221 SHELL_FREE_NON_NULL(Buffer
);
226 This function will populate the device path protocol parameter based on TheHandle.
228 @param[in] TheHandle Driver handle.
229 @param[in, out] FilePath On a sucessful return the device path to the handle.
231 @retval EFI_SUCCESS The device path was sucessfully returned.
232 @retval other A error from gBS->HandleProtocol.
237 GetDevicePathForDriverHandle (
238 IN EFI_HANDLE TheHandle
,
239 IN OUT EFI_DEVICE_PATH_PROTOCOL
**FilePath
243 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
244 EFI_DEVICE_PATH_PROTOCOL
*ImageDevicePath
;
246 Status
= gBS
->OpenProtocol (
248 &gEfiLoadedImageProtocolGuid
,
249 (VOID
**)&LoadedImage
,
252 EFI_OPEN_PROTOCOL_GET_PROTOCOL
254 if (!EFI_ERROR (Status
)) {
255 Status
= gBS
->OpenProtocol (
256 LoadedImage
->DeviceHandle
,
257 &gEfiDevicePathProtocolGuid
,
258 (VOID
**)&ImageDevicePath
,
261 EFI_OPEN_PROTOCOL_GET_PROTOCOL
263 if (!EFI_ERROR (Status
)) {
264 // *DevPath = DuplicateDevicePath (ImageDevicePath);
265 // *FilePath = DuplicateDevicePath (LoadedImage->FilePath);
266 *FilePath
= AppendDevicePath(ImageDevicePath
,LoadedImage
->FilePath
);
268 LoadedImage
->DeviceHandle
,
269 &gEfiDevicePathProtocolGuid
,
275 &gEfiLoadedImageProtocolGuid
,
283 Functino to get Device Path by a handle.
285 @param[in] TheHandle Use it to get DevicePath.
286 @param[in] Target Boot option target.
287 @param[in, out] DevicePath On a sucessful return the device path to the handle.
289 @retval SHELL_INVALID_PARAMETER The handle was NULL.
290 @retval SHELL_NOT_FOUND Not found device path by handle.
291 @retval SHELL_SUCCESS Get device path successfully.
294 GetDevicePathByHandle(
295 IN EFI_HANDLE TheHandle
,
296 IN BCFG_OPERATION_TARGET Target
,
297 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePath
301 SHELL_STATUS ShellStatus
;
303 UINTN DriverBindingHandleCount
;
304 UINTN ParentControllerHandleCount
;
305 UINTN ChildControllerHandleCount
;
307 ShellStatus
= SHELL_SUCCESS
;
309 if (TheHandle
== NULL
) {
310 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Handle Number");
311 return SHELL_INVALID_PARAMETER
;
314 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (TheHandle
, &DriverBindingHandleCount
, NULL
);
315 if (EFI_ERROR(Status
)) {
316 DriverBindingHandleCount
= 0;
319 Status
= PARSE_HANDLE_DATABASE_PARENTS (TheHandle
, &ParentControllerHandleCount
, NULL
);
320 if (EFI_ERROR (Status
)) {
321 ParentControllerHandleCount
= 0;
324 Status
= ParseHandleDatabaseForChildControllers (TheHandle
, &ChildControllerHandleCount
, NULL
);
325 if (EFI_ERROR (Status
)) {
326 ChildControllerHandleCount
= 0;
329 Status
= gBS
->HandleProtocol (TheHandle
, &gEfiDevicePathProtocolGuid
, (VOID
**)DevicePath
);
331 if ( DriverBindingHandleCount
> 0 ||
332 ParentControllerHandleCount
> 0 ||
333 ChildControllerHandleCount
> 0 ||
337 // The handle points to a real controller which has a device path.
339 if (Target
== BcfgTargetDriverOrder
) {
343 NULL
,STRING_TOKEN (STR_GEN_PARAM_INV
),
346 L
"Handle should point to driver image."
348 ShellStatus
= SHELL_NOT_FOUND
;
352 // The handle points to a driver image.
354 if (Target
== BcfgTargetBootOrder
) {
359 STRING_TOKEN (STR_GEN_PARAM_INV
),
362 L
"Handle should point to controller."
364 ShellStatus
= SHELL_NOT_FOUND
;
366 if (EFI_ERROR (GetDevicePathForDriverHandle (TheHandle
, DevicePath
))) {
367 ShellStatus
= SHELL_NOT_FOUND
;
372 return (ShellStatus
);
376 Function to modify an option.
378 @param[in] BcfgOperation Pointer to BCFG operation.
379 @param[in] OrderCount The number if items in CurrentOrder.
381 @retval SHELL_SUCCESS The operation was successful.
382 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
383 @retval SHELL_OUT_OF_RESOUCES A memory allocation failed.
387 IN CONST BGFG_OPERATION
*BcfgOperation
,
388 IN CONST UINTN OrderCount
392 EFI_HANDLE CurHandle
;
393 SHELL_STATUS ShellStatus
;
394 CHAR16 OptionStr
[40];
395 EFI_SHELL_FILE_INFO
*FileList
;
396 EFI_SHELL_FILE_INFO
*Arg
;
397 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
398 EFI_DEVICE_PATH_PROTOCOL
*DevicePathBuffer
;
399 EFI_DEVICE_PATH_PROTOCOL
*DevicePathWalker
;
400 EFI_BOOT_MANAGER_LOAD_OPTION LoadOption
;
402 ShellStatus
= SHELL_SUCCESS
;
405 DevicePathBuffer
= NULL
;
407 ZeroMem (&LoadOption
, sizeof(EFI_BOOT_MANAGER_LOAD_OPTION
));
409 if ( (BcfgOperation
->Type
== BcfgTypeMod
&& BcfgOperation
->Description
== NULL
) ||
410 (BcfgOperation
->Type
== BcfgTypeModf
&& BcfgOperation
->FileName
== NULL
) ||
411 (BcfgOperation
->Type
== BcfgTypeModp
&& BcfgOperation
->FileName
== NULL
) ||
412 (BcfgOperation
->Type
== BcfgTypeModh
&& BcfgOperation
->HandleIndex
== 0) ||
413 (BcfgOperation
->Number1
> OrderCount
)
415 return (SHELL_INVALID_PARAMETER
);
418 if (BcfgOperation
->Type
== BcfgTypeModh
) {
419 CurHandle
= ConvertHandleIndexToHandle (BcfgOperation
->HandleIndex
);
420 ShellStatus
= GetDevicePathByHandle (CurHandle
, BcfgOperation
->Target
, &DevicePathBuffer
);
421 if (ShellStatus
== SHELL_SUCCESS
) {
422 DevicePath
= DuplicateDevicePath (DevicePathBuffer
);
424 } else if (BcfgOperation
->Type
== BcfgTypeModf
|| BcfgOperation
->Type
== BcfgTypeModp
) {
426 // Get Device Path by FileName.
428 ShellOpenFileMetaArg ((CHAR16
*)BcfgOperation
->FileName
, EFI_FILE_MODE_READ
, &FileList
);
429 if (FileList
== NULL
) {
431 // The name of file matched nothing.
433 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", BcfgOperation
->FileName
);
434 ShellStatus
= SHELL_INVALID_PARAMETER
;
436 else if (FileList
->Link
.ForwardLink
!= FileList
->Link
.BackLink
) {
438 // If the name of file expanded to multiple names, it's fail.
440 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE
), gShellBcfgHiiHandle
, L
"bcfg", BcfgOperation
->FileName
);
441 ShellStatus
= SHELL_INVALID_PARAMETER
;
443 Arg
= (EFI_SHELL_FILE_INFO
*)GetFirstNode (&FileList
->Link
);
444 if (EFI_ERROR (Arg
->Status
)) {
445 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_OPEN
), gShellBcfgHiiHandle
, L
"bcfg", BcfgOperation
->FileName
);
446 ShellStatus
= SHELL_INVALID_PARAMETER
;
448 DevicePathBuffer
= gEfiShellProtocol
->GetDevicePathFromFilePath (Arg
->FullName
);
449 if (DevicePathBuffer
== NULL
) {
450 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_DP
), gShellBcfgHiiHandle
, L
"bcfg", Arg
->FullName
);
451 ShellStatus
= SHELL_UNSUPPORTED
;
456 if (ShellStatus
== SHELL_SUCCESS
) {
457 if (BcfgOperation
->Type
== BcfgTypeModp
) {
458 ShellStatus
= SHELL_INVALID_PARAMETER
;
459 DevicePathWalker
= DevicePathBuffer
;
460 while (!IsDevicePathEnd (DevicePathWalker
)) {
461 if ( DevicePathType (DevicePathWalker
) == MEDIA_DEVICE_PATH
&&
462 DevicePathSubType (DevicePathWalker
) == MEDIA_HARDDRIVE_DP
465 // We found the portion of device path starting with the hard driver partition.
467 ShellStatus
= SHELL_SUCCESS
;
468 DevicePath
= DuplicateDevicePath (DevicePathWalker
);
471 DevicePathWalker
= NextDevicePathNode (DevicePathWalker
);
475 DevicePath
= DuplicateDevicePath (DevicePathBuffer
);
478 FreePool (DevicePathBuffer
);
482 if (ShellStatus
== SHELL_SUCCESS
) {
483 if (BcfgOperation
->Target
== BcfgTargetBootOrder
) {
484 UnicodeSPrint (OptionStr
, sizeof (OptionStr
), L
"Boot%04x", BcfgOperation
->Order
[BcfgOperation
->Number1
]);
486 UnicodeSPrint (OptionStr
, sizeof (OptionStr
), L
"Driver%04x", BcfgOperation
->Order
[BcfgOperation
->Number1
]);
488 Status
= EfiBootManagerVariableToLoadOption (OptionStr
, &LoadOption
);
489 if (EFI_ERROR(Status
)) {
490 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NONE
), gShellBcfgHiiHandle
);
491 ShellStatus
= SHELL_NOT_FOUND
;
495 if (ShellStatus
== SHELL_SUCCESS
) {
496 if (BcfgOperation
->Type
== BcfgTypeMod
) {
497 SHELL_FREE_NON_NULL (LoadOption
.Description
);
498 LoadOption
.Description
= AllocateCopyPool (StrSize (BcfgOperation
->Description
), BcfgOperation
->Description
);
500 SHELL_FREE_NON_NULL (LoadOption
.FilePath
);
501 LoadOption
.FilePath
= DuplicateDevicePath (DevicePath
);
504 Status
= EfiBootManagerLoadOptionToVariable (&LoadOption
);
505 if (EFI_ERROR(Status
)) {
506 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", OptionStr
);
507 ShellStatus
= SHELL_INVALID_PARAMETER
;
511 EfiBootManagerFreeLoadOption (&LoadOption
);
513 if (DevicePath
!= NULL
) {
514 FreePool (DevicePath
);
517 if (FileList
!= NULL
) {
518 ShellCloseFileMetaArg (&FileList
);
521 return (ShellStatus
);
525 Function to add a option.
527 @param[in] Position The position to add Target at.
528 @param[in] File The file to make the target.
529 @param[in] Desc The description text.
530 @param[in] CurrentOrder The pointer to the current order of items.
531 @param[in] OrderCount The number if items in CurrentOrder.
532 @param[in] Target The info on the option to add.
533 @param[in] UseHandle TRUE to use HandleNumber, FALSE to use File and Desc.
534 @param[in] UsePath TRUE to convert to devicepath.
535 @param[in] HandleNumber The handle number to add.
537 @retval SHELL_SUCCESS The operation was successful.
538 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
543 IN CONST CHAR16
*File
,
544 IN CONST CHAR16
*Desc
,
545 IN CONST UINT16
*CurrentOrder
,
546 IN CONST UINTN OrderCount
,
547 IN CONST BCFG_OPERATION_TARGET Target
,
548 IN CONST BOOLEAN UseHandle
,
549 IN CONST BOOLEAN UsePath
,
550 IN CONST UINTN HandleNumber
554 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
555 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
556 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
558 UINT8
*TempByteBuffer
;
559 UINT8
*TempByteStart
;
560 EFI_SHELL_FILE_INFO
*Arg
;
561 EFI_SHELL_FILE_INFO
*FileList
;
562 CHAR16 OptionStr
[40];
563 UINTN DescSize
, FilePathSize
;
565 UINTN TargetLocation
;
568 EFI_HANDLE CurHandle
;
569 UINTN DriverBindingHandleCount
;
570 UINTN ParentControllerHandleCount
;
571 UINTN ChildControllerHandleCount
;
572 SHELL_STATUS ShellStatus
;
576 if (File
== NULL
|| Desc
== NULL
) {
577 return (SHELL_INVALID_PARAMETER
);
580 if (HandleNumber
== 0) {
581 return (SHELL_INVALID_PARAMETER
);
585 if (Position
> OrderCount
) {
586 Position
= OrderCount
;
593 ShellStatus
= SHELL_SUCCESS
;
594 TargetLocation
= 0xFFFF;
597 CurHandle
= ConvertHandleIndexToHandle(HandleNumber
);
598 if (CurHandle
== NULL
) {
599 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Handle Number");
600 ShellStatus
= SHELL_INVALID_PARAMETER
;
602 if (Target
== BcfgTargetBootOrder
) {
604 //Make sure that the handle should point to a real controller
606 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
608 &DriverBindingHandleCount
,
611 Status
= PARSE_HANDLE_DATABASE_PARENTS (
613 &ParentControllerHandleCount
,
616 Status
= ParseHandleDatabaseForChildControllers (
618 &ChildControllerHandleCount
,
621 if (DriverBindingHandleCount
> 0
622 || ParentControllerHandleCount
> 0
623 || ChildControllerHandleCount
> 0) {
625 Status
= gBS
->HandleProtocol (
627 &gEfiDevicePathProtocolGuid
,
630 if (EFI_ERROR (Status
)) {
631 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_HANDLE
), gShellBcfgHiiHandle
, L
"bcfg", HandleNumber
);
632 ShellStatus
= SHELL_INVALID_PARAMETER
;
636 //Make sure that the handle should point to driver, not a controller.
638 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
640 &DriverBindingHandleCount
,
643 Status
= PARSE_HANDLE_DATABASE_PARENTS (
645 &ParentControllerHandleCount
,
648 Status
= ParseHandleDatabaseForChildControllers (
650 &ChildControllerHandleCount
,
653 Status
= gBS
->HandleProtocol (
655 &gEfiDevicePathProtocolGuid
,
658 if (DriverBindingHandleCount
> 0
659 || ParentControllerHandleCount
> 0
660 || ChildControllerHandleCount
> 0
661 || !EFI_ERROR(Status
) ) {
662 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Handle Number");
663 ShellStatus
= SHELL_INVALID_PARAMETER
;
666 // Get the DevicePath from the loaded image information.
668 Status
= GetDevicePathForDriverHandle(CurHandle
, &FilePath
);
676 ShellOpenFileMetaArg ((CHAR16
*)File
, EFI_FILE_MODE_READ
, &FileList
);
678 if (FileList
== NULL
) {
680 // If filename matched nothing fail
682 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", File
);
683 ShellStatus
= SHELL_INVALID_PARAMETER
;
684 } else if (FileList
->Link
.ForwardLink
!= FileList
->Link
.BackLink
) {
686 // If filename expanded to multiple names, fail
688 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE
), gShellBcfgHiiHandle
, L
"bcfg", File
);
689 ShellStatus
= SHELL_INVALID_PARAMETER
;
691 Arg
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
);
692 if (EFI_ERROR(Arg
->Status
)) {
693 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_OPEN
), gShellBcfgHiiHandle
, L
"bcfg", File
);
694 ShellStatus
= SHELL_INVALID_PARAMETER
;
697 // Build FilePath to the filename
701 // get the device path
703 DevicePath
= gEfiShellProtocol
->GetDevicePathFromFilePath(Arg
->FullName
);
704 if (DevicePath
== NULL
) {
705 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_DP
), gShellBcfgHiiHandle
, L
"bcfg", Arg
->FullName
);
706 ShellStatus
= SHELL_UNSUPPORTED
;
709 DevPath
= DevicePath
;
710 ShellStatus
= SHELL_INVALID_PARAMETER
;
711 while (!IsDevicePathEnd(DevPath
)) {
712 if ((DevicePathType(DevPath
) == MEDIA_DEVICE_PATH
) &&
713 (DevicePathSubType(DevPath
) == MEDIA_HARDDRIVE_DP
)) {
716 // If we find it use it instead
718 ShellStatus
= SHELL_SUCCESS
;
719 FilePath
= DuplicateDevicePath (DevPath
);
722 DevPath
= NextDevicePathNode(DevPath
);
725 FilePath
= DuplicateDevicePath(DevicePath
);
727 FreePool(DevicePath
);
734 if (ShellStatus
== SHELL_SUCCESS
) {
736 // Find a free target ,a brute force implementation
739 for (TargetLocation
=0; TargetLocation
< 0xFFFF; TargetLocation
++) {
741 for (Index
=0; Index
< OrderCount
; Index
++) {
742 if (CurrentOrder
[Index
] == TargetLocation
) {
753 if (TargetLocation
== 0xFFFF) {
754 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET_NF
), gShellBcfgHiiHandle
, L
"bcfg");
756 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET
), gShellBcfgHiiHandle
, TargetLocation
);
760 if (ShellStatus
== SHELL_SUCCESS
) {
764 DescSize
= StrSize(Desc
);
765 FilePathSize
= GetDevicePathSize (FilePath
);
767 TempByteBuffer
= AllocateZeroPool(sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
);
768 if (TempByteBuffer
!= NULL
) {
769 TempByteStart
= TempByteBuffer
;
770 *((UINT32
*) TempByteBuffer
) = LOAD_OPTION_ACTIVE
; // Attributes
771 TempByteBuffer
+= sizeof (UINT32
);
773 *((UINT16
*) TempByteBuffer
) = (UINT16
)FilePathSize
; // FilePathListLength
774 TempByteBuffer
+= sizeof (UINT16
);
776 CopyMem (TempByteBuffer
, Desc
, DescSize
);
777 TempByteBuffer
+= DescSize
;
778 ASSERT (FilePath
!= NULL
);
779 CopyMem (TempByteBuffer
, FilePath
, FilePathSize
);
781 UnicodeSPrint (OptionStr
, sizeof(OptionStr
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", TargetLocation
);
782 Status
= gRT
->SetVariable (
784 &gEfiGlobalVariableGuid
,
785 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
786 sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
,
790 FreePool(TempByteStart
);
792 Status
= EFI_OUT_OF_RESOURCES
;
795 if (EFI_ERROR(Status
)) {
796 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", OptionStr
);
798 NewOrder
= AllocateZeroPool ((OrderCount
+ 1) * sizeof (NewOrder
[0]));
799 if (NewOrder
!= NULL
) {
800 CopyMem (NewOrder
, CurrentOrder
, (OrderCount
) * sizeof (NewOrder
[0]));
803 // Insert target into order list
805 for (Index
= OrderCount
; Index
> Position
; Index
--) {
806 NewOrder
[Index
] = NewOrder
[Index
- 1];
809 NewOrder
[Position
] = (UINT16
) TargetLocation
;
810 Status
= gRT
->SetVariable (
811 Target
== BcfgTargetBootOrder
? L
"BootOrder" : L
"DriverOrder",
812 &gEfiGlobalVariableGuid
,
813 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
814 (OrderCount
+ 1) * sizeof (UINT16
),
820 if (EFI_ERROR (Status
)) {
821 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
? L
"BootOrder" : L
"DriverOrder");
822 ShellStatus
= SHELL_INVALID_PARAMETER
;
824 Print (L
"bcfg: Add %s as %x\n", OptionStr
, Position
);
831 //If always Free FilePath, will free devicepath in system when use "addh"
833 if (FilePath
!=NULL
&& !UseHandle
) {
841 if (Handles
!= NULL
) {
845 if (FileList
!= NULL
) {
846 ShellCloseFileMetaArg (&FileList
);
849 return (ShellStatus
);
853 Funciton to remove an item.
855 @param[in] Target The target item to move.
856 @param[in] CurrentOrder The pointer to the current order of items.
857 @param[in] OrderCount The number if items in CurrentOrder.
858 @param[in] Location The current location of the Target.
860 @retval SHELL_SUCCESS The operation was successful.
861 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
865 IN CONST BCFG_OPERATION_TARGET Target
,
866 IN CONST UINT16
*CurrentOrder
,
867 IN CONST UINTN OrderCount
,
868 IN CONST UINT16 Location
871 CHAR16 VariableName
[12];
876 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", CurrentOrder
[Location
]);
877 Status
= gRT
->SetVariable(
879 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
880 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
883 if (EFI_ERROR(Status
)) {
884 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
885 return (SHELL_INVALID_PARAMETER
);
887 NewOrder
= AllocateZeroPool(OrderCount
*sizeof(CurrentOrder
[0]));
888 if (NewOrder
!= NULL
) {
889 NewCount
= OrderCount
;
890 CopyMem(NewOrder
, CurrentOrder
, OrderCount
*sizeof(CurrentOrder
[0]));
891 CopyMem(NewOrder
+Location
, NewOrder
+Location
+1, (OrderCount
- Location
- 1)*sizeof(CurrentOrder
[0]));
894 Status
= gRT
->SetVariable(
895 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
896 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
897 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
898 NewCount
*sizeof(NewOrder
[0]),
902 Status
= EFI_OUT_OF_RESOURCES
;
904 if (EFI_ERROR(Status
)) {
905 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder");
906 return (SHELL_INVALID_PARAMETER
);
908 return (SHELL_SUCCESS
);
912 Funciton to move a item to another location.
914 @param[in] Target The target item to move.
915 @param[in] CurrentOrder The pointer to the current order of items.
916 @param[in] OrderCount The number if items in CurrentOrder.
917 @param[in] OldLocation The current location of the Target.
918 @param[in] NewLocation The desired location of the Target.
920 @retval SHELL_SUCCESS The operation was successful.
921 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
925 IN CONST BCFG_OPERATION_TARGET Target
,
926 IN CONST UINT16
*CurrentOrder
,
927 IN CONST UINTN OrderCount
,
928 IN CONST UINT16 OldLocation
,
929 IN UINT16 NewLocation
936 NewOrder
= AllocateCopyPool(OrderCount
*sizeof(CurrentOrder
[0]), CurrentOrder
);
937 if (NewOrder
== NULL
) {
938 return (SHELL_OUT_OF_RESOURCES
);
942 // correct the new location
944 if (NewLocation
>= OrderCount
) {
945 if (OrderCount
> 0) {
946 NewLocation
= (UINT16
)OrderCount
- 1;
952 Temp
= CurrentOrder
[OldLocation
];
953 CopyMem(NewOrder
+OldLocation
, NewOrder
+OldLocation
+1, (OrderCount
- OldLocation
- 1)*sizeof(CurrentOrder
[0]));
954 CopyMem(NewOrder
+NewLocation
+1, NewOrder
+NewLocation
, (OrderCount
- NewLocation
- 1)*sizeof(CurrentOrder
[0]));
955 NewOrder
[NewLocation
] = Temp
;
957 Status
= gRT
->SetVariable(
958 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
959 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
960 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
961 OrderCount
*sizeof(CurrentOrder
[0]),
966 if (EFI_ERROR(Status
)) {
967 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder");
968 return (SHELL_INVALID_PARAMETER
);
970 return (SHELL_SUCCESS
);
974 Function to add optional data to an option.
976 @param[in] OptData The optional data to add.
977 @param[in] CurrentOrder The pointer to the current order of items.
978 @param[in] OrderCount The number if items in CurrentOrder.
979 @param[in] Target The target of the operation.
981 @retval SHELL_SUCCESS The operation was succesful.
985 IN CONST CHAR16
*OptData
,
986 IN CONST UINT16
*CurrentOrder
,
987 IN CONST UINTN OrderCount
,
988 IN CONST BCFG_OPERATION_TARGET Target
991 EFI_KEY_OPTION NewKeyOption
;
992 EFI_KEY_OPTION
*KeyOptionBuffer
;
993 SHELL_STATUS ShellStatus
;
999 CONST CHAR16
*Walker
;
1004 CHAR16 VariableName
[12];
1007 SHELL_FILE_HANDLE FileHandle
;
1009 Status
= EFI_SUCCESS
;
1010 ShellStatus
= SHELL_SUCCESS
;
1014 KeyOptionBuffer
= NULL
;
1015 VariableData
= NULL
;
1017 ZeroMem(&NewKeyOption
, sizeof(EFI_KEY_OPTION
));
1018 ZeroMem(VariableName
, sizeof(VariableName
));
1020 while(Walker
[0] == L
' ') {
1025 // Get the index of the variable we are changing.
1027 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
1028 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
|| ((UINT16
)Intermediate
) > ((UINT16
)OrderCount
)) {
1029 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Option Index");
1030 ShellStatus
= SHELL_INVALID_PARAMETER
;
1031 return (ShellStatus
);
1033 OptionIndex
= (UINT16
)Intermediate
;
1035 Temp
= StrStr(Walker
, L
" ");
1039 while(Walker
[0] == L
' ') {
1044 // determine whether we have file with data, quote delimited information, or a hot-key
1046 if (Walker
[0] == L
'\"') {
1048 // quoted filename or quoted information.
1050 Temp
= StrStr(Walker
+1, L
"\"");
1051 if (Temp
== NULL
|| StrLen(Temp
) != 1) {
1052 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1053 ShellStatus
= SHELL_INVALID_PARAMETER
;
1055 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
+1, 0);
1056 if (FileName
== NULL
) {
1057 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
1058 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1059 return (ShellStatus
);
1061 Temp2
= StrStr(FileName
, L
"\"");
1062 ASSERT(Temp2
!= NULL
);
1063 Temp2
[0] = CHAR_NULL
;
1065 if (StrLen(Temp2
)>0) {
1066 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1067 ShellStatus
= SHELL_INVALID_PARAMETER
;
1069 if (EFI_ERROR(ShellFileExists(Walker
))) {
1071 // Not a file. must be misc information.
1076 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
, 0);
1081 // filename or hot key information.
1083 if (StrStr(Walker
, L
" ") == NULL
) {
1087 if (EFI_ERROR(ShellFileExists(Walker
))) {
1088 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FIND_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1089 ShellStatus
= SHELL_INVALID_PARAMETER
;
1091 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
, 0);
1094 if (Target
!= BcfgTargetBootOrder
) {
1095 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_BOOT_ONLY
), gShellBcfgHiiHandle
, L
"bcfg");
1096 ShellStatus
= SHELL_INVALID_PARAMETER
;
1099 if (ShellStatus
== SHELL_SUCCESS
) {
1101 // Get hot key information
1103 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
1104 if (EFI_ERROR(Status
) || (((UINT32
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
) {
1105 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1106 ShellStatus
= SHELL_INVALID_PARAMETER
;
1108 NewKeyOption
.KeyData
.PackedValue
= (UINT32
)Intermediate
;
1109 Temp
= StrStr(Walker
, L
" ");
1113 while(Walker
[0] == L
' ') {
1118 if (ShellStatus
== SHELL_SUCCESS
) {
1120 // Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.
1121 // Re-allocate with the added information.
1123 KeyOptionBuffer
= AllocateCopyPool(sizeof(EFI_KEY_OPTION
) + (sizeof(EFI_INPUT_KEY
) * NewKeyOption
.KeyData
.Options
.InputKeyCount
), &NewKeyOption
);
1124 if (KeyOptionBuffer
== NULL
) {
1125 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
1126 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1129 for (LoopCounter
= 0 ; ShellStatus
== SHELL_SUCCESS
&& LoopCounter
< NewKeyOption
.KeyData
.Options
.InputKeyCount
; LoopCounter
++) {
1133 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
1134 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
) {
1135 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1136 ShellStatus
= SHELL_INVALID_PARAMETER
;
1138 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof(EFI_KEY_OPTION
)))[LoopCounter
].ScanCode
= (UINT16
)Intermediate
;
1139 Temp
= StrStr(Walker
, L
" ");
1143 while(Walker
[0] == L
' ') {
1150 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
1151 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
)) {
1152 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
1153 ShellStatus
= SHELL_INVALID_PARAMETER
;
1155 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof(EFI_KEY_OPTION
)))[LoopCounter
].UnicodeChar
= (UINT16
)Intermediate
;
1156 Temp
= StrStr(Walker
, L
" ");
1160 while(Walker
[0] == L
' ') {
1165 if (ShellStatus
== SHELL_SUCCESS
) {
1167 // Now do the BootOption / BootOptionCrc
1169 ASSERT (OptionIndex
<= OrderCount
);
1170 KeyOptionBuffer
->BootOption
= CurrentOrder
[OptionIndex
];
1171 Status
= GetBootOptionCrc(&(KeyOptionBuffer
->BootOptionCrc
), KeyOptionBuffer
->BootOption
);
1172 if (EFI_ERROR(Status
)) {
1173 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Option Index");
1174 ShellStatus
= SHELL_INVALID_PARAMETER
;
1178 if (ShellStatus
== SHELL_SUCCESS
) {
1179 for (Temp2
= NULL
, KeyIndex
= 0 ; KeyIndex
<= 0xFFFF ; KeyIndex
++) {
1180 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"Key%04x", KeyIndex
);
1181 Status
= GetEfiGlobalVariable2 (VariableName
, &VariableData
, NULL
);
1182 if (Status
== EFI_NOT_FOUND
) {
1185 if (!EFI_ERROR(Status
)) {
1186 SHELL_FREE_NON_NULL(VariableData
);
1189 if (KeyIndex
<= 0xFFFF) {
1190 Status
= gRT
->SetVariable(
1192 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1193 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
1194 sizeof(EFI_KEY_OPTION
) + (sizeof(EFI_INPUT_KEY
) * NewKeyOption
.KeyData
.Options
.InputKeyCount
),
1196 if (EFI_ERROR(Status
)) {
1197 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1198 ShellStatus
= SHELL_INVALID_PARAMETER
;
1201 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_VAR_NO_NUM
), gShellBcfgHiiHandle
, L
"bcfg");
1202 ShellStatus
= SHELL_INVALID_PARAMETER
;
1204 ASSERT(FileName
== NULL
&& Data
== NULL
);
1210 // Shouldn't be possible to have have both. Neither is ok though.
1212 ASSERT(FileName
== NULL
|| Data
== NULL
);
1214 if (ShellStatus
== SHELL_SUCCESS
&& (FileName
!= NULL
|| Data
!= NULL
)) {
1215 if (FileName
!= NULL
) {
1217 // Open the file and populate the data buffer.
1219 Status
= ShellOpenFileByName(
1224 if (!EFI_ERROR(Status
)) {
1225 Status
= ShellGetFileSize(FileHandle
, &Intermediate
);
1227 Data
= AllocateZeroPool((UINTN
)Intermediate
);
1229 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
1230 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1232 if (!EFI_ERROR(Status
)) {
1233 Status
= ShellReadFile(FileHandle
, (UINTN
*)&Intermediate
, Data
);
1236 Intermediate
= StrSize(Data
);
1239 if (!EFI_ERROR(Status
) && ShellStatus
== SHELL_SUCCESS
&& Data
!= NULL
) {
1240 Status
= UpdateOptionalData(CurrentOrder
[OptionIndex
], (UINTN
)Intermediate
, (UINT8
*)Data
, Target
);
1241 if (EFI_ERROR(Status
)) {
1242 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1243 ShellStatus
= SHELL_INVALID_PARAMETER
;
1246 if (EFI_ERROR(Status
) && ShellStatus
== SHELL_SUCCESS
) {
1247 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1248 ShellStatus
= SHELL_INVALID_PARAMETER
;
1252 SHELL_FREE_NON_NULL(Data
);
1253 SHELL_FREE_NON_NULL(KeyOptionBuffer
);
1254 SHELL_FREE_NON_NULL(FileName
);
1259 Function to dump the Bcfg information.
1261 @param[in] Op The operation.
1262 @param[in] OrderCount How many to dump.
1263 @param[in] CurrentOrder The pointer to the current order of items.
1264 @param[in] VerboseOutput TRUE for extra output. FALSE otherwise.
1266 @retval SHELL_SUCCESS The dump was successful.
1267 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
1271 IN CONST CHAR16
*Op
,
1272 IN CONST UINTN OrderCount
,
1273 IN CONST UINT16
*CurrentOrder
,
1274 IN CONST BOOLEAN VerboseOutput
1280 CHAR16 VariableName
[12];
1282 CHAR16
*DevPathString
;
1285 EFI_LOAD_OPTION
*LoadOption
;
1286 CHAR16
*Description
;
1287 UINTN DescriptionSize
;
1288 UINTN OptionalDataOffset
;
1290 if (OrderCount
== 0) {
1291 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_BCFG_NONE
), gShellBcfgHiiHandle
, L
"bcfg");
1292 return (SHELL_SUCCESS
);
1297 for (LoopVar
= 0 ; LoopVar
< OrderCount
; LoopVar
++) {
1300 DevPathString
= NULL
;
1302 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Op
, CurrentOrder
[LoopVar
]);
1304 Status
= gRT
->GetVariable(
1306 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1310 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1311 Buffer
= AllocateZeroPool(BufferSize
);
1312 Status
= gRT
->GetVariable(
1314 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1320 if (EFI_ERROR(Status
) || Buffer
== NULL
) {
1321 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_READ_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1327 // We expect the Attributes, FilePathListLength, and L'\0'-terminated
1328 // Description fields to be present.
1330 if (BufferSize
< sizeof *LoadOption
+ sizeof (CHAR16
)) {
1335 STRING_TOKEN (STR_BCFG_VAR_CORRUPT
),
1336 gShellBcfgHiiHandle
,
1344 LoadOption
= (EFI_LOAD_OPTION
*)Buffer
;
1345 Description
= (CHAR16
*)(Buffer
+ sizeof (EFI_LOAD_OPTION
));
1346 DescriptionSize
= StrSize (Description
);
1348 if (LoadOption
->FilePathListLength
!= 0) {
1349 FilePathList
= (UINT8
*)Description
+ DescriptionSize
;
1350 DevPathString
= ConvertDevicePathToText(FilePathList
, TRUE
, FALSE
);
1353 OptionalDataOffset
= sizeof *LoadOption
+ DescriptionSize
+
1354 LoadOption
->FilePathListLength
;
1360 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS
),
1361 gShellBcfgHiiHandle
,
1366 OptionalDataOffset
>= BufferSize
? L
'N' : L
'Y'
1368 if (VerboseOutput
&& (OptionalDataOffset
< BufferSize
)) {
1371 0, // Offset (displayed)
1372 BufferSize
- OptionalDataOffset
, // DataSize
1373 Buffer
+ OptionalDataOffset
// UserData
1378 if (Buffer
!= NULL
) {
1381 if (DevPathString
!= NULL
) {
1382 FreePool(DevPathString
);
1385 return (Errors
> 0) ? SHELL_INVALID_PARAMETER
: SHELL_SUCCESS
;
1389 Function to initialize the BCFG operation structure.
1391 @param[in] Struct The stuct to initialize.
1395 IN BGFG_OPERATION
*Struct
1398 ASSERT(Struct
!= NULL
);
1399 Struct
->Target
= BcfgTargetMax
;
1400 Struct
->Type
= BcfgTypeMax
;
1401 Struct
->Number1
= 0;
1402 Struct
->Number2
= 0;
1403 Struct
->HandleIndex
= 0;
1404 Struct
->FileName
= NULL
;
1405 Struct
->Description
= NULL
;
1406 Struct
->Order
= NULL
;
1407 Struct
->OptData
= NULL
;
1411 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
1413 {L
"-opt", TypeMaxValue
},
1418 Function for 'bcfg' command.
1420 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1421 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1425 ShellCommandRunBcfg (
1426 IN EFI_HANDLE ImageHandle
,
1427 IN EFI_SYSTEM_TABLE
*SystemTable
1431 LIST_ENTRY
*Package
;
1432 CHAR16
*ProblemParam
;
1433 SHELL_STATUS ShellStatus
;
1435 CONST CHAR16
*CurrentParam
;
1436 BGFG_OPERATION CurrentOperation
;
1438 UINT64 Intermediate
;
1442 ProblemParam
= NULL
;
1444 ShellStatus
= SHELL_SUCCESS
;
1446 InitBcfgStruct(&CurrentOperation
);
1449 // initialize the shell lib (we must be in non-auto-init...)
1451 Status
= ShellInitialize();
1452 ASSERT_EFI_ERROR(Status
);
1454 Status
= CommandInit();
1455 ASSERT_EFI_ERROR(Status
);
1458 // parse the command line
1460 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
1461 if (EFI_ERROR(Status
)) {
1462 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
1463 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, L
"bcfg", ProblemParam
);
1464 FreePool(ProblemParam
);
1465 ShellStatus
= SHELL_INVALID_PARAMETER
;
1471 // Read in if we are doing -OPT
1473 if (ShellCommandLineGetFlag(Package
, L
"-opt")) {
1474 CurrentOperation
.OptData
= ShellCommandLineGetValue(Package
, L
"-opt");
1475 if (CurrentOperation
.OptData
== NULL
) {
1476 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellBcfgHiiHandle
, L
"bcfg", L
"-opt");
1477 ShellStatus
= SHELL_INVALID_PARAMETER
;
1479 CurrentOperation
.Type
= BcfgTypeOpt
;
1483 // small block to read the target of the operation
1485 if ((ShellCommandLineGetCount(Package
) < 3 && CurrentOperation
.Type
!= BcfgTypeOpt
) ||
1486 (ShellCommandLineGetCount(Package
) < 2 && CurrentOperation
.Type
== BcfgTypeOpt
)
1488 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1489 ShellStatus
= SHELL_INVALID_PARAMETER
;
1490 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"driver") == 0) {
1491 CurrentOperation
.Target
= BcfgTargetDriverOrder
;
1492 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"boot") == 0) {
1493 CurrentOperation
.Target
= BcfgTargetBootOrder
;
1495 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT
), gShellBcfgHiiHandle
, L
"bcfg");
1496 ShellStatus
= SHELL_INVALID_PARAMETER
;
1501 // Read in the boot or driver order environment variable (not needed for opt)
1503 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
1505 Status
= gRT
->GetVariable(
1506 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
1507 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1510 CurrentOperation
.Order
);
1511 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1512 CurrentOperation
.Order
= AllocateZeroPool(Length
+(4*sizeof(CurrentOperation
.Order
[0])));
1513 if (CurrentOperation
.Order
== NULL
) {
1514 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1516 Status
= gRT
->GetVariable(
1517 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
1518 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1521 CurrentOperation
.Order
);
1526 Count
= (UINT16
) (Length
/ sizeof(CurrentOperation
.Order
[0]));
1529 // large block to read the type of operation and verify parameter types for the info.
1531 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
1532 for (ParamNumber
= 2 ; ParamNumber
< ShellCommandLineGetCount(Package
) && ShellStatus
== SHELL_SUCCESS
; ParamNumber
++) {
1533 CurrentParam
= ShellCommandLineGetRawValue(Package
, ParamNumber
);
1534 if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"dump") == 0) {
1535 CurrentOperation
.Type
= BcfgTypeDump
;
1536 if (ShellCommandLineGetCount(Package
) > 3) {
1537 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellBcfgHiiHandle
, L
"bcfg");
1538 ShellStatus
= SHELL_INVALID_PARAMETER
;
1540 } else if (ShellCommandLineGetFlag(Package
, L
"-v")) {
1541 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"-v (without dump)");
1542 ShellStatus
= SHELL_INVALID_PARAMETER
;
1543 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"add") == 0) {
1544 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1545 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1546 ShellStatus
= SHELL_INVALID_PARAMETER
;
1548 CurrentOperation
.Type
= BcfgTypeAdd
;
1549 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1550 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1551 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1552 ShellStatus
= SHELL_INVALID_PARAMETER
;
1554 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1555 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1556 ASSERT(CurrentOperation
.FileName
== NULL
);
1557 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1558 ASSERT(CurrentOperation
.Description
== NULL
);
1559 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1561 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addp") == 0) {
1562 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1563 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1564 ShellStatus
= SHELL_INVALID_PARAMETER
;
1566 CurrentOperation
.Type
= BcfgTypeAddp
;
1567 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1568 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1569 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1570 ShellStatus
= SHELL_INVALID_PARAMETER
;
1572 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1573 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1574 ASSERT(CurrentOperation
.FileName
== NULL
);
1575 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1576 ASSERT(CurrentOperation
.Description
== NULL
);
1577 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1579 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addh") == 0) {
1580 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1581 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1582 ShellStatus
= SHELL_INVALID_PARAMETER
;
1584 CurrentOperation
.Type
= BcfgTypeAddh
;
1585 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1586 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1587 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1588 ShellStatus
= SHELL_INVALID_PARAMETER
;
1590 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1591 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1592 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1593 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1594 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1595 ShellStatus
= SHELL_INVALID_PARAMETER
;
1597 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1598 CurrentOperation
.HandleIndex
= (UINT16
)Intermediate
;
1599 ASSERT(CurrentOperation
.Description
== NULL
);
1600 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1603 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"rm") == 0) {
1604 if ((ParamNumber
+ 1) >= ShellCommandLineGetCount(Package
)) {
1605 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1606 ShellStatus
= SHELL_INVALID_PARAMETER
;
1608 CurrentOperation
.Type
= BcfgTypeRm
;
1609 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1610 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1611 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1612 ShellStatus
= SHELL_INVALID_PARAMETER
;
1614 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1615 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1616 if (CurrentOperation
.Number1
>= Count
){
1617 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1618 ShellStatus
= SHELL_INVALID_PARAMETER
;
1621 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"mv") == 0) {
1622 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount(Package
)) {
1623 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1624 ShellStatus
= SHELL_INVALID_PARAMETER
;
1626 CurrentOperation
.Type
= BcfgTypeMv
;
1627 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1628 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1629 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1630 ShellStatus
= SHELL_INVALID_PARAMETER
;
1632 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1633 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1634 if (CurrentOperation
.Number1
>= Count
){
1635 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1636 ShellStatus
= SHELL_INVALID_PARAMETER
;
1638 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1639 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1640 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1641 ShellStatus
= SHELL_INVALID_PARAMETER
;
1643 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1644 CurrentOperation
.Number2
= (UINT16
)Intermediate
;
1646 if (CurrentOperation
.Number2
== CurrentOperation
.Number1
1647 ||CurrentOperation
.Number2
>= Count
1649 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1650 ShellStatus
= SHELL_INVALID_PARAMETER
;
1655 else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"mod") == 0) {
1656 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount (Package
)) {
1657 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1658 ShellStatus
= SHELL_INVALID_PARAMETER
;
1660 CurrentOperation
.Type
= BcfgTypeMod
;
1661 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1662 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1663 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1664 ShellStatus
= SHELL_INVALID_PARAMETER
;
1666 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1667 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1668 if (CurrentOperation
.Number1
>= Count
) {
1669 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1670 ShellStatus
= SHELL_INVALID_PARAMETER
;
1672 ASSERT (CurrentOperation
.Description
== NULL
);
1673 CurrentOperation
.Description
= StrnCatGrow (&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue (Package
, ++ParamNumber
), 0);
1677 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"modf") == 0) {
1678 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount (Package
)) {
1679 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1680 ShellStatus
= SHELL_INVALID_PARAMETER
;
1682 CurrentOperation
.Type
= BcfgTypeModf
;
1683 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1684 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1685 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1686 ShellStatus
= SHELL_INVALID_PARAMETER
;
1688 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1689 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1690 if (CurrentOperation
.Number1
>= Count
) {
1691 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1692 ShellStatus
= SHELL_INVALID_PARAMETER
;
1694 ASSERT (CurrentOperation
.FileName
== NULL
);
1695 CurrentOperation
.FileName
= StrnCatGrow (&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue (Package
, ++ParamNumber
), 0);
1699 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"modp") == 0) {
1700 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount (Package
)) {
1701 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1702 ShellStatus
= SHELL_INVALID_PARAMETER
;
1704 CurrentOperation
.Type
= BcfgTypeModp
;
1705 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1706 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1707 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1708 ShellStatus
= SHELL_INVALID_PARAMETER
;
1710 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1711 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1712 if (CurrentOperation
.Number1
>= Count
) {
1713 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1714 ShellStatus
= SHELL_INVALID_PARAMETER
;
1716 ASSERT (CurrentOperation
.FileName
== NULL
);
1717 CurrentOperation
.FileName
= StrnCatGrow (&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue (Package
, ++ParamNumber
), 0);
1721 } else if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"modh") == 0) {
1722 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount (Package
)) {
1723 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1724 ShellStatus
= SHELL_INVALID_PARAMETER
;
1726 CurrentOperation
.Type
= BcfgTypeModh
;
1727 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1728 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1729 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1730 ShellStatus
= SHELL_INVALID_PARAMETER
;
1733 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1734 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1735 if (CurrentOperation
.Number1
>= Count
) {
1736 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1737 ShellStatus
= SHELL_INVALID_PARAMETER
;
1739 CurrentParam
= ShellCommandLineGetRawValue (Package
, ++ParamNumber
);
1740 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber (CurrentParam
, TRUE
, FALSE
)) {
1741 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1742 ShellStatus
= SHELL_INVALID_PARAMETER
;
1744 Status
= ShellConvertStringToUint64 (CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1745 CurrentOperation
.HandleIndex
= (UINT16
)Intermediate
;
1751 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1752 ShellStatus
= SHELL_INVALID_PARAMETER
;
1756 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
&& CurrentOperation
.Type
< BcfgTypeMax
) {
1758 // we have all the info. Do the work
1760 switch (CurrentOperation
.Type
) {
1762 ShellStatus
= BcfgDisplayDump(
1763 CurrentOperation
.Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver",
1765 CurrentOperation
.Order
,
1766 ShellCommandLineGetFlag(Package
, L
"-v"));
1769 ShellStatus
= BcfgMove(
1770 CurrentOperation
.Target
,
1771 CurrentOperation
.Order
,
1773 CurrentOperation
.Number1
,
1774 CurrentOperation
.Number2
);
1777 ShellStatus
= BcfgRemove(
1778 CurrentOperation
.Target
,
1779 CurrentOperation
.Order
,
1781 CurrentOperation
.Number1
);
1786 ShellStatus
= BcfgAdd(
1787 CurrentOperation
.Number1
,
1788 CurrentOperation
.FileName
,
1789 CurrentOperation
.Description
==NULL
?L
"":CurrentOperation
.Description
,
1790 CurrentOperation
.Order
,
1792 CurrentOperation
.Target
,
1793 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddh
),
1794 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddp
),
1795 CurrentOperation
.HandleIndex
);
1801 ShellStatus
= BcfgMod (&CurrentOperation
, Count
);
1804 ShellStatus
= BcfgAddOpt(
1805 CurrentOperation
.OptData
,
1806 CurrentOperation
.Order
,
1808 CurrentOperation
.Target
);
1816 if (Package
!= NULL
) {
1817 ShellCommandLineFreeVarList (Package
);
1819 if (CurrentOperation
.FileName
!= NULL
) {
1820 FreePool(CurrentOperation
.FileName
);
1822 if (CurrentOperation
.Description
!= NULL
) {
1823 FreePool(CurrentOperation
.Description
);
1825 if (CurrentOperation
.Order
!= NULL
) {
1826 FreePool(CurrentOperation
.Order
);
1829 return (ShellStatus
);
1834 Function to get the filename with help context if HII will not be used.
1836 @return The filename with help text in it.
1840 ShellCommandGetManFileNameBcfg (
1848 "Constructor" for the library.
1850 This will register the handler for the bcfg command.
1852 @param[in] ImageHandle the image handle of the process
1853 @param[in] SystemTable the EFI System Table pointer
1854 @param[in] Name the profile name to use
1856 @retval EFI_SUCCESS the shell command handlers were installed sucessfully
1857 @retval EFI_UNSUPPORTED the shell level required was not found.
1861 BcfgLibraryRegisterBcfgCommand (
1862 IN EFI_HANDLE ImageHandle
,
1863 IN EFI_SYSTEM_TABLE
*SystemTable
,
1864 IN CONST CHAR16
*Name
1867 if (gShellBcfgHiiHandle
!= NULL
) {
1868 return (EFI_SUCCESS
);
1871 gShellBcfgHiiHandle
= HiiAddPackages (&gShellBcfgHiiGuid
, gImageHandle
, UefiShellBcfgCommandLibStrings
, NULL
);
1872 if (gShellBcfgHiiHandle
== NULL
) {
1873 return (EFI_DEVICE_ERROR
);
1877 // install our shell command handler
1879 ShellCommandRegisterCommandName(L
"bcfg", ShellCommandRunBcfg
, ShellCommandGetManFileNameBcfg
, 0, Name
, FALSE
, gShellBcfgHiiHandle
, STRING_TOKEN(STR_GET_HELP_BCFG
));
1881 return (EFI_SUCCESS
);
1885 Destructor for the library. free any resources.
1887 @param ImageHandle The image handle of the process.
1888 @param SystemTable The EFI System Table pointer.
1892 BcfgLibraryUnregisterBcfgCommand (
1893 IN EFI_HANDLE ImageHandle
,
1894 IN EFI_SYSTEM_TABLE
*SystemTable
1897 if (gShellBcfgHiiHandle
!= NULL
) {
1898 HiiRemovePackages(gShellBcfgHiiHandle
);
1900 gShellBcfgHiiHandle
= NULL
;
1901 return (EFI_SUCCESS
);