* Fixed bug report (Duane Voth: Python sockets test application not working) by starting the receive operations when a connection is established! * Increased performance by extending the idle loop into the network stack with the Poll call. * Added support for TCPv6 (SOCK_STREAM) and UDPv6 (SOCK_DGRAM). * Added support for getaddrinfo and getnameinfo calls. * Moved application PCD values into AppPkg Signed-off-by: lpleahy git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13002 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			352 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			352 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Implement the entry and unload for the socket driver.
 | |
| 
 | |
|   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"
 | |
| 
 | |
| 
 | |
| /**
 | |
|   The following GUID values are only used by the SocketDxe driver.  An
 | |
|   alternative set of values exists in EfiSocketLib\UseEfiSocketLib.c
 | |
|   which an application uses when it links against EfiSocketLib.  These
 | |
|   two sets of values allow the SocketDxe driver to coexist with socket
 | |
|   applications.
 | |
| 
 | |
|   Tag GUID - IPv4 in use by SocketDxe
 | |
| **/
 | |
| CONST EFI_GUID mEslIp4ServiceGuid = {
 | |
|   0x4e3a82e6, 0xe43f, 0x460a, { 0x86, 0x6e, 0x9b, 0x5a, 0xab, 0x80, 0x44, 0x48 }
 | |
| };
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Tag GUID - IPv6 in use by SocketDxe
 | |
| **/
 | |
| CONST EFI_GUID mEslIp6ServiceGuid = {
 | |
|   0x2fc3b2d3, 0x6eba, 0x42b0, { 0xa4, 0xa7, 0x14, 0xc7, 0xa8, 0x4b, 0x5d, 0x22 }
 | |
| };
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Tag GUID - TCPv4 in use by SocketDxe
 | |
| **/
 | |
| CONST EFI_GUID mEslTcp4ServiceGuid = {
 | |
|   0x4dcaab0a, 0x1990, 0x4352, { 0x8d, 0x2f, 0x2d, 0x8f, 0x13, 0x55, 0x98, 0xa5 }
 | |
| };
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Tag GUID - TCPv6 in use by SocketDxe
 | |
| **/
 | |
| CONST EFI_GUID mEslTcp6ServiceGuid = {
 | |
|   0xdd455a69, 0xec75, 0x456c, { 0x84, 0xd2, 0x95, 0xca, 0xe7, 0xd3, 0xc6, 0xd3 }
 | |
| };
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Tag GUID - UDPv4 in use by SocketDxe
 | |
| **/
 | |
| CONST EFI_GUID mEslUdp4ServiceGuid = {
 | |
|   0x43a110ce, 0x9ccd, 0x402b, { 0x8c, 0x29, 0x4a, 0x6d, 0x8a, 0xf7, 0x79, 0x90 }
 | |
| };
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Tag GUID - UDPv6 in use by SocketDxe
 | |
| **/
 | |
| CONST EFI_GUID mEslUdp6ServiceGuid = {
 | |
|   0x32ff59cd, 0xc33, 0x48d0, { 0xa2, 0x44, 0x4b, 0xb8, 0x11, 0x33, 0x64, 0x3 }
 | |
| };
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Socket driver unload routine.
 | |
| 
 | |
|   @param [in] ImageHandle       Handle for the image.
 | |
| 
 | |
|   @retval EFI_SUCCESS           Image may be unloaded
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| DriverUnload (
 | |
|   IN EFI_HANDLE ImageHandle
 | |
|   )
 | |
