* 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
		
			
				
	
	
		
			328 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			328 lines
		
	
	
		
			9.3 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 - TCPv4 in use by SocketDxe
 | 
						|
**/
 | 
						|
CONST EFI_GUID mEslTcp4ServiceGuid = {
 | 
						|
    0x4dcaab0a, 0x1990, 0x4352, { 0x8d, 0x2f, 0x2d, 0x8f, 0x13, 0x55, 0x98, 0xa5 }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Tag GUID - UDPv4 in use by SocketDxe
 | 
						|
**/
 | 
						|
CONST EFI_GUID mEslUdp4ServiceGuid = {
 | 
						|
    0x43a110ce, 0x9ccd, 0x402b, { 0x8c, 0x29, 0x4a, 0x6d, 0x8a, 0xf7, 0x79, 0x90 }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  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
 |