Retail products


Traffic interception SDK

Control every TCP/IP network connection

  • Route connections via proxy
  • Redirect connections and modify the data
  • Block connections and applications
SSL interception SDK

View SSL in plaintext and modify it

  • View the SSL stream decrypted in plaintext
  • Redirect SSL connection and modify decrypted data
  • Browser shows "SSL lock" without warnings

Documentation


lspdef.h File Reference

#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <ws2spi.h>
#include <mswsock.h>
#include <ws2tcpip.h>
#include <mstcpip.h>
#include <lspcommon.h>

Include dependency graph for lspdef.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.


Classes

struct  _SOCK_INFO
struct  _FD_MAP
struct  _ACCEPTEXARGS
struct  _TRANSMITFILEARGS
struct  _CONNECTEXARGS
struct  _TRANSMITPACKETSARGS
struct  _DISCONNECTEXARGS
struct  _WSARECVMSGARGS
struct  _RECVARGS
struct  _RECVFROMARGS
struct  _SENDARGS
struct  _SENDTOARGS
struct  _IOCTLARGS
struct  _WSAOVERLAPPEDPLUS

Defines

#define WM_SOCKET   ( WM_USER + 321 )

Typedefs

typedef struct _SOCK_INFO SOCK_INFO
typedef struct _FD_MAP FD_MAP
typedef struct _ACCEPTEXARGS ACCEPTEXARGS
typedef struct _TRANSMITFILEARGS TRANSMITFILEARGS
typedef struct _CONNECTEXARGS CONNECTEXARGS
typedef struct _TRANSMITPACKETSARGS TRANSMITPACKETSARGS
typedef struct _DISCONNECTEXARGS DISCONNECTEXARGS
typedef struct _WSARECVMSGARGS WSARECVMSGARGS
typedef struct _RECVARGS RECVARGS
typedef struct _RECVFROMARGS RECVFROMARGS
typedef struct _SENDARGS SENDARGS
typedef struct _SENDTOARGS SENDTOARGS
typedef struct _IOCTLARGS IOCTLARGS
typedef struct _WSAOVERLAPPEDPLUS WSAOVERLAPPEDPLUS
typedef struct _WSAOVERLAPPEDPLUSLPWSAOVERLAPPEDPLUS

Enumerations

enum  LspOperation {
  LSP_OP_IOCTL = 1, LSP_OP_RECV, LSP_OP_RECVFROM, LSP_OP_SEND,
  LSP_OP_SENDTO, LSP_OP_TRANSMITFILE, LSP_OP_ACCEPTEX, LSP_OP_CONNECTEX,
  LSP_OP_DISCONNECTEX, LSP_OP_TRANSMITPACKETS, LSP_OP_WSARECVMSG
}

Functions