| {
 | |
|   UINTN BufferSize;
 | |
|   UINTN Index;
 | |
|   UINTN Max;
 | |
|   EFI_HANDLE * pHandle;
 | |
|   EFI_STATUS Status;
 | |
| 
 | |
|   //
 | |
|   //  Determine which devices are using this driver
 | |
|   //
 | |
|   BufferSize = 0;
 | |
|   pHandle = NULL;
 | |
|   Status = gBS->LocateHandle (
 | |
|                   ByProtocol,
 | |
|                   &gEfiCallerIdGuid,
 | |
|                   NULL,
 | |
|                   &BufferSize,
 | |
|                   NULL );
 | |
|   if ( EFI_BUFFER_TOO_SMALL == Status ) {
 | |
|     for ( ; ; ) {
 | |
|       //
 | |
|       //  One or more block IO devices are present
 | |
|       //
 | |
|       Status = gBS->AllocatePool (
 | |
|                       EfiRuntimeServicesData,
 | |
|                       BufferSize,
 | |
|                       (VOID **) &pHandle
 | |
|                       );
 | |
|       if ( EFI_ERROR ( Status )) {
 | |
|         DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
 | |
|                   "Insufficient memory, failed handle buffer allocation\r\n" ));
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       //
 | |
|       //  Locate the block IO devices
 | |
|       //
 | |
|       Status = gBS->LocateHandle (
 | |
|                       ByProtocol,
 | |
|                       &gEfiCallerIdGuid,
 | |
|                       NULL,
 | |
|                       &BufferSize,
 | |
|                       pHandle );
 | |
|       if ( EFI_ERROR ( Status )) {
 | |
|         //
 | |
|         //  Error getting handles
 | |
|         //
 | |
|         DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
 | |
|                 "Failure getting Telnet handles\r\n" ));
 | |
|         break;
 | |
|       }
 | |
|       
 | |
|       //
 | |
|       //  Remove any use of the driver
 | |
|       //
 | |
|       Max = BufferSize / sizeof ( pHandle[ 0 ]);
 | |
|       for ( Index = 0; Max > Index; Index++ ) {
 | |
|         Status = DriverStop ( &mDriverBinding,
 | |
|                               pHandle[ Index ],
 | |
|                               0,
 | |
|                               NULL );
 | |
|         if ( EFI_ERROR ( Status )) {
 | |
|           DEBUG (( DEBUG_WARN | DEBUG_INIT | DEBUG_INFO,
 | |
|                     "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle[ Index ]));
 | |
|           break;
 | |
|         }
 | |
|       }
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
|   else {
 | |
|     if ( EFI_NOT_FOUND == Status ) {
 | |
|       //
 | |
|       //  No devices were found
 | |
|       //
 | |
|       Status = EFI_SUCCESS;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   //  Free the handle array
 | |
|   //
 | |
|   if ( NULL != pHandle ) {
 | |
|     gBS->FreePool ( pHandle );
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   //  Done with the socket layer
 | |
|   //
 | |
|   if ( !EFI_ERROR ( Status )) {
 | |
|     Status = EslDxeUninstall ( ImageHandle );
 | |
|     if ( !EFI_ERROR ( Status )) {
 | |
|       //
 | |
|       //  Remove the protocols installed by the EntryPoint routine.
 | |
|       //
 | |
|       Status = gBS->UninstallMultipleProtocolInterfaces (
 | |
|                   ImageHandle,
 | |
|                   &gEfiDriverBindingProtocolGuid,
 | |
|                   &mDriverBinding,
 | |
|                   &gEfiComponentNameProtocolGuid,
 | |
|                   &mComponentName,
 | |
|                   &gEfiComponentName2ProtocolGuid,
 | |
|                   &mComponentName2,
 | |
|                   NULL
 | |
|                   );
 | |
|       if ( !EFI_ERROR ( Status )) {
 | |
|         DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
 | |
|                 "Removed:   gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
 | |
|                 ImageHandle ));
 | |
|         DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
 | |
|                   "Removed:   gEfiComponentNameProtocolGuid from 0x%08x\r\n",
 | |
|                   ImageHandle ));
 | |
|         DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
 | |
|                   "Removed:   gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
 | |
|                   ImageHandle ));
 | |
|       }
 | |
|       else {
 | |
|         DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
 | |
|                     "ERROR - Failed to remove gEfiDriverBindingProtocolGuid from 0x%08x, Status: %r\r\n",
 | |
|                     ImageHandle,
 | |
|                     Status ));
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   //  Disconnect the network services
 | |
|   //
 | |
