2 Main file for BCFG command.
4 (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010 - 2016, 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>
45 STATIC CONST CHAR16 mFileName
[] = L
"ShellCommands";
46 STATIC EFI_HANDLE gShellBcfgHiiHandle
= NULL
;
49 BcfgTargetBootOrder
= 0,
50 BcfgTargetDriverOrder
= 1,
52 } BCFG_OPERATION_TARGET
;
63 } BCFG_OPERATION_TYPE
;
66 BCFG_OPERATION_TARGET Target
;
67 BCFG_OPERATION_TYPE Type
;
74 CONST CHAR16
*OptData
;
78 Update the optional data for a boot or driver option.
80 If optional data exists it will be changed.
82 @param[in] Index The boot or driver option index update.
83 @param[in] DataSize The size in bytes of Data.
84 @param[in] Data The buffer for the optioanl data.
85 @param[in] Target The target of the operation.
87 @retval EFI_SUCCESS The data was sucessfully updated.
88 @retval other A error occured.
95 IN CONST BCFG_OPERATION_TARGET Target
99 CHAR16 VariableName
[12];
104 UINTN OriginalOptionDataSize
;
106 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", Index
);
113 Status
= gRT
->GetVariable(
115 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
119 if (Status
== EFI_BUFFER_TOO_SMALL
) {
120 OriginalData
= AllocateZeroPool(OriginalSize
);
121 if (OriginalData
== NULL
) {
122 return (EFI_OUT_OF_RESOURCES
);
124 Status
= gRT
->GetVariable(
126 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
132 if (!EFI_ERROR(Status
)) {
134 // Allocate new struct and discard old optional data.
136 ASSERT (OriginalData
!= NULL
);
137 OriginalOptionDataSize
= sizeof(UINT32
) + sizeof(UINT16
) + StrSize(((CHAR16
*)(OriginalData
+ sizeof(UINT32
) + sizeof(UINT16
))));
138 OriginalOptionDataSize
+= (*(UINT16
*)(OriginalData
+ sizeof(UINT32
)));
139 OriginalOptionDataSize
-= OriginalSize
;
140 NewSize
= OriginalSize
- OriginalOptionDataSize
+ DataSize
;
141 NewData
= AllocateCopyPool(NewSize
, OriginalData
);
142 if (NewData
== NULL
) {
143 Status
= EFI_OUT_OF_RESOURCES
;
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 Function to add a option.
280 @param[in] Position The position to add Target at.
281 @param[in] File The file to make the target.
282 @param[in] Desc The description text.
283 @param[in] CurrentOrder The pointer to the current order of items.
284 @param[in] OrderCount The number if items in CurrentOrder.
285 @param[in] Target The info on the option to add.
286 @param[in] UseHandle TRUE to use HandleNumber, FALSE to use File and Desc.
287 @param[in] UsePath TRUE to convert to devicepath.
288 @param[in] HandleNumber The handle number to add.
290 @retval SHELL_SUCCESS The operation was successful.
291 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
296 IN CONST CHAR16
*File
,
297 IN CONST CHAR16
*Desc
,
298 IN CONST UINT16
*CurrentOrder
,
299 IN CONST UINTN OrderCount
,
300 IN CONST BCFG_OPERATION_TARGET Target
,
301 IN CONST BOOLEAN UseHandle
,
302 IN CONST BOOLEAN UsePath
,
303 IN CONST UINTN HandleNumber
307 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
308 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
309 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
311 UINT8
*TempByteBuffer
;
312 UINT8
*TempByteStart
;
313 EFI_SHELL_FILE_INFO
*Arg
;
314 EFI_SHELL_FILE_INFO
*FileList
;
315 CHAR16 OptionStr
[40];
316 UINTN DescSize
, FilePathSize
;
318 UINTN TargetLocation
;
321 EFI_HANDLE CurHandle
;
322 UINTN DriverBindingHandleCount
;
323 UINTN ParentControllerHandleCount
;
324 UINTN ChildControllerHandleCount
;
325 SHELL_STATUS ShellStatus
;
329 if (File
== NULL
|| Desc
== NULL
) {
330 return (SHELL_INVALID_PARAMETER
);
333 if (HandleNumber
== 0) {
334 return (SHELL_INVALID_PARAMETER
);
338 if (Position
> OrderCount
) {
339 Position
= OrderCount
;
346 ShellStatus
= SHELL_SUCCESS
;
347 TargetLocation
= 0xFFFF;
350 CurHandle
= ConvertHandleIndexToHandle(HandleNumber
);
351 if (CurHandle
== NULL
) {
352 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Handle Number");
353 ShellStatus
= SHELL_INVALID_PARAMETER
;
355 if (Target
== BcfgTargetBootOrder
) {
357 //Make sure that the handle should point to a real controller
359 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
361 &DriverBindingHandleCount
,
364 Status
= PARSE_HANDLE_DATABASE_PARENTS (
366 &ParentControllerHandleCount
,
369 Status
= ParseHandleDatabaseForChildControllers (
371 &ChildControllerHandleCount
,
374 if (DriverBindingHandleCount
> 0
375 || ParentControllerHandleCount
> 0
376 || ChildControllerHandleCount
> 0) {
378 Status
= gBS
->HandleProtocol (
380 &gEfiDevicePathProtocolGuid
,
383 if (EFI_ERROR (Status
)) {
384 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_HANDLE
), gShellBcfgHiiHandle
, L
"bcfg", HandleNumber
);
385 ShellStatus
= SHELL_INVALID_PARAMETER
;
389 //Make sure that the handle should point to driver, not a controller.
391 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
393 &DriverBindingHandleCount
,
396 Status
= PARSE_HANDLE_DATABASE_PARENTS (
398 &ParentControllerHandleCount
,
401 Status
= ParseHandleDatabaseForChildControllers (
403 &ChildControllerHandleCount
,
406 Status
= gBS
->HandleProtocol (
408 &gEfiDevicePathProtocolGuid
,
411 if (DriverBindingHandleCount
> 0
412 || ParentControllerHandleCount
> 0
413 || ChildControllerHandleCount
> 0
414 || !EFI_ERROR(Status
) ) {
415 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Handle Number");
416 ShellStatus
= SHELL_INVALID_PARAMETER
;
419 // Get the DevicePath from the loaded image information.
421 Status
= GetDevicePathForDriverHandle(CurHandle
, &FilePath
);
429 ShellOpenFileMetaArg ((CHAR16
*)File
, EFI_FILE_MODE_READ
, &FileList
);
431 if (FileList
== NULL
) {
433 // If filename matched nothing fail
435 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", File
);
436 ShellStatus
= SHELL_INVALID_PARAMETER
;
437 } else if (FileList
->Link
.ForwardLink
!= FileList
->Link
.BackLink
) {
439 // If filename expanded to multiple names, fail
441 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE
), gShellBcfgHiiHandle
, L
"bcfg", File
);
442 ShellStatus
= SHELL_INVALID_PARAMETER
;
444 Arg
= (EFI_SHELL_FILE_INFO
*)GetFirstNode(&FileList
->Link
);
445 if (EFI_ERROR(Arg
->Status
)) {
446 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_OPEN
), gShellBcfgHiiHandle
, L
"bcfg", File
);
447 ShellStatus
= SHELL_INVALID_PARAMETER
;
450 // Build FilePath to the filename
454 // get the device path
456 DevicePath
= gEfiShellProtocol
->GetDevicePathFromFilePath(Arg
->FullName
);
457 if (DevicePath
== NULL
) {
458 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_FILE_DP
), gShellBcfgHiiHandle
, L
"bcfg", Arg
->FullName
);
459 ShellStatus
= SHELL_UNSUPPORTED
;
462 DevPath
= DevicePath
;
463 ShellStatus
= SHELL_INVALID_PARAMETER
;
464 while (!IsDevicePathEnd(DevPath
)) {
465 if ((DevicePathType(DevPath
) == MEDIA_DEVICE_PATH
) &&
466 (DevicePathSubType(DevPath
) == MEDIA_HARDDRIVE_DP
)) {
469 // If we find it use it instead
471 ShellStatus
= SHELL_SUCCESS
;
472 FilePath
= DuplicateDevicePath (DevPath
);
475 DevPath
= NextDevicePathNode(DevPath
);
478 FilePath
= DuplicateDevicePath(DevicePath
);
480 FreePool(DevicePath
);
487 if (ShellStatus
== SHELL_SUCCESS
) {
489 // Find a free target ,a brute force implementation
492 for (TargetLocation
=0; TargetLocation
< 0xFFFF; TargetLocation
++) {
494 for (Index
=0; Index
< OrderCount
; Index
++) {
495 if (CurrentOrder
[Index
] == TargetLocation
) {
506 if (TargetLocation
== 0xFFFF) {
507 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET_NF
), gShellBcfgHiiHandle
, L
"bcfg");
509 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_TARGET
), gShellBcfgHiiHandle
, TargetLocation
);
513 if (ShellStatus
== SHELL_SUCCESS
) {
517 DescSize
= StrSize(Desc
);
518 FilePathSize
= GetDevicePathSize (FilePath
);
520 TempByteBuffer
= AllocateZeroPool(sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
);
521 if (TempByteBuffer
!= NULL
) {
522 TempByteStart
= TempByteBuffer
;
523 *((UINT32
*) TempByteBuffer
) = LOAD_OPTION_ACTIVE
; // Attributes
524 TempByteBuffer
+= sizeof (UINT32
);
526 *((UINT16
*) TempByteBuffer
) = (UINT16
)FilePathSize
; // FilePathListLength
527 TempByteBuffer
+= sizeof (UINT16
);
529 CopyMem (TempByteBuffer
, Desc
, DescSize
);
530 TempByteBuffer
+= DescSize
;
531 ASSERT (FilePath
!= NULL
);
532 CopyMem (TempByteBuffer
, FilePath
, FilePathSize
);
534 UnicodeSPrint (OptionStr
, sizeof(OptionStr
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", TargetLocation
);
535 Status
= gRT
->SetVariable (
537 &gEfiGlobalVariableGuid
,
538 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
539 sizeof(UINT32
) + sizeof(UINT16
) + DescSize
+ FilePathSize
,
543 FreePool(TempByteStart
);
545 Status
= EFI_OUT_OF_RESOURCES
;
548 if (EFI_ERROR(Status
)) {
549 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", OptionStr
);
551 NewOrder
= AllocateZeroPool ((OrderCount
+ 1) * sizeof (NewOrder
[0]));
552 if (NewOrder
!= NULL
) {
553 CopyMem (NewOrder
, CurrentOrder
, (OrderCount
) * sizeof (NewOrder
[0]));
556 // Insert target into order list
558 for (Index
= OrderCount
; Index
> Position
; Index
--) {
559 NewOrder
[Index
] = NewOrder
[Index
- 1];
562 NewOrder
[Position
] = (UINT16
) TargetLocation
;
563 Status
= gRT
->SetVariable (
564 Target
== BcfgTargetBootOrder
? L
"BootOrder" : L
"DriverOrder",
565 &gEfiGlobalVariableGuid
,
566 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
567 (OrderCount
+ 1) * sizeof (UINT16
),
573 if (EFI_ERROR (Status
)) {
574 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
? L
"BootOrder" : L
"DriverOrder");
575 ShellStatus
= SHELL_INVALID_PARAMETER
;
577 Print (L
"bcfg: Add %s as %x\n", OptionStr
, Position
);
584 //If always Free FilePath, will free devicepath in system when use "addh"
586 if (FilePath
!=NULL
&& !UseHandle
) {
594 if (Handles
!= NULL
) {
598 if (FileList
!= NULL
) {
599 ShellCloseFileMetaArg (&FileList
);
602 return (ShellStatus
);
606 Funciton to remove an item.
608 @param[in] Target The target item to move.
609 @param[in] CurrentOrder The pointer to the current order of items.
610 @param[in] OrderCount The number if items in CurrentOrder.
611 @param[in] Location The current location of the Target.
613 @retval SHELL_SUCCESS The operation was successful.
614 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
618 IN CONST BCFG_OPERATION_TARGET Target
,
619 IN CONST UINT16
*CurrentOrder
,
620 IN CONST UINTN OrderCount
,
621 IN CONST UINT16 Location
624 CHAR16 VariableName
[12];
629 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver", CurrentOrder
[Location
]);
630 Status
= gRT
->SetVariable(
632 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
633 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
636 if (EFI_ERROR(Status
)) {
637 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
638 return (SHELL_INVALID_PARAMETER
);
640 NewOrder
= AllocateZeroPool(OrderCount
*sizeof(CurrentOrder
[0]));
641 if (NewOrder
!= NULL
) {
642 NewCount
= OrderCount
;
643 CopyMem(NewOrder
, CurrentOrder
, OrderCount
*sizeof(CurrentOrder
[0]));
644 CopyMem(NewOrder
+Location
, NewOrder
+Location
+1, (OrderCount
- Location
- 1)*sizeof(CurrentOrder
[0]));
647 Status
= gRT
->SetVariable(
648 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
649 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
650 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
651 NewCount
*sizeof(NewOrder
[0]),
655 Status
= EFI_OUT_OF_RESOURCES
;
657 if (EFI_ERROR(Status
)) {
658 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder");
659 return (SHELL_INVALID_PARAMETER
);
661 return (SHELL_SUCCESS
);
665 Funciton to move a item to another location.
667 @param[in] Target The target item to move.
668 @param[in] CurrentOrder The pointer to the current order of items.
669 @param[in] OrderCount The number if items in CurrentOrder.
670 @param[in] OldLocation The current location of the Target.
671 @param[in] NewLocation The desired location of the Target.
673 @retval SHELL_SUCCESS The operation was successful.
674 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
678 IN CONST BCFG_OPERATION_TARGET Target
,
679 IN CONST UINT16
*CurrentOrder
,
680 IN CONST UINTN OrderCount
,
681 IN CONST UINT16 OldLocation
,
682 IN UINT16 NewLocation
689 NewOrder
= AllocateCopyPool(OrderCount
*sizeof(CurrentOrder
[0]), CurrentOrder
);
690 if (NewOrder
== NULL
) {
691 return (SHELL_OUT_OF_RESOURCES
);
695 // correct the new location
697 if (NewLocation
>= OrderCount
) {
698 if (OrderCount
> 0) {
699 NewLocation
= (UINT16
)OrderCount
- 1;
705 Temp
= CurrentOrder
[OldLocation
];
706 CopyMem(NewOrder
+OldLocation
, NewOrder
+OldLocation
+1, (OrderCount
- OldLocation
- 1)*sizeof(CurrentOrder
[0]));
707 CopyMem(NewOrder
+NewLocation
+1, NewOrder
+NewLocation
, (OrderCount
- NewLocation
- 1)*sizeof(CurrentOrder
[0]));
708 NewOrder
[NewLocation
] = Temp
;
710 Status
= gRT
->SetVariable(
711 Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
712 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
713 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
714 OrderCount
*sizeof(CurrentOrder
[0]),
719 if (EFI_ERROR(Status
)) {
720 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_WRITE_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder");
721 return (SHELL_INVALID_PARAMETER
);
723 return (SHELL_SUCCESS
);
727 Function to add optional data to an option.
729 @param[in] OptData The optional data to add.
730 @param[in] CurrentOrder The pointer to the current order of items.
731 @param[in] OrderCount The number if items in CurrentOrder.
732 @param[in] Target The target of the operation.
734 @retval SHELL_SUCCESS The operation was succesful.
738 IN CONST CHAR16
*OptData
,
739 IN CONST UINT16
*CurrentOrder
,
740 IN CONST UINTN OrderCount
,
741 IN CONST BCFG_OPERATION_TARGET Target
744 EFI_KEY_OPTION NewKeyOption
;
745 EFI_KEY_OPTION
*KeyOptionBuffer
;
746 SHELL_STATUS ShellStatus
;
752 CONST CHAR16
*Walker
;
757 CHAR16 VariableName
[12];
760 SHELL_FILE_HANDLE FileHandle
;
762 Status
= EFI_SUCCESS
;
763 ShellStatus
= SHELL_SUCCESS
;
767 KeyOptionBuffer
= NULL
;
770 ZeroMem(&NewKeyOption
, sizeof(EFI_KEY_OPTION
));
771 ZeroMem(VariableName
, sizeof(VariableName
));
773 while(Walker
[0] == L
' ') {
778 // Get the index of the variable we are changing.
780 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
781 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
|| ((UINT16
)Intermediate
) > ((UINT16
)OrderCount
)) {
782 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Option Index");
783 ShellStatus
= SHELL_INVALID_PARAMETER
;
784 return (ShellStatus
);
786 OptionIndex
= (UINT16
)Intermediate
;
788 Temp
= StrStr(Walker
, L
" ");
792 while(Walker
[0] == L
' ') {
797 // determine whether we have file with data, quote delimited information, or a hot-key
799 if (Walker
[0] == L
'\"') {
801 // quoted filename or quoted information.
803 Temp
= StrStr(Walker
+1, L
"\"");
804 if (Temp
== NULL
|| StrLen(Temp
) != 1) {
805 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
806 ShellStatus
= SHELL_INVALID_PARAMETER
;
808 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
+1, 0);
809 if (FileName
== NULL
) {
810 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_OUT_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
811 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
812 return (ShellStatus
);
814 Temp2
= StrStr(FileName
, L
"\"");
815 ASSERT(Temp2
!= NULL
);
816 Temp2
[0] = CHAR_NULL
;
818 if (StrLen(Temp2
)>0) {
819 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
820 ShellStatus
= SHELL_INVALID_PARAMETER
;
822 if (EFI_ERROR(ShellFileExists(Walker
))) {
824 // Not a file. must be misc information.
829 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
, 0);
834 // filename or hot key information.
836 if (StrStr(Walker
, L
" ") == NULL
) {
840 if (EFI_ERROR(ShellFileExists(Walker
))) {
841 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FIND_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
842 ShellStatus
= SHELL_INVALID_PARAMETER
;
844 FileName
= StrnCatGrow(&FileName
, NULL
, Walker
, 0);
847 if (Target
!= BcfgTargetBootOrder
) {
848 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_BOOT_ONLY
), gShellBcfgHiiHandle
, L
"bcfg");
849 ShellStatus
= SHELL_INVALID_PARAMETER
;
852 if (ShellStatus
== SHELL_SUCCESS
) {
854 // Get hot key information
856 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
857 if (EFI_ERROR(Status
) || (((UINT32
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
) {
858 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
859 ShellStatus
= SHELL_INVALID_PARAMETER
;
861 NewKeyOption
.KeyData
.PackedValue
= (UINT32
)Intermediate
;
862 Temp
= StrStr(Walker
, L
" ");
866 while(Walker
[0] == L
' ') {
871 if (ShellStatus
== SHELL_SUCCESS
) {
873 // Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.
874 // Re-allocate with the added information.
876 KeyOptionBuffer
= AllocateCopyPool(sizeof(EFI_KEY_OPTION
) + (sizeof(EFI_INPUT_KEY
) * NewKeyOption
.KeyData
.Options
.InputKeyCount
), &NewKeyOption
);
877 if (KeyOptionBuffer
== NULL
) {
878 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
879 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
882 for (LoopCounter
= 0 ; ShellStatus
== SHELL_SUCCESS
&& LoopCounter
< NewKeyOption
.KeyData
.Options
.InputKeyCount
; LoopCounter
++) {
886 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
887 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
) || StrStr(Walker
, L
" ") == NULL
) {
888 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
889 ShellStatus
= SHELL_INVALID_PARAMETER
;
891 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof(EFI_KEY_OPTION
)))[LoopCounter
].ScanCode
= (UINT16
)Intermediate
;
892 Temp
= StrStr(Walker
, L
" ");
896 while(Walker
[0] == L
' ') {
903 Status
= ShellConvertStringToUint64(Walker
, &Intermediate
, FALSE
, TRUE
);
904 if (EFI_ERROR(Status
) || (((UINT16
)Intermediate
) != Intermediate
)) {
905 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", Walker
);
906 ShellStatus
= SHELL_INVALID_PARAMETER
;
908 ((EFI_INPUT_KEY
*)(((UINT8
*)KeyOptionBuffer
) + sizeof(EFI_KEY_OPTION
)))[LoopCounter
].UnicodeChar
= (UINT16
)Intermediate
;
909 Temp
= StrStr(Walker
, L
" ");
913 while(Walker
[0] == L
' ') {
918 if (ShellStatus
== SHELL_SUCCESS
) {
920 // Now do the BootOption / BootOptionCrc
922 ASSERT (OptionIndex
<= OrderCount
);
923 KeyOptionBuffer
->BootOption
= CurrentOrder
[OptionIndex
];
924 Status
= GetBootOptionCrc(&(KeyOptionBuffer
->BootOptionCrc
), KeyOptionBuffer
->BootOption
);
925 if (EFI_ERROR(Status
)) {
926 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"Option Index");
927 ShellStatus
= SHELL_INVALID_PARAMETER
;
931 if (ShellStatus
== SHELL_SUCCESS
) {
932 for (Temp2
= NULL
, KeyIndex
= 0 ; KeyIndex
<= 0xFFFF ; KeyIndex
++) {
933 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"Key%04x", KeyIndex
);
934 Status
= GetEfiGlobalVariable2 (VariableName
, &VariableData
, NULL
);
935 if (Status
== EFI_NOT_FOUND
) {
938 if (!EFI_ERROR(Status
)) {
939 SHELL_FREE_NON_NULL(VariableData
);
942 if (KeyIndex
<= 0xFFFF) {
943 Status
= gRT
->SetVariable(
945 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
946 EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
,
947 sizeof(EFI_KEY_OPTION
) + (sizeof(EFI_INPUT_KEY
) * NewKeyOption
.KeyData
.Options
.InputKeyCount
),
949 if (EFI_ERROR(Status
)) {
950 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
951 ShellStatus
= SHELL_INVALID_PARAMETER
;
954 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_VAR_NO_NUM
), gShellBcfgHiiHandle
, L
"bcfg");
955 ShellStatus
= SHELL_INVALID_PARAMETER
;
957 ASSERT(FileName
== NULL
&& Data
== NULL
);
963 // Shouldn't be possible to have have both. Neither is ok though.
965 ASSERT(FileName
== NULL
|| Data
== NULL
);
967 if (ShellStatus
== SHELL_SUCCESS
&& (FileName
!= NULL
|| Data
!= NULL
)) {
968 if (FileName
!= NULL
) {
970 // Open the file and populate the data buffer.
972 Status
= ShellOpenFileByName(
977 if (!EFI_ERROR(Status
)) {
978 Status
= ShellGetFileSize(FileHandle
, &Intermediate
);
980 Data
= AllocateZeroPool((UINTN
)Intermediate
);
982 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_MEM
), gShellBcfgHiiHandle
, L
"bcfg");
983 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
985 if (!EFI_ERROR(Status
)) {
986 Status
= ShellReadFile(FileHandle
, (UINTN
*)&Intermediate
, Data
);
989 Intermediate
= StrSize(Data
);
992 if (!EFI_ERROR(Status
) && ShellStatus
== SHELL_SUCCESS
&& Data
!= NULL
) {
993 Status
= UpdateOptionalData(CurrentOrder
[OptionIndex
], (UINTN
)Intermediate
, (UINT8
*)Data
, Target
);
994 if (EFI_ERROR(Status
)) {
995 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
996 ShellStatus
= SHELL_INVALID_PARAMETER
;
999 if (EFI_ERROR(Status
) && ShellStatus
== SHELL_SUCCESS
) {
1000 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1001 ShellStatus
= SHELL_INVALID_PARAMETER
;
1005 SHELL_FREE_NON_NULL(Data
);
1006 SHELL_FREE_NON_NULL(KeyOptionBuffer
);
1007 SHELL_FREE_NON_NULL(FileName
);
1012 Function to dump the Bcfg information.
1014 @param[in] Op The operation.
1015 @param[in] OrderCount How many to dump.
1016 @param[in] CurrentOrder The pointer to the current order of items.
1017 @param[in] VerboseOutput TRUE for extra output. FALSE otherwise.
1019 @retval SHELL_SUCCESS The dump was successful.
1020 @retval SHELL_INVALID_PARAMETER A parameter was invalid.
1024 IN CONST CHAR16
*Op
,
1025 IN CONST UINTN OrderCount
,
1026 IN CONST UINT16
*CurrentOrder
,
1027 IN CONST BOOLEAN VerboseOutput
1033 CHAR16 VariableName
[12];
1035 CHAR16
*DevPathString
;
1038 EFI_LOAD_OPTION
*LoadOption
;
1039 CHAR16
*Description
;
1040 UINTN DescriptionSize
;
1041 UINTN OptionalDataOffset
;
1043 if (OrderCount
== 0) {
1044 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_BCFG_NONE
), gShellBcfgHiiHandle
, L
"bcfg");
1045 return (SHELL_SUCCESS
);
1050 for (LoopVar
= 0 ; LoopVar
< OrderCount
; LoopVar
++) {
1053 DevPathString
= NULL
;
1055 UnicodeSPrint(VariableName
, sizeof(VariableName
), L
"%s%04x", Op
, CurrentOrder
[LoopVar
]);
1057 Status
= gRT
->GetVariable(
1059 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1063 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1064 Buffer
= AllocateZeroPool(BufferSize
);
1065 Status
= gRT
->GetVariable(
1067 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1073 if (EFI_ERROR(Status
) || Buffer
== NULL
) {
1074 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_READ_FAIL
), gShellBcfgHiiHandle
, L
"bcfg", VariableName
);
1080 // We expect the Attributes, FilePathListLength, and L'\0'-terminated
1081 // Description fields to be present.
1083 if (BufferSize
< sizeof *LoadOption
+ sizeof (CHAR16
)) {
1088 STRING_TOKEN (STR_BCFG_VAR_CORRUPT
),
1089 gShellBcfgHiiHandle
,
1097 LoadOption
= (EFI_LOAD_OPTION
*)Buffer
;
1098 Description
= (CHAR16
*)(Buffer
+ sizeof (EFI_LOAD_OPTION
));
1099 DescriptionSize
= StrSize (Description
);
1101 if (LoadOption
->FilePathListLength
!= 0) {
1102 FilePathList
= (UINT8
*)Description
+ DescriptionSize
;
1103 DevPathString
= ConvertDevicePathToText(FilePathList
, TRUE
, FALSE
);
1106 OptionalDataOffset
= sizeof *LoadOption
+ DescriptionSize
+
1107 LoadOption
->FilePathListLength
;
1113 STRING_TOKEN(STR_BCFG_LOAD_OPTIONS
),
1114 gShellBcfgHiiHandle
,
1119 OptionalDataOffset
>= BufferSize
? L
'N' : L
'Y'
1121 if (VerboseOutput
&& (OptionalDataOffset
< BufferSize
)) {
1124 0, // Offset (displayed)
1125 BufferSize
- OptionalDataOffset
, // DataSize
1126 Buffer
+ OptionalDataOffset
// UserData
1131 if (Buffer
!= NULL
) {
1134 if (DevPathString
!= NULL
) {
1135 FreePool(DevPathString
);
1138 return (Errors
> 0) ? SHELL_INVALID_PARAMETER
: SHELL_SUCCESS
;
1142 Function to initialize the BCFG operation structure.
1144 @param[in] Struct The stuct to initialize.
1148 IN BGFG_OPERATION
*Struct
1151 ASSERT(Struct
!= NULL
);
1152 Struct
->Target
= BcfgTargetMax
;
1153 Struct
->Type
= BcfgTypeMax
;
1154 Struct
->Number1
= 0;
1155 Struct
->Number2
= 0;
1156 Struct
->HandleIndex
= 0;
1157 Struct
->FileName
= NULL
;
1158 Struct
->Description
= NULL
;
1159 Struct
->Order
= NULL
;
1160 Struct
->OptData
= NULL
;
1164 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
1166 {L
"-opt", TypeMaxValue
},
1171 Function for 'bcfg' command.
1173 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1174 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1178 ShellCommandRunBcfg (
1179 IN EFI_HANDLE ImageHandle
,
1180 IN EFI_SYSTEM_TABLE
*SystemTable
1184 LIST_ENTRY
*Package
;
1185 CHAR16
*ProblemParam
;
1186 SHELL_STATUS ShellStatus
;
1188 CONST CHAR16
*CurrentParam
;
1189 BGFG_OPERATION CurrentOperation
;
1191 UINT64 Intermediate
;
1195 ProblemParam
= NULL
;
1197 ShellStatus
= SHELL_SUCCESS
;
1199 InitBcfgStruct(&CurrentOperation
);
1202 // initialize the shell lib (we must be in non-auto-init...)
1204 Status
= ShellInitialize();
1205 ASSERT_EFI_ERROR(Status
);
1207 Status
= CommandInit();
1208 ASSERT_EFI_ERROR(Status
);
1211 // parse the command line
1213 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
1214 if (EFI_ERROR(Status
)) {
1215 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
1216 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellBcfgHiiHandle
, L
"bcfg", ProblemParam
);
1217 FreePool(ProblemParam
);
1218 ShellStatus
= SHELL_INVALID_PARAMETER
;
1224 // Read in if we are doing -OPT
1226 if (ShellCommandLineGetFlag(Package
, L
"-opt")) {
1227 CurrentOperation
.OptData
= ShellCommandLineGetValue(Package
, L
"-opt");
1228 if (CurrentOperation
.OptData
== NULL
) {
1229 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellBcfgHiiHandle
, L
"bcfg", L
"-opt");
1230 ShellStatus
= SHELL_INVALID_PARAMETER
;
1232 CurrentOperation
.Type
= BcfgTypeOpt
;
1236 // small block to read the target of the operation
1238 if ((ShellCommandLineGetCount(Package
) < 3 && CurrentOperation
.Type
!= BcfgTypeOpt
) ||
1239 (ShellCommandLineGetCount(Package
) < 2 && CurrentOperation
.Type
== BcfgTypeOpt
)
1241 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1242 ShellStatus
= SHELL_INVALID_PARAMETER
;
1243 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"driver") == 0) {
1244 CurrentOperation
.Target
= BcfgTargetDriverOrder
;
1245 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)ShellCommandLineGetRawValue(Package
, 1), L
"boot") == 0) {
1246 CurrentOperation
.Target
= BcfgTargetBootOrder
;
1248 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT
), gShellBcfgHiiHandle
, L
"bcfg");
1249 ShellStatus
= SHELL_INVALID_PARAMETER
;
1254 // Read in the boot or driver order environment variable (not needed for opt)
1256 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
1258 Status
= gRT
->GetVariable(
1259 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
1260 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1263 CurrentOperation
.Order
);
1264 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1265 CurrentOperation
.Order
= AllocateZeroPool(Length
+(4*sizeof(CurrentOperation
.Order
[0])));
1266 if (CurrentOperation
.Order
== NULL
) {
1267 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
1269 Status
= gRT
->GetVariable(
1270 CurrentOperation
.Target
== BcfgTargetBootOrder
?(CHAR16
*)L
"BootOrder":(CHAR16
*)L
"DriverOrder",
1271 (EFI_GUID
*)&gEfiGlobalVariableGuid
,
1274 CurrentOperation
.Order
);
1279 Count
= (UINT16
) (Length
/ sizeof(CurrentOperation
.Order
[0]));
1282 // large block to read the type of operation and verify parameter types for the info.
1284 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
) {
1285 for (ParamNumber
= 2 ; ParamNumber
< ShellCommandLineGetCount(Package
) && ShellStatus
== SHELL_SUCCESS
; ParamNumber
++) {
1286 CurrentParam
= ShellCommandLineGetRawValue(Package
, ParamNumber
);
1287 if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"dump") == 0) {
1288 CurrentOperation
.Type
= BcfgTypeDump
;
1289 if (ShellCommandLineGetCount(Package
) > 3) {
1290 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellBcfgHiiHandle
, L
"bcfg");
1291 ShellStatus
= SHELL_INVALID_PARAMETER
;
1293 } else if (ShellCommandLineGetFlag(Package
, L
"-v")) {
1294 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", L
"-v (without dump)");
1295 ShellStatus
= SHELL_INVALID_PARAMETER
;
1296 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"add") == 0) {
1297 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1298 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1299 ShellStatus
= SHELL_INVALID_PARAMETER
;
1301 CurrentOperation
.Type
= BcfgTypeAdd
;
1302 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1303 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1304 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1305 ShellStatus
= SHELL_INVALID_PARAMETER
;
1307 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1308 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1309 ASSERT(CurrentOperation
.FileName
== NULL
);
1310 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1311 ASSERT(CurrentOperation
.Description
== NULL
);
1312 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1314 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addp") == 0) {
1315 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1316 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1317 ShellStatus
= SHELL_INVALID_PARAMETER
;
1319 CurrentOperation
.Type
= BcfgTypeAddp
;
1320 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1321 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1322 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1323 ShellStatus
= SHELL_INVALID_PARAMETER
;
1325 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1326 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1327 ASSERT(CurrentOperation
.FileName
== NULL
);
1328 CurrentOperation
.FileName
= StrnCatGrow(&CurrentOperation
.FileName
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1329 ASSERT(CurrentOperation
.Description
== NULL
);
1330 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1332 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"addh") == 0) {
1333 if ((ParamNumber
+ 3) >= ShellCommandLineGetCount(Package
)) {
1334 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1335 ShellStatus
= SHELL_INVALID_PARAMETER
;
1337 CurrentOperation
.Type
= BcfgTypeAddh
;
1338 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1339 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1340 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1341 ShellStatus
= SHELL_INVALID_PARAMETER
;
1343 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1344 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1345 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1346 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1347 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1348 ShellStatus
= SHELL_INVALID_PARAMETER
;
1350 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1351 CurrentOperation
.HandleIndex
= (UINT16
)Intermediate
;
1352 ASSERT(CurrentOperation
.Description
== NULL
);
1353 CurrentOperation
.Description
= StrnCatGrow(&CurrentOperation
.Description
, NULL
, ShellCommandLineGetRawValue(Package
, ++ParamNumber
), 0);
1356 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"rm") == 0) {
1357 if ((ParamNumber
+ 1) >= ShellCommandLineGetCount(Package
)) {
1358 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1359 ShellStatus
= SHELL_INVALID_PARAMETER
;
1361 CurrentOperation
.Type
= BcfgTypeRm
;
1362 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1363 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1364 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1365 ShellStatus
= SHELL_INVALID_PARAMETER
;
1367 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1368 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1369 if (CurrentOperation
.Number1
>= Count
){
1370 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1371 ShellStatus
= SHELL_INVALID_PARAMETER
;
1374 } else if (gUnicodeCollation
->StriColl(gUnicodeCollation
, (CHAR16
*)CurrentParam
, L
"mv") == 0) {
1375 if ((ParamNumber
+ 2) >= ShellCommandLineGetCount(Package
)) {
1376 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellBcfgHiiHandle
, L
"bcfg");
1377 ShellStatus
= SHELL_INVALID_PARAMETER
;
1379 CurrentOperation
.Type
= BcfgTypeMv
;
1380 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1381 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1382 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1383 ShellStatus
= SHELL_INVALID_PARAMETER
;
1385 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1386 CurrentOperation
.Number1
= (UINT16
)Intermediate
;
1387 if (CurrentOperation
.Number1
>= Count
){
1388 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1389 ShellStatus
= SHELL_INVALID_PARAMETER
;
1391 CurrentParam
= ShellCommandLineGetRawValue(Package
, ++ParamNumber
);
1392 if (CurrentParam
== NULL
|| !ShellIsHexOrDecimalNumber(CurrentParam
, TRUE
, FALSE
)) {
1393 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1394 ShellStatus
= SHELL_INVALID_PARAMETER
;
1396 Status
= ShellConvertStringToUint64(CurrentParam
, &Intermediate
, TRUE
, FALSE
);
1397 CurrentOperation
.Number2
= (UINT16
)Intermediate
;
1399 if (CurrentOperation
.Number2
== CurrentOperation
.Number1
1400 ||CurrentOperation
.Number2
>= Count
1402 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_BCFG_NUMB_RANGE
), gShellBcfgHiiHandle
, L
"bcfg", Count
);
1403 ShellStatus
= SHELL_INVALID_PARAMETER
;
1408 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellBcfgHiiHandle
, L
"bcfg", CurrentParam
);
1409 ShellStatus
= SHELL_INVALID_PARAMETER
;
1413 if (ShellStatus
== SHELL_SUCCESS
&& CurrentOperation
.Target
< BcfgTargetMax
&& CurrentOperation
.Type
< BcfgTypeMax
) {
1415 // we have all the info. Do the work
1417 switch (CurrentOperation
.Type
) {
1419 ShellStatus
= BcfgDisplayDump(
1420 CurrentOperation
.Target
== BcfgTargetBootOrder
?L
"Boot":L
"Driver",
1422 CurrentOperation
.Order
,
1423 ShellCommandLineGetFlag(Package
, L
"-v"));
1426 ShellStatus
= BcfgMove(
1427 CurrentOperation
.Target
,
1428 CurrentOperation
.Order
,
1430 CurrentOperation
.Number1
,
1431 CurrentOperation
.Number2
);
1434 ShellStatus
= BcfgRemove(
1435 CurrentOperation
.Target
,
1436 CurrentOperation
.Order
,
1438 CurrentOperation
.Number1
);
1443 ShellStatus
= BcfgAdd(
1444 CurrentOperation
.Number1
,
1445 CurrentOperation
.FileName
,
1446 CurrentOperation
.Description
==NULL
?L
"":CurrentOperation
.Description
,
1447 CurrentOperation
.Order
,
1449 CurrentOperation
.Target
,
1450 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddh
),
1451 (BOOLEAN
)(CurrentOperation
.Type
== BcfgTypeAddp
),
1452 CurrentOperation
.HandleIndex
);
1455 ShellStatus
= BcfgAddOpt(
1456 CurrentOperation
.OptData
,
1457 CurrentOperation
.Order
,
1459 CurrentOperation
.Target
);
1467 if (Package
!= NULL
) {
1468 ShellCommandLineFreeVarList (Package
);
1470 if (CurrentOperation
.FileName
!= NULL
) {
1471 FreePool(CurrentOperation
.FileName
);
1473 if (CurrentOperation
.Description
!= NULL
) {
1474 FreePool(CurrentOperation
.Description
);
1476 if (CurrentOperation
.Order
!= NULL
) {
1477 FreePool(CurrentOperation
.Order
);
1480 return (ShellStatus
);
1485 Function to get the filename with help context if HII will not be used.
1487 @return The filename with help text in it.
1491 ShellCommandGetManFileNameBcfg (
1499 "Constructor" for the library.
1501 This will register the handler for the bcfg command.
1503 @param[in] ImageHandle the image handle of the process
1504 @param[in] SystemTable the EFI System Table pointer
1505 @param[in] Name the profile name to use
1507 @retval EFI_SUCCESS the shell command handlers were installed sucessfully
1508 @retval EFI_UNSUPPORTED the shell level required was not found.
1512 BcfgLibraryRegisterBcfgCommand (
1513 IN EFI_HANDLE ImageHandle
,
1514 IN EFI_SYSTEM_TABLE
*SystemTable
,
1515 IN CONST CHAR16
*Name
1518 if (gShellBcfgHiiHandle
!= NULL
) {
1519 return (EFI_SUCCESS
);
1522 gShellBcfgHiiHandle
= HiiAddPackages (&gShellBcfgHiiGuid
, gImageHandle
, UefiShellBcfgCommandLibStrings
, NULL
);
1523 if (gShellBcfgHiiHandle
== NULL
) {
1524 return (EFI_DEVICE_ERROR
);
1528 // install our shell command handler
1530 ShellCommandRegisterCommandName(L
"bcfg", ShellCommandRunBcfg
, ShellCommandGetManFileNameBcfg
, 0, Name
, FALSE
, gShellBcfgHiiHandle
, STRING_TOKEN(STR_GET_HELP_BCFG
));
1532 return (EFI_SUCCESS
);
1536 Destructor for the library. free any resources.
1538 @param ImageHandle The image handle of the process.
1539 @param SystemTable The EFI System Table pointer.
1543 BcfgLibraryUnregisterBcfgCommand (
1544 IN EFI_HANDLE ImageHandle
,
1545 IN EFI_SYSTEM_TABLE
*SystemTable
1548 if (gShellBcfgHiiHandle
!= NULL
) {
1549 HiiRemovePackages(gShellBcfgHiiHandle
);
1551 gShellBcfgHiiHandle
= NULL
;
1552 return (EFI_SUCCESS
);