HWND GetWorkerWindow ()
int StopAsyncWindowManager ()
SOCKET WSPAPI WSPAccept (SOCKET s, struct sockaddr FAR *addr, LPINT addrlen, LPCONDITIONPROC lpfnCondition, DWORD_PTR dwCallbackData, LPINT lpErrno)
int WSPAPI WSPAddressToString (LPSOCKADDR lpsaAddress, DWORD dwAddressLength, LPWSAPROTOCOL_INFOW lpProtocolInfo, LPWSTR lpszAddressString, LPDWORD lpdwAddressStringLength, LPINT lpErrno)
int WSPAPI WSPAsyncSelect (SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent, LPINT lpErrno)
int WSPAPI WSPBind (SOCKET s, const struct sockaddr FAR *name, int namelen, LPINT lpErrno)
int WSPAPI WSPCancelBlockingCall (LPINT lpErrno)
int WSPAPI WSPCleanup (LPINT lpErrno)
int WSPAPI WSPCloseSocket (SOCKET s, LPINT lpErrno)
int WSPAPI WSPConnect (SOCKET s, const struct sockaddr FAR *name, int namelen, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS, LPINT lpErrno)
int WSPAPI WSPDuplicateSocket (SOCKET s, DWORD dwProcessId, LPWSAPROTOCOL_INFOW lpProtocolInfo, LPINT lpErrno)
int WSPAPI WSPEnumNetworkEvents (SOCKET s, WSAEVENT hEventObject, LPWSANETWORKEVENTS lpNetworkEvents, LPINT lpErrno)
int WSPAPI WSPEventSelect (SOCKET s, WSAEVENT hEventObject, long lNetworkEvents, LPINT lpErrno)
BOOL WSPAPI WSPGetOverlappedResult (SOCKET s, LPWSAOVERLAPPED lpOverlapped, LPDWORD lpcbTransfer, BOOL fWait, LPDWORD lpdwFlags, LPINT lpErrno)
int WSPAPI WSPGetPeerName (SOCKET s, struct sockaddr FAR *name, LPINT namelen, LPINT lpErrno)
int WSPAPI WSPGetSockName (SOCKET s, struct sockaddr FAR *name, LPINT namelen, LPINT lpErrno)
int WSPAPI WSPGetSockOpt (SOCKET s, int level, int optname, char FAR *optval, LPINT optlen, LPINT lpErrno)
BOOL WSPAPI WSPGetQOSByName (SOCKET s, LPWSABUF lpQOSName, LPQOS lpQOS, LPINT lpErrno)
int WSPAPI WSPIoctl (SOCKET s, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
SOCKET WSPAPI WSPJoinLeaf (SOCKET s, const struct sockaddr FAR *name, int namelen, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS, DWORD dwFlags, LPINT lpErrno)
int WSPAPI WSPListen (SOCKET s, int backlog, LPINT lpErrno)
int WSPAPI WSPRecv (SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
int WSPAPI WSPRecvDisconnect (SOCKET s, LPWSABUF lpInboundDisconnectData, LPINT lpErrno)
int WSPAPI WSPRecvFrom (SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, struct sockaddr FAR *lpFrom, LPINT lpFromLen, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
int WSPAPI WSPSelect (int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout, LPINT lpErrno)
int WSPAPI WSPSend (SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
int WSPAPI WSPSendDisconnect (SOCKET s, LPWSABUF lpOutboundDisconnectData, LPINT lpErrno)
int WSPAPI WSPSendTo (SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, const struct sockaddr FAR *lpTo, int iToLen, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
int WSPAPI WSPSetSockOpt (SOCKET s, int level, int optname, const char FAR *optval, int optlen, LPINT lpErrno)
int WSPAPI WSPShutdown (SOCKET s, int how, LPINT lpErrno)
int WSPAPI WSPStringToAddress (LPWSTR AddressString, INT AddressFamily, LPWSAPROTOCOL_INFOW lpProtocolInfo, LPSOCKADDR lpAddress, LPINT lpAddressLength, LPINT lpErrno)
SOCKET WSPAPI WSPSocket (int af, int type, int protocol, __in LPWSAPROTOCOL_INFOW lpProtocolInfo, GROUP g, DWORD dwFlags, LPINT lpErrno)
void CopyOffset (WSAOVERLAPPED *ProviderOverlapped, WSAOVERLAPPED *UserOverlapped)
WSABUF * CopyWSABuf (WSABUF *BufferArray, DWORD BufferCount, int *lpErrno)
void FreeWSABuf (WSABUF *BufferArray)
int InitOverlappedManager ()
int StopOverlappedManager ()
int QueueOverlappedOperation (WSAOVERLAPPEDPLUS *lpOverlapped, SOCK_INFO *Context)
WSAOVERLAPPEDPLUSPrepareOverlappedOperation (SOCK_INFO *SocketContext, LspOperation operation, WSABUF *lpBuffers, DWORD dwBufferCount, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, int *lpErrno)
void CALLBACK IntermediateCompletionRoutine (DWORD dwError, DWORD cbTransferred, LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags)
void UndoOverlappedOperation (SOCK_INFO *SocketContext, WSAOVERLAPPEDPLUS *ProviderOverlapped)
void FreeOverlappedLookasideList ()
SOCK_INFOGetCallerSocket (PROVIDER *provider, SOCKET ProviderSocket)
SOCK_INFOCreateSockInfo (PROVIDER *Provider, SOCKET ProviderSocket, SOCK_INFO *Inherit, BOOL Insert, int *lpErrno)
SOCK_INFOFindAndRefSocketContext (SOCKET s, int *err)
void DerefSocketContext (SOCK_INFO *context, int *err)
void FreeSockInfo (SOCK_INFO *info)
void InsertSocketInfo (PROVIDER *provider, SOCK_INFO *sock)
void RemoveSocketInfo (PROVIDER *provider, SOCK_INFO *sock)
void AcquireSocketLock (SOCK_INFO *SockInfo)
void ReleaseSocketLock (SOCK_INFO *SockInfo)
void CloseAndFreeSocketInfo (PROVIDER *provider, BOOL processDetach)
BOOL PASCAL FAR ExtTransmitFile (IN SOCKET hSocket, IN HANDLE hFile, IN DWORD nNumberOfBytesToWrite, IN DWORD nNumberOfBytesPerSend, IN LPOVERLAPPED lpOverlapped, IN LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers, IN DWORD dwReserved)
BOOL PASCAL FAR ExtAcceptEx (IN SOCKET sListenSocket, IN SOCKET sAcceptSocket, IN PVOID lpOutputBuffer, IN DWORD dwReceiveDataLength, IN DWORD dwLocalAddressLength, IN DWORD dwRemoteAddressLength, OUT LPDWORD lpdwBytesReceived, IN LPOVERLAPPED lpOverlapped)
BOOL PASCAL FAR ExtConnectEx (IN SOCKET s, IN const struct sockaddr FAR *name, IN int namelen, IN PVOID lpSendBuffer OPTIONAL, IN DWORD dwSendDataLength, OUT LPDWORD lpdwBytesSent, IN LPOVERLAPPED lpOverlapped)
BOOL PASCAL FAR ExtTransmitPackets (SOCKET hSocket, LPTRANSMIT_PACKETS_ELEMENT lpPacketArray, DWORD nElementCount, DWORD nSendSize, LPOVERLAPPED lpOverlapped, DWORD dwFlags)
BOOL PASCAL FAR ExtDisconnectEx (IN SOCKET s, IN LPOVERLAPPED lpOverlapped, IN DWORD dwFlags, IN DWORD dwReserved)
INT PASCAL FAR ExtWSARecvMsg (IN SOCKET s, IN OUT LPWSAMSG lpMsg, OUT LPDWORD lpdwNumberOfBytesRecvd, IN LPWSAOVERLAPPED lpOverlapped, IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
BOOL LoadExtensionFunction (FARPROC **func, GUID ExtensionGuid, LPWSPIOCTL fnIoctl, SOCKET s)

Variables

HINSTANCE gDllInstance
CRITICAL_SECTION gCriticalSection
CRITICAL_SECTION gOverlappedCS
INT gLayerCount
PROVIDERgBaseInfo
HANDLE gAddContextEvent
HANDLE gIocp
WSPUPCALLTABLE gMainUpCallTable
GUID gProviderGuid

Define Documentation

#define WM_SOCKET   ( WM_USER + 321 )

Definition at line 38 of file lspdef.h.


Typedef Documentation

typedef struct _ACCEPTEXARGS ACCEPTEXARGS

typedef struct _CONNECTEXARGS CONNECTEXARGS

typedef struct _FD_MAP FD_MAP

typedef struct _IOCTLARGS IOCTLARGS

typedef struct _RECVARGS RECVARGS

typedef struct _RECVFROMARGS RECVFROMARGS

typedef struct _SENDARGS SENDARGS

typedef struct _SENDTOARGS SENDTOARGS

typedef struct _SOCK_INFO SOCK_INFO


Enumeration Type Documentation

Enumerator:
LSP_OP_IOCTL 
LSP_OP_RECV 
LSP_OP_RECVFROM 
LSP_OP_SEND 
LSP_OP_SENDTO 
LSP_OP_TRANSMITFILE 
LSP_OP_ACCEPTEX 
LSP_OP_CONNECTEX 
LSP_OP_DISCONNECTEX 
LSP_OP_TRANSMITPACKETS 
LSP_OP_WSARECVMSG 

Definition at line 200 of file lspdef.h.


Function Documentation

void AcquireSocketLock ( SOCK_INFO SockInfo  ) 

Definition at line 133 of file sockinfo.cpp.

00136 {
00137     EnterCriticalSection( &SockInfo->SockCritSec );
00138 }

void CloseAndFreeSocketInfo ( PROVIDER provider,
BOOL  processDetach 
)

Definition at line 309 of file sockinfo.cpp.

00313 {
00314     LIST_ENTRY   *entry = NULL;
00315     SOCK_INFO    *si = NULL;
00316     struct linger linger;
00317     int           Error, 
00318                   ret;
00319 
00320     ASSERT( provider );
00321 
00322     linger.l_onoff  = 1;
00323     linger.l_linger = 0;
00324 
00325     // Walk the list of sockets
00326     while ( !IsListEmpty( &provider->SocketList ) )
00327     {
00328         entry = RemoveHeadList( &provider->SocketList );
00329 
00330         ASSERT( entry );
00331 
00332         si = CONTAINING_RECORD( entry, SOCK_INFO, Link );
00333 
00334         if ( ( !processDetach ) || 
00335              ( provider->NextProvider.ProtocolChain.ChainLen == BASE_PROTOCOL ) )
00336         {
00337 
00338             ASSERT( provider->NextProcTable.lpWSPSetSockOpt );
00339 
00340             // Set the abortive linger
00341             ret = provider->NextProcTable.lpWSPSetSockOpt(
00342                     si->ProviderSocket,
00343                     SOL_SOCKET,
00344                     SO_LINGER,
00345                     (char *) &linger,
00346                     sizeof(linger),
00347                     &Error
00348                     );
00349             if ( SOCKET_ERROR != ret )
00350             {
00351                 ASSERT( provider->NextProcTable.lpWSPCloseSocket );
00352 
00353                 // Close the lower provider socket
00354                 ret = provider->NextProcTable.lpWSPCloseSocket(
00355                         si->ProviderSocket,
00356                         &Error
00357                         );
00358                 if ( SOCKET_ERROR == ret )
00359                 {
00360                     dbgprint("WSPCloseSocket() on handle %d failed: %d", si->ProviderSocket, Error);
00361                 }
00362 #ifdef DEBUG
00363                 else
00364                 {
00365                     dbgprint("Successfully closed socket %d", si->ProviderSocket);
00366                 }
00367 #endif
00368             }
00369 #ifdef DEBUG
00370             else
00371             {
00372                 dbgprint("WSPSetSockOpt(SO_LINGER) failed: %d", Error);
00373             }
00374 #endif
00375         }
00376 
00377         ASSERT( gMainUpCallTable.lpWPUCloseSocketHandle );
00378 
00379         // Close the layered handle
00380         gMainUpCallTable.lpWPUCloseSocketHandle(
00381                 si->LayeredSocket, 
00382                &Error
00383                 );
00384 
00385         // Free the context structure
00386         FreeSockInfo( si );
00387     }
00388 
00389     return;
00390 }

void CopyOffset ( WSAOVERLAPPED *  ProviderOverlapped,
WSAOVERLAPPED *  UserOverlapped 
)

Definition at line 3431 of file spi.cpp.

03435 {
03436     ProviderOverlapped->Offset     = UserOverlapped->Offset;
03437     ProviderOverlapped->OffsetHigh = UserOverlapped->OffsetHigh;
03438 }

WSABUF* CopyWSABuf ( WSABUF *  BufferArray,
DWORD  BufferCount,
int *  lpErrno 
)

Definition at line 3454 of file spi.cpp.

03459 {
03460     WSABUF      *buffercopy = NULL;
03461     DWORD        i;
03462 
03463     if ( NULL == gIocp )
03464     {
03465         //
03466         // We're on Win9x -- we need to save off the WSABUF structures
03467         // because on Win9x, the overlapped operation does not execute
03468         // immediately and the Winsock spec says apps are free to use
03469         // stack based WSABUF arrays.
03470         //
03471         
03472         buffercopy = (WSABUF *) LspAlloc(
03473                 sizeof(WSABUF) * BufferCount,
03474                 lpErrno
03475                 );
03476         if ( NULL == buffercopy )
03477         {
03478             dbgprint( "CopyWSABuf: HeapAlloc failed: %d", GetLastError() );
03479             return NULL;
03480         }
03481 
03482         for(i=0; i < BufferCount ;i++)
03483         {
03484             buffercopy[i].buf = BufferArray[i].buf;
03485             buffercopy[i].len = BufferArray[i].len;
03486         }
03487 
03488         return buffercopy;
03489     }
03490     else
03491     {
03492         // With completion ports, we post the overlapped operation
03493         // immediately to the lower provider which should capture
03494         // the WSABUF array members itself. If your LSP needs to
03495         // look at the buffers after the operation is initiated,
03496         // you'd better always copy the WSABUF array.
03497 
03498         return BufferArray;
03499     }
03500 }

SOCK_INFO* CreateSockInfo ( PROVIDER Provider,
SOCKET  ProviderSocket,
SOCK_INFO Inherit,
BOOL  Insert,
int *  lpErrno 
)

Definition at line 171 of file sockinfo.cpp.

00178 {
00179     SOCK_INFO   *NewInfo = NULL;
00180 
00181     NewInfo = (SOCK_INFO *) LspAlloc(
00182             sizeof( SOCK_INFO ),
00183             lpErrno
00184             );
00185     if ( NULL == NewInfo )
00186     {
00187         dbgprint("HeapAlloc() failed: %d", GetLastError());
00188        *lpErrno = WSAENOBUFS;
00189         goto cleanup;
00190     }
00191 
00192     //
00193     // Initialize the fields to default values
00194     //
00195     NewInfo->ProviderSocket     = ProviderSocket;
00196     NewInfo->bClosing           = FALSE;
00197     NewInfo->dwOutstandingAsync = 0;
00198     NewInfo->BytesRecv          = 0;
00199     NewInfo->BytesSent          = 0;
00200     NewInfo->Provider           = Provider;
00201     NewInfo->hWnd               = (Inherit ? Inherit->hWnd : 0);
00202     NewInfo->uMsg               = (Inherit ? Inherit->uMsg : 0);
00203 
00204     __try
00205     {
00206         InitializeCriticalSection( &NewInfo->SockCritSec );
00207     }
00208     __except( EXCEPTION_EXECUTE_HANDLER )
00209     {
00210         *lpErrno = WSAENOBUFS;
00211         goto cleanup;
00212     }
00213 
00214     if ( TRUE == Insert )
00215         InsertSocketInfo(Provider, NewInfo);
00216 
00217     return NewInfo;
00218 
00219 cleanup:
00220 
00221     if ( NULL != NewInfo )
00222         LspFree( NewInfo );
00223 
00224     return NULL;
00225 }

void DerefSocketContext ( SOCK_INFO context,
int *  err 
)

Definition at line 83 of file sockinfo.cpp.

00087 {
00088     LONG    newval;
00089     int     ret = NO_ERROR;
00090 
00091     EnterCriticalSection(&gCriticalSection);
00092 
00093     // Decrement the ref count and see if someone closed this socket (from another thread)
00094     newval = InterlockedDecrement(&context->RefCount);
00095     if ( ( 0 == newval ) && 
00096          ( 0 == context->dwOutstandingAsync ) && 
00097          ( TRUE == context->bClosing ) 
00098        )
00099     {
00100         ASSERT( gMainUpCallTable.lpWPUCloseSocketHandle );
00101 
00102         // Socket has been closed so close the handle and free associated resources
00103         ret = gMainUpCallTable.lpWPUCloseSocketHandle(context->LayeredSocket, lpErrno);
00104         if ( SOCKET_ERROR == ret )
00105         {
00106             dbgprint("DerefSocketContext: WPUCloseSocketHandle() failed: %d", *lpErrno);
00107         }
00108 
00109         context->LayeredSocket = INVALID_SOCKET;
00110 
00111         RemoveSocketInfo(context->Provider, context);
00112 
00113         dbgprint("Closing socket %d Bytes Sent [%lu] Bytes Recv [%lu]", 
00114                 context->LayeredSocket, context->BytesSent, context->BytesRecv);
00115 
00116         FreeSockInfo( context );
00117         context = NULL;
00118     }
00119 
00120     LeaveCriticalSection( &gCriticalSection );
00121 }

BOOL PASCAL FAR ExtAcceptEx ( IN SOCKET  sListenSocket,
IN SOCKET  sAcceptSocket,
IN PVOID  lpOutputBuffer,
IN DWORD  dwReceiveDataLength,
IN DWORD  dwLocalAddressLength,
IN DWORD  dwRemoteAddressLength,
OUT LPDWORD  lpdwBytesReceived,
IN LPOVERLAPPED  lpOverlapped 
)

Definition at line 221 of file extension.cpp.

00231 {
00232     LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
00233     SOCK_INFO          *ListenSocketContext = NULL,
00234                        *AcceptSocketContext = NULL;
00235     int                 Errno = 0,
00236                         ret = FALSE;
00237 
00238 
00239     //
00240     // Query the socket context for the listening socket
00241     //
00242     ListenSocketContext = FindAndRefSocketContext( sListenSocket, &Errno );
00243     if ( NULL == ListenSocketContext )
00244     {
00245         dbgprint( "ExtAcceptEx: FindAndRefSocketContext failed! (listen socket)" );
00246         goto cleanup;
00247     }
00248     //
00249     // Also need to query the socket context for the accept socket
00250     //
00251     AcceptSocketContext = FindAndRefSocketContext( sAcceptSocket, &Errno );
00252     if ( NULL == AcceptSocketContext )
00253     {
00254         dbgprint( "ExtAcceptEx: FindAndRefSocketContext failed! (accept socket)" );
00255         goto cleanup;
00256     }
00257 
00258     // Make sure we already have the extension function
00259     if ( NULL == ListenSocketContext->Provider->NextProcTableExt.lpfnAcceptEx )
00260     {
00261         GUID    guidAcceptEx = WSAID_ACCEPTEX;
00262 
00263         ret = LoadExtensionFunction(
00264                  (FARPROC **)&ListenSocketContext->Provider->NextProcTableExt.lpfnAcceptEx,
00265                  guidAcceptEx,
00266                  ListenSocketContext->Provider->NextProcTable.lpWSPIoctl,
00267                  ListenSocketContext->ProviderSocket
00268                  );
00269         if ( FALSE == ret )
00270         {
00271             dbgprint("Lower provider AcceptEx == NULL!");
00272             Errno = WSAEFAULT;
00273             goto cleanup;
00274         }
00275     }
00276 
00277     // Check for overlapped I/O
00278     if ( NULL != lpOverlapped )
00279     {
00280         ProviderOverlapped = PrepareOverlappedOperation(
00281                 ListenSocketContext,
00282                 LSP_OP_ACCEPTEX,
00283                 NULL,
00284                 0,
00285                 lpOverlapped,
00286                 NULL,
00287                 NULL,
00288                &Errno
00289                 );
00290         if ( NULL == ProviderOverlapped )
00291         {
00292             goto cleanup;
00293         }
00294 
00295         __try
00296         {
00297             // Save the arguments
00298             ProviderOverlapped->AcceptExArgs.dwBytesReceived       = (lpdwBytesReceived ? *lpdwBytesReceived : 0);
00299             ProviderOverlapped->AcceptExArgs.sAcceptSocket         = sAcceptSocket;
00300             ProviderOverlapped->AcceptExArgs.sProviderAcceptSocket = AcceptSocketContext->ProviderSocket;
00301             ProviderOverlapped->AcceptExArgs.lpOutputBuffer        = lpOutputBuffer;
00302             ProviderOverlapped->AcceptExArgs.dwReceiveDataLength   = dwReceiveDataLength;
00303             ProviderOverlapped->AcceptExArgs.dwLocalAddressLength  = dwLocalAddressLength;
00304             ProviderOverlapped->AcceptExArgs.dwRemoteAddressLength = dwRemoteAddressLength;
00305         }
00306         __except( EXCEPTION_EXECUTE_HANDLER )
00307         {
00308             Errno = WSAEFAULT;
00309             goto cleanup;
00310         }
00311 
00312         ret = QueueOverlappedOperation( ProviderOverlapped, ListenSocketContext );
00313         if ( NO_ERROR != ret )
00314         {
00315             Errno = ret;
00316             ret = FALSE;
00317         }
00318         else
00319         {
00320             ret = TRUE;
00321         }
00322     }
00323     else
00324     {
00325         ret = ListenSocketContext->Provider->NextProcTableExt.lpfnAcceptEx(
00326                 ListenSocketContext->ProviderSocket,
00327                 AcceptSocketContext->ProviderSocket,
00328                 lpOutputBuffer,
00329                 dwReceiveDataLength,
00330                 dwLocalAddressLength,
00331                 dwRemoteAddressLength,
00332                 lpdwBytesReceived,
00333                 NULL
00334                 );
00335         if ( FALSE == ret )
00336             Errno = WSAGetLastError();
00337     }
00338 
00339 cleanup:
00340 
00341     if ( NULL != ListenSocketContext )
00342         DerefSocketContext(ListenSocketContext, &Errno );
00343 
00344     if ( NULL != AcceptSocketContext )
00345         DerefSocketContext(AcceptSocketContext, &Errno );
00346 
00347     if ( FALSE == ret )
00348         WSASetLastError( Errno );
00349 
00350     return ret;
00351 }

BOOL PASCAL FAR ExtConnectEx ( IN SOCKET  s,
IN const struct sockaddr FAR *  name,
IN int  namelen,
IN PVOID lpSendBuffer  OPTIONAL,
IN DWORD  dwSendDataLength,
OUT LPDWORD  lpdwBytesSent,
IN LPOVERLAPPED  lpOverlapped 
)

Definition at line 362 of file extension.cpp.

00371 {
00372     SOCK_INFO           *SocketContext = NULL;
00373     LPWSAOVERLAPPEDPLUS  ProviderOverlapped = NULL;
00374     int                  Errno = NO_ERROR,
00375                          ret = FALSE;
00376 
00377     // Get the context
00378     SocketContext = FindAndRefSocketContext( s, &Errno );
00379     if ( NULL == SocketContext )
00380     {
00381         dbgprint( "ExtConnectEx: FindAndRefSocketContext failed!" );
00382         goto cleanup;
00383     }
00384 
00385     // Make sure we already have the extension function
00386     if ( NULL == SocketContext->Provider->NextProcTableExt.lpfnConnectEx )
00387     {
00388         GUID    guidConnectEx = WSAID_CONNECTEX;
00389 
00390         ret = LoadExtensionFunction(
00391                 (FARPROC **)&SocketContext->Provider->NextProcTableExt.lpfnConnectEx,
00392                 guidConnectEx,
00393                 SocketContext->Provider->NextProcTable.lpWSPIoctl,
00394                 SocketContext->ProviderSocket
00395                 );
00396         if ( FALSE == ret )
00397         {
00398             dbgprint("Next proc table ConnectEx == NULL!");
00399             Errno = WSAEFAULT;
00400             goto cleanup;
00401         }
00402     }
00403 
00404     // Check for overlapped I/O
00405     if ( NULL != lpOverlapped )
00406     {
00407         ProviderOverlapped = PrepareOverlappedOperation(
00408                 SocketContext,
00409                 LSP_OP_CONNECTEX,
00410                 NULL,
00411                 0,
00412                 lpOverlapped,
00413                 NULL,
00414                 NULL,
00415                &Errno
00416                 );
00417         if ( NULL == ProviderOverlapped )
00418         {
00419             dbgprint("ExtConnectEx: PrepareOverlappedOperation returned NULL");
00420             goto cleanup;
00421         }
00422 
00423         __try
00424         {
00425             ProviderOverlapped->ConnectExArgs.s                = s;
00426             ProviderOverlapped->ConnectExArgs.namelen          = namelen;
00427             ProviderOverlapped->ConnectExArgs.lpSendBuffer     = lpSendBuffer;
00428             ProviderOverlapped->ConnectExArgs.dwSendDataLength = dwSendDataLength;
00429             ProviderOverlapped->ConnectExArgs.dwBytesSent      = (lpdwBytesSent ? *lpdwBytesSent : 0);
00430             if ( namelen <= sizeof( ProviderOverlapped->ConnectExArgs.name ) )
00431                 CopyMemory( &ProviderOverlapped->ConnectExArgs.name, name, namelen );
00432         }
00433         __except( EXCEPTION_EXECUTE_HANDLER )
00434         {
00435             Errno = WSAEFAULT;
00436             goto cleanup;
00437         }
00438 
00439         ret = QueueOverlappedOperation( ProviderOverlapped, SocketContext );
00440         if ( NO_ERROR != ret )
00441         {
00442             Errno = ret;
00443             ret = FALSE;
00444         }
00445         else
00446         {
00447             ret = TRUE;
00448         }
00449     }
00450     else
00451     {
00452         ret = SocketContext->Provider->NextProcTableExt.lpfnConnectEx(
00453                 SocketContext->ProviderSocket,
00454                 name,
00455                 namelen,
00456                 lpSendBuffer,
00457                 dwSendDataLength,
00458                 lpdwBytesSent,
00459                 NULL
00460                 );
00461         if ( FALSE == ret )
00462             Errno = WSAGetLastError();
00463     }
00464 
00465 cleanup:
00466 
00467     if ( NULL != SocketContext )
00468         DerefSocketContext( SocketContext, &Errno );
00469 
00470     if ( FALSE == ret )
00471         WSASetLastError( Errno );
00472 
00473     return ret;
00474 }

BOOL PASCAL FAR ExtDisconnectEx ( IN SOCKET  s,
IN LPOVERLAPPED  lpOverlapped,
IN DWORD  dwFlags,
IN DWORD  dwReserved 
)

Definition at line 598 of file extension.cpp.

00604 {
00605     SOCK_INFO           *SocketContext = NULL;
00606     LPWSAOVERLAPPEDPLUS  ProviderOverlapped = NULL;
00607     int                  Errno = NO_ERROR,
00608                          ret = FALSE;
00609 
00610     // Get the context
00611     SocketContext = FindAndRefSocketContext( s, &Errno );
00612     if ( NULL == SocketContext )
00613     {
00614         dbgprint( "ExtDisconnectEx: FindAndRefSocketContext failed!" );
00615         goto cleanup;
00616     }
00617 
00618     // Make sure we already have the extension function
00619     if ( NULL == SocketContext->Provider->NextProcTableExt.lpfnDisconnectEx )
00620     {
00621         GUID    guidDisconnectEx = WSAID_DISCONNECTEX;
00622 
00623         ret = LoadExtensionFunction(
00624                  (FARPROC **)&SocketContext->Provider->NextProcTableExt.lpfnDisconnectEx,
00625                  guidDisconnectEx,
00626                  SocketContext->Provider->NextProcTable.lpWSPIoctl,
00627                  SocketContext->ProviderSocket
00628                  );
00629         if ( FALSE == ret )
00630         {
00631             dbgprint( "Next provider's DisconnectEx function is NULL!" );
00632             Errno = WSAEFAULT;
00633             goto cleanup;
00634         }
00635     }
00636 
00637     // Check for overlapped I/O
00638 
00639     if ( NULL != lpOverlapped )
00640     {
00641         ProviderOverlapped = PrepareOverlappedOperation(
00642                 SocketContext,
00643                 LSP_OP_DISCONNECTEX,
00644                 NULL,
00645                 0,
00646                 lpOverlapped,
00647                 NULL,
00648                 NULL,
00649                &Errno
00650                 );
00651         if ( NULL == ProviderOverlapped )
00652         {
00653             dbgprint("ExtDisconnectEx: PrepareOverlappedOperation returned NULL");
00654             goto cleanup;
00655         }
00656 
00657         ProviderOverlapped->DisconnectExArgs.s          = s;
00658         ProviderOverlapped->DisconnectExArgs.dwFlags    = dwFlags;
00659         ProviderOverlapped->DisconnectExArgs.dwReserved = dwReserved;
00660  
00661         ret = QueueOverlappedOperation( ProviderOverlapped, SocketContext );
00662         if ( NO_ERROR != ret )
00663         {
00664             Errno = ret;
00665             ret = FALSE;
00666         }
00667         else
00668         {
00669             ret = TRUE;
00670         }
00671     }
00672     else
00673     {
00674         ret = SocketContext->Provider->NextProcTableExt.lpfnDisconnectEx(
00675                 SocketContext->ProviderSocket,
00676                 lpOverlapped,
00677                 dwFlags,
00678                 dwReserved
00679                 );
00680         if ( FALSE == ret )
00681             Errno = WSAGetLastError();
00682     }
00683 
00684 cleanup:
00685 
00686     if ( NULL != SocketContext )
00687         DerefSocketContext( SocketContext, &Errno );
00688 
00689     if ( FALSE == ret )
00690         WSASetLastError( Errno );
00691 
00692     return ret;
00693 }

BOOL PASCAL FAR ExtTransmitFile ( IN SOCKET  hSocket,
IN HANDLE  hFile,
IN DWORD  nNumberOfBytesToWrite,
IN DWORD  nNumberOfBytesPerSend,
IN LPOVERLAPPED  lpOverlapped,
IN LPTRANSMIT_FILE_BUFFERS  lpTransmitBuffers,
IN DWORD  dwReserved 
)

Definition at line 106 of file extension.cpp.

00115 {
00116     SOCK_INFO          *SocketContext = NULL;
00117     LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
00118     int                 Errno = 0,
00119                         ret = FALSE;
00120 
00121     // Get the context
00122     SocketContext = FindAndRefSocketContext( hSocket, &Errno );
00123     if ( NULL == SocketContext )
00124     {
00125         dbgprint( "ExtTransmitFile: FindAndRefSocketContext failed!" );
00126         goto cleanup;
00127     }
00128 
00129     // Make sure we already have the extension function
00130     if ( NULL == SocketContext->Provider->NextProcTableExt.lpfnTransmitFile )
00131     {
00132         GUID    guidTransmitFile = WSAID_TRANSMITFILE;
00133 
00134         ret = LoadExtensionFunction(
00135                 (FARPROC **)&SocketContext->Provider->NextProcTableExt.lpfnTransmitFile,
00136                 guidTransmitFile,
00137                 SocketContext->Provider->NextProcTable.lpWSPIoctl,
00138                 SocketContext->ProviderSocket
00139                 );
00140         if ( FALSE == ret )
00141         {
00142             dbgprint( "Next provider's TransmitFile pointer is NULL!" );
00143             Errno = WSAEFAULT;
00144             goto cleanup;
00145         }   
00146     }
00147 
00148     //
00149     // Check for overlapped I/O
00150     //
00151     if ( NULL != lpOverlapped )
00152     {
00153         ProviderOverlapped = PrepareOverlappedOperation(
00154                 SocketContext,
00155                 LSP_OP_TRANSMITFILE,
00156                 NULL,
00157                 0,
00158                 lpOverlapped,
00159                 NULL,
00160                 NULL,
00161                &Errno
00162                 );
00163         if ( NULL == ProviderOverlapped )
00164         {
00165             goto cleanup;
00166         }
00167 
00168         // Save the arguments
00169         ProviderOverlapped->TransmitFileArgs.hFile                 = hFile;
00170         ProviderOverlapped->TransmitFileArgs.nNumberOfBytesToWrite = nNumberOfBytesToWrite;
00171         ProviderOverlapped->TransmitFileArgs.nNumberOfBytesPerSend = nNumberOfBytesPerSend;
00172         ProviderOverlapped->TransmitFileArgs.lpTransmitBuffers     = lpTransmitBuffers;
00173         ProviderOverlapped->TransmitFileArgs.dwFlags               = dwFlags;
00174 
00175         ret = QueueOverlappedOperation( ProviderOverlapped, SocketContext );
00176         if ( NO_ERROR != ret )
00177         {
00178             Errno = ret;
00179             ret = FALSE;
00180         }
00181         else
00182         {
00183             ret = TRUE;
00184         }
00185     }
00186     else
00187     {
00188         ret = SocketContext->Provider->NextProcTableExt.lpfnTransmitFile(
00189                 SocketContext->ProviderSocket,
00190                 hFile,
00191                 nNumberOfBytesToWrite,
00192                 nNumberOfBytesPerSend,
00193                 NULL,
00194                 lpTransmitBuffers,
00195                 dwFlags
00196                 );
00197         if ( FALSE == ret )
00198             Errno = WSAGetLastError();
00199     }
00200 
00201 cleanup:
00202 
00203     if ( NULL != SocketContext )
00204         DerefSocketContext(SocketContext, &Errno );
00205 
00206     if ( FALSE == ret )
00207         WSASetLastError( Errno );
00208 
00209     return ret;
00210 }

BOOL PASCAL FAR ExtTransmitPackets ( SOCKET  hSocket,
LPTRANSMIT_PACKETS_ELEMENT  lpPacketArray,
DWORD  nElementCount,
DWORD  nSendSize,
LPOVERLAPPED  lpOverlapped,
DWORD  dwFlags 
)

Definition at line 485 of file extension.cpp.

00492 {
00493     SOCK_INFO           *SocketContext = NULL;
00494     LPWSAOVERLAPPEDPLUS  ProviderOverlapped = NULL;
00495     int                  Errno = NO_ERROR,
00496                          ret = FALSE;
00497 
00498     // Get the context
00499     SocketContext = FindAndRefSocketContext( hSocket, &Errno );
00500     if ( NULL == SocketContext )
00501     {
00502         dbgprint( "ExtTransmitPackets: FindAndRefSocketContext failed!" );
00503         goto cleanup;
00504     }
00505 
00506     // Make sure we already have the extension function
00507     if ( NULL == SocketContext->Provider->NextProcTableExt.lpfnTransmitPackets )
00508     {
00509         GUID    guidTransmitPackets = WSAID_TRANSMITPACKETS;
00510 
00511         ret = LoadExtensionFunction(
00512                 (FARPROC **)&SocketContext->Provider->NextProcTableExt.lpfnTransmitPackets,
00513                 guidTransmitPackets,
00514                 SocketContext->Provider->NextProcTable.lpWSPIoctl,
00515                 SocketContext->ProviderSocket
00516                 );
00517         if ( FALSE == ret )
00518         {
00519             dbgprint( "Next provider's TransmitPackets function is NULL!" );
00520             Errno = WSAEFAULT;
00521             goto cleanup;
00522         }
00523     }
00524 
00525     //
00526     // Check for overlapped I/O
00527     //
00528     if ( NULL != lpOverlapped )
00529     {
00530         ProviderOverlapped = PrepareOverlappedOperation(
00531                 SocketContext,
00532                 LSP_OP_TRANSMITPACKETS,
00533                 NULL,
00534                 0,
00535                 lpOverlapped,
00536                 NULL,
00537                 NULL,
00538                &Errno
00539                 );
00540         if ( NULL == ProviderOverlapped )
00541         {
00542             dbgprint("ExtTransmitPackets: PrepareOverlappedOperation returned NULL");
00543             goto cleanup;
00544         }
00545         
00546         ProviderOverlapped->lpCallerCompletionRoutine         = NULL;
00547         ProviderOverlapped->TransmitPacketsArgs.s             = hSocket;
00548         ProviderOverlapped->TransmitPacketsArgs.lpPacketArray = lpPacketArray;
00549         ProviderOverlapped->TransmitPacketsArgs.nElementCount = nElementCount;
00550         ProviderOverlapped->TransmitPacketsArgs.nSendSize     = nSendSize;
00551         ProviderOverlapped->TransmitPacketsArgs.dwFlags       = dwFlags;
00552 
00553         ret = QueueOverlappedOperation( ProviderOverlapped, SocketContext );
00554         if ( NO_ERROR != ret )
00555         {
00556             Errno = ret;
00557             ret = FALSE;
00558         }
00559         else
00560         {
00561             ret = TRUE;
00562         }
00563     }
00564     else
00565     {
00566         ret = SocketContext->Provider->NextProcTableExt.lpfnTransmitPackets(
00567                 SocketContext->ProviderSocket,
00568                 lpPacketArray,
00569                 nElementCount,
00570                 nSendSize,
00571                 NULL,
00572                 dwFlags
00573                 );
00574         if ( FALSE == ret )
00575             Errno = WSAGetLastError();
00576     }
00577 
00578 cleanup:
00579 
00580     if ( NULL != SocketContext )
00581         DerefSocketContext( SocketContext, &Errno );
00582 
00583     if ( FALSE == ret )
00584         WSASetLastError( Errno );
00585 
00586     return ret;
00587 }

INT PASCAL FAR ExtWSARecvMsg ( IN SOCKET  s,
IN OUT LPWSAMSG  lpMsg,
OUT LPDWORD  lpdwNumberOfBytesRecvd,
IN LPWSAOVERLAPPED  lpOverlapped,
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine 
)

Definition at line 704 of file extension.cpp.

00711 {
00712     SOCK_INFO           *SocketContext = NULL;
00713     LPWSAOVERLAPPEDPLUS  ProviderOverlapped = NULL;
00714     int                  Errno = NO_ERROR,
00715                          ret = SOCKET_ERROR;
00716 
00717     // Get the context
00718     SocketContext = FindAndRefSocketContext( s, &Errno );
00719     if ( NULL == SocketContext )
00720     {
00721         dbgprint( "ExtWSARecvMsg: FindAndRefSocketContext failed!" );
00722         goto cleanup;
00723     }
00724 
00725     // Make sure we already have the extension function
00726     if ( NULL == SocketContext->Provider->NextProcTableExt.lpfnWSARecvMsg )
00727     {
00728         GUID    guidWSARecvMsg = WSAID_WSARECVMSG;
00729 
00730         ret = LoadExtensionFunction(
00731                 (FARPROC **)&SocketContext->Provider->NextProcTableExt.lpfnWSARecvMsg,
00732                 guidWSARecvMsg,
00733                 SocketContext->Provider->NextProcTable.lpWSPIoctl,
00734                 SocketContext->ProviderSocket
00735                 );
00736         if ( FALSE == ret )
00737         {
00738             dbgprint("Next proc table WSARecvMsg == NULL!");
00739             Errno = WSAEFAULT;
00740             goto cleanup;
00741         }
00742     }
00743 
00744     //
00745     // Check for overlapped I/O
00746     //
00747     if ( NULL != lpOverlapped )
00748     {
00749         ProviderOverlapped = PrepareOverlappedOperation(
00750                 SocketContext,
00751                 LSP_OP_WSARECVMSG,
00752                 NULL,
00753                 0,
00754                 lpOverlapped,
00755                 lpCompletionRoutine,
00756                 NULL,
00757                &Errno
00758                 );
00759         if ( NULL == ProviderOverlapped )
00760         {
00761             dbgprint("ExtWSARecvMsg: PrepareOverlappedOperation returned NULL");
00762             goto cleanup;
00763         }
00764 
00765         __try 
00766         {
00767             ProviderOverlapped->WSARecvMsgArgs.dwNumberOfBytesRecvd = (lpdwNumberOfBytesRecvd ? *lpdwNumberOfBytesRecvd : 0);
00768             ProviderOverlapped->WSARecvMsgArgs.s                    = s;
00769             ProviderOverlapped->WSARecvMsgArgs.lpMsg                = lpMsg;
00770         }
00771         __except( EXCEPTION_EXECUTE_HANDLER )
00772         {
00773             Errno = WSAEFAULT;
00774             goto cleanup;
00775         }
00776 
00777         ret = QueueOverlappedOperation( ProviderOverlapped, SocketContext );
00778         if ( NO_ERROR != ret )
00779         {
00780             Errno = ret;
00781             ret = SOCKET_ERROR;
00782         }
00783     }
00784     else
00785     {
00786         ASSERT( SocketContext->Provider->NextProcTableExt.lpfnWSARecvMsg );
00787 
00788         ret = SocketContext->Provider->NextProcTableExt.lpfnWSARecvMsg(
00789                 SocketContext->ProviderSocket,
00790                 lpMsg,
00791                 lpdwNumberOfBytesRecvd,
00792                 NULL,
00793                 NULL
00794                 );
00795         if ( SOCKET_ERROR == ret )
00796             Errno = WSAGetLastError();
00797     }
00798 
00799 cleanup:
00800 
00801     if ( NULL != SocketContext )
00802         DerefSocketContext( SocketContext, &Errno );
00803 
00804     if ( SOCKET_ERROR == ret )
00805         WSASetLastError( Errno );
00806 
00807     return ret;
00808 }

SOCK_INFO* FindAndRefSocketContext ( SOCKET  s,
int *  err 
)

Definition at line 40 of file sockinfo.cpp.

00044 {
00045     SOCK_INFO *SocketContext = NULL;
00046     int        ret;
00047 
00048     EnterCriticalSection(&gCriticalSection);
00049 
00050     ASSERT( gMainUpCallTable.lpWPUQuerySocketHandleContext );
00051 
00052     ret = gMainUpCallTable.lpWPUQuerySocketHandleContext(
00053             s,
00054             (PDWORD_PTR) &SocketContext,
00055             lpErrno
00056             );
00057     if ( SOCKET_ERROR == ret )
00058     {
00059         dbgprint("FindAndRefSocketContext: WPUQuerySocketHandleContext failed: %d", *lpErrno);
00060         *lpErrno = WSAENOTSOCK;
00061     }
00062     else
00063     {
00064         InterlockedIncrement(&SocketContext->RefCount);
00065     }
00066 
00067     LeaveCriticalSection(&gCriticalSection);
00068 
00069     return SocketContext;
00070 }

void FreeOverlappedLookasideList (  ) 

Definition at line 1545 of file overlap.cpp.

01547 {
01548     WSAOVERLAPPEDPLUS  *olp = NULL;
01549     LIST_ENTRY         *entry = NULL;
01550 
01551     EnterCriticalSection( &gOverlappedCS );
01552 
01553     while ( ! IsListEmpty( &gFreeOverlappedPlus ) )
01554     {
01555         entry = RemoveHeadList( &gFreeOverlappedPlus );
01556 
01557         olp = CONTAINING_RECORD( entry, WSAOVERLAPPEDPLUS, Link );
01558 
01559         LspFree( olp );
01560     }
01561 
01562     LeaveCriticalSection( &gOverlappedCS );
01563 }

void FreeSockInfo ( SOCK_INFO info  ) 

Definition at line 234 of file sockinfo.cpp.

00237 {
00238     DeleteCriticalSection( &info->SockCritSec );
00239     LspFree( info );
00240 
00241     return;
00242 }

void FreeWSABuf ( WSABUF *  BufferArray  ) 

Definition at line 3513 of file spi.cpp.

03516 {
03517     if ( ( NULL == gIocp ) && ( NULL != BufferArray ) )
03518     {
03519         // If we're on Win9x, the WSABUF array was copied so free it up now
03520 
03521         LspFree( BufferArray );
03522     }
03523 }

SOCK_INFO* GetCallerSocket ( PROVIDER provider,
SOCKET  ProviderSocket 
)

Definition at line 444 of file sockinfo.cpp.

00448 {
00449     SOCK_INFO *si = NULL;
00450 
00451     EnterCriticalSection( &gCriticalSection );
00452 
00453     if ( NULL != provider )
00454     {
00455         // If we know the provider just search its list of sockets
00456         si = FindSockInfoFromProviderSocket( provider, ProviderSock );
00457     }
00458     else
00459     {
00460         // Don't know the provider so we must search all of them
00461         for(INT i=0; i < gLayerCount ;i++)
00462         {
00463             si = FindSockInfoFromProviderSocket( &gBaseInfo[ i ], ProviderSock );
00464             if ( NULL != si )
00465                 break;
00466         }
00467     }
00468 
00469     LeaveCriticalSection( &gCriticalSection );
00470 
00471     return si;
00472 }

HWND GetWorkerWindow (  ) 

Definition at line 142 of file asyncselect.cpp.

00144 {
00145     HANDLE  ReadyEvent = NULL;
00146     int     rc;
00147 
00148     EnterCriticalSection( &gCriticalSection );
00149     if ( NULL == WorkerThreadHandle ) 
00150     {
00151         // Create an event which the worker thread will signal when its ready
00152         ReadyEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
00153         if ( NULL == ReadyEvent )
00154         {
00155             dbgprint("GetWorkerWindow: CreateEvent failed: %d", GetLastError() );
00156             goto cleanup;
00157         }
00158 
00159         // Create the asyn window message thread
00160         WorkerThreadHandle = CreateThread(
00161                 NULL, 
00162                 0, 
00163                 AsyncMsgHandler, 
00164                 (LPVOID)ReadyEvent, 
00165                 0, 
00166                 NULL
00167                 ); 
00168         if ( NULL == WorkerThreadHandle )
00169         {
00170             dbgprint( "GetWorkerWindow: CreateThread failed: %d", GetLastError() );
00171             goto cleanup;
00172         }
00173 
00174         // Wait for the window to become initialized
00175         rc = WaitForSingleObject( ReadyEvent, INFINITE );
00176         if ( ( WAIT_FAILED == rc ) || ( WAIT_TIMEOUT == rc ) )
00177             dbgprint( "GetWorkerWindow: WaitForSingleObject failed: %d! (error = %d)", 
00178                     rc, GetLastError() );
00179     }
00180 
00181 cleanup:
00182 
00183     if ( NULL != ReadyEvent )
00184     {
00185         // Close the ready event
00186         rc = CloseHandle( ReadyEvent );
00187         if ( 0 == rc )
00188         {
00189             dbgprint("GetWorkerWindow: CloseHandle failed: %d", GetLastError() );
00190         }
00191     }
00192 
00193     LeaveCriticalSection( &gCriticalSection );
00194 
00195     return AsyncWindow;
00196 }

int InitOverlappedManager (  ) 

Definition at line 127 of file overlap.cpp.

00129 {
00130     DWORD   i;
00131     int     ret = NO_ERROR;
00132 
00133     EnterCriticalSection( &gOverlappedCS );
00134 
00135     //
00136     // Make sure we're not already initialized -- we'll always have at least
00137     // one worker thread running
00138     //
00139     if ( NULL != gWorkerThread )
00140         goto cleanup;
00141 
00142     InitializeListHead( &gFreeOverlappedPlus );
00143     InitializeListHead( &gPendingOperations );
00144 
00145     //
00146     // See if we're on NT by trying to create the completion port. If it
00147     //  fails then we're on Win9x.
00148     //
00149     gIocp = CreateIoCompletionPort(
00150             INVALID_HANDLE_VALUE,
00151             NULL,
00152             (ULONG_PTR)0,
00153             0
00154             );
00155     if ( NULL != gIocp )
00156     {
00157         SYSTEM_INFO     sinfo;
00158 
00159         //
00160         // We're on NT so figure out how many processors we have
00161         //
00162         GetSystemInfo( &sinfo );
00163         gThreadCount = sinfo.dwNumberOfProcessors;
00164     }
00165     else
00166     {
00167         //
00168         // We're on Win9x so create a semaphore instead. This is used to
00169         //  wake up the worker thread to service overlapped IO calls.
00170         //
00171         gWakeupSemaphore = CreateSemaphore(
00172                 NULL,
00173                 0,
00174                 MAXLONG,
00175                 NULL
00176                 );
00177         if ( NULL == gWakeupSemaphore )
00178         {
00179             dbgprint("InitOverlappedManager: CreateSemaphore() failed: %d", GetLastError());
00180             ret = WSAEPROVIDERFAILEDINIT;
00181             goto cleanup;
00182         }
00183 
00184         //
00185         // This is Win9x, no multiproc support so create just a single thread
00186         //
00187         gThreadCount = 1;
00188     }
00189 
00190     dbgprint("Creating %d threads", gThreadCount);
00191 
00192     gWorkerThread = (HANDLE *) LspAlloc(
00193             sizeof( HANDLE ) * gThreadCount,
00194            &ret         // if fails, ret will be WSAENOBUFS
00195             );
00196     if ( NULL == gWorkerThread )
00197     {
00198         goto cleanup;
00199     }
00200 
00201     //
00202     // Create our worker threads
00203     //
00204     for(i=0; i < gThreadCount ;i++)
00205     {
00206         gWorkerThread[i] = CreateThread(
00207                 NULL, 
00208                 0, 
00209                 OverlappedManagerThread, 
00210                 (LPVOID)gIocp, 
00211                 0, 
00212                 NULL
00213                 );
00214         if ( NULL == gWorkerThread[ i ] )
00215         {
00216             dbgprint("InitOverlappedManager: CreateThread() failed: %d", GetLastError());
00217             ret = WSAEPROVIDERFAILEDINIT;
00218             goto cleanup;
00219         }
00220     }
00221 
00222 cleanup:
00223 
00224     LeaveCriticalSection( &gOverlappedCS );
00225 
00226     return ret;
00227 }

void InsertSocketInfo ( PROVIDER provider,
SOCK_INFO sock 
)

Definition at line 253 of file sockinfo.cpp.

00257 {
00258     if ( ( NULL == provider ) || ( NULL == sock ) )
00259     {
00260         dbgprint("InsertSocketInfo: PROVIDER or SOCK_INFO == NULL!");
00261         goto cleanup;
00262     }
00263 
00264     EnterCriticalSection( &provider->ProviderCritSec );
00265 
00266     InsertTailList( &provider->SocketList, &sock->Link );
00267 
00268     LeaveCriticalSection( &provider->ProviderCritSec );
00269 
00270     SetEvent( gAddContextEvent );
00271 
00272 cleanup:
00273 
00274     return;
00275 }

void CALLBACK IntermediateCompletionRoutine ( DWORD  dwError,
DWORD  cbTransferred,
LPWSAOVERLAPPED  lpOverlapped,
DWORD  dwFlags 
)

Definition at line 1033 of file overlap.cpp.

01039 {
01040     LPWSAOVERLAPPEDPLUS olp = NULL;
01041     SOCK_INFO          *SocketContext = NULL,
01042                        *AcceptSocketContext = NULL;
01043     int                 Error,
01044                         ret;
01045 
01046     if ( NULL == lpOverlapped )
01047     {
01048         dbgprint("IntermediateCompletionRoutine: lpOverlapped == NULL!");
01049         goto cleanup;
01050     }
01051 
01052     ASSERT( lpOverlapped );
01053 
01054     olp = CONTAINING_RECORD( lpOverlapped, WSAOVERLAPPEDPLUS, ProviderOverlapped );
01055 
01056     //
01057     // We actually already have the socket context for this operation (its in
01058     //    the WSAOVERLAPPEDPLUS structure but do this anyway to make sure the
01059     //    socket hasn't been closed as well as to increment the ref count while
01060     //    we're accessing the SOCK_INFO structure.
01061     //
01062     SocketContext = FindAndRefSocketContext(olp->CallerSocket, &Error);
01063     if ( NULL == SocketContext )
01064     {
01065         dbgprint( "IntermediateCompletionRoutine: FindAndRefSocketContext failed!" );
01066         goto cleanup;
01067     }
01068 
01069     if ( WSA_IO_PENDING == dwError )
01070     {
01071         //
01072         // Get the results of the operation
01073         //
01074 
01075         ASSERT( olp->Provider );
01076         ASSERT( olp->Provider->NextProcTable.lpWSPGetOverlappedResult );
01077 
01078         dwError = NO_ERROR;
01079         ret = olp->Provider->NextProcTable.lpWSPGetOverlappedResult(
01080                 olp->ProviderSocket,
01081                 lpOverlapped,
01082                &cbTransferred,
01083                 FALSE,
01084                &dwFlags,
01085                 (int *)&dwError
01086                 );
01087  
01088         if ( FALSE == ret )
01089         {
01090             dbgprint("IntermediateCompletionRoutine: WSPGetOverlappedResult failed: %d", dwError);
01091         }
01092         else
01093         {
01094 
01095             dbgprint("Bytes transferred on socket 0x%x: %d [op=%d; err=%d]", 
01096                     olp->CallerSocket, cbTransferred, olp->Operation, dwError);
01097         }
01098     }
01099 
01100     olp->lpCallerOverlapped->Offset       = dwFlags;
01101     olp->lpCallerOverlapped->OffsetHigh   = dwError;
01102     olp->lpCallerOverlapped->InternalHigh = cbTransferred;
01103 
01104     SocketContext->LastError = dwError;
01105 
01106     if ( 0 == dwError )
01107     {
01108         AcquireSocketLock( SocketContext );
01109 
01110         //
01111         // NOTE: This is where any post processing should go for overlapped operations.
01112         //       For example, if you wanted to inspect the data received, you would do
01113         //       that here for any operation that receives data (don't forget AcceptEx!).
01114         //       In this sample, all we do is count the bytes sent and received on the
01115         //       socket.
01116         //
01117 
01118         switch ( olp->Operation )
01119         {
01120             case LSP_OP_RECV:
01121                 SocketContext->BytesRecv += cbTransferred;
01122                 FreeWSABuf(olp->RecvArgs.lpBuffers);
01123                 break;
01124 
01125             case LSP_OP_RECVFROM:
01126                 SocketContext->BytesRecv += cbTransferred;
01127                 FreeWSABuf(olp->RecvFromArgs.lpBuffers);
01128                 break;
01129 
01130             case LSP_OP_SEND:
01131                 SocketContext->BytesSent += cbTransferred;
01132                 FreeWSABuf(olp->SendArgs.lpBuffers);
01133                 break;
01134 
01135             case LSP_OP_SENDTO:
01136                 SocketContext->BytesSent += cbTransferred;
01137                 FreeWSABuf(olp->SendToArgs.lpBuffers);
01138                 break;
01139 
01140             case LSP_OP_TRANSMITFILE:
01141                 SocketContext->BytesSent += cbTransferred;
01142                 break;
01143 
01144             case LSP_OP_TRANSMITPACKETS:
01145                 SocketContext->BytesSent += cbTransferred;
01146                 break;
01147 
01148             case LSP_OP_ACCEPTEX:
01149 
01150                 ReleaseSocketLock( SocketContext );
01151 
01152                 AcceptSocketContext = FindAndRefSocketContext(
01153                         olp->AcceptExArgs.sAcceptSocket,
01154                        &Error
01155                        );
01156                 if (AcceptSocketContext == NULL)
01157                 {
01158                     dbgprint( "IntermediateCompletionRoutine: FindAndRefSocketContext failed! (LSP_OP_ACCEPTEX)" );
01159                 }
01160                 AcquireSocketLock( AcceptSocketContext );
01161 
01162                 AcceptSocketContext->BytesRecv += cbTransferred;
01163 
01164                 ReleaseSocketLock( AcceptSocketContext );
01165 
01166                 DerefSocketContext(AcceptSocketContext, &Error);
01167 
01168                 break;
01169 
01170             case LSP_OP_CONNECTEX:
01171                 SocketContext->BytesSent += cbTransferred;
01172                 break;
01173 
01174             case LSP_OP_WSARECVMSG:
01175                 SocketContext->BytesRecv += cbTransferred;
01176                 break;
01177 
01178             default:
01179                 break;
01180         }
01181         // Already released for AcceptEx operations
01182         if ( LSP_OP_ACCEPTEX != olp->Operation )
01183             ReleaseSocketLock( SocketContext );
01184     }
01185 
01186     DerefSocketContext( SocketContext, &Error );
01187 
01188     if ( NULL != olp->lpCallerCompletionRoutine )
01189     {
01190         //
01191         // If the app supplied a completion routine, queue it up for completion
01192         //
01193         olp->lpCallerOverlapped->Internal = (ULONG_PTR)olp->lpCallerCompletionRoutine;
01194 
01195         ret = gMainUpCallTable.lpWPUQueueApc(
01196                &olp->CallerThreadId,
01197                CallUserApcProc,
01198                (DWORD_PTR) olp->lpCallerOverlapped,
01199               &Error
01200                );
01201         if ( SOCKET_ERROR == ret )
01202         {
01203             dbgprint("IntermediateCompletionRoutine: WPUQueueApc() failed: %d", Error);
01204         }
01205     }
01206     else
01207     {
01208         //
01209         // Otherwise we signal that the op has completed
01210         //
01211         ret = WPUCompleteOverlappedRequest(
01212                 olp->CallerSocket,
01213                 olp->lpCallerOverlapped,
01214                 dwError,
01215                 cbTransferred,
01216                &Error
01217                 );
01218         if ( SOCKET_ERROR == ret )
01219         {
01220             dbgprint("WPUCompleteOverlappedRequest failed: %d (provider socket 0x%x)", 
01221                     Error, olp->CallerSocket );
01222         }
01223     }
01224 
01225     if ( ( NULL != olp ) && ( TRUE == olp->CloseThread ) )
01226     {
01227         ret = gMainUpCallTable.lpWPUCloseThread( &olp->CallerThreadId, &Error );
01228         if ( SOCKET_ERROR == ret )
01229         {
01230             dbgprint("WPUCloseThread failed: %d", Error );
01231         }
01232         olp->CloseThread = FALSE;
01233     }
01234 
01235     //
01236     // Cleanup the accounting on the socket
01237     //
01238     CheckForContextCleanup( olp );
01239 
01240 cleanup:
01241 
01242     if ( NULL != olp )
01243         FreeOverlappedStructure( olp );
01244 
01245     return;
01246 }

BOOL LoadExtensionFunction ( FARPROC **  func,
GUID  ExtensionGuid,
LPWSPIOCTL  fnIoctl,
SOCKET  s 
)

Definition at line 38 of file extension.cpp.

00044 {
00045     DWORD   dwBytes;
00046     int     rc, 
00047             error,
00048             ret = TRUE;
00049 
00050     // Use the lower provider's WSPIoctl to load the extension function
00051     rc = fnIoctl(
00052             s,
00053             SIO_GET_EXTENSION_FUNCTION_POINTER,
00054            &ExtensionGuid,
00055             sizeof(GUID),
00056             func,
00057             sizeof(FARPROC),
00058            &dwBytes,
00059             NULL,
00060             NULL,
00061             NULL,
00062            &error
00063             );
00064     
00065 
00066     if ( SOCKET_ERROR == rc )
00067     {
00068         dbgprint("LoadExtensionFunction: WSAIoctl (SIO_GET_EXTENSION_FUNCTION) failed: %d",
00069             error);
00070         ret = FALSE;
00071     }
00072     else if( NULL == *func )
00073     {
00074         // Some providers won't throw an error even when
00075         // they return a NULL function pointer    
00076 
00077         dbgprint("LoadExtensionFunction: WSAIoctl (SIO_GET_EXTENSION_FUNCTION) returned a NULL"
00078                     " function pointer");
00079         ret = FALSE;
00080     }
00081 
00082     return ret;
00083 }

WSAOVERLAPPEDPLUS* PrepareOverlappedOperation ( SOCK_INFO SocketContext,
LspOperation  operation,
WSABUF *  lpBuffers,
DWORD  dwBufferCount,
LPWSAOVERLAPPED  lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine,
LPWSATHREADID  lpThreadId,
int *  lpErrno 
)

Definition at line 1361 of file overlap.cpp.

01371 {
01372     WSAOVERLAPPEDPLUS *ProviderOverlapped = NULL;
01373     int                ret = SOCKET_ERROR,
01374                        err = 0;
01375 
01376     // Allocate a WSAOVERLAPPEDPLUS structure
01377     ProviderOverlapped = AllocOverlappedStructure( SocketContext );
01378     if ( NULL == ProviderOverlapped )
01379     {
01380         *lpErrno = WSAENOBUFS;
01381         goto cleanup;
01382     }
01383 
01384     __try 
01385     {
01386         // Check for an event and reset if. Also, copy the offsets from the upper
01387         // layer's WSAOVERLAPPED structure.
01388         if ( ( NULL == lpCompletionRoutine ) && 
01389              ( NULL != lpOverlapped->hEvent ) )
01390         { 
01391             ULONG_PTR   ptr = 1;
01392 
01393             ret = ResetEvent( (HANDLE) ( (ULONG_PTR) lpOverlapped->hEvent & ~ptr ) );
01394             if (ret == 0)
01395             {
01396                 *lpErrno = ERROR_INVALID_HANDLE;
01397                 ret = SOCKET_ERROR;
01398                 goto cleanup;
01399             }
01400         }
01401 
01402         // Copy any offset information from the caller's overlapped to ours
01403         CopyOffset( &ProviderOverlapped->ProviderOverlapped, lpOverlapped );
01404 
01405     }
01406     __except(EXCEPTION_EXECUTE_HANDLER)
01407     {
01408         *lpErrno = WSAEFAULT;
01409         goto cleanup;
01410     }
01411 
01412     if ( NULL != lpThreadId )
01413     {
01414         ProviderOverlapped->CallerThreadId = *lpThreadId;
01415     }
01416     else
01417     {
01418         // If thread info wasn't passed to us, we need to open the thread context
01419         ret = gMainUpCallTable.lpWPUOpenCurrentThread( &ProviderOverlapped->CallerThreadId, &err );
01420         if ( SOCKET_ERROR == ret )
01421         {
01422             dbgprint("WPUOpenCurrentThread failed: %d", err);
01423         }
01424         else
01425         {
01426             // Need to remember for later to close the context since we opened it
01427             ProviderOverlapped->CloseThread = TRUE;
01428         }
01429     }
01430 
01431     // Fill in the remaining fields
01432     ProviderOverlapped->Provider           = SocketContext->Provider;
01433     ProviderOverlapped->lpCallerOverlapped = lpOverlapped;
01434     ProviderOverlapped->lpCallerCompletionRoutine = lpCompletionRoutine;
01435     ProviderOverlapped->SockInfo           = SocketContext;
01436     ProviderOverlapped->CallerSocket       = SocketContext->LayeredSocket;
01437     ProviderOverlapped->ProviderSocket     = SocketContext->ProviderSocket;
01438     ProviderOverlapped->Error              = NO_ERROR;
01439     ProviderOverlapped->Operation          = operation;
01440 
01441     if ( ( NULL != lpBuffers) && ( dwBufferCount ) )
01442     {
01443         // Depending on the underlying operation, copy some parameters specific to it
01444         switch ( operation )
01445         {
01446             case LSP_OP_RECV:
01447                 ProviderOverlapped->RecvArgs.dwBufferCount = dwBufferCount;
01448                 ProviderOverlapped->RecvArgs.lpBuffers = CopyWSABuf(
01449                         lpBuffers,
01450                         dwBufferCount,
01451                         lpErrno
01452                         );
01453                 if ( NULL == ProviderOverlapped->RecvArgs.lpBuffers )
01454                     goto cleanup;
01455 
01456                 break;
01457 
01458             case LSP_OP_RECVFROM:
01459                 ProviderOverlapped->RecvFromArgs.dwBufferCount = dwBufferCount;
01460                 ProviderOverlapped->RecvFromArgs.lpBuffers = CopyWSABuf(
01461                         lpBuffers,
01462                         dwBufferCount,
01463                         lpErrno
01464                         );
01465                 if ( NULL == ProviderOverlapped->RecvFromArgs.lpBuffers )
01466                     goto cleanup;
01467 
01468                 break;
01469 
01470             case LSP_OP_SEND:
01471                 ProviderOverlapped->SendArgs.dwBufferCount = dwBufferCount;
01472                 ProviderOverlapped->SendArgs.lpBuffers = CopyWSABuf(
01473                         lpBuffers,
01474                         dwBufferCount,
01475                         lpErrno
01476                         );
01477                 if ( NULL == ProviderOverlapped->SendArgs.lpBuffers )
01478                     goto cleanup;
01479 
01480                 break;
01481               
01482             case LSP_OP_SENDTO:
01483                 ProviderOverlapped->SendToArgs.dwBufferCount = dwBufferCount;
01484                 ProviderOverlapped->SendToArgs.lpBuffers = CopyWSABuf(
01485                         lpBuffers,
01486                         dwBufferCount,
01487                         lpErrno
01488                         );
01489                 if ( NULL == ProviderOverlapped->SendToArgs.lpBuffers )
01490                     goto cleanup;
01491 
01492                 break;
01493 
01494             default:
01495                 break;
01496         }
01497     }
01498 
01499     ret = NO_ERROR;
01500 
01501 cleanup:
01502 
01503     if ( SOCKET_ERROR == ret )
01504     {
01505         UndoOverlappedOperation( SocketContext, ProviderOverlapped );
01506         ProviderOverlapped = NULL;
01507     }
01508     else
01509     {
01510         ASSERT( NO_ERROR == ret );
01511     }
01512 
01513     return ProviderOverlapped;
01514 }

int QueueOverlappedOperation ( WSAOVERLAPPEDPLUS lpOverlapped,
SOCK_INFO Context 
)

Definition at line 344 of file overlap.cpp.

00348 {
00349     BOOL    bSynchronous = FALSE;
00350     int     err;
00351 
00352     //
00353     // Set the fields of the overlapped to indicate IO is not complete yet
00354     //
00355 
00356     __try
00357     {
00358         SetOverlappedInProgress( ol->lpCallerOverlapped );
00359     } 
00360     __except( EXCEPTION_EXECUTE_HANDLER )
00361     {
00362         return WSAEFAULT;
00363     }
00364 
00365     if ( NULL != gIocp )
00366     {
00367         //
00368         // If we haven't already added the provider socket to the IOCP then
00369         //  do it now.
00370         //
00371         AcquireSocketLock( SocketContext );
00372 
00373         if ( NULL == SocketContext->hIocp )
00374         {
00375             SocketContext->hIocp = CreateIoCompletionPort(
00376                     (HANDLE)ol->ProviderSocket,
00377                     gIocp,
00378                     ol->CallerSocket,
00379                     0
00380                     );
00381             if ( NULL == SocketContext->hIocp )
00382             {
00383                 if ( ERROR_INVALID_PARAMETER == (err = GetLastError() ) )
00384                 {
00385                     //
00386                     // If the socket option SO_SYNCHRONOUS_(NON)ALERT is set then 
00387                     // no overlapped operation can be performed on that socket and 
00388                     // tryiing to associate it with a completion port will fail. 
00389                     // The other bad news is that an LSP cannot trap this setsockopt 
00390                     // call. In reality we don't have to do anything. If an app sets 
00391                     // this option and then makes overlapped calls anyway, then they 
00392                     // shouldn't be expecting any overlapped notifications! This 
00393                     // statement is put here in case you want to mark the socket
00394                     // info structure as synchronous.
00395                     //
00396                     bSynchronous = TRUE;
00397                 }
00398                 else
00399                 {
00400                     dbgprint("QueueOverlappedOperation: CreateIoCompletionPort() "
00401                               "failed: %d (Prov %d Iocp 0x%x Caller 0x%x 0)", 
00402                             err, ol->ProviderSocket, 
00403                             gIocp, ol->CallerSocket);
00404                 }
00405             }
00406 
00407             dbgprint("Adding provider handle %X to IOCP", ol->ProviderSocket);
00408         }
00409 
00410         ReleaseSocketLock( SocketContext );
00411 
00412         //
00413         // Simply execute the operation
00414         //
00415         return ExecuteOverlappedOperation( ol, bSynchronous );
00416     }
00417     else
00418     {
00419         // Queue up the operation for the worker thread to initiate
00420         //
00421         return EnqueueOverlappedOperation( ol );
00422     }
00423 }

void ReleaseSocketLock ( SOCK_INFO SockInfo  ) 

Definition at line 147 of file sockinfo.cpp.

00150 {
00151     LeaveCriticalSection( &SockInfo->SockCritSec );
00152 }

void RemoveSocketInfo ( PROVIDER provider,
SOCK_INFO sock 
)

Definition at line 286 of file sockinfo.cpp.

00290 {
00291     EnterCriticalSection( &provider->ProviderCritSec );
00292 
00293     RemoveEntryList( &si->Link );
00294 
00295     LeaveCriticalSection( &provider->ProviderCritSec );
00296 
00297     return;
00298 }

int StopAsyncWindowManager (  ) 

Definition at line 96 of file asyncselect.cpp.

00098 {
00099     int     rc,
00100             code;
00101 
00102     if ( NULL != AsyncWindow )
00103     {
00104         // Post a quit message to the thread
00105         PostMessage( AsyncWindow, WM_DESTROY, 0, 0 );
00106 
00107         // Wait for the thread to cleanup and exit
00108         rc = WaitForSingleObject( WorkerThreadHandle, 10000 );
00109         if ( WAIT_TIMEOUT == rc )
00110         {
00111             dbgprint("StopAsyncWindowManager: Timed out waiting for async thread!");
00112             goto cleanup;
00113         }
00114 
00115         // Retrieve the exit code and display a simple message
00116         rc = GetExitCodeThread( WorkerThreadHandle, (LPDWORD) &code );
00117         if ( 0 == rc )
00118             dbgprint("StopAsyncWindowManager: Unable to retrieve thread exit code: %d",
00119                     GetLastError() );
00120         else if ( 0 != code )
00121             dbgprint("StopAsyncWindowManager: Async window thread exited abnormally!");
00122 
00123 cleanup:
00124 
00125         CloseHandle( WorkerThreadHandle );
00126 
00127         WorkerThreadHandle = NULL;
00128     }
00129 
00130     return 0;
00131 }

int StopOverlappedManager (  ) 

Definition at line 238 of file overlap.cpp.

00240 {
00241     DWORD     i;
00242     int       ret = NO_ERROR;
00243 
00244     EnterCriticalSection( &gOverlappedCS );
00245 
00246     //
00247     // Post a completion packet to the IOCP (one for each thread)
00248     //
00249     if ( NULL != gIocp )
00250     {
00251         for(i=0; i < gThreadCount ;i++)
00252         {
00253             ret = PostQueuedCompletionStatus(
00254                     gIocp,
00255                     (DWORD)-1,
00256                     0,
00257                     NULL
00258                     );
00259             if ( 0 == ret )
00260             {
00261                 dbgprint("PostQueuedCompletionStatus() failed: %d", GetLastError());
00262             }
00263         }
00264 
00265         //
00266         // Wait a while for the threads to get the signal and exit - if it fails or
00267         // times out then oh well, we need to clean up anyway
00268         //
00269     }
00270     else
00271     {
00272         //
00273         // On Win9x we closed the semaphore so the worker thread should fail
00274         // when waiting for a signal and break out of the loop.
00275         // 
00276 
00277         LIST_ENTRY         *entry = NULL;
00278         WSAOVERLAPPEDPLUS  *olp = NULL;
00279 
00280         while ( !IsListEmpty( &gPendingOperations ) )
00281         {
00282             entry = RemoveHeadList( &gPendingOperations );
00283 
00284             olp = CONTAINING_RECORD( entry, WSAOVERLAPPEDPLUS, Link );
00285 
00286             FreeOverlappedStructure( olp );
00287         }
00288     }
00289 
00290     if ( NULL != gWorkerThread )
00291     {
00292         ret = WaitForMultipleObjectsEx( gThreadCount, gWorkerThread, TRUE, 5000, TRUE );
00293         if ( WAIT_TIMEOUT == ret )
00294             dbgprint("StopOverlappedManager: Timed out waiting for IOCP threads to exit!");
00295         else if ( WAIT_FAILED == ret )
00296             dbgprint("StopOverlappedManager: WaitForMultipleObjectsEx failed: %d",
00297                     GetLastError());
00298         else
00299             dbgprint("StopOverlappedManager: All worker threads stopped!");
00300 
00301         for(i=0; i < gThreadCount ;i++)
00302         {
00303             CloseHandle( gWorkerThread[ i ] );
00304             gWorkerThread[ i ] = NULL;
00305 
00306             dbgprint("Closing overlapped thread(s)");
00307         }
00308 
00309         LspFree( gWorkerThread );
00310         gWorkerThread = NULL;
00311     }
00312 
00313     //
00314     // Cleanup remaining handles...
00315     //
00316     if ( NULL != gIocp )
00317     {
00318         CloseHandle( gIocp );
00319         gIocp = NULL;
00320     }
00321 
00322     if ( NULL != gWakeupSemaphore )
00323     {
00324         CloseHandle( gWakeupSemaphore );
00325         gWakeupSemaphore = NULL;
00326     }
00327 
00328     LeaveCriticalSection( &gOverlappedCS );
00329 
00330     return ret;
00331 }

void UndoOverlappedOperation ( SOCK_INFO SocketContext,
WSAOVERLAPPEDPLUS ProviderOverlapped 
)

Definition at line 1525 of file overlap.cpp.

01529 {
01530     AcquireSocketLock( SocketContext );
01531     (SocketContext->dwOutstandingAsync)--;
01532     ReleaseSocketLock( SocketContext );
01533 
01534     FreeOverlappedStructure( ProviderOverlapped );
01535 }

SOCKET WSPAPI WSPAccept ( SOCKET  s,
struct sockaddr FAR *  addr,
LPINT  addrlen,
LPCONDITIONPROC  lpfnCondition,
DWORD_PTR  dwCallbackData,
LPINT  lpErrno 
)

Definition at line 258 of file spi.cpp.

00266 {
00267     SOCKET     NewProviderSocket;
00268     SOCKET     NewSocket = INVALID_SOCKET;
00269     SOCK_INFO *NewSocketContext = NULL;
00270     SOCK_INFO *SocketContext = NULL;
00271 
00272     //
00273     // Query for our per socket info
00274     //
00275     SocketContext = FindAndRefSocketContext(s, lpErrno);
00276     if ( NULL == SocketContext )
00277     {
00278         dbgprint( "WSPAccept: FindAndRefSocketContext failed!" );
00279         goto cleanup;
00280     }
00281 
00282     //
00283     // Note: You can subsitute your own conditional accept callback function
00284     //       in order to intercept this callback. You would have to keep track
00285     //       of the user's callback function so that you can call that when
00286     //       your intermediate function executes.
00287     //
00288 
00289     ASSERT( SocketContext->Provider->NextProcTable.lpWSPAccept );
00290 
00291     SetBlockingProvider(SocketContext->Provider);
00292     NewProviderSocket = SocketContext->Provider->NextProcTable.lpWSPAccept(
00293                             SocketContext->ProviderSocket, 
00294                             addr, 
00295                             addrlen,
00296                             lpfnCondition, 
00297                             dwCallbackData, 
00298                             lpErrno);
00299     SetBlockingProvider(NULL);
00300     if ( INVALID_SOCKET != NewProviderSocket )
00301     {
00302         // The underlying provider received a new connection so lets create our own
00303         //  socket to pass back up to the application.
00304         //
00305         NewSocketContext = CreateSockInfo(
00306                 SocketContext->Provider,
00307                 NewProviderSocket,
00308                 SocketContext,
00309                 FALSE,
00310                 lpErrno
00311                 );
00312         if  ( NULL == NewSocketContext )
00313         {
00314             goto cleanup;
00315         }
00316         
00317         NewSocket = NewSocketContext->LayeredSocket = gMainUpCallTable.lpWPUCreateSocketHandle(
00318                 SocketContext->Provider->LayerProvider.dwCatalogEntryId,
00319                 (DWORD_PTR) NewSocketContext,
00320                 lpErrno);
00321         if ( INVALID_SOCKET == NewSocket )
00322         {
00323             int     tempErr;
00324 
00325             dbgprint("WSPAccept(): WPUCreateSocketHandle() failed: %d", *lpErrno);
00326             
00327             // Close the lower provider's socket but preserve the original error value
00328             SocketContext->Provider->NextProcTable.lpWSPCloseSocket(
00329                 NewProviderSocket,
00330                &tempErr
00331                 );
00332 
00333             // Context is not in the list yet so we can just free it
00334             FreeSockInfo(NewSocketContext);
00335         }
00336         else
00337         {
00338             InsertSocketInfo(SocketContext->Provider, NewSocketContext);
00339         }
00340     }
00341 
00342 cleanup:
00343 
00344     if ( NULL != SocketContext )
00345         DerefSocketContext( SocketContext, lpErrno );
00346 
00347     return NewSocket;
00348 }

int WSPAPI WSPAddressToString ( LPSOCKADDR  lpsaAddress,
DWORD  dwAddressLength,
LPWSAPROTOCOL_INFOW  lpProtocolInfo,
LPWSTR  lpszAddressString,
LPDWORD  lpdwAddressStringLength,
LPINT  lpErrno 
)

Definition at line 357 of file spi.cpp.

00365 {
00366     WSAPROTOCOL_INFOW *pInfo=NULL;
00367     PROVIDER          *Provider=NULL;
00368     INT                ret = SOCKET_ERROR,
00369                        i;
00370 
00371     //
00372     // First find the appropriate provider
00373     //
00374     for(i=0; i < gLayerCount ;i++)
00375     {
00376         if ((gBaseInfo[i].NextProvider.iAddressFamily == lpProtocolInfo->iAddressFamily) &&
00377             (gBaseInfo[i].NextProvider.iSocketType == lpProtocolInfo->iSocketType) && 
00378             (gBaseInfo[i].NextProvider.iProtocol   == lpProtocolInfo->iProtocol))
00379         {
00380             if ( NULL != lpProtocolInfo )
00381             {
00382                 // In case of multiple providers check the provider flags 
00383                 if ( ( gBaseInfo[i].NextProvider.dwServiceFlags1 & ~XP1_IFS_HANDLES ) != 
00384                      ( lpProtocolInfo->dwServiceFlags1 & ~XP1_IFS_HANDLES ) 
00385                    )
00386                 {
00387                     continue;
00388                 }
00389             }
00390             Provider = &gBaseInfo[i];
00391             pInfo = &gBaseInfo[i].NextProvider;
00392             break;
00393         }
00394     }
00395 
00396     if ( NULL == Provider )
00397     {
00398         *lpErrno = WSAEINVAL;
00399         goto cleanup;
00400     }
00401 
00402     //
00403     // Of course if the next layer isn't a base just pass down lpProtocolInfo.
00404     //
00405     if ( BASE_PROTOCOL != pInfo->ProtocolChain.ChainLen )
00406     {
00407         pInfo = lpProtocolInfo;
00408     }
00409    
00410     if ( 0 == Provider->StartupCount )
00411     {
00412         if ( SOCKET_ERROR == InitializeProvider( Provider, MAKEWORD(2,2), lpProtocolInfo,
00413                 gMainUpCallTable, lpErrno ) )
00414         {
00415             dbgprint("WSPAddressToString: InitializeProvider failed: %d", *lpErrno);
00416             goto cleanup;
00417         }
00418     }
00419 
00420     ASSERT( Provider->NextProcTable.lpWSPAddressToString );
00421 
00422     SetBlockingProvider(Provider);
00423     ret = Provider->NextProcTable.lpWSPAddressToString(
00424             lpsaAddress, 
00425             dwAddressLength,               
00426             pInfo, 
00427             lpszAddressString, 
00428             lpdwAddressStringLength, 
00429             lpErrno
00430             );
00431     SetBlockingProvider(NULL);
00432 
00433 cleanup:
00434 
00435     return ret;
00436 }

int WSPAPI WSPAsyncSelect ( SOCKET  s,
HWND  hWnd,
unsigned int  wMsg,
long  lEvent,
LPINT  lpErrno 
)

Definition at line 446 of file spi.cpp.

00453 {
00454     SOCK_INFO *SocketContext = NULL;
00455     HWND       hWorkerWindow = NULL;
00456     INT        ret = SOCKET_ERROR;
00457 
00458     //
00459     // Make sure the window handle is valid
00460     //
00461     ret = SOCKET_ERROR;
00462     if ( FALSE == IsWindow( hWnd ) )
00463     {
00464         *lpErrno = WSAEINVAL;
00465         goto cleanup;
00466     }
00467 
00468     //
00469     // Verify only valid events have been set
00470     //
00471     if ( 0 != (lEvent & ~FD_ALL_EVENTS) )
00472     {
00473         *lpErrno = WSAEINVAL;
00474         goto cleanup;
00475     }
00476 
00477     //
00478     // Find our provider socket corresponding to this one
00479     //
00480     SocketContext = FindAndRefSocketContext(s, lpErrno);
00481     if ( NULL == SocketContext )
00482     {
00483         dbgprint( "WSPAsyncSelect: FindAndRefSocketContext failed!" );
00484         goto cleanup;
00485     }
00486 
00487     SocketContext->hWnd = hWnd;
00488     SocketContext->uMsg = wMsg;
00489 
00490     //
00491     // Get the handle to our hidden window
00492     //
00493     if ( NULL == ( hWorkerWindow = GetWorkerWindow() ) )
00494     {
00495         *lpErrno = WSAEINVAL;
00496         goto cleanup;
00497     }
00498 
00499     ASSERT( SocketContext->Provider->NextProcTable.lpWSPAsyncSelect );
00500 
00501     SetBlockingProvider(SocketContext->Provider);
00502     ret = SocketContext->Provider->NextProcTable.lpWSPAsyncSelect(
00503             SocketContext->ProviderSocket, 
00504             hWorkerWindow, 
00505             WM_SOCKET, 
00506             lEvent, 
00507             lpErrno
00508             );
00509     SetBlockingProvider(NULL);
00510 
00511 cleanup:
00512 
00513     if ( NULL != SocketContext )
00514         DerefSocketContext( SocketContext, lpErrno );
00515 
00516     return ret;
00517 }

int WSPAPI WSPBind ( SOCKET  s,
const struct sockaddr FAR *  name,
int  namelen,
LPINT  lpErrno 
)

Definition at line 527 of file spi.cpp.

00533 {
00534     SOCK_INFO *SocketContext = NULL;
00535     INT        ret = SOCKET_ERROR;
00536 
00537     //
00538     // Find our provider socket corresponding to this one
00539     //
00540     SocketContext = FindAndRefSocketContext(s, lpErrno);
00541     if ( NULL == SocketContext )
00542     {
00543         dbgprint( "WSPBind: FindAndRefSocketContext failed!" );
00544         goto cleanup;
00545     }
00546 
00547     ASSERT( SocketContext->Provider->NextProcTable.lpWSPBind );
00548 
00549     SetBlockingProvider(SocketContext->Provider);
00550     ret = SocketContext->Provider->NextProcTable.lpWSPBind(
00551             SocketContext->ProviderSocket, 
00552             name, 
00553             namelen, 
00554             lpErrno
00555             );
00556     SetBlockingProvider(NULL);
00557 
00558 cleanup:
00559 
00560     if ( NULL != SocketContext )
00561         DerefSocketContext( SocketContext, lpErrno );
00562 
00563     return ret;
00564 }

int WSPAPI WSPCancelBlockingCall ( LPINT  lpErrno  ) 

Definition at line 577 of file spi.cpp.

00580 {
00581     PROVIDER *Provider = NULL;
00582     INT       ret = NO_ERROR;
00583 
00584     Provider = (PROVIDER *) TlsGetValue( gTlsIndex );
00585     if ( NULL != Provider )
00586     {
00587         ASSERT( Provider->NextProcTable.lpWSPCancelBlockingCall );
00588 
00589         ret = Provider->NextProcTable.lpWSPCancelBlockingCall(lpErrno);
00590     }
00591     return ret;
00592 }

int WSPAPI WSPCleanup ( LPINT  lpErrno  ) 

Definition at line 602 of file spi.cpp.

00605 {
00606     int        ret = SOCKET_ERROR;
00607 
00608     if ( gDetached )
00609     {
00610         dbgprint("WSPCleanup: DLL has already been unloaded from process!");
00611         ret = NO_ERROR;
00612         goto cleanup;
00613     }
00614 
00615     //
00616     // Grab the DLL global critical section
00617     //
00618     EnterCriticalSection( &gCriticalSection );
00619 
00620     if ( 0 == gEntryCount )
00621     {
00622         *lpErrno = WSANOTINITIALISED;
00623         dbgprint("WSPCleanup returning WSAENOTINITIALISED");
00624         goto cleanup;
00625     }
00626 
00627     //
00628     // Decrement the entry count
00629     //
00630     gEntryCount--;
00631 
00632     #ifdef DEBUG
00633     dbgprint("WSPCleanup: %d", gEntryCount);
00634     #endif
00635 
00636     if ( 0 == gEntryCount )
00637     {
00638         //
00639         // App released the last reference to use so shutdown the async window
00640         // and overlapped threads.
00641         //
00642         StopAsyncWindowManager();
00643         StopOverlappedManager();
00644 
00645         Sleep(200);
00646 
00647         FreeSocketsAndMemory( FALSE, lpErrno );
00648 
00649         FreeOverlappedLookasideList();
00650     }
00651 
00652 cleanup:
00653 
00654     LeaveCriticalSection(&gCriticalSection);
00655 
00656     return ret;
00657 }

int WSPAPI WSPCloseSocket ( SOCKET  s,
LPINT  lpErrno 
)

Definition at line 670 of file spi.cpp.

00674 {
00675     SOCK_INFO *SocketContext = NULL;
00676     int        ret = SOCKET_ERROR;
00677 
00678     //
00679     // Find our provider socket corresponding to this one
00680     //
00681     SocketContext = FindAndRefSocketContext(s, lpErrno);
00682     if ( NULL == SocketContext )
00683     {
00684         dbgprint( "WSPCloseSocket: FindAndRefSocketContext failed!" );
00685         goto cleanup;
00686     }
00687 
00688     AcquireSocketLock( SocketContext );
00689 
00690     dbgprint("WSPCloseSocket: Closing layered socket 0x%p (provider 0x%p)",
00691         s, SocketContext->ProviderSocket);
00692 
00693     //
00694     // If we there are outstanding async calls on this handle don't close the app
00695     //  socket handle...only close the provider's handle.  Therefore any errors
00696     //  incurred can be propogated back to the app socket. Also verify closesocket
00697     //  hasn't already been called on this socket
00698     //
00699 
00700     dbgprint("dwOutstanding = %d; RefCount = %d", SocketContext->dwOutstandingAsync, 
00701         SocketContext->RefCount);
00702 
00703     ASSERT( SocketContext->Provider->NextProcTable.lpWSPCloseSocket );
00704 
00705     if ( ( ( 0 != SocketContext->dwOutstandingAsync ) || 
00706            ( 1 != SocketContext->RefCount ) ) &&
00707          ( TRUE != SocketContext->bClosing )
00708        )
00709     {
00710         //
00711         // Either there are outstanding asynchronous operations or some other thread
00712         // is performing an operation AND close has not already been called on this
00713         // socket
00714         //
00715         SocketContext->bClosing = TRUE;
00716 
00717         ret = SocketContext->Provider->NextProcTable.lpWSPCloseSocket(
00718                 SocketContext->ProviderSocket, 
00719                 lpErrno
00720                 );
00721         if ( SOCKET_ERROR == ret )
00722         {
00723             goto cleanup;
00724         }
00725        
00726         dbgprint("Closed lower provider socket: 0x%p", SocketContext->ProviderSocket);
00727 
00728         SocketContext->ProviderSocket = INVALID_SOCKET;
00729 
00730     }
00731     else if ( ( 0 == SocketContext->dwOutstandingAsync ) &&
00732               ( 1 == SocketContext->RefCount )
00733             )
00734     {
00735         //
00736         // No one else is referencing this socket so we can close and free all
00737         //  objects associated with it
00738         //
00739         SetBlockingProvider(SocketContext->Provider);
00740         ret = SocketContext->Provider->NextProcTable.lpWSPCloseSocket(
00741                 SocketContext->ProviderSocket, 
00742                 lpErrno
00743                 );
00744         
00745         SetBlockingProvider(NULL);
00746         
00747         if ( SOCKET_ERROR == ret )
00748         {
00749             dbgprint("WSPCloseSocket: Provider close failed");
00750             goto cleanup;
00751         }
00752         
00753 
00754         SocketContext->ProviderSocket = INVALID_SOCKET;
00755 
00756         //
00757         // Remove the socket info
00758         //
00759         RemoveSocketInfo(SocketContext->Provider, SocketContext);
00760 
00761         //
00762         // Close the app socket
00763         //
00764         ret = gMainUpCallTable.lpWPUCloseSocketHandle(s, lpErrno);
00765         if ( SOCKET_ERROR == ret )
00766         {
00767             dbgprint("WPUCloseSocketHandle failed: %d", *lpErrno);
00768         }
00769 
00770         dbgprint("Closing socket %d Bytes Sent [%lu] Bytes Recv [%lu]", 
00771                 s, SocketContext->BytesSent, SocketContext->BytesRecv);
00772 
00773         ReleaseSocketLock( SocketContext );
00774 
00775         // Don't need to 'DerefSocketContext' as we're deleting the object now
00776 
00777         FreeSockInfo( SocketContext );
00778         SocketContext = NULL;
00779     }
00780 
00781 cleanup:
00782     
00783     if ( NULL != SocketContext )
00784     {
00785         ReleaseSocketLock(SocketContext);
00786         DerefSocketContext( SocketContext, lpErrno );
00787     }
00788 
00789     return ret;
00790 }

int WSPAPI WSPConnect ( SOCKET  s,
const struct sockaddr FAR *  name,
int  namelen,
LPWSABUF  lpCallerData,
LPWSABUF  lpCalleeData,
LPQOS  lpSQOS,
LPQOS  lpGQOS,
LPINT  lpErrno 
)

Definition at line 800 of file spi.cpp.

00810 {
00811     SOCK_INFO *SocketContext = NULL;
00812     INT        ret = SOCKET_ERROR;
00813 
00814     //
00815     // Find our provider socket corresponding to this one
00816     //
00817     SocketContext = FindAndRefSocketContext(s, lpErrno);
00818     if ( NULL == SocketContext )
00819     {
00820         dbgprint( "WSPConnect: FindAndRefSocketContext failed!" );
00821         goto cleanup;
00822     }
00823 
00824     ASSERT( SocketContext->Provider->NextProcTable.lpWSPConnect );
00825 
00826     SetBlockingProvider(SocketContext->Provider);
00827     ret = SocketContext->Provider->NextProcTable.lpWSPConnect(
00828             SocketContext->ProviderSocket, 
00829             name, 
00830             namelen, 
00831             lpCallerData, 
00832             lpCalleeData,
00833             lpSQOS, 
00834             lpGQOS, 
00835             lpErrno
00836             );
00837     SetBlockingProvider(NULL);
00838 
00839 cleanup:
00840 
00841     if ( NULL != SocketContext )
00842         DerefSocketContext( SocketContext, lpErrno );
00843 
00844     return ret;
00845 }

int WSPAPI WSPDuplicateSocket ( SOCKET  s,
DWORD  dwProcessId,
LPWSAPROTOCOL_INFOW  lpProtocolInfo,
LPINT  lpErrno 
)

Definition at line 858 of file spi.cpp.

00864 {
00865     PROVIDER          *Provider = NULL;
00866     SOCK_INFO         *SocketContext = NULL;
00867     DWORD              dwReserved;
00868     int                ret = SOCKET_ERROR;
00869 
00870     //
00871     // Find our provider socket corresponding to this one
00872     //
00873     SocketContext = FindAndRefSocketContext(s, lpErrno);
00874     if ( NULL == SocketContext )
00875     {
00876         dbgprint( "WSPDuplicateSocket: FindAndRefSocketContext failed!" );
00877         goto cleanup;
00878     }
00879     //
00880     // Find the underlying provider
00881     //
00882     Provider = SocketContext->Provider;
00883 
00884     ASSERT( Provider->NextProcTable.lpWSPDuplicateSocket );
00885 
00886     SetBlockingProvider(Provider);
00887     ret = Provider->NextProcTable.lpWSPDuplicateSocket(
00888             SocketContext->ProviderSocket,
00889             dwProcessId,
00890             lpProtocolInfo,
00891             lpErrno
00892             );
00893     SetBlockingProvider(NULL);
00894 
00895     if ( NO_ERROR == ret )
00896     {
00897         //
00898         // We want to return the WSAPROTOCOL_INFOW structure of the underlying
00899         // provider but we need to preserve the reserved info returned by the
00900         // WSPDuplicateSocket call.
00901         //
00902         dwReserved = lpProtocolInfo->dwProviderReserved;
00903         memcpy(lpProtocolInfo, &Provider->LayerProvider, sizeof(WSAPROTOCOL_INFOW));
00904         lpProtocolInfo->dwProviderReserved = dwReserved;
00905 
00906         dbgprint("WSPDuplicateSocket: Returning %S provider with reserved %d",
00907                 lpProtocolInfo->szProtocol, dwReserved );
00908     }
00909 
00910 cleanup:
00911 
00912     if ( NULL != SocketContext )
00913         DerefSocketContext( SocketContext, lpErrno );
00914 
00915     return ret;    
00916 }

int WSPAPI WSPEnumNetworkEvents ( SOCKET  s,
WSAEVENT  hEventObject,
LPWSANETWORKEVENTS  lpNetworkEvents,
LPINT  lpErrno 
)

Definition at line 926 of file spi.cpp.

00932 {
00933     SOCK_INFO *SocketContext = NULL;
00934     INT        ret = SOCKET_ERROR;
00935 
00936     //
00937     // Find our provider socket corresponding to this one
00938     //
00939     SocketContext = FindAndRefSocketContext(s, lpErrno);
00940     if ( NULL == SocketContext )
00941     {
00942         dbgprint( "WSPEnumNetworkEvents: FindAndRefSocketContext failed!" );
00943         goto cleanup;
00944     }
00945 
00946     ASSERT( SocketContext->Provider->NextProcTable.lpWSPEnumNetworkEvents );
00947 
00948     SetBlockingProvider(SocketContext->Provider);
00949     ret = SocketContext->Provider->NextProcTable.lpWSPEnumNetworkEvents(
00950             SocketContext->ProviderSocket,                             
00951             hEventObject, 
00952             lpNetworkEvents, 
00953             lpErrno
00954             );
00955     SetBlockingProvider(NULL);
00956 
00957 cleanup:
00958 
00959     if ( NULL != SocketContext )
00960         DerefSocketContext( SocketContext, lpErrno );
00961 
00962     return ret;
00963 }

int WSPAPI WSPEventSelect ( SOCKET  s,
WSAEVENT  hEventObject,
long  lNetworkEvents,
LPINT  lpErrno 
)

Definition at line 973 of file spi.cpp.

00979 {
00980     SOCK_INFO *SocketContext = NULL;
00981     INT        ret = SOCKET_ERROR;
00982 
00983     //
00984     // Find our provider socket corresponding to this one
00985     //
00986     SocketContext = FindAndRefSocketContext(s, lpErrno);
00987     if ( NULL == SocketContext )
00988     {
00989         dbgprint( "WSPEventSelect: FindAndRefSocketContext failed!" );
00990         goto cleanup;
00991     }
00992     
00993     ASSERT( SocketContext->Provider->NextProcTable.lpWSPEventSelect );
00994 
00995     SetBlockingProvider(SocketContext->Provider);
00996     ret = SocketContext->Provider->NextProcTable.lpWSPEventSelect(
00997             SocketContext->ProviderSocket, 
00998             hEventObject,
00999             lNetworkEvents, 
01000             lpErrno
01001             );
01002     SetBlockingProvider(NULL);
01003 
01004 cleanup:
01005 
01006     if ( NULL != SocketContext )
01007         DerefSocketContext( SocketContext, lpErrno );
01008 
01009     return ret;
01010 }

BOOL WSPAPI WSPGetOverlappedResult ( SOCKET  s,
LPWSAOVERLAPPED  lpOverlapped,
LPDWORD  lpcbTransfer,
BOOL  fWait,
LPDWORD  lpdwFlags,
LPINT  lpErrno 
)

Definition at line 1022 of file spi.cpp.

01030 {
01031     DWORD ret = FALSE;
01032 
01033     UNREFERENCED_PARAMETER( s );
01034 
01035     __try
01036     {
01037         if ( WSS_OPERATION_IN_PROGRESS != lpOverlapped->Internal ) 
01038         {
01039             // Operation has completed, update the parameters and return 
01040             //
01041             *lpcbTransfer = (DWORD)lpOverlapped->InternalHigh;
01042             *lpdwFlags = (DWORD)lpOverlapped->Offset;
01043             *lpErrno = (INT)lpOverlapped->OffsetHigh;
01044 
01045             ret = (lpOverlapped->OffsetHigh == 0 ? TRUE : FALSE);
01046         }
01047         else if ( FALSE != fWait )
01048         {
01049             //
01050             // Operation is still in progress so wait until it completes
01051             //
01052 
01053             //
01054             // Wait on the app supplied event handle. Once the operation
01055             //  is completed the IOCP or completion routine will fire.
01056             //  Once that is handled, WPUCompleteOverlappedRequest will
01057             //  be called which will signal the app event.
01058             //
01059             ret = WaitForSingleObject(lpOverlapped->hEvent, INFINITE);
01060             if ( ( WAIT_OBJECT_0 == ret ) &&
01061                     ( WSS_OPERATION_IN_PROGRESS != lpOverlapped->Internal ) )
01062             {
01063                 *lpcbTransfer = (DWORD)lpOverlapped->InternalHigh;
01064                 *lpdwFlags = (DWORD)lpOverlapped->Offset;
01065                 *lpErrno = (INT)lpOverlapped->OffsetHigh;
01066 
01067                 ret = (lpOverlapped->OffsetHigh == 0 ? TRUE : FALSE);
01068             }
01069             else if ( WSS_OPERATION_IN_PROGRESS == lpOverlapped->Internal )
01070             {
01071                 *lpErrno = WSA_IO_PENDING;
01072             }
01073             else 
01074             {
01075                 *lpErrno = GetLastError();
01076             }
01077         }
01078         else 
01079         {
01080             // Operation is in progress and we aren't waiting
01081             *lpErrno = WSA_IO_INCOMPLETE;
01082         }
01083     }
01084     __except( EXCEPTION_EXECUTE_HANDLER )
01085     {
01086         *lpErrno = WSAEFAULT;
01087     }
01088 
01089     return ret;
01090 }

int WSPAPI WSPGetPeerName ( SOCKET  s,
struct sockaddr FAR *  name,
LPINT  namelen,
LPINT  lpErrno 
)

Definition at line 1100 of file spi.cpp.

01106 {
01107     SOCK_INFO *SocketContext = NULL;
01108     INT        ret = SOCKET_ERROR;
01109 
01110     //
01111     // Find our provider socket corresponding to this one
01112     //
01113     SocketContext = FindAndRefSocketContext(s, lpErrno);
01114     if ( NULL == SocketContext )
01115     {
01116         dbgprint( "WSPGetPeerName: FindAndRefSocketContext failed!" );
01117         goto cleanup;
01118     }
01119 
01120     ASSERT( SocketContext->Provider->NextProcTable.lpWSPGetPeerName );
01121 
01122     SetBlockingProvider(SocketContext->Provider);
01123     ret = SocketContext->Provider->NextProcTable.lpWSPGetPeerName(
01124                 SocketContext->ProviderSocket, 
01125                 name,
01126                 namelen, 
01127                 lpErrno);
01128     SetBlockingProvider(NULL);
01129 
01130 cleanup:
01131 
01132     if ( NULL != SocketContext )
01133         DerefSocketContext( SocketContext, lpErrno );
01134 
01135     return ret;
01136 }

BOOL WSPAPI WSPGetQOSByName ( SOCKET  s,
LPWSABUF  lpQOSName,
LPQOS  lpQOS,
LPINT  lpErrno 
)

Definition at line 1307 of file spi.cpp.

01313 {
01314     SOCK_INFO *SocketContext = NULL;
01315     INT        ret = SOCKET_ERROR;
01316 
01317     //
01318     // Find our provider socket corresponding to this one
01319     //
01320     SocketContext = FindAndRefSocketContext(s, lpErrno);
01321     if ( NULL == SocketContext )
01322     {
01323         dbgprint( "WSPGetQOSByName: FindAndRefSocketContext failed!" );
01324         goto cleanup;
01325     }
01326 
01327     ASSERT( SocketContext->Provider->NextProcTable.lpWSPGetQOSByName );
01328 
01329     SetBlockingProvider(SocketContext->Provider);
01330     ret = SocketContext->Provider->NextProcTable.lpWSPGetQOSByName(
01331             SocketContext->ProviderSocket, 
01332             lpQOSName,
01333             lpQOS, 
01334             lpErrno
01335             );
01336     SetBlockingProvider(NULL);
01337 
01338 cleanup:
01339 
01340     if ( NULL != SocketContext )
01341         DerefSocketContext( SocketContext, lpErrno );
01342 
01343     return ret;
01344 }

int WSPAPI WSPGetSockName ( SOCKET  s,
struct sockaddr FAR *  name,
LPINT  namelen,
LPINT  lpErrno 
)

Definition at line 1146 of file spi.cpp.

01152 {
01153     SOCK_INFO *SocketContext = NULL;
01154     INT        ret = SOCKET_ERROR;
01155 
01156     //
01157     // Find our provider socket corresponding to this one
01158     //
01159     SocketContext = FindAndRefSocketContext(s, lpErrno);
01160     if ( NULL == SocketContext )
01161     {
01162         dbgprint( "WSPGetSockName: FindAndRefSocketContext failed!" );
01163         goto cleanup;
01164     }
01165 
01166     ASSERT( SocketContext->Provider->NextProcTable.lpWSPGetSockName );
01167 
01168     SetBlockingProvider(SocketContext->Provider);
01169     ret = SocketContext->Provider->NextProcTable.lpWSPGetSockName(
01170             SocketContext->ProviderSocket, 
01171             name,
01172             namelen, 
01173             lpErrno
01174             );
01175     SetBlockingProvider(NULL);
01176 
01177 cleanup:
01178 
01179     if ( NULL != SocketContext )
01180         DerefSocketContext( SocketContext, lpErrno );
01181 
01182     return ret;
01183 }

int WSPAPI WSPGetSockOpt ( SOCKET  s,
int  level,
int  optname,
char FAR *  optval,
LPINT  optlen,
LPINT  lpErrno 
)

Definition at line 1193 of file spi.cpp.

01201 {
01202     SOCK_INFO *SocketContext = NULL;
01203     INT        ret = NO_ERROR;
01204 
01205 
01206     //
01207     // Find our provider socket corresponding to this one
01208     //
01209     SocketContext = FindAndRefSocketContext(s, lpErrno);
01210     if ( NULL == SocketContext )
01211     {
01212         dbgprint( "WSPGetSockOpt: FindAndRefSocketContext failed!" );
01213         goto cleanup;
01214     }
01215 
01216 
01217     __try
01218     {
01219         //
01220         // We need to capture this and return our own WSAPROTOCOL_INFO structure.
01221         // Otherwise, if we translate the handle and pass it to the lower provider
01222         // we'll return the lower provider's protocol info!
01223         //
01224         if ( ( SOL_SOCKET == level ) && ( ( SO_PROTOCOL_INFOA == optname ) ||
01225                                           ( SO_PROTOCOL_INFOW == optname ) )
01226            )
01227         {
01228             if ( ( SO_PROTOCOL_INFOW == optname ) && 
01229                  ( sizeof( WSAPROTOCOL_INFOW ) <= *optlen )
01230                )
01231             {
01232 
01233                     // No conversion necessary, just copy the data
01234                     memcpy(optval, 
01235                            &SocketContext->Provider->LayerProvider, 
01236                            sizeof(WSAPROTOCOL_INFOW));
01237        
01238             }
01239             else if ( ( SO_PROTOCOL_INFOA == optname ) && 
01240                       ( sizeof( WSAPROTOCOL_INFOA ) <= *optlen )
01241                     )
01242             {
01243              
01244                 // Copy everything but the string
01245                 memcpy(optval,
01246                        &SocketContext->Provider->LayerProvider,
01247                        sizeof(WSAPROTOCOL_INFOW)-WSAPROTOCOL_LEN+1);
01248                 // Convert our saved UNICODE string to ANSII
01249                 WideCharToMultiByte(
01250                         CP_ACP,
01251                         0,
01252                         SocketContext->Provider->LayerProvider.szProtocol,
01253                         -1,
01254                         ((WSAPROTOCOL_INFOA *)optval)->szProtocol,
01255                         WSAPROTOCOL_LEN+1,
01256                         NULL,
01257                         NULL
01258                         );
01259 
01260      
01261             }
01262             else
01263             {
01264                 ret = SOCKET_ERROR;
01265                 *lpErrno = WSAEFAULT;
01266                 goto cleanup;
01267             }
01268 
01269             goto cleanup;
01270         }
01271     }
01272     __except( EXCEPTION_EXECUTE_HANDLER )
01273     {
01274         ret = SOCKET_ERROR;
01275         *lpErrno = WSAEFAULT;
01276         goto cleanup;
01277     }       
01278    
01279     ASSERT( SocketContext->Provider->NextProcTable.lpWSPGetSockOpt );
01280 
01281     SetBlockingProvider(SocketContext->Provider);
01282     ret = SocketContext->Provider->NextProcTable.lpWSPGetSockOpt(
01283                 SocketContext->ProviderSocket, 
01284                 level,
01285                 optname, 
01286                 optval, 
01287                 optlen, 
01288                 lpErrno);
01289     SetBlockingProvider(NULL);
01290 
01291 cleanup:
01292 
01293     if ( NULL != SocketContext )
01294         DerefSocketContext( SocketContext, lpErrno );
01295 
01296     return ret;
01297 }

int WSPAPI WSPIoctl ( SOCKET  s,
DWORD  dwIoControlCode,
LPVOID  lpvInBuffer,
DWORD  cbInBuffer,
LPVOID  lpvOutBuffer,
DWORD  cbOutBuffer,
LPDWORD  lpcbBytesReturned,
LPWSAOVERLAPPED  lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine,
LPWSATHREADID  lpThreadId,
LPINT  lpErrno 
)

Definition at line 1359 of file spi.cpp.

01372 {
01373     LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
01374     SOCK_INFO          *SocketContext = NULL;
01375     GUID                AcceptExGuid = WSAID_ACCEPTEX,
01376                         TransmitFileGuid = WSAID_TRANSMITFILE,
01377                         GetAcceptExSockAddrsGuid = WSAID_GETACCEPTEXSOCKADDRS,
01378                         ConnectExGuid = WSAID_CONNECTEX,
01379                         DisconnectExGuid = WSAID_DISCONNECTEX,
01380                         TransmitPacketsGuid = WSAID_TRANSMITPACKETS,
01381                         WSARecvMsgGuid = WSAID_WSARECVMSG;
01382     DWORD               dwBytesReturned = 0;
01383     int                 ret = NO_ERROR;
01384 
01385 
01386     *lpErrno = NO_ERROR;
01387 
01388     //
01389     // Find our provider socket corresponding to this one
01390     //
01391     SocketContext = FindAndRefSocketContext(s, lpErrno);
01392     if ( NULL == SocketContext )
01393     {
01394         dbgprint( "WSPIoctl: FindAndRefSocketContext failed!" );
01395         goto cleanup;
01396     }
01397 
01398     if ( SIO_GET_EXTENSION_FUNCTION_POINTER == dwIoControlCode )
01399     {
01400         LPVOID      lpFunction = NULL;
01401 
01402 
01403         // Sanity check the buffers
01404         
01405         if( cbInBuffer < sizeof(GUID) || lpvInBuffer == NULL ||
01406             cbOutBuffer < sizeof(LPVOID) || lpvOutBuffer == NULL )        
01407         {
01408             ret = SOCKET_ERROR;
01409             *lpErrno = WSAEFAULT;
01410             goto cleanup;            
01411         }
01412         
01413         __try
01414         {
01415             //
01416             // Check to see which extension function is being requested.
01417             //
01418             if ( 0 == memcmp( lpvInBuffer, &TransmitFileGuid, sizeof( GUID ) ) )
01419             {
01420                 // Return a pointer to our intermediate extesion function
01421                 dwBytesReturned = sizeof(LPFN_TRANSMITFILE);
01422                 lpFunction = ExtTransmitFile;
01423 
01424                 // Attempt to load the lower provider's extension function
01425                 if ( NULL == SocketContext->Provider->NextProcTableExt.lpfnTransmitFile )
01426                 {
01427                     SetBlockingProvider(SocketContext->Provider);
01428                     LoadExtensionFunction(
01429                             (FARPROC **) &SocketContext->Provider->NextProcTableExt.lpfnTransmitFile,
01430                             TransmitFileGuid,
01431                             SocketContext->Provider->NextProcTable.lpWSPIoctl,
01432                             SocketContext->ProviderSocket
01433                             );
01434                     SetBlockingProvider(NULL);
01435                 }
01436             }
01437             else if ( 0 == memcmp( lpvInBuffer, &AcceptExGuid, sizeof( GUID ) ) )
01438             {
01439                 // Return a pointer to our intermediate extension function
01440                 dwBytesReturned = sizeof( LPFN_ACCEPTEX );
01441                 lpFunction = ExtAcceptEx;
01442 
01443                 // Attempt to load the lower provider's extension function
01444                 if ( NULL == SocketContext->Provider->NextProcTableExt.lpfnAcceptEx )
01445                 {
01446                     SetBlockingProvider(SocketContext->Provider);
01447                     LoadExtensionFunction(
01448                             (FARPROC **) &SocketContext->Provider->NextProcTableExt.lpfnAcceptEx,
01449                             AcceptExGuid,
01450                             SocketContext->Provider->NextProcTable.lpWSPIoctl,
01451                             SocketContext->ProviderSocket
01452                             );
01453                     SetBlockingProvider(NULL);
01454                 }
01455             }
01456             else if ( 0 == memcmp( lpvInBuffer, &ConnectExGuid, sizeof( GUID ) ) )
01457             {
01458                 // Return a pointer to our intermediate extension function
01459                 dwBytesReturned = sizeof( LPFN_CONNECTEX );
01460                 lpFunction = ExtConnectEx;
01461 
01462                 // Attempt to load the lower provider's extension function
01463                 if ( NULL == SocketContext->Provider->NextProcTableExt.lpfnConnectEx )
01464                 {
01465                     SetBlockingProvider(SocketContext->Provider);
01466                     LoadExtensionFunction(
01467                             (FARPROC **) &SocketContext->Provider->NextProcTableExt.lpfnConnectEx,
01468                             ConnectExGuid,
01469                             SocketContext->Provider->NextProcTable.lpWSPIoctl,
01470                             SocketContext->ProviderSocket
01471                             );
01472                     SetBlockingProvider(NULL);
01473                 }
01474             }
01475             else if ( 0 == memcmp( lpvInBuffer, &DisconnectExGuid, sizeof( GUID ) ) )
01476             {
01477                 // Return a pointer to our intermediate extension function
01478                 dwBytesReturned = sizeof( LPFN_DISCONNECTEX );
01479                 lpFunction = ExtDisconnectEx;
01480 
01481                 // Attempt to load the lower provider's extension function
01482                 if ( NULL == SocketContext->Provider->NextProcTableExt.lpfnDisconnectEx )
01483                 {
01484                     SetBlockingProvider(SocketContext->Provider);
01485                     LoadExtensionFunction(
01486                             (FARPROC **) &SocketContext->Provider->NextProcTableExt.lpfnDisconnectEx,
01487                             DisconnectExGuid,
01488                             SocketContext->Provider->NextProcTable.lpWSPIoctl,
01489                             SocketContext->ProviderSocket
01490                             );
01491                     SetBlockingProvider(NULL);
01492                 }
01493             }
01494             else if ( 0 == memcmp( lpvInBuffer, &TransmitPacketsGuid, sizeof( GUID ) ) )
01495             {
01496                 // Return a pointer to our intermediate extension function
01497                 dwBytesReturned = sizeof( LPFN_TRANSMITPACKETS );
01498                 lpFunction = ExtTransmitPackets;
01499 
01500                 // Attempt to load the lower provider's extension function
01501                 if ( NULL == SocketContext->Provider->NextProcTableExt.lpfnTransmitPackets )
01502                 {
01503                     SetBlockingProvider(SocketContext->Provider);
01504                     LoadExtensionFunction(
01505                             (FARPROC **) &SocketContext->Provider->NextProcTableExt.lpfnTransmitPackets,
01506                             TransmitPacketsGuid,
01507                             SocketContext->Provider->NextProcTable.lpWSPIoctl,
01508                             SocketContext->ProviderSocket
01509                             );
01510                     SetBlockingProvider(NULL);
01511                 }
01512             }
01513             else if ( 0 == memcmp( lpvInBuffer, &WSARecvMsgGuid, sizeof( GUID ) ) )
01514             {
01515                 // Return a pointer to our intermediate extension function
01516                 dwBytesReturned = sizeof( LPFN_WSARECVMSG );
01517                 lpFunction = ExtWSARecvMsg;
01518 
01519                 // Attempt to load the lower provider's extension function
01520                 if ( NULL == SocketContext->Provider->NextProcTableExt.lpfnWSARecvMsg )
01521                 {
01522                     SetBlockingProvider(SocketContext->Provider);
01523                     LoadExtensionFunction(
01524                             (FARPROC **) &SocketContext->Provider->NextProcTableExt.lpfnWSARecvMsg,
01525                             WSARecvMsgGuid,
01526                             SocketContext->Provider->NextProcTable.lpWSPIoctl,
01527                             SocketContext->ProviderSocket
01528                             );
01529                     SetBlockingProvider(NULL);
01530                 }
01531             }
01532             else if ( 0 == memcmp( lpvInBuffer, &GetAcceptExSockAddrsGuid, sizeof( GUID ) ) )
01533             {
01534                 // No socket handle translation needed, let the call pass through below
01535                 // (i.e. we really don't have any need to intercept this call)
01536             }
01537             else 
01538             {
01539                 ret = SOCKET_ERROR;
01540                 *lpErrno = WSAEINVAL;
01541                 goto cleanup;
01542             }
01543         }
01544         __except( EXCEPTION_EXECUTE_HANDLER )
01545         {
01546             ret = SOCKET_ERROR;
01547             *lpErrno = WSAEFAULT;
01548             goto cleanup;
01549                     
01550         }
01551         //
01552         // Update the output parameters if successful
01553         //
01554         if ( NULL != lpFunction )
01555         {
01556             __try 
01557             {
01558                 *((DWORD_PTR *)lpvOutBuffer) = (DWORD_PTR) lpFunction;
01559                 *lpcbBytesReturned = dwBytesReturned;
01560             }
01561             __except( EXCEPTION_EXECUTE_HANDLER )
01562             {
01563                 ret = SOCKET_ERROR;
01564                 *lpErrno = WSAEFAULT;
01565             }
01566             goto cleanup;
01567         }
01568 
01569         // Only if GetAcceptExSockAddresGuid was passed in will we get here
01570         // We fall through and make the call to the lower layer
01571 
01572     }
01573     else if ( SIO_QUERY_TARGET_PNP_HANDLE == dwIoControlCode )
01574     {
01575         //
01576         // If the next layer is another LSP, keep passing. Otherwise return the 
01577         //    lower provider's handle so it may be used in PNP event notifications.
01578         //
01579         if ( SocketContext->Provider->NextProvider.ProtocolChain.ChainLen != BASE_PROTOCOL )
01580         {
01581             __try
01582             {
01583                 *((SOCKET *)lpvOutBuffer) = SocketContext->ProviderSocket;
01584                 dwBytesReturned = *lpcbBytesReturned = sizeof(SocketContext->ProviderSocket);
01585             }
01586             __except( EXCEPTION_EXECUTE_HANDLER )
01587             {
01588                 ret = SOCKET_ERROR;
01589                 *lpErrno = WSAEFAULT;
01590                 goto cleanup;
01591             }
01592 
01593             if ( NULL != lpOverlapped )
01594             {
01595                 ProviderOverlapped = PrepareOverlappedOperation(
01596                         SocketContext,
01597                         LSP_OP_IOCTL,
01598                         NULL,
01599                         0,
01600                         lpOverlapped,
01601                         lpCompletionRoutine,
01602                         lpThreadId,
01603                         lpErrno
01604                         );
01605                 if ( NULL == ProviderOverlapped )
01606                     goto cleanup;
01607 
01608                 __try
01609                 {
01610                     ProviderOverlapped->IoctlArgs.cbBytesReturned   = (lpcbBytesReturned ? *lpcbBytesReturned : 0);
01611                 }
01612                 __except( EXCEPTION_EXECUTE_HANDLER )
01613                 {
01614                     ret = SOCKET_ERROR;
01615                     *lpErrno = WSAEFAULT;
01616                     goto cleanup;
01617                 }
01618 
01619                 //
01620                 // Call the completion routine immediately since there is nothing
01621                 //  else to do. For this ioctl all we do is return the provider
01622                 //  socket. If it was called overlapped just complete the operation.
01623                 //
01624 
01625                 dbgprint("SIO_QUERY_TARGET_PNP_HANDLE overlapped");
01626 
01627                 IntermediateCompletionRoutine(
01628                         0,
01629                         dwBytesReturned,
01630                         (WSAOVERLAPPED *)ProviderOverlapped,
01631                         0);
01632             }
01633 
01634             goto cleanup;
01635         }
01636     }
01637 
01638     //
01639     // Check for overlapped I/O
01640     // 
01641     if ( NULL != lpOverlapped )
01642     {
01643         ProviderOverlapped = PrepareOverlappedOperation(
01644                 SocketContext,
01645                 LSP_OP_IOCTL,
01646                 NULL,
01647                 0,
01648                 lpOverlapped,
01649                 lpCompletionRoutine,
01650                 lpThreadId,
01651                 lpErrno
01652                 );
01653         if ( NULL == ProviderOverlapped )
01654         {
01655             ret = SOCKET_ERROR;
01656             // lpErrno is set by PrepareOverlappedOperation
01657             goto cleanup;
01658         }
01659 
01660         __try
01661         {
01662             ProviderOverlapped->IoctlArgs.cbBytesReturned = (lpcbBytesReturned ? *lpcbBytesReturned : 0);
01663             ProviderOverlapped->IoctlArgs.dwIoControlCode = dwIoControlCode;
01664             ProviderOverlapped->IoctlArgs.lpvInBuffer     = lpvInBuffer;
01665             ProviderOverlapped->IoctlArgs.cbInBuffer      = cbInBuffer;
01666             ProviderOverlapped->IoctlArgs.lpvOutBuffer    = lpvOutBuffer;
01667             ProviderOverlapped->IoctlArgs.cbOutBuffer     = cbOutBuffer;
01668         }
01669         __except( EXCEPTION_EXECUTE_HANDLER )
01670         {
01671             ret = SOCKET_ERROR;
01672             *lpErrno = WSAEFAULT;
01673             goto cleanup;
01674         }
01675 
01676         //
01677         // Make the overlapped call which will always fail (either with WSA_IO_PENDING
01678         // or actual error code if something is wrong).
01679         //
01680         ret = QueueOverlappedOperation(ProviderOverlapped, SocketContext);
01681         if ( NO_ERROR != ret )
01682         {
01683             *lpErrno = ret;
01684             ret = SOCKET_ERROR;
01685         }
01686     }
01687     else
01688     {
01689         ASSERT( SocketContext->Provider->NextProcTable.lpWSPIoctl );
01690 
01691         SetBlockingProvider(SocketContext->Provider);
01692         ret = SocketContext->Provider->NextProcTable.lpWSPIoctl(
01693                 SocketContext->ProviderSocket, 
01694                 dwIoControlCode, 
01695                 lpvInBuffer,
01696                 cbInBuffer, 
01697                 lpvOutBuffer, 
01698                 cbOutBuffer, 
01699                 lpcbBytesReturned, 
01700                 lpOverlapped, 
01701                 lpCompletionRoutine, 
01702                 lpThreadId, 
01703                 lpErrno);
01704         SetBlockingProvider(NULL);
01705     }
01706 
01707 cleanup:
01708 
01709     if ( NULL != SocketContext )
01710         DerefSocketContext( SocketContext, lpErrno );
01711 
01712     return ret;
01713 }

SOCKET WSPAPI WSPJoinLeaf ( SOCKET  s,
const struct sockaddr FAR *  name,
int  namelen,
LPWSABUF  lpCallerData,
LPWSABUF  lpCalleeData,
LPQOS  lpSQOS,
LPQOS  lpGQOS,
DWORD  dwFlags,
LPINT  lpErrno 
)

Definition at line 1729 of file spi.cpp.

01740 {
01741     SOCK_INFO *SocketContext = NULL;
01742     SOCKET     NextProviderSocket = INVALID_SOCKET,
01743                NewSocket = INVALID_SOCKET;
01744 
01745     //
01746     // Find our provider socket corresponding to this one
01747     //
01748     SocketContext = FindAndRefSocketContext(s, lpErrno);
01749     if ( NULL == SocketContext )
01750     {
01751         dbgprint( "WSPJoinLeaf: FindAndRefSocketContext failed!" );
01752         goto cleanup;
01753     }
01754 
01755     ASSERT( SocketContext->Provider->NextProcTable.lpWSPJoinLeaf );
01756 
01757     SetBlockingProvider(SocketContext->Provider);
01758     NextProviderSocket = SocketContext->Provider->NextProcTable.lpWSPJoinLeaf(
01759             SocketContext->ProviderSocket,                           
01760             name, 
01761             namelen, 
01762             lpCallerData, 
01763             lpCalleeData, 
01764             lpSQOS, 
01765             lpGQOS, 
01766             dwFlags,                        
01767             lpErrno
01768             );
01769     SetBlockingProvider(NULL);
01770 
01771     //    
01772     // If the socket returned from the lower provider is the same as the socket
01773     //  passed into it then there really isn't a new socket - just return. 
01774     //  Otherwise, a new socket has been created and we need to create the socket
01775     //  context and create a user socket to pass back.
01776     //
01777     if ( ( INVALID_SOCKET != NextProviderSocket ) && 
01778          ( NextProviderSocket != SocketContext->ProviderSocket )
01779        )
01780     {
01781         SOCK_INFO   *NewSocketContext = NULL;
01782 
01783         //
01784         // Create socket context for new socket
01785         //
01786         NewSocketContext = CreateSockInfo(
01787                 SocketContext->Provider,
01788                 NextProviderSocket,
01789                 SocketContext,
01790                 FALSE,
01791                 lpErrno
01792                 );
01793         if  ( NULL == NewSocketContext )
01794         {
01795             goto cleanup;
01796         }
01797 
01798         //
01799         // Create a socket handle to pass to the app
01800         //
01801         NewSocket = NewSocketContext->LayeredSocket = gMainUpCallTable.lpWPUCreateSocketHandle(
01802                 SocketContext->Provider->LayerProvider.dwCatalogEntryId,
01803                 (DWORD_PTR) NewSocketContext,
01804                 lpErrno
01805                 );
01806         if ( INVALID_SOCKET == NewSocketContext->LayeredSocket )
01807         {
01808             int tempErr;
01809 
01810             ASSERT( SocketContext->Provider->NextProcTable.lpWSPCloseSocket );
01811 
01812             // Close the lower provider's socket
01813             SocketContext->Provider->NextProcTable.lpWSPCloseSocket(
01814                     NextProviderSocket,
01815                    &tempErr
01816                     );
01817 
01818             // Context is not in the list yet so we can just free it
01819             FreeSockInfo(NewSocketContext);
01820             goto cleanup;
01821         }
01822 
01823         // Need to insert the context
01824         InsertSocketInfo(SocketContext->Provider, NewSocketContext);
01825     }
01826     else if ( NextProviderSocket == SocketContext->ProviderSocket )
01827     {
01828         NewSocket = s;
01829     }
01830 
01831 cleanup:
01832 
01833     if ( NULL != SocketContext )
01834         DerefSocketContext( SocketContext, lpErrno );
01835 
01836     return NewSocket;
01837 }

int WSPAPI WSPListen ( SOCKET  s,
int  backlog,
LPINT  lpErrno 
)

Definition at line 1847 of file spi.cpp.

01852 {
01853     SOCK_INFO *SocketContext = NULL;
01854     INT        ret = SOCKET_ERROR;
01855 
01856     //
01857     // Find our provider socket corresponding to this one
01858     //
01859     SocketContext = FindAndRefSocketContext(s, lpErrno);
01860     if ( NULL == SocketContext )
01861     {
01862         dbgprint( "WSPListen: FindAndRefSocketContext failed!" );
01863         goto cleanup;
01864     }
01865 
01866     ASSERT( SocketContext->Provider->NextProcTable.lpWSPListen );
01867 
01868     SetBlockingProvider(SocketContext->Provider);
01869     ret = SocketContext->Provider->NextProcTable.lpWSPListen(
01870             SocketContext->ProviderSocket, 
01871             backlog, 
01872             lpErrno
01873             );
01874     SetBlockingProvider(NULL);
01875 
01876 cleanup:
01877 
01878     if ( NULL != SocketContext )
01879         DerefSocketContext( SocketContext, lpErrno );
01880 
01881     return ret;
01882 }

int WSPAPI WSPRecv ( SOCKET  s,
LPWSABUF  lpBuffers,
DWORD  dwBufferCount,
LPDWORD  lpNumberOfBytesRecvd,
LPDWORD  lpFlags,
LPWSAOVERLAPPED  lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine,
LPWSATHREADID  lpThreadId,
LPINT  lpErrno 
)

Definition at line 1894 of file spi.cpp.

01905 {
01906     LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
01907     SOCK_INFO          *SocketContext = NULL;
01908     int                 ret = SOCKET_ERROR;
01909 
01910 
01911     *lpErrno = NO_ERROR;
01912 
01913     //
01914     // Find our provider socket corresponding to this one
01915     //
01916     SocketContext = FindAndRefSocketContext(s, lpErrno);
01917     if ( NULL == SocketContext )
01918     {
01919         dbgprint( "WSPRecv: FindAndRefSocketContext failed!" );
01920         goto cleanup;
01921     }
01922 
01923     //
01924     // Check for overlapped I/O
01925     //
01926     if ( NULL != lpOverlapped )
01927     {
01928         ProviderOverlapped = PrepareOverlappedOperation(
01929                 SocketContext,
01930                 LSP_OP_RECV,
01931                 lpBuffers,
01932                 dwBufferCount,
01933                 lpOverlapped,
01934                 lpCompletionRoutine,
01935                 lpThreadId,
01936                 lpErrno
01937                 );
01938         if ( NULL == ProviderOverlapped )
01939             goto cleanup;
01940 
01941         __try
01942         {
01943             ProviderOverlapped->RecvArgs.dwNumberOfBytesRecvd = (lpNumberOfBytesRecvd ? *lpNumberOfBytesRecvd : 0);
01944             ProviderOverlapped->RecvArgs.dwFlags              = (lpFlags ? *lpFlags : 0);
01945         }
01946         __except( EXCEPTION_EXECUTE_HANDLER )
01947         {
01948             // Return to original state and indicate error
01949             *lpErrno = WSAEFAULT;
01950             goto cleanup;
01951         }
01952 
01953         //
01954         // Make the overlapped call which will always fail (either with WSA_IO_PENDING
01955         // or actual error code if something is wrong).
01956         //
01957         ret = QueueOverlappedOperation(ProviderOverlapped, SocketContext);
01958         if ( NO_ERROR != ret )
01959         {
01960             *lpErrno = ret;
01961             ret = SOCKET_ERROR;
01962         }
01963     }
01964     else
01965     {
01966         ASSERT( SocketContext->Provider->NextProcTable.lpWSPRecv );
01967 
01968         SetBlockingProvider(SocketContext->Provider);
01969         ret = SocketContext->Provider->NextProcTable.lpWSPRecv(
01970                 SocketContext->ProviderSocket, 
01971                 lpBuffers, 
01972                 dwBufferCount,
01973                 lpNumberOfBytesRecvd, 
01974                 lpFlags, 
01975                 lpOverlapped, 
01976                 lpCompletionRoutine, 
01977                 lpThreadId,
01978                 lpErrno);
01979         SetBlockingProvider(NULL);
01980         if ( SOCKET_ERROR != ret )
01981         {
01982             SocketContext->BytesRecv += *lpNumberOfBytesRecvd;
01983         }
01984     }
01985 
01986 cleanup:
01987 
01988     if ( NULL != SocketContext )
01989         DerefSocketContext( SocketContext, lpErrno );
01990 
01991     return ret;
01992 }

int WSPAPI WSPRecvDisconnect ( SOCKET  s,
LPWSABUF  lpInboundDisconnectData,
LPINT  lpErrno 
)

Definition at line 2002 of file spi.cpp.

02007 {
02008     SOCK_INFO *SocketContext = NULL;
02009     INT        ret = SOCKET_ERROR;
02010 
02011     //
02012     // Find our provider socket corresponding to this one
02013     //
02014     SocketContext = FindAndRefSocketContext(s, lpErrno);
02015     if ( NULL == SocketContext )
02016     {
02017         dbgprint( "WSPRecvDisconnect: FindAndRefSocketContext failed!" );
02018         goto cleanup;
02019     }
02020 
02021     ASSERT( SocketContext->Provider->NextProcTable.lpWSPRecvDisconnect );
02022 
02023     SetBlockingProvider(SocketContext->Provider);
02024     ret = SocketContext->Provider->NextProcTable.lpWSPRecvDisconnect(
02025             SocketContext->ProviderSocket,                           
02026             lpInboundDisconnectData, 
02027             lpErrno
02028             );
02029     SetBlockingProvider(NULL);
02030 
02031 cleanup:
02032 
02033     if ( NULL != SocketContext )
02034         DerefSocketContext( SocketContext, lpErrno );
02035 
02036     return ret;
02037 }

int WSPAPI WSPRecvFrom ( SOCKET  s,
LPWSABUF  lpBuffers,
DWORD  dwBufferCount,
LPDWORD  lpNumberOfBytesRecvd,
LPDWORD  lpFlags,
struct sockaddr FAR *  lpFrom,
LPINT  lpFromLen,
LPWSAOVERLAPPED  lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine,
LPWSATHREADID  lpThreadId,
LPINT  lpErrno 
)

Definition at line 2049 of file spi.cpp.

02062 {
02063     LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
02064     SOCK_INFO          *SocketContext = NULL;
02065     int                 ret = SOCKET_ERROR;
02066 
02067     *lpErrno = NO_ERROR;
02068 
02069     //
02070     // Find our provider socket corresponding to this one
02071     //
02072     SocketContext = FindAndRefSocketContext(s, lpErrno);
02073     if ( NULL == SocketContext )
02074     {
02075         dbgprint( "WSPRecvFrom: FindAndRefSocketContext failed!" );
02076         goto cleanup;
02077     }
02078 
02079     //
02080     // Check for overlapped I/O
02081     //
02082     if ( NULL != lpOverlapped )
02083     {
02084         ProviderOverlapped = PrepareOverlappedOperation(
02085                 SocketContext,
02086                 LSP_OP_RECVFROM,
02087                 lpBuffers,
02088                 dwBufferCount,
02089                 lpOverlapped,
02090                 lpCompletionRoutine,
02091                 lpThreadId,
02092                 lpErrno
02093                 );
02094         if ( NULL == ProviderOverlapped )
02095         {
02096             goto cleanup;
02097         }
02098 
02099         __try 
02100         {
02101             ProviderOverlapped->RecvFromArgs.lpFrom        = lpFrom;
02102             ProviderOverlapped->RecvFromArgs.lpFromLen     = lpFromLen;
02103         }
02104         __except(EXCEPTION_EXECUTE_HANDLER)
02105         {
02106             // Return to original state and indicate error
02107             *lpErrno = WSAEFAULT;
02108             goto cleanup;
02109         }
02110 
02111         //
02112         // Make the overlapped call which will always fail (either with WSA_IO_PENDING
02113         // or actual error code if something is wrong).
02114         //
02115         ret = QueueOverlappedOperation(ProviderOverlapped, SocketContext);
02116         if ( NO_ERROR != ret )
02117         {
02118             *lpErrno = ret;
02119             ret = SOCKET_ERROR;
02120         }
02121     }
02122     else
02123     {
02124         ASSERT( SocketContext->Provider->NextProcTable.lpWSPRecvFrom );
02125 
02126         // Make a blocking WSPRecvFrom call
02127         SetBlockingProvider(SocketContext->Provider);
02128         ret = SocketContext->Provider->NextProcTable.lpWSPRecvFrom(
02129                 SocketContext->ProviderSocket, 
02130                 lpBuffers, 
02131                 dwBufferCount,
02132                 lpNumberOfBytesRecvd, 
02133                 lpFlags, 
02134                 lpFrom, 
02135                 lpFromLen, 
02136                 lpOverlapped, 
02137                 lpCompletionRoutine, 
02138                 lpThreadId, 
02139                 lpErrno);
02140         SetBlockingProvider(NULL);
02141         if ( SOCKET_ERROR != ret )
02142         {
02143             SocketContext->BytesRecv += *lpNumberOfBytesRecvd;
02144         }
02145     }
02146 
02147 cleanup:
02148 
02149     if ( NULL != SocketContext )
02150         DerefSocketContext( SocketContext, lpErrno );
02151 
02152     return ret;
02153 }

int WSPAPI WSPSelect ( int  nfds,
fd_set FAR *  readfds,
fd_set FAR *  writefds,
fd_set FAR *  exceptfds,
const struct timeval FAR *  timeout,
LPINT  lpErrno 
)

Definition at line 2236 of file spi.cpp.

02244 {
02245     SOCK_INFO *SocketContext = NULL;
02246     u_int      count,
02247                i;
02248     BOOL       unlocked = FALSE;
02249     int        HandleCount,
02250                ret SOCKET_ERROR;
02251 
02252     fd_set     ReadFds, 
02253                WriteFds, 
02254                ExceptFds;
02255 
02256     FD_MAP    *Read = NULL, 
02257               *Write = NULL, 
02258               *Except = NULL;
02259 
02260     if ( ( NULL == readfds ) && ( NULL == writefds ) && ( NULL == exceptfds ) )
02261     {
02262         *lpErrno = WSAEINVAL;
02263         goto cleanup;
02264     }
02265 
02266     // Allocate storage to map upper level sockets to lower provider's sockets
02267     if ( NULL != readfds )
02268     {
02269         Read = (FD_MAP *) LspAlloc( sizeof( FD_MAP ) * readfds->fd_count, lpErrno );
02270         if ( NULL == Read )
02271             goto cleanup;
02272     }
02273 
02274     if ( NULL != writefds )
02275     {
02276         Write = (FD_MAP *) LspAlloc( sizeof( FD_MAP ) * writefds->fd_count, lpErrno );
02277         if ( NULL == Write )
02278             goto cleanup;
02279     }
02280 
02281     if ( NULL != exceptfds )
02282     {
02283         Except = (FD_MAP *) LspAlloc( sizeof( FD_MAP ) * exceptfds->fd_count, lpErrno );
02284         if ( NULL == Except )
02285             goto cleanup;
02286     }
02287 
02288     //
02289     // Translate all handles contained in the fd_set structures.
02290     //  For each fd_set go through and build another fd_set which contains
02291     //  their lower provider socket handles.
02292     //
02293 
02294     // Map the upper layer sockets to lower layer sockets in the write array
02295     if ( NULL != readfds )
02296     {
02297         FD_ZERO( &ReadFds );
02298 
02299         if ( readfds->fd_count > FD_SETSIZE )
02300         {
02301             *lpErrno = WSAENOBUFS;
02302             goto cleanup;
02303         }
02304 
02305         for (i = 0; i < readfds->fd_count; i++)
02306         {
02307             Read[i].Context = FindAndRefSocketContext(
02308                     (Read[i].ClientSocket = readfds->fd_array[i]),
02309                     lpErrno
02310                     );
02311             if ( NULL == Read[i].Context )
02312             {
02313                 // This socket isn't ours -- just pass down in hopes the lower provider
02314                 // knows about it
02315                 Read[i].ProvSocket = readfds->fd_array[i];
02316                 FD_SET(Read[i].ProvSocket, &ReadFds);
02317             }
02318             else
02319             {
02320                 Read[i].ProvSocket = Read[i].Context->ProviderSocket;
02321                 FD_SET(Read[i].ProvSocket, &ReadFds);
02322 
02323                 // Save the first valid socket context structure
02324                 if ( NULL == SocketContext )
02325                     SocketContext = Read[i].Context;
02326             }
02327         }
02328     }
02329 
02330     // Map the upper layer sockets to lower layer sockets in the write array
02331     if ( NULL != writefds )
02332     {
02333         FD_ZERO( &WriteFds );
02334 
02335         if ( writefds->fd_count > FD_SETSIZE )
02336         {
02337             *lpErrno = WSAENOBUFS;
02338             goto cleanup;
02339         }
02340         for (i = 0; i < writefds->fd_count; i++)
02341         {
02342             Write[i].Context = FindAndRefSocketContext(
02343                     (Write[i].ClientSocket = writefds->fd_array[i]), 
02344                     lpErrno
02345                     );
02346             if ( NULL == Write[i].Context )
02347             {
02348                 // This socket isn't ours -- just pass down in hopes the lower provider
02349                 // knows about it
02350                 Write[i].ProvSocket = writefds->fd_array[i];
02351                 FD_SET(Write[i].ProvSocket, &WriteFds);
02352             }
02353             else
02354             {
02355                 Write[i].ProvSocket = Write[i].Context->ProviderSocket;
02356                 FD_SET(Write[i].ProvSocket, &WriteFds);
02357 
02358                 // Save the first valid socket context structure
02359                 if ( NULL == SocketContext )
02360                     SocketContext = Write[i].Context;
02361             }
02362         }
02363     }
02364 
02365     // Map the upper layer sockets to lower layer sockets in the except array
02366     if ( NULL != exceptfds )
02367     {
02368         FD_ZERO( &ExceptFds );
02369 
02370         if (exceptfds->fd_count > FD_SETSIZE)
02371         {
02372             *lpErrno = WSAENOBUFS;
02373             goto cleanup;
02374         }
02375         for (i = 0; i < exceptfds->fd_count; i++)
02376         {
02377             Except[i].Context = FindAndRefSocketContext(
02378                     (Except[i].ClientSocket = exceptfds->fd_array[i]), 
02379                     lpErrno
02380                     );
02381             if ( NULL == Except[i].Context )
02382             {
02383                 // This socket isn't ours -- just pass down in hopes the lower provider
02384                 // knows about it
02385                 Except[i].ProvSocket = exceptfds->fd_array[i];
02386                 FD_SET(Except[i].ProvSocket, &ExceptFds);
02387             }
02388             else
02389             {
02390                 Except[i].ProvSocket = Except[i].Context->ProviderSocket;
02391                 FD_SET(Except[i].ProvSocket, &ExceptFds);
02392 
02393                 // Save the first valid socket context structure
02394                 if ( NULL == SocketContext )
02395                     SocketContext = Except[i].Context;
02396             }
02397         }
02398     }
02399 
02400     //
02401     // Now call the lower provider's WSPSelect with the fd_set structures we built
02402     //  containing the lower provider's socket handles.
02403     //
02404     if ( NULL == SocketContext )
02405     {
02406         *lpErrno = WSAEINVAL;
02407         goto cleanup;
02408     }
02409 
02410     ASSERT( SocketContext->Provider->NextProcTable.lpWSPSelect );
02411 
02412     SetBlockingProvider(SocketContext->Provider);
02413     ret = SocketContext->Provider->NextProcTable.lpWSPSelect(
02414             nfds, 
02415             (readfds ? &ReadFds : NULL), 
02416             (writefds ? &WriteFds : NULL), 
02417             (exceptfds ? &ExceptFds : NULL), 
02418             timeout, 
02419             lpErrno
02420             );
02421     SetBlockingProvider(NULL);
02422 
02423     // Need to unlock the contexts before the original fd_sets are modified
02424     UnlockFdSets( readfds, Read, writefds, Write, exceptfds, Except, lpErrno );
02425     unlocked = TRUE;
02426 
02427     if ( SOCKET_ERROR != ret )
02428     {
02429         // Once we complete we now have to go through the fd_sets we passed and
02430         //  map them BACK to the application socket handles. Fun!
02431         //
02432         HandleCount = ret;
02433 
02434         if ( NULL != readfds )
02435         {
02436             count = readfds->fd_count;
02437             FD_ZERO(readfds);
02438 
02439             for(i = 0; (i < count) && HandleCount; i++)
02440             {
02441                 if ( gMainUpCallTable.lpWPUFDIsSet(Read[i].ProvSocket, &ReadFds) )
02442                 {
02443                     FD_SET(Read[i].ClientSocket, readfds);
02444                     HandleCount--;
02445                 }
02446             }
02447         }
02448 
02449         if ( NULL != writefds )
02450         {
02451             count = writefds->fd_count;
02452             FD_ZERO(writefds);
02453 
02454             for(i = 0; (i < count) && HandleCount; i++)
02455             {
02456                 if ( gMainUpCallTable.lpWPUFDIsSet(Write[i].ProvSocket, &WriteFds) )
02457                 {
02458                     FD_SET(Write[i].ClientSocket, writefds);
02459                     HandleCount--;
02460                 }
02461             }
02462         }
02463 
02464         if ( NULL != exceptfds )
02465         {
02466             count = exceptfds->fd_count;
02467             FD_ZERO(exceptfds);
02468 
02469             for(i = 0; (i < count) && HandleCount; i++)
02470             {
02471                 if ( gMainUpCallTable.lpWPUFDIsSet(Except[i].ProvSocket, &ExceptFds) )
02472                 {
02473                     FD_SET(Except[i].ClientSocket, exceptfds);
02474                     HandleCount--;
02475                 }
02476             }
02477         }
02478     }
02479 
02480 cleanup:
02481 
02482     // In case of error, ensure the socket contexts get unlocked
02483     if ( FALSE == unlocked )
02484         UnlockFdSets( readfds, Read, writefds, Write, exceptfds, Except, lpErrno );
02485 
02486     // Unlock socket context here in case an error occurs
02487     if ( NULL != Read )
02488         LspFree( Read );
02489 
02490     if ( NULL != Write )
02491         LspFree( Write );
02492 
02493     if ( NULL != Except )
02494         LspFree( Except );
02495 
02496     return ret;
02497 }

int WSPAPI WSPSend ( SOCKET  s,
LPWSABUF  lpBuffers,
DWORD  dwBufferCount,
LPDWORD  lpNumberOfBytesSent,
DWORD  dwFlags,
LPWSAOVERLAPPED  lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine,
LPWSATHREADID  lpThreadId,
LPINT  lpErrno 
)

Definition at line 2509 of file spi.cpp.

02520 {
02521     INT                 ret = SOCKET_ERROR;
02522     SOCK_INFO          *SocketContext = NULL;
02523     LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
02524 
02525     *lpErrno = NO_ERROR;
02526 
02527     //
02528     // Find our provider socket corresponding to this one
02529     //
02530     SocketContext = FindAndRefSocketContext(s, lpErrno);
02531     if ( NULL == SocketContext )
02532     {
02533         dbgprint( "WSPSend: FindAndRefSocketContext failed!" );
02534         goto cleanup;
02535     }
02536 
02537     //
02538     // Check for overlapped I/O
02539     // 
02540     if ( NULL != lpOverlapped )
02541     {
02542         ProviderOverlapped = PrepareOverlappedOperation(
02543                 SocketContext,
02544                 LSP_OP_SEND,
02545                 lpBuffers,
02546                 dwBufferCount,
02547                 lpOverlapped,
02548                 lpCompletionRoutine,
02549                 lpThreadId,
02550                 lpErrno
02551                 );
02552         if ( NULL == ProviderOverlapped )
02553         {
02554             goto cleanup;
02555         }
02556 
02557         __try 
02558         {
02559             ProviderOverlapped->SendArgs.dwFlags       = dwFlags;
02560         }
02561         __except( EXCEPTION_EXECUTE_HANDLER )
02562         {
02563             // Return to original state and indicate error
02564             *lpErrno = WSAEFAULT;
02565             goto cleanup;
02566         }
02567 
02568         //
02569         // Make the overlapped call which will always fail (either with WSA_IO_PENDING
02570         // or actual error code if something is wrong).
02571         //
02572         ret = QueueOverlappedOperation(ProviderOverlapped, SocketContext);
02573         if ( NO_ERROR != ret )
02574         {
02575             *lpErrno = ret;
02576             ret = SOCKET_ERROR;
02577         }
02578     }
02579     else
02580     {
02581         ASSERT( SocketContext->Provider->NextProcTable.lpWSPSend );
02582 
02583         // Make a blocking send call
02584         SetBlockingProvider(SocketContext->Provider);
02585         ret = SocketContext->Provider->NextProcTable.lpWSPSend(
02586                 SocketContext->ProviderSocket, 
02587                 lpBuffers, 
02588                 dwBufferCount,
02589                 lpNumberOfBytesSent, 
02590                 dwFlags, 
02591                 lpOverlapped, 
02592                 lpCompletionRoutine, 
02593                 lpThreadId, 
02594                 lpErrno
02595                 );
02596         SetBlockingProvider(NULL);
02597         if ( SOCKET_ERROR != ret )
02598         {
02599             SocketContext->BytesSent += *lpNumberOfBytesSent;
02600         }
02601     }
02602 
02603 cleanup:
02604 
02605     if ( NULL != SocketContext )
02606         DerefSocketContext( SocketContext, lpErrno );
02607 
02608     return ret;
02609 }

int WSPAPI WSPSendDisconnect ( SOCKET  s,
LPWSABUF  lpOutboundDisconnectData,
LPINT  lpErrno 
)

Definition at line 2619 of file spi.cpp.

02624 {
02625     SOCK_INFO *SocketContext = NULL;
02626     INT        ret = SOCKET_ERROR;
02627 
02628     //
02629     // Find our provider socket corresponding to this one
02630     //
02631     SocketContext = FindAndRefSocketContext(s, lpErrno);
02632     if ( NULL == SocketContext )
02633     {
02634         dbgprint( "WSPSendDisconnect: FindAndRefSocketContext failed!" );
02635         goto cleanup;
02636     }
02637 
02638     ASSERT( SocketContext->Provider->NextProcTable.lpWSPSendDisconnect );
02639 
02640     SetBlockingProvider(SocketContext->Provider);
02641     ret = SocketContext->Provider->NextProcTable.lpWSPSendDisconnect(
02642             SocketContext->ProviderSocket,
02643             lpOutboundDisconnectData, 
02644             lpErrno
02645             );
02646     SetBlockingProvider(NULL);
02647 
02648 cleanup:
02649 
02650     if ( NULL != SocketContext )
02651         DerefSocketContext( SocketContext, lpErrno );
02652 
02653     return ret;
02654 }

int WSPAPI WSPSendTo ( SOCKET  s,
LPWSABUF  lpBuffers,
DWORD  dwBufferCount,
LPDWORD  lpNumberOfBytesSent,
DWORD  dwFlags,
const struct sockaddr FAR *  lpTo,
int  iToLen,
LPWSAOVERLAPPED  lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine,
LPWSATHREADID  lpThreadId,
LPINT  lpErrno 
)

Definition at line 2666 of file spi.cpp.

02679 {
02680     int                 ret = SOCKET_ERROR;
02681     SOCK_INFO          *SocketContext = NULL;
02682     LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
02683 
02684     //
02685     // Find our provider socket corresponding to this one
02686     //
02687     SocketContext = FindAndRefSocketContext(s, lpErrno);
02688     if ( NULL == SocketContext )
02689     {
02690         dbgprint( "WSPSendTo: FindAndRefSocketContext failed!" );
02691         goto cleanup;
02692     }
02693 
02694     //
02695     // Check for overlapped
02696     //
02697     if ( NULL != lpOverlapped )
02698     {
02699         ProviderOverlapped = PrepareOverlappedOperation(
02700                 SocketContext,
02701                 LSP_OP_SENDTO,
02702                 lpBuffers,
02703                 dwBufferCount,
02704                 lpOverlapped,
02705                 lpCompletionRoutine,
02706                 lpThreadId,
02707                 lpErrno
02708                 );
02709         if ( NULL == ProviderOverlapped )
02710             goto cleanup;
02711 
02712         __try 
02713         {
02714             ProviderOverlapped->SendToArgs.dwFlags             = dwFlags;
02715             ProviderOverlapped->SendToArgs.iToLen              = iToLen;
02716             ProviderOverlapped->SendToArgs.dwNumberOfBytesSent = (lpNumberOfBytesSent ? *lpNumberOfBytesSent : 0);
02717             if ( iToLen <= sizeof( ProviderOverlapped->SendToArgs.To ) )
02718                 CopyMemory(&ProviderOverlapped->SendToArgs.To, lpTo, iToLen);
02719         }
02720         __except( EXCEPTION_EXECUTE_HANDLER )
02721         {
02722             // Return to original state and indicate error
02723             *lpErrno = WSAEFAULT;
02724             goto cleanup;
02725         }
02726 
02727         //
02728         // Make the overlapped call which will always fail (either with WSA_IO_PENDING
02729         // or actual error code if something is wrong).
02730         //
02731         ret = QueueOverlappedOperation(ProviderOverlapped, SocketContext);
02732         if ( NO_ERROR != ret )
02733         {
02734             *lpErrno = ret;
02735             ret = SOCKET_ERROR;
02736         }
02737     }
02738     else
02739     {
02740         ASSERT( SocketContext->Provider->NextProcTable.lpWSPSendTo );
02741 
02742         SetBlockingProvider(SocketContext->Provider);
02743         ret = SocketContext->Provider->NextProcTable.lpWSPSendTo(
02744                 SocketContext->ProviderSocket, 
02745                 lpBuffers, 
02746                 dwBufferCount,
02747                 lpNumberOfBytesSent, 
02748                 dwFlags, 
02749                 lpTo, 
02750                 iToLen, 
02751                 lpOverlapped, 
02752                 lpCompletionRoutine, 
02753                 lpThreadId, 
02754                 lpErrno
02755                 );
02756         SetBlockingProvider(NULL);
02757         if ( SOCKET_ERROR != ret )
02758         {
02759             SocketContext->BytesSent += *lpNumberOfBytesSent;
02760         }
02761     }
02762 
02763 cleanup:
02764 
02765     if ( NULL != SocketContext )
02766         DerefSocketContext( SocketContext, lpErrno );
02767 
02768     return ret;
02769 }

int WSPAPI WSPSetSockOpt ( SOCKET  s,
int  level,
int  optname,
const char FAR *  optval,
int  optlen,
LPINT  lpErrno 
)

Definition at line 2780 of file spi.cpp.

02788 {
02789     SOCK_INFO *SocketContext = NULL,
02790               *AcceptContext = NULL;
02791     INT        ret = SOCKET_ERROR;
02792 
02793     SocketContext = FindAndRefSocketContext(s, lpErrno);
02794     if ( NULL == SocketContext )
02795     {
02796         dbgprint( "WSPSetSockOpt: FindAndRefSocketContext failed!" );
02797         goto cleanup;
02798     }
02799 
02800     ASSERT( SocketContext->Provider->NextProcTable.lpWSPSetSockOpt );
02801 
02802     if ( SO_UPDATE_ACCEPT_CONTEXT == optname )
02803     {
02804         // We need to intercept this (and any other options) that pass
02805         //  a socket handle as an argument so we can replace it with the
02806         //  correct underlying provider's socket handle.
02807         //
02808         AcceptContext = FindAndRefSocketContext( *((SOCKET *)optval), lpErrno);
02809         if ( NULL == AcceptContext )
02810         {
02811             dbgprint( "WSPSetSockOpt: SO_UPDATE_ACCEPT_CONTEXT: FindAndRefSocketContext failed!" );
02812             goto cleanup;
02813         }
02814 
02815         SetBlockingProvider(SocketContext->Provider);
02816         ret = SocketContext->Provider->NextProcTable.lpWSPSetSockOpt(
02817                 SocketContext->ProviderSocket, 
02818                 level,
02819                 optname, 
02820                 (char *)&AcceptContext->ProviderSocket, 
02821                 optlen, 
02822                 lpErrno
02823                 );
02824         SetBlockingProvider(NULL);
02825     }
02826     else
02827     {
02828         SetBlockingProvider(SocketContext->Provider);
02829         ret = SocketContext->Provider->NextProcTable.lpWSPSetSockOpt(
02830                 SocketContext->ProviderSocket, 
02831                 level,                 
02832                 optname, 
02833                 optval, 
02834                 optlen, 
02835                 lpErrno
02836                 );
02837         SetBlockingProvider(NULL);
02838     }
02839 
02840 cleanup:
02841 
02842     if ( NULL != SocketContext )
02843         DerefSocketContext( SocketContext, lpErrno );
02844 
02845     if ( NULL != AcceptContext )
02846         DerefSocketContext( AcceptContext, lpErrno );
02847 
02848     return ret;
02849 }

int WSPAPI WSPShutdown ( SOCKET  s,
int  how,
LPINT  lpErrno 
)

Definition at line 2859 of file spi.cpp.

02864 {
02865     SOCK_INFO *SocketContext = NULL;
02866     INT        ret = SOCKET_ERROR;
02867 
02868     SocketContext = FindAndRefSocketContext(s, lpErrno);
02869     if ( NULL == SocketContext )
02870     {
02871         dbgprint( "WSPShutdown: FindAndRefSocketContext failed!" );
02872         goto cleanup;
02873     }
02874 
02875     ASSERT( SocketContext->Provider->NextProcTable.lpWSPShutdown );
02876 
02877     SetBlockingProvider(SocketContext->Provider);
02878     ret = SocketContext->Provider->NextProcTable.lpWSPShutdown(
02879             SocketContext->ProviderSocket, 
02880             how, 
02881             lpErrno
02882             );
02883     SetBlockingProvider(NULL);
02884 
02885 cleanup:
02886 
02887     if ( NULL != SocketContext )
02888         DerefSocketContext( SocketContext, lpErrno );
02889 
02890     return ret;
02891 }

SOCKET WSPAPI WSPSocket ( int  af,
int  type,
int  protocol,
__in LPWSAPROTOCOL_INFOW  lpProtocolInfo,
GROUP  g,
DWORD  dwFlags,
LPINT  lpErrno 
)

Definition at line 2995 of file spi.cpp.

03004 {
03005     SOCKET              NextProviderSocket = INVALID_SOCKET;
03006     SOCKET              NewSocket = INVALID_SOCKET;
03007     SOCK_INFO          *SocketContext = NULL;
03008     WSAPROTOCOL_INFOW  *pInfo = NULL, 
03009                         InfoCopy;
03010     PROVIDER           *Provider = NULL;
03011     BOOL                bAddressFamilyOkay = FALSE,
03012                         bSockTypeOkay = FALSE,
03013                         bProtocolOkay = FALSE;
03014     INT                 iAddressFamily,
03015                         iSockType, 
03016                         iProtocol, 
03017                         i;
03018 
03019     *lpErrno = NO_ERROR;
03020 
03021     //
03022     // If a WSAPROTOCOL_INFO structure was passed in, use those socket/protocol
03023     //  values. Then find the underlying provider's WSAPROTOCOL_INFO structure.
03024     //
03025     iAddressFamily = (lpProtocolInfo ? lpProtocolInfo->iAddressFamily : af);
03026     iProtocol      = (lpProtocolInfo ? lpProtocolInfo->iProtocol   : protocol);
03027     iSockType      = (lpProtocolInfo ? lpProtocolInfo->iSocketType : type);
03028 
03029     #ifdef DEBUG
03030     if (lpProtocolInfo)
03031         dbgprint("WSPSocket: Provider: '%S'", lpProtocolInfo->szProtocol);
03032     #endif
03033 
03034     for(i=0; i < gLayerCount ;i++)
03035     {
03036         if ( ( iAddressFamily == AF_UNSPEC) ||
03037              ( iAddressFamily == gBaseInfo[i].NextProvider.iAddressFamily )
03038            )
03039         {
03040             bAddressFamilyOkay = TRUE;
03041         }
03042         if ( iSockType == gBaseInfo[i].NextProvider.iSocketType )
03043         {
03044             bSockTypeOkay = TRUE;
03045         }
03046         if ( ( iProtocol == 0) || 
03047              ( iProtocol == gBaseInfo[i].NextProvider.iProtocol) ||
03048              ( iProtocol == IPPROTO_RAW) || 
03049               (iSockType == SOCK_RAW )
03050            )
03051         {
03052             bProtocolOkay = TRUE;
03053         }
03054     }
03055     if ( FALSE == bAddressFamilyOkay )
03056     {
03057         *lpErrno = WSAEAFNOSUPPORT;
03058         goto cleanup;
03059     }
03060     if ( FALSE == bSockTypeOkay )
03061     {
03062         *lpErrno = WSAESOCKTNOSUPPORT;
03063         goto cleanup;
03064     }
03065     if ( FALSE == bProtocolOkay )
03066     {
03067         *lpErrno = WSAEPROTONOSUPPORT;
03068         goto cleanup;
03069     }
03070 
03071     //
03072     // If AF_UNSPEC was passed in we need to go by the socket type and protocol
03073     //  if possible.
03074     //
03075     if ( ( AF_UNSPEC == iAddressFamily ) && ( 0 == iProtocol ) )
03076     {
03077         for(i=0; i < gLayerCount ;i++)
03078         {
03079             if ( gBaseInfo[i].NextProvider.iSocketType == iSockType )
03080             {
03081                 if ( NULL != lpProtocolInfo )
03082                 {
03083                     // In case of multiple providers check the provider flags 
03084                     if ( (gBaseInfo[i].NextProvider.dwServiceFlags1 & ~XP1_IFS_HANDLES) != 
03085                          (lpProtocolInfo->dwServiceFlags1 & ~XP1_IFS_HANDLES) )
03086                     {
03087                         continue;
03088                     }
03089                 }
03090                 Provider = &gBaseInfo[i];
03091                 pInfo = &gBaseInfo[i].NextProvider;
03092                 //if ( NULL != lpProtocolInfo )
03093                 //    pInfo->dwProviderReserved = lpProtocolInfo->dwProviderReserved;
03094                 break;
03095             }
03096         }
03097     }
03098     else if ( ( AF_UNSPEC == iAddressFamily ) && ( 0 != iProtocol ) )
03099     {
03100         for(i=0; i < gLayerCount ;i++)
03101         {
03102             if ( ( gBaseInfo[i].NextProvider.iProtocol == iProtocol ) &&
03103                  ( gBaseInfo[i].NextProvider.iSocketType == iSockType ) 
03104                )
03105             {
03106                 if ( NULL != lpProtocolInfo )
03107                 {
03108                     // In case of multiple providers check the provider flags 
03109                     if ( (gBaseInfo[i].NextProvider.dwServiceFlags1 & ~XP1_IFS_HANDLES) != 
03110                          (lpProtocolInfo->dwServiceFlags1 & ~XP1_IFS_HANDLES) )
03111                     {
03112                         continue;
03113                     }
03114                 }
03115                 Provider = &gBaseInfo[i];
03116                 pInfo = &gBaseInfo[i].NextProvider;
03117                 //if ( NULL != lpProtocolInfo )
03118                 //    pInfo->dwProviderReserved = lpProtocolInfo->dwProviderReserved;
03119                 break;
03120             }
03121         }
03122         if ( NULL == pInfo )
03123         {
03124             *lpErrno = WSAEPROTOTYPE;
03125             goto cleanup;
03126         }
03127     }
03128     else if ( ( 0 != iProtocol ) && 
03129               ( IPPROTO_RAW != iProtocol ) && 
03130               ( SOCK_RAW != iSockType ) 
03131             )
03132     {
03133         for(i=0; i < gLayerCount ;i++)
03134         {
03135             if ((gBaseInfo[i].NextProvider.iAddressFamily == iAddressFamily) &&
03136                 (gBaseInfo[i].NextProvider.iSocketType == iSockType) &&
03137                 (gBaseInfo[i].NextProvider.iProtocol == iProtocol))
03138             {
03139                 if ( NULL != lpProtocolInfo )
03140                 {
03141                     // In case of multiple providers check the provider flags 
03142                     if ( (gBaseInfo[i].NextProvider.dwServiceFlags1 & ~XP1_IFS_HANDLES) != 
03143                          (lpProtocolInfo->dwServiceFlags1 & ~XP1_IFS_HANDLES) )
03144                     {
03145                         continue;
03146                     }
03147                 }
03148                 Provider = &gBaseInfo[i];
03149                 pInfo = &gBaseInfo[i].NextProvider;
03150                 //if ( NULL != lpProtocolInfo )
03151                 //    pInfo->dwProviderReserved = lpProtocolInfo->dwProviderReserved;
03152                 break;
03153             }
03154         }
03155     }
03156     else
03157     {
03158         for(i=0; i < gLayerCount ;i++)
03159         {
03160             if ( ( gBaseInfo[i].NextProvider.iAddressFamily == iAddressFamily ) &&
03161                  ( gBaseInfo[i].NextProvider.iSocketType == iSockType )
03162                )
03163             {
03164                 if ( NULL != lpProtocolInfo )
03165                 {
03166                     // In case of multiple providers check the provider flags 
03167                     if ( (gBaseInfo[i].NextProvider.dwServiceFlags1 & ~XP1_IFS_HANDLES) != 
03168                          (lpProtocolInfo->dwServiceFlags1 & ~XP1_IFS_HANDLES) )
03169                     {
03170                         continue;
03171                     }
03172                 }
03173                 Provider = &gBaseInfo[i];
03174                 pInfo = &gBaseInfo[i].NextProvider;
03175                 //if ( NULL != lpProtocolInfo )
03176                 //    pInfo->dwProviderReserved = lpProtocolInfo->dwProviderReserved;
03177                 break;
03178             }
03179         }
03180     }
03181     if ( NULL == Provider )
03182     {
03183         *lpErrno = WSAEAFNOSUPPORT;
03184         return INVALID_SOCKET;
03185     }
03186 
03187     if ( BASE_PROTOCOL != pInfo->ProtocolChain.ChainLen )
03188     {
03189         pInfo = lpProtocolInfo;
03190     }
03191 
03192     memcpy(&InfoCopy, pInfo, sizeof(InfoCopy));
03193 
03194     if ( NULL != lpProtocolInfo )
03195     {
03196         InfoCopy.dwProviderReserved = lpProtocolInfo->dwProviderReserved;
03197         if ( InfoCopy.dwProviderReserved )
03198             dbgprint("WSPSocket: dwProviderReserved = %d", InfoCopy.dwProviderReserved );
03199     }
03200 
03201     if ( 0 == Provider->StartupCount ) 
03202     {
03203         if ( SOCKET_ERROR == InitializeProvider( Provider, MAKEWORD(2,2), lpProtocolInfo, 
03204                 gMainUpCallTable, lpErrno ) )
03205         {
03206             dbgprint("WSPSocket: InitializeProvider failed: %d", *lpErrno );
03207             goto cleanup;
03208         }
03209     }
03210 
03211     //
03212     // Create the underlying provider's socket.
03213     //
03214 
03215     dbgprint("Calling the lower provider WSPSocket: '%S'", Provider->NextProvider.szProtocol);
03216 
03217     ASSERT( Provider->NextProcTable.lpWSPSocket );
03218 
03219     SetBlockingProvider(Provider);
03220     NextProviderSocket = Provider->NextProcTable.lpWSPSocket(
03221             af, 
03222             type, 
03223             protocol, 
03224            &InfoCopy,
03225             g, 
03226             dwFlags | WSA_FLAG_OVERLAPPED, // Always Or in the overlapped flag
03227             lpErrno
03228             );
03229     SetBlockingProvider(NULL);
03230 
03231     if ( INVALID_SOCKET == NextProviderSocket )
03232     {
03233         dbgprint("WSPSocket: NextProcTable.WSPSocket() failed: %d", *lpErrno);
03234         goto cleanup;
03235     }
03236 
03237     //
03238     // Create the context information to be associated with this socket
03239     //
03240     SocketContext = CreateSockInfo(
03241             Provider,
03242             NextProviderSocket,
03243             NULL,
03244             TRUE,
03245             lpErrno
03246             );
03247     if ( NULL == SocketContext )
03248     {
03249         dbgprint( "WSPSocket: CreateSockInfo failed: %d", *lpErrno );
03250         goto cleanup;
03251     }
03252 
03253     //
03254     // Create a socket handle to pass back to app
03255     //  
03256     NewSocket = gMainUpCallTable.lpWPUCreateSocketHandle(
03257             Provider->LayerProvider.dwCatalogEntryId,
03258             (DWORD_PTR) SocketContext, 
03259             lpErrno
03260             );
03261     if ( INVALID_SOCKET == NewSocket )
03262     {
03263         int tempErr;
03264 
03265         dbgprint("WSPSocket: WPUCreateSocketHandle() failed: %d", *lpErrno);
03266 
03267         Provider->NextProcTable.lpWSPCloseSocket(
03268                 NextProviderSocket, 
03269                &tempErr
03270                 );
03271 
03272         goto cleanup;
03273     }
03274 
03275     dbgprint("Lower provider socket = 0x%x  LSP Socket = 0x%x\n", NextProviderSocket, NewSocket);
03276 
03277     SocketContext->LayeredSocket = NewSocket;
03278 
03279     //pInfo->dwProviderReserved = 0;
03280 
03281     return NewSocket;
03282 
03283 cleanup:
03284 
03285     if ( ( NULL != Provider ) && ( NULL != SocketContext ) )
03286         RemoveSocketInfo(Provider, SocketContext);
03287 
03288     if ( NULL != SocketContext )
03289         FreeSockInfo(SocketContext);
03290 
03291     return INVALID_SOCKET;
03292 }

int WSPAPI WSPStringToAddress ( LPWSTR  AddressString,
INT  AddressFamily,
LPWSAPROTOCOL_INFOW  lpProtocolInfo,
LPSOCKADDR  lpAddress,
LPINT  lpAddressLength,
LPINT  lpErrno 
)

Definition at line 2902 of file spi.cpp.

02910 {
02911     WSAPROTOCOL_INFOW   *pInfo = NULL;
02912     PROVIDER            *Provider = NULL;
02913     INT                  ret = SOCKET_ERROR,
02914                          i;
02915 
02916     for(i=0; i < gLayerCount ;i++)
02917     {
02918         if ( ( gBaseInfo[i].NextProvider.iAddressFamily == lpProtocolInfo->iAddressFamily ) &&
02919              ( gBaseInfo[i].NextProvider.iSocketType == lpProtocolInfo->iSocketType ) && 
02920              ( gBaseInfo[i].NextProvider.iProtocol   == lpProtocolInfo->iProtocol )
02921            )
02922         {
02923             if ( NULL != lpProtocolInfo )
02924             {
02925                 // In case of multiple providers check the provider flags 
02926                 if ( ( gBaseInfo[i].NextProvider.dwServiceFlags1 & ~XP1_IFS_HANDLES ) != 
02927                      ( lpProtocolInfo->dwServiceFlags1 & ~XP1_IFS_HANDLES ) 
02928                    )
02929                 {
02930                     continue;
02931                 }
02932             }
02933             Provider = &gBaseInfo[i];
02934             pInfo = &gBaseInfo[i].NextProvider;
02935             break;
02936         }
02937     }
02938 
02939     if ( NULL == Provider )
02940     {
02941         *lpErrno = WSAEINVAL;
02942         goto cleanup;
02943     }
02944 
02945     //
02946     // If we're not immediately above the base then pass the lpProtocolInfo passed
02947     // into us.
02948     //
02949     if ( BASE_PROTOCOL != pInfo->ProtocolChain.ChainLen )
02950     {
02951         pInfo = lpProtocolInfo;
02952     }
02953 
02954     if ( 0 == Provider->StartupCount )
02955     {
02956         if ( SOCKET_ERROR == InitializeProvider( Provider, MAKEWORD(2,2), lpProtocolInfo,
02957                 gMainUpCallTable, lpErrno ) )
02958         {
02959             dbgprint("WSPStringToAddress: InitializeProvider failed: %d", *lpErrno );
02960             goto cleanup;
02961         }
02962     }
02963 
02964     ASSERT( Provider->NextProcTable.lpWSPStringToAddress );
02965 
02966     SetBlockingProvider(Provider);
02967     ret = Provider->NextProcTable.lpWSPStringToAddress(
02968             AddressString, 
02969             AddressFamily,
02970             pInfo, 
02971             lpAddress, 
02972             lpAddressLength, 
02973             lpErrno
02974             );
02975     SetBlockingProvider(NULL);
02976 
02977 cleanup:
02978 
02979     return ret;
02980 }


Variable Documentation

Definition at line 43 of file spi.cpp.

Definition at line 41 of file spi.cpp.

CRITICAL_SECTION gCriticalSection

Definition at line 37 of file spi.cpp.

HINSTANCE gDllInstance

Definition at line 40 of file spi.cpp.

HANDLE gIocp

Definition at line 47 of file overlap.cpp.

Definition at line 42 of file spi.cpp.

WSPUPCALLTABLE gMainUpCallTable

Definition at line 39 of file spi.cpp.

CRITICAL_SECTION gOverlappedCS

Definition at line 37 of file spi.cpp.

Definition at line 37 of file lspguid.cpp.