Update the sockets library code
* Passes conformance and functional tests. * Builds with GCC 4.4 compiler. Signed-off by: lpleahy git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12497 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
322
StdLib/EfiSocketLib/DxeSupport.c
Normal file
322
StdLib/EfiSocketLib/DxeSupport.c
Normal file
@@ -0,0 +1,322 @@
|
||||
/** @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;
|
||||
ESL_SOCKET * pSocket;
|
||||
ESL_SOCKET * pSocketPrevious;
|
||||
EFI_SOCKET_PROTOCOL * pSocketProtocol;
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL TplPrevious;
|
||||
|
||||
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 )) {
|
||||
pSocket = SOCKET_FROM_PROTOCOL ( pSocketProtocol );
|
||||
|
||||
//
|
||||
// Synchronize with the socket layer
|
||||
//
|
||||
RAISE_TPL ( TplPrevious, TPL_SOCKETS );
|
||||
|
||||
//
|
||||
// Walk the socket list
|
||||
//
|
||||
pSocketPrevious = pLayer->pSocketList;
|
||||
if ( NULL != pSocketPrevious ) {
|
||||
if ( pSocket == pSocketPrevious ) {
|
||||
//
|
||||
// Remove the socket from the head of the list
|
||||
//
|
||||
pLayer->pSocketList = pSocket->pNext;
|
||||
}
|
||||
else {
|
||||
//
|
||||
// Find the socket in the middle of the list
|
||||
//
|
||||
while (( NULL != pSocketPrevious )
|
||||
&& ( pSocket != pSocketPrevious->pNext )) {
|
||||
//
|
||||
// Set the next socket
|
||||
//
|
||||
pSocketPrevious = pSocketPrevious->pNext;
|
||||
}
|
||||
if ( NULL != pSocketPrevious ) {
|
||||
//
|
||||
// Remove the socket from the middle of the list
|
||||
//
|
||||
pSocketPrevious = pSocket->pNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
DEBUG (( DEBUG_ERROR | DEBUG_POOL,
|
||||
"ERROR - Socket list is empty!\r\n" ));
|
||||
}
|
||||
|
||||
//
|
||||
// Release the socket layer synchronization
|
||||
//
|
||||
RESTORE_TPL ( TplPrevious );
|
||||
|
||||
//
|
||||
// Determine if the socket was found
|
||||
//
|
||||
if ( NULL != pSocketPrevious ) {
|
||||
pSocket->pNext = NULL;
|
||||
|
||||
//
|
||||
// Remove the socket protocol
|
||||
//
|
||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||
ChildHandle,
|
||||
&gEfiSocketProtocolGuid,
|
||||
&pSocket->SocketProtocol,
|
||||
NULL );
|
||||
if ( !EFI_ERROR ( Status )) {
|
||||
DEBUG (( DEBUG_POOL | DEBUG_INFO,
|
||||
"Removed: gEfiSocketProtocolGuid from 0x%08x\r\n",
|
||||
ChildHandle ));
|
||||
|
||||
//
|
||||
// Free the socket structure
|
||||
//
|
||||
Status = gBS->FreePool ( pSocket );
|
||||
if ( !EFI_ERROR ( Status )) {
|
||||
DEBUG (( DEBUG_POOL,
|
||||
"0x%08x: Free pSocket, %d bytes\r\n",
|
||||
pSocket,
|
||||
sizeof ( *pSocket )));
|
||||
}
|
||||
else {
|
||||
DEBUG (( DEBUG_ERROR | DEBUG_POOL,
|
||||
"ERROR - Failed to free pSocket 0x%08x, Status: %r\r\n",
|
||||
pSocket,
|
||||
Status ));
|
||||
}
|
||||
}
|
||||
else {
|
||||
DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INFO,
|
||||
"ERROR - Failed to remove gEfiSocketProtocolGuid from 0x%08x, Status: %r\r\n",
|
||||
ChildHandle,
|
||||
Status ));
|
||||
}
|
||||
}
|
||||
else {
|
||||
DEBUG (( DEBUG_ERROR | DEBUG_INFO,
|
||||
"ERROR - The socket was not in the socket list!\r\n" ));
|
||||
Status = EFI_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
@@ -28,7 +28,9 @@
|
||||
#
|
||||
|
||||
[Sources.common]
|
||||
DxeSupport.c
|
||||
Init.c
|
||||
Ip4.c
|
||||
Service.c
|
||||
Socket.c
|
||||
Tcp4.c
|
||||
@@ -43,10 +45,13 @@
|
||||
[LibraryClasses]
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
MemoryAllocationLib
|
||||
UefiBootServicesTableLib
|
||||
UefiLib
|
||||
|
||||
[Protocols]
|
||||
gEfiIp4ProtocolGuid
|
||||
gEfiIp4ServiceBindingProtocolGuid
|
||||
gEfiTcp4ProtocolGuid
|
||||
gEfiTcp4ServiceBindingProtocolGuid
|
||||
gEfiUdp4ProtocolGuid
|
||||
|
@@ -18,7 +18,22 @@
|
||||
/**
|
||||
EFI Socket Library Constructor
|
||||
|
||||
@retval EFI_SUCCESS The initialization was successful
|
||||
This routine supports an implementation dependent constructor
|
||||
depending upon whether the library is linked to a socket
|
||||
application or the SocketDxe driver. The following modules
|
||||
declare the redirection for the constructor in ::mpfnEslConstructor:
|
||||
<ul>
|
||||
<li>StdLib/EfiSocketLib/UseSocketLib.c - Application links against EfiSocketLib</li>
|
||||
<li>StdLib/SocketDxe/EntryUnload.c - SocketDxe links against EfiSocketLib</li>
|
||||
</ul>
|
||||
|
||||
The EfiSocketLib.inf file lists ::EslConstructor as the CONSTRUCTOR
|
||||
in the [Defines] section. As a result, this routine is called by
|
||||
the ProcessLibraryConstructorList routine of the AutoGen.c module
|
||||
in the Build directory associated with the socket application or
|
||||
the SocketDxe driver.
|
||||
|
||||
@retval EFI_SUCCESS The socket layer initialization was successful
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
@@ -54,7 +69,22 @@ EslConstructor (
|
||||
/**
|
||||
EFI Socket Library Destructor
|
||||
|
||||
@retval EFI_SUCCESS The shutdown was successful
|
||||
This routine supports an implementation dependent destructor
|
||||
depending upon whether the library is linked to a socket
|
||||
application or the SocketDxe driver. The following modules
|
||||
declare the redirection for the destructor in ::mpfnEslDestructor:
|
||||
<ul>
|
||||
<li>StdLib/EfiSocketLib/UseSocketLib.c - Application links against EfiSocketLib</li>
|
||||
<li>StdLib/SocketDxe/EntryUnload.c - SocketDxe links against EfiSocketLib</li>
|
||||
</ul>
|
||||
|
||||
The EfiSocketLib.inf file lists ::EslDestructor as the DESTRUCTOR
|
||||
in the [Defines] section. As a result, this routine is called by
|
||||
the ProcessLibraryDestructorList routine of the AutoGen.c module
|
||||
in the Build directory associated with the socket application or
|
||||
the SocketDxe driver.
|
||||
|
||||
@retval EFI_SUCCESS The socket layer shutdown was successful
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
|
1264
StdLib/EfiSocketLib/Ip4.c
Normal file
1264
StdLib/EfiSocketLib/Ip4.c
Normal file
File diff suppressed because it is too large
Load Diff
31
StdLib/EfiSocketLib/ReleaseNotes.txt
Normal file
31
StdLib/EfiSocketLib/ReleaseNotes.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
The following issues exist with the EFI Socket Library:
|
||||
|
||||
* Don't run socket applications or the socket driver for a long time - The IPv4Config
|
||||
and DHCP protocols are not properly running the renew and lease expiration timers.
|
||||
When the DHCP lease expires it is possible for a duplicate IP address to exist on
|
||||
the network. HSD 206136
|
||||
|
||||
* Network adapters must be initialized prior to running the socket application - Static
|
||||
and dynamic IP address need to be properly assigned to the network adapters on the
|
||||
system. Note that sockets does not assign the IP addresses since it does not
|
||||
understand how the system is connected to the network!
|
||||
|
||||
* The default device must contain the Efi\etc directory populated with files containing
|
||||
the proper network configuration - A template set of files is in StdLib\Efi\etc. Note
|
||||
that the resolv.conf file contains the set of DNS servers.
|
||||
|
||||
* Since DHCP is not running when the sockets application is running, the last negotiated
|
||||
packet is no longer available. As a result, any of the options that DHCP did negotiate
|
||||
are no longer available for sockets such as the list of DNS servers.
|
||||
|
||||
* DHCP does not request the domain name and domain name server (DNS) addresses. This
|
||||
requires that sockets use configuration files in Efi\etc!
|
||||
|
||||
* TCPv4 transfer rate is slow (< 10 Mbits/sec) - This is an unidentified issue.
|
||||
|
||||
* Raw socket applications are not able to pass the IP header as part of their
|
||||
payload by using the IP option IP_HDRINCL. This is because the UEFI IPv4 driver
|
||||
(Ip4Dxe) does not support RawData. HSD 206136
|
||||
|
||||
* Only version 4 of the UEFI network stack is supported
|
||||
|
@@ -14,15 +14,16 @@
|
||||
|
||||
#include "Socket.h"
|
||||
|
||||
EFI_TCP4_PROTOCOL * mpEfiTcpClose4 [ 1024 ];
|
||||
|
||||
|
||||
/**
|
||||
Connect to the network service bindings
|
||||
|
||||
Walk the network service protocols on the controller handle and
|
||||
locate any that are not in use. Create service structures to
|
||||
manage the service binding for the socket driver.
|
||||
locate any that are not in use. Create ::ESL_SERVICE structures to
|
||||
manage the network layer interfaces for the socket driver. Tag
|
||||
each of the network interfaces that are being used. Finally, this
|
||||
routine calls ESL_SOCKET_BINDING::pfnInitialize to prepare the network
|
||||
interface for use by the socket layer.
|
||||
|
||||
@param [in] BindingHandle Handle for protocol binding.
|
||||
@param [in] Controller Handle of device to work with.
|
||||
@@ -40,11 +41,13 @@ EslServiceConnect (
|
||||
{
|
||||
BOOLEAN bInUse;
|
||||
UINTN LengthInBytes;
|
||||
CONST DT_SOCKET_BINDING * pEnd;
|
||||
UINT8 * pBuffer;
|
||||
CONST ESL_SOCKET_BINDING * pEnd;
|
||||
VOID * pJunk;
|
||||
VOID * pInterface;
|
||||
DT_SERVICE * pService;
|
||||
CONST DT_SOCKET_BINDING * pSocketBinding;
|
||||
ESL_SERVICE ** ppServiceListHead;
|
||||
ESL_SERVICE * pService;
|
||||
CONST ESL_SOCKET_BINDING * pSocketBinding;
|
||||
EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL TplPrevious;
|
||||
|
||||
@@ -68,7 +71,7 @@ EslServiceConnect (
|
||||
Status = gBS->OpenProtocol (
|
||||
Controller,
|
||||
pSocketBinding->pNetworkBinding,
|
||||
&pInterface,
|
||||
(VOID**)&pServiceBinding,
|
||||
BindingHandle,
|
||||
Controller,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
@@ -108,7 +111,7 @@ EslServiceConnect (
|
||||
pService->Signature = SERVICE_SIGNATURE;
|
||||
pService->pSocketBinding = pSocketBinding;
|
||||
pService->Controller = Controller;
|
||||
pService->pInterface = pInterface;
|
||||
pService->pServiceBinding = pServiceBinding;
|
||||
|
||||
//
|
||||
// Mark the controller in use
|
||||
@@ -154,9 +157,13 @@ EslServiceConnect (
|
||||
RAISE_TPL ( TplPrevious, TPL_SOCKETS );
|
||||
|
||||
//
|
||||
// Initialize the service
|
||||
// Connect the service to the list
|
||||
//
|
||||
Status = pSocketBinding->pfnInitialize ( pService );
|
||||
pBuffer = (UINT8 *)&mEslLayer;
|
||||
pBuffer = &pBuffer[ pSocketBinding->ServiceListOffset ];
|
||||
ppServiceListHead = (ESL_SERVICE **)pBuffer;
|
||||
pService->pNext = *ppServiceListHead;
|
||||
*ppServiceListHead = pService;
|
||||
|
||||
//
|
||||
// Release the socket layer synchronization
|
||||
@@ -253,12 +260,13 @@ EslServiceConnect (
|
||||
|
||||
|
||||
/**
|
||||
Shutdown the network connections to this controller by removing
|
||||
NetworkInterfaceIdentifier protocol and closing the DevicePath
|
||||
and PciIo protocols on Controller.
|
||||
Shutdown the connections to the network layer by locating the
|
||||
tags on the network interfaces established by ::EslServiceConnect.
|
||||
This routine shutdowns any activity on the network interface and
|
||||
then frees the ::ESL_SERVICE structures.
|
||||
|
||||
@param [in] BindingHandle Handle for protocol binding.
|
||||
@param [in] Controller Handle of device to stop driver on.
|
||||
@param [in] Controller Handle of device to stop driver on.
|
||||
|
||||
@retval EFI_SUCCESS This driver is removed Controller.
|
||||
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
|
||||
@@ -272,9 +280,13 @@ EslServiceDisconnect (
|
||||
IN EFI_HANDLE Controller
|
||||
)
|
||||
{
|
||||
CONST DT_SOCKET_BINDING * pEnd;
|
||||
DT_SERVICE * pService;
|
||||
CONST DT_SOCKET_BINDING * pSocketBinding;
|
||||
UINT8 * pBuffer;
|
||||
CONST ESL_SOCKET_BINDING * pEnd;
|
||||
ESL_PORT * pPort;
|
||||
ESL_SERVICE * pPreviousService;
|
||||
ESL_SERVICE * pService;
|
||||
ESL_SERVICE ** ppServiceListHead;
|
||||
CONST ESL_SOCKET_BINDING * pSocketBinding;
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL TplPrevious;
|
||||
|
||||
@@ -310,9 +322,54 @@ EslServiceDisconnect (
|
||||
RAISE_TPL ( TplPrevious, TPL_SOCKETS );
|
||||
|
||||
//
|
||||
// Shutdown the service
|
||||
// Walk the list of ports
|
||||
//
|
||||
pSocketBinding->pfnShutdown ( pService );
|
||||
pPort = pService->pPortList;
|
||||
while ( NULL != pPort ) {
|
||||
//
|
||||
// Remove the port from the port list
|
||||
//
|
||||
pPort->pService = NULL;
|
||||
pService->pPortList = pPort->pLinkService;
|
||||
|
||||
//
|
||||
// Close the port
|
||||
//
|
||||
EslSocketPortCloseStart ( pPort,
|
||||
TRUE,
|
||||
DEBUG_POOL | DEBUG_INIT );
|
||||
|
||||
//
|
||||
// Set the next port
|
||||
//
|
||||
pPort = pService->pPortList;
|
||||
}
|
||||
|
||||
//
|
||||
// Remove the service from the service list
|
||||
//
|
||||
pBuffer = (UINT8 *)&mEslLayer;
|
||||
pBuffer = &pBuffer[ pService->pSocketBinding->ServiceListOffset ];
|
||||
ppServiceListHead = (ESL_SERVICE **)pBuffer;
|
||||
pPreviousService = *ppServiceListHead;
|
||||
if ( pService == pPreviousService ) {
|
||||
//
|
||||
// Remove the service from the beginning of the list
|
||||
//
|
||||
*ppServiceListHead = pService->pNext;
|
||||
}
|
||||
else {
|
||||
//
|
||||
// Remove the service from the middle of the list
|
||||
//
|
||||
while ( NULL != pPreviousService ) {
|
||||
if ( pService == pPreviousService->pNext ) {
|
||||
pPreviousService->pNext = pService->pNext;
|
||||
break;
|
||||
}
|
||||
pPreviousService = pPreviousService->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Release the socket layer synchronization
|
||||
@@ -387,48 +444,6 @@ EslServiceDisconnect (
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Install the socket service
|
||||
|
||||
@param [in] pImageHandle Address of the image handle
|
||||
|
||||
@retval EFI_SUCCESS Service installed successfully
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EslServiceInstall (
|
||||
IN EFI_HANDLE * pImageHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Install the socket service binding protocol
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
pImageHandle,
|
||||
&gEfiSocketServiceBindingProtocolGuid,
|
||||
&mEslLayer.ServiceBinding,
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Initialize the service layer
|
||||
|
||||
@@ -441,69 +456,20 @@ EslServiceLoad (
|
||||
IN EFI_HANDLE ImageHandle
|
||||
)
|
||||
{
|
||||
DT_LAYER * pLayer;
|
||||
ESL_LAYER * pLayer;
|
||||
|
||||
//
|
||||
// Save the image handle
|
||||
//
|
||||
pLayer = &mEslLayer;
|
||||
ZeroMem ( pLayer, sizeof ( *pLayer ));
|
||||
pLayer->Signature = LAYER_SIGNATURE;
|
||||
pLayer->ImageHandle = ImageHandle;
|
||||
|
||||
//
|
||||
// Initialize the TCP4 close
|
||||
//
|
||||
pLayer->TcpCloseMax4 = DIM ( mpEfiTcpClose4 );
|
||||
pLayer->ppTcpClose4 = mpEfiTcpClose4;
|
||||
|
||||
//
|
||||
// Connect the service binding protocol to the image handle
|
||||
//
|
||||
pLayer->ServiceBinding.CreateChild = EslSocketCreateChild;
|
||||
pLayer->ServiceBinding.DestroyChild = EslSocketDestroyChild;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Uninstall the socket service
|
||||
|
||||
@param [in] ImageHandle Handle for the image.
|
||||
|
||||
@retval EFI_SUCCESS Service installed successfully
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EslServiceUninstall (
|
||||
IN EFI_HANDLE ImageHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Install the socket service binding protocol
|
||||
//
|
||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||
ImageHandle,
|
||||
&gEfiSocketServiceBindingProtocolGuid,
|
||||
&mEslLayer.ServiceBinding,
|
||||
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;
|
||||
pLayer->pServiceBinding = &mEfiServiceBinding;
|
||||
}
|
||||
|
||||
|
||||
@@ -517,13 +483,12 @@ EslServiceUnload (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
DT_LAYER * pLayer;
|
||||
ESL_LAYER * pLayer;
|
||||
|
||||
//
|
||||
// Undo the work by ServiceLoad
|
||||
//
|
||||
pLayer = &mEslLayer;
|
||||
pLayer->ImageHandle = NULL;
|
||||
pLayer->ServiceBinding.CreateChild = NULL;
|
||||
pLayer->ServiceBinding.DestroyChild = NULL;
|
||||
pLayer->pServiceBinding = NULL;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -15,14 +15,30 @@
|
||||
#include "Socket.h"
|
||||
|
||||
|
||||
CONST EFI_GUID mEslRawServiceGuid = {
|
||||
0xc31bf4a5, 0x2c7, 0x49d2, { 0xa5, 0x58, 0xfe, 0x62, 0x6f, 0x7e, 0xd4, 0x77 }
|
||||
/**
|
||||
The following GUID values are only used when an application links
|
||||
against EfiSocketLib. An alternative set of values exists in
|
||||
SocketDxe\EntryUnload.c which the SocketDxe driver uses to coexist
|
||||
with socket applications.
|
||||
|
||||
Tag GUID - IPv4 in use by an application using EfiSocketLib
|
||||
**/
|
||||
CONST EFI_GUID mEslIp4ServiceGuid = {
|
||||
0x9c756011, 0x5d44, 0x4ee0, { 0xbc, 0xe7, 0xc3, 0x82, 0x18, 0xfe, 0x39, 0x8d }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Tag GUID - TCPv4 in use by an application using EfiSocketLib
|
||||
**/
|
||||
CONST EFI_GUID mEslTcp4ServiceGuid = {
|
||||
0xffc659c2, 0x4ef2, 0x4532, { 0xb8, 0x75, 0xcd, 0x9a, 0xa4, 0x27, 0x4c, 0xde }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Tag GUID - UDPv4 in use by an application using EfiSocketLib
|
||||
**/
|
||||
CONST EFI_GUID mEslUdp4ServiceGuid = {
|
||||
0x44e03a55, 0x8d97, 0x4511, { 0xbf, 0xef, 0xa, 0x8b, 0xc6, 0x2c, 0x25, 0xae }
|
||||
};
|
||||
@@ -31,10 +47,20 @@ CONST EFI_GUID mEslUdp4ServiceGuid = {
|
||||
/**
|
||||
Connect to the EFI socket library
|
||||
|
||||
@param [in] ppSocketProtocol Address to receive the socket protocol address
|
||||
This routine creates the ::ESL_SOCKET structure and returns
|
||||
the API (::EFI_SOCKET_PROTOCOL address) to the socket file
|
||||
system layer in BsdSocketLib.
|
||||
|
||||
This routine is called from the ::socket routine in BsdSocketLib
|
||||
to create the data structure and initialize the API for a socket.
|
||||
Note that this implementation is only used by socket applications
|
||||
that link directly to EslSocketLib.
|
||||
|
||||
@param [in] ppSocketProtocol Address to receive the ::EFI_SOCKET_PROTOCOL
|
||||
structure address
|
||||
|
||||
@return Value for ::errno, zero (0) indicates success.
|
||||
|
||||
@retval 0 Successfully returned the socket protocol
|
||||
@retval other Value for errno
|
||||
**/
|
||||
int
|
||||
EslServiceGetProtocol (
|
||||
@@ -42,7 +68,7 @@ EslServiceGetProtocol (
|
||||
)
|
||||
{
|
||||
EFI_HANDLE ChildHandle;
|
||||
DT_SOCKET * pSocket;
|
||||
ESL_SOCKET * pSocket;
|
||||
int RetVal;
|
||||
EFI_STATUS Status;
|
||||
|
||||
@@ -81,6 +107,16 @@ EslServiceGetProtocol (
|
||||
/**
|
||||
Connect to the network layer
|
||||
|
||||
This routine is the constructor for the EfiSocketLib when the
|
||||
library is linked directly to an application. This routine
|
||||
walks the ::cEslSocketBinding table to create ::ESL_SERVICE
|
||||
structures, associated with the network adapters, which this
|
||||
routine links to the ::ESL_LAYER structure.
|
||||
|
||||
This routine is called from ::EslConstructor as a result of the
|
||||
constructor redirection in ::mpfnEslConstructor at the end of this
|
||||
file.
|
||||
|
||||
@retval EFI_SUCCESS Successfully connected to the network layer
|
||||
|
||||
**/
|
||||
@@ -89,11 +125,12 @@ EslServiceNetworkConnect (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
BOOLEAN bSomethingFound;
|
||||
UINTN HandleCount;
|
||||
EFI_HANDLE * pHandles;
|
||||
UINTN Index;
|
||||
CONST DT_SOCKET_BINDING * pSocketBinding;
|
||||
CONST DT_SOCKET_BINDING * pEnd;
|
||||
CONST ESL_SOCKET_BINDING * pEnd;
|
||||
EFI_HANDLE * pHandles;
|
||||
CONST ESL_SOCKET_BINDING * pSocketBinding;
|
||||
EFI_STATUS Status;
|
||||
|
||||
DBG_ENTER ( );
|
||||
@@ -102,13 +139,14 @@ EslServiceNetworkConnect (
|
||||
// Initialize the socket layer
|
||||
//
|
||||
Status = EFI_SUCCESS;
|
||||
bSomethingFound = FALSE;
|
||||
EslServiceLoad ( gImageHandle );
|
||||
|
||||
//
|
||||
// Connect the network devices
|
||||
//
|
||||
pSocketBinding = &cEslSocketBinding [0];
|
||||
pEnd = &pSocketBinding [ cEslSocketBindingEntries ];
|
||||
pSocketBinding = &cEslSocketBinding[0];
|
||||
pEnd = &pSocketBinding[ cEslSocketBindingEntries ];
|
||||
while ( pEnd > pSocketBinding ) {
|
||||
//
|
||||
// Attempt to locate the network adapters
|
||||
@@ -121,24 +159,30 @@ EslServiceNetworkConnect (
|
||||
&HandleCount,
|
||||
&pHandles );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
DEBUG (( DEBUG_ERROR,
|
||||
"ERROR with %s layer, Status: %r\r\n",
|
||||
pSocketBinding->pName,
|
||||
Status ));
|
||||
}
|
||||
if ( NULL != pHandles ) {
|
||||
//
|
||||
// Attempt to connect to this network adapter
|
||||
//
|
||||
for ( Index = 0; HandleCount > Index; Index++ ) {
|
||||
Status = EslServiceConnect ( gImageHandle,
|
||||
pHandles [ Index ]);
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
else {
|
||||
if ( NULL != pHandles ) {
|
||||
//
|
||||
// Attempt to connect to this network adapter
|
||||
//
|
||||
for ( Index = 0; HandleCount > Index; Index++ ) {
|
||||
Status = EslServiceConnect ( gImageHandle,
|
||||
pHandles[ Index ]);
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
bSomethingFound = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Done with the handles
|
||||
//
|
||||
gBS->FreePool ( pHandles );
|
||||
//
|
||||
// Done with the handles
|
||||
//
|
||||
gBS->FreePool ( pHandles );
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@@ -150,6 +194,9 @@ EslServiceNetworkConnect (
|
||||
//
|
||||
// Return the network connection status
|
||||
//
|
||||
if ( bSomethingFound ) {
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
DBG_EXIT_STATUS ( Status );
|
||||
return Status;
|
||||
}
|
||||
@@ -158,6 +205,15 @@ EslServiceNetworkConnect (
|
||||
/**
|
||||
Disconnect from the network layer
|
||||
|
||||
Destructor for the EfiSocketLib when the library is linked
|
||||
directly to an application. This routine walks the
|
||||
::cEslSocketBinding table to remove the ::ESL_SERVICE
|
||||
structures (network connections) from the ::ESL_LAYER structure.
|
||||
|
||||
This routine is called from ::EslDestructor as a result of the
|
||||
destructor redirection in ::mpfnEslDestructor at the end of this
|
||||
file.
|
||||
|
||||
@retval EFI_SUCCESS Successfully disconnected from the network layer
|
||||
|
||||
**/
|
||||
@@ -167,10 +223,10 @@ EslServiceNetworkDisconnect (
|
||||
)
|
||||
{
|
||||
UINTN HandleCount;
|
||||
EFI_HANDLE * pHandles;
|
||||
UINTN Index;
|
||||
CONST DT_SOCKET_BINDING * pSocketBinding;
|
||||
CONST DT_SOCKET_BINDING * pEnd;
|
||||
CONST ESL_SOCKET_BINDING * pEnd;
|
||||
EFI_HANDLE * pHandles;
|
||||
CONST ESL_SOCKET_BINDING * pSocketBinding;
|
||||
EFI_STATUS Status;
|
||||
|
||||
DBG_ENTER ( );
|
||||
@@ -183,8 +239,8 @@ EslServiceNetworkDisconnect (
|
||||
//
|
||||
// Disconnect the network devices
|
||||
//
|
||||
pSocketBinding = &cEslSocketBinding [0];
|
||||
pEnd = &pSocketBinding [ cEslSocketBindingEntries ];
|
||||
pSocketBinding = &cEslSocketBinding[0];
|
||||
pEnd = &pSocketBinding[ cEslSocketBindingEntries ];
|
||||
while ( pEnd > pSocketBinding ) {
|
||||
//
|
||||
// Attempt to locate the network adapters
|
||||
@@ -205,7 +261,7 @@ EslServiceNetworkDisconnect (
|
||||
//
|
||||
for ( Index = 0; HandleCount > Index; Index++ ) {
|
||||
Status = EslServiceDisconnect ( gImageHandle,
|
||||
pHandles [ Index ]);
|
||||
pHandles[ Index ]);
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
@@ -238,5 +294,19 @@ EslServiceNetworkDisconnect (
|
||||
}
|
||||
|
||||
|
||||
PFN_ESL_xSTRUCTOR mpfnEslConstructor = EslServiceNetworkConnect;
|
||||
PFN_ESL_xSTRUCTOR mpfnEslDestructor = EslServiceNetworkDisconnect;
|
||||
/**
|
||||
Socket layer's service binding protocol delcaration.
|
||||
**/
|
||||
CONST EFI_SERVICE_BINDING_PROTOCOL mEfiServiceBinding = {
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
The following entries redirect the constructor and destructor
|
||||
for any socket application that links against the EfiSocketLib.
|
||||
Note that the SocketDxe driver uses different redirection.
|
||||
**/
|
||||
PFN_ESL_xSTRUCTOR mpfnEslConstructor = EslServiceNetworkConnect; ///< Constructor for EfiSocketLib
|
||||
PFN_ESL_xSTRUCTOR mpfnEslDestructor = EslServiceNetworkDisconnect; ///< Destructor for EfiSocketLib
|
||||
|
Reference in New Issue
Block a user