summaryrefslogtreecommitdiff
path: root/ShellPkg/Library/UefiShellBcfgCommandLib
diff options
context:
space:
mode:
Diffstat (limited to 'ShellPkg/Library/UefiShellBcfgCommandLib')
-rw-r--r--ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.c3942
-rw-r--r--ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf84
-rw-r--r--ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.uni306
3 files changed, 2166 insertions, 2166 deletions
diff --git a/ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.c b/ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.c
index 0b94d9f5a1..80e9799077 100644
--- a/ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.c
+++ b/ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.c
@@ -1,1971 +1,1971 @@
-/** @file
- Main file for BCFG command.
-
- (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Uefi.h>
-
-#include <Guid/GlobalVariable.h>
-#include <Guid/ShellLibHiiGuid.h>
-
-#include <Protocol/Shell.h>
-#include <Protocol/ShellParameters.h>
-#include <Protocol/DevicePath.h>
-#include <Protocol/LoadedImage.h>
-#include <Protocol/UnicodeCollation.h>
-
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/PcdLib.h>
-#include <Library/ShellCommandLib.h>
-#include <Library/ShellLib.h>
-#include <Library/SortLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/HiiLib.h>
-#include <Library/FileHandleLib.h>
-#include <Library/PrintLib.h>
-#include <Library/HandleParsingLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/UefiBootManagerLib.h>
-
-STATIC CONST CHAR16 mFileName[] = L"ShellCommands";
-STATIC EFI_HII_HANDLE gShellBcfgHiiHandle = NULL;
-
-typedef enum {
- BcfgTargetBootOrder = 0,
- BcfgTargetDriverOrder = 1,
- BcfgTargetMax = 2
-} BCFG_OPERATION_TARGET;
-
-typedef enum {
- BcfgTypeDump = 0,
- BcfgTypeAdd = 1,
- BcfgTypeAddp = 2,
- BcfgTypeAddh = 3,
- BcfgTypeRm = 4,
- BcfgTypeMv = 5,
- BcfgTypeOpt = 6,
- BcfgTypeMod = 7,
- BcfgTypeModf = 8,
- BcfgTypeModp = 9,
- BcfgTypeModh = 10,
- BcfgTypeMax = 11
-} BCFG_OPERATION_TYPE;
-
-typedef struct {
- BCFG_OPERATION_TARGET Target;
- BCFG_OPERATION_TYPE Type;
- UINT16 Number1;
- UINT16 Number2;
- UINTN HandleIndex;
- CHAR16 *FileName;
- CHAR16 *Description;
- UINT16 *Order;
- CONST CHAR16 *OptData;
-} BGFG_OPERATION;
-
-/**
- Update the optional data for a boot or driver option.
-
- If optional data exists it will be changed.
-
- @param[in] Index The boot or driver option index update.
- @param[in] DataSize The size in bytes of Data.
- @param[in] Data The buffer for the optional data.
- @param[in] Target The target of the operation.
-
- @retval EFI_SUCCESS The data was successfully updated.
- @retval other A error occurred.
-**/
-EFI_STATUS
-UpdateOptionalData (
- UINT16 Index,
- UINTN DataSize,
- UINT8 *Data,
- IN CONST BCFG_OPERATION_TARGET Target
- )
-{
- EFI_STATUS Status;
- CHAR16 VariableName[12];
- UINTN OriginalSize;
- UINT8 *OriginalData;
- UINTN NewSize;
- UINT8 *NewData;
- UINTN OriginalOptionDataSize;
-
- UnicodeSPrint (VariableName, sizeof (VariableName), L"%s%04x", Target == BcfgTargetBootOrder ? L"Boot" : L"Driver", Index);
-
- OriginalSize = 0;
- OriginalData = NULL;
- NewData = NULL;
- NewSize = 0;
-
- Status = gRT->GetVariable (
- VariableName,
- (EFI_GUID *)&gEfiGlobalVariableGuid,
- NULL,
- &OriginalSize,
- OriginalData
- );
- if (Status == EFI_BUFFER_TOO_SMALL) {
- OriginalData = AllocateZeroPool (OriginalSize);
- if (OriginalData == NULL) {
- return (EFI_OUT_OF_RESOURCES);
- }
-
- Status = gRT->GetVariable (
- VariableName,
- (EFI_GUID *)&gEfiGlobalVariableGuid,
- NULL,
- &OriginalSize,
- OriginalData
- );
- }
-
- if (!EFI_ERROR (Status)) {
- //
- // Allocate new struct and discard old optional data.
- //
- ASSERT (OriginalData != NULL);
- OriginalOptionDataSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (((CHAR16 *)(OriginalData + sizeof (UINT32) + sizeof (UINT16))));
- OriginalOptionDataSize += (*(UINT16 *)(OriginalData + sizeof (UINT32)));
- OriginalOptionDataSize -= OriginalSize;
- NewSize = OriginalSize - OriginalOptionDataSize + DataSize;
- NewData = AllocatePool (NewSize);
- if (NewData == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- } else {
- CopyMem (NewData, OriginalData, OriginalSize - OriginalOptionDataSize);
- CopyMem (NewData + OriginalSize - OriginalOptionDataSize, Data, DataSize);
- }
- }
-
- if (!EFI_ERROR (Status)) {
- //
- // put the data back under the variable
- //
- Status = gRT->SetVariable (
- VariableName,
- (EFI_GUID *)&gEfiGlobalVariableGuid,
- EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
- NewSize,
- NewData
- );
- }
-
- SHELL_FREE_NON_NULL (OriginalData);
- SHELL_FREE_NON_NULL (NewData);
- return (Status);
-}
-
-/**
- This function will get a CRC for a boot option.
-
- @param[in, out] Crc The CRC value to return.
- @param[in] BootIndex The boot option index to CRC.
-
- @retval EFI_SUCCESS The CRC was successfully returned.
- @retval other A error occurred.
-**/
-EFI_STATUS
-GetBootOptionCrc (
- UINT32 *Crc,
- UINT16 BootIndex
- )
-{
- CHAR16 VariableName[12];
- EFI_STATUS Status;
- UINT8 *Buffer;
- UINTN BufferSize;
-
- Buffer = NULL;
- BufferSize = 0;
-
- //
- // Get the data Buffer
- //
- UnicodeSPrint (VariableName, sizeof (VariableName), L"%Boot%04x", BootIndex);
- Status = gRT->GetVariable (
- VariableName,
- (EFI_GUID *)&gEfiGlobalVariableGuid,
- NULL,
- &BufferSize,
- NULL
- );
- if (Status == EFI_BUFFER_TOO_SMALL) {
- Buffer = AllocateZeroPool (BufferSize);
- Status = gRT->GetVariable (
- VariableName,
- (EFI_GUID *)&gEfiGlobalVariableGuid,
- NULL,
- &BufferSize,
- Buffer
- );
- }
-
- //
- // Get the CRC computed
- //
- if (!EFI_ERROR (Status)) {
- Status = gBS->CalculateCrc32 (Buffer, BufferSize, Crc);
- }
-
- SHELL_FREE_NON_NULL (Buffer);
- return EFI_SUCCESS;
-}
-
-/**
- This function will populate the device path protocol parameter based on TheHandle.
-
- @param[in] TheHandle Driver handle.
- @param[in, out] FilePath On a successful return the device path to the handle.
-
- @retval EFI_SUCCESS The device path was successfully returned.
- @retval other A error from gBS->HandleProtocol.
-
- @sa HandleProtocol
-**/
-EFI_STATUS
-GetDevicePathForDriverHandle (
- IN EFI_HANDLE TheHandle,
- IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath
- )
-{
- EFI_STATUS Status;
- EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
- EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
-
- Status = gBS->OpenProtocol (
- TheHandle,
- &gEfiLoadedImageProtocolGuid,
- (VOID **)&LoadedImage,
- gImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (!EFI_ERROR (Status)) {
- Status = gBS->OpenProtocol (
- LoadedImage->DeviceHandle,
- &gEfiDevicePathProtocolGuid,
- (VOID **)&ImageDevicePath,
- gImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (!EFI_ERROR (Status)) {
- // *DevPath = DuplicateDevicePath (ImageDevicePath);
- // *FilePath = DuplicateDevicePath (LoadedImage->FilePath);
- *FilePath = AppendDevicePath (ImageDevicePath, LoadedImage->FilePath);
- gBS->CloseProtocol (
- LoadedImage->DeviceHandle,
- &gEfiDevicePathProtocolGuid,
- gImageHandle,
- NULL
- );
- }
-
- gBS->CloseProtocol (
- TheHandle,
- &gEfiLoadedImageProtocolGuid,
- gImageHandle,
- NULL
- );
- }
-
- return (Status);
-}
-
-/**
- Function to get Device Path by a handle.
-
- @param[in] TheHandle Use it to get DevicePath.
- @param[in] Target Boot option target.
- @param[in, out] DevicePath On a successful return the device path to the handle.
-
- @retval SHELL_INVALID_PARAMETER The handle was NULL.
- @retval SHELL_NOT_FOUND Not found device path by handle.
- @retval SHELL_SUCCESS Get device path successfully.
-**/
-SHELL_STATUS
-GetDevicePathByHandle (
- IN EFI_HANDLE TheHandle,
- IN BCFG_OPERATION_TARGET Target,
- IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
- )
-{
- EFI_STATUS Status;
- SHELL_STATUS ShellStatus;
-
- UINTN DriverBindingHandleCount;
- UINTN ParentControllerHandleCount;
- UINTN ChildControllerHandleCount;
-
- ShellStatus = SHELL_SUCCESS;
-
- if (TheHandle == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");
- return SHELL_INVALID_PARAMETER;
- }
-
- Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (TheHandle, &DriverBindingHandleCount, NULL);
- if (EFI_ERROR (Status)) {
- DriverBindingHandleCount = 0;
- }
-
- Status = PARSE_HANDLE_DATABASE_PARENTS (TheHandle, &ParentControllerHandleCount, NULL);
- if (EFI_ERROR (Status)) {
- ParentControllerHandleCount = 0;
- }
-
- Status = ParseHandleDatabaseForChildControllers (TheHandle, &ChildControllerHandleCount, NULL);
- if (EFI_ERROR (Status)) {
- ChildControllerHandleCount = 0;
- }
-
- Status = gBS->HandleProtocol (TheHandle, &gEfiDevicePathProtocolGuid, (VOID **)DevicePath);
-
- if ((DriverBindingHandleCount > 0) ||
- (ParentControllerHandleCount > 0) ||
- (ChildControllerHandleCount > 0) ||
- !EFI_ERROR (Status)
- )
- {
- //
- // The handle points to a real controller which has a device path.
- //
- if (Target == BcfgTargetDriverOrder) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_GEN_PARAM_INV),
- gShellBcfgHiiHandle,
- L"bcfg",
- L"Handle should point to driver image."
- );
- ShellStatus = SHELL_NOT_FOUND;
- }
- } else {
- //
- // The handle points to a driver image.
- //
- if (Target == BcfgTargetBootOrder) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_GEN_PARAM_INV),
- gShellBcfgHiiHandle,
- L"bcfg",
- L"Handle should point to controller."
- );
- ShellStatus = SHELL_NOT_FOUND;
- } else {
- if (EFI_ERROR (GetDevicePathForDriverHandle (TheHandle, DevicePath))) {
- ShellStatus = SHELL_NOT_FOUND;
- }
- }
- }
-
- return (ShellStatus);
-}
-
-/**
- Function to modify an option.
-
- @param[in] BcfgOperation Pointer to BCFG operation.
- @param[in] OrderCount The number if items in CurrentOrder.
-
- @retval SHELL_SUCCESS The operation was successful.
- @retval SHELL_INVALID_PARAMETER A parameter was invalid.
- @retval SHELL_OUT_OF_RESOUCES A memory allocation failed.
-**/
-SHELL_STATUS
-BcfgMod (
- IN CONST BGFG_OPERATION *BcfgOperation,
- IN CONST UINTN OrderCount
- )
-{
- EFI_STATUS Status;
- EFI_HANDLE CurHandle;
- SHELL_STATUS ShellStatus;
- CHAR16 OptionStr[40];
- EFI_SHELL_FILE_INFO *FileList;
- EFI_SHELL_FILE_INFO *Arg;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- EFI_DEVICE_PATH_PROTOCOL *DevicePathBuffer;
- EFI_DEVICE_PATH_PROTOCOL *DevicePathWalker;
- EFI_BOOT_MANAGER_LOAD_OPTION LoadOption;
-
- ShellStatus = SHELL_SUCCESS;
- FileList = NULL;
- DevicePath = NULL;
- DevicePathBuffer = NULL;
-
- ZeroMem (&LoadOption, sizeof (EFI_BOOT_MANAGER_LOAD_OPTION));
-
- if (((BcfgOperation->Type == BcfgTypeMod) && (BcfgOperation->Description == NULL)) ||
- ((BcfgOperation->Type == BcfgTypeModf) && (BcfgOperation->FileName == NULL)) ||
- ((BcfgOperation->Type == BcfgTypeModp) && (BcfgOperation->FileName == NULL)) ||
- ((BcfgOperation->Type == BcfgTypeModh) && (BcfgOperation->HandleIndex == 0)) ||
- (BcfgOperation->Number1 > OrderCount)
- )
- {
- return (SHELL_INVALID_PARAMETER);
- }
-
- if (BcfgOperation->Type == BcfgTypeModh) {
- CurHandle = ConvertHandleIndexToHandle (BcfgOperation->HandleIndex);
- ShellStatus = GetDevicePathByHandle (CurHandle, BcfgOperation->Target, &DevicePathBuffer);
- if (ShellStatus == SHELL_SUCCESS) {
- DevicePath = DuplicateDevicePath (DevicePathBuffer);
- }
- } else if ((BcfgOperation->Type == BcfgTypeModf) || (BcfgOperation->Type == BcfgTypeModp)) {
- //
- // Get Device Path by FileName.
- //
- ShellOpenFileMetaArg ((CHAR16 *)BcfgOperation->FileName, EFI_FILE_MODE_READ, &FileList);
- if (FileList == NULL) {
- //
- // The name of file matched nothing.
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else if (FileList->Link.ForwardLink != FileList->Link.BackLink) {
- //
- // If the name of file expanded to multiple names, it's fail.
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Arg = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link);
- if (EFI_ERROR (Arg->Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- DevicePathBuffer = gEfiShellProtocol->GetDevicePathFromFilePath (Arg->FullName);
- if (DevicePathBuffer == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellBcfgHiiHandle, L"bcfg", Arg->FullName);
- ShellStatus = SHELL_UNSUPPORTED;
- }
- }
- }
-
- if (ShellStatus == SHELL_SUCCESS) {
- if (BcfgOperation->Type == BcfgTypeModp) {
- ShellStatus = SHELL_INVALID_PARAMETER;
- DevicePathWalker = DevicePathBuffer;
- while (!IsDevicePathEnd (DevicePathWalker)) {
- if ((DevicePathType (DevicePathWalker) == MEDIA_DEVICE_PATH) &&
- (DevicePathSubType (DevicePathWalker) == MEDIA_HARDDRIVE_DP)
- )
- {
- //
- // We found the portion of device path starting with the hard driver partition.
- //
- ShellStatus = SHELL_SUCCESS;
- DevicePath = DuplicateDevicePath (DevicePathWalker);
- break;
- } else {
- DevicePathWalker = NextDevicePathNode (DevicePathWalker);
- }
- }
- } else {
- DevicePath = DuplicateDevicePath (DevicePathBuffer);
- }
-
- FreePool (DevicePathBuffer);
- }
- }
-
- if (ShellStatus == SHELL_SUCCESS) {
- if (BcfgOperation->Target == BcfgTargetBootOrder) {
- UnicodeSPrint (OptionStr, sizeof (OptionStr), L"Boot%04x", BcfgOperation->Order[BcfgOperation->Number1]);
- } else {
- UnicodeSPrint (OptionStr, sizeof (OptionStr), L"Driver%04x", BcfgOperation->Order[BcfgOperation->Number1]);
- }
-
- Status = EfiBootManagerVariableToLoadOption (OptionStr, &LoadOption);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NONE), gShellBcfgHiiHandle);
- ShellStatus = SHELL_NOT_FOUND;
- }
- }
-
- if (ShellStatus == SHELL_SUCCESS) {
- if (BcfgOperation->Type == BcfgTypeMod) {
- SHELL_FREE_NON_NULL (LoadOption.Description);
- LoadOption.Description = AllocateCopyPool (StrSize (BcfgOperation->Description), BcfgOperation->Description);
- } else {
- SHELL_FREE_NON_NULL (LoadOption.FilePath);
- LoadOption.FilePath = DuplicateDevicePath (DevicePath);
- }
-
- Status = EfiBootManagerLoadOptionToVariable (&LoadOption);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", OptionStr);
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
- }
-
- EfiBootManagerFreeLoadOption (&LoadOption);
-
- if (DevicePath != NULL) {
- FreePool (DevicePath);
- }
-
- if (FileList != NULL) {
- ShellCloseFileMetaArg (&FileList);
- }
-
- return (ShellStatus);
-}
-
-/**
- Function to add a option.
-
- @param[in] Position The position to add Target at.
- @param[in] File The file to make the target.
- @param[in] Desc The description text.
- @param[in] CurrentOrder The pointer to the current order of items.
- @param[in] OrderCount The number if items in CurrentOrder.
- @param[in] Target The info on the option to add.
- @param[in] UseHandle TRUE to use HandleNumber, FALSE to use File and Desc.
- @param[in] UsePath TRUE to convert to devicepath.
- @param[in] HandleNumber The handle number to add.
-
- @retval SHELL_SUCCESS The operation was successful.
- @retval SHELL_INVALID_PARAMETER A parameter was invalid.
-**/
-SHELL_STATUS
-BcfgAdd (
- IN UINTN Position,
- IN CONST CHAR16 *File,
- IN CONST CHAR16 *Desc,
- IN CONST UINT16 *CurrentOrder,
- IN CONST UINTN OrderCount,
- IN CONST BCFG_OPERATION_TARGET Target,
- IN CONST BOOLEAN UseHandle,
- IN CONST BOOLEAN UsePath,
- IN CONST UINTN HandleNumber
- )
-{
- EFI_STATUS Status;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- EFI_DEVICE_PATH_PROTOCOL *DevPath;
- EFI_DEVICE_PATH_PROTOCOL *FilePath;
- CHAR16 *Str;
- UINT8 *TempByteBuffer;
- UINT8 *TempByteStart;
- EFI_SHELL_FILE_INFO *Arg;
- EFI_SHELL_FILE_INFO *FileList;
- CHAR16 OptionStr[40];
- UINTN DescSize, FilePathSize;
- BOOLEAN Found;
- UINTN TargetLocation;
- UINTN Index;
- EFI_HANDLE *Handles;
- EFI_HANDLE CurHandle;
- UINTN DriverBindingHandleCount;
- UINTN ParentControllerHandleCount;
- UINTN ChildControllerHandleCount;
- SHELL_STATUS ShellStatus;
- UINT16 *NewOrder;
-
- if (!UseHandle) {
- if ((File == NULL) || (Desc == NULL)) {
- return (SHELL_INVALID_PARAMETER);
- }
- } else {
- if (HandleNumber == 0) {
- return (SHELL_INVALID_PARAMETER);
- }
- }
-
- if (Position > OrderCount) {
- Position = OrderCount;
- }
-
- Str = NULL;
- FilePath = NULL;
- FileList = NULL;
- Handles = NULL;
- ShellStatus = SHELL_SUCCESS;
- TargetLocation = 0xFFFF;
-
- if (UseHandle) {
- CurHandle = ConvertHandleIndexToHandle (HandleNumber);
- if (CurHandle == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- if (Target == BcfgTargetBootOrder) {
- //
- // Make sure that the handle should point to a real controller
- //
- Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
- CurHandle,
- &DriverBindingHandleCount,
- NULL
- );
-
- Status = PARSE_HANDLE_DATABASE_PARENTS (
- CurHandle,
- &ParentControllerHandleCount,
- NULL
- );
-
- Status = ParseHandleDatabaseForChildControllers (
- CurHandle,
- &ChildControllerHandleCount,
- NULL
- );
-
- if ( (DriverBindingHandleCount > 0)
- || (ParentControllerHandleCount > 0)
- || (ChildControllerHandleCount > 0))
- {
- FilePath = NULL;
- Status = gBS->HandleProtocol (
- CurHandle,
- &gEfiDevicePathProtocolGuid,
- (VOID **)&FilePath
- );
- }
-
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_HANDLE), gShellBcfgHiiHandle, L"bcfg", HandleNumber);
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
- } else {
- //
- // Make sure that the handle should point to driver, not a controller.
- //
- Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
- CurHandle,
- &DriverBindingHandleCount,
- NULL
- );
-
- Status = PARSE_HANDLE_DATABASE_PARENTS (
- CurHandle,
- &ParentControllerHandleCount,
- NULL
- );
-
- Status = ParseHandleDatabaseForChildControllers (
- CurHandle,
- &ChildControllerHandleCount,
- NULL
- );
-
- Status = gBS->HandleProtocol (
- CurHandle,
- &gEfiDevicePathProtocolGuid,
- (VOID **)&FilePath
- );
-
- if ( (DriverBindingHandleCount > 0)
- || (ParentControllerHandleCount > 0)
- || (ChildControllerHandleCount > 0)
- || !EFI_ERROR (Status))
- {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- //
- // Get the DevicePath from the loaded image information.
- //
- Status = GetDevicePathForDriverHandle (CurHandle, &FilePath);
- }
- }
- }
- } else {
- //
- // Get file info
- //
- ShellOpenFileMetaArg ((CHAR16 *)File, EFI_FILE_MODE_READ, &FileList);
-
- if (FileList == NULL) {
- //
- // If filename matched nothing fail
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellBcfgHiiHandle, L"bcfg", File);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else if (FileList->Link.ForwardLink != FileList->Link.BackLink) {
- //
- // If filename expanded to multiple names, fail
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellBcfgHiiHandle, L"bcfg", File);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Arg = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link);
- if (EFI_ERROR (Arg->Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellBcfgHiiHandle, L"bcfg", File);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- //
- // Build FilePath to the filename
- //
-
- //
- // get the device path
- //
- DevicePath = gEfiShellProtocol->GetDevicePathFromFilePath (Arg->FullName);
- if (DevicePath == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellBcfgHiiHandle, L"bcfg", Arg->FullName);
- ShellStatus = SHELL_UNSUPPORTED;
- } else {
- if (UsePath) {
- DevPath = DevicePath;
- ShellStatus = SHELL_INVALID_PARAMETER;
- while (!IsDevicePathEnd (DevPath)) {
- if ((DevicePathType (DevPath) == MEDIA_DEVICE_PATH) &&
- (DevicePathSubType (DevPath) == MEDIA_HARDDRIVE_DP))
- {
- //
- // If we find it use it instead
- //
- ShellStatus = SHELL_SUCCESS;
- FilePath = DuplicateDevicePath (DevPath);
- break;
- }
-
- DevPath = NextDevicePathNode (DevPath);
- }
- } else {
- FilePath = DuplicateDevicePath (DevicePath);
- }
-
- FreePool (DevicePath);
- }
- }
- }
- }
-
- if (ShellStatus == SHELL_SUCCESS) {
- //
- // Find a free target ,a brute force implementation
- //
- Found = FALSE;
- for (TargetLocation = 0; TargetLocation < 0xFFFF; TargetLocation++) {
- Found = TRUE;
- for (Index = 0; Index < OrderCount; Index++) {
- if (CurrentOrder[Index] == TargetLocation) {
- Found = FALSE;
- break;
- }
- }
-
- if (Found) {
- break;
- }
- }
-
- if (TargetLocation == 0xFFFF) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET_NF), gShellBcfgHiiHandle, L"bcfg");
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET), gShellBcfgHiiHandle, TargetLocation);
- }
- }
-
- if (ShellStatus == SHELL_SUCCESS) {
- //
- // Add the option
- //
- DescSize = StrSize (Desc);
- FilePathSize = GetDevicePathSize (FilePath);
-
- TempByteBuffer = AllocateZeroPool (sizeof (UINT32) + sizeof (UINT16) + DescSize + FilePathSize);
- if (TempByteBuffer != NULL) {
- TempByteStart = TempByteBuffer;
- *((UINT32 *)TempByteBuffer) = LOAD_OPTION_ACTIVE; // Attributes
- TempByteBuffer += sizeof (UINT32);
-
- *((UINT16 *)TempByteBuffer) = (UINT16)FilePathSize; // FilePathListLength
- TempByteBuffer += sizeof (UINT16);
-
- CopyMem (TempByteBuffer, Desc, DescSize);
- TempByteBuffer += DescSize;
- ASSERT (FilePath != NULL);
- CopyMem (TempByteBuffer, FilePath, FilePathSize);
-
- UnicodeSPrint (OptionStr, sizeof (OptionStr), L"%s%04x", Target == BcfgTargetBootOrder ? L"Boot" : L"Driver", TargetLocation);
- Status = gRT->SetVariable (
- OptionStr,
- &gEfiGlobalVariableGuid,
- EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
- sizeof (UINT32) + sizeof (UINT16) + DescSize + FilePathSize,
- TempByteStart
- );
-
- FreePool (TempByteStart);
- } else {
- Status = EFI_OUT_OF_RESOURCES;
- }
-
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", OptionStr);
- } else {
- NewOrder = AllocateZeroPool ((OrderCount + 1) * sizeof (NewOrder[0]));
- if (NewOrder != NULL) {
- CopyMem (NewOrder, CurrentOrder, (OrderCount) * sizeof (NewOrder[0]));
-
- //
- // Insert target into order list
- //
- for (Index = OrderCount; Index > Position; Index--) {
- NewOrder[Index] = NewOrder[Index - 1];
- }
-
- NewOrder[Position] = (UINT16)TargetLocation;
- Status = gRT->SetVariable (
- Target == BcfgTargetBootOrder ? L"BootOrder" : L"DriverOrder",
- &gEfiGlobalVariableGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- (OrderCount + 1) * sizeof (UINT16),
- NewOrder
- );
-
- FreePool (NewOrder);
-
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder ? L"BootOrder" : L"DriverOrder");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Print (L"bcfg: Add %s as %x\n", OptionStr, Position);
- }
- }
- }
- }
-
- //
- // If always Free FilePath, will free devicepath in system when use "addh"
- //
- if ((FilePath != NULL) && !UseHandle) {
- FreePool (FilePath);
- }
-
- if (Str != NULL) {
- FreePool (Str);
- }
-
- if (Handles != NULL) {
- FreePool (Handles);
- }
-
- if (FileList != NULL) {
- ShellCloseFileMetaArg (&FileList);
- }
-
- return (ShellStatus);
-}
-
-/**
- Function to remove an item.
-
- @param[in] Target The target item to move.
- @param[in] CurrentOrder The pointer to the current order of items.
- @param[in] OrderCount The number if items in CurrentOrder.
- @param[in] Location The current location of the Target.
-
- @retval SHELL_SUCCESS The operation was successful.
- @retval SHELL_INVALID_PARAMETER A parameter was invalid.
-**/
-SHELL_STATUS
-BcfgRemove (
- IN CONST BCFG_OPERATION_TARGET Target,
- IN CONST UINT16 *CurrentOrder,
- IN CONST UINTN OrderCount,
- IN CONST UINT16 Location
- )
-{
- CHAR16 VariableName[12];
- UINT16 *NewOrder;
- EFI_STATUS Status;
- UINTN NewCount;
-
- UnicodeSPrint (VariableName, sizeof (VariableName), L"%s%04x", Target == BcfgTargetBootOrder ? L"Boot" : L"Driver", CurrentOrder[Location]);
- Status = gRT->SetVariable (
- VariableName,
- (EFI_GUID *)&gEfiGlobalVariableGuid,
- EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
- 0,
- NULL
- );
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
- return (SHELL_INVALID_PARAMETER);
- }
-
- NewOrder = AllocateZeroPool (OrderCount*sizeof (CurrentOrder[0]));
- if (NewOrder != NULL) {
- NewCount = OrderCount;
- CopyMem (NewOrder, CurrentOrder, OrderCount*sizeof (CurrentOrder[0]));
- CopyMem (NewOrder+Location, NewOrder+Location+1, (OrderCount - Location - 1)*sizeof (CurrentOrder[0]));
- NewCount--;
-
- Status = gRT->SetVariable (
- Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder",
- (EFI_GUID *)&gEfiGlobalVariableGuid,
- EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
- NewCount*sizeof (NewOrder[0]),
- NewOrder
- );
- FreePool (NewOrder);
- } else {
- Status = EFI_OUT_OF_RESOURCES;
- }
-
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder");
- return (SHELL_INVALID_PARAMETER);
- }
-
- return (SHELL_SUCCESS);
-}
-
-/**
- Function to move a item to another location.
-
- @param[in] Target The target item to move.
- @param[in] CurrentOrder The pointer to the current order of items.
- @param[in] OrderCount The number if items in CurrentOrder.
- @param[in] OldLocation The current location of the Target.
- @param[in] NewLocation The desired location of the Target.
-
- @retval SHELL_SUCCESS The operation was successful.
- @retval SHELL_INVALID_PARAMETER A parameter was invalid.
-**/
-SHELL_STATUS
-BcfgMove (
- IN CONST BCFG_OPERATION_TARGET Target,
- IN CONST UINT16 *CurrentOrder,
- IN CONST UINTN OrderCount,
- IN CONST UINT16 OldLocation,
- IN UINT16 NewLocation
- )
-{
- UINT16 *NewOrder;
- EFI_STATUS Status;
- UINT16 Temp;
-
- NewOrder = AllocateCopyPool (OrderCount*sizeof (CurrentOrder[0]), CurrentOrder);
- if (NewOrder == NULL) {
- return (SHELL_OUT_OF_RESOURCES);
- }
-
- //
- // correct the new location
- //
- if (NewLocation >= OrderCount) {
- if (OrderCount > 0) {
- NewLocation = (UINT16)OrderCount - 1;
- } else {
- NewLocation = 0;
- }
- }
-
- Temp = CurrentOrder[OldLocation];
- CopyMem (NewOrder+OldLocation, NewOrder+OldLocation+1, (OrderCount - OldLocation - 1)*sizeof (CurrentOrder[0]));
- CopyMem (NewOrder+NewLocation+1, NewOrder+NewLocation, (OrderCount - NewLocation - 1)*sizeof (CurrentOrder[0]));
- NewOrder[NewLocation] = Temp;
-
- Status = gRT->SetVariable (
- Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder",
- (EFI_GUID *)&gEfiGlobalVariableGuid,
- EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
- OrderCount*sizeof (CurrentOrder[0]),
- NewOrder
- );
-
- FreePool (NewOrder);
-
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder");
- return (SHELL_INVALID_PARAMETER);
- }
-
- return (SHELL_SUCCESS);
-}
-
-/**
- Function to add optional data to an option.
-
- @param[in] OptData The optional data to add.
- @param[in] CurrentOrder The pointer to the current order of items.
- @param[in] OrderCount The number if items in CurrentOrder.
- @param[in] Target The target of the operation.
-
- @retval SHELL_SUCCESS The operation was succesful.
-**/
-SHELL_STATUS
-BcfgAddOpt (
- IN CONST CHAR16 *OptData,
- IN CONST UINT16 *CurrentOrder,
- IN CONST UINTN OrderCount,
- IN CONST BCFG_OPERATION_TARGET Target
- )
-{
- EFI_KEY_OPTION NewKeyOption;
- EFI_KEY_OPTION *KeyOptionBuffer;
- SHELL_STATUS ShellStatus;
- EFI_STATUS Status;
- UINT16 OptionIndex;
- UINT16 LoopCounter;
- UINT64 Intermediate;
- CONST CHAR16 *Temp;
- CONST CHAR16 *Walker;
- CHAR16 *FileName;
- CHAR16 *Temp2;
- CHAR16 *Data;
- UINT32 KeyIndex;
- CHAR16 VariableName[12];
- VOID *VariableData;
-
- SHELL_FILE_HANDLE FileHandle;
-
- Status = EFI_SUCCESS;
- ShellStatus = SHELL_SUCCESS;
- Walker = OptData;
- FileName = NULL;
- Data = NULL;
- KeyOptionBuffer = NULL;
- VariableData = NULL;
-
- ZeroMem (&NewKeyOption, sizeof (EFI_KEY_OPTION));
- ZeroMem (VariableName, sizeof (VariableName));
-
- while (Walker[0] == L' ') {
- Walker++;
- }
-
- //
- // Get the index of the variable we are changing.
- //
- Status = ShellConvertStringToUint64 (Walker, &Intermediate, TRUE, TRUE);
- if (EFI_ERROR (Status) || (((UINT16)Intermediate) != Intermediate) || (StrStr (Walker, L" ") == NULL) || (((UINT16)Intermediate) > ((UINT16)OrderCount))) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Option Index");
- ShellStatus = SHELL_INVALID_PARAMETER;
- return (ShellStatus);
- }
-
- OptionIndex = (UINT16)Intermediate;
-
- Temp = StrStr (Walker, L" ");
- if (Temp != NULL) {
- Walker = Temp;
- }
-
- while (Walker[0] == L' ') {
- Walker++;
- }
-
- //
- // determine whether we have file with data, quote delimited information, or a hot-key
- //
- if (Walker[0] == L'\"') {
- //
- // quoted filename or quoted information.
- //
- Temp = StrStr (Walker+1, L"\"");
- if ((Temp == NULL) || (StrLen (Temp) != 1)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- FileName = StrnCatGrow (&FileName, NULL, Walker+1, 0);
- if (FileName == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellBcfgHiiHandle, L"bcfg");
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- return (ShellStatus);
- }
-
- Temp2 = StrStr (FileName, L"\"");
- ASSERT (Temp2 != NULL);
- Temp2[0] = CHAR_NULL;
- Temp2++;
- if (StrLen (Temp2) > 0) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
-
- if (EFI_ERROR (ShellFileExists (Walker))) {
- //
- // Not a file. must be misc information.
- //
- Data = FileName;
- FileName = NULL;
- } else {
- FileName = StrnCatGrow (&FileName, NULL, Walker, 0);
- }
- }
- } else {
- //
- // filename or hot key information.
- //
- if (StrStr (Walker, L" ") == NULL) {
- //
- // filename
- //
- if (EFI_ERROR (ShellFileExists (Walker))) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FIND_FAIL), gShellBcfgHiiHandle, L"bcfg", Walker);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- FileName = StrnCatGrow (&FileName, NULL, Walker, 0);
- }
- } else {
- if (Target != BcfgTargetBootOrder) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_BOOT_ONLY), gShellBcfgHiiHandle, L"bcfg");
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
-
- if (ShellStatus == SHELL_SUCCESS) {
- //
- // Get hot key information
- //
- Status = ShellConvertStringToUint64 (Walker, &Intermediate, FALSE, TRUE);
- if (EFI_ERROR (Status) || (((UINT32)Intermediate) != Intermediate) || (StrStr (Walker, L" ") == NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
-
- NewKeyOption.KeyData.PackedValue = (UINT32)Intermediate;
- Temp = StrStr (Walker, L" ");
- if (Temp != NULL) {
- Walker = Temp;
- }
-
- while (Walker[0] == L' ') {
- Walker++;
- }
- }
-
- if (ShellStatus == SHELL_SUCCESS) {
- //
- // Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.
- // Re-allocate with the added information.
- //
- KeyOptionBuffer = AllocatePool (sizeof (EFI_KEY_OPTION) + (sizeof (EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount));
- if (KeyOptionBuffer == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellBcfgHiiHandle, L"bcfg");
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- return ShellStatus;
- }
-
- CopyMem (KeyOptionBuffer, &NewKeyOption, sizeof (EFI_KEY_OPTION));
- }
-
- for (LoopCounter = 0; ShellStatus == SHELL_SUCCESS && LoopCounter < NewKeyOption.KeyData.Options.InputKeyCount; LoopCounter++) {
- //
- // ScanCode
- //
- Status = ShellConvertStringToUint64 (Walker, &Intermediate, FALSE, TRUE);
- if (EFI_ERROR (Status) || (((UINT16)Intermediate) != Intermediate) || (StrStr (Walker, L" ") == NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
-
- ((EFI_INPUT_KEY *)(((UINT8 *)KeyOptionBuffer) + sizeof (EFI_KEY_OPTION)))[LoopCounter].ScanCode = (UINT16)Intermediate;
- Temp = StrStr (Walker, L" ");
- if (Temp != NULL) {
- Walker = Temp;
- }
-
- while (Walker[0] == L' ') {
- Walker++;
- }
-
- //
- // UnicodeChar
- //
- Status = ShellConvertStringToUint64 (Walker, &Intermediate, FALSE, TRUE);
- if (EFI_ERROR (Status) || (((UINT16)Intermediate) != Intermediate)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
-
- ((EFI_INPUT_KEY *)(((UINT8 *)KeyOptionBuffer) + sizeof (EFI_KEY_OPTION)))[LoopCounter].UnicodeChar = (UINT16)Intermediate;
- Temp = StrStr (Walker, L" ");
- if (Temp != NULL) {
- Walker = Temp;
- }
-
- while (Walker[0] == L' ') {
- Walker++;
- }
- }
-
- if (ShellStatus == SHELL_SUCCESS) {
- //
- // Now do the BootOption / BootOptionCrc
- //
- ASSERT (OptionIndex <= OrderCount);
- KeyOptionBuffer->BootOption = CurrentOrder[OptionIndex];
- Status = GetBootOptionCrc (&(KeyOptionBuffer->BootOptionCrc), KeyOptionBuffer->BootOption);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Option Index");
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
- }
-
- if (ShellStatus == SHELL_SUCCESS) {
- for (Temp2 = NULL, KeyIndex = 0; KeyIndex <= 0xFFFF; KeyIndex++) {
- UnicodeSPrint (VariableName, sizeof (VariableName), L"Key%04x", KeyIndex);
- Status = GetEfiGlobalVariable2 (VariableName, &VariableData, NULL);
- if (Status == EFI_NOT_FOUND) {
- break;
- }
-
- if (!EFI_ERROR (Status)) {
- SHELL_FREE_NON_NULL (VariableData);
- }
- }
-
- if (KeyIndex <= 0xFFFF) {
- Status = gRT->SetVariable (
- VariableName,
- (EFI_GUID *)&gEfiGlobalVariableGuid,
- EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
- sizeof (EFI_KEY_OPTION) + (sizeof (EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount),
- KeyOptionBuffer
- );
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_VAR_NO_NUM), gShellBcfgHiiHandle, L"bcfg");
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
-
- ASSERT (FileName == NULL && Data == NULL);
- }
- }
- }
-
- //
- // Shouldn't be possible to have have both. Neither is ok though.
- //
- ASSERT (FileName == NULL || Data == NULL);
-
- if ((ShellStatus == SHELL_SUCCESS) && ((FileName != NULL) || (Data != NULL))) {
- if (FileName != NULL) {
- //
- // Open the file and populate the data buffer.
- //
- Status = ShellOpenFileByName (
- FileName,
- &FileHandle,
- EFI_FILE_MODE_READ,
- 0
- );
- if (!EFI_ERROR (Status)) {
- Status = ShellGetFileSize (FileHandle, &Intermediate);
- }
-
- Data = AllocateZeroPool ((UINTN)Intermediate);
- if (Data == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellBcfgHiiHandle, L"bcfg");
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- }
-
- if (!EFI_ERROR (Status)) {
- Status = ShellReadFile (FileHandle, (UINTN *)&Intermediate, Data);
- }
- } else {
- Intermediate = StrSize (Data);
- }
-
- if (!EFI_ERROR (Status) && (ShellStatus == SHELL_SUCCESS) && (Data != NULL)) {
- Status = UpdateOptionalData (CurrentOrder[OptionIndex], (UINTN)Intermediate, (UINT8 *)Data, Target);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
- }
-
- if (EFI_ERROR (Status) && (ShellStatus == SHELL_SUCCESS)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
- }
-
- SHELL_FREE_NON_NULL (Data);
- SHELL_FREE_NON_NULL (KeyOptionBuffer);
- SHELL_FREE_NON_NULL (FileName);
- return ShellStatus;
-}
-
-/**
- Function to dump the Bcfg information.
-
- @param[in] Op The operation.
- @param[in] OrderCount How many to dump.
- @param[in] CurrentOrder The pointer to the current order of items.
- @param[in] VerboseOutput TRUE for extra output. FALSE otherwise.
-
- @retval SHELL_SUCCESS The dump was successful.
- @retval SHELL_INVALID_PARAMETER A parameter was invalid.
-**/
-SHELL_STATUS
-BcfgDisplayDump (
- IN CONST CHAR16 *Op,
- IN CONST UINTN OrderCount,
- IN CONST UINT16 *CurrentOrder,
- IN CONST BOOLEAN VerboseOutput
- )
-{
- EFI_STATUS Status;
- UINT8 *Buffer;
- UINTN BufferSize;
- CHAR16 VariableName[12];
- UINTN LoopVar;
- CHAR16 *DevPathString;
- VOID *FilePathList;
- UINTN Errors;
- EFI_LOAD_OPTION *LoadOption;
- CHAR16 *Description;
- UINTN DescriptionSize;
- UINTN OptionalDataOffset;
-
- if (OrderCount == 0) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NONE), gShellBcfgHiiHandle, L"bcfg");
- return (SHELL_SUCCESS);
- }
-
- Errors = 0;
-
- for (LoopVar = 0; LoopVar < OrderCount; LoopVar++) {
- Buffer = NULL;
- BufferSize = 0;
- DevPathString = NULL;
-
- UnicodeSPrint (VariableName, sizeof (VariableName), L"%s%04x", Op, CurrentOrder[LoopVar]);
-
- Status = gRT->GetVariable (
- VariableName,
- (EFI_GUID *)&gEfiGlobalVariableGuid,
- NULL,
- &BufferSize,
- Buffer
- );
- if (Status == EFI_BUFFER_TOO_SMALL) {
- Buffer = AllocateZeroPool (BufferSize);
- Status = gRT->GetVariable (
- VariableName,
- (EFI_GUID *)&gEfiGlobalVariableGuid,
- NULL,
- &BufferSize,
- Buffer
- );
- }
-
- if (EFI_ERROR (Status) || (Buffer == NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_READ_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
- ++Errors;
- goto Cleanup;
- }
-
- //
- // We expect the Attributes, FilePathListLength, and L'\0'-terminated
- // Description fields to be present.
- //
- if (BufferSize < sizeof *LoadOption + sizeof (CHAR16)) {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_BCFG_VAR_CORRUPT),
- gShellBcfgHiiHandle,
- L"bcfg",
- VariableName
- );
- ++Errors;
- goto Cleanup;
- }
-
- LoadOption = (EFI_LOAD_OPTION *)Buffer;
- Description = (CHAR16 *)(Buffer + sizeof (EFI_LOAD_OPTION));
- DescriptionSize = StrSize (Description);
-
- if (LoadOption->FilePathListLength != 0) {
- FilePathList = (UINT8 *)Description + DescriptionSize;
- DevPathString = ConvertDevicePathToText (FilePathList, TRUE, FALSE);
- }
-
- OptionalDataOffset = sizeof *LoadOption + DescriptionSize +
- LoadOption->FilePathListLength;
-
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_BCFG_LOAD_OPTIONS),
- gShellBcfgHiiHandle,
- LoopVar,
- VariableName,
- Description,
- DevPathString,
- OptionalDataOffset >= BufferSize ? L'N' : L'Y'
- );
- if (VerboseOutput && (OptionalDataOffset < BufferSize)) {
- DumpHex (
- 2, // Indent
- 0, // Offset (displayed)
- BufferSize - OptionalDataOffset, // DataSize
- Buffer + OptionalDataOffset // UserData
- );
- }
-
-Cleanup:
- if (Buffer != NULL) {
- FreePool (Buffer);
- }
-
- if (DevPathString != NULL) {
- FreePool (DevPathString);
- }
- }
-
- return (Errors > 0) ? SHELL_INVALID_PARAMETER : SHELL_SUCCESS;
-}
-
-/**
- Function to initialize the BCFG operation structure.
-
- @param[in] Struct The stuct to initialize.
-**/
-VOID
-InitBcfgStruct (
- IN BGFG_OPERATION *Struct
- )
-{
- ASSERT (Struct != NULL);
- Struct->Target = BcfgTargetMax;
- Struct->Type = BcfgTypeMax;
- Struct->Number1 = 0;
- Struct->Number2 = 0;
- Struct->HandleIndex = 0;
- Struct->FileName = NULL;
- Struct->Description = NULL;
- Struct->Order = NULL;
- Struct->OptData = NULL;
-}
-
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- { L"-v", TypeFlag },
- { L"-opt", TypeMaxValue },
- { NULL, TypeMax }
-};
-
-/**
- Function for 'bcfg' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunBcfg (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- CHAR16 *ProblemParam;
- SHELL_STATUS ShellStatus;
- UINTN ParamNumber;
- CONST CHAR16 *CurrentParam;
- BGFG_OPERATION CurrentOperation;
- UINTN Length;
- UINT64 Intermediate;
- UINT16 Count;
-
- Length = 0;
- ProblemParam = NULL;
- Package = NULL;
- ShellStatus = SHELL_SUCCESS;
-
- InitBcfgStruct (&CurrentOperation);
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- Status = CommandInit ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // parse the command line
- //
- Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellBcfgHiiHandle, L"bcfg", ProblemParam);
- FreePool (ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (FALSE);
- }
- } else {
- //
- // Read in if we are doing -OPT
- //
- if (ShellCommandLineGetFlag (Package, L"-opt")) {
- CurrentOperation.OptData = ShellCommandLineGetValue (Package, L"-opt");
- if (CurrentOperation.OptData == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellBcfgHiiHandle, L"bcfg", L"-opt");
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
-
- CurrentOperation.Type = BcfgTypeOpt;
- }
-
- //
- // small block to read the target of the operation
- //
- if (((ShellCommandLineGetCount (Package) < 3) && (CurrentOperation.Type != BcfgTypeOpt)) ||
- ((ShellCommandLineGetCount (Package) < 2) && (CurrentOperation.Type == BcfgTypeOpt))
- )
- {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)ShellCommandLineGetRawValue (Package, 1), L"driver") == 0) {
- CurrentOperation.Target = BcfgTargetDriverOrder;
- } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)ShellCommandLineGetRawValue (Package, 1), L"boot") == 0) {
- CurrentOperation.Target = BcfgTargetBootOrder;
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT), gShellBcfgHiiHandle, L"bcfg");
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
-
- //
- // Read in the boot or driver order environment variable (not needed for opt)
- //
- if ((ShellStatus == SHELL_SUCCESS) && (CurrentOperation.Target < BcfgTargetMax)) {
- Length = 0;
- Status = gRT->GetVariable (
- CurrentOperation.Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder",
- (EFI_GUID *)&gEfiGlobalVariableGuid,
- NULL,
- &Length,
- CurrentOperation.Order
- );
- if (Status == EFI_BUFFER_TOO_SMALL) {
- CurrentOperation.Order = AllocateZeroPool (Length+(4*sizeof (CurrentOperation.Order[0])));
- if (CurrentOperation.Order == NULL) {
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- } else {
- Status = gRT->GetVariable (
- CurrentOperation.Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder",
- (EFI_GUID *)&gEfiGlobalVariableGuid,
- NULL,
- &Length,
- CurrentOperation.Order
- );
- }
- }
- }
-
- Count = (UINT16)(Length / sizeof (CurrentOperation.Order[0]));
-
- //
- // large block to read the type of operation and verify parameter types for the info.
- //
- if ((ShellStatus == SHELL_SUCCESS) && (CurrentOperation.Target < BcfgTargetMax)) {
- for (ParamNumber = 2; ParamNumber < ShellCommandLineGetCount (Package) && ShellStatus == SHELL_SUCCESS; ParamNumber++) {
- CurrentParam = ShellCommandLineGetRawValue (Package, ParamNumber);
- if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"dump") == 0) {
- CurrentOperation.Type = BcfgTypeDump;
- if (ShellCommandLineGetCount (Package) > 3) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellBcfgHiiHandle, L"bcfg");
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
- } else if (ShellCommandLineGetFlag (Package, L"-v")) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"-v (without dump)");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"add") == 0) {
- if ((ParamNumber + 3) >= ShellCommandLineGetCount (Package)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
-
- CurrentOperation.Type = BcfgTypeAdd;
- CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
- if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
- CurrentOperation.Number1 = (UINT16)Intermediate;
- ASSERT (CurrentOperation.FileName == NULL);
- CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
- ASSERT (CurrentOperation.Description == NULL);
- CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
- }
- } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"addp") == 0) {
- if ((ParamNumber + 3) >= ShellCommandLineGetCount (Package)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
-
- CurrentOperation.Type = BcfgTypeAddp;
- CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
- if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
- CurrentOperation.Number1 = (UINT16)Intermediate;
- ASSERT (CurrentOperation.FileName == NULL);
- CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
- ASSERT (CurrentOperation.Description == NULL);
- CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
- }
- } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"addh") == 0) {
- if ((ParamNumber + 3) >= ShellCommandLineGetCount (Package)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
-
- CurrentOperation.Type = BcfgTypeAddh;
- CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
- if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
- CurrentOperation.Number1 = (UINT16)Intermediate;
- CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
- if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
- CurrentOperation.HandleIndex = (UINT16)Intermediate;
- ASSERT (CurrentOperation.Description == NULL);
- CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
- }
- }
- } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"rm") == 0) {
- if ((ParamNumber + 1) >= ShellCommandLineGetCount (Package)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
-
- CurrentOperation.Type = BcfgTypeRm;
- CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
- if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
- CurrentOperation.Number1 = (UINT16)Intermediate;
- if (CurrentOperation.Number1 >= Count) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
- }
- } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"mv") == 0) {
- if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
-
- CurrentOperation.Type = BcfgTypeMv;
- CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
- if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
- CurrentOperation.Number1 = (UINT16)Intermediate;
- if (CurrentOperation.Number1 >= Count) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
- if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
- CurrentOperation.Number2 = (UINT16)Intermediate;
- }
-
- if ( (CurrentOperation.Number2 == CurrentOperation.Number1)
- || (CurrentOperation.Number2 >= Count)
- )
- {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
- }
- }
- } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"mod") == 0) {
- if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- CurrentOperation.Type = BcfgTypeMod;
- CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
- if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
- CurrentOperation.Number1 = (UINT16)Intermediate;
- if (CurrentOperation.Number1 >= Count) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (CurrentOperation.Description == NULL);
- CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
- }
- }
- }
- } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"modf") == 0) {
- if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- CurrentOperation.Type = BcfgTypeModf;
- CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
- if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
- CurrentOperation.Number1 = (UINT16)Intermediate;
- if (CurrentOperation.Number1 >= Count) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (CurrentOperation.FileName == NULL);
- CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
- }
- }
- }
- } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"modp") == 0) {
- if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- CurrentOperation.Type = BcfgTypeModp;
- CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
- if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
- CurrentOperation.Number1 = (UINT16)Intermediate;
- if (CurrentOperation.Number1 >= Count) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- ASSERT (CurrentOperation.FileName == NULL);
- CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
- }
- }
- }
- } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"modh") == 0) {
- if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- CurrentOperation.Type = BcfgTypeModh;
- CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
- if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
- CurrentOperation.Number1 = (UINT16)Intermediate;
- if (CurrentOperation.Number1 >= Count) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
- if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else {
- Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
- CurrentOperation.HandleIndex = (UINT16)Intermediate;
- }
- }
- }
- }
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- }
- }
- }
-
- if ((ShellStatus == SHELL_SUCCESS) && (CurrentOperation.Target < BcfgTargetMax) && (CurrentOperation.Type < BcfgTypeMax)) {
- //
- // we have all the info. Do the work
- //
- switch (CurrentOperation.Type) {
- case BcfgTypeDump:
- ShellStatus = BcfgDisplayDump (
- CurrentOperation.Target == BcfgTargetBootOrder ? L"Boot" : L"Driver",
- Count,
- CurrentOperation.Order,
- ShellCommandLineGetFlag (Package, L"-v")
- );
- break;
- case BcfgTypeMv:
- ShellStatus = BcfgMove (
- CurrentOperation.Target,
- CurrentOperation.Order,
- Count,
- CurrentOperation.Number1,
- CurrentOperation.Number2
- );
- break;
- case BcfgTypeRm:
- ShellStatus = BcfgRemove (
- CurrentOperation.Target,
- CurrentOperation.Order,
- Count,
- CurrentOperation.Number1
- );
- break;
- case BcfgTypeAdd:
- case BcfgTypeAddp:
- case BcfgTypeAddh:
- ShellStatus = BcfgAdd (
- CurrentOperation.Number1,
- CurrentOperation.FileName,
- CurrentOperation.Description == NULL ? L"" : CurrentOperation.Description,
- CurrentOperation.Order,
- Count,
- CurrentOperation.Target,
- (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddh),
- (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddp),
- CurrentOperation.HandleIndex
- );
- break;
- case BcfgTypeMod:
- case BcfgTypeModf:
- case BcfgTypeModp:
- case BcfgTypeModh:
- ShellStatus = BcfgMod (&CurrentOperation, Count);
- break;
- case BcfgTypeOpt:
- ShellStatus = BcfgAddOpt (
- CurrentOperation.OptData,
- CurrentOperation.Order,
- Count,
- CurrentOperation.Target
- );
- break;
- default:
- ASSERT (FALSE);
- }
- }
- }
-
- if (Package != NULL) {
- ShellCommandLineFreeVarList (Package);
- }
-
- if (CurrentOperation.FileName != NULL) {
- FreePool (CurrentOperation.FileName);
- }
-
- if (CurrentOperation.Description != NULL) {
- FreePool (CurrentOperation.Description);
- }
-
- if (CurrentOperation.Order != NULL) {
- FreePool (CurrentOperation.Order);
- }
-
- return (ShellStatus);
-}
-
-/**
- Function to get the filename with help context if HII will not be used.
-
- @return The filename with help text in it.
-**/
-CONST CHAR16 *
-EFIAPI
-ShellCommandGetManFileNameBcfg (
- VOID
- )
-{
- return (mFileName);
-}
-
-/**
- "Constructor" for the library.
-
- This will register the handler for the bcfg command.
-
- @param[in] ImageHandle the image handle of the process
- @param[in] SystemTable the EFI System Table pointer
- @param[in] Name the profile name to use
-
- @retval EFI_SUCCESS the shell command handlers were installed successfully
- @retval EFI_UNSUPPORTED the shell level required was not found.
-**/
-EFI_STATUS
-EFIAPI
-BcfgLibraryRegisterBcfgCommand (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable,
- IN CONST CHAR16 *Name
- )
-{
- if (gShellBcfgHiiHandle != NULL) {
- return (EFI_SUCCESS);
- }
-
- gShellBcfgHiiHandle = HiiAddPackages (&gShellBcfgHiiGuid, gImageHandle, UefiShellBcfgCommandLibStrings, NULL);
- if (gShellBcfgHiiHandle == NULL) {
- return (EFI_DEVICE_ERROR);
- }
-
- //
- // install our shell command handler
- //
- ShellCommandRegisterCommandName (L"bcfg", ShellCommandRunBcfg, ShellCommandGetManFileNameBcfg, 0, Name, FALSE, gShellBcfgHiiHandle, STRING_TOKEN (STR_GET_HELP_BCFG));
-
- return (EFI_SUCCESS);
-}
-
-/**
- Destructor for the library. free any resources.
-
- @param ImageHandle The image handle of the process.
- @param SystemTable The EFI System Table pointer.
-**/
-EFI_STATUS
-EFIAPI
-BcfgLibraryUnregisterBcfgCommand (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- if (gShellBcfgHiiHandle != NULL) {
- HiiRemovePackages (gShellBcfgHiiHandle);
- }
-
- gShellBcfgHiiHandle = NULL;
- return (EFI_SUCCESS);
-}
+/** @file
+ Main file for BCFG command.
+
+ (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
+ Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Guid/GlobalVariable.h>
+#include <Guid/ShellLibHiiGuid.h>
+
+#include <Protocol/Shell.h>
+#include <Protocol/ShellParameters.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/UnicodeCollation.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/ShellCommandLib.h>
+#include <Library/ShellLib.h>
+#include <Library/SortLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/HiiLib.h>
+#include <Library/FileHandleLib.h>
+#include <Library/PrintLib.h>
+#include <Library/HandleParsingLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiBootManagerLib.h>
+
+STATIC CONST CHAR16 mFileName[] = L"ShellCommands";
+STATIC EFI_HII_HANDLE gShellBcfgHiiHandle = NULL;
+
+typedef enum {
+ BcfgTargetBootOrder = 0,
+ BcfgTargetDriverOrder = 1,
+ BcfgTargetMax = 2
+} BCFG_OPERATION_TARGET;
+
+typedef enum {
+ BcfgTypeDump = 0,
+ BcfgTypeAdd = 1,
+ BcfgTypeAddp = 2,
+ BcfgTypeAddh = 3,
+ BcfgTypeRm = 4,
+ BcfgTypeMv = 5,
+ BcfgTypeOpt = 6,
+ BcfgTypeMod = 7,
+ BcfgTypeModf = 8,
+ BcfgTypeModp = 9,
+ BcfgTypeModh = 10,
+ BcfgTypeMax = 11
+} BCFG_OPERATION_TYPE;
+
+typedef struct {
+ BCFG_OPERATION_TARGET Target;
+ BCFG_OPERATION_TYPE Type;
+ UINT16 Number1;
+ UINT16 Number2;
+ UINTN HandleIndex;
+ CHAR16 *FileName;
+ CHAR16 *Description;
+ UINT16 *Order;
+ CONST CHAR16 *OptData;
+} BGFG_OPERATION;
+
+/**
+ Update the optional data for a boot or driver option.
+
+ If optional data exists it will be changed.
+
+ @param[in] Index The boot or driver option index update.
+ @param[in] DataSize The size in bytes of Data.
+ @param[in] Data The buffer for the optional data.
+ @param[in] Target The target of the operation.
+
+ @retval EFI_SUCCESS The data was successfully updated.
+ @retval other A error occurred.
+**/
+EFI_STATUS
+UpdateOptionalData (
+ UINT16 Index,
+ UINTN DataSize,
+ UINT8 *Data,
+ IN CONST BCFG_OPERATION_TARGET Target
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 VariableName[12];
+ UINTN OriginalSize;
+ UINT8 *OriginalData;
+ UINTN NewSize;
+ UINT8 *NewData;
+ UINTN OriginalOptionDataSize;
+
+ UnicodeSPrint (VariableName, sizeof (VariableName), L"%s%04x", Target == BcfgTargetBootOrder ? L"Boot" : L"Driver", Index);
+
+ OriginalSize = 0;
+ OriginalData = NULL;
+ NewData = NULL;
+ NewSize = 0;
+
+ Status = gRT->GetVariable (
+ VariableName,
+ (EFI_GUID *)&gEfiGlobalVariableGuid,
+ NULL,
+ &OriginalSize,
+ OriginalData
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ OriginalData = AllocateZeroPool (OriginalSize);
+ if (OriginalData == NULL) {
+ return (EFI_OUT_OF_RESOURCES);
+ }
+
+ Status = gRT->GetVariable (
+ VariableName,
+ (EFI_GUID *)&gEfiGlobalVariableGuid,
+ NULL,
+ &OriginalSize,
+ OriginalData
+ );
+ }
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Allocate new struct and discard old optional data.
+ //
+ ASSERT (OriginalData != NULL);
+ OriginalOptionDataSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (((CHAR16 *)(OriginalData + sizeof (UINT32) + sizeof (UINT16))));
+ OriginalOptionDataSize += (*(UINT16 *)(OriginalData + sizeof (UINT32)));
+ OriginalOptionDataSize -= OriginalSize;
+ NewSize = OriginalSize - OriginalOptionDataSize + DataSize;
+ NewData = AllocatePool (NewSize);
+ if (NewData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ CopyMem (NewData, OriginalData, OriginalSize - OriginalOptionDataSize);
+ CopyMem (NewData + OriginalSize - OriginalOptionDataSize, Data, DataSize);
+ }
+ }
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // put the data back under the variable
+ //
+ Status = gRT->SetVariable (
+ VariableName,
+ (EFI_GUID *)&gEfiGlobalVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
+ NewSize,
+ NewData
+ );
+ }
+
+ SHELL_FREE_NON_NULL (OriginalData);
+ SHELL_FREE_NON_NULL (NewData);
+ return (Status);
+}
+
+/**
+ This function will get a CRC for a boot option.
+
+ @param[in, out] Crc The CRC value to return.
+ @param[in] BootIndex The boot option index to CRC.
+
+ @retval EFI_SUCCESS The CRC was successfully returned.
+ @retval other A error occurred.
+**/
+EFI_STATUS
+GetBootOptionCrc (
+ UINT32 *Crc,
+ UINT16 BootIndex
+ )
+{
+ CHAR16 VariableName[12];
+ EFI_STATUS Status;
+ UINT8 *Buffer;
+ UINTN BufferSize;
+
+ Buffer = NULL;
+ BufferSize = 0;
+
+ //
+ // Get the data Buffer
+ //
+ UnicodeSPrint (VariableName, sizeof (VariableName), L"%Boot%04x", BootIndex);
+ Status = gRT->GetVariable (
+ VariableName,
+ (EFI_GUID *)&gEfiGlobalVariableGuid,
+ NULL,
+ &BufferSize,
+ NULL
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Buffer = AllocateZeroPool (BufferSize);
+ Status = gRT->GetVariable (
+ VariableName,
+ (EFI_GUID *)&gEfiGlobalVariableGuid,
+ NULL,
+ &BufferSize,
+ Buffer
+ );
+ }
+
+ //
+ // Get the CRC computed
+ //
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->CalculateCrc32 (Buffer, BufferSize, Crc);
+ }
+
+ SHELL_FREE_NON_NULL (Buffer);
+ return EFI_SUCCESS;
+}
+
+/**
+ This function will populate the device path protocol parameter based on TheHandle.
+
+ @param[in] TheHandle Driver handle.
+ @param[in, out] FilePath On a successful return the device path to the handle.
+
+ @retval EFI_SUCCESS The device path was successfully returned.
+ @retval other A error from gBS->HandleProtocol.
+
+ @sa HandleProtocol
+**/
+EFI_STATUS
+GetDevicePathForDriverHandle (
+ IN EFI_HANDLE TheHandle,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
+
+ Status = gBS->OpenProtocol (
+ TheHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **)&LoadedImage,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->OpenProtocol (
+ LoadedImage->DeviceHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **)&ImageDevicePath,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ // *DevPath = DuplicateDevicePath (ImageDevicePath);
+ // *FilePath = DuplicateDevicePath (LoadedImage->FilePath);
+ *FilePath = AppendDevicePath (ImageDevicePath, LoadedImage->FilePath);
+ gBS->CloseProtocol (
+ LoadedImage->DeviceHandle,
+ &gEfiDevicePathProtocolGuid,
+ gImageHandle,
+ NULL
+ );
+ }
+
+ gBS->CloseProtocol (
+ TheHandle,
+ &gEfiLoadedImageProtocolGuid,
+ gImageHandle,
+ NULL
+ );
+ }
+
+ return (Status);
+}
+
+/**
+ Function to get Device Path by a handle.
+
+ @param[in] TheHandle Use it to get DevicePath.
+ @param[in] Target Boot option target.
+ @param[in, out] DevicePath On a successful return the device path to the handle.
+
+ @retval SHELL_INVALID_PARAMETER The handle was NULL.
+ @retval SHELL_NOT_FOUND Not found device path by handle.
+ @retval SHELL_SUCCESS Get device path successfully.
+**/
+SHELL_STATUS
+GetDevicePathByHandle (
+ IN EFI_HANDLE TheHandle,
+ IN BCFG_OPERATION_TARGET Target,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
+ )
+{
+ EFI_STATUS Status;
+ SHELL_STATUS ShellStatus;
+
+ UINTN DriverBindingHandleCount;
+ UINTN ParentControllerHandleCount;
+ UINTN ChildControllerHandleCount;
+
+ ShellStatus = SHELL_SUCCESS;
+
+ if (TheHandle == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");
+ return SHELL_INVALID_PARAMETER;
+ }
+
+ Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (TheHandle, &DriverBindingHandleCount, NULL);
+ if (EFI_ERROR (Status)) {
+ DriverBindingHandleCount = 0;
+ }
+
+ Status = PARSE_HANDLE_DATABASE_PARENTS (TheHandle, &ParentControllerHandleCount, NULL);
+ if (EFI_ERROR (Status)) {
+ ParentControllerHandleCount = 0;
+ }
+
+ Status = ParseHandleDatabaseForChildControllers (TheHandle, &ChildControllerHandleCount, NULL);
+ if (EFI_ERROR (Status)) {
+ ChildControllerHandleCount = 0;
+ }
+
+ Status = gBS->HandleProtocol (TheHandle, &gEfiDevicePathProtocolGuid, (VOID **)DevicePath);
+
+ if ((DriverBindingHandleCount > 0) ||
+ (ParentControllerHandleCount > 0) ||
+ (ChildControllerHandleCount > 0) ||
+ !EFI_ERROR (Status)
+ )
+ {
+ //
+ // The handle points to a real controller which has a device path.
+ //
+ if (Target == BcfgTargetDriverOrder) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_PARAM_INV),
+ gShellBcfgHiiHandle,
+ L"bcfg",
+ L"Handle should point to driver image."
+ );
+ ShellStatus = SHELL_NOT_FOUND;
+ }
+ } else {
+ //
+ // The handle points to a driver image.
+ //
+ if (Target == BcfgTargetBootOrder) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_PARAM_INV),
+ gShellBcfgHiiHandle,
+ L"bcfg",
+ L"Handle should point to controller."
+ );
+ ShellStatus = SHELL_NOT_FOUND;
+ } else {
+ if (EFI_ERROR (GetDevicePathForDriverHandle (TheHandle, DevicePath))) {
+ ShellStatus = SHELL_NOT_FOUND;
+ }
+ }
+ }
+
+ return (ShellStatus);
+}
+
+/**
+ Function to modify an option.
+
+ @param[in] BcfgOperation Pointer to BCFG operation.
+ @param[in] OrderCount The number if items in CurrentOrder.
+
+ @retval SHELL_SUCCESS The operation was successful.
+ @retval SHELL_INVALID_PARAMETER A parameter was invalid.
+ @retval SHELL_OUT_OF_RESOUCES A memory allocation failed.
+**/
+SHELL_STATUS
+BcfgMod (
+ IN CONST BGFG_OPERATION *BcfgOperation,
+ IN CONST UINTN OrderCount
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE CurHandle;
+ SHELL_STATUS ShellStatus;
+ CHAR16 OptionStr[40];
+ EFI_SHELL_FILE_INFO *FileList;
+ EFI_SHELL_FILE_INFO *Arg;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathBuffer;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathWalker;
+ EFI_BOOT_MANAGER_LOAD_OPTION LoadOption;
+
+ ShellStatus = SHELL_SUCCESS;
+ FileList = NULL;
+ DevicePath = NULL;
+ DevicePathBuffer = NULL;
+
+ ZeroMem (&LoadOption, sizeof (EFI_BOOT_MANAGER_LOAD_OPTION));
+
+ if (((BcfgOperation->Type == BcfgTypeMod) && (BcfgOperation->Description == NULL)) ||
+ ((BcfgOperation->Type == BcfgTypeModf) && (BcfgOperation->FileName == NULL)) ||
+ ((BcfgOperation->Type == BcfgTypeModp) && (BcfgOperation->FileName == NULL)) ||
+ ((BcfgOperation->Type == BcfgTypeModh) && (BcfgOperation->HandleIndex == 0)) ||
+ (BcfgOperation->Number1 > OrderCount)
+ )
+ {
+ return (SHELL_INVALID_PARAMETER);
+ }
+
+ if (BcfgOperation->Type == BcfgTypeModh) {
+ CurHandle = ConvertHandleIndexToHandle (BcfgOperation->HandleIndex);
+ ShellStatus = GetDevicePathByHandle (CurHandle, BcfgOperation->Target, &DevicePathBuffer);
+ if (ShellStatus == SHELL_SUCCESS) {
+ DevicePath = DuplicateDevicePath (DevicePathBuffer);
+ }
+ } else if ((BcfgOperation->Type == BcfgTypeModf) || (BcfgOperation->Type == BcfgTypeModp)) {
+ //
+ // Get Device Path by FileName.
+ //
+ ShellOpenFileMetaArg ((CHAR16 *)BcfgOperation->FileName, EFI_FILE_MODE_READ, &FileList);
+ if (FileList == NULL) {
+ //
+ // The name of file matched nothing.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else if (FileList->Link.ForwardLink != FileList->Link.BackLink) {
+ //
+ // If the name of file expanded to multiple names, it's fail.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Arg = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link);
+ if (EFI_ERROR (Arg->Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ DevicePathBuffer = gEfiShellProtocol->GetDevicePathFromFilePath (Arg->FullName);
+ if (DevicePathBuffer == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellBcfgHiiHandle, L"bcfg", Arg->FullName);
+ ShellStatus = SHELL_UNSUPPORTED;
+ }
+ }
+ }
+
+ if (ShellStatus == SHELL_SUCCESS) {
+ if (BcfgOperation->Type == BcfgTypeModp) {
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ DevicePathWalker = DevicePathBuffer;
+ while (!IsDevicePathEnd (DevicePathWalker)) {
+ if ((DevicePathType (DevicePathWalker) == MEDIA_DEVICE_PATH) &&
+ (DevicePathSubType (DevicePathWalker) == MEDIA_HARDDRIVE_DP)
+ )
+ {
+ //
+ // We found the portion of device path starting with the hard driver partition.
+ //
+ ShellStatus = SHELL_SUCCESS;
+ DevicePath = DuplicateDevicePath (DevicePathWalker);
+ break;
+ } else {
+ DevicePathWalker = NextDevicePathNode (DevicePathWalker);
+ }
+ }
+ } else {
+ DevicePath = DuplicateDevicePath (DevicePathBuffer);
+ }
+
+ FreePool (DevicePathBuffer);
+ }
+ }
+
+ if (ShellStatus == SHELL_SUCCESS) {
+ if (BcfgOperation->Target == BcfgTargetBootOrder) {
+ UnicodeSPrint (OptionStr, sizeof (OptionStr), L"Boot%04x", BcfgOperation->Order[BcfgOperation->Number1]);
+ } else {
+ UnicodeSPrint (OptionStr, sizeof (OptionStr), L"Driver%04x", BcfgOperation->Order[BcfgOperation->Number1]);
+ }
+
+ Status = EfiBootManagerVariableToLoadOption (OptionStr, &LoadOption);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NONE), gShellBcfgHiiHandle);
+ ShellStatus = SHELL_NOT_FOUND;
+ }
+ }
+
+ if (ShellStatus == SHELL_SUCCESS) {
+ if (BcfgOperation->Type == BcfgTypeMod) {
+ SHELL_FREE_NON_NULL (LoadOption.Description);
+ LoadOption.Description = AllocateCopyPool (StrSize (BcfgOperation->Description), BcfgOperation->Description);
+ } else {
+ SHELL_FREE_NON_NULL (LoadOption.FilePath);
+ LoadOption.FilePath = DuplicateDevicePath (DevicePath);
+ }
+
+ Status = EfiBootManagerLoadOptionToVariable (&LoadOption);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", OptionStr);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+ }
+
+ EfiBootManagerFreeLoadOption (&LoadOption);
+
+ if (DevicePath != NULL) {
+ FreePool (DevicePath);
+ }
+
+ if (FileList != NULL) {
+ ShellCloseFileMetaArg (&FileList);
+ }
+
+ return (ShellStatus);
+}
+
+/**
+ Function to add a option.
+
+ @param[in] Position The position to add Target at.
+ @param[in] File The file to make the target.
+ @param[in] Desc The description text.
+ @param[in] CurrentOrder The pointer to the current order of items.
+ @param[in] OrderCount The number if items in CurrentOrder.
+ @param[in] Target The info on the option to add.
+ @param[in] UseHandle TRUE to use HandleNumber, FALSE to use File and Desc.
+ @param[in] UsePath TRUE to convert to devicepath.
+ @param[in] HandleNumber The handle number to add.
+
+ @retval SHELL_SUCCESS The operation was successful.
+ @retval SHELL_INVALID_PARAMETER A parameter was invalid.
+**/
+SHELL_STATUS
+BcfgAdd (
+ IN UINTN Position,
+ IN CONST CHAR16 *File,
+ IN CONST CHAR16 *Desc,
+ IN CONST UINT16 *CurrentOrder,
+ IN CONST UINTN OrderCount,
+ IN CONST BCFG_OPERATION_TARGET Target,
+ IN CONST BOOLEAN UseHandle,
+ IN CONST BOOLEAN UsePath,
+ IN CONST UINTN HandleNumber
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+ EFI_DEVICE_PATH_PROTOCOL *FilePath;
+ CHAR16 *Str;
+ UINT8 *TempByteBuffer;
+ UINT8 *TempByteStart;
+ EFI_SHELL_FILE_INFO *Arg;
+ EFI_SHELL_FILE_INFO *FileList;
+ CHAR16 OptionStr[40];
+ UINTN DescSize, FilePathSize;
+ BOOLEAN Found;
+ UINTN TargetLocation;
+ UINTN Index;
+ EFI_HANDLE *Handles;
+ EFI_HANDLE CurHandle;
+ UINTN DriverBindingHandleCount;
+ UINTN ParentControllerHandleCount;
+ UINTN ChildControllerHandleCount;
+ SHELL_STATUS ShellStatus;
+ UINT16 *NewOrder;
+
+ if (!UseHandle) {
+ if ((File == NULL) || (Desc == NULL)) {
+ return (SHELL_INVALID_PARAMETER);
+ }
+ } else {
+ if (HandleNumber == 0) {
+ return (SHELL_INVALID_PARAMETER);
+ }
+ }
+
+ if (Position > OrderCount) {
+ Position = OrderCount;
+ }
+
+ Str = NULL;
+ FilePath = NULL;
+ FileList = NULL;
+ Handles = NULL;
+ ShellStatus = SHELL_SUCCESS;
+ TargetLocation = 0xFFFF;
+
+ if (UseHandle) {
+ CurHandle = ConvertHandleIndexToHandle (HandleNumber);
+ if (CurHandle == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ if (Target == BcfgTargetBootOrder) {
+ //
+ // Make sure that the handle should point to a real controller
+ //
+ Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
+ CurHandle,
+ &DriverBindingHandleCount,
+ NULL
+ );
+
+ Status = PARSE_HANDLE_DATABASE_PARENTS (
+ CurHandle,
+ &ParentControllerHandleCount,
+ NULL
+ );
+
+ Status = ParseHandleDatabaseForChildControllers (
+ CurHandle,
+ &ChildControllerHandleCount,
+ NULL
+ );
+
+ if ( (DriverBindingHandleCount > 0)
+ || (ParentControllerHandleCount > 0)
+ || (ChildControllerHandleCount > 0))
+ {
+ FilePath = NULL;
+ Status = gBS->HandleProtocol (
+ CurHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **)&FilePath
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_HANDLE), gShellBcfgHiiHandle, L"bcfg", HandleNumber);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+ } else {
+ //
+ // Make sure that the handle should point to driver, not a controller.
+ //
+ Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
+ CurHandle,
+ &DriverBindingHandleCount,
+ NULL
+ );
+
+ Status = PARSE_HANDLE_DATABASE_PARENTS (
+ CurHandle,
+ &ParentControllerHandleCount,
+ NULL
+ );
+
+ Status = ParseHandleDatabaseForChildControllers (
+ CurHandle,
+ &ChildControllerHandleCount,
+ NULL
+ );
+
+ Status = gBS->HandleProtocol (
+ CurHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **)&FilePath
+ );
+
+ if ( (DriverBindingHandleCount > 0)
+ || (ParentControllerHandleCount > 0)
+ || (ChildControllerHandleCount > 0)
+ || !EFI_ERROR (Status))
+ {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ //
+ // Get the DevicePath from the loaded image information.
+ //
+ Status = GetDevicePathForDriverHandle (CurHandle, &FilePath);
+ }
+ }
+ }
+ } else {
+ //
+ // Get file info
+ //
+ ShellOpenFileMetaArg ((CHAR16 *)File, EFI_FILE_MODE_READ, &FileList);
+
+ if (FileList == NULL) {
+ //
+ // If filename matched nothing fail
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellBcfgHiiHandle, L"bcfg", File);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else if (FileList->Link.ForwardLink != FileList->Link.BackLink) {
+ //
+ // If filename expanded to multiple names, fail
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellBcfgHiiHandle, L"bcfg", File);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Arg = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link);
+ if (EFI_ERROR (Arg->Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellBcfgHiiHandle, L"bcfg", File);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ //
+ // Build FilePath to the filename
+ //
+
+ //
+ // get the device path
+ //
+ DevicePath = gEfiShellProtocol->GetDevicePathFromFilePath (Arg->FullName);
+ if (DevicePath == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellBcfgHiiHandle, L"bcfg", Arg->FullName);
+ ShellStatus = SHELL_UNSUPPORTED;
+ } else {
+ if (UsePath) {
+ DevPath = DevicePath;
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ while (!IsDevicePathEnd (DevPath)) {
+ if ((DevicePathType (DevPath) == MEDIA_DEVICE_PATH) &&
+ (DevicePathSubType (DevPath) == MEDIA_HARDDRIVE_DP))
+ {
+ //
+ // If we find it use it instead
+ //
+ ShellStatus = SHELL_SUCCESS;
+ FilePath = DuplicateDevicePath (DevPath);
+ break;
+ }
+
+ DevPath = NextDevicePathNode (DevPath);
+ }
+ } else {
+ FilePath = DuplicateDevicePath (DevicePath);
+ }
+
+ FreePool (DevicePath);
+ }
+ }
+ }
+ }
+
+ if (ShellStatus == SHELL_SUCCESS) {
+ //
+ // Find a free target ,a brute force implementation
+ //
+ Found = FALSE;
+ for (TargetLocation = 0; TargetLocation < 0xFFFF; TargetLocation++) {
+ Found = TRUE;
+ for (Index = 0; Index < OrderCount; Index++) {
+ if (CurrentOrder[Index] == TargetLocation) {
+ Found = FALSE;
+ break;
+ }
+ }
+
+ if (Found) {
+ break;
+ }
+ }
+
+ if (TargetLocation == 0xFFFF) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET_NF), gShellBcfgHiiHandle, L"bcfg");
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET), gShellBcfgHiiHandle, TargetLocation);
+ }
+ }
+
+ if (ShellStatus == SHELL_SUCCESS) {
+ //
+ // Add the option
+ //
+ DescSize = StrSize (Desc);
+ FilePathSize = GetDevicePathSize (FilePath);
+
+ TempByteBuffer = AllocateZeroPool (sizeof (UINT32) + sizeof (UINT16) + DescSize + FilePathSize);
+ if (TempByteBuffer != NULL) {
+ TempByteStart = TempByteBuffer;
+ *((UINT32 *)TempByteBuffer) = LOAD_OPTION_ACTIVE; // Attributes
+ TempByteBuffer += sizeof (UINT32);
+
+ *((UINT16 *)TempByteBuffer) = (UINT16)FilePathSize; // FilePathListLength
+ TempByteBuffer += sizeof (UINT16);
+
+ CopyMem (TempByteBuffer, Desc, DescSize);
+ TempByteBuffer += DescSize;
+ ASSERT (FilePath != NULL);
+ CopyMem (TempByteBuffer, FilePath, FilePathSize);
+
+ UnicodeSPrint (OptionStr, sizeof (OptionStr), L"%s%04x", Target == BcfgTargetBootOrder ? L"Boot" : L"Driver", TargetLocation);
+ Status = gRT->SetVariable (
+ OptionStr,
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof (UINT32) + sizeof (UINT16) + DescSize + FilePathSize,
+ TempByteStart
+ );
+
+ FreePool (TempByteStart);
+ } else {
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", OptionStr);
+ } else {
+ NewOrder = AllocateZeroPool ((OrderCount + 1) * sizeof (NewOrder[0]));
+ if (NewOrder != NULL) {
+ CopyMem (NewOrder, CurrentOrder, (OrderCount) * sizeof (NewOrder[0]));
+
+ //
+ // Insert target into order list
+ //
+ for (Index = OrderCount; Index > Position; Index--) {
+ NewOrder[Index] = NewOrder[Index - 1];
+ }
+
+ NewOrder[Position] = (UINT16)TargetLocation;
+ Status = gRT->SetVariable (
+ Target == BcfgTargetBootOrder ? L"BootOrder" : L"DriverOrder",
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ (OrderCount + 1) * sizeof (UINT16),
+ NewOrder
+ );
+
+ FreePool (NewOrder);
+
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder ? L"BootOrder" : L"DriverOrder");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Print (L"bcfg: Add %s as %x\n", OptionStr, Position);
+ }
+ }
+ }
+ }
+
+ //
+ // If always Free FilePath, will free devicepath in system when use "addh"
+ //
+ if ((FilePath != NULL) && !UseHandle) {
+ FreePool (FilePath);
+ }
+
+ if (Str != NULL) {
+ FreePool (Str);
+ }
+
+ if (Handles != NULL) {
+ FreePool (Handles);
+ }
+
+ if (FileList != NULL) {
+ ShellCloseFileMetaArg (&FileList);
+ }
+
+ return (ShellStatus);
+}
+
+/**
+ Function to remove an item.
+
+ @param[in] Target The target item to move.
+ @param[in] CurrentOrder The pointer to the current order of items.
+ @param[in] OrderCount The number if items in CurrentOrder.
+ @param[in] Location The current location of the Target.
+
+ @retval SHELL_SUCCESS The operation was successful.
+ @retval SHELL_INVALID_PARAMETER A parameter was invalid.
+**/
+SHELL_STATUS
+BcfgRemove (
+ IN CONST BCFG_OPERATION_TARGET Target,
+ IN CONST UINT16 *CurrentOrder,
+ IN CONST UINTN OrderCount,
+ IN CONST UINT16 Location
+ )
+{
+ CHAR16 VariableName[12];
+ UINT16 *NewOrder;
+ EFI_STATUS Status;
+ UINTN NewCount;
+
+ UnicodeSPrint (VariableName, sizeof (VariableName), L"%s%04x", Target == BcfgTargetBootOrder ? L"Boot" : L"Driver", CurrentOrder[Location]);
+ Status = gRT->SetVariable (
+ VariableName,
+ (EFI_GUID *)&gEfiGlobalVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
+ 0,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
+ return (SHELL_INVALID_PARAMETER);
+ }
+
+ NewOrder = AllocateZeroPool (OrderCount*sizeof (CurrentOrder[0]));
+ if (NewOrder != NULL) {
+ NewCount = OrderCount;
+ CopyMem (NewOrder, CurrentOrder, OrderCount*sizeof (CurrentOrder[0]));
+ CopyMem (NewOrder+Location, NewOrder+Location+1, (OrderCount - Location - 1)*sizeof (CurrentOrder[0]));
+ NewCount--;
+
+ Status = gRT->SetVariable (
+ Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder",
+ (EFI_GUID *)&gEfiGlobalVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
+ NewCount*sizeof (NewOrder[0]),
+ NewOrder
+ );
+ FreePool (NewOrder);
+ } else {
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder");
+ return (SHELL_INVALID_PARAMETER);
+ }
+
+ return (SHELL_SUCCESS);
+}
+
+/**
+ Function to move a item to another location.
+
+ @param[in] Target The target item to move.
+ @param[in] CurrentOrder The pointer to the current order of items.
+ @param[in] OrderCount The number if items in CurrentOrder.
+ @param[in] OldLocation The current location of the Target.
+ @param[in] NewLocation The desired location of the Target.
+
+ @retval SHELL_SUCCESS The operation was successful.
+ @retval SHELL_INVALID_PARAMETER A parameter was invalid.
+**/
+SHELL_STATUS
+BcfgMove (
+ IN CONST BCFG_OPERATION_TARGET Target,
+ IN CONST UINT16 *CurrentOrder,
+ IN CONST UINTN OrderCount,
+ IN CONST UINT16 OldLocation,
+ IN UINT16 NewLocation
+ )
+{
+ UINT16 *NewOrder;
+ EFI_STATUS Status;
+ UINT16 Temp;
+
+ NewOrder = AllocateCopyPool (OrderCount*sizeof (CurrentOrder[0]), CurrentOrder);
+ if (NewOrder == NULL) {
+ return (SHELL_OUT_OF_RESOURCES);
+ }
+
+ //
+ // correct the new location
+ //
+ if (NewLocation >= OrderCount) {
+ if (OrderCount > 0) {
+ NewLocation = (UINT16)OrderCount - 1;
+ } else {
+ NewLocation = 0;
+ }
+ }
+
+ Temp = CurrentOrder[OldLocation];
+ CopyMem (NewOrder+OldLocation, NewOrder+OldLocation+1, (OrderCount - OldLocation - 1)*sizeof (CurrentOrder[0]));
+ CopyMem (NewOrder+NewLocation+1, NewOrder+NewLocation, (OrderCount - NewLocation - 1)*sizeof (CurrentOrder[0]));
+ NewOrder[NewLocation] = Temp;
+
+ Status = gRT->SetVariable (
+ Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder",
+ (EFI_GUID *)&gEfiGlobalVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
+ OrderCount*sizeof (CurrentOrder[0]),
+ NewOrder
+ );
+
+ FreePool (NewOrder);
+
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder");
+ return (SHELL_INVALID_PARAMETER);
+ }
+
+ return (SHELL_SUCCESS);
+}
+
+/**
+ Function to add optional data to an option.
+
+ @param[in] OptData The optional data to add.
+ @param[in] CurrentOrder The pointer to the current order of items.
+ @param[in] OrderCount The number if items in CurrentOrder.
+ @param[in] Target The target of the operation.
+
+ @retval SHELL_SUCCESS The operation was succesful.
+**/
+SHELL_STATUS
+BcfgAddOpt (
+ IN CONST CHAR16 *OptData,
+ IN CONST UINT16 *CurrentOrder,
+ IN CONST UINTN OrderCount,
+ IN CONST BCFG_OPERATION_TARGET Target
+ )
+{
+ EFI_KEY_OPTION NewKeyOption;
+ EFI_KEY_OPTION *KeyOptionBuffer;
+ SHELL_STATUS ShellStatus;
+ EFI_STATUS Status;
+ UINT16 OptionIndex;
+ UINT16 LoopCounter;
+ UINT64 Intermediate;
+ CONST CHAR16 *Temp;
+ CONST CHAR16 *Walker;
+ CHAR16 *FileName;
+ CHAR16 *Temp2;
+ CHAR16 *Data;
+ UINT32 KeyIndex;
+ CHAR16 VariableName[12];
+ VOID *VariableData;
+
+ SHELL_FILE_HANDLE FileHandle;
+
+ Status = EFI_SUCCESS;
+ ShellStatus = SHELL_SUCCESS;
+ Walker = OptData;
+ FileName = NULL;
+ Data = NULL;
+ KeyOptionBuffer = NULL;
+ VariableData = NULL;
+
+ ZeroMem (&NewKeyOption, sizeof (EFI_KEY_OPTION));
+ ZeroMem (VariableName, sizeof (VariableName));
+
+ while (Walker[0] == L' ') {
+ Walker++;
+ }
+
+ //
+ // Get the index of the variable we are changing.
+ //
+ Status = ShellConvertStringToUint64 (Walker, &Intermediate, TRUE, TRUE);
+ if (EFI_ERROR (Status) || (((UINT16)Intermediate) != Intermediate) || (StrStr (Walker, L" ") == NULL) || (((UINT16)Intermediate) > ((UINT16)OrderCount))) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Option Index");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ return (ShellStatus);
+ }
+
+ OptionIndex = (UINT16)Intermediate;
+
+ Temp = StrStr (Walker, L" ");
+ if (Temp != NULL) {
+ Walker = Temp;
+ }
+
+ while (Walker[0] == L' ') {
+ Walker++;
+ }
+
+ //
+ // determine whether we have file with data, quote delimited information, or a hot-key
+ //
+ if (Walker[0] == L'\"') {
+ //
+ // quoted filename or quoted information.
+ //
+ Temp = StrStr (Walker+1, L"\"");
+ if ((Temp == NULL) || (StrLen (Temp) != 1)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ FileName = StrnCatGrow (&FileName, NULL, Walker+1, 0);
+ if (FileName == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellBcfgHiiHandle, L"bcfg");
+ ShellStatus = SHELL_OUT_OF_RESOURCES;
+ return (ShellStatus);
+ }
+
+ Temp2 = StrStr (FileName, L"\"");
+ ASSERT (Temp2 != NULL);
+ Temp2[0] = CHAR_NULL;
+ Temp2++;
+ if (StrLen (Temp2) > 0) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+
+ if (EFI_ERROR (ShellFileExists (Walker))) {
+ //
+ // Not a file. must be misc information.
+ //
+ Data = FileName;
+ FileName = NULL;
+ } else {
+ FileName = StrnCatGrow (&FileName, NULL, Walker, 0);
+ }
+ }
+ } else {
+ //
+ // filename or hot key information.
+ //
+ if (StrStr (Walker, L" ") == NULL) {
+ //
+ // filename
+ //
+ if (EFI_ERROR (ShellFileExists (Walker))) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FIND_FAIL), gShellBcfgHiiHandle, L"bcfg", Walker);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ FileName = StrnCatGrow (&FileName, NULL, Walker, 0);
+ }
+ } else {
+ if (Target != BcfgTargetBootOrder) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_BOOT_ONLY), gShellBcfgHiiHandle, L"bcfg");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+
+ if (ShellStatus == SHELL_SUCCESS) {
+ //
+ // Get hot key information
+ //
+ Status = ShellConvertStringToUint64 (Walker, &Intermediate, FALSE, TRUE);
+ if (EFI_ERROR (Status) || (((UINT32)Intermediate) != Intermediate) || (StrStr (Walker, L" ") == NULL)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+
+ NewKeyOption.KeyData.PackedValue = (UINT32)Intermediate;
+ Temp = StrStr (Walker, L" ");
+ if (Temp != NULL) {
+ Walker = Temp;
+ }
+
+ while (Walker[0] == L' ') {
+ Walker++;
+ }
+ }
+
+ if (ShellStatus == SHELL_SUCCESS) {
+ //
+ // Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.
+ // Re-allocate with the added information.
+ //
+ KeyOptionBuffer = AllocatePool (sizeof (EFI_KEY_OPTION) + (sizeof (EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount));
+ if (KeyOptionBuffer == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellBcfgHiiHandle, L"bcfg");
+ ShellStatus = SHELL_OUT_OF_RESOURCES;
+ return ShellStatus;
+ }
+
+ CopyMem (KeyOptionBuffer, &NewKeyOption, sizeof (EFI_KEY_OPTION));
+ }
+
+ for (LoopCounter = 0; ShellStatus == SHELL_SUCCESS && LoopCounter < NewKeyOption.KeyData.Options.InputKeyCount; LoopCounter++) {
+ //
+ // ScanCode
+ //
+ Status = ShellConvertStringToUint64 (Walker, &Intermediate, FALSE, TRUE);
+ if (EFI_ERROR (Status) || (((UINT16)Intermediate) != Intermediate) || (StrStr (Walker, L" ") == NULL)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+
+ ((EFI_INPUT_KEY *)(((UINT8 *)KeyOptionBuffer) + sizeof (EFI_KEY_OPTION)))[LoopCounter].ScanCode = (UINT16)Intermediate;
+ Temp = StrStr (Walker, L" ");
+ if (Temp != NULL) {
+ Walker = Temp;
+ }
+
+ while (Walker[0] == L' ') {
+ Walker++;
+ }
+
+ //
+ // UnicodeChar
+ //
+ Status = ShellConvertStringToUint64 (Walker, &Intermediate, FALSE, TRUE);
+ if (EFI_ERROR (Status) || (((UINT16)Intermediate) != Intermediate)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+
+ ((EFI_INPUT_KEY *)(((UINT8 *)KeyOptionBuffer) + sizeof (EFI_KEY_OPTION)))[LoopCounter].UnicodeChar = (UINT16)Intermediate;
+ Temp = StrStr (Walker, L" ");
+ if (Temp != NULL) {
+ Walker = Temp;
+ }
+
+ while (Walker[0] == L' ') {
+ Walker++;
+ }
+ }
+
+ if (ShellStatus == SHELL_SUCCESS) {
+ //
+ // Now do the BootOption / BootOptionCrc
+ //
+ ASSERT (OptionIndex <= OrderCount);
+ KeyOptionBuffer->BootOption = CurrentOrder[OptionIndex];
+ Status = GetBootOptionCrc (&(KeyOptionBuffer->BootOptionCrc), KeyOptionBuffer->BootOption);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Option Index");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+ }
+
+ if (ShellStatus == SHELL_SUCCESS) {
+ for (Temp2 = NULL, KeyIndex = 0; KeyIndex <= 0xFFFF; KeyIndex++) {
+ UnicodeSPrint (VariableName, sizeof (VariableName), L"Key%04x", KeyIndex);
+ Status = GetEfiGlobalVariable2 (VariableName, &VariableData, NULL);
+ if (Status == EFI_NOT_FOUND) {
+ break;
+ }
+
+ if (!EFI_ERROR (Status)) {
+ SHELL_FREE_NON_NULL (VariableData);
+ }
+ }
+
+ if (KeyIndex <= 0xFFFF) {
+ Status = gRT->SetVariable (
+ VariableName,
+ (EFI_GUID *)&gEfiGlobalVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof (EFI_KEY_OPTION) + (sizeof (EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount),
+ KeyOptionBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_VAR_NO_NUM), gShellBcfgHiiHandle, L"bcfg");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+
+ ASSERT (FileName == NULL && Data == NULL);
+ }
+ }
+ }
+
+ //
+ // Shouldn't be possible to have have both. Neither is ok though.
+ //
+ ASSERT (FileName == NULL || Data == NULL);
+
+ if ((ShellStatus == SHELL_SUCCESS) && ((FileName != NULL) || (Data != NULL))) {
+ if (FileName != NULL) {
+ //
+ // Open the file and populate the data buffer.
+ //
+ Status = ShellOpenFileByName (
+ FileName,
+ &FileHandle,
+ EFI_FILE_MODE_READ,
+ 0
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = ShellGetFileSize (FileHandle, &Intermediate);
+ }
+
+ Data = AllocateZeroPool ((UINTN)Intermediate);
+ if (Data == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellBcfgHiiHandle, L"bcfg");
+ ShellStatus = SHELL_OUT_OF_RESOURCES;
+ }
+
+ if (!EFI_ERROR (Status)) {
+ Status = ShellReadFile (FileHandle, (UINTN *)&Intermediate, Data);
+ }
+ } else {
+ Intermediate = StrSize (Data);
+ }
+
+ if (!EFI_ERROR (Status) && (ShellStatus == SHELL_SUCCESS) && (Data != NULL)) {
+ Status = UpdateOptionalData (CurrentOrder[OptionIndex], (UINTN)Intermediate, (UINT8 *)Data, Target);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+ }
+
+ if (EFI_ERROR (Status) && (ShellStatus == SHELL_SUCCESS)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+ }
+
+ SHELL_FREE_NON_NULL (Data);
+ SHELL_FREE_NON_NULL (KeyOptionBuffer);
+ SHELL_FREE_NON_NULL (FileName);
+ return ShellStatus;
+}
+
+/**
+ Function to dump the Bcfg information.
+
+ @param[in] Op The operation.
+ @param[in] OrderCount How many to dump.
+ @param[in] CurrentOrder The pointer to the current order of items.
+ @param[in] VerboseOutput TRUE for extra output. FALSE otherwise.
+
+ @retval SHELL_SUCCESS The dump was successful.
+ @retval SHELL_INVALID_PARAMETER A parameter was invalid.
+**/
+SHELL_STATUS
+BcfgDisplayDump (
+ IN CONST CHAR16 *Op,
+ IN CONST UINTN OrderCount,
+ IN CONST UINT16 *CurrentOrder,
+ IN CONST BOOLEAN VerboseOutput
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *Buffer;
+ UINTN BufferSize;
+ CHAR16 VariableName[12];
+ UINTN LoopVar;
+ CHAR16 *DevPathString;
+ VOID *FilePathList;
+ UINTN Errors;
+ EFI_LOAD_OPTION *LoadOption;
+ CHAR16 *Description;
+ UINTN DescriptionSize;
+ UINTN OptionalDataOffset;
+
+ if (OrderCount == 0) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NONE), gShellBcfgHiiHandle, L"bcfg");
+ return (SHELL_SUCCESS);
+ }
+
+ Errors = 0;
+
+ for (LoopVar = 0; LoopVar < OrderCount; LoopVar++) {
+ Buffer = NULL;
+ BufferSize = 0;
+ DevPathString = NULL;
+
+ UnicodeSPrint (VariableName, sizeof (VariableName), L"%s%04x", Op, CurrentOrder[LoopVar]);
+
+ Status = gRT->GetVariable (
+ VariableName,
+ (EFI_GUID *)&gEfiGlobalVariableGuid,
+ NULL,
+ &BufferSize,
+ Buffer
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Buffer = AllocateZeroPool (BufferSize);
+ Status = gRT->GetVariable (
+ VariableName,
+ (EFI_GUID *)&gEfiGlobalVariableGuid,
+ NULL,
+ &BufferSize,
+ Buffer
+ );
+ }
+
+ if (EFI_ERROR (Status) || (Buffer == NULL)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_READ_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
+ ++Errors;
+ goto Cleanup;
+ }
+
+ //
+ // We expect the Attributes, FilePathListLength, and L'\0'-terminated
+ // Description fields to be present.
+ //
+ if (BufferSize < sizeof *LoadOption + sizeof (CHAR16)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_BCFG_VAR_CORRUPT),
+ gShellBcfgHiiHandle,
+ L"bcfg",
+ VariableName
+ );
+ ++Errors;
+ goto Cleanup;
+ }
+
+ LoadOption = (EFI_LOAD_OPTION *)Buffer;
+ Description = (CHAR16 *)(Buffer + sizeof (EFI_LOAD_OPTION));
+ DescriptionSize = StrSize (Description);
+
+ if (LoadOption->FilePathListLength != 0) {
+ FilePathList = (UINT8 *)Description + DescriptionSize;
+ DevPathString = ConvertDevicePathToText (FilePathList, TRUE, FALSE);
+ }
+
+ OptionalDataOffset = sizeof *LoadOption + DescriptionSize +
+ LoadOption->FilePathListLength;
+
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_BCFG_LOAD_OPTIONS),
+ gShellBcfgHiiHandle,
+ LoopVar,
+ VariableName,
+ Description,
+ DevPathString,
+ OptionalDataOffset >= BufferSize ? L'N' : L'Y'
+ );
+ if (VerboseOutput && (OptionalDataOffset < BufferSize)) {
+ DumpHex (
+ 2, // Indent
+ 0, // Offset (displayed)
+ BufferSize - OptionalDataOffset, // DataSize
+ Buffer + OptionalDataOffset // UserData
+ );
+ }
+
+Cleanup:
+ if (Buffer != NULL) {
+ FreePool (Buffer);
+ }
+
+ if (DevPathString != NULL) {
+ FreePool (DevPathString);
+ }
+ }
+
+ return (Errors > 0) ? SHELL_INVALID_PARAMETER : SHELL_SUCCESS;
+}
+
+/**
+ Function to initialize the BCFG operation structure.
+
+ @param[in] Struct The stuct to initialize.
+**/
+VOID
+InitBcfgStruct (
+ IN BGFG_OPERATION *Struct
+ )
+{
+ ASSERT (Struct != NULL);
+ Struct->Target = BcfgTargetMax;
+ Struct->Type = BcfgTypeMax;
+ Struct->Number1 = 0;
+ Struct->Number2 = 0;
+ Struct->HandleIndex = 0;
+ Struct->FileName = NULL;
+ Struct->Description = NULL;
+ Struct->Order = NULL;
+ Struct->OptData = NULL;
+}
+
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
+ { L"-v", TypeFlag },
+ { L"-opt", TypeMaxValue },
+ { NULL, TypeMax }
+};
+
+/**
+ Function for 'bcfg' command.
+
+ @param[in] ImageHandle Handle to the Image (NULL if Internal).
+ @param[in] SystemTable Pointer to the System Table (NULL if Internal).
+**/
+SHELL_STATUS
+EFIAPI
+ShellCommandRunBcfg (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ LIST_ENTRY *Package;
+ CHAR16 *ProblemParam;
+ SHELL_STATUS ShellStatus;
+ UINTN ParamNumber;
+ CONST CHAR16 *CurrentParam;
+ BGFG_OPERATION CurrentOperation;
+ UINTN Length;
+ UINT64 Intermediate;
+ UINT16 Count;
+
+ Length = 0;
+ ProblemParam = NULL;
+ Package = NULL;
+ ShellStatus = SHELL_SUCCESS;
+
+ InitBcfgStruct (&CurrentOperation);
+
+ //
+ // initialize the shell lib (we must be in non-auto-init...)
+ //
+ Status = ShellInitialize ();
+ ASSERT_EFI_ERROR (Status);
+
+ Status = CommandInit ();
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // parse the command line
+ //
+ Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
+ if (EFI_ERROR (Status)) {
+ if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellBcfgHiiHandle, L"bcfg", ProblemParam);
+ FreePool (ProblemParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ ASSERT (FALSE);
+ }
+ } else {
+ //
+ // Read in if we are doing -OPT
+ //
+ if (ShellCommandLineGetFlag (Package, L"-opt")) {
+ CurrentOperation.OptData = ShellCommandLineGetValue (Package, L"-opt");
+ if (CurrentOperation.OptData == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellBcfgHiiHandle, L"bcfg", L"-opt");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+
+ CurrentOperation.Type = BcfgTypeOpt;
+ }
+
+ //
+ // small block to read the target of the operation
+ //
+ if (((ShellCommandLineGetCount (Package) < 3) && (CurrentOperation.Type != BcfgTypeOpt)) ||
+ ((ShellCommandLineGetCount (Package) < 2) && (CurrentOperation.Type == BcfgTypeOpt))
+ )
+ {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)ShellCommandLineGetRawValue (Package, 1), L"driver") == 0) {
+ CurrentOperation.Target = BcfgTargetDriverOrder;
+ } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)ShellCommandLineGetRawValue (Package, 1), L"boot") == 0) {
+ CurrentOperation.Target = BcfgTargetBootOrder;
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT), gShellBcfgHiiHandle, L"bcfg");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+
+ //
+ // Read in the boot or driver order environment variable (not needed for opt)
+ //
+ if ((ShellStatus == SHELL_SUCCESS) && (CurrentOperation.Target < BcfgTargetMax)) {
+ Length = 0;
+ Status = gRT->GetVariable (
+ CurrentOperation.Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder",
+ (EFI_GUID *)&gEfiGlobalVariableGuid,
+ NULL,
+ &Length,
+ CurrentOperation.Order
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ CurrentOperation.Order = AllocateZeroPool (Length+(4*sizeof (CurrentOperation.Order[0])));
+ if (CurrentOperation.Order == NULL) {
+ ShellStatus = SHELL_OUT_OF_RESOURCES;
+ } else {
+ Status = gRT->GetVariable (
+ CurrentOperation.Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder",
+ (EFI_GUID *)&gEfiGlobalVariableGuid,
+ NULL,
+ &Length,
+ CurrentOperation.Order
+ );
+ }
+ }
+ }
+
+ Count = (UINT16)(Length / sizeof (CurrentOperation.Order[0]));
+
+ //
+ // large block to read the type of operation and verify parameter types for the info.
+ //
+ if ((ShellStatus == SHELL_SUCCESS) && (CurrentOperation.Target < BcfgTargetMax)) {
+ for (ParamNumber = 2; ParamNumber < ShellCommandLineGetCount (Package) && ShellStatus == SHELL_SUCCESS; ParamNumber++) {
+ CurrentParam = ShellCommandLineGetRawValue (Package, ParamNumber);
+ if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"dump") == 0) {
+ CurrentOperation.Type = BcfgTypeDump;
+ if (ShellCommandLineGetCount (Package) > 3) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellBcfgHiiHandle, L"bcfg");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+ } else if (ShellCommandLineGetFlag (Package, L"-v")) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"-v (without dump)");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"add") == 0) {
+ if ((ParamNumber + 3) >= ShellCommandLineGetCount (Package)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+
+ CurrentOperation.Type = BcfgTypeAdd;
+ CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
+ if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
+ CurrentOperation.Number1 = (UINT16)Intermediate;
+ ASSERT (CurrentOperation.FileName == NULL);
+ CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
+ ASSERT (CurrentOperation.Description == NULL);
+ CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
+ }
+ } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"addp") == 0) {
+ if ((ParamNumber + 3) >= ShellCommandLineGetCount (Package)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+
+ CurrentOperation.Type = BcfgTypeAddp;
+ CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
+ if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
+ CurrentOperation.Number1 = (UINT16)Intermediate;
+ ASSERT (CurrentOperation.FileName == NULL);
+ CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
+ ASSERT (CurrentOperation.Description == NULL);
+ CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
+ }
+ } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"addh") == 0) {
+ if ((ParamNumber + 3) >= ShellCommandLineGetCount (Package)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+
+ CurrentOperation.Type = BcfgTypeAddh;
+ CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
+ if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
+ CurrentOperation.Number1 = (UINT16)Intermediate;
+ CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
+ if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
+ CurrentOperation.HandleIndex = (UINT16)Intermediate;
+ ASSERT (CurrentOperation.Description == NULL);
+ CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
+ }
+ }
+ } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"rm") == 0) {
+ if ((ParamNumber + 1) >= ShellCommandLineGetCount (Package)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+
+ CurrentOperation.Type = BcfgTypeRm;
+ CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
+ if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
+ CurrentOperation.Number1 = (UINT16)Intermediate;
+ if (CurrentOperation.Number1 >= Count) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+ }
+ } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"mv") == 0) {
+ if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+
+ CurrentOperation.Type = BcfgTypeMv;
+ CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
+ if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
+ CurrentOperation.Number1 = (UINT16)Intermediate;
+ if (CurrentOperation.Number1 >= Count) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
+ if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
+ CurrentOperation.Number2 = (UINT16)Intermediate;
+ }
+
+ if ( (CurrentOperation.Number2 == CurrentOperation.Number1)
+ || (CurrentOperation.Number2 >= Count)
+ )
+ {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+ }
+ }
+ } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"mod") == 0) {
+ if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ CurrentOperation.Type = BcfgTypeMod;
+ CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
+ if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
+ CurrentOperation.Number1 = (UINT16)Intermediate;
+ if (CurrentOperation.Number1 >= Count) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ ASSERT (CurrentOperation.Description == NULL);
+ CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
+ }
+ }
+ }
+ } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"modf") == 0) {
+ if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ CurrentOperation.Type = BcfgTypeModf;
+ CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
+ if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
+ CurrentOperation.Number1 = (UINT16)Intermediate;
+ if (CurrentOperation.Number1 >= Count) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ ASSERT (CurrentOperation.FileName == NULL);
+ CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
+ }
+ }
+ }
+ } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"modp") == 0) {
+ if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ CurrentOperation.Type = BcfgTypeModp;
+ CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
+ if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
+ CurrentOperation.Number1 = (UINT16)Intermediate;
+ if (CurrentOperation.Number1 >= Count) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ ASSERT (CurrentOperation.FileName == NULL);
+ CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
+ }
+ }
+ }
+ } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"modh") == 0) {
+ if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ CurrentOperation.Type = BcfgTypeModh;
+ CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
+ if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
+ CurrentOperation.Number1 = (UINT16)Intermediate;
+ if (CurrentOperation.Number1 >= Count) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
+ if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
+ CurrentOperation.HandleIndex = (UINT16)Intermediate;
+ }
+ }
+ }
+ }
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+ }
+ }
+
+ if ((ShellStatus == SHELL_SUCCESS) && (CurrentOperation.Target < BcfgTargetMax) && (CurrentOperation.Type < BcfgTypeMax)) {
+ //
+ // we have all the info. Do the work
+ //
+ switch (CurrentOperation.Type) {
+ case BcfgTypeDump:
+ ShellStatus = BcfgDisplayDump (
+ CurrentOperation.Target == BcfgTargetBootOrder ? L"Boot" : L"Driver",
+ Count,
+ CurrentOperation.Order,
+ ShellCommandLineGetFlag (Package, L"-v")
+ );
+ break;
+ case BcfgTypeMv:
+ ShellStatus = BcfgMove (
+ CurrentOperation.Target,
+ CurrentOperation.Order,
+ Count,
+ CurrentOperation.Number1,
+ CurrentOperation.Number2
+ );
+ break;
+ case BcfgTypeRm:
+ ShellStatus = BcfgRemove (
+ CurrentOperation.Target,
+ CurrentOperation.Order,
+ Count,
+ CurrentOperation.Number1
+ );
+ break;
+ case BcfgTypeAdd:
+ case BcfgTypeAddp:
+ case BcfgTypeAddh:
+ ShellStatus = BcfgAdd (
+ CurrentOperation.Number1,
+ CurrentOperation.FileName,
+ CurrentOperation.Description == NULL ? L"" : CurrentOperation.Description,
+ CurrentOperation.Order,
+ Count,
+ CurrentOperation.Target,
+ (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddh),
+ (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddp),
+ CurrentOperation.HandleIndex
+ );
+ break;
+ case BcfgTypeMod:
+ case BcfgTypeModf:
+ case BcfgTypeModp:
+ case BcfgTypeModh:
+ ShellStatus = BcfgMod (&CurrentOperation, Count);
+ break;
+ case BcfgTypeOpt:
+ ShellStatus = BcfgAddOpt (
+ CurrentOperation.OptData,
+ CurrentOperation.Order,
+ Count,
+ CurrentOperation.Target
+ );
+ break;
+ default:
+ ASSERT (FALSE);
+ }
+ }
+ }
+
+ if (Package != NULL) {
+ ShellCommandLineFreeVarList (Package);
+ }
+
+ if (CurrentOperation.FileName != NULL) {
+ FreePool (CurrentOperation.FileName);
+ }
+
+ if (CurrentOperation.Description != NULL) {
+ FreePool (CurrentOperation.Description);
+ }
+
+ if (CurrentOperation.Order != NULL) {
+ FreePool (CurrentOperation.Order);
+ }
+
+ return (ShellStatus);
+}
+
+/**
+ Function to get the filename with help context if HII will not be used.
+
+ @return The filename with help text in it.
+**/
+CONST CHAR16 *
+EFIAPI
+ShellCommandGetManFileNameBcfg (
+ VOID
+ )
+{
+ return (mFileName);
+}
+
+/**
+ "Constructor" for the library.
+
+ This will register the handler for the bcfg command.
+
+ @param[in] ImageHandle the image handle of the process
+ @param[in] SystemTable the EFI System Table pointer
+ @param[in] Name the profile name to use
+
+ @retval EFI_SUCCESS the shell command handlers were installed successfully
+ @retval EFI_UNSUPPORTED the shell level required was not found.
+**/
+EFI_STATUS
+EFIAPI
+BcfgLibraryRegisterBcfgCommand (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN CONST CHAR16 *Name
+ )
+{
+ if (gShellBcfgHiiHandle != NULL) {
+ return (EFI_SUCCESS);
+ }
+
+ gShellBcfgHiiHandle = HiiAddPackages (&gShellBcfgHiiGuid, gImageHandle, UefiShellBcfgCommandLibStrings, NULL);
+ if (gShellBcfgHiiHandle == NULL) {
+ return (EFI_DEVICE_ERROR);
+ }
+
+ //
+ // install our shell command handler
+ //
+ ShellCommandRegisterCommandName (L"bcfg", ShellCommandRunBcfg, ShellCommandGetManFileNameBcfg, 0, Name, FALSE, gShellBcfgHiiHandle, STRING_TOKEN (STR_GET_HELP_BCFG));
+
+ return (EFI_SUCCESS);
+}
+
+/**
+ Destructor for the library. free any resources.
+
+ @param ImageHandle The image handle of the process.
+ @param SystemTable The EFI System Table pointer.
+**/
+EFI_STATUS
+EFIAPI
+BcfgLibraryUnregisterBcfgCommand (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ if (gShellBcfgHiiHandle != NULL) {
+ HiiRemovePackages (gShellBcfgHiiHandle);
+ }
+
+ gShellBcfgHiiHandle = NULL;
+ return (EFI_SUCCESS);
+}
diff --git a/ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf b/ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
index 6ed0ebc966..5938a9ce71 100644
--- a/ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+++ b/ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
@@ -1,42 +1,42 @@
-## @file
-# Provides shell install1 functions
-#
-# Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. <BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-##
-[Defines]
- INF_VERSION = 0x00010006
- BASE_NAME = UefiShellBcfgCommandLib
- FILE_GUID = F6A3BF5D-4095-4E4F-9670-408770C2DBDF
- MODULE_TYPE = UEFI_DRIVER
- VERSION_STRING = 1.1
- LIBRARY_CLASS = BcfgCommandLib|UEFI_APPLICATION UEFI_DRIVER
-
-[Sources.common]
- UefiShellBcfgCommandLib.c
- UefiShellBcfgCommandLib.uni
-
-[Packages]
- MdePkg/MdePkg.dec
- ShellPkg/ShellPkg.dec
- MdeModulePkg/MdeModulePkg.dec
-
-[LibraryClasses]
- MemoryAllocationLib
- BaseLib
- BaseMemoryLib
- DebugLib
- ShellCommandLib
- ShellLib
- UefiLib
- UefiRuntimeServicesTableLib
- UefiBootServicesTableLib
- SortLib
- PrintLib
- UefiBootManagerLib
-
-[Guids]
- gShellBcfgHiiGuid ## SOMETIMES_CONSUMES ## HII
+## @file
+# Provides shell install1 functions
+#
+# Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = UefiShellBcfgCommandLib
+ FILE_GUID = F6A3BF5D-4095-4E4F-9670-408770C2DBDF
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.1
+ LIBRARY_CLASS = BcfgCommandLib|UEFI_APPLICATION UEFI_DRIVER
+
+[Sources.common]
+ UefiShellBcfgCommandLib.c
+ UefiShellBcfgCommandLib.uni
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ ShellCommandLib
+ ShellLib
+ UefiLib
+ UefiRuntimeServicesTableLib
+ UefiBootServicesTableLib
+ SortLib
+ PrintLib
+ UefiBootManagerLib
+
+[Guids]
+ gShellBcfgHiiGuid ## SOMETIMES_CONSUMES ## HII
diff --git a/ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.uni b/ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.uni
index c8e261ba74..c6a53be906 100644
--- a/ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.uni
+++ b/ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.uni
@@ -1,153 +1,153 @@
-// /**
-//
-// (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
-// Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// Module Name:
-//
-// UefiBcfgCommandsLib.uni
-//
-// Abstract:
-//
-// String definitions for UEFI Shell 2.0 BCFG command
-//
-//
-// **/
-
-/=#
-
-#langdef en-US "english"
-
-#string STR_GEN_NO_MEM #language en-US "%H%s%N: Memory is not available.\r\n"
-#string STR_GEN_PROBLEM #language en-US "%H%s%N: Unknown flag - '%H%s%N'\r\n"
-#string STR_GEN_NO_VALUE #language en-US "%H%s%N: Missing argument for flag - '%H%s%N'\r\n"
-#string STR_GEN_PARAM_INV #language en-US "%H%s%N: Invalid argument - '%H%s%N'\r\n"
-#string STR_GEN_NO_DRIVER_BOOT #language en-US "%H%s%N: Driver or Boot must be selected.\r\n"
-#string STR_GEN_BOOT_ONLY #language en-US "%H%s%N: Boot must be selected for hot key options.\r\n"
-#string STR_GEN_TOO_FEW #language en-US "%H%s%N: Too few arguments.\r\n"
-#string STR_GEN_TOO_MANY #language en-US "%H%s%N: Too many arguments\r\n"
-#string STR_GEN_FILE_OPEN_FAIL #language en-US "%H%s%N: Cannot open file - '%H%s%N'\r\n"
-#string STR_GEN_FIND_FAIL #language en-US "%H%s%N: File not found - '%H%s%N'\r\n"
-#string STR_GEN_OUT_MEM #language en-US "%H%s%N: Memory allocation was not successful.\r\n"
-#string STR_BCFG_WRITE_FAIL #language en-US "%H%s%N: Unable to write to '%H%s%N'\r\n"
-#string STR_BCFG_READ_FAIL #language en-US "%H%s%N: Unable to read from '%H%s%N'\r\n"
-#string STR_BCFG_VAR_CORRUPT #language en-US "%H%s%N: Variable '%H%s%N' corrupt.\r\n"
-#string STR_BCFG_HANDLE #language en-US "%H%s%N: The handle [%H%02x%N] does not have DevicePath.\r\n"
-#string STR_BCFG_FILE #language en-US "%H%s%N: The file '%H%s%N' matches multiple files.\r\n"
-#string STR_BCFG_FILE_OPEN #language en-US "%H%s%N: The file '%H%s%N' did not open.\r\n"
-#string STR_BCFG_FILE_DP #language en-US "%H%s%N: The file '%H%s%N' could not convert to DevPath.\r\n"
-#string STR_BCFG_TARGET_NF #language en-US "%H%s%N: Could not find unused target index.\r\n"
-#string STR_BCFG_TARGET #language en-US "Target = %04x.\r\n"
-#string STR_BCFG_SET_VAR_FAIL #language en-US "%H%s%N: Unable to set %H%s%N\r\n"
-#string STR_BCFG_VAR_NO_NUM #language en-US "%H%s%N: Cannot create Key#### variable: All the numbers from 0x0000 - 0xFFFF have been used.\r\n"
-#string STR_BCFG_NUMB_RANGE #language en-US "%H%s%N: Numbers must be under %d.\r\n"
-#string STR_BCFG_NONE #language en-US "No options found.\r\n"
-
-#string STR_BCFG_LOAD_OPTIONS #language en-US "Option: %B%02x%N. Variable: %B%-11s%N\r\n"
- " Desc - %s\r\n"
- " DevPath - %s\r\n"
- " Optional- %c\r\n"
-#string STR_GET_HELP_BCFG #language en-US ""
-".TH bcfg 0 "configure boot and driver"\r\n"
-".SH NAME\r\n"
-"Manages the boot and driver options that are stored in NVRAM.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"BCFG driver|boot [dump [-v]] [add # file "desc"] [addp # file "desc"] \r\n"
-" [addh # handle "desc"] [rm #] [mv # #] \r\n"
-" [-opt # [[filename]|["data"]] | \r\n"
-" [KeyData <ScanCode UnicodeChar>]]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" -v - Displays verbose information about options, including the optional\r\n"
-" data.\r\n"
-" -opt - Displays or modifies the optional data associated with a \r\n"
-" driver or boot option. This parameter is followed by the file name of the\r\n"
-" file that contains the binary data to be associated with the\r\n"
-" driver or boot option optional data, or the quote\r\n"
-" delimited data to be associated with the driver or\r\n"
-" boot option optional data.\r\n"
-" driver - Displays or modifies the driver option list.\r\n"
-" boot - Displays or modifies the boot option list.\r\n"
-" dump - Displays the option list.\r\n"
-" add - Adds an option. The # is the number of options to add in\r\n"
-" hexadecimal format. The file name is the name of the UEFI application/driver for\r\n"
-" the option. The quoted parameter is the description of the\r\n"
-" option to be added.\r\n"
-" addh - Adds an option that refers to the driver specified by a handle.\r\n"
-" The # is the number of options to add, in hexadecimal format. The\r\n"
-" handle is the driver handle, in hexadecimal format. The device path\r\n"
-" for the option is retrieved from the handle. The quoted\r\n"
-" parameter is the description of the option to be added.\r\n"
-" addp - Adds an option that refers to a specific file. Only the portion\r\n"
-" of the device path starting with the hard drive partition is\r\n"
-" placed in the option. The # is the number of options to add,\r\n"
-" in hexadecimal format. The quoted parameter is the description of the\r\n"
-" option being added.\r\n"
-" rm - Removes an option. The parameter lists the number of the options\r\n"
-" to remove in hexadecimal format.\r\n"
-" mv - Moves an option. The first numeric parameter is the number of\r\n"
-" the option to move in hexadecimal format. The second numeric parameter\r\n"
-" is the new number of the option to be moved.\r\n"
-" KeyData - Specifies the packed value associated with a hot-key.\r\n"
-" ScanCode - Specifies the UEFI-defined scan code portion of the\r\n"
-" EFI_INPUT_KEY instruction. This value is directly associated\r\n"
-" with the preceding KeyData value. When one instance of this\r\n"
-" parameter has a non-zero value, the paired UnicodeChar value\r\n"
-" will have a zero-based value.\r\n"
-" UnicodeChar - Specifies the Unicode value for the character associated with\r\n"
-" the preceding KeyData value. When one instance of this\r\n"
-" parameter has a non-zero value, the paired ScanCode value\r\n"
-" will have a zero-based value.\r\n"
-".SH DESCRIPTION\r\n"
-" \r\n"
-"NOTES:\r\n"
-" 1. This command manages the boot and driver options stored in NVRAM.\r\n"
-" 2. Use the dump option to display Boot#### or Driver#### environment variables.\r\n"
-" 3. Use the add option to add a new Boot#### or Driver#### \r\n"
-" environment variable.\r\n"
-" 4. Use the rm option to delete a Boot#### or Driver#### \r\n"
-" environment variable, and then the mv option to reorder\r\n"
-" the Boot#### and Driver#### environment variables.\r\n"
-" 5. The add, rm, and mv options also update the BootOrder or DriverOrder\r\n"
-" environment variables, as appropriate.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To display driver options:\r\n"
-" Shell> bcfg driver dump\r\n"
-" \r\n"
-" * To display boot options:\r\n"
-" Shell> bcfg boot dump\r\n"
-" \r\n"
-" * To display verbose information about boot options:\r\n"
-" Shell> bcfg boot dump -v\r\n"
-" \r\n"
-" * To add a driver option #5:\r\n"
-" Shell> bcfg driver add 5 mydriver.efi "My Driver"\r\n"
-" \r\n"
-" * To add a boot option #3:\r\n"
-" Shell> bcfg boot add 3 osloader.efi "My OS"\r\n"
-" \r\n"
-" * To remove boot option #3:\r\n"
-" Shell> bcfg boot rm 3\r\n"
-" \r\n"
-" * To move boot option #3 to boot option #7:\r\n"
-" Shell> bcfg boot mv 3 7\r\n"
-" \r\n"
-" * To assign a CTRL-B hot-key to boot option #3:\r\n"
-" Shell> bcfg boot -opt 3 0x40000200 0 0x42\r\n"
-".SH RETURNVALUES\r\n"
-" \r\n"
-"RETURN VALUES:\r\n"
-" SHELL_SUCCESS The action was completed as requested.\r\n"
-" SHELL_NOT_FOUND The requested option was not found.\r\n"
-" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n"
-" formatted or its value was out of bounds.\r\n"
-" SHELL_UNSUPPORTED The action as requested was unsupported.\r\n"
-" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n"
-" violation.\r\n"
-" SHELL_OUT_OF_RESOURCES There was insufficient free space for the request\r\n"
-" to be completed.\r\n"
-
+// /**
+//
+// (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
+// Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Module Name:
+//
+// UefiBcfgCommandsLib.uni
+//
+// Abstract:
+//
+// String definitions for UEFI Shell 2.0 BCFG command
+//
+//
+// **/
+
+/=#
+
+#langdef en-US "english"
+
+#string STR_GEN_NO_MEM #language en-US "%H%s%N: Memory is not available.\r\n"
+#string STR_GEN_PROBLEM #language en-US "%H%s%N: Unknown flag - '%H%s%N'\r\n"
+#string STR_GEN_NO_VALUE #language en-US "%H%s%N: Missing argument for flag - '%H%s%N'\r\n"
+#string STR_GEN_PARAM_INV #language en-US "%H%s%N: Invalid argument - '%H%s%N'\r\n"
+#string STR_GEN_NO_DRIVER_BOOT #language en-US "%H%s%N: Driver or Boot must be selected.\r\n"
+#string STR_GEN_BOOT_ONLY #language en-US "%H%s%N: Boot must be selected for hot key options.\r\n"
+#string STR_GEN_TOO_FEW #language en-US "%H%s%N: Too few arguments.\r\n"
+#string STR_GEN_TOO_MANY #language en-US "%H%s%N: Too many arguments\r\n"
+#string STR_GEN_FILE_OPEN_FAIL #language en-US "%H%s%N: Cannot open file - '%H%s%N'\r\n"
+#string STR_GEN_FIND_FAIL #language en-US "%H%s%N: File not found - '%H%s%N'\r\n"
+#string STR_GEN_OUT_MEM #language en-US "%H%s%N: Memory allocation was not successful.\r\n"
+#string STR_BCFG_WRITE_FAIL #language en-US "%H%s%N: Unable to write to '%H%s%N'\r\n"
+#string STR_BCFG_READ_FAIL #language en-US "%H%s%N: Unable to read from '%H%s%N'\r\n"
+#string STR_BCFG_VAR_CORRUPT #language en-US "%H%s%N: Variable '%H%s%N' corrupt.\r\n"
+#string STR_BCFG_HANDLE #language en-US "%H%s%N: The handle [%H%02x%N] does not have DevicePath.\r\n"
+#string STR_BCFG_FILE #language en-US "%H%s%N: The file '%H%s%N' matches multiple files.\r\n"
+#string STR_BCFG_FILE_OPEN #language en-US "%H%s%N: The file '%H%s%N' did not open.\r\n"
+#string STR_BCFG_FILE_DP #language en-US "%H%s%N: The file '%H%s%N' could not convert to DevPath.\r\n"
+#string STR_BCFG_TARGET_NF #language en-US "%H%s%N: Could not find unused target index.\r\n"
+#string STR_BCFG_TARGET #language en-US "Target = %04x.\r\n"
+#string STR_BCFG_SET_VAR_FAIL #language en-US "%H%s%N: Unable to set %H%s%N\r\n"
+#string STR_BCFG_VAR_NO_NUM #language en-US "%H%s%N: Cannot create Key#### variable: All the numbers from 0x0000 - 0xFFFF have been used.\r\n"
+#string STR_BCFG_NUMB_RANGE #language en-US "%H%s%N: Numbers must be under %d.\r\n"
+#string STR_BCFG_NONE #language en-US "No options found.\r\n"
+
+#string STR_BCFG_LOAD_OPTIONS #language en-US "Option: %B%02x%N. Variable: %B%-11s%N\r\n"
+ " Desc - %s\r\n"
+ " DevPath - %s\r\n"
+ " Optional- %c\r\n"
+#string STR_GET_HELP_BCFG #language en-US ""
+".TH bcfg 0 "configure boot and driver"\r\n"
+".SH NAME\r\n"
+"Manages the boot and driver options that are stored in NVRAM.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"BCFG driver|boot [dump [-v]] [add # file "desc"] [addp # file "desc"] \r\n"
+" [addh # handle "desc"] [rm #] [mv # #] \r\n"
+" [-opt # [[filename]|["data"]] | \r\n"
+" [KeyData <ScanCode UnicodeChar>]]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" -v - Displays verbose information about options, including the optional\r\n"
+" data.\r\n"
+" -opt - Displays or modifies the optional data associated with a \r\n"
+" driver or boot option. This parameter is followed by the file name of the\r\n"
+" file that contains the binary data to be associated with the\r\n"
+" driver or boot option optional data, or the quote\r\n"
+" delimited data to be associated with the driver or\r\n"
+" boot option optional data.\r\n"
+" driver - Displays or modifies the driver option list.\r\n"
+" boot - Displays or modifies the boot option list.\r\n"
+" dump - Displays the option list.\r\n"
+" add - Adds an option. The # is the number of options to add in\r\n"
+" hexadecimal format. The file name is the name of the UEFI application/driver for\r\n"
+" the option. The quoted parameter is the description of the\r\n"
+" option to be added.\r\n"
+" addh - Adds an option that refers to the driver specified by a handle.\r\n"
+" The # is the number of options to add, in hexadecimal format. The\r\n"
+" handle is the driver handle, in hexadecimal format. The device path\r\n"
+" for the option is retrieved from the handle. The quoted\r\n"
+" parameter is the description of the option to be added.\r\n"
+" addp - Adds an option that refers to a specific file. Only the portion\r\n"
+" of the device path starting with the hard drive partition is\r\n"
+" placed in the option. The # is the number of options to add,\r\n"
+" in hexadecimal format. The quoted parameter is the description of the\r\n"
+" option being added.\r\n"
+" rm - Removes an option. The parameter lists the number of the options\r\n"
+" to remove in hexadecimal format.\r\n"
+" mv - Moves an option. The first numeric parameter is the number of\r\n"
+" the option to move in hexadecimal format. The second numeric parameter\r\n"
+" is the new number of the option to be moved.\r\n"
+" KeyData - Specifies the packed value associated with a hot-key.\r\n"
+" ScanCode - Specifies the UEFI-defined scan code portion of the\r\n"
+" EFI_INPUT_KEY instruction. This value is directly associated\r\n"
+" with the preceding KeyData value. When one instance of this\r\n"
+" parameter has a non-zero value, the paired UnicodeChar value\r\n"
+" will have a zero-based value.\r\n"
+" UnicodeChar - Specifies the Unicode value for the character associated with\r\n"
+" the preceding KeyData value. When one instance of this\r\n"
+" parameter has a non-zero value, the paired ScanCode value\r\n"
+" will have a zero-based value.\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. This command manages the boot and driver options stored in NVRAM.\r\n"
+" 2. Use the dump option to display Boot#### or Driver#### environment variables.\r\n"
+" 3. Use the add option to add a new Boot#### or Driver#### \r\n"
+" environment variable.\r\n"
+" 4. Use the rm option to delete a Boot#### or Driver#### \r\n"
+" environment variable, and then the mv option to reorder\r\n"
+" the Boot#### and Driver#### environment variables.\r\n"
+" 5. The add, rm, and mv options also update the BootOrder or DriverOrder\r\n"
+" environment variables, as appropriate.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To display driver options:\r\n"
+" Shell> bcfg driver dump\r\n"
+" \r\n"
+" * To display boot options:\r\n"
+" Shell> bcfg boot dump\r\n"
+" \r\n"
+" * To display verbose information about boot options:\r\n"
+" Shell> bcfg boot dump -v\r\n"
+" \r\n"
+" * To add a driver option #5:\r\n"
+" Shell> bcfg driver add 5 mydriver.efi "My Driver"\r\n"
+" \r\n"
+" * To add a boot option #3:\r\n"
+" Shell> bcfg boot add 3 osloader.efi "My OS"\r\n"
+" \r\n"
+" * To remove boot option #3:\r\n"
+" Shell> bcfg boot rm 3\r\n"
+" \r\n"
+" * To move boot option #3 to boot option #7:\r\n"
+" Shell> bcfg boot mv 3 7\r\n"
+" \r\n"
+" * To assign a CTRL-B hot-key to boot option #3:\r\n"
+" Shell> bcfg boot -opt 3 0x40000200 0 0x42\r\n"
+".SH RETURNVALUES\r\n"
+" \r\n"
+"RETURN VALUES:\r\n"
+" SHELL_SUCCESS The action was completed as requested.\r\n"
+" SHELL_NOT_FOUND The requested option was not found.\r\n"
+" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n"
+" formatted or its value was out of bounds.\r\n"
+" SHELL_UNSUPPORTED The action as requested was unsupported.\r\n"
+" SHELL_SECURITY_VIOLATION This function was not performed due to a security\r\n"
+" violation.\r\n"
+" SHELL_OUT_OF_RESOURCES There was insufficient free space for the request\r\n"
+" to be completed.\r\n"
+