]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellDriver1CommandsLib/DrvCfg.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / Library / UefiShellDriver1CommandsLib / DrvCfg.c
index 074a49c3beb2e2a592630653831675b59f308285..9bbbb1444dadd19bfb59784f001bb2d00dcf5630 100644 (file)
@@ -1,14 +1,9 @@
 /** @file\r
   Main file for DrvCfg shell Driver1 function.\r
 \r
-  Copyright (c) 2010 - 2011, 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
+  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
+  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include <Protocol/HiiConfigAccess.h>\r
 #include <Protocol/HiiDatabase.h>\r
 \r
+STATIC CONST EFI_GUID  *CfgGuidList[] = { &gEfiDriverConfigurationProtocolGuid, &gEfiDriverConfiguration2ProtocolGuid, NULL };\r
+\r
 /**\r
-  Function to validate configuration information on a configurable handle.\r
+  Find the EFI_HII_HANDLE by device path.\r
 \r
-  @param[in] Handle           The handle to validate info on.\r
-  @param[in] HiiDb            A pointer to the HII Database protocol.\r
+  @param[in] DevPath1     The Device Path to match.\r
+  @param[out] HiiHandle   The EFI_HII_HANDLE after the converstion.\r
+  @param[in] HiiDb        The Hii database protocol\r
 \r
-  @retval EFI_SUCCESS       The operation was successful.\r
+  @retval EFI_SUCCESS     The operation was successful.\r
+  @retval EFI_NOT_FOUND   There was no EFI_HII_HANDLE found for that deviec path.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
-ValidateConfigInfoOnSingleHandleHii(\r
-  IN CONST EFI_HANDLE             Handle,\r
-  IN EFI_HII_DATABASE_PROTOCOL    *HiiDb\r
+FindHiiHandleViaDevPath (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevPath1,\r
+  OUT EFI_HII_HANDLE                 *HiiHandle,\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
+  EFI_HII_HANDLE               *HandleBuffer;\r
+  UINTN                        HandleBufferSize;\r
+  VOID                         *MainBuffer;\r
+  UINTN                        MainBufferSize;\r
+  EFI_HII_PACKAGE_LIST_HEADER  *PackageListHeader;\r
+  EFI_HII_PACKAGE_HEADER       *PackageHeader;\r
+  UINTN                        LoopVariable;\r
+  EFI_DEVICE_PATH_PROTOCOL     *DevPath2;\r
+  EFI_STATUS                   Status;\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
+  ASSERT (DevPath1 != NULL);\r
+  ASSERT (HiiHandle != NULL);\r
+  ASSERT (*HiiHandle == NULL);\r
+  ASSERT (HiiDb != NULL);\r
 \r
+  HandleBufferSize = 0;\r
+  HandleBuffer     = NULL;\r
+  Status           = HiiDb->ListPackageLists (HiiDb, EFI_HII_PACKAGE_DEVICE_PATH, NULL, &HandleBufferSize, HandleBuffer);\r
   if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    HiiHandle = AllocateZeroPool(Size);\r
-    if (HiiHandle == NULL) {\r
-      return (EFI_OUT_OF_RESOURCES);\r
+    HandleBuffer = AllocateZeroPool (HandleBufferSize);\r
+    if (HandleBuffer == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+    } else {\r
+      Status = HiiDb->ListPackageLists (HiiDb, EFI_HII_PACKAGE_DEVICE_PATH, NULL, &HandleBufferSize, HandleBuffer);\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
+\r
+  if (EFI_ERROR (Status)) {\r
+    SHELL_FREE_NON_NULL (HandleBuffer);\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
+  if (HandleBuffer == NULL) {\r
+    return EFI_NOT_FOUND;\r
   }\r
 \r
+  for (LoopVariable = 0; LoopVariable < (HandleBufferSize/sizeof (HandleBuffer[0])) && *HiiHandle == NULL; LoopVariable++) {\r
+    MainBufferSize = 0;\r
+    MainBuffer     = NULL;\r
+    Status         = HiiDb->ExportPackageLists (HiiDb, HandleBuffer[LoopVariable], &MainBufferSize, MainBuffer);\r
+    if (Status == EFI_BUFFER_TOO_SMALL) {\r
+      MainBuffer = AllocateZeroPool (MainBufferSize);\r
+      if (MainBuffer != NULL) {\r
+        Status = HiiDb->ExportPackageLists (HiiDb, HandleBuffer[LoopVariable], &MainBufferSize, MainBuffer);\r
+      }\r
+    }\r
 \r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
 \r
+    //\r
+    // Enumerate through the block of returned memory.\r
+    // This should actually be a small block, but we need to be sure.\r
+    //\r
+    for (PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)MainBuffer\r
+         ; PackageListHeader != NULL && ((CHAR8 *)PackageListHeader) < (((CHAR8 *)MainBuffer)+MainBufferSize) && *HiiHandle == NULL\r
+         ; PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)(((CHAR8 *)(PackageListHeader)) + PackageListHeader->PackageLength))\r
+    {\r
+      for (PackageHeader = (EFI_HII_PACKAGE_HEADER *)(((CHAR8 *)(PackageListHeader))+sizeof (EFI_HII_PACKAGE_LIST_HEADER))\r
+           ; PackageHeader != NULL && ((CHAR8 *)PackageHeader) < (((CHAR8 *)MainBuffer)+MainBufferSize) && PackageHeader->Type != EFI_HII_PACKAGE_END && *HiiHandle == NULL\r
+           ; PackageHeader = (EFI_HII_PACKAGE_HEADER *)(((CHAR8 *)(PackageHeader))+PackageHeader->Length))\r
+      {\r
+        if (PackageHeader->Type == EFI_HII_PACKAGE_DEVICE_PATH) {\r
+          DevPath2 = (EFI_DEVICE_PATH_PROTOCOL *)(((CHAR8 *)PackageHeader) + sizeof (EFI_HII_PACKAGE_HEADER));\r
+          if (DevicePathCompare (&DevPath1, &DevPath2) == 0) {\r
+            *HiiHandle = HandleBuffer[LoopVariable];\r
+            break;\r
+          }\r
+        }\r
+      }\r
+    }\r
+\r
+    SHELL_FREE_NON_NULL (MainBuffer);\r
+  }\r
 \r
+  SHELL_FREE_NON_NULL (HandleBuffer);\r
+\r
+  if (*HiiHandle == NULL) {\r
+    return (EFI_NOT_FOUND);\r
+  }\r
 \r
-  SHELL_FREE_NON_NULL(HiiHandle);\r
-  return (Status);\r
+  return (EFI_SUCCESS);\r
 }\r
 \r
 /**\r
-  Function to validate configuration information on all configurable handles.\r
+  Convert a EFI_HANDLE to a EFI_HII_HANDLE.\r
 \r
-  @param[in] ChildrenToo    TRUE to tewst for children.\r
+  @param[in] Handle       The EFI_HANDLE to convert.\r
+  @param[out] HiiHandle   The EFI_HII_HANDLE after the converstion.\r
+  @param[in] HiiDb        The Hii database protocol\r
 \r
-  @retval SHELL_SUCCESS     The operation was successful.\r
+  @retval EFI_SUCCESS   The operation was successful.\r
 **/\r
