--- /dev/null
+/** @file\r
+ Main file for bcfg shell install1 function.\r
+\r
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "UefiShellInstall1CommandsLib.h"\r
+#include <Guid/GlobalVariable.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/HandleParsingLib.h>\r
+#include <Library/DevicePathLib.h>\r
+\r
+typedef enum {\r
+ BCFG_TARGET_BOOT_ORDER = 0,\r
+ BCFG_TARGET_DRIVER_ORDER = 1,\r
+ BCFG_TARGET_MAX = 2\r
+} BCFG_OPERATION_TARGET;\r
+\r
+typedef enum {\r
+ BCFG_TYPE_DUMP = 0,\r
+ BCFG_TYPE_ADD = 1,\r
+ BCFG_TYPE_ADDP = 2,\r
+ BCFG_TYPE_ADDH = 3,\r
+ BCFG_TYPE_RM = 4,\r
+ BCFG_TYPE_MV = 5,\r
+ BCFG_TYPE_OPT = 6,\r
+ BCFG_TYPE_MAX = 7\r
+} BCFG_OPERATION_TYPE;\r
+\r
+typedef struct {\r
+ BCFG_OPERATION_TARGET Target;\r
+ BCFG_OPERATION_TYPE Type;\r
+ UINT16 Number1;\r
+ UINT16 Number2;\r
+ UINTN HandleIndex;\r
+ CHAR16 *FileName;\r
+ CHAR16 *Description;\r
+ UINT16 *Order;\r
+ CONST CHAR16 *OptData;\r
+} BGFG_OPERATION;\r
+\r
+/**\r
+ Function to update the optional data associated with an option.\r
+\r
+ @param[in] Target The type being modified. BOOT or DRIVER\r
+ @param[in] OptData The pointer to the data to modify with.\r
+\r
+ @retval SHELL_SUCCESS The optional data was updated sucessfully.\r
+**/\r
+SHELL_STATUS\r
+EFIAPI\r
+BcfgAddOptInstall(\r
+ IN CONST BCFG_OPERATION_TARGET Target,\r
+ IN CONST CHAR16 *OptData\r
+ )\r
+{\r
+ ShellPrintEx(-1, -1, L"use of -opt is not currently supported.");\r
+ return (SHELL_UNSUPPORTED);\r
+}\r
+\r
+/**\r
+ Function to add an option.\r
+\r
+ @param[in] Position The position to add this in at.\r
+ @param[in] File The file to add as the option.\r
+ @param[in] Desc The description.\r
+ @param[in] CurrentOrder The current order of that type.\r
+ @param[in] OrderCount The number of items in the current order.\r
+ @param[in] Target The type being modified. BOOT or DRIVER\r
+ @param[in] UseHandle Add something by a handle. Uses HandleNumber if TRUE and File if FALSE.\r
+ @param[in] UsePath Add something by local path. Only used of UseHandle is FALSE.\r
+ @param[in] HandleNumber The HandleIndex to use.\r
+\r
+ @retval SHELL_SUCCESS The option was added sucessfully.\r
+**/\r
+SHELL_STATUS\r
+EFIAPI\r
+BcfgAddInstall (\r
+ IN UINTN Position,\r
+ IN CONST CHAR16 *File,\r
+ IN CONST CHAR16 *Desc,\r
+ IN CONST UINT16 *CurrentOrder,\r
+ IN CONST UINTN OrderCount,\r
+ IN CONST BCFG_OPERATION_TARGET Target,\r
+ IN CONST BOOLEAN UseHandle,\r
+ IN CONST BOOLEAN UseFullPath,\r
+ IN CONST UINTN HandleNumber\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath, *FilePath, *FileNode;\r
+ CHAR16 *Str;\r
+ CONST CHAR16 *p;\r
+ UINT8 *p8;\r
+ UINT8 *p8Copy;\r
+ EFI_SHELL_FILE_INFO *Arg;\r
+ EFI_SHELL_FILE_INFO *FileList;\r
+ CHAR16 OptionStr[40];\r
+ UINTN DescSize, FilePathSize;\r
+ BOOLEAN Found;\r
+ UINTN TargetLocation;\r
+ UINTN Index;\r
+ EFI_HANDLE *Handles;\r
+ EFI_HANDLE CurHandle;\r
+ SHELL_STATUS ShellStatus;\r
+ UINT16 *NewOrder;\r
+ EFI_LOADED_IMAGE_PROTOCOL *Image;\r
+\r
+ if (!UseHandle) {\r
+ ASSERT(File != NULL);\r
+ ASSERT(Desc != NULL);\r
+ } else {\r
+ ASSERT(HandleNumber != 0);\r
+ }\r
+\r
+ Str = NULL;\r
+ FilePath = NULL;\r
+ FileNode = NULL;\r
+ FileList = NULL;\r
+ Handles = NULL;\r
+ ShellStatus = SHELL_SUCCESS;\r
+ TargetLocation = 0xFFFF;\r
+\r
+ if (UseHandle) {\r
+ CurHandle = ConvertHandleIndexToHandle(HandleNumber);\r
+ if (CurHandle == NULL) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, L"<HandleNumber>");\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ FilePath = NULL;\r
+ Status = gBS->HandleProtocol (CurHandle, &gEfiLoadedImageDevicePathProtocolGuid, (VOID**)&FilePath);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_SUCCESS;\r
+ //\r
+ // Try to construct the DevicePath\r
+ //\r
+ Status = gBS->OpenProtocol(CurHandle, &gEfiLoadedImageProtocolGuid, (VOID**)&Image, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
+ if (EFI_ERROR(Status)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_HANDLE), gShellInstall1HiiHandle, HandleNumber);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ Status = gBS->HandleProtocol (Image->DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID**)&DevicePath);\r
+ if (EFI_ERROR(Status)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_HANDLE), gShellInstall1HiiHandle, HandleNumber);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ FilePath = AppendDevicePath(DevicePath, Image->FilePath);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ } else {\r
+ //\r
+ // Get file info\r
+ //\r
+ Status = ShellOpenFileMetaArg ((CHAR16*)File, EFI_FILE_MODE_READ, &FileList);\r
+ if (EFI_ERROR(Status)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellInstall1HiiHandle, File);\r
+ ShellStatus = SHELL_NOT_FOUND;\r
+ } else if (FileList == NULL || FileList->Link.ForwardLink != FileList->Link.BackLink) {\r
+ //\r
+ // If filename expanded to multiple names, fail\r
+ //\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellInstall1HiiHandle, File);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ Arg = (EFI_SHELL_FILE_INFO*)GetFirstNode(&FileList->Link);\r
+ if (EFI_ERROR(Arg->Status)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellInstall1HiiHandle, File, Arg->Status);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ //\r
+ // Build FilePath to the filename\r
+ //\r
+\r
+ //\r
+ // get the device path\r
+ //\r
+ DevicePath = mEfiShellProtocol->GetDevicePathFromFilePath(Arg->FullName);\r
+ if (DevicePath == NULL) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellInstall1HiiHandle, Arg->FullName);\r
+ ShellStatus = SHELL_UNSUPPORTED;\r
+ } else {\r
+ if (UseFullPath) {\r
+ FilePath = DuplicateDevicePath(DevicePath);\r
+ } else {\r
+ for(p=Arg->FullName; *p != CHAR_NULL && *p != ':'; p++);\r
+ FilePath = FileDevicePath(NULL, p+1);\r
+ }\r
+\r
+ FreePool(DevicePath);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ if (ShellStatus == SHELL_SUCCESS) {\r
+ //\r
+ // Find a free target ,a brute force implementation\r
+ //\r
+ Found = FALSE;\r
+ for (TargetLocation=0; TargetLocation < 0xFFFF; TargetLocation++) {\r
+ Found = TRUE;\r
+ for (Index=0; Index < OrderCount; Index++) {\r
+ if (CurrentOrder[Index] == TargetLocation) {\r
+ Found = FALSE;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (Found) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (TargetLocation == 0xFFFF) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET_NF), gShellInstall1HiiHandle);\r
+ } else {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET), gShellInstall1HiiHandle, TargetLocation);\r
+ }\r
+ }\r
+\r
+ if (ShellStatus == SHELL_SUCCESS) {\r
+ //\r
+ // Add the option\r
+ //\r
+ DescSize = StrSize(Desc);\r
+ FilePathSize = GetDevicePathSize (FilePath);\r
+\r
+ p8 = AllocateZeroPool(sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize);\r
+ if (p8 != NULL) {\r
+ p8Copy = p8;\r
+ *((UINT32 *) p8) = LOAD_OPTION_ACTIVE; // Attributes\r
+ p8 += sizeof (UINT32);\r
+\r
+ *((UINT16 *) p8) = (UINT16)FilePathSize; // FilePathListLength\r
+ p8 += sizeof (UINT16);\r
+\r
+ CopyMem (p8, Desc, DescSize);\r
+ p8 += DescSize;\r
+ CopyMem (p8, FilePath, FilePathSize);\r
+\r
+ UnicodeSPrint (OptionStr, sizeof(OptionStr), L"%s%04x", Target == BCFG_TARGET_BOOT_ORDER?L"Boot":L"Driver", TargetLocation);\r
+ Status = gRT->SetVariable (\r
+ OptionStr,\r
+ &gEfiGlobalVariableGuid,\r
+ EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
+ sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize,\r
+ p8Copy\r
+ );\r
+\r
+ FreePool(p8Copy);\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellInstall1HiiHandle, OptionStr, Status);\r
+ } else {\r
+ NewOrder = AllocateZeroPool((OrderCount+1)*sizeof(UINT16));\r
+ ASSERT(NewOrder != NULL);\r
+ CopyMem(NewOrder, CurrentOrder, (OrderCount)*sizeof(UINT16));\r
+\r
+ //\r
+ // Insert target into order list\r
+ //\r
+ for (Index=OrderCount; Index > Position; Index--) {\r
+ NewOrder[Index] = NewOrder[Index-1];\r
+ }\r
+\r
+ NewOrder[Index] = (UINT16)TargetLocation;\r
+ Status = gRT->SetVariable (\r
+ Target == BCFG_TARGET_BOOT_ORDER?L"BootOrder":L"DriverOrder",\r
+ &gEfiGlobalVariableGuid,\r
+ EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
+ (OrderCount+1) * sizeof(UINT16),\r
+ NewOrder\r
+ );\r
+\r
+ FreePool(NewOrder);\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, Target == BCFG_TARGET_BOOT_ORDER?L"BootOrder":L"DriverOrder", Status);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ ShellPrintEx (-1, -1, L"bcfg: Add %s as %x\n", OptionStr, Index);\r
+ }\r
+ }\r
+ } else {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellInstall1HiiHandle);\r
+ ShellStatus = SHELL_OUT_OF_RESOURCES;\r
+ }\r
+ }\r
+\r
+//\r
+//If always Free FilePath, will free devicepath in system when use "addh"\r
+//\r
+\r
+ if (FilePath!=NULL && !UseHandle) {\r
+ FreePool (FilePath);\r
+ }\r
+\r
+ if (Str != NULL) {\r
+ FreePool(Str);\r
+ }\r
+\r
+ if (Handles != NULL) {\r
+ FreePool (Handles);\r
+ }\r
+\r
+ if (FileList != NULL) {\r
+ ShellCloseFileMetaArg (&FileList);\r
+ }\r
+\r
+ return (ShellStatus);\r
+}\r
+\r
+SHELL_STATUS\r
+EFIAPI\r
+BcfgRemoveInstall(\r
+ IN CONST BCFG_OPERATION_TARGET Target,\r
+ IN CONST UINT16 *CurrentOrder,\r
+ IN CONST UINTN OrderCount,\r
+ IN CONST UINT16 Location\r
+ )\r
+{\r
+ CHAR16 VariableName[12];\r
+ UINT16 *NewOrder;\r
+ EFI_STATUS Status;\r
+\r
+ NewOrder = AllocatePool(OrderCount*sizeof(CurrentOrder[0]));\r
+ if (NewOrder == NULL) {\r
+ return (SHELL_OUT_OF_RESOURCES);\r
+ }\r
+\r
+ CopyMem(NewOrder, CurrentOrder, OrderCount*sizeof(CurrentOrder[0]));\r
+ CopyMem(NewOrder+Location, NewOrder+Location+1, (OrderCount - Location - 1)*sizeof(CurrentOrder[0]));\r
+\r
+ Status = gRT->SetVariable(\r
+ Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",\r
+ (EFI_GUID*)&gEfiGlobalVariableGuid,\r
+ EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
+ (OrderCount-1)*sizeof(CurrentOrder[0]), // drop 1 off since the list is 1 shorter\r
+ NewOrder);\r
+\r
+ FreePool(NewOrder);\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder", Status);\r
+ return (SHELL_INVALID_PARAMETER);\r
+ }\r
+\r
+ UnicodeSPrint(VariableName, sizeof(VariableName), L"%s%04x", Target == BCFG_TARGET_BOOT_ORDER?L"Boot":L"Driver", CurrentOrder[Location]);\r
+ Status = gRT->SetVariable(\r
+ VariableName,\r
+ (EFI_GUID*)&gEfiGlobalVariableGuid,\r
+ EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
+ 0,\r
+ NULL);\r
+ if (EFI_ERROR(Status)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, VariableName, Status);\r
+ return (SHELL_INVALID_PARAMETER);\r
+ }\r
+\r
+ return (SHELL_SUCCESS);\r
+}\r
+\r
+SHELL_STATUS\r
+EFIAPI\r
+BcfgMoveInstall(\r
+ IN CONST BCFG_OPERATION_TARGET Target,\r
+ IN CONST UINT16 *CurrentOrder,\r
+ IN CONST UINTN OrderCount,\r
+ IN CONST UINT16 OldLocation,\r
+ IN CONST UINT16 NewLocation\r
+ )\r
+{\r
+ UINT16 *NewOrder;\r
+ EFI_STATUS Status;\r
+ UINT16 Temp;\r
+\r
+ NewOrder = AllocatePool(OrderCount*sizeof(CurrentOrder[0]));\r
+ ASSERT(NewOrder != NULL);\r
+\r
+ Temp = CurrentOrder[OldLocation];\r
+ CopyMem(NewOrder, CurrentOrder, OrderCount*sizeof(CurrentOrder[0]));\r
+ CopyMem(NewOrder+OldLocation, NewOrder+OldLocation+1, (OrderCount - OldLocation - 1)*sizeof(CurrentOrder[0]));\r
+ if (NewLocation == OrderCount) {\r
+ NewOrder[OrderCount-1] = Temp;\r
+ } else {\r
+ CopyMem(NewOrder+NewLocation+1, NewOrder+NewLocation, (OrderCount - NewLocation - 1)*sizeof(CurrentOrder[0]));\r
+ NewOrder[NewLocation] = Temp;\r
+ }\r
+\r
+\r
+ Status = gRT->SetVariable(\r
+ Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",\r
+ (EFI_GUID*)&gEfiGlobalVariableGuid,\r
+ EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
+ OrderCount*sizeof(CurrentOrder[0]),\r
+ NewOrder);\r
+\r
+ FreePool(NewOrder);\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellInstall1HiiHandle, Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder", Status);\r
+ return (SHELL_INVALID_PARAMETER);\r
+ }\r
+ return (SHELL_SUCCESS);\r
+}\r
+\r
+SHELL_STATUS\r
+EFIAPI\r
+BcfgDisplayDumpInstall(\r
+ IN CONST CHAR16 *Op,\r
+ IN CONST UINT16 *CurrentOrder,\r
+ IN CONST UINTN OrderCount,\r
+ IN CONST BOOLEAN VerboseOutput\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 *Buffer;\r
+ UINTN BufferSize;\r
+ CHAR16 VariableName[12];\r
+ UINTN LoopVar;\r
+ UINTN LoopVar2;\r
+ CHAR16 *DevPathString;\r
+ VOID *DevPath;\r
+\r
+ for (LoopVar = 0 ; LoopVar < OrderCount ; LoopVar++) {\r
+ Buffer = NULL;\r
+ BufferSize = 0;\r
+ UnicodeSPrint(VariableName, sizeof(VariableName), L"%s%04x", Op, CurrentOrder[LoopVar]);\r
+\r
+ Status = gRT->GetVariable(\r
+ VariableName,\r
+ (EFI_GUID*)&gEfiGlobalVariableGuid,\r
+ NULL,\r
+ &BufferSize,\r
+ Buffer);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ Buffer = AllocatePool(BufferSize);\r
+ Status = gRT->GetVariable(\r
+ VariableName,\r
+ (EFI_GUID*)&gEfiGlobalVariableGuid,\r
+ NULL,\r
+ &BufferSize,\r
+ Buffer);\r
+ }\r
+\r
+ if (EFI_ERROR(Status) || Buffer == NULL) {\r
+ SHELL_FREE_NON_NULL(Buffer);\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_READ_FAIL), gShellInstall1HiiHandle, VariableName, Status);\r
+ return (SHELL_INVALID_PARAMETER);\r
+ }\r
+\r
+ DevPath = AllocatePool(*(UINT16*)(Buffer+4));\r
+ CopyMem(DevPath, Buffer+6+StrSize((CHAR16*)(Buffer+6)), *(UINT16*)(Buffer+4));\r
+ DevPathString = gDevPathToText->ConvertDevicePathToText(DevPath, TRUE, FALSE);\r
+ ShellPrintHiiEx(\r
+ -1,\r
+ -1,\r
+ NULL,\r
+ STRING_TOKEN(STR_BCFG_LOAD_OPTIONS),\r
+ gShellInstall1HiiHandle,\r
+ Op,\r
+ LoopVar,\r
+ (CHAR16*)(Buffer+6),\r
+ DevPathString,\r
+ (StrSize((CHAR16*)(Buffer+6)) + *(UINT16*)(Buffer+4) + 6) <= BufferSize?L'N':L'Y');\r
+ if (VerboseOutput) {\r
+ for (LoopVar2 = (StrSize((CHAR16*)(Buffer+6)) + *(UINT16*)(Buffer+4) + 6);LoopVar2<BufferSize;LoopVar2++){\r
+ ShellPrintEx(-1, -1, L"%02x", Buffer[LoopVar2]);\r
+ }\r
+ ShellPrintEx(-1, -1, L"\r\n");\r
+ }\r
+\r
+ if (Buffer != NULL) {\r
+ FreePool(Buffer);\r
+ }\r
+ if (DevPath != NULL) {\r
+ FreePool(DevPath);\r
+ }\r
+ if (DevPathString != NULL) {\r
+ FreePool(DevPathString);\r
+ }\r
+ }\r
+ return (SHELL_SUCCESS);\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+InitBcfgStructInstall(\r
+ IN BGFG_OPERATION *Struct\r
+ )\r
+{\r
+ ASSERT(Struct != NULL);\r
+ Struct->Target = BCFG_TARGET_MAX;\r
+ Struct->Type = BCFG_TYPE_MAX;\r
+ Struct->Number1 = 0;\r
+ Struct->Number2 = 0;\r
+ Struct->HandleIndex = 0;\r
+ Struct->FileName = NULL;\r
+ Struct->Description = NULL;\r
+ Struct->Order = NULL;\r
+ Struct->OptData = NULL;\r
+}\r
+\r
+\r
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
+ {L"-v", TypeFlag},\r
+ {L"-opt", TypeMaxValue},\r
+ {NULL, TypeMax}\r
+ };\r
+\r
+/**\r
+ Function for 'bcfg' command.\r
+\r
+ @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
+ @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
+**/\r
+SHELL_STATUS\r
+EFIAPI\r
+ShellCommandRunBcfgInstall (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Package;\r
+ CHAR16 *ProblemParam;\r
+ SHELL_STATUS ShellStatus;\r
+ UINTN ParamNumber;\r
+ CONST CHAR16 *CurrentParam;\r
+ BGFG_OPERATION CurrentOperation;\r
+ UINTN Length;\r
+\r
+ Length = 0;\r
+ ProblemParam = NULL;\r
+ Package = NULL;\r
+ ShellStatus = SHELL_SUCCESS;\r
+\r
+ InitBcfgStructInstall(&CurrentOperation);\r
+\r
+ //\r
+ // initialize the shell lib (we must be in non-auto-init...)\r
+ //\r
+ Status = ShellInitialize();\r
+ ASSERT_EFI_ERROR(Status);\r
+\r
+ Status = CommandInit();\r
+ ASSERT_EFI_ERROR(Status);\r
+\r
+ //\r
+ // parse the command line\r
+ //\r
+ Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
+ if (EFI_ERROR(Status)) {\r
+ if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, ProblemParam);\r
+ FreePool(ProblemParam);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ ASSERT(FALSE);\r
+ }\r
+ } else {\r
+ //\r
+ // small block to read the target of the operation\r
+ //\r
+ if (ShellCommandLineGetFlag(Package, L"-opt") && ShellCommandLineGetCount(Package) < 2) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else if (!ShellCommandLineGetFlag(Package, L"-opt") && ShellCommandLineGetCount(Package) < 3) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"driver") == 0) {\r
+ CurrentOperation.Target = BCFG_TARGET_DRIVER_ORDER;\r
+ } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"boot") == 0) {\r
+ CurrentOperation.Target = BCFG_TARGET_BOOT_ORDER;\r
+ } else {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT), gShellInstall1HiiHandle);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Read in if we are doing -OPT\r
+ //\r
+ if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BCFG_TARGET_MAX && ShellCommandLineGetFlag(Package, L"-opt")) {\r
+ CurrentOperation.OptData = ShellCommandLineGetValue(Package, L"-opt");\r
+ CurrentOperation.Type = BCFG_TYPE_OPT;\r
+ }\r
+\r
+ //\r
+ // Read in the boot or driver order environment variable (not needed for opt)\r
+ //\r
+ if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BCFG_TARGET_MAX && CurrentOperation.Type != BCFG_TYPE_OPT) {\r
+ Length = 0;\r
+ Status = gRT->GetVariable(\r
+ CurrentOperation.Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",\r
+ (EFI_GUID*)&gEfiGlobalVariableGuid,\r
+ NULL,\r
+ &Length,\r
+ CurrentOperation.Order);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ CurrentOperation.Order = AllocatePool(Length+(4*sizeof(CurrentOperation.Order[0])));\r
+ Status = gRT->GetVariable(\r
+ CurrentOperation.Target == BCFG_TARGET_BOOT_ORDER?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder",\r
+ (EFI_GUID*)&gEfiGlobalVariableGuid,\r
+ NULL,\r
+ &Length,\r
+ CurrentOperation.Order);\r
+ }\r
+ }\r
+\r
+ //\r
+ // large block to read the type of operation and verify parameter types for the info.\r
+ //\r
+ if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BCFG_TARGET_MAX) {\r
+ for (ParamNumber = 2 ; ParamNumber < ShellCommandLineGetCount(Package) && ShellStatus == SHELL_SUCCESS; ParamNumber++) {\r
+ CurrentParam = ShellCommandLineGetRawValue(Package, ParamNumber);\r
+ if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"dump") == 0) {\r
+ if (ShellCommandLineGetCount(Package) > 3) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellInstall1HiiHandle);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ }\r
+ CurrentOperation.Type = BCFG_TYPE_DUMP;\r
+ } else if (ShellCommandLineGetFlag(Package, L"-v")) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, L"-v (without dump)");\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"add") == 0) {\r
+ if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ }\r
+ CurrentOperation.Type = BCFG_TYPE_ADD;\r
+ CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
+ if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ CurrentOperation.Number1 = (UINT16)StrHexToUintn(CurrentParam);\r
+ ASSERT(CurrentOperation.FileName == NULL);\r
+ CurrentOperation.FileName = StrnCatGrow(&CurrentOperation.FileName , NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
+ ASSERT(CurrentOperation.Description == NULL);\r
+ CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
+ }\r
+ } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addp") == 0) {\r
+ if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ CurrentOperation.Type = BCFG_TYPE_ADDP;\r
+ CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
+ if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ CurrentOperation.Number1 = (UINT16)StrHexToUintn(CurrentParam);\r
+ ASSERT(CurrentOperation.FileName == NULL);\r
+ CurrentOperation.FileName = StrnCatGrow(&CurrentOperation.FileName , NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
+ ASSERT(CurrentOperation.Description == NULL);\r
+ CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
+ }\r
+ }\r
+ } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addh") == 0) {\r
+ if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ }\r
+ CurrentOperation.Type = BCFG_TYPE_ADDH;\r
+ CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
+ if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ CurrentOperation.Number1 = (UINT16)StrHexToUintn(CurrentParam);\r
+ CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
+ if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ CurrentOperation.HandleIndex = (UINT16)StrHexToUintn(CurrentParam);\r
+ ASSERT(CurrentOperation.Description == NULL);\r
+ CurrentOperation.Description = StrnCatGrow(&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue(Package, ++ParamNumber), 0);\r
+ }\r
+ }\r
+ } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"rm") == 0) {\r
+ if ((ParamNumber + 1) >= ShellCommandLineGetCount(Package)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ }\r
+ CurrentOperation.Type = BCFG_TYPE_RM;\r
+ CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
+ if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ CurrentOperation.Number1 = (UINT16)StrHexToUintn(CurrentParam);\r
+ if (CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))){\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_LOCATION_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"mv") == 0) {\r
+ if ((ParamNumber + 2) >= ShellCommandLineGetCount(Package)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellInstall1HiiHandle);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ }\r
+ CurrentOperation.Type = BCFG_TYPE_MV;\r
+ CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
+ if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ CurrentOperation.Number1 = (UINT16)StrHexToUintn(CurrentParam);\r
+ if (CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))){\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_LOCATION_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ }\r
+ CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
+ if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ CurrentOperation.Number2 = (UINT16)StrHexToUintn(CurrentParam);\r
+ }\r
+ if (CurrentOperation.Number2 == CurrentOperation.Number1\r
+ ||CurrentOperation.Number1 > (Length / sizeof(CurrentOperation.Order[0]))\r
+ ||CurrentOperation.Number2 > (Length / sizeof(CurrentOperation.Order[0]))\r
+ ){\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_LOCATION_RANGE), gShellInstall1HiiHandle, Length / sizeof(CurrentOperation.Order[0]));\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ } else {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, CurrentParam);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ }\r
+ if (ShellStatus == SHELL_SUCCESS && CurrentOperation.Target < BCFG_TARGET_MAX && CurrentOperation.Type < BCFG_TYPE_MAX) {\r
+ //\r
+ // we have all the info. Do the work\r
+ //\r
+ switch (CurrentOperation.Type) {\r
+ case BCFG_TYPE_DUMP:\r
+ ShellStatus = BcfgDisplayDumpInstall(\r
+ CurrentOperation.Target == BCFG_TARGET_BOOT_ORDER?L"Boot":L"Driver",\r
+ CurrentOperation.Order,\r
+ Length / sizeof(CurrentOperation.Order[0]),\r
+ ShellCommandLineGetFlag(Package, L"-v"));\r
+ break;\r
+ case BCFG_TYPE_MV:\r
+ ShellStatus = BcfgMoveInstall(\r
+ CurrentOperation.Target,\r
+ CurrentOperation.Order,\r
+ Length / sizeof(CurrentOperation.Order[0]),\r
+ CurrentOperation.Number1,\r
+ CurrentOperation.Number2);\r
+ break;\r
+ case BCFG_TYPE_RM:\r
+ ShellStatus = BcfgRemoveInstall(\r
+ CurrentOperation.Target,\r
+ CurrentOperation.Order,\r
+ (Length / sizeof(CurrentOperation.Order[0])),\r
+ CurrentOperation.Number1);\r
+ break;\r
+ case BCFG_TYPE_ADD:\r
+ case BCFG_TYPE_ADDP:\r
+ case BCFG_TYPE_ADDH:\r
+ ShellStatus = BcfgAddInstall(\r
+ CurrentOperation.Number1,\r
+ CurrentOperation.FileName,\r
+ CurrentOperation.Description,\r
+ CurrentOperation.Order,\r
+ Length / sizeof(CurrentOperation.Order[0]),\r
+ CurrentOperation.Target,\r
+ (BOOLEAN)(CurrentOperation.Type == BCFG_TYPE_ADDH),\r
+ (BOOLEAN)(CurrentOperation.Type == BCFG_TYPE_ADD ),\r
+ CurrentOperation.HandleIndex);\r
+ break;\r
+ case BCFG_TYPE_OPT:\r
+ ShellStatus = BcfgAddOptInstall(\r
+ CurrentOperation.Target,\r
+ CurrentOperation.OptData);\r
+ break;\r
+ default:\r
+ ASSERT(FALSE);\r
+ }\r
+ }\r
+ }\r
+\r
+ if (Package != NULL) {\r
+ ShellCommandLineFreeVarList (Package);\r
+ }\r
+ if (CurrentOperation.FileName != NULL) {\r
+ FreePool(CurrentOperation.FileName);\r
+ }\r
+ if (CurrentOperation.Description != NULL) {\r
+ FreePool(CurrentOperation.Description);\r
+ }\r
+ if (CurrentOperation.Order != NULL) {\r
+ FreePool(CurrentOperation.Order);\r
+ }\r
+\r
+ return (ShellStatus);\r
+}\r