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


spi.cpp File Reference

#include "lspdef.h"
#include <stdio.h>
#include <stdlib.h>

Include dependency graph for spi.cpp:

Go to the source code of this file.


Defines

#define SetBlockingProvider(Provider)

Functions

void FreeSocketsAndMemory (BOOL processDetach, int *lpErrno)
void PrintProcTable (LPWSPPROC_TABLE lpProcTable)
BOOL WINAPI DllMain (IN HINSTANCE hinstDll, IN DWORD dwReason, LPVOID lpvReserved)
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)
void UnlockFdSets (fd_set *readfds, FD_MAP *readmap, fd_set *writefds, FD_MAP *writemap, fd_set *exceptfds, FD_MAP *exceptmap, 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)
int WSPAPI WSPStartup (WORD wVersion, LPWSPDATA lpWSPData, LPWSAPROTOCOL_INFOW lpProtocolInfo, WSPUPCALLTABLE UpCallTable, LPWSPPROC_TABLE lpProcTable)
void CopyOffset (WSAOVERLAPPED *ProviderOverlapped, WSAOVERLAPPED *UserOverlapped)
WSABUF * CopyWSABuf (WSABUF *BufferArray, DWORD BufferCount, int *lpErrno)
void FreeWSABuf (WSABUF *BufferArray)

Variables

CRITICAL_SECTION gCriticalSection
CRITICAL_SECTION gOverlappedCS
WSPUPCALLTABLE gMainUpCallTable
HINSTANCE gDllInstance = NULL
LPPROVIDER gBaseInfo = NULL
INT gLayerCount = 0
HANDLE gAddContextEvent = NULL

Define Documentation

#define SetBlockingProvider ( Provider   ) 

Value:

( gTlsIndex!=0xFFFFFFFF )                   \
        ? TlsSetValue ( gTlsIndex, Provider )   \
        : NULL

Definition at line 62 of file spi.cpp.


Function Documentation

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 }

BOOL WINAPI DllMain ( IN HINSTANCE  hinstDll,
IN DWORD  dwReason,
LPVOID  lpvReserved 
)

Definition at line 175 of file spi.cpp.

00180 {
00181     switch (dwReason)
00182     {
00183 
00184         case DLL_PROCESS_ATTACH:
00185             gDllInstance = hinstDll;
00186             //
00187             // Initialize some critical section objects 
00188             //
00189             __try
00190             {
00191                 InitializeCriticalSection( &gCriticalSection );
00192                 InitializeCriticalSection( &gOverlappedCS );
00193                 InitializeCriticalSection( &gDebugCritSec );
00194             }
00195             __except( EXCEPTION_EXECUTE_HANDLER )
00196             {
00197                 goto cleanup;
00198             }
00199 
00200             gTlsIndex = TlsAlloc();
00201             break;
00202 
00203         case DLL_THREAD_ATTACH:
00204             break;
00205 
00206         case DLL_THREAD_DETACH:
00207             break;
00208 
00209         case DLL_PROCESS_DETACH:
00210             gDetached = TRUE;
00211 
00212             EnterCriticalSection( &gCriticalSection );
00213             if ( NULL != gBaseInfo )
00214             {
00215                 int Error;
00216 
00217                 StopAsyncWindowManager();
00218                 StopOverlappedManager();
00219 
00220                 Sleep(200);
00221 
00222                 FreeSocketsAndMemory( TRUE, &Error );
00223             }
00224             LeaveCriticalSection( &gCriticalSection );
00225 
00226             DeleteCriticalSection( &gCriticalSection );
00227             DeleteCriticalSection( &gOverlappedCS );
00228             DeleteCriticalSection( &gDebugCritSec );
00229 
00230             if ( NULL == lpvReserved )
00231             {
00232                 if ( 0xFFFFFFFF != gTlsIndex )
00233                 {
00234                     TlsFree( gTlsIndex );
00235                     gTlsIndex = 0xFFFFFFFF;
00236                 }
00237             }
00238             break;
00239     }
00240 
00241     return TRUE;
00242 
00243 cleanup:
00244 
00245     return FALSE;
00246 }

void FreeSocketsAndMemory ( BOOL  processDetach,
int *  lpErrno 
)

Definition at line 3533 of file spi.cpp.