-SHELL_STATUS\r
-EFIAPI\r
-ValidOptionsOnAll(\r
-  IN CONST BOOLEAN ChildrenToo\r
+EFI_STATUS\r
+ConvertHandleToHiiHandle (\r
+  IN CONST EFI_HANDLE           Handle,\r
+  OUT EFI_HII_HANDLE            *HiiHandle,\r
+  IN EFI_HII_DATABASE_PROTOCOL  *HiiDb\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 (SHELL_NOT_FOUND);\r
+  EFI_STATUS                Status;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevPath1;\r
+\r
+  if ((HiiHandle == NULL) || (HiiDb == NULL)) {\r
+    return (EFI_INVALID_PARAMETER);\r
+  }\r
+\r
+  *HiiHandle = NULL;\r
+\r
+  if (Handle == NULL) {\r
+    return (EFI_SUCCESS);\r
   }\r
 \r
-  ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_HEADER), gShellDriver1HiiHandle);\r
+  DevPath1 = NULL;\r
+  Status   = gBS->OpenProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPath1, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
+  if (EFI_ERROR (Status) || (DevPath1 == NULL)) {\r
+    return (EFI_NOT_FOUND);\r
+  }\r
+\r
+  return (FindHiiHandleViaDevPath (DevPath1, HiiHandle, HiiDb));\r
+}\r
+\r
+/**\r
+  Function to print out all HII configuration information to a file.\r
+\r
+  @param[in] Handle           The handle to get info on.  NULL to do all handles.\r
+  @param[in] FileName         The filename to rwite the info to.\r
+**/\r
+SHELL_STATUS\r
+ConfigToFile (\r
+  IN CONST EFI_HANDLE  Handle,\r
+  IN CONST CHAR16      *FileName\r
+  )\r
+{\r
+  EFI_HII_DATABASE_PROTOCOL  *HiiDatabase;\r
+  EFI_STATUS                 Status;\r
+  VOID                       *MainBuffer;\r
+  UINTN                      MainBufferSize;\r
+  EFI_HII_HANDLE             HiiHandle;\r
+  SHELL_FILE_HANDLE          FileHandle;\r
+\r
+  HiiDatabase    = NULL;\r
+  MainBufferSize = 0;\r
+  MainBuffer     = NULL;\r
+  FileHandle     = NULL;\r
+\r
+  Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL),\r
+      gShellDriver1HiiHandle,\r
+      L"drvcfg",\r
+      FileName,\r
+      Status\r
+      );\r
+    return (SHELL_DEVICE_ERROR);\r
+  }\r
 \r
   //\r
-  // First do HII method\r
+  // Locate HII Database protocol\r
   //\r
-  HandleList = GetHandleListByProtocol(&gEfiHiiConfigAccessProtocolGuid);\r
-  for (CurrentHandle = HandleList ; CurrentHandle != NULL && *CurrentHandle != NULL && ShellStatus == SHELL_SUCCESS; CurrentHandle++){\r
-    Found = TRUE;\r
-    ///@todo VALIDATE\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiHiiDatabaseProtocolGuid,\r
+                  NULL,\r
+                  (VOID **)&HiiDatabase\r
+                  );\r
+\r
+  if (EFI_ERROR (Status) || (HiiDatabase == NULL)) {\r
+    ShellPrintHiiEx (\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_GEN_PROTOCOL_NF),\r
+      gShellDriver1HiiHandle,\r
+      L"drvcfg",\r
+      L"EfiHiiDatabaseProtocol",\r
+      &gEfiHiiDatabaseProtocolGuid\r
+      );\r
+    ShellCloseFile (&FileHandle);\r
+    return (SHELL_NOT_FOUND);\r
+  }\r
+\r
+  HiiHandle = NULL;\r
+  Status    = ConvertHandleToHiiHandle (Handle, &HiiHandle, HiiDatabase);\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_GEN_HANDLE_NOT),\r
+      gShellDriver1HiiHandle,\r
+      L"drvcfg",\r
+      ConvertHandleToHandleIndex (Handle),\r
+      L"Device"\r
+      );\r
+    ShellCloseFile (&FileHandle);\r
+    return (SHELL_DEVICE_ERROR);\r
+  }\r
+\r
+  Status = HiiDatabase->ExportPackageLists (HiiDatabase, HiiHandle, &MainBufferSize, MainBuffer);\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    MainBuffer = AllocateZeroPool (MainBufferSize);\r
+    Status     = HiiDatabase->ExportPackageLists (HiiDatabase, HiiHandle, &MainBufferSize, MainBuffer);\r
+  }\r
+\r
+  Status = ShellWriteFile (FileHandle, &MainBufferSize, MainBuffer);\r
+\r
+  ShellCloseFile (&FileHandle);\r
+  SHELL_FREE_NON_NULL (MainBuffer);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_FILE_WRITE_FAIL),\r
+      gShellDriver1HiiHandle,\r
+      L"drvcfg",\r
+      FileName\r
+      );\r
+    return (SHELL_DEVICE_ERROR);\r
+  }\r
+\r
+  ShellPrintHiiEx (\r
+    -1,\r
+    -1,\r
+    NULL,\r
+    STRING_TOKEN (STR_DRVCFG_COMP),\r
+    gShellDriver1HiiHandle\r
+    );\r
+\r
+  return (SHELL_SUCCESS);\r
+}\r
+\r
+/**\r
+  Function to read in HII configuration information from a file.\r
+\r
+  @param[in] Handle           The handle to get info for.\r
+  @param[in] FileName         The filename to read the info from.\r
+**/\r
+SHELL_STATUS\r
+ConfigFromFile (\r
+  IN       EFI_HANDLE  Handle,\r
+  IN CONST CHAR16      *FileName\r
+  )\r
+{\r
+  EFI_HII_DATABASE_PROTOCOL    *HiiDatabase;\r
+  EFI_STATUS                   Status;\r
+  VOID                         *MainBuffer;\r
+  UINT64                       Temp;\r
+  UINTN                        MainBufferSize;\r
+  EFI_HII_HANDLE               HiiHandle;\r
+  SHELL_FILE_HANDLE            FileHandle;\r
+  CHAR16                       *TempDevPathString;\r
+  EFI_HII_PACKAGE_LIST_HEADER  *PackageListHeader;\r
+  EFI_HII_PACKAGE_HEADER       *PackageHeader;\r
+  EFI_DEVICE_PATH_PROTOCOL     *DevPath;\r
+  UINTN                        HandleIndex;\r
+\r
+  HiiDatabase    = NULL;\r
+  MainBufferSize = 0;\r
+  MainBuffer     = NULL;\r
+  FileHandle     = NULL;\r
+\r
+  Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL),\r
+      gShellDriver1HiiHandle,\r
+      L"drvcfg",\r
+      FileName,\r
+      Status\r
+      );\r
+    return (SHELL_DEVICE_ERROR);\r
   }\r
-  SHELL_FREE_NON_NULL(HandleList);\r
 \r
   //\r
