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