1 /** @file
2   Main file for Unload shell Driver1 function.
3 
4   (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5   Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
6   SPDX-License-Identifier: BSD-2-Clause-Patent
7 
8 **/
9 
10 #include "UefiShellDriver1CommandsLib.h"
11 
12 /**
13   Function to dump LoadedImage info from TheHandle.
14 
15   @param[in] TheHandle              The handle to dump info from.
16 
17   @retval EFI_SUCCESS               The info was dumped.
18   @retval EFI_INVALID_PARAMETER     The handle did not have LoadedImage
19 **/
20 EFI_STATUS
DumpLoadedImageProtocolInfo(IN EFI_HANDLE TheHandle)21 DumpLoadedImageProtocolInfo (
22   IN EFI_HANDLE   TheHandle
23   )
24 {
25   CHAR16 *TheString;
26 
27   TheString = GetProtocolInformationDump(TheHandle, &gEfiLoadedImageProtocolGuid, TRUE);
28 
29   ShellPrintEx(-1, -1, L"%s", TheString);
30 
31   SHELL_FREE_NON_NULL(TheString);
32 
33   return (EFI_SUCCESS);
34 }
35 
36 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
37   {L"-n", TypeFlag},
38   {L"-v", TypeFlag},
39   {L"-verbose", TypeFlag},
40   {NULL, TypeMax}
41   };
42 
43 /**
44   Function for 'unload' command.
45 
46   @param[in] ImageHandle  Handle to the Image (NULL if Internal).
47   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
48 **/
49 SHELL_STATUS
50 EFIAPI
ShellCommandRunUnload(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)51 ShellCommandRunUnload (
52   IN EFI_HANDLE        ImageHandle,
53   IN EFI_SYSTEM_TABLE  *SystemTable
54   )
55 {
56   EFI_STATUS            Status;
57   LIST_ENTRY            *Package;
58   CHAR16                *ProblemParam;
59   SHELL_STATUS          ShellStatus;
60   EFI_HANDLE            TheHandle;
61   CONST CHAR16          *Param1;
62   SHELL_PROMPT_RESPONSE *Resp;
63   UINT64                Value;
64 
65   ShellStatus         = SHELL_SUCCESS;
66   Package             = NULL;
67   Resp                = NULL;
68   Value               = 0;
69   TheHandle           = NULL;
70 
71   //
72   // initialize the shell lib (we must be in non-auto-init...)
73   //
74   Status = ShellInitialize();
75   ASSERT_EFI_ERROR(Status);
76 
77   //
78   // parse the command line
79   //
80   Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
81   if (EFI_ERROR(Status)) {
82     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
83       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle,L"unload", ProblemParam);
84       FreePool(ProblemParam);
85       ShellStatus = SHELL_INVALID_PARAMETER;
86     } else {
87       ASSERT(FALSE);
88     }
89   } else {
90     if (ShellCommandLineGetCount(Package) > 2){
91       //
92       // error for too many parameters
93       //
94       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"unload");
95       ShellStatus = SHELL_INVALID_PARAMETER;
96     } else if (ShellCommandLineGetCount(Package) < 2) {
97       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDriver1HiiHandle, L"unload");
98       ShellStatus = SHELL_INVALID_PARAMETER;
99     } else {
100       Param1    = ShellCommandLineGetRawValue(Package, 1);
101       if (Param1 != NULL) {
102         Status    = ShellConvertStringToUint64(Param1, &Value, TRUE, FALSE);
103         TheHandle = ConvertHandleIndexToHandle((UINTN)Value);
104       }
105 
106       if (EFI_ERROR(Status) || Param1 == NULL || TheHandle == NULL){
107         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"unload", Param1);
108         ShellStatus = SHELL_INVALID_PARAMETER;
109       } else {
110         ASSERT(TheHandle != NULL);
111         if (ShellCommandLineGetFlag(Package, L"-v") || ShellCommandLineGetFlag(Package, L"-verbose")) {
112           DumpLoadedImageProtocolInfo(TheHandle);
113         }
114 
115         if (!ShellCommandLineGetFlag(Package, L"-n")) {
116           Status = ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_UNLOAD_CONF), gShellDriver1HiiHandle, (UINTN)TheHandle);
117           Status = ShellPromptForResponse(ShellPromptResponseTypeYesNo, NULL, (VOID**)&Resp);
118         }
119         if (ShellCommandLineGetFlag(Package, L"-n") || (Resp != NULL && *Resp == ShellPromptResponseYes)) {
120           Status = gBS->UnloadImage(TheHandle);
121           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HANDLE_RESULT), gShellDriver1HiiHandle, L"Unload", (UINTN)TheHandle, Status);
122         }
123         SHELL_FREE_NON_NULL(Resp);
124       }
125     }
126   }
127   if (ShellStatus == SHELL_SUCCESS) {
128     if (Status == EFI_SECURITY_VIOLATION) {
129       ShellStatus = SHELL_SECURITY_VIOLATION;
130     } else if (Status == EFI_INVALID_PARAMETER) {
131       ShellStatus = SHELL_INVALID_PARAMETER;
132     } else if (EFI_ERROR(Status)) {
133       ShellStatus = SHELL_NOT_FOUND;
134     }
135   }
136 
137   if (Package != NULL) {
138     ShellCommandLineFreeVarList(Package);
139   }
140 
141   return (ShellStatus);
142 }
143