03537 {
03538     int     ret,
03539             i;
03540 
03541     if ( NULL != gBaseInfo )
03542     {
03543         // Walk through each PROVIDER entry in the array
03544         for(i=0; i < gLayerCount ;i++)
03545         {
03546             if ( NULL != gBaseInfo[i].Module )
03547             {
03548                 //
03549                 // Close all sockets created from this provider
03550                 //
03551                 CloseAndFreeSocketInfo( &gBaseInfo[i], processDetach );
03552 
03553                 //
03554                 // Call the WSPCleanup of the provider's were layered over.
03555                 //
03556 
03557                 if ( ( !processDetach ) || 
03558                      ( gBaseInfo[ i ].NextProvider.ProtocolChain.ChainLen == BASE_PROTOCOL ) )
03559                 {
03560                     while( 0 != gBaseInfo[ i ].StartupCount )
03561                     {
03562                         gBaseInfo[ i ].StartupCount--;
03563 
03564                         if ( gBaseInfo[i].NextProcTable.lpWSPCleanup != NULL )
03565                             ret = gBaseInfo[i].NextProcTable.lpWSPCleanup( lpErrno );
03566                     }
03567                 }
03568 
03569                 DeleteCriticalSection( &gBaseInfo[i].ProviderCritSec );
03570 
03571                 if ( NULL != gBaseInfo[i].Module )
03572                     FreeLibrary( gBaseInfo[i].Module );
03573 
03574                 gBaseInfo[i].Module = NULL;
03575             }
03576         }
03577 
03578         LspFree( gBaseInfo );
03579         gBaseInfo = NULL;
03580     }
03581 
03582     if ( NULL != gAddContextEvent )
03583     {
03584         CloseHandle( gAddContextEvent );
03585         gAddContextEvent = NULL;
03586     }
03587 
03588     LspDestroyHeap();
03589 }

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 }

void PrintProcTable ( LPWSPPROC_TABLE  lpProcTable  ) 

Definition at line 127 of file spi.cpp.

00130 {
00131     #ifdef DBG_PRINTPROCTABLE
00132     dbgprint("WSPAccept              = 0x%X", lpProcTable->lpWSPAccept);
00133     dbgprint("WSPAddressToString     = 0x%X", lpProcTable->lpWSPAddressToString);
00134     dbgprint("WSPAsyncSelect         = 0x%X", lpProcTable->lpWSPAsyncSelect);
00135     dbgprint("WSPBind                = 0x%X", lpProcTable->lpWSPBind);
00136     dbgprint("WSPCancelBlockingCall  = 0x%X", lpProcTable->lpWSPCancelBlockingCall);
00137     dbgprint("WSPCleanup             = 0x%X", lpProcTable->lpWSPCleanup);
00138     dbgprint("WSPCloseSocket         = 0x%X", lpProcTable->lpWSPCloseSocket);
00139     dbgprint("WSPConnect             = 0x%X", lpProcTable->lpWSPConnect);
00140     dbgprint("WSPDuplicateSocket     = 0x%X", lpProcTable->lpWSPDuplicateSocket);
00141     dbgprint("WSPEnumNetworkEvents   = 0x%X", lpProcTable->lpWSPEnumNetworkEvents);
00142     dbgprint("WSPEventSelect         = 0x%X", lpProcTable->lpWSPEventSelect);
00143     dbgprint("WSPGetOverlappedResult = 0x%X", lpProcTable->lpWSPGetOverlappedResult);
00144     dbgprint("WSPGetPeerName         = 0x%X", lpProcTable->lpWSPGetPeerName);
00145     dbgprint("WSPGetSockOpt          = 0x%X", lpProcTable->lpWSPGetSockOpt);
00146     dbgprint("WSPGetSockName         = 0x%X", lpProcTable->lpWSPGetSockName);
00147     dbgprint("WSPGetQOSByName        = 0x%X", lpProcTable->lpWSPGetQOSByName);
00148     dbgprint("WSPIoctl               = 0x%X", lpProcTable->lpWSPIoctl);
00149     dbgprint("WSPJoinLeaf            = 0x%X", lpProcTable->lpWSPJoinLeaf);
00150     dbgprint("WSPListen              = 0x%X", lpProcTable->lpWSPListen);
00151     dbgprint("WSPRecv                = 0x%X", lpProcTable->lpWSPRecv);
00152     dbgprint("WSPRecvDisconnect      = 0x%X", lpProcTable->lpWSPRecvDisconnect);
00153     dbgprint("WSPRecvFrom            = 0x%X", lpProcTable->lpWSPRecvFrom);
00154     dbgprint("WSPSelect              = 0x%X", lpProcTable->lpWSPSelect);
00155     dbgprint("WSPSend                = 0x%X", lpProcTable->lpWSPSend);
00156     dbgprint("WSPSendDisconnect      = 0x%X", lpProcTable->lpWSPSendDisconnect);
00157     dbgprint("WSPSendTo              = 0x%X", lpProcTable->lpWSPSendTo);
00158     dbgprint("WSPSetSockOpt          = 0x%X", lpProcTable->lpWSPSetSockOpt);
00159     dbgprint("WSPShutdown            = 0x%X", lpProcTable->lpWSPShutdown);
00160     dbgprint("WSPSocket              = 0x%X", lpProcTable->lpWSPSocket);
00161     dbgprint("WSPStringToAddress     = 0x%X", lpProcTable->lpWSPStringToAddress);
00162     #else
00163     UNREFERENCED_PARAMETER( lpProcTable );  // For W4 compliance
00164     #endif
00165 }

void UnlockFdSets ( fd_set *  readfds,
FD_MAP readmap,
fd_set *  writefds,
FD_MAP writemap,
fd_set *  exceptfds,
FD_MAP exceptmap,
LPINT  lpErrno 
)

Definition at line 2166 of file spi.cpp.