-  // Now do EFI 1.10 & UEFI 2.0 drivers\r
+  // Locate HII Database protocol\r
   //\r
-  HandleList = GetHandleListByProtocol(&gEfiDriverConfigurationProtocolGuid);\r
-  for (CurrentHandle = HandleList ; CurrentHandle != NULL && *CurrentHandle != NULL && ShellStatus == SHELL_SUCCESS; CurrentHandle++){\r
-    Found = TRUE;\r
-    ///@todo VALIDATE\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiHiiDatabaseProtocolGuid,\r
+                  NULL,\r
+                  (VOID **)&HiiDatabase\r
+                  );\r
+\r
+  if (EFI_ERROR (Status) || (HiiDatabase == NULL)) {\r
+    ShellPrintHiiEx (\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_GEN_PROTOCOL_NF),\r
+      gShellDriver1HiiHandle,\r
+      L"drvcfg",\r
+      L"EfiHiiDatabaseProtocol",\r
+      &gEfiHiiDatabaseProtocolGuid\r
+      );\r
+    ShellCloseFile (&FileHandle);\r
+    return (SHELL_NOT_FOUND);\r
   }\r
 \r
-  if (!Found) {\r
-    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NONE), gShellDriver1HiiHandle);\r
-    return (SHELL_SUCCESS);\r
+  Status         = ShellGetFileSize (FileHandle, &Temp);\r
+  MainBufferSize = (UINTN)Temp;\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_FILE_READ_FAIL),\r
+      gShellDriver1HiiHandle,\r
+      L"drvcfg",\r
+      FileName\r
+      );\r
+\r
+    ShellCloseFile (&FileHandle);\r
+    return (SHELL_DEVICE_ERROR);\r
   }\r
 \r
-  SHELL_FREE_NON_NULL(HandleList);\r
-  return (ShellStatus);\r
+  MainBuffer = AllocateZeroPool ((UINTN)MainBufferSize);\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_GEN_OUT_MEM),\r
+      gShellDriver1HiiHandle,\r
+      L"drvcfg"\r
+      );\r
+    ShellCloseFile (&FileHandle);\r
+    return (SHELL_DEVICE_ERROR);\r
+  }\r
+\r
+  Status = ShellReadFile (FileHandle, &MainBufferSize, MainBuffer);\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_FILE_READ_FAIL),\r
+      gShellDriver1HiiHandle,\r
+      L"drvcfg",\r
+      FileName\r
+      );\r
+\r
+    ShellCloseFile (&FileHandle);\r
+    SHELL_FREE_NON_NULL (MainBuffer);\r
+    return (SHELL_DEVICE_ERROR);\r
+  }\r
+\r
+  ShellCloseFile (&FileHandle);\r
+\r
+  if (Handle != NULL) {\r
+    //\r
+    // User override in place.  Just do it.\r
+    //\r
+    HiiHandle = NULL;\r
+    Status    = ConvertHandleToHiiHandle (Handle, &HiiHandle, HiiDatabase);\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_GEN_HANDLE_NOT),\r
+        gShellDriver1HiiHandle,\r
+        L"drvcfg",\r
+        ConvertHandleToHandleIndex (Handle),\r
+        L"Device"\r
+        );\r
+      ShellCloseFile (&FileHandle);\r
+      return (SHELL_DEVICE_ERROR);\r
+    }\r
+\r
+    Status = HiiDatabase->UpdatePackageList (HiiDatabase, HiiHandle, MainBuffer);\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN),\r
+        gShellDriver1HiiHandle,\r
+        L"drvcfg",\r
+        L"HiiDatabase->UpdatePackageList",\r
+        Status\r
+        );\r
+      return (SHELL_DEVICE_ERROR);\r
+    }\r
+  } else {\r
+    //\r
+    // we need to parse the buffer and try to match the device paths for each item to try to find it's device path.\r
+    //\r
+\r
+    for (PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)MainBuffer\r
+         ; PackageListHeader != NULL && ((CHAR8 *)PackageListHeader) < (((CHAR8 *)MainBuffer)+MainBufferSize)\r
+         ; PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)(((CHAR8 *)(PackageListHeader)) + PackageListHeader->PackageLength))\r
+    {\r
+      for (PackageHeader = (EFI_HII_PACKAGE_HEADER *)(((CHAR8 *)(PackageListHeader))+sizeof (EFI_HII_PACKAGE_LIST_HEADER))\r
+           ; PackageHeader != NULL && ((CHAR8 *)PackageHeader) < (((CHAR8 *)MainBuffer)+MainBufferSize) && PackageHeader->Type != EFI_HII_PACKAGE_END\r
+           ; PackageHeader = (EFI_HII_PACKAGE_HEADER *)(((CHAR8 *)(PackageHeader))+PackageHeader->Length))\r
+      {\r
+        if (PackageHeader->Type == EFI_HII_PACKAGE_DEVICE_PATH) {\r
+          HiiHandle = NULL;\r
+          Status    = FindHiiHandleViaDevPath ((EFI_DEVICE_PATH_PROTOCOL *)(((CHAR8 *)PackageHeader) + sizeof (EFI_HII_PACKAGE_HEADER)), &HiiHandle, HiiDatabase);\r
+          if (EFI_ERROR (Status)) {\r
+            //\r
+            // print out an error.\r
+            //\r
+            TempDevPathString = ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL *)(((CHAR8 *)PackageHeader) + sizeof (EFI_HII_PACKAGE_HEADER)), TRUE, TRUE);\r
+            ShellPrintHiiEx (\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_IN_FILE_NF),\r
+              gShellDriver1HiiHandle,\r
+              TempDevPathString\r
+              );\r
+            SHELL_FREE_NON_NULL (TempDevPathString);\r
+          } else {\r
+            Status = HiiDatabase->UpdatePackageList (HiiDatabase, HiiHandle, PackageListHeader);\r
+            if (EFI_ERROR (Status)) {\r
+              ShellPrintHiiEx (\r
+                -1,\r
+                -1,\r
+                NULL,\r
+                STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN),\r
+                gShellDriver1HiiHandle,\r
+                L"drvcfg",\r
+                L"HiiDatabase->UpdatePackageList",\r
+                Status\r
+                );\r
+              return (SHELL_DEVICE_ERROR);\r
+            } else {\r
+              DevPath = (EFI_DEVICE_PATH_PROTOCOL *)(((CHAR8 *)PackageHeader) + sizeof (EFI_HII_PACKAGE_HEADER));\r
+              gBS->LocateDevicePath (&gEfiHiiConfigAccessProtocolGuid, &DevPath, &Handle);\r
+              HandleIndex = ConvertHandleToHandleIndex (Handle);\r
+              ShellPrintHiiEx (\r
+                -1,\r
+                -1,\r
+                NULL,\r
+                STRING_TOKEN (STR_DRVCFG_DONE_HII),\r
+                gShellDriver1HiiHandle,\r
+                HandleIndex\r
+                );\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  SHELL_FREE_NON_NULL (MainBuffer);\r
+\r
+  ShellPrintHiiEx (\r
+    -1,\r
+    -1,\r
+    NULL,\r
+    STRING_TOKEN (STR_DRVCFG_COMP),\r
+    gShellDriver1HiiHandle\r
+    );\r
+  return (SHELL_SUCCESS);\r
+}\r
+\r
+/**\r
+  Present a requested action to the user.\r
+\r
+  @param[in] DriverImageHandle  The handle for the driver to configure.\r
+  @param[in] ControllerHandle   The handle of the device being managed by the Driver specified.\r
+  @param[in] ChildHandle        The handle of a child device of the specified device.\r
+  @param[in] ActionRequired     The required HII action.\r
+\r
+  @retval SHELL_INVALID_PARAMETER   A parameter has a invalid value.\r
+**/\r
+EFI_STATUS\r
+ShellCmdDriverConfigurationProcessActionRequired (\r
+  EFI_HANDLE                                DriverImageHandle,\r
+  EFI_HANDLE                                ControllerHandle,\r
+  EFI_HANDLE                                ChildHandle,\r
+  EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED  ActionRequired\r
+  )\r
+{\r
+  EFI_HANDLE  ConnectControllerContextOverride[2];\r
+\r
+  switch (ActionRequired) {\r
+    case EfiDriverConfigurationActionNone:\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NONE), gShellDriver1HiiHandle);\r
+      break;\r
+\r
+    case EfiDriverConfigurationActionStopController:\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_STOP), gShellDriver1HiiHandle);\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_ENTER_S), gShellDriver1HiiHandle, L"stop controller");\r
+      ShellPromptForResponse (ShellPromptResponseTypeEnterContinue, NULL, NULL);\r
+\r
+      gBS->DisconnectController (ControllerHandle, DriverImageHandle, ChildHandle);\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_CTLR_S), gShellDriver1HiiHandle, L"stopped");\r
+      break;\r
+\r
+    case EfiDriverConfigurationActionRestartController:\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_RESTART_S), gShellDriver1HiiHandle, L"controller");\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_ENTER_S), gShellDriver1HiiHandle, L"restart controller");\r
+      ShellPromptForResponse (ShellPromptResponseTypeEnterContinue, NULL, NULL);\r
+\r
+      gBS->DisconnectController (ControllerHandle, DriverImageHandle, ChildHandle);\r
+      ConnectControllerContextOverride[0] = DriverImageHandle;\r
+      ConnectControllerContextOverride[1] = NULL;\r
+      gBS->ConnectController (ControllerHandle, ConnectControllerContextOverride, NULL, TRUE);\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_CTLR_S), gShellDriver1HiiHandle, L"restarted");\r
+      break;\r
+\r
+    case EfiDriverConfigurationActionRestartPlatform:\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_RESTART_S), gShellDriver1HiiHandle, L"platform");\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_ENTER_S), gShellDriver1HiiHandle, L"restart platform");\r
+      ShellPromptForResponse (ShellPromptResponseTypeEnterContinue, NULL, NULL);\r
+\r
+      gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
+      break;\r
+\r
+    default:\r
+      return (EFI_INVALID_PARAMETER);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  Function to print out configuration information on a configurable handle.\r
+  Do the configuration in an environment without HII.\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
+  @param[in] Language           The language code.\r
+  @param[in] ForceDefaults      TRUE to force defaults, FALSE otherwise.\r
+  @param[in] DefaultType        If ForceDefaults is TRUE, specifies the default type.\r
+  @param[in] AllChildren        TRUE to configure all children, FALSE otherwise.\r
+  @param[in] ValidateOptions    TRUE to validate existing options, FALSE otherwise.\r
+  @param[in] SetOptions         TRUE to set options, FALSE otherwise.\r
+  @param[in] DriverImageHandle  The handle for the driver to configure.\r
+  @param[in] DeviceHandle       The handle of the device being managed by the Driver specified.\r
+  @param[in] ChildHandle        The handle of a child device of the specified device.\r
 \r
