Fixed close for socket to properly release the socket context structure and the handle.
[mirror_edk2.git] / StdLib / EfiSocketLib / DxeSupport.c
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
40 EFI_STATUS\r
41 EFIAPI\r
42 EslDxeCreateChild (\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
86 EFI_STATUS\r
87 EFIAPI\r
88 EslDxeDestroyChild (\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   EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
95   EFI_STATUS Status;\r
96 \r
97   DBG_ENTER ( );\r
98 \r
99   //\r
100   //  Locate the socket control structure\r
101   //\r
102   pLayer = &mEslLayer;\r
103   Status = gBS->OpenProtocol (\r
104                   ChildHandle,\r
105                   &gEfiSocketProtocolGuid,\r
106                   (VOID **)&pSocketProtocol,\r
107                   pLayer->ImageHandle,\r
108                   NULL,\r
109                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
110                   );\r
111   if ( !EFI_ERROR ( Status )) {\r
112     //\r
113     //  Free the socket resources\r
114     //\r
115     Status = EslSocketFree ( pSocketProtocol, NULL );\r
116   }\r
117   else {\r
118     DEBUG (( DEBUG_ERROR,\r
119               "ERROR - Failed to open socket protocol on 0x%08x, Status; %r\r\n",\r
120               ChildHandle,\r
121               Status ));\r
122   }\r
123 \r
124   //\r
125   //  Return the operation status\r
126   //\r
127   DBG_EXIT_STATUS ( Status );\r
128   return Status;\r
129 }\r
130 \r
131 \r
132 /**\r
133 Install the socket service\r
134 \r
135 This routine installs the ::gEfiSocketServiceBindingProtocolGuid\r
136 on the SocketDxe image handle to announce the availability\r
137 of the socket layer to the rest of EFI.\r
138 \r
139 SocketDxe's EntryPoint routine calls this routine to\r
140 make the socket layer available.\r
141 \r
142 @param [in] pImageHandle      Address of the image handle\r
143 \r
144 @retval EFI_SUCCESS     Service installed successfully\r
145 **/\r
146 EFI_STATUS\r
147 EFIAPI\r
148 EslDxeInstall (\r
149   IN EFI_HANDLE * pImageHandle\r
150   )\r
151 {\r
152   EFI_STATUS Status;\r
153 \r
154   //\r
155   //  Install the socket service binding protocol\r
156   //\r
157   Status = gBS->InstallMultipleProtocolInterfaces (\r
158                   pImageHandle,\r
159                   &gEfiSocketServiceBindingProtocolGuid,\r
160                   mEslLayer.pServiceBinding,\r
161                   NULL\r
162                   );\r
163   if ( !EFI_ERROR ( Status )) {\r
164     DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
165               "Installed: gEfiSocketServiceBindingProtocolGuid on   0x%08x\r\n",\r
166               *pImageHandle ));\r
167   }\r
168   else {\r
169     DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
170               "ERROR - InstallMultipleProtocolInterfaces failed, Status: %r\r\n",\r
171               Status ));\r
172   }\r
173 \r
174   //\r
175   //  Return the operation status\r
176   //\r
177   return Status;\r
178 }\r
179 \r
180 \r
181 /**\r
182 Uninstall the socket service\r
183 \r
184 This routine removes the gEfiSocketServiceBindingProtocolGuid from\r
185 the SocketDxe image handle to notify EFI that the socket layer\r
186 is no longer available.\r
187 \r
188 SocketDxe's DriverUnload routine calls this routine to remove the\r
189 socket layer.\r
190 \r
191 @param [in] ImageHandle       Handle for the image.\r
192 \r
193 @retval EFI_SUCCESS     Service installed successfully\r
194 **/\r
195 EFI_STATUS\r
196 EFIAPI\r
197 EslDxeUninstall (\r
198   IN EFI_HANDLE ImageHandle\r
199   )\r
200 {\r
201   EFI_STATUS Status;\r
202 \r
203   //\r
204   //  Install the socket service binding protocol\r
205   //\r
206   Status = gBS->UninstallMultipleProtocolInterfaces (\r
207               ImageHandle,\r
208               &gEfiSocketServiceBindingProtocolGuid,\r
209               mEslLayer.pServiceBinding,\r
210               NULL\r
211               );\r
212   if ( !EFI_ERROR ( Status )) {\r
213     DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
214                 "Removed:   gEfiSocketServiceBindingProtocolGuid from 0x%08x\r\n",\r
215                 ImageHandle ));\r
216   }\r
217   else {\r
218     DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
219                 "ERROR - Failed to remove gEfiSocketServiceBindingProtocolGuid from 0x%08x, Status: %r\r\n",\r
220                 ImageHandle,\r
221                 Status ));\r
222   }\r
223 \r
224   //\r
225   //  Return the operation status\r
226   //\r
227   return Status;\r
228 }\r