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