-  @retval SHELL_SUCCESS       The operation was successful.\r
+  @retval SHELL_NOT_FOUND           A specified handle could not be found.\r
+  @retval SHELL_INVALID_PARAMETER   A parameter has a invalid value.\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
+PreHiiDrvCfg (\r
+  IN CONST CHAR8  *Language,\r
+  IN BOOLEAN      ForceDefaults,\r
+  IN UINT32       DefaultType,\r
+  IN BOOLEAN      AllChildren,\r
+  IN BOOLEAN      ValidateOptions,\r
+  IN BOOLEAN      SetOptions,\r
+  IN EFI_HANDLE   DriverImageHandle,\r
+  IN EFI_HANDLE   DeviceHandle,\r
+  IN EFI_HANDLE   ChildHandle\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
+  EFI_STATUS                                Status;\r
+  SHELL_STATUS                              ShellStatus;\r
+  UINTN                                     OuterLoopCounter;\r
+  CHAR8                                     *BestLanguage;\r
+  UINTN                                     DriverImageHandleCount;\r
+  EFI_HANDLE                                *DriverImageHandleBuffer;\r
+  UINTN                                     HandleCount;\r
+  EFI_HANDLE                                *HandleBuffer;\r
+  UINTN                                     *HandleType;\r
+  UINTN                                     LoopCounter;\r
+  UINTN                                     ChildIndex;\r
+  UINTN                                     ChildHandleCount;\r
+  EFI_HANDLE                                *ChildHandleBuffer;\r
+  UINTN                                     *ChildHandleType;\r
+  EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED  ActionRequired;\r
+  EFI_DRIVER_CONFIGURATION_PROTOCOL         *DriverConfiguration;\r
+  BOOLEAN                                   Iso639Language;\r
+  UINTN                                     HandleIndex1;\r
+  UINTN                                     HandleIndex2;\r
+  UINTN                                     HandleIndex3;\r
+\r
+  ShellStatus = SHELL_SUCCESS;\r
+\r
+  if ((ChildHandle == NULL) && AllChildren) {\r
+    SetOptions = FALSE;\r
+  }\r
+\r
+  if (ForceDefaults) {\r
+    ShellPrintHiiEx (\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_DRVCFG_FORCE_D),\r
+      gShellDriver1HiiHandle,\r
+      DefaultType\r
+      );\r
+  } else if (ValidateOptions) {\r
+    ShellPrintHiiEx (\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_DRVCFG_VALIDATE),\r
+      gShellDriver1HiiHandle\r
+      );\r
+  } else if (SetOptions) {\r
+    ShellPrintHiiEx (\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_DRVCFG_SET),\r
+      gShellDriver1HiiHandle\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
+  if (DriverImageHandle == 0) {\r
+    DriverImageHandleBuffer = GetHandleListByProtocolList (CfgGuidList);\r
+    if (DriverImageHandleBuffer == NULL) {\r
+      ShellStatus = SHELL_NOT_FOUND;\r
+      goto Done;\r
+    }\r
+\r
+    for (\r
+         HandleBuffer = DriverImageHandleBuffer, DriverImageHandleCount = 0\r
+         ; HandleBuffer != NULL && *HandleBuffer != NULL\r
+         ; HandleBuffer++, DriverImageHandleCount++)\r
+    {\r
+    }\r
+  } else {\r
+    DriverImageHandleCount = 1;\r
+    //\r
+    // Allocate buffer to hold the image handle so as to\r
+    // keep consistent with the above clause\r
+    //\r
+    DriverImageHandleBuffer = AllocatePool (sizeof (EFI_HANDLE));\r
+    ASSERT (DriverImageHandleBuffer);\r
+    DriverImageHandleBuffer[0] = DriverImageHandle;\r
+  }\r
+\r
+  for (OuterLoopCounter = 0; OuterLoopCounter < DriverImageHandleCount; OuterLoopCounter++) {\r
+    Iso639Language = FALSE;\r
+    Status         = gBS->OpenProtocol (\r
+                            DriverImageHandleBuffer[OuterLoopCounter],\r
+                            &gEfiDriverConfiguration2ProtocolGuid,\r
+                            (VOID **)&DriverConfiguration,\r
+                            NULL,\r
+                            NULL,\r
+                            EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                            );\r
+    if (EFI_ERROR (Status)) {\r
+      Iso639Language = TRUE;\r
+      Status         = gBS->OpenProtocol (\r
+                              DriverImageHandleBuffer[OuterLoopCounter],\r
+                              &gEfiDriverConfigurationProtocolGuid,\r
+                              (VOID **)&DriverConfiguration,\r
+                              NULL,\r
+                              NULL,\r
+                              EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                              );\r
+    }\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      //      ShellPrintHiiEx(\r
+      //        -1,\r
+      //        -1,\r
+      //        NULL,\r
+      //        STRING_TOKEN (STR_DRVCFG_NOT_SUPPORT),\r
+      //        gShellDriver1HiiHandle,\r
+      //        ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter])\r
+      //        );\r
+      ShellStatus = SHELL_UNSUPPORTED;\r
+      continue;\r
+    }\r
+\r
+    BestLanguage = GetBestLanguage (\r
+                     DriverConfiguration->SupportedLanguages,\r
+                     Iso639Language,\r
+                     Language != NULL ? Language : "",\r
+                     DriverConfiguration->SupportedLanguages,\r
+                     NULL\r
+                     );\r
+    if (BestLanguage == NULL) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_GEN_NO_VALUE),\r
+        gShellDriver1HiiHandle,\r
+        L"drvcfg",\r
+        L"-l"\r
         );\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+      continue;\r