02175 {
02176     int     i;
02177 
02178     // Unlock socket contexts for the readfds sockets
02179     if ( NULL != readfds )
02180     {
02181         for(i=0; i < (int)readfds->fd_count ;i++)
02182         {
02183             if ( NULL != readmap[i].Context )
02184             {
02185                 DerefSocketContext( readmap[i].Context, lpErrno );
02186                 readmap[i].Context = NULL;
02187             }
02188         }
02189     }
02190 
02191     // Unlock socket contexts for the writefds sockets
02192     if ( NULL != writefds )
02193     {
02194         for(i=0; i < (int)writefds->fd_count ;i++)
02195         {
02196             if ( NULL != writemap[i].Context )
02197             {
02198                 DerefSocketContext( writemap[i].Context, lpErrno );
02199                 writemap[i].Context = NULL;
02200             }
02201         }
02202     }
02203 
02204     // Unlock socket contexts for the except sockets
02205     if ( NULL != exceptfds )
02206     {
02207         for(i=0; i < (int)exceptfds->fd_count ;i++)
02208         {
02209             if ( NULL != exceptmap[i].Context )
02210             {
02211                 DerefSocketContext( exceptmap[i].Context, lpErrno );
02212                 exceptmap[i].Context = NULL;
02213             }
02214         }
02215     }
02216 }

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 WSPStartup ( WORD  wVersion,
LPWSPDATA  lpWSPData,
LPWSAPROTOCOL_INFOW  lpProtocolInfo,
WSPUPCALLTABLE  UpCallTable,
LPWSPPROC_TABLE  lpProcTable 
)

Definition at line 3322 of file spi.cpp.

03329 {
03330     PROVIDER           *loadProvider = NULL;
03331     INT                 ret,
03332                         Error = WSAEPROVIDERFAILEDINIT;
03333 
03334     EnterCriticalSection( &gCriticalSection );
03335 
03336     //
03337     // Load Next Provider in chain if this is the first time called
03338     //
03339     if ( 0 == gEntryCount )
03340     {
03341         ret = LspCreateHeap( &Error );
03342         if ( SOCKET_ERROR == ret )
03343         {
03344             dbgprint("WSPStartup: LspCreateHeap failed: %d", Error );
03345             goto cleanup;
03346         }
03347 
03348         memcpy( &gMainUpCallTable, &UpCallTable, sizeof( gMainUpCallTable ) );
03349 
03350         // Create an event which is signaled when a socket context is added
03351         gAddContextEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
03352         if ( NULL == gAddContextEvent )
03353         {
03354             dbgprint("WSPStartup: CreateEvent failed: %d", GetLastError());
03355             goto cleanup;
03356         }
03357 
03358         ret = FindLspEntries( &gBaseInfo, &gLayerCount, &Error );
03359         if ( FALSE == ret )
03360         {
03361             dbgprint("WSPStartup: FindLspEntries failed: %d", Error );
03362             goto cleanup;
03363         }
03364 
03365         //
03366         // Initialize the overlapped manager. This creates the completion port used
03367         // by the LSP which needs to occur here since other parts of the LSP use the
03368         // gIocp variable to determine whether we're on Win9x or NT.
03369         //
03370         Error = InitOverlappedManager();
03371     }
03372 
03373     loadProvider = FindMatchingLspEntryForProtocolInfo(
03374             lpProtocolInfo,
03375             gBaseInfo,
03376             gLayerCount,
03377             TRUE
03378             );
03379     if ( NULL == loadProvider )
03380     {
03381         dbgprint("WSPStartup: FindMatchingLspEntryForProtocolInfo failed!");
03382         ASSERT( 0 );
03383         goto cleanup;
03384     }
03385 
03386     if ( 0 == loadProvider->StartupCount )
03387     {
03388         if ( SOCKET_ERROR == InitializeProvider( loadProvider, wVersion, lpProtocolInfo, 
03389                 UpCallTable, &Error ) )
03390         {
03391             dbgprint("WSPStartup: InitializeProvider failed: %d", Error );
03392             goto cleanup;
03393         }
03394     }
03395 
03396     gEntryCount++;
03397 
03398     //
03399     // Copy the LSP's proc table to the caller's data structures
03400     //
03401     memcpy( lpWSPData, &loadProvider->WinsockVersion, sizeof( WSPDATA ) );
03402     memcpy( lpProcTable, &gProcTable, sizeof( WSPPROC_TABLE ) );
03403 
03404     Error = NO_ERROR;
03405 
03406 cleanup:
03407 
03408     if ( NO_ERROR != Error )
03409     {
03410         dbgprint( "WSPStartup failed!" );
03411 
03412         // Had errors during initialization and gEntryCount is still zero so
03413         // cleanup the internal structures
03414         FreeSocketsAndMemory( FALSE, &Error );
03415     }
03416 
03417     LeaveCriticalSection( &gCriticalSection );
03418 
03419     return Error;
03420 }

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

HANDLE gAddContextEvent = NULL

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 = NULL

Definition at line 40 of file spi.cpp.

INT gLayerCount = 0

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.