]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellDriver1CommandsLib/DrvCfg.c
Adding Driver1 profile commands to the UEFI Shell 2.0.
[mirror_edk2.git] / ShellPkg / Library / UefiShellDriver1CommandsLib / DrvCfg.c
diff --git a/ShellPkg/Library/UefiShellDriver1CommandsLib/DrvCfg.c b/ShellPkg/Library/UefiShellDriver1CommandsLib/DrvCfg.c
new file mode 100644 (file)
index 0000000..1e0456d
--- /dev/null
@@ -0,0 +1,406 @@
+/** @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