summaryrefslogtreecommitdiffstats
path: root/StdLib/EfiSocketLib/DxeSupport.c
blob: 808b710d27467fe908a8d8c381e65f91458fd4fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/** @file
  SocketDxe support routines

  Copyright (c) 2011, Intel Corporation
  All rights reserved. This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Socket.h"


/**
  Creates a child handle and installs gEfiSocketProtocolGuid.

  This routine creates a child handle for the socket driver and
  installs the ::gEfiSocketProtocolGuid on that handle with a pointer
  to the ::EFI_SOCKET_PROTOCOL structure address.

  This routine is called by ::EslServiceGetProtocol in UseSocketDxe
  when the socket application is linked with UseSocketDxe.

  @param [in] pThis        Address of the EFI_SERVICE_BINDING_PROTOCOL structure.
  @param [in] pChildHandle Pointer to the handle of the child to create. If it is NULL,
                           then a new handle is created. If it is a pointer to an existing UEFI handle, 
                           then the protocol is added to the existing UEFI handle.

  @retval EFI_SUCCESS           The protocol was added to ChildHandle.
  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
  @retval EFI_OUT_OF_RESOURCES  There are not enough resources availabe to create
                                the child
  @retval other                 The child handle was not created

**/
EFI_STATUS
EFIAPI
EslDxeCreateChild (
  IN     EFI_SERVICE_BINDING_PROTOCOL * pThis,
  IN OUT EFI_HANDLE * pChildHandle
  )
{
  ESL_SOCKET * pSocket;
  EFI_STATUS Status;

  DBG_ENTER ( );

  //
  //  Create a socket structure
  //
  Status = EslSocketAllocate ( pChildHandle,
                               DEBUG_SOCKET,
                               &pSocket );

  //
  //  Return the operation status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}


/**
  Removes gEfiSocketProtocolGuid and destroys the child handle.

  This routine uninstalls ::gEfiSocketProtocolGuid from the child handle
  and destroys the child handle if necessary.

  This routine is called from ???.
  
  @param [in] pThis       Address of the EFI_SERVICE_BINDING_PROTOCOL structure.
  @param [in] ChildHandle Handle of the child to destroy

  @retval EFI_SUCCESS           The protocol was removed from ChildHandle.
  @retval EFI_UNSUPPORTED       ChildHandle does not support the protocol that is being removed.
  @retval EFI_INVALID_PARAMETER Child handle is not a valid UEFI Handle.
  @retval EFI_ACCESS_DENIED     The protocol could not be removed from the ChildHandle
                                because its services are being used.
  @retval other                 The child handle was not destroyed

**/
EFI_STATUS
EFIAPI
EslDxeDestroyChild (
  IN EFI_SERVICE_BINDING_PROTOCOL * pThis,
  IN EFI_HANDLE ChildHandle
  )
{
  ESL_LAYER * pLayer;
  EFI_SOCKET_PROTOCOL * pSocketProtocol;
  EFI_STATUS Status;

  DBG_ENTER ( );

  //
  //  Locate the socket control structure
  //
  pLayer = &mEslLayer;
  Status = gBS->OpenProtocol (
                  ChildHandle,
                  &gEfiSocketProtocolGuid,
                  (VOID **)&pSocketProtocol,
                  pLayer->ImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if ( !EFI_ERROR ( Status )) {
    //
    //  Free the socket resources
    //
    Status = EslSocketFree ( pSocketProtocol, NULL );
  }
  else {
    DEBUG (( DEBUG_ERROR,
              "ERROR - Failed to open socket protocol on 0x%08x, Status; %r\r\n",
              ChildHandle,
              Status ));
  }

  //
  //  Return the operation status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}


/**
Install the socket service

This routine installs the ::gEfiSocketServiceBindingProtocolGuid
on the SocketDxe image handle to announce the availability
of the socket layer to the rest of EFI.

SocketDxe's EntryPoint routine calls this routine to
make the socket layer available.

@param [in] pImageHandle      Address of the image handle

@retval EFI_SUCCESS     Service installed successfully
**/
EFI_STATUS
EFIAPI
EslDxeInstall (
  IN EFI_HANDLE * pImageHandle
  )
{
  EFI_STATUS Status;

  //
  //  Install the socket service binding protocol
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  pImageHandle,
                  &gEfiSocketServiceBindingProtocolGuid,
                  mEslLayer.pServiceBinding,
                  NULL
                  );
  if ( !EFI_ERROR ( Status )) {
    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
              "Installed: gEfiSocketServiceBindingProtocolGuid on   0x%08x\r\n",
              *pImageHandle ));
  }
  else {
    DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
              "ERROR - InstallMultipleProtocolInterfaces failed, Status: %r\r\n",
              Status ));
  }

  //
  //  Return the operation status
  //
  return Status;
}


/**
Uninstall the socket service

This routine removes the gEfiSocketServiceBindingProtocolGuid from
the SocketDxe image handle to notify EFI that the socket layer
is no longer available.

SocketDxe's DriverUnload routine calls this routine to remove the
socket layer.

@param [in] ImageHandle       Handle for the image.

@retval EFI_SUCCESS     Service installed successfully
**/
EFI_STATUS
EFIAPI
EslDxeUninstall (
  IN EFI_HANDLE ImageHandle
  )
{
  EFI_STATUS Status;

  //
  //  Install the socket service binding protocol
  //
  Status = gBS->UninstallMultipleProtocolInterfaces (
              ImageHandle,
              &gEfiSocketServiceBindingProtocolGuid,
              mEslLayer.pServiceBinding,
              NULL
              );
  if ( !EFI_ERROR ( Status )) {
    DEBUG (( DEBUG_POOL | DEBUG_INIT,
                "Removed:   gEfiSocketServiceBindingProtocolGuid from 0x%08x\r\n",
                ImageHandle ));
  }
  else {
    DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
                "ERROR - Failed to remove gEfiSocketServiceBindingProtocolGuid from 0x%08x, Status: %r\r\n",
                ImageHandle,
                Status ));
  }

  //
  //  Return the operation status
  //
  return Status;
}