1/** @file
2  Main file for DrvCfg shell Driver1 function.
3
4  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5  Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
6  This program and the accompanying materials
7  are licensed and made available under the terms and conditions of the BSD License
8  which accompanies this distribution.  The full text of the license may be found at
9  http://opensource.org/licenses/bsd-license.php
10
11  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14**/
15
16#include "UefiShellDriver1CommandsLib.h"
17#include <Protocol/HiiConfigAccess.h>
18#include <Protocol/HiiDatabase.h>
19
20STATIC CONST EFI_GUID *CfgGuidList[] = {&gEfiDriverConfigurationProtocolGuid, &gEfiDriverConfiguration2ProtocolGuid, NULL};
21
22/**
23  Find the EFI_HII_HANDLE by device path.
24
25  @param[in] DevPath1     The Device Path to match.
26  @param[out] HiiHandle   The EFI_HII_HANDLE after the converstion.
27  @param[in] HiiDb        The Hii database protocol
28
29  @retval EFI_SUCCESS     The operation was successful.
30  @retval EFI_NOT_FOUND   There was no EFI_HII_HANDLE found for that deviec path.
31**/
32EFI_STATUS
33EFIAPI
34FindHiiHandleViaDevPath(
35  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevPath1,
36  OUT EFI_HII_HANDLE                *HiiHandle,
37  IN EFI_HII_DATABASE_PROTOCOL      *HiiDb
38  )
39{
40  EFI_HII_HANDLE                *HandleBuffer;
41  UINTN                         HandleBufferSize;
42  VOID                          *MainBuffer;
43  UINTN                         MainBufferSize;
44  EFI_HII_PACKAGE_LIST_HEADER   *PackageListHeader;
45  EFI_HII_PACKAGE_HEADER        *PackageHeader;
46  UINTN                         LoopVariable;
47  EFI_DEVICE_PATH_PROTOCOL      *DevPath2;
48  EFI_STATUS                    Status;
49
50  ASSERT(DevPath1 != NULL);
51  ASSERT(HiiHandle != NULL);
52  ASSERT(*HiiHandle == NULL);
53  ASSERT(HiiDb != NULL);
54
55  HandleBufferSize  = 0;
56  HandleBuffer      = NULL;
57  Status = HiiDb->ListPackageLists(HiiDb, EFI_HII_PACKAGE_DEVICE_PATH, NULL, &HandleBufferSize, HandleBuffer);
58  if (Status == EFI_BUFFER_TOO_SMALL) {
59    HandleBuffer = AllocateZeroPool(HandleBufferSize);
60    ASSERT (HandleBuffer != NULL);
61    Status = HiiDb->ListPackageLists(HiiDb, EFI_HII_PACKAGE_DEVICE_PATH, NULL, &HandleBufferSize, HandleBuffer);
62  }
63  if (EFI_ERROR(Status)) {
64    SHELL_FREE_NON_NULL(HandleBuffer);
65    return (Status);
66  }
67
68  if (HandleBuffer == NULL) {
69    return EFI_NOT_FOUND;
70  }
71
72  for (LoopVariable = 0 ; LoopVariable < (HandleBufferSize/sizeof(HandleBuffer[0])) && *HiiHandle == NULL ; LoopVariable++) {
73    MainBufferSize    = 0;
74    MainBuffer        = NULL;
75    Status = HiiDb->ExportPackageLists(HiiDb, HandleBuffer[LoopVariable], &MainBufferSize, MainBuffer);
76    if (Status == EFI_BUFFER_TOO_SMALL) {
77      MainBuffer = AllocateZeroPool(MainBufferSize);
78      ASSERT (MainBuffer != NULL);
79      Status = HiiDb->ExportPackageLists(HiiDb, HandleBuffer[LoopVariable], &MainBufferSize, MainBuffer);
80    }
81    //
82    // Enumerate through the block of returned memory.
83    // This should actually be a small block, but we need to be sure.
84    //
85    for (PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER*)MainBuffer
86      ;  PackageListHeader != NULL && ((CHAR8*)PackageListHeader) < (((CHAR8*)MainBuffer)+MainBufferSize) && *HiiHandle == NULL
87      ;  PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER*)(((CHAR8*)(PackageListHeader)) + PackageListHeader->PackageLength )) {
88        for (PackageHeader = (EFI_HII_PACKAGE_HEADER*)(((CHAR8*)(PackageListHeader))+sizeof(EFI_HII_PACKAGE_LIST_HEADER))
89          ; PackageHeader != NULL && ((CHAR8*)PackageHeader) < (((CHAR8*)MainBuffer)+MainBufferSize) && PackageHeader->Type != EFI_HII_PACKAGE_END && *HiiHandle == NULL
90          ; PackageHeader = (EFI_HII_PACKAGE_HEADER*)(((CHAR8*)(PackageHeader))+PackageHeader->Length)) {
91            if (PackageHeader->Type == EFI_HII_PACKAGE_DEVICE_PATH) {
92              DevPath2 = (EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER));
93              if (DevicePathCompare(&DevPath1, &DevPath2) == 0) {
94                *HiiHandle = HandleBuffer[LoopVariable];
95                break;
96              }
97            }
98        }
99    }
100    SHELL_FREE_NON_NULL(MainBuffer);
101  }
102  SHELL_FREE_NON_NULL(HandleBuffer);
103
104  if (*HiiHandle == NULL) {
105    return (EFI_NOT_FOUND);
106  }
107  return (EFI_SUCCESS);
108}
109
110/**
111  Convert a EFI_HANDLE to a EFI_HII_HANDLE.
112
113  @param[in] Handle       The EFI_HANDLE to convert.
114  @param[out] HiiHandle   The EFI_HII_HANDLE after the converstion.
115  @param[in] HiiDb        The Hii database protocol
116
117  @retval EFI_SUCCESS   The operation was successful.
118**/
119EFI_STATUS
120EFIAPI
121ConvertHandleToHiiHandle(
122  IN CONST EFI_HANDLE           Handle,
123  OUT EFI_HII_HANDLE            *HiiHandle,
124  IN EFI_HII_DATABASE_PROTOCOL  *HiiDb
125  )
126{
127  EFI_STATUS                    Status;
128  EFI_DEVICE_PATH_PROTOCOL      *DevPath1;
129
130  if (HiiHandle == NULL || HiiDb == NULL) {
131    return (EFI_INVALID_PARAMETER);
132  }
133  *HiiHandle = NULL;
134
135  if (Handle == NULL) {
136    return (EFI_SUCCESS);
137  }
138
139  DevPath1 = NULL;
140  Status = gBS->OpenProtocol(Handle, &gEfiDevicePathProtocolGuid, (VOID**)&DevPath1, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
141  if (EFI_ERROR(Status) || DevPath1 == NULL) {
142    return (EFI_NOT_FOUND);
143  }
144
145  return (FindHiiHandleViaDevPath(DevPath1, HiiHandle, HiiDb));
146}
147
148/**
149  Function to print out all HII configuration information to a file.
150
151  @param[in] Handle           The handle to get info on.  NULL to do all handles.
152  @param[in] FileName         The filename to rwite the info to.
153**/
154SHELL_STATUS
155EFIAPI
156ConfigToFile(
157  IN CONST EFI_HANDLE     Handle,
158  IN CONST CHAR16         *FileName
159  )
160{
161  EFI_HII_DATABASE_PROTOCOL     *HiiDatabase;
162  EFI_STATUS                    Status;
163  VOID                          *MainBuffer;
164  UINTN                         MainBufferSize;
165  EFI_HII_HANDLE                HiiHandle;
166  SHELL_FILE_HANDLE             FileHandle;
167
168  HiiDatabase       = NULL;
169  MainBufferSize    = 0;
170  MainBuffer        = NULL;
171  FileHandle        = NULL;
172
173  Status = ShellOpenFileByName(FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
174  if (EFI_ERROR(Status)) {
175    ShellPrintHiiEx(
176      -1,
177      -1,
178      NULL,
179      STRING_TOKEN(STR_GEN_FILE_OPEN_FAIL),
180      gShellDriver1HiiHandle,
181      L"drvcfg",
182      FileName,
183      Status);
184    return (SHELL_DEVICE_ERROR);
185  }
186
187  //
188  // Locate HII Database protocol
189  //
190  Status = gBS->LocateProtocol (
191                  &gEfiHiiDatabaseProtocolGuid,
192                  NULL,
193                  (VOID **) &HiiDatabase
194                  );
195
196  if (EFI_ERROR(Status) || HiiDatabase == NULL) {
197    ShellPrintHiiEx(
198      -1,
199      -1,
200      NULL,
201      STRING_TOKEN(STR_GEN_PROTOCOL_NF),
202      gShellDriver1HiiHandle,
203      L"drvcfg",
204      L"EfiHiiDatabaseProtocol",
205      &gEfiHiiDatabaseProtocolGuid);
206    ShellCloseFile(&FileHandle);
207    return (SHELL_NOT_FOUND);
208  }
209
210  HiiHandle = NULL;
211  Status = ConvertHandleToHiiHandle(Handle, &HiiHandle, HiiDatabase);
212  if (EFI_ERROR(Status)) {
213    ShellPrintHiiEx(
214      -1,
215      -1,
216      NULL,
217      STRING_TOKEN(STR_GEN_HANDLE_NOT),
218      gShellDriver1HiiHandle,
219      L"drvcfg",
220      ConvertHandleToHandleIndex(Handle),
221      L"Device");
222    ShellCloseFile(&FileHandle);
223    return (SHELL_DEVICE_ERROR);
224  }
225
226  Status = HiiDatabase->ExportPackageLists(HiiDatabase, HiiHandle, &MainBufferSize, MainBuffer);
227  if (Status == EFI_BUFFER_TOO_SMALL) {
228    MainBuffer = AllocateZeroPool(MainBufferSize);
229    Status = HiiDatabase->ExportPackageLists(HiiDatabase, HiiHandle, &MainBufferSize, MainBuffer);
230  }
231
232  Status = ShellWriteFile(FileHandle, &MainBufferSize, MainBuffer);
233
234  ShellCloseFile(&FileHandle);
235  SHELL_FREE_NON_NULL(MainBuffer);
236
237  if (EFI_ERROR(Status)) {
238    ShellPrintHiiEx(
239      -1,
240      -1,
241      NULL,
242      STRING_TOKEN(STR_FILE_WRITE_FAIL),
243      gShellDriver1HiiHandle,
244      L"drvcfg",
245      FileName);
246    return (SHELL_DEVICE_ERROR);
247  }
248  ShellPrintHiiEx(
249    -1,
250    -1,
251    NULL,
252    STRING_TOKEN(STR_DRVCFG_COMP),
253    gShellDriver1HiiHandle);
254
255  return (SHELL_SUCCESS);
256}
257
258/**
259  Function to read in HII configuration information from a file.
260
261  @param[in] Handle           The handle to get info for.
262  @param[in] FileName         The filename to read the info from.
263**/
264SHELL_STATUS
265EFIAPI
266ConfigFromFile(
267  IN       EFI_HANDLE     Handle,
268  IN CONST CHAR16         *FileName
269  )
270{
271  EFI_HII_DATABASE_PROTOCOL     *HiiDatabase;
272  EFI_STATUS                    Status;
273  VOID                          *MainBuffer;
274  UINT64                        Temp;
275  UINTN                         MainBufferSize;
276  EFI_HII_HANDLE                HiiHandle;
277  SHELL_FILE_HANDLE             FileHandle;
278  CHAR16                        *TempDevPathString;
279  EFI_HII_PACKAGE_LIST_HEADER   *PackageListHeader;
280  EFI_HII_PACKAGE_HEADER        *PackageHeader;
281  EFI_DEVICE_PATH_PROTOCOL      *DevPath;
282  UINTN                         HandleIndex;
283
284  HiiDatabase       = NULL;
285  MainBufferSize    = 0;
286  MainBuffer        = NULL;
287  FileHandle        = NULL;
288
289  Status = ShellOpenFileByName(FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
290  if (EFI_ERROR(Status)) {
291    ShellPrintHiiEx(
292      -1,
293      -1,
294      NULL,
295      STRING_TOKEN(STR_GEN_FILE_OPEN_FAIL),
296      gShellDriver1HiiHandle,
297      L"drvcfg",
298      FileName,
299      Status);
300    return (SHELL_DEVICE_ERROR);
301  }
302
303  //
304  // Locate HII Database protocol
305  //
306  Status = gBS->LocateProtocol (
307                  &gEfiHiiDatabaseProtocolGuid,
308                  NULL,
309                  (VOID **) &HiiDatabase
310                  );
311
312  if (EFI_ERROR(Status) || HiiDatabase == NULL) {
313    ShellPrintHiiEx(
314      -1,
315      -1,
316      NULL,
317      STRING_TOKEN(STR_GEN_PROTOCOL_NF),
318      gShellDriver1HiiHandle,
319      L"drvcfg",
320      L"EfiHiiDatabaseProtocol",
321      &gEfiHiiDatabaseProtocolGuid);
322    ShellCloseFile(&FileHandle);
323    return (SHELL_NOT_FOUND);
324  }
325
326  Status = ShellGetFileSize(FileHandle, &Temp);
327  MainBufferSize = (UINTN)Temp;
328  if (EFI_ERROR(Status)) {
329    ShellPrintHiiEx(
330      -1,
331      -1,
332      NULL,
333      STRING_TOKEN(STR_FILE_READ_FAIL),
334      gShellDriver1HiiHandle,
335      L"drvcfg",
336      FileName);
337
338    ShellCloseFile(&FileHandle);
339    return (SHELL_DEVICE_ERROR);
340  }
341  MainBuffer = AllocateZeroPool((UINTN)MainBufferSize);
342  if (EFI_ERROR(Status)) {
343    ShellPrintHiiEx(
344      -1,
345      -1,
346      NULL,
347      STRING_TOKEN(STR_GEN_OUT_MEM),
348      gShellDriver1HiiHandle, L"drvcfg");
349    ShellCloseFile(&FileHandle);
350    return (SHELL_DEVICE_ERROR);
351  }
352  Status = ShellReadFile(FileHandle, &MainBufferSize, MainBuffer);
353  if (EFI_ERROR(Status)) {
354    ShellPrintHiiEx(
355      -1,
356      -1,
357      NULL,
358      STRING_TOKEN(STR_FILE_READ_FAIL),
359      gShellDriver1HiiHandle,
360      L"drvcfg",
361      FileName);
362
363    ShellCloseFile(&FileHandle);
364    SHELL_FREE_NON_NULL(MainBuffer);
365    return (SHELL_DEVICE_ERROR);
366  }
367
368  ShellCloseFile(&FileHandle);
369
370  if (Handle != NULL) {
371    //
372    // User override in place.  Just do it.
373    //
374    HiiHandle         = NULL;
375    Status = ConvertHandleToHiiHandle(Handle, &HiiHandle, HiiDatabase);
376    if (EFI_ERROR(Status)) {
377      ShellPrintHiiEx(
378        -1,
379        -1,
380        NULL,
381        STRING_TOKEN(STR_GEN_HANDLE_NOT),
382        gShellDriver1HiiHandle, L"drvcfg",
383        ConvertHandleToHandleIndex(Handle),
384        L"Device");
385      ShellCloseFile(&FileHandle);
386      return (SHELL_DEVICE_ERROR);
387    }
388    Status = HiiDatabase->UpdatePackageList(HiiDatabase, HiiHandle, MainBuffer);
389    if (EFI_ERROR(Status)) {
390      ShellPrintHiiEx(
391        -1,
392        -1,
393        NULL,
394        STRING_TOKEN(STR_GEN_UEFI_FUNC_WARN),
395        gShellDriver1HiiHandle,
396        L"drvcfg",
397        L"HiiDatabase->UpdatePackageList",
398        Status);
399      return (SHELL_DEVICE_ERROR);
400    }
401  } else {
402    //
403    // we need to parse the buffer and try to match the device paths for each item to try to find it's device path.
404    //
405
406    for (PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER*)MainBuffer
407      ;  PackageListHeader != NULL && ((CHAR8*)PackageListHeader) < (((CHAR8*)MainBuffer)+MainBufferSize)
408      ;  PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER*)(((CHAR8*)(PackageListHeader)) + PackageListHeader->PackageLength )) {
409        for (PackageHeader = (EFI_HII_PACKAGE_HEADER*)(((CHAR8*)(PackageListHeader))+sizeof(EFI_HII_PACKAGE_LIST_HEADER))
410          ; PackageHeader != NULL && ((CHAR8*)PackageHeader) < (((CHAR8*)MainBuffer)+MainBufferSize) && PackageHeader->Type != EFI_HII_PACKAGE_END
411          ; PackageHeader = (EFI_HII_PACKAGE_HEADER*)(((CHAR8*)(PackageHeader))+PackageHeader->Length)) {
412            if (PackageHeader->Type == EFI_HII_PACKAGE_DEVICE_PATH) {
413              HiiHandle         = NULL;
414              Status = FindHiiHandleViaDevPath((EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER)), &HiiHandle, HiiDatabase);
415              if (EFI_ERROR(Status)) {
416                //
417                // print out an error.
418                //
419                TempDevPathString = ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER)), TRUE, TRUE);
420                ShellPrintHiiEx(
421                  -1,
422                  -1,
423                  NULL,
424                  STRING_TOKEN(STR_DRVCFG_IN_FILE_NF),
425                  gShellDriver1HiiHandle,
426                  TempDevPathString);
427                SHELL_FREE_NON_NULL(TempDevPathString);
428             } else {
429                Status = HiiDatabase->UpdatePackageList(HiiDatabase, HiiHandle, PackageListHeader);
430                if (EFI_ERROR(Status)) {
431                  ShellPrintHiiEx(
432                    -1,
433                    -1,
434                    NULL,
435                    STRING_TOKEN(STR_GEN_UEFI_FUNC_WARN),
436                    gShellDriver1HiiHandle,
437                    L"drvcfg",
438                    L"HiiDatabase->UpdatePackageList",
439                    Status);
440                  return (SHELL_DEVICE_ERROR);
441                } else {
442                  DevPath = (EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER));
443                  gBS->LocateDevicePath(&gEfiHiiConfigAccessProtocolGuid, &DevPath, &Handle);
444                  HandleIndex = ConvertHandleToHandleIndex(Handle);
445                  ShellPrintHiiEx(
446                    -1,
447                    -1,
448                    NULL,
449                    STRING_TOKEN(STR_DRVCFG_DONE_HII),
450                    gShellDriver1HiiHandle,
451                    HandleIndex);
452                }
453              }
454            }
455        }
456    }
457  }
458
459  SHELL_FREE_NON_NULL(MainBuffer);
460
461
462  ShellPrintHiiEx(
463    -1,
464    -1,
465    NULL,
466    STRING_TOKEN(STR_DRVCFG_COMP),
467    gShellDriver1HiiHandle);
468  return (SHELL_SUCCESS);
469}
470
471/**
472  Present a requested action to the user.
473
474  @param[in] DriverImageHandle  The handle for the driver to configure.
475  @param[in] ControllerHandle   The handle of the device being managed by the Driver specified.
476  @param[in] ChildHandle        The handle of a child device of the specified device.
477  @param[in] ActionRequired     The required HII action.
478
479  @retval SHELL_INVALID_PARAMETER   A parameter has a invalid value.
480**/
481EFI_STATUS
482EFIAPI
483ShellCmdDriverConfigurationProcessActionRequired (
484  EFI_HANDLE                                DriverImageHandle,
485  EFI_HANDLE                                ControllerHandle,
486  EFI_HANDLE                                ChildHandle,
487  EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED  ActionRequired
488  )
489{
490  EFI_HANDLE  ConnectControllerContextOverride[2];
491
492  switch (ActionRequired) {
493  case EfiDriverConfigurationActionNone:
494    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_NONE), gShellDriver1HiiHandle);
495    break;
496
497  case EfiDriverConfigurationActionStopController:
498    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_STOP), gShellDriver1HiiHandle);
499    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_ENTER_S), gShellDriver1HiiHandle, L"stop controller");
500    ShellPromptForResponse(ShellPromptResponseTypeEnterContinue, NULL, NULL);
501
502    gBS->DisconnectController (ControllerHandle, DriverImageHandle, ChildHandle);
503    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_CTLR_S), gShellDriver1HiiHandle, L"stopped");
504    break;
505
506  case EfiDriverConfigurationActionRestartController:
507    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_RESTART_S), gShellDriver1HiiHandle, L"controller");
508    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_ENTER_S), gShellDriver1HiiHandle, L"restart controller");
509    ShellPromptForResponse(ShellPromptResponseTypeEnterContinue, NULL, NULL);
510
511    gBS->DisconnectController (ControllerHandle, DriverImageHandle, ChildHandle);
512    ConnectControllerContextOverride[0]  = DriverImageHandle;
513    ConnectControllerContextOverride[1]  = NULL;
514    gBS->ConnectController (ControllerHandle, ConnectControllerContextOverride, NULL, TRUE);
515    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_CTLR_S), gShellDriver1HiiHandle, L"restarted");
516    break;
517
518  case EfiDriverConfigurationActionRestartPlatform:
519    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_RESTART_S), gShellDriver1HiiHandle, L"platform");
520    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_ENTER_S), gShellDriver1HiiHandle, L"restart platform");
521    ShellPromptForResponse(ShellPromptResponseTypeEnterContinue, NULL, NULL);
522
523    gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
524    break;
525
526  default:
527    return (EFI_INVALID_PARAMETER);
528  }
529
530  return EFI_SUCCESS;
531}
532
533/**
534  Do the configuration in an environment without HII.
535
536  @param[in] Language           The language code.
537  @param[in] ForceDefaults      TRUE to force defaults, FALSE otherwise.
538  @param[in] DefaultType        If ForceDefaults is TRUE, specifies the default type.
539  @param[in] AllChildren        TRUE to configure all children, FALSE otherwise.
540  @param[in] ValidateOptions    TRUE to validate existing options, FALSE otherwise.
541  @param[in] SetOptions         TRUE to set options, FALSE otherwise.
542  @param[in] DriverImageHandle  The handle for the driver to configure.
543  @param[in] DeviceHandle       The handle of the device being managed by the Driver specified.
544  @param[in] ChildHandle        The handle of a child device of the specified device.
545
546  @retval SHELL_NOT_FOUND           A specified handle could not be found.
547  @retval SHELL_INVALID_PARAMETER   A parameter has a invalid value.
548**/
549SHELL_STATUS
550EFIAPI
551PreHiiDrvCfg (
552  IN CONST CHAR8    *Language,
553  IN BOOLEAN        ForceDefaults,
554  IN UINT32         DefaultType,
555  IN BOOLEAN        AllChildren,
556  IN BOOLEAN        ValidateOptions,
557  IN BOOLEAN        SetOptions,
558  IN EFI_HANDLE     DriverImageHandle,
559  IN EFI_HANDLE     DeviceHandle,
560  IN EFI_HANDLE     ChildHandle
561  )
562{
563  EFI_STATUS                                Status;
564  SHELL_STATUS                              ShellStatus;
565  UINTN                                     OuterLoopCounter;
566  CHAR8                                     *BestLanguage;
567  UINTN                                     DriverImageHandleCount;
568  EFI_HANDLE                                *DriverImageHandleBuffer;
569  UINTN                                     HandleCount;
570  EFI_HANDLE                                *HandleBuffer;
571  UINTN                                     *HandleType;
572  UINTN                                     LoopCounter;
573  UINTN                                     ChildIndex;
574  UINTN                                     ChildHandleCount;
575  EFI_HANDLE                                *ChildHandleBuffer;
576  UINTN                                     *ChildHandleType;
577  EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED  ActionRequired;
578  EFI_DRIVER_CONFIGURATION_PROTOCOL         *DriverConfiguration;
579  BOOLEAN                                   Iso639Language;
580  UINTN                                     HandleIndex1;
581  UINTN                                     HandleIndex2;
582  UINTN                                     HandleIndex3;
583
584  ShellStatus = SHELL_SUCCESS;
585
586  if (ChildHandle == NULL && AllChildren) {
587    SetOptions = FALSE;
588  }
589
590  if (ForceDefaults) {
591    ShellPrintHiiEx(
592      -1,
593      -1,
594      NULL,
595      STRING_TOKEN (STR_DRVCFG_FORCE_D),
596      gShellDriver1HiiHandle,
597      DefaultType);
598  } else if (ValidateOptions) {
599    ShellPrintHiiEx(
600      -1,
601      -1,
602      NULL,
603      STRING_TOKEN (STR_DRVCFG_VALIDATE),
604      gShellDriver1HiiHandle);
605  } else if (SetOptions) {
606    ShellPrintHiiEx(
607      -1,
608      -1,
609      NULL,
610      STRING_TOKEN (STR_DRVCFG_SET),
611      gShellDriver1HiiHandle);
612  }
613
614  if (DriverImageHandle == 0) {
615    DriverImageHandleBuffer = GetHandleListByProtocolList(CfgGuidList);
616    if (DriverImageHandleBuffer == NULL) {
617      ShellStatus = SHELL_NOT_FOUND;
618      goto Done;
619    }
620    for (
621      HandleBuffer = DriverImageHandleBuffer, DriverImageHandleCount = 0
622      ; HandleBuffer != NULL && *HandleBuffer != NULL
623      ; HandleBuffer++,DriverImageHandleCount++);
624  } else {
625    DriverImageHandleCount = 1;
626    //
627    // Allocate buffer to hold the image handle so as to
628    // keep consistent with the above clause
629    //
630    DriverImageHandleBuffer = AllocatePool (sizeof (EFI_HANDLE));
631    ASSERT (DriverImageHandleBuffer);
632    DriverImageHandleBuffer[0] = DriverImageHandle;
633  }
634
635  for (OuterLoopCounter = 0; OuterLoopCounter < DriverImageHandleCount; OuterLoopCounter++) {
636    Iso639Language = FALSE;
637    Status = gBS->OpenProtocol (
638                  DriverImageHandleBuffer[OuterLoopCounter],
639                  &gEfiDriverConfiguration2ProtocolGuid,
640                  (VOID **) &DriverConfiguration,
641                  NULL,
642                  NULL,
643                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
644                  );
645    if (EFI_ERROR (Status)) {
646      Iso639Language = TRUE;
647      Status = gBS->OpenProtocol (
648                    DriverImageHandleBuffer[OuterLoopCounter],
649                    &gEfiDriverConfigurationProtocolGuid,
650                    (VOID **) &DriverConfiguration,
651                    NULL,
652                    NULL,
653                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
654                    );
655    }
656    if (EFI_ERROR (Status)) {
657//      ShellPrintHiiEx(
658//        -1,
659//        -1,
660//        NULL,
661//        STRING_TOKEN (STR_DRVCFG_NOT_SUPPORT),
662//        gShellDriver1HiiHandle,
663//        ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter])
664//        );
665      ShellStatus = SHELL_UNSUPPORTED;
666      continue;
667    }
668
669    BestLanguage = GetBestLanguage (
670                          DriverConfiguration->SupportedLanguages,
671                          Iso639Language,
672                          Language!=NULL?Language:"",
673                          DriverConfiguration->SupportedLanguages,
674                          NULL
675                          );
676    if (BestLanguage == NULL) {
677      ShellPrintHiiEx(
678        -1,
679        -1,
680        NULL,
681        STRING_TOKEN (STR_GEN_NO_VALUE),
682        gShellDriver1HiiHandle,
683        L"drvcfg",
684        L"-l"
685        );
686      ShellStatus = SHELL_INVALID_PARAMETER;
687      continue;
688    }
689
690    Status = ParseHandleDatabaseByRelationshipWithType (
691              DriverImageHandleBuffer[OuterLoopCounter],
692              NULL,
693              &HandleCount,
694              &HandleBuffer,
695              &HandleType
696              );
697    if (EFI_ERROR (Status)) {
698      continue;
699    }
700
701    if (SetOptions && DeviceHandle == NULL) {
702
703      gST->ConOut->ClearScreen (gST->ConOut);
704      Status = DriverConfiguration->SetOptions (
705                                      DriverConfiguration,
706                                      NULL,
707                                      NULL,
708                                      BestLanguage,
709                                      &ActionRequired
710                                      );
711      gST->ConOut->ClearScreen (gST->ConOut);
712
713      ShellPrintHiiEx(
714        -1,
715        -1,
716        NULL,
717        STRING_TOKEN (STR_DRVCFG_ALL_LANG),
718        gShellDriver1HiiHandle,
719        ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]),
720        DriverConfiguration->SupportedLanguages
721        );
722      if (!EFI_ERROR (Status)) {
723        ShellPrintHiiEx(
724          -1,
725          -1,
726          NULL,
727          STRING_TOKEN (STR_DRVCFG_OPTIONS_SET),
728          gShellDriver1HiiHandle);
729        for (LoopCounter = 0; LoopCounter < HandleCount; LoopCounter++) {
730          if ((HandleType[LoopCounter] & HR_CONTROLLER_HANDLE) == HR_CONTROLLER_HANDLE) {
731            ShellCmdDriverConfigurationProcessActionRequired (
732              DriverImageHandleBuffer[OuterLoopCounter],
733              HandleBuffer[LoopCounter],
734              NULL,
735              ActionRequired
736              );
737          }
738        }
739      } else {
740        ShellPrintHiiEx(
741          -1,
742          -1,
743          NULL,
744          STRING_TOKEN (STR_DRVCFG_NOT_SET),
745          gShellDriver1HiiHandle,
746          Status);
747      }
748      continue;
749    }
750
751    for (LoopCounter = 0; LoopCounter < HandleCount; LoopCounter++) {
752      if ((HandleType[LoopCounter] & HR_CONTROLLER_HANDLE) != HR_CONTROLLER_HANDLE) {
753        continue;
754      }
755      if (DeviceHandle != NULL && DeviceHandle != HandleBuffer[LoopCounter]) {
756        continue;
757      }
758      if (ChildHandle == NULL) {
759        HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]);
760        HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]);
761        ShellPrintHiiEx(
762          -1,
763          -1,
764          NULL,
765          STRING_TOKEN (STR_DRVCFG_CTRL_LANG),
766          gShellDriver1HiiHandle,
767          HandleIndex1,
768          HandleIndex2,
769          DriverConfiguration->SupportedLanguages
770          );
771
772        if (ForceDefaults) {
773          Status = DriverConfiguration->ForceDefaults (
774                                          DriverConfiguration,
775                                          HandleBuffer[LoopCounter],
776                                          NULL,
777                                          DefaultType,
778                                          &ActionRequired
779                                          );
780
781          if (!EFI_ERROR (Status)) {
782            ShellPrintHiiEx(
783              -1,
784              -1,
785              NULL,
786              STRING_TOKEN (STR_DRVCFG_DEF_FORCED),
787              gShellDriver1HiiHandle);
788            ShellCmdDriverConfigurationProcessActionRequired (
789              DriverImageHandleBuffer[OuterLoopCounter],
790              HandleBuffer[LoopCounter],
791              NULL,
792              ActionRequired
793              );
794          } else {
795            ShellPrintHiiEx(
796              -1,
797              -1,
798              NULL,
799              STRING_TOKEN (STR_DRVCFG_FORCE_FAILED),
800              gShellDriver1HiiHandle,
801              Status);
802           ShellStatus = SHELL_DEVICE_ERROR;
803         }
804        } else if (ValidateOptions) {
805          Status = DriverConfiguration->OptionsValid (
806                                          DriverConfiguration,
807                                          HandleBuffer[LoopCounter],
808                                          NULL
809                                          );
810
811          if (!EFI_ERROR (Status)) {
812            ShellPrintHiiEx(
813              -1,
814              -1,
815              NULL,
816              STRING_TOKEN (STR_DRVCFG_OPTIONS_VALID),
817              gShellDriver1HiiHandle);
818          } else {
819            ShellPrintHiiEx(
820              -1,
821              -1,
822              NULL,
823              STRING_TOKEN (STR_DRVCFG_OPTIONS_INV),
824              gShellDriver1HiiHandle,
825              Status);
826            ShellStatus = SHELL_DEVICE_ERROR;
827          }
828        } else if (SetOptions) {
829          gST->ConOut->ClearScreen (gST->ConOut);
830          Status = DriverConfiguration->SetOptions (
831                                          DriverConfiguration,
832                                          HandleBuffer[LoopCounter],
833                                          NULL,
834                                          BestLanguage,
835                                          &ActionRequired
836                                          );
837          gST->ConOut->ClearScreen (gST->ConOut);
838          HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]);
839          HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]);
840          ShellPrintHiiEx(
841            -1,
842            -1,
843            NULL,
844            STRING_TOKEN (STR_DRVCFG_CTRL_LANG),
845            gShellDriver1HiiHandle,
846            HandleIndex1,
847            HandleIndex2,
848            DriverConfiguration->SupportedLanguages
849            );
850          if (!EFI_ERROR (Status)) {
851            ShellPrintHiiEx(
852              -1,
853              -1,
854              NULL,
855              STRING_TOKEN (STR_DRVCFG_OPTIONS_SET),
856              gShellDriver1HiiHandle);
857
858            ShellCmdDriverConfigurationProcessActionRequired (
859              DriverImageHandleBuffer[OuterLoopCounter],
860              HandleBuffer[LoopCounter],
861              NULL,
862              ActionRequired
863              );
864
865          } else {
866            ShellPrintHiiEx(
867              -1,
868              -1,
869              NULL,
870              STRING_TOKEN (STR_DRVCFG_NOT_SET),
871              gShellDriver1HiiHandle,
872              Status);
873            ShellStatus = SHELL_DEVICE_ERROR;
874          }
875        } else {
876          Print (L"\n");
877        }
878      }
879
880      if (ChildHandle == NULL && !AllChildren) {
881        continue;
882      }
883
884      Status = ParseHandleDatabaseByRelationshipWithType (
885                DriverImageHandleBuffer[OuterLoopCounter],
886                HandleBuffer[LoopCounter],
887                &ChildHandleCount,
888                &ChildHandleBuffer,
889                &ChildHandleType
890                );
891      if (EFI_ERROR (Status)) {
892        continue;
893      }
894
895      for (ChildIndex = 0; ChildIndex < ChildHandleCount; ChildIndex++) {
896
897        if ((ChildHandleType[ChildIndex] & HR_CHILD_HANDLE) != HR_CHILD_HANDLE) {
898          continue;
899        }
900
901        if (ChildHandle != NULL && ChildHandle != ChildHandleBuffer[ChildIndex]) {
902          continue;
903        }
904
905        HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]);
906        HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]);
907        HandleIndex3 = ConvertHandleToHandleIndex (ChildHandleBuffer[ChildIndex]);
908        ShellPrintHiiEx(
909          -1,
910          -1,
911          NULL,
912          STRING_TOKEN (STR_DRVCFG_CHILD_LANG),
913          gShellDriver1HiiHandle,
914          HandleIndex1,
915          HandleIndex2,
916          HandleIndex3,
917          DriverConfiguration->SupportedLanguages);
918
919        if (ForceDefaults) {
920          Status = DriverConfiguration->ForceDefaults (
921                                          DriverConfiguration,
922                                          HandleBuffer[LoopCounter],
923                                          ChildHandleBuffer[ChildIndex],
924                                          DefaultType,
925                                          &ActionRequired
926                                          );
927
928          if (!EFI_ERROR (Status)) {
929            ShellPrintHiiEx(
930              -1,
931              -1,
932              NULL,
933              STRING_TOKEN (STR_DRVCFG_DEF_FORCED),
934              gShellDriver1HiiHandle);
935
936            ShellCmdDriverConfigurationProcessActionRequired (
937              DriverImageHandleBuffer[OuterLoopCounter],
938              HandleBuffer[LoopCounter],
939              ChildHandleBuffer[ChildIndex],
940              ActionRequired
941              );
942
943          } else {
944            ShellPrintHiiEx(
945              -1,
946              -1,
947              NULL,
948              STRING_TOKEN (STR_DRVCFG_FORCE_FAILED),
949              gShellDriver1HiiHandle,
950              Status);
951            ShellStatus = SHELL_DEVICE_ERROR;
952          }
953        } else if (ValidateOptions) {
954          Status = DriverConfiguration->OptionsValid (
955                                          DriverConfiguration,
956                                          HandleBuffer[LoopCounter],
957                                          ChildHandleBuffer[ChildIndex]
958                                          );
959
960          if (!EFI_ERROR (Status)) {
961            ShellPrintHiiEx(
962              -1,
963              -1,
964              NULL,
965              STRING_TOKEN (STR_DRVCFG_OPTIONS_VALID),
966              gShellDriver1HiiHandle);
967          } else {
968            ShellPrintHiiEx(
969              -1,
970              -1,
971              NULL,
972              STRING_TOKEN (STR_DRVCFG_OPTIONS_INV),
973              gShellDriver1HiiHandle,
974              Status);
975            ShellStatus = SHELL_DEVICE_ERROR;
976          }
977        } else if (SetOptions) {
978          gST->ConOut->ClearScreen (gST->ConOut);
979          Status = DriverConfiguration->SetOptions (
980                                          DriverConfiguration,
981                                          HandleBuffer[LoopCounter],
982                                          ChildHandleBuffer[ChildIndex],
983                                          BestLanguage,
984                                          &ActionRequired
985                                          );
986          gST->ConOut->ClearScreen (gST->ConOut);
987          HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]);
988          HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]);
989          HandleIndex3 = ConvertHandleToHandleIndex (ChildHandleBuffer[ChildIndex]);
990          ShellPrintHiiEx(
991            -1,
992            -1,
993            NULL,
994            STRING_TOKEN (STR_DRVCFG_CHILD_LANG),
995            gShellDriver1HiiHandle,
996            HandleIndex1,
997            HandleIndex2,
998            HandleIndex3,
999            DriverConfiguration->SupportedLanguages
1000            );
1001          if (!EFI_ERROR (Status)) {
1002            ShellPrintHiiEx(
1003              -1,
1004              -1,
1005              NULL,
1006              STRING_TOKEN (STR_DRVCFG_OPTIONS_SET),
1007              gShellDriver1HiiHandle);
1008
1009            ShellCmdDriverConfigurationProcessActionRequired (
1010              DriverImageHandleBuffer[OuterLoopCounter],
1011              HandleBuffer[LoopCounter],
1012              ChildHandleBuffer[ChildIndex],
1013              ActionRequired
1014              );
1015
1016          } else {
1017            ShellPrintHiiEx(
1018              -1,
1019              -1,
1020              NULL,
1021              STRING_TOKEN (STR_DRVCFG_NOT_SET),
1022              gShellDriver1HiiHandle,
1023              Status);
1024            ShellStatus = SHELL_DEVICE_ERROR;
1025          }
1026        } else {
1027          Print (L"\n");
1028        }
1029      }
1030
1031      FreePool (ChildHandleBuffer);
1032      FreePool (ChildHandleType);
1033    }
1034
1035    FreePool (BestLanguage);
1036    FreePool (HandleBuffer);
1037    FreePool (HandleType);
1038  }
1039
1040  if (DriverImageHandle != NULL && DriverImageHandleCount != 0) {
1041    FreePool (DriverImageHandleBuffer);
1042  }
1043
1044Done:
1045  return ShellStatus;
1046}
1047
1048/**
1049  Function to print out configuration information on all configurable handles.
1050
1051  @param[in] ChildrenToo    TRUE to tewst for children.
1052  @param[in] Language       ASCII string for language code.
1053  @param[in] UseHii         TRUE to check for Hii and DPC, FALSE for DCP only.
1054
1055  @retval SHELL_SUCCESS     The operation was successful.
1056**/
1057SHELL_STATUS
1058EFIAPI
1059PrintConfigInfoOnAll(
1060  IN CONST BOOLEAN ChildrenToo,
1061  IN CONST CHAR8   *Language,
1062  IN CONST BOOLEAN UseHii
1063  )
1064{
1065  EFI_HANDLE        *HandleList;
1066  EFI_HANDLE        *CurrentHandle;
1067  BOOLEAN           Found;
1068  UINTN             Index2;
1069
1070
1071  Found             = FALSE;
1072  HandleList        = NULL;
1073  CurrentHandle     = NULL;
1074
1075  if (UseHii) {
1076    //
1077    // HII method
1078    //
1079    HandleList = GetHandleListByProtocol(&gEfiHiiConfigAccessProtocolGuid);
1080    for (CurrentHandle = HandleList ; CurrentHandle != NULL && *CurrentHandle != NULL; CurrentHandle++){
1081      Found = TRUE;
1082      Index2 = *CurrentHandle == NULL ? 0 : ConvertHandleToHandleIndex(*CurrentHandle);
1083      ShellPrintHiiEx(
1084        -1,
1085        -1,
1086        NULL,
1087        STRING_TOKEN (STR_DRVCFG_LINE_HII),
1088        gShellDriver1HiiHandle,
1089        Index2
1090        );
1091    }
1092    SHELL_FREE_NON_NULL(HandleList);
1093  }
1094
1095  if (PreHiiDrvCfg (
1096    Language,
1097    FALSE,
1098    0,
1099    ChildrenToo,
1100    FALSE,
1101    FALSE,
1102    0,
1103    0,
1104    0) == SHELL_SUCCESS) {
1105      Found = TRUE;
1106  }
1107
1108  if (!Found) {
1109    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NONE_FOUND), gShellDriver1HiiHandle);
1110    return (SHELL_SUCCESS);
1111  }
1112
1113  return (SHELL_SUCCESS);
1114}
1115
1116STATIC CONST SHELL_PARAM_ITEM ParamListHii[] = {
1117  {L"-s", TypeFlag},
1118  {L"-l", TypeValue},
1119  {L"-f", TypeValue},
1120  {L"-o", TypeValue},
1121  {L"-i", TypeValue},
1122  {NULL, TypeMax}
1123  };
1124STATIC CONST SHELL_PARAM_ITEM ParamListPreHii[] = {
1125  {L"-c", TypeFlag},
1126  {L"-s", TypeFlag},
1127  {L"-v", TypeFlag},
1128  {L"-l", TypeValue},
1129  {L"-f", TypeValue},
1130  {NULL, TypeMax}
1131  };
1132
1133/**
1134  Function for 'drvcfg' command.
1135
1136  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
1137  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
1138**/
1139SHELL_STATUS
1140EFIAPI
1141ShellCommandRunDrvCfg (
1142  IN EFI_HANDLE        ImageHandle,
1143  IN EFI_SYSTEM_TABLE  *SystemTable
1144  )
1145{
1146  EFI_STATUS          Status;
1147  LIST_ENTRY          *Package;
1148  CHAR16              *ProblemParam;
1149  SHELL_STATUS        ShellStatus;
1150  CHAR8               *Language;
1151  CONST CHAR16        *Lang;
1152  CONST CHAR16        *HandleIndex1;
1153  CONST CHAR16        *HandleIndex2;
1154  CONST CHAR16        *HandleIndex3;
1155  CONST CHAR16        *ForceTypeString;
1156  BOOLEAN             Force;
1157  BOOLEAN             Set;
1158  BOOLEAN             Validate;
1159  BOOLEAN             InFromFile;
1160  BOOLEAN             OutToFile;
1161  BOOLEAN             AllChildren;
1162  BOOLEAN             UseHii;
1163  UINT32              ForceType;
1164  UINT64              Intermediate;
1165  EFI_HANDLE          Handle1;
1166  EFI_HANDLE          Handle2;
1167  EFI_HANDLE          Handle3;
1168  CONST CHAR16        *FileName;
1169
1170  ShellStatus         = SHELL_SUCCESS;
1171  Status              = EFI_SUCCESS;
1172  Language            = NULL;
1173  UseHii              = TRUE;
1174  ProblemParam        = NULL;
1175
1176  //
1177  // initialize the shell lib (we must be in non-auto-init...)
1178  //
1179  Status = ShellInitialize();
1180  ASSERT_EFI_ERROR(Status);
1181
1182  Status = CommandInit();
1183  ASSERT_EFI_ERROR(Status);
1184
1185  //
1186  // parse the command line
1187  //
1188  Status = ShellCommandLineParse (ParamListHii, &Package, &ProblemParam, TRUE);
1189  if (EFI_ERROR(Status) || ShellCommandLineGetCount(Package) > 2) {
1190    UseHii = FALSE;
1191    if (Package != NULL) {
1192      ShellCommandLineFreeVarList (Package);
1193    }
1194    SHELL_FREE_NON_NULL(ProblemParam);
1195    Status = ShellCommandLineParse (ParamListPreHii, &Package, &ProblemParam, TRUE);
1196    if (EFI_ERROR(Status)) {
1197      if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
1198        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"drvcfg", ProblemParam);
1199        FreePool(ProblemParam);
1200        ShellStatus = SHELL_INVALID_PARAMETER;
1201        goto Done;
1202      } else {
1203        ASSERT(FALSE);
1204      }
1205    }
1206  }
1207  if (ShellStatus == SHELL_SUCCESS) {
1208    Lang = ShellCommandLineGetValue(Package, L"-l");
1209    if (Lang != NULL) {
1210      Language = AllocateZeroPool(StrSize(Lang));
1211      AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
1212    } else if (ShellCommandLineGetFlag(Package, L"-l")){
1213      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvcfg",  L"-l");
1214      ShellStatus = SHELL_INVALID_PARAMETER;
1215      goto Done;
1216    }
1217    Set                 = ShellCommandLineGetFlag (Package, L"-s");
1218    Validate            = ShellCommandLineGetFlag (Package, L"-v");
1219    InFromFile          = ShellCommandLineGetFlag (Package, L"-i");
1220    OutToFile           = ShellCommandLineGetFlag (Package, L"-o");
1221    AllChildren         = ShellCommandLineGetFlag (Package, L"-c");
1222    Force               = ShellCommandLineGetFlag (Package, L"-f");
1223    ForceTypeString     = ShellCommandLineGetValue(Package, L"-f");
1224
1225    if (OutToFile) {
1226      FileName = ShellCommandLineGetValue(Package, L"-o");
1227    } else if (InFromFile) {
1228      FileName = ShellCommandLineGetValue(Package, L"-i");
1229    } else {
1230      FileName = NULL;
1231    }
1232
1233    if (InFromFile && EFI_ERROR(ShellFileExists(FileName))) {
1234      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FIND_FAIL), gShellDriver1HiiHandle, L"drvcfg", FileName);
1235      ShellStatus = SHELL_INVALID_PARAMETER;
1236      goto Done;
1237    }
1238    if (OutToFile && !EFI_ERROR(ShellFileExists(FileName))) {
1239      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_EXIST), gShellDriver1HiiHandle, L"drvcfg", FileName);
1240      ShellStatus = SHELL_INVALID_PARAMETER;
1241      goto Done;
1242    }
1243    if (Force && ForceTypeString == NULL) {
1244      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvcfg", L"-f");
1245      ShellStatus = SHELL_INVALID_PARAMETER;
1246      goto Done;
1247    }
1248    if (Force) {
1249      Status = ShellConvertStringToUint64(ForceTypeString, &Intermediate, FALSE, FALSE);
1250      if (EFI_ERROR(Status)) {
1251        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDriver1HiiHandle, L"drvcfg", ForceTypeString, L"-f");
1252        ShellStatus = SHELL_INVALID_PARAMETER;
1253        goto Done;
1254      }
1255      ForceType = (UINT32)Intermediate;
1256    } else {
1257      ForceType = 0;
1258    }
1259    HandleIndex1        = ShellCommandLineGetRawValue(Package, 1);
1260    Handle1             = NULL;
1261    if (HandleIndex1 != NULL && !EFI_ERROR(ShellConvertStringToUint64(HandleIndex1, &Intermediate, TRUE, FALSE))) {
1262      Handle1 = ConvertHandleIndexToHandle((UINTN)Intermediate);
1263      if (Handle1 == NULL || (UINT64)(UINTN)Intermediate != Intermediate) {
1264        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"drvcfg", HandleIndex1);
1265        ShellStatus = SHELL_INVALID_PARAMETER;
1266        goto Done;
1267      }
1268    }
1269    HandleIndex2        = ShellCommandLineGetRawValue(Package, 2);
1270    Handle2             = NULL;
1271    if (HandleIndex2 != NULL && !EFI_ERROR(ShellConvertStringToUint64(HandleIndex2, &Intermediate, TRUE, FALSE))) {
1272      Handle2 = ConvertHandleIndexToHandle((UINTN)Intermediate);
1273      if (Handle2 == NULL || (UINT64)(UINTN)Intermediate != Intermediate) {
1274        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"drvcfg", HandleIndex2);
1275        ShellStatus = SHELL_INVALID_PARAMETER;
1276        goto Done;
1277      }
1278    }
1279    HandleIndex3        = ShellCommandLineGetRawValue(Package, 3);
1280    Handle3             = NULL;
1281    if (HandleIndex3 != NULL && !EFI_ERROR(ShellConvertStringToUint64(HandleIndex3, &Intermediate, TRUE, FALSE))) {
1282      Handle3 = ConvertHandleIndexToHandle((UINTN)Intermediate);
1283      if (Handle3 == NULL || (UINT64)(UINTN)Intermediate != Intermediate) {
1284        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"drvcfg", HandleIndex3);
1285        ShellStatus = SHELL_INVALID_PARAMETER;
1286        goto Done;
1287      }
1288    }
1289
1290    if ((InFromFile || OutToFile) && (FileName == NULL)) {
1291      if (FileName == NULL) {
1292        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvcfg",  InFromFile?L"-i":L"-o");
1293      } else {
1294        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_HANDLE_REQ), gShellDriver1HiiHandle, L"drvcfg");
1295      }
1296      ShellStatus = SHELL_INVALID_PARAMETER;
1297      goto Done;
1298    }
1299    if (!UseHii && (InFromFile || OutToFile)) {
1300      if (InFromFile) {
1301        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDriver1HiiHandle, L"drvcfg", L"-i");
1302        ShellStatus = SHELL_INVALID_PARAMETER;
1303        goto Done;
1304      }
1305      if (OutToFile) {
1306        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDriver1HiiHandle, L"drvcfg", L"-o");
1307        ShellStatus = SHELL_INVALID_PARAMETER;
1308        goto Done;
1309      }
1310    }
1311    if (Validate && Force) {
1312      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-v", L"-f");
1313      ShellStatus = SHELL_INVALID_PARAMETER;
1314      goto Done;
1315    }
1316    if (Validate && Set) {
1317      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-v", L"-s");
1318      ShellStatus = SHELL_INVALID_PARAMETER;
1319      goto Done;
1320    }
1321    if (Set && Force) {
1322      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-s", L"-f");
1323      ShellStatus = SHELL_INVALID_PARAMETER;
1324      goto Done;
1325    }
1326    if (OutToFile && InFromFile) {
1327      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-i", L"-o");
1328      ShellStatus = SHELL_INVALID_PARAMETER;
1329      goto Done;
1330    }
1331
1332    //
1333    // We do HII first.
1334    //
1335    if (UseHii) {
1336      if (Handle1 != NULL && EFI_ERROR(gBS->OpenProtocol(Handle1, &gEfiHiiConfigAccessProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
1337        //
1338        // no HII on this handle.
1339        //
1340        ShellStatus = SHELL_UNSUPPORTED;
1341      } else if (Validate) {
1342      } else if (Force) {
1343      } else if (Set) {
1344      } else if (InFromFile) {
1345        ShellStatus = ConfigFromFile(Handle1, FileName);
1346        if (Handle1 != NULL && ShellStatus == SHELL_SUCCESS) {
1347          goto Done;
1348        }
1349      } else if (OutToFile) {
1350        ShellStatus = ConfigToFile(Handle1, FileName);
1351        if (Handle1 != NULL && ShellStatus == SHELL_SUCCESS) {
1352          goto Done;
1353        }
1354      } else if (HandleIndex1 == NULL) {
1355        //
1356        // display all that are configurable
1357        //
1358        ShellStatus = PrintConfigInfoOnAll(AllChildren, Language, UseHii);
1359        goto Done;
1360      } else {
1361        if (!EFI_ERROR(gBS->OpenProtocol(Handle1, &gEfiHiiConfigAccessProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
1362          ShellPrintHiiEx(
1363            -1,
1364            -1,
1365            NULL,
1366            STRING_TOKEN (STR_DRVCFG_LINE_HII),
1367            gShellDriver1HiiHandle,
1368            ConvertHandleToHandleIndex(Handle1)
1369            );
1370          goto Done;
1371        }
1372      }
1373    }
1374
1375    //
1376    // We allways need to do this one since it does both by default.
1377    //
1378    if (!InFromFile && !OutToFile) {
1379      ShellStatus = PreHiiDrvCfg (
1380        Language,
1381        Force,
1382        ForceType,
1383        AllChildren,
1384        Validate,
1385        Set,
1386        Handle1,
1387        Handle2,
1388        Handle3);
1389    }
1390
1391    if (ShellStatus == SHELL_UNSUPPORTED) {
1392      ShellPrintHiiEx(
1393        -1,
1394        -1,
1395        NULL,
1396        STRING_TOKEN (STR_DRVCFG_NOT_SUPPORT),
1397        gShellDriver1HiiHandle,
1398        ConvertHandleToHandleIndex(Handle1)
1399        );
1400    }
1401  }
1402
1403Done:
1404  ShellCommandLineFreeVarList (Package);
1405  SHELL_FREE_NON_NULL(Language);
1406  return (ShellStatus);
1407}
1408