]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDriver1CommandsLib/Connect.c
Update return value.
[mirror_edk2.git] / ShellPkg / Library / UefiShellDriver1CommandsLib / Connect.c
1 /** @file
2 Main file for connect shell Driver1 function.
3
4 Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "UefiShellDriver1CommandsLib.h"
16
17 /**
18 **/
19 EFI_STATUS
20 EFIAPI
21 ConnectControllers (
22 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,
23 IN CONST EFI_HANDLE DriverHandle OPTIONAL,
24 IN CONST BOOLEAN Recursive,
25 IN CONST BOOLEAN Output,
26 IN CONST BOOLEAN AlwaysOutput
27 )
28 {
29 EFI_STATUS Status;
30 EFI_STATUS Status2;
31 EFI_HANDLE *ControllerHandleList;
32 EFI_HANDLE *DriverHandleList;
33 EFI_HANDLE *HandleWalker;
34
35 ControllerHandleList = NULL;
36 Status = EFI_NOT_FOUND;
37 Status2 = EFI_NOT_FOUND;
38
39 //
40 // If we have a single handle to connect make that a 'list'
41 //
42 if (DriverHandle == NULL) {
43 DriverHandleList = NULL;
44 } else {
45 DriverHandleList = AllocatePool(2*sizeof(EFI_HANDLE));
46 if (DriverHandleList == NULL) {
47 return (EFI_OUT_OF_RESOURCES);
48 }
49 DriverHandleList[0] = DriverHandle;
50 DriverHandleList[1] = NULL;
51 }
52
53 //
54 // do we connect all controllers (with a loop) or a single one...
55 // This is where we call the gBS->ConnectController function.
56 //
57 if (ControllerHandle == NULL) {
58 ControllerHandleList = GetHandleListByProtocol(&gEfiDevicePathProtocolGuid);
59 for (HandleWalker = ControllerHandleList
60 ; HandleWalker != NULL && *HandleWalker != NULL
61 ; HandleWalker++
62 ){
63 Status = gBS->ConnectController(*HandleWalker, DriverHandleList, NULL, Recursive);
64 if (!EFI_ERROR(Status)) {
65 Status2 = EFI_SUCCESS;
66 }
67 if ((Output && !EFI_ERROR(Status)) || AlwaysOutput) {
68 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_HANDLE_RESULT), gShellDriver1HiiHandle, L"Connect", ConvertHandleToHandleIndex(*HandleWalker), Status);
69 }
70 }
71 } else {
72 Status = gBS->ConnectController(ControllerHandle, DriverHandleList, NULL, Recursive);
73 if (!EFI_ERROR(Status)) {
74 Status2 = EFI_SUCCESS;
75 }
76 if ((Output && !EFI_ERROR(Status)) || AlwaysOutput) {
77 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_HANDLE_RESULT), gShellDriver1HiiHandle, L"Connect", ConvertHandleToHandleIndex(ControllerHandle), Status);
78 }
79 }
80
81 //
82 // Free any memory we allocated.
83 //
84 if (ControllerHandleList != NULL) {
85 FreePool(ControllerHandleList);
86 }
87 if (DriverHandleList != NULL) {
88 FreePool(DriverHandleList);
89 }
90 return (Status2);
91 }
92
93 EFI_STATUS
94 EFIAPI
95 ConnectFromDevPaths (
96 IN CONST CHAR16 *Key
97 )
98 {
99 EFI_DEVICE_PATH_PROTOCOL *DevPath;
100 EFI_DEVICE_PATH_PROTOCOL *DevPathWalker;
101 UINTN Length;
102 EFI_HANDLE Handle;
103 EFI_STATUS Status;
104
105 DevPath = NULL;
106 Length = 0;
107
108 //
109 // Get the DevicePath buffer from the variable...
110 //
111 Status = gRT->GetVariable((CHAR16*)Key, (EFI_GUID*)&gEfiGlobalVariableGuid, NULL, &Length, DevPath);
112 if (Status == EFI_BUFFER_TOO_SMALL) {
113 DevPath = AllocatePool(Length);
114 Status = gRT->GetVariable((CHAR16*)Key, (EFI_GUID*)&gEfiGlobalVariableGuid, NULL, &Length, DevPath);
115 }
116
117 Status = EFI_NOT_FOUND;
118 //
119 // walk the list of devices and connect them
120 //
121 for (DevPathWalker = DevPath
122 ; DevPathWalker < (DevPath + Length) && EFI_ERROR(Status) && DevPath != NULL
123 ; DevPathWalker += GetDevicePathSize(DevPathWalker)
124 ){
125 //
126 // get the correct handle from a given device path
127 //
128 if ((StrCmp(Key, L"ConInDev") == 0)
129 ||(StrCmp(Key, L"ConIn") == 0)
130 ){
131 Status = gBS->LocateDevicePath((EFI_GUID*)&gEfiConsoleInDeviceGuid, &DevPathWalker, &Handle);
132 if (!EFI_ERROR(Status)) {
133 Status = ConnectControllers(NULL, Handle, FALSE, TRUE, FALSE);
134 }
135 } else if ((StrCmp(Key, L"ConOutDev") == 0)
136 || (StrCmp(Key, L"ConErrDev") == 0)
137 || (StrCmp(Key, L"ConOut") == 0)
138 || (StrCmp(Key, L"ConErr") == 0)
139 ){
140 Status = gBS->LocateDevicePath((EFI_GUID*)&gEfiConsoleOutDeviceGuid, &DevPathWalker, &Handle);
141 if (!EFI_ERROR(Status)) {
142 Status = ConnectControllers(NULL, Handle, FALSE, TRUE, FALSE);
143 }
144 }
145 }
146
147 if (DevPath != NULL) {
148 FreePool(DevPath);
149 }
150 return (Status);
151 }
152
153 EFI_STATUS
154 EFIAPI
155 ConvertAndConnectControllers (
156 IN CONST CHAR16 *StringHandle1 OPTIONAL,
157 IN CONST CHAR16 *StringHandle2 OPTIONAL,
158 IN CONST BOOLEAN Recursive,
159 IN CONST BOOLEAN Output
160 )
161 {
162 EFI_HANDLE Handle1;
163 EFI_HANDLE Handle2;
164
165 //
166 // Convert the command line parameters to HANDLES. They must be in HEX according to spec.
167 //
168 if (StringHandle1 != NULL) {
169 Handle1 = ConvertHandleIndexToHandle(StrHexToUintn(StringHandle1));
170 } else {
171 Handle1 = NULL;
172 }
173 if (StringHandle2 != NULL) {
174 Handle2 = ConvertHandleIndexToHandle(StrHexToUintn(StringHandle2));
175 } else {
176 Handle2 = NULL;
177 }
178
179 //
180 // if only one is NULL verify it's the proper one...
181 //
182 if ( (Handle1 == NULL && Handle2 != NULL)
183 || (Handle1 != NULL && Handle2 == NULL)
184 ){
185 //
186 // Figure out which one should be NULL and move the handle to the right place.
187 // If Handle1 is NULL then test Handle2 and vise versa.
188 // The one that DOES has driver binding must be Handle2
189 //
190 if (Handle1 == NULL) {
191 if (EFI_ERROR(gBS->OpenProtocol(Handle2, &gEfiDriverBindingProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
192 // swap
193 Handle1 = Handle2;
194 Handle2 = NULL;
195 } else {
196 // We're all good...
197 }
198 } else {
199 if (EFI_ERROR(gBS->OpenProtocol(Handle1, &gEfiDriverBindingProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
200 // We're all good...
201 } else {
202 // swap
203 Handle2 = Handle1;
204 Handle1 = NULL;
205 }
206 }
207 }
208
209 return (ConnectControllers(Handle1, Handle2, Recursive, Output, FALSE));
210 }
211
212 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
213 {L"-c", TypeFlag},
214 {L"-r", TypeFlag},
215 {NULL, TypeMax}
216 };
217
218 /**
219 Function for 'connect' command.
220
221 @param[in] ImageHandle Handle to the Image (NULL if Internal).
222 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
223 **/
224 SHELL_STATUS
225 EFIAPI
226 ShellCommandRunConnect (
227 IN EFI_HANDLE ImageHandle,
228 IN EFI_SYSTEM_TABLE *SystemTable
229 )
230 {
231 EFI_STATUS Status;
232 LIST_ENTRY *Package;
233 CHAR16 *ProblemParam;
234 SHELL_STATUS ShellStatus;
235 CONST CHAR16 *Param1;
236 CONST CHAR16 *Param2;
237 UINTN Count;
238
239 ShellStatus = SHELL_SUCCESS;
240
241 //
242 // initialize the shell lib (we must be in non-auto-init...)
243 //
244 Status = ShellInitialize();
245 ASSERT_EFI_ERROR(Status);
246
247 Status = CommandInit();
248 ASSERT_EFI_ERROR(Status);
249
250 //
251 // parse the command line
252 //
253 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
254 if (EFI_ERROR(Status)) {
255 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
256 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, ProblemParam);
257 FreePool(ProblemParam);
258 ShellStatus = SHELL_INVALID_PARAMETER;
259 } else {
260 ASSERT(FALSE);
261 }
262 } else {
263 //
264 // if more than 2 'value' parameters (plus the name one) or either -r or -c with any value parameters we have too many parameters
265 //
266 if ((ShellCommandLineGetCount(Package) > 3)
267 ||((ShellCommandLineGetFlag(Package, L"-r") || ShellCommandLineGetFlag(Package, L"-c")) && ShellCommandLineGetCount(Package)>1)
268 ||(ShellCommandLineGetFlag(Package, L"-r") && ShellCommandLineGetFlag(Package, L"-c") )
269 ){
270 //
271 // error for too many parameters
272 //
273 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle);
274 ShellStatus = SHELL_INVALID_PARAMETER;
275 } else if (ShellCommandLineGetFlag(Package, L"-c")) {
276 //
277 // do the conin and conout from EFI variables
278 // if the first fails dont 'loose' the error
279 //
280 Status = ConnectFromDevPaths(L"ConInDev");
281 if (EFI_ERROR(Status)) {
282 ConnectFromDevPaths(L"ConOutDev");
283 } else {
284 Status = ConnectFromDevPaths(L"ConOutDev");
285 }
286 if (EFI_ERROR(Status)) {
287 ConnectFromDevPaths(L"ConErrDev");
288 } else {
289 Status = ConnectFromDevPaths(L"ConErrDev");
290 }
291 if (EFI_ERROR(Status)) {
292 ConnectFromDevPaths(L"ConErr");
293 } else {
294 Status = ConnectFromDevPaths(L"ConErr");
295 }
296 if (EFI_ERROR(Status)) {
297 ConnectFromDevPaths(L"ConIn");
298 } else {
299 Status = ConnectFromDevPaths(L"ConIn");
300 }
301 if (EFI_ERROR(Status)) {
302 ConnectFromDevPaths(L"ConOut");
303 } else {
304 Status = ConnectFromDevPaths(L"ConOut");
305 }
306 if (EFI_ERROR(Status)) {
307 ShellStatus = SHELL_DEVICE_ERROR;
308 }
309 } else {
310 //
311 // 0, 1, or 2 specific handles and possibly recursive
312 //
313 Param1 = ShellCommandLineGetRawValue(Package, 1);
314 Param2 = ShellCommandLineGetRawValue(Package, 2);
315 Count = ShellCommandLineGetCount(Package);
316 if (Param1 != NULL && ConvertHandleIndexToHandle(StrHexToUintn(Param1)) == NULL){
317 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, Param1);
318 ShellStatus = SHELL_INVALID_PARAMETER;
319 } else if (Param2 != NULL && ConvertHandleIndexToHandle(StrHexToUintn(Param2)) == NULL) {
320 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, Param2);
321 ShellStatus = SHELL_INVALID_PARAMETER;
322 } else {
323 Status = ConvertAndConnectControllers(Param1, Param2, ShellCommandLineGetFlag(Package, L"-r"), (BOOLEAN)(Count!=0));
324 if (EFI_ERROR(Status)) {
325 ShellStatus = SHELL_DEVICE_ERROR;
326 }
327 }
328 }
329
330 ShellCommandLineFreeVarList (Package);
331 }
332 return (ShellStatus);
333 }
334