00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "lspdef.h"
00025
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028
00029 #pragma warning(disable:4127) // Disable "conditional expression is constant" warning
00030
00031
00032
00033
00034
00035
00036
00037 CRITICAL_SECTION gCriticalSection,
00038 gOverlappedCS;
00039 WSPUPCALLTABLE gMainUpCallTable;
00040 HINSTANCE gDllInstance = NULL;
00041 LPPROVIDER gBaseInfo = NULL;
00042 INT gLayerCount = 0;
00043 HANDLE gAddContextEvent=NULL;
00044
00045
00046
00047
00048
00049
00050
00051
00052 void
00053 FreeSocketsAndMemory(
00054 BOOL processDetach,
00055 int *lpErrno
00056 );
00057
00058
00059
00060
00061
00062 #define SetBlockingProvider(Provider) \
00063 ( gTlsIndex!=0xFFFFFFFF ) \
00064 ? TlsSetValue ( gTlsIndex, Provider ) \
00065 : NULL
00066
00067
00068
00069
00070
00071
00072
00073 static DWORD gTlsIndex = 0xFFFFFFFF;
00074 static DWORD gEntryCount = 0;
00075 static DWORD gLayerCatId = 0;
00076 static WSPDATA gWSPData;
00077 static BOOL gDetached = FALSE;
00078
00079
00080 static WSPPROC_TABLE gProcTable = {
00081 WSPAccept,
00082 WSPAddressToString,
00083 WSPAsyncSelect,
00084 WSPBind,
00085 WSPCancelBlockingCall,
00086 WSPCleanup,
00087 WSPCloseSocket,
00088 WSPConnect,
00089 WSPDuplicateSocket,
00090 WSPEnumNetworkEvents,
00091 WSPEventSelect,
00092 WSPGetOverlappedResult,
00093 WSPGetPeerName,
00094 WSPGetSockName,
00095 WSPGetSockOpt,
00096 WSPGetQOSByName,
00097 WSPIoctl,
00098 WSPJoinLeaf,
00099 WSPListen,
00100 WSPRecv,
00101 WSPRecvDisconnect,
00102 WSPRecvFrom,
00103 WSPSelect,
00104 WSPSend,
00105 WSPSendDisconnect,
00106 WSPSendTo,
00107 WSPSetSockOpt,
00108 WSPShutdown,
00109 WSPSocket,
00110 WSPStringToAddress
00111 };
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 void
00127 PrintProcTable(
00128 LPWSPPROC_TABLE lpProcTable
00129 )
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 );
00164 #endif
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174 BOOL WINAPI
00175 DllMain(
00176 IN HINSTANCE hinstDll,
00177 IN DWORD dwReason,
00178 LPVOID lpvReserved
00179 )
00180 {
00181 switch (dwReason)
00182 {
00183
00184 case DLL_PROCESS_ATTACH:
00185 gDllInstance = hinstDll;
00186
00187
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 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 SOCKET WSPAPI
00258 WSPAccept(
00259 SOCKET s,
00260 struct sockaddr FAR * addr,
00261 LPINT addrlen,
00262 LPCONDITIONPROC lpfnCondition,
00263 DWORD_PTR dwCallbackData,
00264 LPINT lpErrno
00265 )
00266 {
00267 SOCKET NewProviderSocket;
00268 SOCKET NewSocket = INVALID_SOCKET;
00269 SOCK_INFO *NewSocketContext = NULL;
00270 SOCK_INFO *SocketContext = NULL;
00271
00272
00273
00274
00275 SocketContext = FindAndRefSocketContext(s, lpErrno);
00276 if ( NULL == SocketContext )
00277 {
00278 dbgprint( "WSPAccept: FindAndRefSocketContext failed!" );
00279 goto cleanup;
00280 }
00281
00282
00283
00284
00285
00286
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
00303
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
00328 SocketContext->Provider->NextProcTable.lpWSPCloseSocket(
00329 NewProviderSocket,
00330 &tempErr
00331 );
00332
00333
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 }
00349
00350
00351
00352
00353
00354
00355
00356 int WSPAPI
00357 WSPAddressToString(
00358 LPSOCKADDR lpsaAddress,
00359 DWORD dwAddressLength,
00360 LPWSAPROTOCOL_INFOW lpProtocolInfo,
00361 LPWSTR lpszAddressString,
00362 LPDWORD lpdwAddressStringLength,
00363 LPINT lpErrno
00364 )
00365 {
00366 WSAPROTOCOL_INFOW *pInfo=NULL;
00367 PROVIDER *Provider=NULL;
00368 INT ret = SOCKET_ERROR,
00369 i;
00370
00371
00372
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
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
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 }
00437
00438
00439
00440
00441
00442
00443
00444
00445 int WSPAPI
00446 WSPAsyncSelect(
00447 SOCKET s,
00448 HWND hWnd,
00449 unsigned int wMsg,
00450 long lEvent,
00451 LPINT lpErrno
00452 )
00453 {
00454 SOCK_INFO *SocketContext = NULL;
00455 HWND hWorkerWindow = NULL;
00456 INT ret = SOCKET_ERROR;
00457
00458
00459
00460
00461 ret = SOCKET_ERROR;
00462 if ( FALSE == IsWindow( hWnd ) )
00463 {
00464 *lpErrno = WSAEINVAL;
00465 goto cleanup;
00466 }
00467
00468
00469
00470
00471 if ( 0 != (lEvent & ~FD_ALL_EVENTS) )
00472 {
00473 *lpErrno = WSAEINVAL;
00474 goto cleanup;
00475 }
00476
00477
00478
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
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 }
00518
00519
00520
00521
00522
00523
00524
00525
00526 int WSPAPI
00527 WSPBind(
00528 SOCKET s,
00529 const struct sockaddr FAR * name,
00530 int namelen,
00531 LPINT lpErrno
00532 )
00533 {
00534 SOCK_INFO *SocketContext = NULL;
00535 INT ret = SOCKET_ERROR;
00536
00537
00538
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 }
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 int WSPAPI
00577 WSPCancelBlockingCall(
00578 LPINT lpErrno
00579 )
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 }
00593
00594
00595
00596
00597
00598
00599
00600
00601 int WSPAPI
00602 WSPCleanup(
00603 LPINT lpErrno
00604 )
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
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
00629
00630 gEntryCount--;
00631
00632 #ifdef DEBUG
00633 dbgprint("WSPCleanup: %d", gEntryCount);
00634 #endif
00635
00636 if ( 0 == gEntryCount )
00637 {
00638
00639
00640
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 }
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669 int WSPAPI
00670 WSPCloseSocket(
00671 SOCKET s,
00672 LPINT lpErrno
00673 )
00674 {
00675 SOCK_INFO *SocketContext = NULL;
00676 int ret = SOCKET_ERROR;
00677
00678
00679
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
00695
00696
00697
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
00712
00713
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
00737
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
00758
00759 RemoveSocketInfo(SocketContext->Provider, SocketContext);
00760
00761
00762
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
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 }
00791
00792
00793
00794
00795
00796
00797
00798
00799 int WSPAPI
00800 WSPConnect(
00801 SOCKET s,
00802 const struct sockaddr FAR * name,
00803 int namelen,
00804 LPWSABUF lpCallerData,
00805 LPWSABUF lpCalleeData,
00806 LPQOS lpSQOS,
00807 LPQOS lpGQOS,
00808 LPINT lpErrno
00809 )
00810 {
00811 SOCK_INFO *SocketContext = NULL;
00812 INT ret = SOCKET_ERROR;
00813
00814
00815
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 }
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857 int WSPAPI
00858 WSPDuplicateSocket(
00859 SOCKET s,
00860 DWORD dwProcessId,
00861 LPWSAPROTOCOL_INFOW lpProtocolInfo,
00862 LPINT lpErrno
00863 )
00864 {
00865 PROVIDER *Provider = NULL;
00866 SOCK_INFO *SocketContext = NULL;
00867 DWORD dwReserved;
00868 int ret = SOCKET_ERROR;
00869
00870
00871
00872
00873 SocketContext = FindAndRefSocketContext(s, lpErrno);
00874 if ( NULL == SocketContext )
00875 {
00876 dbgprint( "WSPDuplicateSocket: FindAndRefSocketContext failed!" );
00877 goto cleanup;
00878 }
00879
00880
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
00899
00900
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 }
00917
00918
00919
00920
00921
00922
00923
00924
00925 int WSPAPI
00926 WSPEnumNetworkEvents(
00927 SOCKET s,
00928 WSAEVENT hEventObject,
00929 LPWSANETWORKEVENTS lpNetworkEvents,
00930 LPINT lpErrno
00931 )
00932 {
00933 SOCK_INFO *SocketContext = NULL;
00934 INT ret = SOCKET_ERROR;
00935
00936
00937
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 }
00964
00965
00966
00967
00968
00969
00970
00971
00972 int WSPAPI
00973 WSPEventSelect(
00974 SOCKET s,
00975 WSAEVENT hEventObject,
00976 long lNetworkEvents,
00977 LPINT lpErrno
00978 )
00979 {
00980 SOCK_INFO *SocketContext = NULL;
00981 INT ret = SOCKET_ERROR;
00982
00983
00984
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 }
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021 BOOL WSPAPI
01022 WSPGetOverlappedResult(
01023 SOCKET s,
01024 LPWSAOVERLAPPED lpOverlapped,
01025 LPDWORD lpcbTransfer,
01026 BOOL fWait,
01027 LPDWORD lpdwFlags,
01028 LPINT lpErrno
01029 )
01030 {
01031 DWORD ret = FALSE;
01032
01033 UNREFERENCED_PARAMETER( s );
01034
01035 __try
01036 {
01037 if ( WSS_OPERATION_IN_PROGRESS != lpOverlapped->Internal )
01038 {
01039
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
01051
01052
01053
01054
01055
01056
01057
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
01081 *lpErrno = WSA_IO_INCOMPLETE;
01082 }
01083 }
01084 __except( EXCEPTION_EXECUTE_HANDLER )
01085 {
01086 *lpErrno = WSAEFAULT;
01087 }
01088
01089 return ret;
01090 }
01091
01092
01093
01094
01095
01096
01097
01098
01099 int WSPAPI
01100 WSPGetPeerName(
01101 SOCKET s,
01102 struct sockaddr FAR * name,
01103 LPINT namelen,
01104 LPINT lpErrno
01105 )
01106 {
01107 SOCK_INFO *SocketContext = NULL;
01108 INT ret = SOCKET_ERROR;
01109
01110
01111
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 }
01137
01138
01139
01140
01141
01142
01143
01144
01145 int WSPAPI
01146 WSPGetSockName(
01147 SOCKET s,
01148 struct sockaddr FAR * name,
01149 LPINT namelen,
01150 LPINT lpErrno
01151 )
01152 {
01153 SOCK_INFO *SocketContext = NULL;
01154 INT ret = SOCKET_ERROR;
01155
01156
01157
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 }
01184
01185
01186
01187
01188
01189
01190
01191
01192 int WSPAPI
01193 WSPGetSockOpt(
01194 SOCKET s,
01195 int level,
01196 int optname,
01197 char FAR * optval,
01198 LPINT optlen,
01199 LPINT lpErrno
01200 )
01201 {
01202 SOCK_INFO *SocketContext = NULL;
01203 INT ret = NO_ERROR;
01204
01205
01206
01207
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
01221
01222
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
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
01245 memcpy(optval,
01246 &SocketContext->Provider->LayerProvider,
01247 sizeof(WSAPROTOCOL_INFOW)-WSAPROTOCOL_LEN+1);
01248
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 }
01298
01299
01300
01301
01302
01303
01304
01305
01306 BOOL WSPAPI
01307 WSPGetQOSByName(
01308 SOCKET s,
01309 LPWSABUF lpQOSName,
01310 LPQOS lpQOS,
01311 LPINT lpErrno
01312 )
01313 {
01314 SOCK_INFO *SocketContext = NULL;
01315 INT ret = SOCKET_ERROR;
01316
01317
01318
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 }
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358 int WSPAPI
01359 WSPIoctl(
01360 SOCKET s,
01361 DWORD dwIoControlCode,
01362 LPVOID lpvInBuffer,
01363 DWORD cbInBuffer,
01364 LPVOID lpvOutBuffer,
01365 DWORD cbOutBuffer,
01366 LPDWORD lpcbBytesReturned,
01367 LPWSAOVERLAPPED lpOverlapped,
01368 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
01369 LPWSATHREADID lpThreadId,
01370 LPINT lpErrno
01371 )
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
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
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
01417
01418 if ( 0 == memcmp( lpvInBuffer, &TransmitFileGuid, sizeof( GUID ) ) )
01419 {
01420
01421 dwBytesReturned = sizeof(LPFN_TRANSMITFILE);
01422 lpFunction = ExtTransmitFile;
01423
01424
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
01440 dwBytesReturned = sizeof( LPFN_ACCEPTEX );
01441 lpFunction = ExtAcceptEx;
01442
01443
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
01459 dwBytesReturned = sizeof( LPFN_CONNECTEX );
01460 lpFunction = ExtConnectEx;
01461
01462
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
01478 dwBytesReturned = sizeof( LPFN_DISCONNECTEX );
01479 lpFunction = ExtDisconnectEx;
01480
01481
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
01497 dwBytesReturned = sizeof( LPFN_TRANSMITPACKETS );
01498 lpFunction = ExtTransmitPackets;
01499
01500
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
01516 dwBytesReturned = sizeof( LPFN_WSARECVMSG );
01517 lpFunction = ExtWSARecvMsg;
01518
01519
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
01535
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
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
01570
01571
01572 }
01573 else if ( SIO_QUERY_TARGET_PNP_HANDLE == dwIoControlCode )
01574 {
01575
01576
01577
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
01621
01622
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
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
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
01678
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 }
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728 SOCKET WSPAPI
01729 WSPJoinLeaf(
01730 SOCKET s,
01731 const struct sockaddr FAR * name,
01732 int namelen,
01733 LPWSABUF lpCallerData,
01734 LPWSABUF lpCalleeData,
01735 LPQOS lpSQOS,
01736 LPQOS lpGQOS,
01737 DWORD dwFlags,
01738 LPINT lpErrno
01739 )
01740 {
01741 SOCK_INFO *SocketContext = NULL;
01742 SOCKET NextProviderSocket = INVALID_SOCKET,
01743 NewSocket = INVALID_SOCKET;
01744
01745
01746
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
01773
01774
01775
01776
01777 if ( ( INVALID_SOCKET != NextProviderSocket ) &&
01778 ( NextProviderSocket != SocketContext->ProviderSocket )
01779 )
01780 {
01781 SOCK_INFO *NewSocketContext = NULL;
01782
01783
01784
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
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
01813 SocketContext->Provider->NextProcTable.lpWSPCloseSocket(
01814 NextProviderSocket,
01815 &tempErr
01816 );
01817
01818
01819 FreeSockInfo(NewSocketContext);
01820 goto cleanup;
01821 }
01822
01823
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 }
01838
01839
01840
01841
01842
01843
01844
01845
01846 int WSPAPI
01847 WSPListen(
01848 SOCKET s,
01849 int backlog,
01850 LPINT lpErrno
01851 )
01852 {
01853 SOCK_INFO *SocketContext = NULL;
01854 INT ret = SOCKET_ERROR;
01855
01856
01857
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 }
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893 int WSPAPI
01894 WSPRecv(
01895 SOCKET s,
01896 LPWSABUF lpBuffers,
01897 DWORD dwBufferCount,
01898 LPDWORD lpNumberOfBytesRecvd,
01899 LPDWORD lpFlags,
01900 LPWSAOVERLAPPED lpOverlapped,
01901 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
01902 LPWSATHREADID lpThreadId,
01903 LPINT lpErrno
01904 )
01905 {
01906 LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
01907 SOCK_INFO *SocketContext = NULL;
01908 int ret = SOCKET_ERROR;
01909
01910
01911 *lpErrno = NO_ERROR;
01912
01913
01914
01915
01916 SocketContext = FindAndRefSocketContext(s, lpErrno);
01917 if ( NULL == SocketContext )
01918 {
01919 dbgprint( "WSPRecv: FindAndRefSocketContext failed!" );
01920 goto cleanup;
01921 }
01922
01923
01924
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
01949 *lpErrno = WSAEFAULT;
01950 goto cleanup;
01951 }
01952
01953
01954
01955
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 }
01993
01994
01995
01996
01997
01998
01999
02000
02001 int WSPAPI
02002 WSPRecvDisconnect(
02003 SOCKET s,
02004 LPWSABUF lpInboundDisconnectData,
02005 LPINT lpErrno
02006 )
02007 {
02008 SOCK_INFO *SocketContext = NULL;
02009 INT ret = SOCKET_ERROR;
02010
02011
02012
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 }
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048 int WSPAPI
02049 WSPRecvFrom(
02050 SOCKET s,
02051 LPWSABUF lpBuffers,
02052 DWORD dwBufferCount,
02053 LPDWORD lpNumberOfBytesRecvd,
02054 LPDWORD lpFlags,
02055 struct sockaddr FAR * lpFrom,
02056 LPINT lpFromLen,
02057 LPWSAOVERLAPPED lpOverlapped,
02058 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
02059 LPWSATHREADID lpThreadId,
02060 LPINT lpErrno
02061 )
02062 {
02063 LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
02064 SOCK_INFO *SocketContext = NULL;
02065 int ret = SOCKET_ERROR;
02066
02067 *lpErrno = NO_ERROR;
02068
02069
02070
02071
02072 SocketContext = FindAndRefSocketContext(s, lpErrno);
02073 if ( NULL == SocketContext )
02074 {
02075 dbgprint( "WSPRecvFrom: FindAndRefSocketContext failed!" );
02076 goto cleanup;
02077 }
02078
02079
02080
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
02107 *lpErrno = WSAEFAULT;
02108 goto cleanup;
02109 }
02110
02111
02112
02113
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
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 }
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165 void
02166 UnlockFdSets(
02167 fd_set *readfds,
02168 FD_MAP *readmap,
02169 fd_set *writefds,
02170 FD_MAP *writemap,
02171 fd_set *exceptfds,
02172 FD_MAP *exceptmap,
02173 LPINT lpErrno
02174 )
02175 {
02176 int i;
02177
02178
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
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
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 }
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235 int WSPAPI
02236 WSPSelect(
02237 int nfds,
02238 fd_set FAR * readfds,
02239 fd_set FAR * writefds,
02240 fd_set FAR * exceptfds,
02241 const struct timeval FAR * timeout,
02242 LPINT lpErrno
02243 )
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
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
02290
02291
02292
02293
02294
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
02314
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
02324 if ( NULL == SocketContext )
02325 SocketContext = Read[i].Context;
02326 }
02327 }
02328 }
02329
02330
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
02349
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
02359 if ( NULL == SocketContext )
02360 SocketContext = Write[i].Context;
02361 }
02362 }
02363 }
02364
02365
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
02384
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
02394 if ( NULL == SocketContext )
02395 SocketContext = Except[i].Context;
02396 }
02397 }
02398 }
02399
02400
02401
02402
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
02424 UnlockFdSets( readfds, Read, writefds, Write, exceptfds, Except, lpErrno );
02425 unlocked = TRUE;
02426
02427 if ( SOCKET_ERROR != ret )
02428 {
02429
02430
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
02483 if ( FALSE == unlocked )
02484 UnlockFdSets( readfds, Read, writefds, Write, exceptfds, Except, lpErrno );
02485
02486
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 }
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508 int WSPAPI
02509 WSPSend(
02510 SOCKET s,
02511 LPWSABUF lpBuffers,
02512 DWORD dwBufferCount,
02513 LPDWORD lpNumberOfBytesSent,
02514 DWORD dwFlags,
02515 LPWSAOVERLAPPED lpOverlapped,
02516 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
02517 LPWSATHREADID lpThreadId,
02518 LPINT lpErrno
02519 )
02520 {
02521 INT ret = SOCKET_ERROR;
02522 SOCK_INFO *SocketContext = NULL;
02523 LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
02524
02525 *lpErrno = NO_ERROR;
02526
02527
02528
02529
02530 SocketContext = FindAndRefSocketContext(s, lpErrno);
02531 if ( NULL == SocketContext )
02532 {
02533 dbgprint( "WSPSend: FindAndRefSocketContext failed!" );
02534 goto cleanup;
02535 }
02536
02537
02538
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
02564 *lpErrno = WSAEFAULT;
02565 goto cleanup;
02566 }
02567
02568
02569
02570
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
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 }
02610
02611
02612
02613
02614
02615
02616
02617
02618 int WSPAPI
02619 WSPSendDisconnect(
02620 SOCKET s,
02621 LPWSABUF lpOutboundDisconnectData,
02622 LPINT lpErrno
02623 )
02624 {
02625 SOCK_INFO *SocketContext = NULL;
02626 INT ret = SOCKET_ERROR;
02627
02628
02629
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 }
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665 int WSPAPI
02666 WSPSendTo(
02667 SOCKET s,
02668 LPWSABUF lpBuffers,
02669 DWORD dwBufferCount,
02670 LPDWORD lpNumberOfBytesSent,
02671 DWORD dwFlags,
02672 const struct sockaddr FAR * lpTo,
02673 int iToLen,
02674 LPWSAOVERLAPPED lpOverlapped,
02675 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
02676 LPWSATHREADID lpThreadId,
02677 LPINT lpErrno
02678 )
02679 {
02680 int ret = SOCKET_ERROR;
02681 SOCK_INFO *SocketContext = NULL;
02682 LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
02683
02684
02685
02686
02687 SocketContext = FindAndRefSocketContext(s, lpErrno);
02688 if ( NULL == SocketContext )
02689 {
02690 dbgprint( "WSPSendTo: FindAndRefSocketContext failed!" );
02691 goto cleanup;
02692 }
02693
02694
02695
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
02723 *lpErrno = WSAEFAULT;
02724 goto cleanup;
02725 }
02726
02727
02728
02729
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 }
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780 int WSPAPI WSPSetSockOpt(
02781 SOCKET s,
02782 int level,
02783 int optname,
02784 const char FAR * optval,
02785 int optlen,
02786 LPINT lpErrno
02787 )
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
02805
02806
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 }
02850
02851
02852
02853
02854
02855
02856
02857
02858 int WSPAPI
02859 WSPShutdown (
02860 SOCKET s,
02861 int how,
02862 LPINT lpErrno
02863 )
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 }
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901 int WSPAPI
02902 WSPStringToAddress(
02903 LPWSTR AddressString,
02904 INT AddressFamily,
02905 LPWSAPROTOCOL_INFOW lpProtocolInfo,
02906 LPSOCKADDR lpAddress,
02907 LPINT lpAddressLength,
02908 LPINT lpErrno
02909 )
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
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
02947
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 }
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994 SOCKET WSPAPI
02995 WSPSocket(
02996 int af,
02997 int type,
02998 int protocol,
02999 __in LPWSAPROTOCOL_INFOW lpProtocolInfo,
03000 GROUP g,
03001 DWORD dwFlags,
03002 LPINT lpErrno
03003 )
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
03023
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
03073
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
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
03093
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
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
03118
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
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
03151
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
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
03176
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
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,
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
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
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
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 }
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321 int WSPAPI
03322 WSPStartup(
03323 WORD wVersion,
03324 LPWSPDATA lpWSPData,
03325 LPWSAPROTOCOL_INFOW lpProtocolInfo,
03326 WSPUPCALLTABLE UpCallTable,
03327 LPWSPPROC_TABLE lpProcTable
03328 )
03329 {
03330 PROVIDER *loadProvider = NULL;
03331 INT ret,
03332 Error = WSAEPROVIDERFAILEDINIT;
03333
03334 EnterCriticalSection( &gCriticalSection );
03335
03336
03337
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
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
03367
03368
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
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
03413
03414 FreeSocketsAndMemory( FALSE, &Error );
03415 }
03416
03417 LeaveCriticalSection( &gCriticalSection );
03418
03419 return Error;
03420 }
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430 void
03431 CopyOffset(
03432 WSAOVERLAPPED *ProviderOverlapped,
03433 WSAOVERLAPPED *UserOverlapped
03434 )
03435 {
03436 ProviderOverlapped->Offset = UserOverlapped->Offset;
03437 ProviderOverlapped->OffsetHigh = UserOverlapped->OffsetHigh;
03438 }
03439
03440
03441
03442
03443
03444
03445
03446
03447
03448
03449
03450
03451
03452
03453 WSABUF *
03454 CopyWSABuf(
03455 WSABUF *BufferArray,
03456 DWORD BufferCount,
03457 int *lpErrno
03458 )
03459 {
03460 WSABUF *buffercopy = NULL;
03461 DWORD i;
03462
03463 if ( NULL == gIocp )
03464 {
03465
03466
03467
03468
03469
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
03493
03494
03495
03496
03497
03498 return BufferArray;
03499 }
03500 }
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511
03512 void
03513 FreeWSABuf(
03514 WSABUF *BufferArray
03515 )
03516 {
03517 if ( ( NULL == gIocp ) && ( NULL != BufferArray ) )
03518 {
03519
03520
03521 LspFree( BufferArray );
03522 }
03523 }
03524
03525
03526
03527
03528
03529
03530
03531
03532 void
03533 FreeSocketsAndMemory(
03534 BOOL processDetach,
03535 int *lpErrno
03536 )
03537 {
03538 int ret,
03539 i;
03540
03541 if ( NULL != gBaseInfo )
03542 {
03543
03544 for(i=0; i < gLayerCount ;i++)
03545 {
03546 if ( NULL != gBaseInfo[i].Module )
03547 {
03548
03549
03550
03551 CloseAndFreeSocketInfo( &gBaseInfo[i], processDetach );
03552
03553
03554
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 }