--- /dev/null
+/** @file\r
+ Main file for DrvCfg shell Driver1 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 "UefiShellDriver1CommandsLib.h"\r
+#include <Protocol/HiiConfigAccess.h>\r
+#include <Protocol/HiiDatabase.h>\r
+\r
+/**\r
+ Function to validate configuration information on a configurable handle.\r
+\r
+ @param[in] Handle The handle to validate info on.\r
+ @param[in] HiiDb A pointer to the HII Database protocol.\r
+\r
+ @retval EFI_SUCCESS The operation was successful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ValidateConfigInfoOnSingleHandleHii(\r
+ IN CONST EFI_HANDLE Handle,\r
+ IN EFI_HII_DATABASE_PROTOCOL *HiiDb\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Size;\r
+ EFI_HII_HANDLE *HiiHandle;\r
+ EFI_HII_HANDLE *CurrentHandle;\r
+ EFI_HANDLE NormalHandle;\r
+\r
+ if (HiiDb == NULL || Handle == NULL) {\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+\r
+ Size = 0;\r
+ HiiHandle = NULL;\r
+\r
+ Status = HiiDb->ListPackageLists(\r
+ HiiDb,\r
+ EFI_HII_PACKAGE_TYPE_ALL,\r
+ NULL,\r
+ &Size,\r
+ HiiHandle);\r
+\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ HiiHandle = AllocateZeroPool(Size);\r
+ if (HiiHandle == NULL) {\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
+ Status = HiiDb->ListPackageLists(\r
+ HiiDb,\r
+ EFI_HII_PACKAGE_TYPE_ALL,\r
+ NULL,\r
+ &Size,\r
+ HiiHandle);\r
+ }\r
+ if (EFI_ERROR(Status)) {\r
+ SHELL_FREE_NON_NULL(HiiHandle);\r
+ return (Status);\r
+ }\r
+\r
+ for (CurrentHandle = HiiHandle ; CurrentHandle != NULL && *CurrentHandle != NULL ; CurrentHandle++) {\r
+ NormalHandle = NULL;\r
+ Status = HiiDb->GetPackageListHandle(\r
+ HiiDb,\r
+ *CurrentHandle,\r
+ &NormalHandle);\r
+ if (NormalHandle == Handle) {\r
+ break;\r
+ }\r
+ }\r
+\r
+\r
+\r
+\r
+\r
+ SHELL_FREE_NON_NULL(HiiHandle);\r
+ return (Status);\r
+}\r
+\r
+/**\r
+ Function to validate configuration information on all configurable handles.\r
+\r
+ @param[in] ChildrenToo TRUE to tewst for children.\r
+\r
+ @retval SHELL_SUCCESS The operation was successful.\r
+**/\r
+SHELL_STATUS\r
+EFIAPI\r
+ValidOptionsOnAll(\r
+ IN CONST BOOLEAN ChildrenToo\r
+ )\r
+{\r
+ EFI_HANDLE *HandleList;\r
+ EFI_HANDLE *CurrentHandle;\r
+ SHELL_STATUS ShellStatus;\r
+ EFI_STATUS Status;\r
+ BOOLEAN Found;\r
+ EFI_HII_DATABASE_PROTOCOL *HiiDb;\r
+\r
+ Found = FALSE;\r
+ HandleList = NULL;\r
+ ShellStatus = SHELL_SUCCESS;\r
+ Status = EFI_SUCCESS;\r
+\r
+ Status = gBS->LocateProtocol(&gEfiHiiDatabaseProtocolGuid, NULL, (VOID**)&HiiDb);\r
+ if (EFI_ERROR(Status)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROTOCOL_NF), gShellDriver1HiiHandle, L"gEfiHiiDatabaseProtocolGuid", &gEfiHiiDatabaseProtocolGuid);\r
+ return (Status);\r
+ }\r
+\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_HEADER), gShellDriver1HiiHandle);\r
+\r
+ //\r
+ // First do HII method\r
+ //\r
+ HandleList = GetHandleListByProtocol(&gEfiHiiConfigAccessProtocolGuid);\r
+ for (CurrentHandle = HandleList ; CurrentHandle != NULL && *CurrentHandle != NULL && ShellStatus == SHELL_SUCCESS; CurrentHandle++){\r
+ Found = TRUE;\r
+ ///@todo VALIDATE\r
+ }\r
+ SHELL_FREE_NON_NULL(HandleList);\r
+\r
+ //\r
+ // Now do EFI 1.10 & UEFI 2.0 drivers\r
+ //\r
+ HandleList = GetHandleListByProtocol(&gEfiDriverConfigurationProtocolGuid);\r
+ for (CurrentHandle = HandleList ; CurrentHandle != NULL && *CurrentHandle != NULL && ShellStatus == SHELL_SUCCESS; CurrentHandle++){\r
+ Found = TRUE;\r
+ ///@todo VALIDATE\r
+ }\r
+\r
+ if (!Found) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NONE), gShellDriver1HiiHandle);\r
+ return (SHELL_SUCCESS);\r
+ }\r
+\r
+ SHELL_FREE_NON_NULL(HandleList);\r
+ return (ShellStatus);\r
+}\r
+\r
+/**\r
+ Function to print out configuration information on a configurable handle.\r
+\r
+ @param[in] DriverHandle The driver handle to print info on.\r
+ @param[in] ControllerHandle The controllerHandle to print on.\r
+ @param[in] ChildrenToo TRUE to tewst for children.\r
+ @param[in] ProtocolMask BIT0 for HII, BIT1 for DirverConfiguration.\r
+\r
+ @retval SHELL_SUCCESS The operation was successful.\r
+**/\r
+SHELL_STATUS\r
+EFIAPI\r
+PrintConfigInfoOnSingleHandle(\r
+ IN CONST EFI_HANDLE DriverHandle,\r
+ IN CONST EFI_HANDLE ControllerHandle OPTIONAL,\r
+ IN CONST BOOLEAN ChildrenToo,\r
+ IN CONST UINT8 ProtocolMask // BIT0 - HII, BIT1 - DriverConfiguration\r
+ )\r
+{\r
+ UINTN Index1;\r
+ UINTN Index2;\r
+ EFI_HANDLE *ChildHandleList;\r
+ UINTN Count;\r
+ UINTN LoopVar;\r
+\r
+ Index1 = DriverHandle == NULL ? 0 : ConvertHandleToHandleIndex(DriverHandle );\r
+ Index2 = ControllerHandle == NULL ? 0 : ConvertHandleToHandleIndex(ControllerHandle);\r
+\r
+ if ((ProtocolMask & BIT0) == BIT0) {\r
+ ASSERT(Index1 == 0);\r
+ ShellPrintHiiEx(\r
+ -1, \r
+ -1, \r
+ NULL, \r
+ STRING_TOKEN (STR_DRVCFG_LINE_HII), \r
+ gShellDriver1HiiHandle, \r
+ Index2\r
+ );\r
+ }\r
+ if ((ProtocolMask & BIT1) == BIT1) {\r
+ PARSE_HANDLE_DATABASE_MANAGED_CHILDREN(DriverHandle, ControllerHandle, &Count, &ChildHandleList);\r
+ for (LoopVar = 0 ; LoopVar <= Count ; LoopVar++) {\r
+ ShellPrintHiiEx(\r
+ -1, \r
+ -1, \r
+ NULL, \r
+ STRING_TOKEN (STR_DRVCFG_LINE_DRV), \r
+ gShellDriver1HiiHandle, \r
+ Index1,\r
+ Index2,\r
+ Count != 0 ? ChildHandleList[LoopVar] : 0\r
+ );\r
+ }\r
+ }\r
+ return (SHELL_SUCCESS);\r
+}\r
+\r
+/**\r
+ Function to print out configuration information on all configurable handles.\r
+\r
+ @param[in] ChildrenToo TRUE to tewst for children.\r
+\r
+ @retval SHELL_SUCCESS The operation was successful.\r
+**/\r
+SHELL_STATUS\r
+EFIAPI\r
+PrintConfigInfoOnAll(\r
+ IN CONST BOOLEAN ChildrenToo\r
+ )\r
+{\r
+// lcoate all the HII_CONFIG_ACCESS_PROTOCOL - those are all configurable\r
+// then cross reference with EFI_DRIVER_CONFIGURATION_PROTOCOL - those are legacy configurable\r
+// can be on chlid, but that is ok... just find the driver\r
+ EFI_HANDLE *HandleList;\r
+ EFI_HANDLE *CurrentHandle;\r
+ EFI_HANDLE *DriverHandleList;\r
+ EFI_HANDLE *ParentHandleList;\r
+ EFI_HANDLE *CurrentDriver;\r
+ UINTN Count;\r
+ SHELL_STATUS ShellStatus;\r
+ EFI_STATUS Status;\r
+ UINTN LoopVar;\r
+ BOOLEAN Found;\r
+\r
+ Found = FALSE;\r
+ Count = 0;\r
+ HandleList = NULL;\r
+ CurrentHandle = NULL;\r
+ DriverHandleList = NULL;\r
+ CurrentDriver = NULL;\r
+ ShellStatus = SHELL_SUCCESS;\r
+\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_HEADER), gShellDriver1HiiHandle);\r
+ //\r
+ // First do HII method\r
+ //\r
+ HandleList = GetHandleListByProtocol(&gEfiHiiConfigAccessProtocolGuid);\r
+ for (CurrentHandle = HandleList ; CurrentHandle != NULL && *CurrentHandle != NULL && ShellStatus == SHELL_SUCCESS; CurrentHandle++){\r
+ // is this a driver handle itself? if yes print options for it.\r
+ if (!EFI_ERROR(gBS->OpenProtocol(*CurrentHandle, &gEfiDriverBindingProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {\r
+ ShellStatus = PrintConfigInfoOnSingleHandle(*CurrentHandle, NULL, ChildrenToo, BIT0);\r
+ } else {\r
+ // get its driver and print options for it.\r
+ Count = 0;\r
+ Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS(*CurrentHandle, &Count, &DriverHandleList);\r
+ if (EFI_ERROR(Status)) {\r
+ Status = PARSE_HANDLE_DATABASE_PARENTS(*CurrentHandle, &Count, &ParentHandleList);\r
+ if (!EFI_ERROR(Status)) {\r
+ Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS(*ParentHandleList, &Count, &DriverHandleList);\r
+ }\r
+ }\r
+ if (Count == 0) {\r
+ Found = TRUE;\r
+ ShellStatus = PrintConfigInfoOnSingleHandle(NULL, *CurrentHandle, ChildrenToo, BIT0);\r
+ } else if (DriverHandleList != NULL) {\r
+ for (LoopVar = 0 ; LoopVar < Count ; LoopVar++) {\r
+ Found = TRUE;\r
+ ShellStatus = PrintConfigInfoOnSingleHandle(DriverHandleList[LoopVar], *CurrentHandle, ChildrenToo, BIT0);\r
+ }\r
+ }\r
+ SHELL_FREE_NON_NULL(DriverHandleList);\r
+ }\r
+ }\r
+ SHELL_FREE_NON_NULL(HandleList);\r
+\r
+ //\r
+ // Now do EFI 1.10 & UEFI 2.0 drivers\r
+ //\r
+ HandleList = GetHandleListByProtocol(&gEfiDriverConfigurationProtocolGuid);\r
+ for (CurrentHandle = HandleList ; CurrentHandle != NULL && *CurrentHandle != NULL && ShellStatus == SHELL_SUCCESS; CurrentHandle++){\r
+ Found = TRUE;\r
+ ShellStatus = PrintConfigInfoOnSingleHandle(*CurrentHandle, NULL, ChildrenToo, BIT1);\r
+ }\r
+ SHELL_FREE_NON_NULL(HandleList);\r
+ if (!Found) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NONE), gShellDriver1HiiHandle);\r
+ return (SHELL_SUCCESS);\r
+ }\r
+ return (ShellStatus);\r
+}\r
+\r
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
+ {L"-c", TypeFlag},\r
+ {L"-s", TypeFlag},\r
+ {L"-v", TypeFlag},\r
+ {L"-l", TypeValue},\r
+ {L"-f", TypeValue},\r
+ {L"-o", TypeValue},\r
+ {L"-i", TypeValue},\r
+ {NULL, TypeMax}\r
+ };\r
+\r
+SHELL_STATUS\r
+EFIAPI\r
+ShellCommandRunDrvCfg (\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
+ CHAR8 *Language;\r
+ CONST CHAR16 *Lang;\r
+ CONST CHAR16 *Temp2;\r
+\r
+ ShellStatus = SHELL_SUCCESS;\r
+ Status = EFI_SUCCESS;\r
+ Language = NULL;\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), gShellDriver1HiiHandle, ProblemParam);\r
+ FreePool(ProblemParam);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ ASSERT(FALSE);\r
+ }\r
+ } else {\r
+ Lang = ShellCommandLineGetValue(Package, L"-l");\r
+ if (Lang != NULL) {\r
+ Language = AllocateZeroPool(StrSize(Lang));\r
+ AsciiSPrint(Language, StrSize(Lang), "%S", Lang);\r
+ } else if (!ShellCommandLineGetFlag(Package, L"-l")){\r
+ Language = AllocateZeroPool(10);\r
+ AsciiSPrint(Language, 10, "en-us");\r
+ } else {\r
+ ASSERT(Language == NULL);\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"-l");\r
+ ShellCommandLineFreeVarList (Package);\r
+ return (SHELL_INVALID_PARAMETER);\r
+ }\r
+\r
+ //\r
+ // Should be DriverHandle\r
+ //\r
+ Temp2 = ShellCommandLineGetRawValue(Package, 1);\r
+ if (Temp2 == NULL) {\r
+ //\r
+ // no driver specified. cannot be export, inport, or set (and no specified language)\r
+ //\r
+ if (ShellCommandLineGetFlag(Package, L"-s")\r
+ ||ShellCommandLineGetFlag(Package, L"-l")\r
+ ||ShellCommandLineGetFlag(Package, L"-o")\r
+ ||ShellCommandLineGetFlag(Package, L"-i")) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_HANDLE_REQ), gShellDriver1HiiHandle);\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ //\r
+ // do a loop for validation, forcing, or printing\r
+ //\r
+ if (ShellCommandLineGetFlag(Package, L"-v") && ShellCommandLineGetFlag(Package, L"-f")) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONF), gShellDriver1HiiHandle, L"-v", L"-f");\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else if (ShellCommandLineGetFlag(Package, L"-v")){\r
+ //\r
+ // validate\r
+ //\r
+ ShellStatus = ValidOptionsOnAll(ShellCommandLineGetFlag(Package, L"-c"));\r
+ } else if (ShellCommandLineGetFlag(Package, L"-f")){\r
+ //\r
+ // force\r
+ //\r
+ASSERT(FALSE);// ShellStatus = ForceOptionsOnAll(ShellCommandLineGetFlag(Package, L"-c"));\r
+ } else {\r
+ //\r
+ // display all that are configurable\r
+ //\r
+ ShellStatus = PrintConfigInfoOnAll(ShellCommandLineGetFlag(Package, L"-c"));\r
+ }\r
+ }\r
+ } else {\r
+ //\r
+ // we have a driver handle, make sure it's valid then process it...\r
+ //\r
+ ASSERT(FALSE);\r
+ }\r
+ }\r
+ ShellCommandLineFreeVarList (Package);\r
+ SHELL_FREE_NON_NULL(Language);\r
+ return (ShellStatus);\r
+}\r