1 /** @file 2 Main file for Disconnect shell Driver1 function. 3 4 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> 5 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> 6 Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR> 7 This program and the accompanying materials 8 are licensed and made available under the terms and conditions of the BSD License 9 which accompanies this distribution. The full text of the license may be found at 10 http://opensource.org/licenses/bsd-license.php 11 12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 14 15 **/ 16 17 #include "UefiShellDriver1CommandsLib.h" 18 19 STATIC CONST SHELL_PARAM_ITEM ParamList[] = { 20 {L"-r", TypeFlag}, 21 {L"-nc", TypeFlag}, 22 {NULL, TypeMax} 23 }; 24 25 /** 26 Disconnect everything. 27 28 @retval EFI_SUCCESS The operation was successful. 29 **/ 30 EFI_STATUS 31 DisconnectAll( 32 VOID 33 ) 34 { 35 // 36 // Stolen from UEFI 2.3 spec (May 2009 version) 37 // Pages 171/172 38 // Removed gBS local definition 39 // 40 41 // 42 // Disconnect All Handles Example 43 // The following example recusively disconnects all drivers from all 44 // controllers in a platform. 45 // 46 EFI_STATUS Status; 47 // EFI_BOOT_SERVICES *gBS; 48 UINTN HandleCount; 49 EFI_HANDLE *HandleBuffer; 50 UINTN HandleIndex; 51 // 52 // Retrieve the list of all handles from the handle database 53 // 54 Status = gBS->LocateHandleBuffer ( 55 AllHandles, 56 NULL, 57 NULL, 58 &HandleCount, 59 &HandleBuffer 60 ); 61 if (!EFI_ERROR (Status)) { 62 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) { 63 Status = gBS->DisconnectController ( 64 HandleBuffer[HandleIndex], 65 NULL, 66 NULL 67 ); 68 } 69 gBS->FreePool(HandleBuffer); 70 // 71 // end of stealing 72 // 73 } 74 return (EFI_SUCCESS); 75 } 76 77 /** 78 Function for 'disconnect' command. 79 80 @param[in] ImageHandle Handle to the Image (NULL if Internal). 81 @param[in] SystemTable Pointer to the System Table (NULL if Internal). 82 **/ 83 SHELL_STATUS 84 EFIAPI 85 ShellCommandRunDisconnect ( 86 IN EFI_HANDLE ImageHandle, 87 IN EFI_SYSTEM_TABLE *SystemTable 88 ) 89 { 90 EFI_STATUS Status; 91 LIST_ENTRY *Package; 92 CHAR16 *ProblemParam; 93 SHELL_STATUS ShellStatus; 94 CONST CHAR16 *Param1; 95 CONST CHAR16 *Param2; 96 CONST CHAR16 *Param3; 97 EFI_HANDLE Handle1; 98 EFI_HANDLE Handle2; 99 EFI_HANDLE Handle3; 100 UINT64 Intermediate1; 101 UINT64 Intermediate2; 102 UINT64 Intermediate3; 103 104 ShellStatus = SHELL_SUCCESS; 105 106 // 107 // initialize the shell lib (we must be in non-auto-init...) 108 // 109 Status = ShellInitialize(); 110 ASSERT_EFI_ERROR(Status); 111 112 Status = CommandInit(); 113 ASSERT_EFI_ERROR(Status); 114 115 // 116 // parse the command line 117 // 118 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); 119 if (EFI_ERROR(Status)) { 120 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { 121 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"disconnect", ProblemParam); 122 FreePool(ProblemParam); 123 ShellStatus = SHELL_INVALID_PARAMETER; 124 } else { 125 ASSERT(FALSE); 126 } 127 } else { 128 if (ShellCommandLineGetFlag(Package, L"-r")){ 129 if (ShellCommandLineGetCount(Package) > 1){ 130 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"disconnect"); 131 ShellStatus = SHELL_INVALID_PARAMETER; 132 } else if (ShellCommandLineGetCount(Package) < 1) { 133 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDriver1HiiHandle, L"disconnect"); 134 ShellStatus = SHELL_INVALID_PARAMETER; 135 } else { 136 Status = DisconnectAll (); 137 // 138 // Reconnect all consoles if -nc is not provided 139 // 140 if (!ShellCommandLineGetFlag (Package, L"-nc")){ 141 ShellConnectFromDevPaths (L"ConInDev"); 142 ShellConnectFromDevPaths (L"ConOutDev"); 143 ShellConnectFromDevPaths (L"ErrOutDev"); 144 ShellConnectFromDevPaths (L"ErrOut"); 145 ShellConnectFromDevPaths (L"ConIn"); 146 ShellConnectFromDevPaths (L"ConOut"); 147 } 148 } 149 } else if (ShellCommandLineGetFlag (Package, L"-nc")) { 150 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDriver1HiiHandle, L"disconnect"); 151 ShellStatus = SHELL_INVALID_PARAMETER; 152 } else { 153 if (ShellCommandLineGetCount(Package) > 4){ 154 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"disconnect"); 155 ShellStatus = SHELL_INVALID_PARAMETER; 156 } else if (ShellCommandLineGetCount(Package) < 2) { 157 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDriver1HiiHandle, L"disconnect"); 158 ShellStatus = SHELL_INVALID_PARAMETER; 159 } else { 160 // 161 // must have between 1 and 3 handles passed in ... 162 // 163 Param1 = ShellCommandLineGetRawValue(Package, 1); 164 Param2 = ShellCommandLineGetRawValue(Package, 2); 165 Param3 = ShellCommandLineGetRawValue(Package, 3); 166 ShellConvertStringToUint64(Param1, &Intermediate1, TRUE, FALSE); 167 Handle1 = Param1!=NULL?ConvertHandleIndexToHandle((UINTN)Intermediate1):NULL; 168 ShellConvertStringToUint64(Param2, &Intermediate2, TRUE, FALSE); 169 Handle2 = Param2!=NULL?ConvertHandleIndexToHandle((UINTN)Intermediate2):NULL; 170 ShellConvertStringToUint64(Param3, &Intermediate3, TRUE, FALSE); 171 Handle3 = Param3!=NULL?ConvertHandleIndexToHandle((UINTN)Intermediate3):NULL; 172 173 if (Param1 != NULL && Handle1 == NULL) { 174 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"disconnect", Param1); 175 ShellStatus = SHELL_INVALID_PARAMETER; 176 } else if (Param2 != NULL && Handle2 == NULL) { 177 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"disconnect", Param2); 178 ShellStatus = SHELL_INVALID_PARAMETER; 179 } else if (Param3 != NULL && Handle3 == NULL) { 180 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"disconnect", Param3); 181 ShellStatus = SHELL_INVALID_PARAMETER; 182 } else if (Handle2 != NULL && EFI_ERROR(gBS->OpenProtocol(Handle2, &gEfiDriverBindingProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) { 183 ASSERT(Param2 != NULL); 184 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_HANDLE_NOT), gShellDriver1HiiHandle, L"disconnect", ShellStrToUintn(Param2), L"driver handle"); 185 ShellStatus = SHELL_INVALID_PARAMETER; 186 } else { 187 ASSERT(Param1 != NULL); 188 Status = gBS->DisconnectController(Handle1, Handle2, Handle3); 189 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_3P_RESULT), gShellDriver1HiiHandle, L"Disconnect", (UINTN)Intermediate1, (UINTN)Intermediate2, (UINTN)Intermediate3, Status); 190 } 191 } 192 } 193 } 194 if (ShellStatus == SHELL_SUCCESS) { 195 if (Status == EFI_SECURITY_VIOLATION) { 196 ShellStatus = SHELL_SECURITY_VIOLATION; 197 } else if (Status == EFI_INVALID_PARAMETER) { 198 ShellStatus = SHELL_INVALID_PARAMETER; 199 } else if (EFI_ERROR(Status)) { 200 ShellStatus = SHELL_NOT_FOUND; 201 } 202 } 203 return (ShellStatus); 204 } 205