+    }\r
+\r
+    Status = ParseHandleDatabaseByRelationshipWithType (\r
+               DriverImageHandleBuffer[OuterLoopCounter],\r
+               NULL,\r
+               &HandleCount,\r
+               &HandleBuffer,\r
+               &HandleType\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
     }\r
+\r
+    if (SetOptions && (DeviceHandle == NULL)) {\r
+      gST->ConOut->ClearScreen (gST->ConOut);\r
+      Status = DriverConfiguration->SetOptions (\r
+                                      DriverConfiguration,\r
+                                      NULL,\r
+                                      NULL,\r
+                                      BestLanguage,\r
+                                      &ActionRequired\r
+                                      );\r
+      gST->ConOut->ClearScreen (gST->ConOut);\r
+\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_DRVCFG_ALL_LANG),\r
+        gShellDriver1HiiHandle,\r
+        ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]),\r
+        DriverConfiguration->SupportedLanguages\r
+        );\r
+      if (!EFI_ERROR (Status)) {\r
+        ShellPrintHiiEx (\r
+          -1,\r
+          -1,\r
+          NULL,\r
+          STRING_TOKEN (STR_DRVCFG_OPTIONS_SET),\r
+          gShellDriver1HiiHandle\r
+          );\r
+        for (LoopCounter = 0; LoopCounter < HandleCount; LoopCounter++) {\r
+          if ((HandleType[LoopCounter] & HR_CONTROLLER_HANDLE) == HR_CONTROLLER_HANDLE) {\r
+            ShellCmdDriverConfigurationProcessActionRequired (\r
+              DriverImageHandleBuffer[OuterLoopCounter],\r
+              HandleBuffer[LoopCounter],\r
+              NULL,\r
+              ActionRequired\r
+              );\r
+          }\r
+        }\r
+      } else {\r
+        ShellPrintHiiEx (\r
+          -1,\r
+          -1,\r
+          NULL,\r
+          STRING_TOKEN (STR_DRVCFG_NOT_SET),\r
+          gShellDriver1HiiHandle,\r
+          Status\r
+          );\r
+      }\r
+\r
+      continue;\r
+    }\r
+\r
+    for (LoopCounter = 0; LoopCounter < HandleCount; LoopCounter++) {\r
+      if ((HandleType[LoopCounter] & HR_CONTROLLER_HANDLE) != HR_CONTROLLER_HANDLE) {\r
+        continue;\r
+      }\r
+\r
+      if ((DeviceHandle != NULL) && (DeviceHandle != HandleBuffer[LoopCounter])) {\r
+        continue;\r
+      }\r
+\r
+      if (ChildHandle == NULL) {\r
+        HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]);\r
+        HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]);\r
+        ShellPrintHiiEx (\r
+          -1,\r
+          -1,\r
+          NULL,\r
+          STRING_TOKEN (STR_DRVCFG_CTRL_LANG),\r
+          gShellDriver1HiiHandle,\r
+          HandleIndex1,\r
+          HandleIndex2,\r
+          DriverConfiguration->SupportedLanguages\r
+          );\r
+\r
+        if (ForceDefaults) {\r
+          Status = DriverConfiguration->ForceDefaults (\r
+                                          DriverConfiguration,\r
+                                          HandleBuffer[LoopCounter],\r
+                                          NULL,\r
+                                          DefaultType,\r
+                                          &ActionRequired\r
+                                          );\r
+\r
+          if (!EFI_ERROR (Status)) {\r
+            ShellPrintHiiEx (\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_DEF_FORCED),\r
+              gShellDriver1HiiHandle\r
+              );\r
+            ShellCmdDriverConfigurationProcessActionRequired (\r
+              DriverImageHandleBuffer[OuterLoopCounter],\r
+              HandleBuffer[LoopCounter],\r
+              NULL,\r
+              ActionRequired\r
+              );\r
+          } else {\r
+            ShellPrintHiiEx (\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_FORCE_FAILED),\r
+              gShellDriver1HiiHandle,\r
+              Status\r
+              );\r
+            ShellStatus = SHELL_DEVICE_ERROR;\r
+          }\r
+        } else if (ValidateOptions) {\r
+          Status = DriverConfiguration->OptionsValid (\r
+                                          DriverConfiguration,\r
+                                          HandleBuffer[LoopCounter],\r
+                                          NULL\r
+                                          );\r
+\r
+          if (!EFI_ERROR (Status)) {\r
+            ShellPrintHiiEx (\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_OPTIONS_VALID),\r
+              gShellDriver1HiiHandle\r
+              );\r
+          } else {\r
+            ShellPrintHiiEx (\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_OPTIONS_INV),\r
+              gShellDriver1HiiHandle,\r
+              Status\r
+              );\r
+            ShellStatus = SHELL_DEVICE_ERROR;\r
+          }\r
+        } else if (SetOptions) {\r
+          gST->ConOut->ClearScreen (gST->ConOut);\r
+          Status = DriverConfiguration->SetOptions (\r
+                                          DriverConfiguration,\r
+                                          HandleBuffer[LoopCounter],\r
+                                          NULL,\r
+                                          BestLanguage,\r
+                                          &ActionRequired\r
+                                          );\r
+          gST->ConOut->ClearScreen (gST->ConOut);\r
+          HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]);\r
+          HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]);\r
+          ShellPrintHiiEx (\r
+            -1,\r
+            -1,\r
+            NULL,\r
+            STRING_TOKEN (STR_DRVCFG_CTRL_LANG),\r
+            gShellDriver1HiiHandle,\r
+            HandleIndex1,\r
+            HandleIndex2,\r
+            DriverConfiguration->SupportedLanguages\r
+            );\r
+          if (!EFI_ERROR (Status)) {\r
+            ShellPrintHiiEx (\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_OPTIONS_SET),\r
+              gShellDriver1HiiHandle\r
+              );\r
+\r
+            ShellCmdDriverConfigurationProcessActionRequired (\r
+              DriverImageHandleBuffer[OuterLoopCounter],\r
+              HandleBuffer[LoopCounter],\r
+              NULL,\r
+              ActionRequired\r
+              );\r
+          } else {\r
+            ShellPrintHiiEx (\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_NOT_SET),\r
+              gShellDriver1HiiHandle,\r
+              Status\r
+              );\r
+            ShellStatus = SHELL_DEVICE_ERROR;\r
+          }\r
+        } else {\r
+          Print (L"\n");\r
+        }\r
+      }\r
+\r
+      if ((ChildHandle == NULL) && !AllChildren) {\r
+        continue;\r
+      }\r
+\r
+      Status = ParseHandleDatabaseByRelationshipWithType (\r
+                 DriverImageHandleBuffer[OuterLoopCounter],\r
+                 HandleBuffer[LoopCounter],\r
+                 &ChildHandleCount,\r
+                 &ChildHandleBuffer,\r
+                 &ChildHandleType\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        continue;\r
+      }\r
+\r
+      for (ChildIndex = 0; ChildIndex < ChildHandleCount; ChildIndex++) {\r
+        if ((ChildHandleType[ChildIndex] & HR_CHILD_HANDLE) != HR_CHILD_HANDLE) {\r
+          continue;\r
+        }\r
+\r
+        if ((ChildHandle != NULL) && (ChildHandle != ChildHandleBuffer[ChildIndex])) {\r
+          continue;\r
+        }\r
+\r
+        HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]);\r
+        HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]);\r
+        HandleIndex3 = ConvertHandleToHandleIndex (ChildHandleBuffer[ChildIndex]);\r
+        ShellPrintHiiEx (\r
+          -1,\r
+          -1,\r
+          NULL,\r
+          STRING_TOKEN (STR_DRVCFG_CHILD_LANG),\r
+          gShellDriver1HiiHandle,\r
+          HandleIndex1,\r
+          HandleIndex2,\r
+          HandleIndex3,\r
+          DriverConfiguration->SupportedLanguages\r
+          );\r
+\r
+        if (ForceDefaults) {\r
+          Status = DriverConfiguration->ForceDefaults (\r
+                                          DriverConfiguration,\r
+                                          HandleBuffer[LoopCounter],\r
+                                          ChildHandleBuffer[ChildIndex],\r
+                                          DefaultType,\r
+                                          &ActionRequired\r
+                                          );\r
+\r
+          if (!EFI_ERROR (Status)) {\r
+            ShellPrintHiiEx (\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_DEF_FORCED),\r
+              gShellDriver1HiiHandle\r
+              );\r
+\r
+            ShellCmdDriverConfigurationProcessActionRequired (\r
+              DriverImageHandleBuffer[OuterLoopCounter],\r
+              HandleBuffer[LoopCounter],\r
+              ChildHandleBuffer[ChildIndex],\r
+              ActionRequired\r
+              );\r
+          } else {\r
+            ShellPrintHiiEx (\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_FORCE_FAILED),\r
+              gShellDriver1HiiHandle,\r
+              Status\r
+              );\r
+            ShellStatus = SHELL_DEVICE_ERROR;\r
+          }\r
+        } else if (ValidateOptions) {\r
+          Status = DriverConfiguration->OptionsValid (\r
+                                          DriverConfiguration,\r
+                                          HandleBuffer[LoopCounter],\r
+                                          ChildHandleBuffer[ChildIndex]\r
+                                          );\r
+\r
+          if (!EFI_ERROR (Status)) {\r
+            ShellPrintHiiEx (\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_OPTIONS_VALID),\r
+              gShellDriver1HiiHandle\r
+              );\r
+          } else {\r
+            ShellPrintHiiEx (\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_OPTIONS_INV),\r
+              gShellDriver1HiiHandle,\r
+              Status\r
+              );\r
+            ShellStatus = SHELL_DEVICE_ERROR;\r
+          }\r
+        } else if (SetOptions) {\r
+          gST->ConOut->ClearScreen (gST->ConOut);\r
+          Status = DriverConfiguration->SetOptions (\r
+                                          DriverConfiguration,\r
+                                          HandleBuffer[LoopCounter],\r
+                                          ChildHandleBuffer[ChildIndex],\r
+                                          BestLanguage,\r
+                                          &ActionRequired\r
+                                          );\r
+          gST->ConOut->ClearScreen (gST->ConOut);\r
+          HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]);\r
+          HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]);\r
+          HandleIndex3 = ConvertHandleToHandleIndex (ChildHandleBuffer[ChildIndex]);\r
+          ShellPrintHiiEx (\r
+            -1,\r
+            -1,\r
+            NULL,\r
+            STRING_TOKEN (STR_DRVCFG_CHILD_LANG),\r
+            gShellDriver1HiiHandle,\r
+            HandleIndex1,\r
+            HandleIndex2,\r
+            HandleIndex3,\r
+            DriverConfiguration->SupportedLanguages\r
+            );\r
+          if (!EFI_ERROR (Status)) {\r
+            ShellPrintHiiEx (\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_OPTIONS_SET),\r
+              gShellDriver1HiiHandle\r
+              );\r
+\r
+            ShellCmdDriverConfigurationProcessActionRequired (\r
+              DriverImageHandleBuffer[OuterLoopCounter],\r
+              HandleBuffer[LoopCounter],\r
+              ChildHandleBuffer[ChildIndex],\r
+              ActionRequired\r
+              );\r
+          } else {\r
+            ShellPrintHiiEx (\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_NOT_SET),\r
+              gShellDriver1HiiHandle,\r
+              Status\r
+              );\r
+            ShellStatus = SHELL_DEVICE_ERROR;\r
+          }\r
+        } else {\r
+          Print (L"\n");\r
+        }\r
+      }\r
+\r
+      FreePool (ChildHandleBuffer);\r
+      FreePool (ChildHandleType);\r
+    }\r
+\r
+    FreePool (BestLanguage);\r
+    FreePool (HandleBuffer);\r
+    FreePool (HandleType);\r
   }\r