|   if ( !EFI_ERROR ( Status )) {
 | |
|     EslServiceUnload ( );
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   //  Return the unload status
 | |
|   //
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
| Socket driver entry point.
 | |
| 
 | |
| @param [in] ImageHandle       Handle for the image.
 | |
| @param [in] pSystemTable      Address of the system table.
 | |
| 
 | |
| @retval EFI_SUCCESS           Image successfully loaded.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| EntryPoint (
 | |
|   IN EFI_HANDLE ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE * pSystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_LOADED_IMAGE_PROTOCOL * pLoadedImage;
 | |
|   EFI_STATUS    Status;
 | |
| 
 | |
|   DBG_ENTER ( );
 | |
| 
 | |
|   //
 | |
|   //  Display the image handle
 | |
|   //
 | |
|   DEBUG (( DEBUG_INFO,
 | |
|             "ImageHandle: 0x%08x\r\n",
 | |
|             ImageHandle ));
 | |
| 
 | |
|   //
 | |
|   //  Enable unload support
 | |
|   //
 | |
|   Status = gBS->HandleProtocol (
 | |
|                   gImageHandle,
 | |
|                   &gEfiLoadedImageProtocolGuid,
 | |
|                   (VOID **)&pLoadedImage
 | |
|                   );
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     pLoadedImage->Unload = DriverUnload;
 | |
| 
 | |
|     //
 | |
|     //  Add the driver to the list of drivers
 | |
|     //
 | |
|     Status = EfiLibInstallDriverBindingComponentName2 (
 | |
|                ImageHandle,
 | |
|                pSystemTable,
 | |
|                &mDriverBinding,
 | |
|                ImageHandle,
 | |
|                &mComponentName,
 | |
|                &mComponentName2
 | |
|                );
 | |
|     if ( !EFI_ERROR ( Status )) {
 | |
|       DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
 | |
|                 "Installed: gEfiDriverBindingProtocolGuid on   0x%08x\r\n",
 | |
|                 ImageHandle ));
 | |
|       DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
 | |
|                 "Installed: gEfiComponentNameProtocolGuid on   0x%08x\r\n",
 | |
|                 ImageHandle ));
 | |
|       DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
 | |
|                 "Installed: gEfiComponentName2ProtocolGuid on   0x%08x\r\n",
 | |
|                 ImageHandle ));
 | |
| 
 | |
|       //
 | |
|       //  Initialize the service layer
 | |
|       //
 | |
|       EslServiceLoad ( ImageHandle );
 | |
| 
 | |
|       //
 | |
|       //  Make the socket serivces available to other drivers
 | |
|       //  and applications
 | |
|       //
 | |
|       Status = EslDxeInstall ( &ImageHandle );
 | |
|       if ( EFI_ERROR ( Status )) {
 | |
|         //
 | |
|         //  Disconnect from the network
 | |
|         //
 | |
|         EslServiceUnload ( );
 | |
| 
 | |
|         //
 | |
|         //  Remove the driver bindings
 | |
|         //
 | |
|         gBS->UninstallMultipleProtocolInterfaces (
 | |
|                 ImageHandle,
 | |
|                 &gEfiDriverBindingProtocolGuid,
 | |
|                 &mDriverBinding,
 | |
|                 &gEfiComponentNameProtocolGuid,
 | |
|                 &mComponentName,
 | |
|                 &gEfiComponentName2ProtocolGuid,
 | |
|                 &mComponentName2,
 | |
|                 NULL
 | |
|                 );
 | |
|         DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
 | |
|                 "Removed:   gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
 | |
|                 ImageHandle ));
 | |
|         DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
 | |
|                   "Removed:   gEfiComponentNameProtocolGuid from 0x%08x\r\n",
 | |
|                   ImageHandle ));
 | |
|         DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
 | |
|                   "Removed:   gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
 | |
|                   ImageHandle ));
 | |
|       }
 | |
|     }
 | |
|     else  {
 | |
|       DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,
 | |
|                 "ERROR - EfiLibInstallDriverBindingComponentName2 failed, Status: %r\r\n",
 | |
|                 Status ));
 | |
|     }
 | |
|   }
 | |
|   DBG_EXIT_STATUS ( Status );
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Socket layer's service binding protocol delcaration.
 | |
| **/
 | |
| CONST EFI_SERVICE_BINDING_PROTOCOL mEfiServiceBinding = {
 | |
|   EslDxeCreateChild,
 | |
|   EslDxeDestroyChild
 | |
| };
 | |
| 
 | |
| 
 | |
| /**
 | |
|   The following entries disable the constructor and destructor
 | |
|   for the SocketDxe driver.  Note that socket applications linking
 | |
|   against EfiSocketLib use different redirection.
 | |
| **/
 | |
| PFN_ESL_xSTRUCTOR mpfnEslConstructor = NULL;  ///<  No EfiSocketLib constructor needed for SocketDxe
 | |
| PFN_ESL_xSTRUCTOR mpfnEslDestructor = NULL;   ///<  No EfiSocketLib destructor needed for SocketDxe
 |