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