]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDriver1CommandsLib/Connect.c
udk2010.up2.shell initial release.
[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 #include <Guid/GlobalVariable.h>
17 #include <Guid/ConsoleInDevice.h>
18 #include <Guid/ConsoleOutDevice.h>
19
20 EFI_STATUS
21 EFIAPI
22 ConnectControllers (
23 IN CONST EFI_HANDLE ControllerHandle,
24 IN CONST EFI_HANDLE DriverHandle,
25 IN CONST BOOLEAN Recursive,
26 IN CONST BOOLEAN Output
27 ){
28 EFI_STATUS Status;
29 EFI_HANDLE *ControllerHandleList;
30 EFI_HANDLE *DriverHandleList;
31 EFI_HANDLE *HandleWalker;
32
33 ControllerHandleList = NULL;
34 Status = EFI_NOT_FOUND;
35
36 //
37 // If we have a single handle to connect make that a 'list'
38 //
39 if (DriverHandle == NULL) {
40 DriverHandleList = NULL;
41 } else {
42 DriverHandleList = AllocatePool(2*sizeof(EFI_HANDLE));
43 DriverHandleList[0] = DriverHandle;
44 DriverHandleList[1] = NULL;
45 }
46
47 //
48 // do we connect all controllers (with a loop) or a single one...
49 // This is where we call the gBS->ConnectController function.
50 //
51 if (ControllerHandle == NULL) {
52 ControllerHandleList = GetHandleListByPotocol(&gEfiDevicePathProtocolGuid);
53 for (HandleWalker = ControllerHandleList
54 ; HandleWalker != NULL && *HandleWalker != NULL
55 ; HandleWalker++
56 ){
57 Status = gBS->ConnectController(*HandleWalker, DriverHandleList, NULL, Recursive);
58 if (Output) {
59 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_CON_RESULT), gShellDriver1HiiHandle, *HandleWalker, Status);
60 }
61 }
62 } else {
63 Status = gBS->ConnectController(ControllerHandle, DriverHandleList, NULL, Recursive);
64 ASSERT(Output == FALSE);
65 }
66
67 //
68 // Free any memory we allocated.
69 //
70 if (ControllerHandleList != NULL) {
71 FreePool(ControllerHandleList);
72 }
73 if (DriverHandleList != NULL) {
74 FreePool(DriverHandleList);
75 }
76 return (Status);
77 }
78
79 EFI_STATUS
80 EFIAPI
81 ConnectFromDevPaths (
82 IN CONST CHAR16 *Key
83 ){
84 EFI_DEVICE_PATH_PROTOCOL *DevPath;
85 EFI_DEVICE_PATH_PROTOCOL *DevPathWalker;
86 UINTN Length;
87 EFI_HANDLE Handle;
88 EFI_STATUS Status;
89
90 DevPath = NULL;
91 Length = 0;
92
93 //
94 // Get the DevicePath buffer from the variable...
95 //
96 Status = gRT->GetVariable((CHAR16*)Key, (EFI_GUID*)&gEfiGlobalVariableGuid, NULL, &Length, DevPath);
97 if (Status == EFI_BUFFER_TOO_SMALL) {
98 DevPath = AllocatePool(Length);
99 Status = gRT->GetVariable((CHAR16*)Key, (EFI_GUID*)&gEfiGlobalVariableGuid, NULL, &Length, DevPath);
100 }
101
102 //
103 // walk the list of devices and connect them
104 //
105 for (DevPathWalker = DevPath
106 ; DevPathWalker < (DevPath + Length) && !EFI_ERROR(Status) && DevPath != NULL
107 ; DevPathWalker += GetDevicePathSize(DevPathWalker)
108 ){
109 //
110 // get the correct handle from a given device path
111 //
112 if (StrCmp(Key, L"ConInDev") == 0) {
113 Status = gBS->LocateDevicePath((EFI_GUID*)&gEfiConsoleInDeviceGuid, &DevPathWalker, &Handle);
114 } else if (StrCmp(Key, L"ConOutDev") == 0) {
115 Status = gBS->LocateDevicePath((EFI_GUID*)&gEfiConsoleOutDeviceGuid, &DevPathWalker, &Handle);
116 } else {
117 Handle = NULL;
118 Status = EFI_INVALID_PARAMETER;
119 ASSERT(FALSE);
120 }
121 if (!EFI_ERROR(Status)) {
122 Status = ConnectControllers(Handle, NULL, FALSE, FALSE);
123 }
124 }
125
126 if (DevPath != NULL) {
127 FreePool(DevPath);
128 }
129 return (Status);
130 }
131
132 EFI_STATUS
133 EFIAPI
134 ConvertAndConnectControllers (
135 IN CONST CHAR16 *StringHandle1,
136 IN CONST CHAR16 *StringHandle2 OPTIONAL,
137 IN CONST BOOLEAN Recursive,
138 IN CONST BOOLEAN Output
139 ){
140 EFI_HANDLE Handle1;
141 EFI_HANDLE Handle2;
142
143 //
144 // Convert the command line parameters to HANDLES. They must be in HEX according to spec.
145 //
146 if (StringHandle1 != NULL) {
147 Handle1 = (EFI_HANDLE)StrHexToUintn(StringHandle1);
148 } else {
149 Handle1 = NULL;
150 }
151 if (StringHandle2 != NULL) {
152 Handle2 = (EFI_HANDLE)StrHexToUintn(StringHandle2);
153 } else {
154 Handle2 = NULL;
155 }
156
157 //
158 // if only one is NULL verify it's the proper one...
159 //
160 if ( (Handle1 == NULL && Handle2 != NULL)
161 || (Handle1 != NULL && Handle2 == NULL)
162 ){
163 //
164 // Figure out which one should be NULL and move the handle to the right place.
165 // If Handle1 is NULL then test Handle2 and vise versa.
166 // The one that DOES has driver binding must be Handle2
167 //
168 if (Handle1 == NULL) {
169 if (EFI_ERROR(gBS->OpenProtocol(Handle2, &gEfiDriverBindingProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
170 // swap
171 Handle1 = Handle2;
172 Handle2 = NULL;
173 } else {
174 // We're all good...
175 }
176 } else {
177 if (EFI_ERROR(gBS->OpenProtocol(Handle1, &gEfiDriverBindingProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
178 // We're all good...
179 } else {
180 // swap
181 Handle2 = Handle1;
182 Handle1 = NULL;
183 }
184 }
185 }
186
187 return (ConnectControllers(Handle1, Handle2, Recursive, Output));
188 }
189
190 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
191 {L"-c", TypeFlag},
192 {L"-r", TypeFlag},
193 {NULL, TypeMax}
194 };
195
196 SHELL_STATUS
197 EFIAPI
198 ShellCommandRunConnect (
199 VOID *RESERVED
200 ) {
201 EFI_STATUS Status;
202 LIST_ENTRY *Package;
203 CHAR16 *ProblemParam;
204 SHELL_STATUS ShellStatus;
205
206 ShellStatus = SHELL_SUCCESS;
207
208 //
209 // initialize the shell lib (we must be in non-auto-init...)
210 //
211 Status = ShellInitialize();
212 ASSERT_EFI_ERROR(Status);
213
214 Status = CommandInit();
215 ASSERT_EFI_ERROR(Status);
216
217 //
218 // parse the command line
219 //
220 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
221 if EFI_ERROR(Status) {
222 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
223 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, ProblemParam);
224 FreePool(ProblemParam);
225 ShellStatus = SHELL_INVALID_PARAMETER;
226 } else {
227 ASSERT(FALSE);
228 }
229 } else {
230 //
231 // if more than 2 'value' parameters (plus the name one) or either -r or -c with any value parameters we have too many parameters
232 //
233 if ((ShellCommandLineGetCount() > 3)
234 ||((ShellCommandLineGetFlag(Package, L"-r") != FALSE || ShellCommandLineGetFlag(Package, L"-c") != FALSE) && ShellCommandLineGetCount()!=0)
235 ){
236 //
237 // error for too many parameters
238 //
239 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle);
240 ShellStatus = SHELL_INVALID_PARAMETER;
241 } else if (ShellCommandLineGetFlag(Package, L"-c") != FALSE) {
242 //
243 // do the conin and conout from EFI variables
244 // if the first fails dont 'loose' the error
245 //
246 Status = ConnectFromDevPaths(L"ConInDev");
247 if (EFI_ERROR(Status)) {
248 ConnectFromDevPaths(L"ConOutDev");
249 } else {
250 Status = ConnectFromDevPaths(L"ConOutDev");
251 }
252 ShellStatus = Status & (~MAX_BIT);
253 } else {
254 //
255 // 0, 1, or 2 specific handles and possibly recursive
256 //
257 if (ShellCommandLineGetRawValue(Package, 1) != NULL && CommandLibGetHandleValue(StrHexToUintn(ShellCommandLineGetRawValue(Package, 1))) == NULL){
258 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, ShellCommandLineGetRawValue(Package, 1));
259 ShellStatus = SHELL_INVALID_PARAMETER;
260 } else if (ShellCommandLineGetRawValue(Package, 2) != NULL && CommandLibGetHandleValue(StrHexToUintn(ShellCommandLineGetRawValue(Package, 2))) == NULL) {
261 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, ShellCommandLineGetRawValue(Package, 2));
262 ShellStatus = SHELL_INVALID_PARAMETER;
263 } else {
264 Status = ConvertAndConnectControllers(ShellCommandLineGetRawValue(Package, 1), ShellCommandLineGetRawValue(Package, 2), ShellCommandLineGetFlag(Package, L"-r"), (BOOLEAN)(ShellCommandLineGetCount()!=0));
265 ShellStatus = Status & (~MAX_BIT);
266 }
267 }
268
269 ShellCommandLineFreeVarList (Package);
270 }
271 return (ShellStatus);
272 }
273