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**/
26EFI_STATUS
27DumpLoadedImageProtocolInfo (
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
42STATIC 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**/
55SHELL_STATUS
56EFIAPI
57ShellCommandRunUnload (
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