-  return (SHELL_SUCCESS);\r
+\r
+  if ((DriverImageHandle != NULL) && (DriverImageHandleCount != 0)) {\r
+    FreePool (DriverImageHandleBuffer);\r
+  }\r
+\r
+Done:\r
+  return ShellStatus;\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
+  @param[in] Language       ASCII string for language code.\r
+  @param[in] UseHii         TRUE to check for Hii and DPC, FALSE for DCP only.\r
 \r
   @retval SHELL_SUCCESS     The operation was successful.\r
 **/\r
 SHELL_STATUS\r
-EFIAPI\r
-PrintConfigInfoOnAll(\r
-  IN CONST BOOLEAN ChildrenToo\r
+PrintConfigInfoOnAll (\r
+  IN CONST BOOLEAN  ChildrenToo,\r
+  IN CONST CHAR8    *Language,\r
+  IN CONST BOOLEAN  UseHii\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
+  EFI_HANDLE  *HandleList;\r
+  EFI_HANDLE  *CurrentHandle;\r
+  BOOLEAN     Found;\r
+  UINTN       Index2;\r
+\r
+  Found         = FALSE;\r
+  HandleList    = NULL;\r
+  CurrentHandle = NULL;\r
+\r
+  if (UseHii) {\r
+    //\r
+    // HII method\r
+    //\r
+    HandleList = GetHandleListByProtocol (&gEfiHiiConfigAccessProtocolGuid);\r
+    for (CurrentHandle = HandleList; CurrentHandle != NULL && *CurrentHandle != NULL; CurrentHandle++) {\r
+      Found  = TRUE;\r
+      Index2 = *CurrentHandle == NULL ? 0 : ConvertHandleToHandleIndex (*CurrentHandle);\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_DRVCFG_LINE_HII),\r
+        gShellDriver1HiiHandle,\r
+        Index2\r
+        );\r
     }\r
+\r
+    SHELL_FREE_NON_NULL (HandleList);\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
+  if (PreHiiDrvCfg (\r
+        Language,\r
+        FALSE,\r
+        0,\r
+        ChildrenToo,\r
+        FALSE,\r
+        FALSE,\r
+        0,\r
+        0,\r
+        0\r
+        ) == SHELL_SUCCESS)\r
+  {\r
     Found = TRUE;\r
-    ShellStatus = PrintConfigInfoOnSingleHandle(*CurrentHandle, NULL, ChildrenToo, BIT1);\r
   }\r
-  SHELL_FREE_NON_NULL(HandleList);\r
+\r
   if (!Found) {\r
-    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NONE), gShellDriver1HiiHandle);\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NONE_FOUND), gShellDriver1HiiHandle);\r
     return (SHELL_SUCCESS);\r
   }\r
