00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "lspdef.h"
00023
00024
00025 SOCK_INFO *
00026 FindSockInfoFromProviderSocket(
00027 PROVIDER *provider,
00028 SOCKET socket
00029 );
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 SOCK_INFO *
00040 FindAndRefSocketContext(
00041 SOCKET s,
00042 int *lpErrno
00043 )
00044 {
00045 SOCK_INFO *SocketContext = NULL;
00046 int ret;
00047
00048 EnterCriticalSection(&gCriticalSection);
00049
00050 ASSERT( gMainUpCallTable.lpWPUQuerySocketHandleContext );
00051
00052 ret = gMainUpCallTable.lpWPUQuerySocketHandleContext(
00053 s,
00054 (PDWORD_PTR) &SocketContext,
00055 lpErrno
00056 );
00057 if ( SOCKET_ERROR == ret )
00058 {
00059 dbgprint("FindAndRefSocketContext: WPUQuerySocketHandleContext failed: %d", *lpErrno);
00060 *lpErrno = WSAENOTSOCK;
00061 }
00062 else
00063 {
00064 InterlockedIncrement(&SocketContext->RefCount);
00065 }
00066
00067 LeaveCriticalSection(&gCriticalSection);
00068
00069 return SocketContext;
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 void
00083 DerefSocketContext(
00084 SOCK_INFO *context,
00085 int *lpErrno
00086 )
00087 {
00088 LONG newval;
00089 int ret = NO_ERROR;
00090
00091 EnterCriticalSection(&gCriticalSection);
00092
00093
00094 newval = InterlockedDecrement(&context->RefCount);
00095 if ( ( 0 == newval ) &&
00096 ( 0 == context->dwOutstandingAsync ) &&
00097 ( TRUE == context->bClosing )
00098 )
00099 {
00100 ASSERT( gMainUpCallTable.lpWPUCloseSocketHandle );
00101
00102
00103 ret = gMainUpCallTable.lpWPUCloseSocketHandle(context->LayeredSocket, lpErrno);
00104 if ( SOCKET_ERROR == ret )
00105 {
00106 dbgprint("DerefSocketContext: WPUCloseSocketHandle() failed: %d", *lpErrno);
00107 }
00108
00109 context->LayeredSocket = INVALID_SOCKET;
00110
00111 RemoveSocketInfo(context->Provider, context);
00112
00113 dbgprint("Closing socket %d Bytes Sent [%lu] Bytes Recv [%lu]",
00114 context->LayeredSocket, context->BytesSent, context->BytesRecv);
00115
00116 FreeSockInfo( context );
00117 context = NULL;
00118 }
00119
00120 LeaveCriticalSection( &gCriticalSection );
00121 }
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 void
00133 AcquireSocketLock(
00134 SOCK_INFO *SockInfo
00135 )
00136 {
00137 EnterCriticalSection( &SockInfo->SockCritSec );
00138 }
00139
00140
00141
00142
00143
00144
00145
00146 void
00147 ReleaseSocketLock(
00148 SOCK_INFO *SockInfo
00149 )
00150 {
00151 LeaveCriticalSection( &SockInfo->SockCritSec );
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 SOCK_INFO *
00171 CreateSockInfo(
00172 PROVIDER *Provider,
00173 SOCKET ProviderSocket,
00174 SOCK_INFO *Inherit,
00175 BOOL Insert,
00176 int *lpErrno
00177 )
00178 {
00179 SOCK_INFO *NewInfo = NULL;
00180
00181 NewInfo = (SOCK_INFO *) LspAlloc(
00182 sizeof( SOCK_INFO ),
00183 lpErrno
00184 );
00185 if ( NULL == NewInfo )
00186 {
00187 dbgprint("HeapAlloc() failed: %d", GetLastError());
00188 *lpErrno = WSAENOBUFS;
00189 goto cleanup;
00190 }
00191
00192
00193
00194
00195 NewInfo->ProviderSocket = ProviderSocket;
00196 NewInfo->bClosing = FALSE;
00197 NewInfo->dwOutstandingAsync = 0;
00198 NewInfo->BytesRecv = 0;
00199 NewInfo->BytesSent = 0;
00200 NewInfo->Provider = Provider;
00201 NewInfo->hWnd = (Inherit ? Inherit->hWnd : 0);
00202 NewInfo->uMsg = (Inherit ? Inherit->uMsg : 0);
00203
00204 __try
00205 {
00206 InitializeCriticalSection( &NewInfo->SockCritSec );
00207 }
00208 __except( EXCEPTION_EXECUTE_HANDLER )
00209 {
00210 *lpErrno = WSAENOBUFS;
00211 goto cleanup;
00212 }
00213
00214 if ( TRUE == Insert )
00215 InsertSocketInfo(Provider, NewInfo);
00216
00217 return NewInfo;
00218
00219 cleanup:
00220
00221 if ( NULL != NewInfo )
00222 LspFree( NewInfo );
00223
00224 return NULL;
00225 }
00226
00227
00228
00229
00230
00231
00232
00233 void
00234 FreeSockInfo(
00235 SOCK_INFO *info
00236 )
00237 {
00238 DeleteCriticalSection( &info->SockCritSec );
00239 LspFree( info );
00240
00241 return;
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 void
00253 InsertSocketInfo(
00254 PROVIDER *provider,
00255 SOCK_INFO *sock
00256 )
00257 {
00258 if ( ( NULL == provider ) || ( NULL == sock ) )
00259 {
00260 dbgprint("InsertSocketInfo: PROVIDER or SOCK_INFO == NULL!");
00261 goto cleanup;
00262 }
00263
00264 EnterCriticalSection( &provider->ProviderCritSec );
00265
00266 InsertTailList( &provider->SocketList, &sock->Link );
00267
00268 LeaveCriticalSection( &provider->ProviderCritSec );
00269
00270 SetEvent( gAddContextEvent );
00271
00272 cleanup:
00273
00274 return;
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 void
00286 RemoveSocketInfo(
00287 PROVIDER *provider,
00288 SOCK_INFO *si
00289 )
00290 {
00291 EnterCriticalSection( &provider->ProviderCritSec );
00292
00293 RemoveEntryList( &si->Link );
00294
00295 LeaveCriticalSection( &provider->ProviderCritSec );
00296
00297 return;
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 void
00309 CloseAndFreeSocketInfo(
00310 PROVIDER *provider,
00311 BOOL processDetach
00312 )
00313 {
00314 LIST_ENTRY *entry = NULL;
00315 SOCK_INFO *si = NULL;
00316 struct linger linger;
00317 int Error,
00318 ret;
00319
00320 ASSERT( provider );
00321
00322 linger.l_onoff = 1;
00323 linger.l_linger = 0;
00324
00325
00326 while ( !IsListEmpty( &provider->SocketList ) )
00327 {
00328 entry = RemoveHeadList( &provider->SocketList );
00329
00330 ASSERT( entry );
00331
00332 si = CONTAINING_RECORD( entry, SOCK_INFO, Link );
00333
00334 if ( ( !processDetach ) ||
00335 ( provider->NextProvider.ProtocolChain.ChainLen == BASE_PROTOCOL ) )
00336 {
00337
00338 ASSERT( provider->NextProcTable.lpWSPSetSockOpt );
00339
00340
00341 ret = provider->NextProcTable.lpWSPSetSockOpt(
00342 si->ProviderSocket,
00343 SOL_SOCKET,
00344 SO_LINGER,
00345 (char *) &linger,
00346 sizeof(linger),
00347 &Error
00348 );
00349 if ( SOCKET_ERROR != ret )
00350 {
00351 ASSERT( provider->NextProcTable.lpWSPCloseSocket );
00352
00353
00354 ret = provider->NextProcTable.lpWSPCloseSocket(
00355 si->ProviderSocket,
00356 &Error
00357 );
00358 if ( SOCKET_ERROR == ret )
00359 {
00360 dbgprint("WSPCloseSocket() on handle %d failed: %d", si->ProviderSocket, Error);
00361 }
00362 #ifdef DEBUG
00363 else
00364 {
00365 dbgprint("Successfully closed socket %d", si->ProviderSocket);
00366 }
00367 #endif
00368 }
00369 #ifdef DEBUG
00370 else
00371 {
00372 dbgprint("WSPSetSockOpt(SO_LINGER) failed: %d", Error);
00373 }
00374 #endif
00375 }
00376
00377 ASSERT( gMainUpCallTable.lpWPUCloseSocketHandle );
00378
00379
00380 gMainUpCallTable.lpWPUCloseSocketHandle(
00381 si->LayeredSocket,
00382 &Error
00383 );
00384
00385
00386 FreeSockInfo( si );
00387 }
00388
00389 return;
00390 }
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 SOCK_INFO *
00401 FindSockInfoFromProviderSocket(
00402 PROVIDER *provider,
00403 SOCKET socket
00404 )
00405 {
00406 LIST_ENTRY *lptr = NULL;
00407 SOCK_INFO *si = NULL;
00408
00409 ASSERT( provider );
00410
00411 if ( IsListEmpty( &provider->SocketList ) )
00412 {
00413 dbgprint( "FindSockInfoFromProviderSocket: Empty SOCK_INFO list!" );
00414 goto cleanup;
00415 }
00416
00417 for(lptr = provider->SocketList.Flink ; lptr != &provider->SocketList ; lptr = lptr->Flink )
00418 {
00419 si = CONTAINING_RECORD( lptr, SOCK_INFO, Link );
00420
00421 if ( socket == si->ProviderSocket )
00422 break;
00423
00424 si = NULL;
00425 }
00426
00427 cleanup:
00428
00429 return si;
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 SOCK_INFO *
00444 GetCallerSocket(
00445 PROVIDER *provider,
00446 SOCKET ProviderSock
00447 )
00448 {
00449 SOCK_INFO *si = NULL;
00450
00451 EnterCriticalSection( &gCriticalSection );
00452
00453 if ( NULL != provider )
00454 {
00455
00456 si = FindSockInfoFromProviderSocket( provider, ProviderSock );
00457 }
00458 else
00459 {
00460
00461 for(INT i=0; i < gLayerCount ;i++)
00462 {
00463 si = FindSockInfoFromProviderSocket( &gBaseInfo[ i ], ProviderSock );
00464 if ( NULL != si )
00465 break;
00466 }
00467 }
00468
00469 LeaveCriticalSection( &gCriticalSection );
00470
00471 return si;
00472 }