]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellDriver1CommandsLib/DrvCfg.c
ShellPkg/for: Fix potential null pointer deference
[mirror_edk2.git] / ShellPkg / Library / UefiShellDriver1CommandsLib / DrvCfg.c
index 4f4375414c5e1c84a8f83bc60aeecdf2532c6369..37501d4d3fdcfb5d0abc9864750861e52e1273d1 100644 (file)
@@ -1,7 +1,8 @@
 /** @file\r
   Main file for DrvCfg shell Driver1 function.\r
 \r
-  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
+  Copyright (c) 2010 - 2016, 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
 #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
-\r
-  if (HiiDb == NULL || Handle == NULL) {\r
-    return (EFI_INVALID_PARAMETER);\r
-  }\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
-  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
+    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
+  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
+    if (EFI_ERROR (Status)) {\r
+      continue;\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
+        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
+            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
+    SHELL_FREE_NON_NULL(MainBuffer);\r
   }\r
+  SHELL_FREE_NON_NULL(HandleBuffer);\r
 \r
+  if (*HiiHandle == NULL) {\r
+    return (EFI_NOT_FOUND);\r
+  }\r
+  return (EFI_SUCCESS);\r
+}\r
 \r
+/**\r
+  Convert a EFI_HANDLE to a EFI_HII_HANDLE.\r
 \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 EFI_SUCCESS   The operation was successful.\r
+**/\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_STATUS                    Status;\r
+  EFI_DEVICE_PATH_PROTOCOL      *DevPath1;\r
+\r
+  if (HiiHandle == NULL || HiiDb == NULL) {\r
+    return (EFI_INVALID_PARAMETER);\r
+  }\r
+  *HiiHandle = NULL;\r
+\r
+  if (Handle == NULL) {\r
+    return (EFI_SUCCESS);\r
+  }\r
+\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
-  SHELL_FREE_NON_NULL(HiiHandle);\r
-  return (Status);\r
+  return (FindHiiHandleViaDevPath(DevPath1, HiiHandle, HiiDb));\r
 }\r
 \r
 /**\r
-  Function to validate configuration information on all configurable handles.\r
-\r
-  @param[in] ChildrenToo    TRUE to tewst for children.\r
+  Function to print out all HII configuration information to a file.\r
 \r
-  @retval SHELL_SUCCESS     The operation was successful.\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
-EFIAPI\r
-ValidOptionsOnAll(\r
-  IN CONST BOOLEAN ChildrenToo\r
+ConfigToFile(\r
+  IN CONST EFI_HANDLE     Handle,\r
+  IN CONST CHAR16         *FileName\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
+  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
-  Found             = FALSE;\r
-  HandleList        = NULL;\r
-  ShellStatus       = SHELL_SUCCESS;\r
-  Status            = EFI_SUCCESS;\r
+  HiiDatabase       = NULL;\r
+  MainBufferSize    = 0;\r
+  MainBuffer        = NULL;\r
+  FileHandle        = NULL;\r
 \r
-  Status = gBS->LocateProtocol(&gEfiHiiDatabaseProtocolGuid, NULL, (VOID**)&HiiDb);\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(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROTOCOL_NF), gShellDriver1HiiHandle, L"gEfiHiiDatabaseProtocolGuid", &gEfiHiiDatabaseProtocolGuid);\r
-    return (SHELL_NOT_FOUND);\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
+    return (SHELL_DEVICE_ERROR);\r
   }\r
 \r
-  ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_HEADER), gShellDriver1HiiHandle);\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
+    ShellCloseFile(&FileHandle);\r
+    return (SHELL_NOT_FOUND);\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
+  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
+    ShellCloseFile(&FileHandle);\r
+    return (SHELL_DEVICE_ERROR);   \r
   }\r
 \r
-  if (!Found) {\r
-    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NONE), gShellDriver1HiiHandle);\r
-    return (SHELL_SUCCESS);\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
-  SHELL_FREE_NON_NULL(HandleList);\r
-  return (ShellStatus);\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
+    return (SHELL_DEVICE_ERROR);   \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
-  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
+  Function to read in HII configuration information from a file.\r
 \r
-  @retval SHELL_SUCCESS       The operation was successful.\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
-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
+ConfigFromFile(\r
+  IN       EFI_HANDLE     Handle,\r
+  IN CONST CHAR16         *FileName\r
   )\r
 {\r
-  UINTN       Index1;\r
-  UINTN       Index2;\r
-  EFI_HANDLE  *ChildHandleList;\r
-  UINTN       Count;\r
-  UINTN       LoopVar;\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
+    return (SHELL_DEVICE_ERROR);\r
+  }\r
+\r
+  //\r
+  // Locate HII Database protocol\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiHiiDatabaseProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &HiiDatabase\r
+                  );\r
 \r
-  Index1 = DriverHandle     == NULL ? 0 : ConvertHandleToHandleIndex(DriverHandle    );\r
-  Index2 = ControllerHandle == NULL ? 0 : ConvertHandleToHandleIndex(ControllerHandle);\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
+    ShellCloseFile(&FileHandle);\r
+    return (SHELL_NOT_FOUND);\r
+  }\r
 \r
-  if ((ProtocolMask & BIT0) == BIT0) {\r
-    ASSERT(Index1 == 0);\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_DRVCFG_LINE_HII), \r
+      STRING_TOKEN(STR_FILE_READ_FAIL), \r
+      gShellDriver1HiiHandle,\r
+      L"drvcfg",\r
+      FileName);\r
+\r
+    ShellCloseFile(&FileHandle);\r
+    return (SHELL_DEVICE_ERROR);   \r
+  }\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, L"drvcfg");\r
+    ShellCloseFile(&FileHandle);\r
+    return (SHELL_DEVICE_ERROR);   \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
-      Index2\r
-      );\r
+      L"drvcfg",\r
+      FileName);\r
+\r
+    ShellCloseFile(&FileHandle);\r
+    SHELL_FREE_NON_NULL(MainBuffer);\r
+    return (SHELL_DEVICE_ERROR);   \r
   }\r
-  if ((ProtocolMask & BIT1) == BIT1) {\r
-    PARSE_HANDLE_DATABASE_MANAGED_CHILDREN(DriverHandle, ControllerHandle, &Count, &ChildHandleList);\r
-    for (LoopVar = 0 ; LoopVar <= Count ; LoopVar++) {\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_DRVCFG_LINE_DRV), \r
-        gShellDriver1HiiHandle, \r
-        Index1,\r
-        Index2,\r
-        Count != 0 ? ChildHandleList[LoopVar] : 0\r
-        );\r
+        STRING_TOKEN(STR_GEN_HANDLE_NOT), \r
+        gShellDriver1HiiHandle, L"drvcfg",\r
+        ConvertHandleToHandleIndex(Handle), \r
+        L"Device");\r
+      ShellCloseFile(&FileHandle);\r
+      return (SHELL_DEVICE_ERROR);   \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
+      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
+        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
+            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
+                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
+                  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
+  SHELL_FREE_NON_NULL(MainBuffer);\r
+\r
+\r
+  ShellPrintHiiEx(\r
+    -1, \r
+    -1,\r
+    NULL,\r
+    STRING_TOKEN(STR_DRVCFG_COMP), \r
+    gShellDriver1HiiHandle);\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
+  Do the configuration in an environment without HII.\r
+\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_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
+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
+  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
+  } else if (ValidateOptions) {\r
+    ShellPrintHiiEx(\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_DRVCFG_VALIDATE), \r
+      gShellDriver1HiiHandle);\r
+  } else if (SetOptions) {\r
+    ShellPrintHiiEx(\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_DRVCFG_SET), \r
+      gShellDriver1HiiHandle);\r
+  }\r
+\r
+  if (DriverImageHandle == 0) {\r
+    DriverImageHandleBuffer = GetHandleListByProtocolList(CfgGuidList);\r
+    if (DriverImageHandleBuffer == NULL) {\r
+      ShellStatus = SHELL_NOT_FOUND;\r
+      goto Done;\r
+    }\r
+    for (\r
+      HandleBuffer = DriverImageHandleBuffer, DriverImageHandleCount = 0 \r
+      ; HandleBuffer != NULL && *HandleBuffer != NULL \r
+      ; HandleBuffer++,DriverImageHandleCount++);\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
+    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
+\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
+        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
+      continue;\r
+    }\r
+\r
+    for (LoopCounter = 0; LoopCounter < HandleCount; LoopCounter++) {\r
+      if ((HandleType[LoopCounter] & HR_CONTROLLER_HANDLE) != HR_CONTROLLER_HANDLE) {\r
+        continue;\r
+      }\r
+      if (DeviceHandle != NULL && DeviceHandle != HandleBuffer[LoopCounter]) {\r
+        continue;\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
+            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
+           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
+          } else {\r
+            ShellPrintHiiEx(\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_OPTIONS_INV), \r
+              gShellDriver1HiiHandle, \r
+              Status);\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
+            ShellCmdDriverConfigurationProcessActionRequired (\r
+              DriverImageHandleBuffer[OuterLoopCounter],\r
+              HandleBuffer[LoopCounter],\r
+              NULL,\r
+              ActionRequired\r
+              );\r
+\r
+          } else {\r
+            ShellPrintHiiEx(\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_NOT_SET), \r
+              gShellDriver1HiiHandle, \r
+              Status);\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
+\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
+        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
+            ShellCmdDriverConfigurationProcessActionRequired (\r
+              DriverImageHandleBuffer[OuterLoopCounter],\r
+              HandleBuffer[LoopCounter],\r
+              ChildHandleBuffer[ChildIndex],\r
+              ActionRequired\r
+              );\r
+\r
+          } else {\r
+            ShellPrintHiiEx(\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_FORCE_FAILED), \r
+              gShellDriver1HiiHandle, \r
+              Status);\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
+          } else {\r
+            ShellPrintHiiEx(\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_OPTIONS_INV), \r
+              gShellDriver1HiiHandle, \r
+              Status);\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
+            ShellCmdDriverConfigurationProcessActionRequired (\r
+              DriverImageHandleBuffer[OuterLoopCounter],\r
+              HandleBuffer[LoopCounter],\r
+              ChildHandleBuffer[ChildIndex],\r
+              ActionRequired\r
+              );\r
+\r
+          } else {\r
+            ShellPrintHiiEx(\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_DRVCFG_NOT_SET), \r
+              gShellDriver1HiiHandle, \r
+              Status);\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
+\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
+  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
+  UINTN             Index2;\r
+\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
+  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
+    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
-    Found = TRUE;\r
-    ShellStatus = PrintConfigInfoOnSingleHandle(*CurrentHandle, NULL, ChildrenToo, BIT1);\r
+  if (PreHiiDrvCfg (\r
+    Language,\r
+    FALSE,\r
+    0,\r
+    ChildrenToo,\r
+    FALSE,\r
+    FALSE,\r
+    0,\r
+    0,\r
+    0) == SHELL_SUCCESS) {\r
+      Found = TRUE;\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
+STATIC CONST SHELL_PARAM_ITEM ParamListHii[] = {\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 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
 \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
 ShellCommandRunDrvCfg (\r
@@ -313,11 +1149,29 @@ ShellCommandRunDrvCfg (
   SHELL_STATUS        ShellStatus;\r
   CHAR8               *Language;\r
   CONST CHAR16        *Lang;\r
-  CONST CHAR16        *Temp2;\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
@@ -331,75 +1185,227 @@ ShellCommandRunDrvCfg (
   //\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
+    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
+  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
     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 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
+    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
+    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
+    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
+    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
+      ForceType = (UINT32)Intermediate;\r
+    } else {\r
+      ForceType = 0;\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
+    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
+    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
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+      goto Done;\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
+      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
+    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
+    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
+    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
+    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
+    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
   return (ShellStatus);\r