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 
20 STATIC 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 **/
32 EFI_STATUS
33 EFIAPI
FindHiiHandleViaDevPath(IN CONST EFI_DEVICE_PATH_PROTOCOL * DevPath1,OUT EFI_HII_HANDLE * HiiHandle,IN EFI_HII_DATABASE_PROTOCOL * HiiDb)34 FindHiiHandleViaDevPath(
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 **/
119 EFI_STATUS
120 EFIAPI
ConvertHandleToHiiHandle(IN CONST EFI_HANDLE Handle,OUT EFI_HII_HANDLE * HiiHandle,IN EFI_HII_DATABASE_PROTOCOL * HiiDb)121 ConvertHandleToHiiHandle(
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 **/
154 SHELL_STATUS
155 EFIAPI
ConfigToFile(IN CONST EFI_HANDLE Handle,IN CONST CHAR16 * FileName)156 ConfigToFile(
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 **/
264 SHELL_STATUS
265 EFIAPI
ConfigFromFile(IN EFI_HANDLE Handle,IN CONST CHAR16 * FileName)266 ConfigFromFile(
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 **/
481 EFI_STATUS
482 EFIAPI
ShellCmdDriverConfigurationProcessActionRequired(EFI_HANDLE DriverImageHandle,EFI_HANDLE ControllerHandle,EFI_HANDLE ChildHandle,EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED ActionRequired)483 ShellCmdDriverConfigurationProcessActionRequired (
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 **/
549 SHELL_STATUS
550 EFIAPI
PreHiiDrvCfg(IN CONST CHAR8 * Language,IN BOOLEAN ForceDefaults,IN UINT32 DefaultType,IN BOOLEAN AllChildren,IN BOOLEAN ValidateOptions,IN BOOLEAN SetOptions,IN EFI_HANDLE DriverImageHandle,IN EFI_HANDLE DeviceHandle,IN EFI_HANDLE ChildHandle)551 PreHiiDrvCfg (
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 
1044 Done:
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 **/
1057 SHELL_STATUS
1058 EFIAPI
PrintConfigInfoOnAll(IN CONST BOOLEAN ChildrenToo,IN CONST CHAR8 * Language,IN CONST BOOLEAN UseHii)1059 PrintConfigInfoOnAll(
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 
1116 STATIC 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   };
1124 STATIC 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 **/
1139 SHELL_STATUS
1140 EFIAPI
ShellCommandRunDrvCfg(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)1141 ShellCommandRunDrvCfg (
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 
1403 Done:
1404   ShellCommandLineFreeVarList (Package);
1405   SHELL_FREE_NON_NULL(Language);
1406   return (ShellStatus);
1407 }
1408