]> git.proxmox.com Git - mirror_edk2.git/blame - StdLib/UseSocketDxe/UseSocketDxe.c
Fixed close for socket to properly release the socket context structure and the handle.
[mirror_edk2.git] / StdLib / UseSocketDxe / UseSocketDxe.c
CommitLineData
d7ce7006 1/** @file\r
2 Implement the connection to the socket driver\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 <Uefi.h>\r
16\r
17#include <Library/DebugLib.h>\r
18#include <Library/UefiBootServicesTableLib.h>\r
19#include <Library/UefiLib.h>\r
20\r
21#include <Protocol/EfiSocket.h>\r
22#include <Protocol/ServiceBinding.h>\r
23\r
24\r
4652be0c 25/**\r
26 Free the socket resources\r
27\r
28 This releases the socket resources allocated by calling\r
29 EslServiceGetProtocol.\r
30\r
31 This routine is called from the ::close routine in BsdSocketLib\r
32 to release the socket resources.\r
33\r
34 @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL\r
35 structure\r
36\r
37 @return Value for ::errno, zero (0) indicates success.\r
38\r
39 **/\r
40int\r
41EslServiceFreeProtocol (\r
42 IN EFI_SOCKET_PROTOCOL * pSocketProtocol\r
43 )\r
44{\r
45 EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;\r
46 int RetVal;\r
47 EFI_STATUS Status;\r
48\r
49 //\r
50 // Assume success\r
51 //\r
52 RetVal = 0;\r
53\r
54 //\r
55 // Locate the socket protocol\r
56 //\r
57 Status = gBS->LocateProtocol ( &gEfiSocketServiceBindingProtocolGuid,\r
58 NULL,\r
59 (VOID **) &pServiceBinding );\r
60 if ( !EFI_ERROR ( Status )) {\r
61 //\r
62 // Release the handle\r
63 //\r
64 Status = pServiceBinding->DestroyChild ( pServiceBinding,\r
65 pSocketProtocol->SocketHandle );\r
66 }\r
67 if ( EFI_ERROR ( Status )) {\r
68 RetVal = EIO;\r
69 }\r
70\r
71 //\r
72 // Return the operation status\r
73 //\r
74 return RetVal;\r
75}\r
76\r
77\r
d7ce7006 78/**\r
a88c3163 79 Connect to the EFI socket library\r
d7ce7006 80\r
a88c3163 81 This routine establishes a connection to the socket driver\r
82 and returns the API (::EFI_SOCKET_PROTOCOL address) to the\r
83 socket file system layer in BsdSocketLib. This routine looks for\r
84 the gEfiSocketServiceBindingProtocolGuid to locate the socket\r
85 driver. This routine then creates a child handle and locates\r
86 the gEfiSocketProtocolGuid protocol on that handle to get the\r
87 ::EFI_SOCKET_PROTOCOL structure address.\r
88\r
89 This routine is called from the ::socket routine in BsdSocketLib\r
90 to create the data structure and initialize the API for a socket.\r
91 Note that this implementation is only used by socket applications\r
92 that link directly to UseSocketDxe.\r
93\r
94 @param [in] ppSocketProtocol Address to receive the ::EFI_SOCKET_PROTOCOL\r
95 structure address\r
96\r
97 @return Value for ::errno, zero (0) indicates success.\r
d7ce7006 98\r
d7ce7006 99 **/\r
100int\r
101EslServiceGetProtocol (\r
102 IN EFI_SOCKET_PROTOCOL ** ppSocketProtocol\r
103 )\r
104{\r
105 EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;\r
106 int RetVal;\r
107 EFI_HANDLE SocketHandle;\r
108 EFI_STATUS Status;\r
109\r
110 //\r
111 // Locate the socket protocol\r
112 //\r
113 Status = gBS->LocateProtocol ( &gEfiSocketServiceBindingProtocolGuid,\r
114 NULL,\r
115 (VOID **)&pServiceBinding );\r
116 if ( !EFI_ERROR ( Status )) {\r
117 //\r
118 // Create a new socket\r
119 //\r
120 SocketHandle = NULL;\r
121 Status = pServiceBinding->CreateChild ( pServiceBinding,\r
122 &SocketHandle );\r
123 if ( !EFI_ERROR ( Status )) {\r
124 //\r
125 // Get the socket protocol\r
126 //\r
127 Status = gBS->OpenProtocol ( SocketHandle,\r
128 &gEfiSocketProtocolGuid,\r
129 (VOID **)ppSocketProtocol,\r
130 NULL,\r
131 NULL,\r
132 EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );\r
133 if ( !EFI_ERROR ( Status )) {\r
134 //\r
135 // Success!\r
136 //\r
137 RetVal = 0;\r
138 }\r
139 else {\r
140 DEBUG (( DEBUG_ERROR,\r
141 "ERROR - No socket protocol on 0x%08x, Status: %r\r\n",\r
142 SocketHandle,\r
143 Status ));\r
144 RetVal = ENODEV;\r
145 }\r
146 }\r
147 else {\r
148 //\r
149 // Translate the error\r
150 //\r
151 DEBUG (( DEBUG_ERROR,\r
152 "ERROR - CreateChild failed, Status: %r\r\n",\r
153 Status ));\r
154 switch ( Status ) {\r
155 case EFI_SUCCESS:\r
156 RetVal = 0;\r
157 break;\r
158\r
159 case EFI_ACCESS_DENIED:\r
160 case EFI_WRITE_PROTECTED:\r
161 RetVal = EACCES;\r
162 break;\r
163\r
164 case EFI_NO_RESPONSE:\r
165 RetVal = EHOSTUNREACH;\r
166 break;\r
167\r
168 case EFI_BAD_BUFFER_SIZE:\r
169 case EFI_BUFFER_TOO_SMALL:\r
170 case EFI_INVALID_PARAMETER:\r
171 RetVal = EINVAL;\r
172 break;\r
173\r
174 case EFI_DEVICE_ERROR:\r
175 case EFI_MEDIA_CHANGED:\r
176 case EFI_NO_MEDIA:\r
177 case EFI_VOLUME_CORRUPTED:\r
178 RetVal = EIO;\r
179 break;\r
180\r
181 case EFI_NOT_FOUND:\r
182 RetVal = ENOENT;\r
183 break;\r
184\r
185 default:\r
186 case EFI_OUT_OF_RESOURCES:\r
187 RetVal = ENOMEM;\r
188 break;\r
189\r
190 case EFI_VOLUME_FULL:\r
191 RetVal = ENOSPC;\r
192 break;\r
193\r
194 case EFI_UNSUPPORTED:\r
195 RetVal = ENOSYS;\r
196 break;\r
197\r
198 case EFI_NO_MAPPING:\r
199 RetVal = ENXIO;\r
200 break;\r
201\r
202 case EFI_LOAD_ERROR:\r
203 RetVal = ESRCH;\r
204 break;\r
205\r
206 case EFI_TIMEOUT:\r
207 RetVal = ETIMEDOUT;\r
208 break;\r
209\r
210 case EFI_NOT_READY:\r
211 RetVal = EWOULDBLOCK;\r
212 break;\r
213 }\r
214 }\r
215 }\r
216 else {\r
217 DEBUG (( DEBUG_ERROR,\r
a88c3163 218 "ERROR - Socket driver not loaded, Status: %r\r\n",\r
d7ce7006 219 Status ));\r
220 RetVal = ENODEV;\r
221 }\r
222\r
223 //\r
224 // Return the operation status\r
225 //\r
226 return RetVal;\r
227}\r