]> git.proxmox.com Git - mirror_edk2.git/blame - StdLib/EfiSocketLib/DxeSupport.c
Only use ports with a network connection (media present) when connecting to a remote...
[mirror_edk2.git] / StdLib / EfiSocketLib / DxeSupport.c
CommitLineData
a88c3163 1/** @file\r
2 SocketDxe support routines\r
3\r
4 Copyright (c) 2011, Intel Corporation\r
5 All rights reserved. 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 "Socket.h"\r
16\r
17\r
18/**\r
19 Creates a child handle and installs gEfiSocketProtocolGuid.\r
20\r
21 This routine creates a child handle for the socket driver and\r
22 installs the ::gEfiSocketProtocolGuid on that handle with a pointer\r
23 to the ::EFI_SOCKET_PROTOCOL structure address.\r
24\r
25 This routine is called by ::EslServiceGetProtocol in UseSocketDxe\r
26 when the socket application is linked with UseSocketDxe.\r
27\r
28 @param [in] pThis Address of the EFI_SERVICE_BINDING_PROTOCOL structure.\r
29 @param [in] pChildHandle Pointer to the handle of the child to create. If it is NULL,\r
30 then a new handle is created. If it is a pointer to an existing UEFI handle, \r
31 then the protocol is added to the existing UEFI handle.\r
32\r
33 @retval EFI_SUCCESS The protocol was added to ChildHandle.\r
34 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
35 @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create\r
36 the child\r
37 @retval other The child handle was not created\r
38\r
39**/\r
40EFI_STATUS\r
41EFIAPI\r
42EslDxeCreateChild (\r
43 IN EFI_SERVICE_BINDING_PROTOCOL * pThis,\r
44 IN OUT EFI_HANDLE * pChildHandle\r
45 )\r
46{\r
47 ESL_SOCKET * pSocket;\r
48 EFI_STATUS Status;\r
49\r
50 DBG_ENTER ( );\r
51\r
52 //\r
53 // Create a socket structure\r
54 //\r
55 Status = EslSocketAllocate ( pChildHandle,\r
56 DEBUG_SOCKET,\r
57 &pSocket );\r
58\r
59 //\r
60 // Return the operation status\r
61 //\r
62 DBG_EXIT_STATUS ( Status );\r
63 return Status;\r
64}\r
65\r
66\r
67/**\r
68 Removes gEfiSocketProtocolGuid and destroys the child handle.\r
69\r
70 This routine uninstalls ::gEfiSocketProtocolGuid from the child handle\r
71 and destroys the child handle if necessary.\r
72\r
73 This routine is called from ???.\r
74 \r
75 @param [in] pThis Address of the EFI_SERVICE_BINDING_PROTOCOL structure.\r
76 @param [in] ChildHandle Handle of the child to destroy\r
77\r
78 @retval EFI_SUCCESS The protocol was removed from ChildHandle.\r
79 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.\r
80 @retval EFI_INVALID_PARAMETER Child handle is not a valid UEFI Handle.\r
81 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle\r
82 because its services are being used.\r
83 @retval other The child handle was not destroyed\r
84\r
85**/\r
86EFI_STATUS\r
87EFIAPI\r
88EslDxeDestroyChild (\r
89 IN EFI_SERVICE_BINDING_PROTOCOL * pThis,\r
90 IN EFI_HANDLE ChildHandle\r
91 )\r
92{\r
93 ESL_LAYER * pLayer;\r
94 ESL_SOCKET * pSocket;\r
95 ESL_SOCKET * pSocketPrevious;\r
96 EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
97 EFI_STATUS Status;\r
98 EFI_TPL TplPrevious;\r
99\r
100 DBG_ENTER ( );\r
101\r
102 //\r
103 // Locate the socket control structure\r
104 //\r
105 pLayer = &mEslLayer;\r
106 Status = gBS->OpenProtocol (\r
107 ChildHandle,\r
108 &gEfiSocketProtocolGuid,\r
109 (VOID **)&pSocketProtocol,\r
110 pLayer->ImageHandle,\r
111 NULL,\r
112 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
113 );\r
114 if ( !EFI_ERROR ( Status )) {\r
115 pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );\r
116\r
117 //\r
118 // Synchronize with the socket layer\r
119 //\r
120 RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
121\r
122 //\r
123 // Walk the socket list\r
124 //\r
125 pSocketPrevious = pLayer->pSocketList;\r
126 if ( NULL != pSocketPrevious ) {\r
127 if ( pSocket == pSocketPrevious ) {\r
128 //\r
129 // Remove the socket from the head of the list\r
130 //\r
131 pLayer->pSocketList = pSocket->pNext;\r
132 }\r
133 else {\r
134 //\r
135 // Find the socket in the middle of the list\r
136 //\r
137 while (( NULL != pSocketPrevious )\r
138 && ( pSocket != pSocketPrevious->pNext )) {\r
139 //\r
140 // Set the next socket\r
141 //\r
142 pSocketPrevious = pSocketPrevious->pNext;\r
143 }\r
144 if ( NULL != pSocketPrevious ) {\r
145 //\r
146 // Remove the socket from the middle of the list\r
147 //\r
148 pSocketPrevious = pSocket->pNext;\r
149 }\r
150 }\r
151 }\r
152 else {\r
153 DEBUG (( DEBUG_ERROR | DEBUG_POOL,\r
154 "ERROR - Socket list is empty!\r\n" ));\r
155 }\r
156\r
157 //\r
158 // Release the socket layer synchronization\r
159 //\r
160 RESTORE_TPL ( TplPrevious );\r
161\r
162 //\r
163 // Determine if the socket was found\r
164 //\r
165 if ( NULL != pSocketPrevious ) {\r
166 pSocket->pNext = NULL;\r
167\r
168 //\r
169 // Remove the socket protocol\r
170 //\r
171 Status = gBS->UninstallMultipleProtocolInterfaces (\r
172 ChildHandle,\r
173 &gEfiSocketProtocolGuid,\r
174 &pSocket->SocketProtocol,\r
175 NULL );\r
176 if ( !EFI_ERROR ( Status )) {\r
177 DEBUG (( DEBUG_POOL | DEBUG_INFO,\r
178 "Removed: gEfiSocketProtocolGuid from 0x%08x\r\n",\r
179 ChildHandle ));\r
180\r
181 //\r
182 // Free the socket structure\r
183 //\r
184 Status = gBS->FreePool ( pSocket );\r
185 if ( !EFI_ERROR ( Status )) {\r
186 DEBUG (( DEBUG_POOL,\r
187 "0x%08x: Free pSocket, %d bytes\r\n",\r
188 pSocket,\r
189 sizeof ( *pSocket )));\r
190 }\r
191 else {\r
192 DEBUG (( DEBUG_ERROR | DEBUG_POOL,\r
193 "ERROR - Failed to free pSocket 0x%08x, Status: %r\r\n",\r
194 pSocket,\r
195 Status ));\r
196 }\r
197 }\r
198 else {\r
199 DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INFO,\r
200 "ERROR - Failed to remove gEfiSocketProtocolGuid from 0x%08x, Status: %r\r\n",\r
201 ChildHandle,\r
202 Status ));\r
203 }\r
204 }\r
205 else {\r
206 DEBUG (( DEBUG_ERROR | DEBUG_INFO,\r
207 "ERROR - The socket was not in the socket list!\r\n" ));\r
208 Status = EFI_NOT_FOUND;\r
209 }\r
210 }\r
211 else {\r
212 DEBUG (( DEBUG_ERROR,\r
213 "ERROR - Failed to open socket protocol on 0x%08x, Status; %r\r\n",\r
214 ChildHandle,\r
215 Status ));\r
216 }\r
217\r
218 //\r
219 // Return the operation status\r
220 //\r
221 DBG_EXIT_STATUS ( Status );\r
222 return Status;\r
223}\r
224\r
225\r
226/**\r
227Install the socket service\r
228\r
229This routine installs the ::gEfiSocketServiceBindingProtocolGuid\r
230on the SocketDxe image handle to announce the availability\r
231of the socket layer to the rest of EFI.\r
232\r
233SocketDxe's EntryPoint routine calls this routine to\r
234make the socket layer available.\r
235\r
236@param [in] pImageHandle Address of the image handle\r
237\r
238@retval EFI_SUCCESS Service installed successfully\r
239**/\r
240EFI_STATUS\r
241EFIAPI\r
242EslDxeInstall (\r
243 IN EFI_HANDLE * pImageHandle\r
244 )\r
245{\r
246 EFI_STATUS Status;\r
247\r
248 //\r
249 // Install the socket service binding protocol\r
250 //\r
251 Status = gBS->InstallMultipleProtocolInterfaces (\r
252 pImageHandle,\r
253 &gEfiSocketServiceBindingProtocolGuid,\r
254 mEslLayer.pServiceBinding,\r
255 NULL\r
256 );\r
257 if ( !EFI_ERROR ( Status )) {\r
258 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
259 "Installed: gEfiSocketServiceBindingProtocolGuid on 0x%08x\r\n",\r
260 *pImageHandle ));\r
261 }\r
262 else {\r
263 DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
264 "ERROR - InstallMultipleProtocolInterfaces failed, Status: %r\r\n",\r
265 Status ));\r
266 }\r
267\r
268 //\r
269 // Return the operation status\r
270 //\r
271 return Status;\r
272}\r
273\r
274\r
275/**\r
276Uninstall the socket service\r
277\r
278This routine removes the gEfiSocketServiceBindingProtocolGuid from\r
279the SocketDxe image handle to notify EFI that the socket layer\r
280is no longer available.\r
281\r
282SocketDxe's DriverUnload routine calls this routine to remove the\r
283socket layer.\r
284\r
285@param [in] ImageHandle Handle for the image.\r
286\r
287@retval EFI_SUCCESS Service installed successfully\r
288**/\r
289EFI_STATUS\r
290EFIAPI\r
291EslDxeUninstall (\r
292 IN EFI_HANDLE ImageHandle\r
293 )\r
294{\r
295 EFI_STATUS Status;\r
296\r
297 //\r
298 // Install the socket service binding protocol\r
299 //\r
300 Status = gBS->UninstallMultipleProtocolInterfaces (\r
301 ImageHandle,\r
302 &gEfiSocketServiceBindingProtocolGuid,\r
303 mEslLayer.pServiceBinding,\r
304 NULL\r
305 );\r
306 if ( !EFI_ERROR ( Status )) {\r
307 DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
308 "Removed: gEfiSocketServiceBindingProtocolGuid from 0x%08x\r\n",\r
309 ImageHandle ));\r
310 }\r
311 else {\r
312 DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
313 "ERROR - Failed to remove gEfiSocketServiceBindingProtocolGuid from 0x%08x, Status: %r\r\n",\r
314 ImageHandle,\r
315 Status ));\r
316 }\r
317\r
318 //\r
319 // Return the operation status\r
320 //\r
321 return Status;\r
322}\r