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