-  return (ShellStatus);\r
+\r
+  return (SHELL_SUCCESS);\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
+STATIC CONST SHELL_PARAM_ITEM  ParamListHii[] = {\r
+  { L"-s", TypeFlag  },\r
+  { L"-l", TypeValue },\r
+  { L"-f", TypeValue },\r
+  { L"-o", TypeValue },\r
+  { L"-i", TypeValue },\r
+  { NULL,  TypeMax   }\r
+};\r
+STATIC CONST SHELL_PARAM_ITEM  ParamListPreHii[] = {\r
+  { L"-c", TypeFlag  },\r
+  { L"-s", TypeFlag  },\r
+  { L"-v", TypeFlag  },\r
+  { L"-l", TypeValue },\r
+  { L"-f", TypeValue },\r
+  { NULL,  TypeMax   }\r
+};\r
 \r
 /**\r
   Function for 'drvcfg' command.\r
@@ -313,100 +1191,289 @@ ShellCommandRunDrvCfg (
   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
+  EFI_STATUS    Status;\r
+  LIST_ENTRY    *Package;\r
+  CHAR16        *ProblemParam;\r
+  SHELL_STATUS  ShellStatus;\r
+  CHAR8         *Language;\r
+  CONST CHAR16  *Lang;\r
+  CONST CHAR16  *HandleIndex1;\r
+  CONST CHAR16  *HandleIndex2;\r
+  CONST CHAR16  *HandleIndex3;\r
+  CONST CHAR16  *ForceTypeString;\r
+  BOOLEAN       Force;\r
+  BOOLEAN       Set;\r
+  BOOLEAN       Validate;\r
+  BOOLEAN       InFromFile;\r
+  BOOLEAN       OutToFile;\r
+  BOOLEAN       AllChildren;\r
+  BOOLEAN       UseHii;\r
+  UINT32        ForceType;\r
+  UINT64        Intermediate;\r
+  EFI_HANDLE    Handle1;\r
+  EFI_HANDLE    Handle2;\r
+  EFI_HANDLE    Handle3;\r
+  CONST CHAR16  *FileName;\r
+\r
+  ShellStatus  = SHELL_SUCCESS;\r
+  Status       = EFI_SUCCESS;\r
+  Language     = NULL;\r
+  UseHii       = TRUE;\r
+  ProblemParam = 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
+  Status = ShellInitialize ();\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
-  Status = CommandInit();\r
-  ASSERT_EFI_ERROR(Status);\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
+  Status = ShellCommandLineParse (ParamListHii, &Package, &ProblemParam, TRUE);\r
+  if (EFI_ERROR (Status) || (ShellCommandLineGetCount (Package) > 2)) {\r
+    UseHii = FALSE;\r
+    if (Package != NULL) {\r
+      ShellCommandLineFreeVarList (Package);\r
+    }\r
+\r
+    SHELL_FREE_NON_NULL (ProblemParam);\r
+    Status = ShellCommandLineParse (ParamListPreHii, &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, L"drvcfg", ProblemParam);\r
+        FreePool (ProblemParam);\r
+        ShellStatus = SHELL_INVALID_PARAMETER;\r
+        goto Done;\r
+      } else {\r
+        ASSERT (FALSE);\r
+      }\r
+    }\r
+  }\r
+\r
+  if (ShellStatus == SHELL_SUCCESS) {\r
+    if (ShellCommandLineGetCount (Package) > 4) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"drvcfg");\r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
-    } else {\r
-      ASSERT(FALSE);\r
+      goto Done;\r
     }\r
-  } else {\r
-    Lang = ShellCommandLineGetValue(Package, L"-l");\r
+\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
+      Language = AllocateZeroPool (StrSize (Lang));\r
+      AsciiSPrint (Language, StrSize (Lang), "%S", Lang);\r
+    } else if (ShellCommandLineGetFlag (Package, L"-l")) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvcfg", L"-l");\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    Set             = ShellCommandLineGetFlag (Package, L"-s");\r
+    Validate        = ShellCommandLineGetFlag (Package, L"-v");\r
+    InFromFile      = ShellCommandLineGetFlag (Package, L"-i");\r
+    OutToFile       = ShellCommandLineGetFlag (Package, L"-o");\r
+    AllChildren     = ShellCommandLineGetFlag (Package, L"-c");\r
+    Force           = ShellCommandLineGetFlag (Package, L"-f");\r
+    ForceTypeString = ShellCommandLineGetValue (Package, L"-f");\r
+\r
+    if (OutToFile) {\r
+      FileName = ShellCommandLineGetValue (Package, L"-o");\r
+    } else if (InFromFile) {\r
+      FileName = ShellCommandLineGetValue (Package, L"-i");\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
+      FileName = NULL;\r
+    }\r
+\r
+    if (InFromFile && EFI_ERROR (ShellFileExists (FileName))) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FIND_FAIL), gShellDriver1HiiHandle, L"drvcfg", FileName);\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    if (OutToFile && !EFI_ERROR (ShellFileExists (FileName))) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_EXIST), gShellDriver1HiiHandle, L"drvcfg", FileName);\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    if (Force && (ForceTypeString == NULL)) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvcfg", L"-f");\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    if (Force) {\r
+      Status = ShellConvertStringToUint64 (ForceTypeString, &Intermediate, FALSE, FALSE);\r
+      if (EFI_ERROR (Status)) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDriver1HiiHandle, L"drvcfg", ForceTypeString, L"-f");\r
+        ShellStatus = SHELL_INVALID_PARAMETER;\r
+        goto Done;\r
+      }\r
+\r
+      ForceType = (UINT32)Intermediate;\r
+    } else {\r
+      ForceType = 0;\r
+    }\r
+\r
+    HandleIndex1 = ShellCommandLineGetRawValue (Package, 1);\r
+    Handle1      = NULL;\r
+    if ((HandleIndex1 != NULL) && !EFI_ERROR (ShellConvertStringToUint64 (HandleIndex1, &Intermediate, TRUE, FALSE))) {\r
+      Handle1 = ConvertHandleIndexToHandle ((UINTN)Intermediate);\r
+      if ((Handle1 == NULL) || ((UINT64)(UINTN)Intermediate != Intermediate)) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"drvcfg", HandleIndex1);\r
+        ShellStatus = SHELL_INVALID_PARAMETER;\r
+        goto Done;\r
+      }\r
+    }\r
+\r
+    HandleIndex2 = ShellCommandLineGetRawValue (Package, 2);\r
+    Handle2      = NULL;\r
+    if ((HandleIndex2 != NULL) && !EFI_ERROR (ShellConvertStringToUint64 (HandleIndex2, &Intermediate, TRUE, FALSE))) {\r
+      Handle2 = ConvertHandleIndexToHandle ((UINTN)Intermediate);\r
+      if ((Handle2 == NULL) || ((UINT64)(UINTN)Intermediate != Intermediate)) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"drvcfg", HandleIndex2);\r
+        ShellStatus = SHELL_INVALID_PARAMETER;\r
+        goto Done;\r
+      }\r
+    }\r
+\r
+    HandleIndex3 = ShellCommandLineGetRawValue (Package, 3);\r
+    Handle3      = NULL;\r
+    if ((HandleIndex3 != NULL) && !EFI_ERROR (ShellConvertStringToUint64 (HandleIndex3, &Intermediate, TRUE, FALSE))) {\r
+      Handle3 = ConvertHandleIndexToHandle ((UINTN)Intermediate);\r
+      if ((Handle3 == NULL) || ((UINT64)(UINTN)Intermediate != Intermediate)) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"drvcfg", HandleIndex3);\r
+        ShellStatus = SHELL_INVALID_PARAMETER;\r
+        goto Done;\r
+      }\r
+    }\r
+\r
+    if ((InFromFile || OutToFile) && (FileName == NULL)) {\r
+      if (FileName == NULL) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvcfg", InFromFile ? L"-i" : L"-o");\r
+      } else {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_HANDLE_REQ), gShellDriver1HiiHandle, L"drvcfg");\r
+      }\r
+\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    if (!UseHii && (InFromFile || OutToFile)) {\r
+      if (InFromFile) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDriver1HiiHandle, L"drvcfg", L"-i");\r
+        ShellStatus = SHELL_INVALID_PARAMETER;\r
+        goto Done;\r
+      }\r
+\r
+      if (OutToFile) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDriver1HiiHandle, L"drvcfg", L"-o");\r
+        ShellStatus = SHELL_INVALID_PARAMETER;\r
+        goto Done;\r
+      }\r
+    }\r
+\r
+    if (Validate && Force) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-v", L"-f");\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    if (Validate && Set) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-v", L"-s");\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    if (Set && Force) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-s", L"-f");\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    if (OutToFile && InFromFile) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-i", L"-o");\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+      goto Done;\r
     }\r
 \r
     //\r
-    // Should be DriverHandle\r
+    // We do HII first.\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
+    if (UseHii) {\r
+      if ((Handle1 != NULL) && EFI_ERROR (gBS->OpenProtocol (Handle1, &gEfiHiiConfigAccessProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {\r
         //\r
-        // do a loop for validation, forcing, or printing\r
+        // no HII on this handle.\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
+        ShellStatus = SHELL_UNSUPPORTED;\r
+      } else if (Validate) {\r
+      } else if (Force) {\r
+      } else if (Set) {\r
+      } else if (InFromFile) {\r
+        ShellStatus = ConfigFromFile (Handle1, FileName);\r
+        if ((Handle1 != NULL) && (ShellStatus == SHELL_SUCCESS)) {\r
+          goto Done;\r
+        }\r
+      } else if (OutToFile) {\r
+        ShellStatus = ConfigToFile (Handle1, FileName);\r
+        if ((Handle1 != NULL) && (ShellStatus == SHELL_SUCCESS)) {\r
+          goto Done;\r
+        }\r
+      } else if (HandleIndex1 == NULL) {\r
+        //\r
+        // display all that are configurable\r
+        //\r
+        ShellStatus = PrintConfigInfoOnAll (AllChildren, Language, UseHii);\r
+        goto Done;\r
+      } else {\r
+        if (!EFI_ERROR (gBS->OpenProtocol (Handle1, &gEfiHiiConfigAccessProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {\r
+          ShellPrintHiiEx (\r
+            -1,\r
+            -1,\r
+            NULL,\r
+            STRING_TOKEN (STR_DRVCFG_LINE_HII),\r
+            gShellDriver1HiiHandle,\r
+            ConvertHandleToHandleIndex (Handle1)\r
+            );\r
+          goto Done;\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
+    //\r
+    // We allways need to do this one since it does both by default.\r
+    //\r
+    if (!InFromFile && !OutToFile) {\r
+      ShellStatus = PreHiiDrvCfg (\r
+                      Language,\r
+                      Force,\r
+                      ForceType,\r
+                      AllChildren,\r
+                      Validate,\r
+                      Set,\r
+                      Handle1,\r
+                      Handle2,\r
+                      Handle3\r
+                      );\r
+    }\r
+\r
+    if (ShellStatus == SHELL_UNSUPPORTED) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_DRVCFG_NOT_SUPPORT),\r
+        gShellDriver1HiiHandle,\r
+        ConvertHandleToHandleIndex (Handle1)\r
+        );\r
     }\r
   }\r
+\r
+Done:\r
   ShellCommandLineFreeVarList (Package);\r
-  SHELL_FREE_NON_NULL(Language);\r
+  SHELL_FREE_NON_NULL (Language);\r
   return (ShellStatus);\r
 }\r