00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "lspdef.h"
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 BOOL
00038 LoadExtensionFunction(
00039 FARPROC **func,
00040 GUID ExtensionGuid,
00041 LPWSPIOCTL fnIoctl,
00042 SOCKET s
00043 )
00044 {
00045 DWORD dwBytes;
00046 int rc,
00047 error,
00048 ret = TRUE;
00049
00050
00051 rc = fnIoctl(
00052 s,
00053 SIO_GET_EXTENSION_FUNCTION_POINTER,
00054 &ExtensionGuid,
00055 sizeof(GUID),
00056 func,
00057 sizeof(FARPROC),
00058 &dwBytes,
00059 NULL,
00060 NULL,
00061 NULL,
00062 &error
00063 );
00064
00065
00066 if ( SOCKET_ERROR == rc )
00067 {
00068 dbgprint("LoadExtensionFunction: WSAIoctl (SIO_GET_EXTENSION_FUNCTION) failed: %d",
00069 error);
00070 ret = FALSE;
00071 }
00072 else if( NULL == *func )
00073 {
00074
00075
00076
00077 dbgprint("LoadExtensionFunction: WSAIoctl (SIO_GET_EXTENSION_FUNCTION) returned a NULL"
00078 " function pointer");
00079 ret = FALSE;
00080 }
00081
00082 return ret;
00083 }
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 BOOL PASCAL FAR
00106 ExtTransmitFile(
00107 IN SOCKET hSocket,
00108 IN HANDLE hFile,
00109 IN DWORD nNumberOfBytesToWrite,
00110 IN DWORD nNumberOfBytesPerSend,
00111 IN LPOVERLAPPED lpOverlapped,
00112 IN LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
00113 IN DWORD dwFlags
00114 )
00115 {
00116 SOCK_INFO *SocketContext = NULL;
00117 LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
00118 int Errno = 0,
00119 ret = FALSE;
00120
00121
00122 SocketContext = FindAndRefSocketContext( hSocket, &Errno );
00123 if ( NULL == SocketContext )
00124 {
00125 dbgprint( "ExtTransmitFile: FindAndRefSocketContext failed!" );
00126 goto cleanup;
00127 }
00128
00129
00130 if ( NULL == SocketContext->Provider->NextProcTableExt.lpfnTransmitFile )
00131 {
00132 GUID guidTransmitFile = WSAID_TRANSMITFILE;
00133
00134 ret = LoadExtensionFunction(
00135 (FARPROC **)&SocketContext->Provider->NextProcTableExt.lpfnTransmitFile,
00136 guidTransmitFile,
00137 SocketContext->Provider->NextProcTable.lpWSPIoctl,
00138 SocketContext->ProviderSocket
00139 );
00140 if ( FALSE == ret )
00141 {
00142 dbgprint( "Next provider's TransmitFile pointer is NULL!" );
00143 Errno = WSAEFAULT;
00144 goto cleanup;
00145 }
00146 }
00147
00148
00149
00150
00151 if ( NULL != lpOverlapped )
00152 {
00153 ProviderOverlapped = PrepareOverlappedOperation(
00154 SocketContext,
00155 LSP_OP_TRANSMITFILE,
00156 NULL,
00157 0,
00158 lpOverlapped,
00159 NULL,
00160 NULL,
00161 &Errno
00162 );
00163 if ( NULL == ProviderOverlapped )
00164 {
00165 goto cleanup;
00166 }
00167
00168
00169 ProviderOverlapped->TransmitFileArgs.hFile = hFile;
00170 ProviderOverlapped->TransmitFileArgs.nNumberOfBytesToWrite = nNumberOfBytesToWrite;
00171 ProviderOverlapped->TransmitFileArgs.nNumberOfBytesPerSend = nNumberOfBytesPerSend;
00172 ProviderOverlapped->TransmitFileArgs.lpTransmitBuffers = lpTransmitBuffers;
00173 ProviderOverlapped->TransmitFileArgs.dwFlags = dwFlags;
00174
00175 ret = QueueOverlappedOperation( ProviderOverlapped, SocketContext );
00176 if ( NO_ERROR != ret )
00177 {
00178 Errno = ret;
00179 ret = FALSE;
00180 }
00181 else
00182 {
00183 ret = TRUE;
00184 }
00185 }
00186 else
00187 {
00188 ret = SocketContext->Provider->NextProcTableExt.lpfnTransmitFile(
00189 SocketContext->ProviderSocket,
00190 hFile,
00191 nNumberOfBytesToWrite,
00192 nNumberOfBytesPerSend,
00193 NULL,
00194 lpTransmitBuffers,
00195 dwFlags
00196 );
00197 if ( FALSE == ret )
00198 Errno = WSAGetLastError();
00199 }
00200
00201 cleanup:
00202
00203 if ( NULL != SocketContext )
00204 DerefSocketContext(SocketContext, &Errno );
00205
00206 if ( FALSE == ret )
00207 WSASetLastError( Errno );
00208
00209 return ret;
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 BOOL PASCAL FAR
00221 ExtAcceptEx(
00222 IN SOCKET sListenSocket,
00223 IN SOCKET sAcceptSocket,
00224 IN PVOID lpOutputBuffer,
00225 IN DWORD dwReceiveDataLength,
00226 IN DWORD dwLocalAddressLength,
00227 IN DWORD dwRemoteAddressLength,
00228 OUT LPDWORD lpdwBytesReceived,
00229 IN LPOVERLAPPED lpOverlapped
00230 )
00231 {
00232 LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
00233 SOCK_INFO *ListenSocketContext = NULL,
00234 *AcceptSocketContext = NULL;
00235 int Errno = 0,
00236 ret = FALSE;
00237
00238
00239
00240
00241
00242 ListenSocketContext = FindAndRefSocketContext( sListenSocket, &Errno );
00243 if ( NULL == ListenSocketContext )
00244 {
00245 dbgprint( "ExtAcceptEx: FindAndRefSocketContext failed! (listen socket)" );
00246 goto cleanup;
00247 }
00248
00249
00250
00251 AcceptSocketContext = FindAndRefSocketContext( sAcceptSocket, &Errno );
00252 if ( NULL == AcceptSocketContext )
00253 {
00254 dbgprint( "ExtAcceptEx: FindAndRefSocketContext failed! (accept socket)" );
00255 goto cleanup;
00256 }
00257
00258
00259 if ( NULL == ListenSocketContext->Provider->NextProcTableExt.lpfnAcceptEx )
00260 {
00261 GUID guidAcceptEx = WSAID_ACCEPTEX;
00262
00263 ret = LoadExtensionFunction(
00264 (FARPROC **)&ListenSocketContext->Provider->NextProcTableExt.lpfnAcceptEx,
00265 guidAcceptEx,
00266 ListenSocketContext->Provider->NextProcTable.lpWSPIoctl,
00267 ListenSocketContext->ProviderSocket
00268 );
00269 if ( FALSE == ret )
00270 {
00271 dbgprint("Lower provider AcceptEx == NULL!");
00272 Errno = WSAEFAULT;
00273 goto cleanup;
00274 }
00275 }
00276
00277
00278 if ( NULL != lpOverlapped )
00279 {
00280 ProviderOverlapped = PrepareOverlappedOperation(
00281 ListenSocketContext,
00282 LSP_OP_ACCEPTEX,
00283 NULL,
00284 0,
00285 lpOverlapped,
00286 NULL,
00287 NULL,
00288 &Errno
00289 );
00290 if ( NULL == ProviderOverlapped )
00291 {
00292 goto cleanup;
00293 }
00294
00295 __try
00296 {
00297
00298 ProviderOverlapped->AcceptExArgs.dwBytesReceived = (lpdwBytesReceived ? *lpdwBytesReceived : 0);
00299 ProviderOverlapped->AcceptExArgs.sAcceptSocket = sAcceptSocket;
00300 ProviderOverlapped->AcceptExArgs.sProviderAcceptSocket = AcceptSocketContext->ProviderSocket;
00301 ProviderOverlapped->AcceptExArgs.lpOutputBuffer = lpOutputBuffer;
00302 ProviderOverlapped->AcceptExArgs.dwReceiveDataLength = dwReceiveDataLength;
00303 ProviderOverlapped->AcceptExArgs.dwLocalAddressLength = dwLocalAddressLength;
00304 ProviderOverlapped->AcceptExArgs.dwRemoteAddressLength = dwRemoteAddressLength;
00305 }
00306 __except( EXCEPTION_EXECUTE_HANDLER )
00307 {
00308 Errno = WSAEFAULT;
00309 goto cleanup;
00310 }
00311
00312 ret = QueueOverlappedOperation( ProviderOverlapped, ListenSocketContext );
00313 if ( NO_ERROR != ret )
00314 {
00315 Errno = ret;
00316 ret = FALSE;
00317 }
00318 else
00319 {
00320 ret = TRUE;
00321 }
00322 }
00323 else
00324 {
00325 ret = ListenSocketContext->Provider->NextProcTableExt.lpfnAcceptEx(
00326 ListenSocketContext->ProviderSocket,
00327 AcceptSocketContext->ProviderSocket,
00328 lpOutputBuffer,
00329 dwReceiveDataLength,
00330 dwLocalAddressLength,
00331 dwRemoteAddressLength,
00332 lpdwBytesReceived,
00333 NULL
00334 );
00335 if ( FALSE == ret )
00336 Errno = WSAGetLastError();
00337 }
00338
00339 cleanup:
00340
00341 if ( NULL != ListenSocketContext )
00342 DerefSocketContext(ListenSocketContext, &Errno );
00343
00344 if ( NULL != AcceptSocketContext )
00345 DerefSocketContext(AcceptSocketContext, &Errno );
00346
00347 if ( FALSE == ret )
00348 WSASetLastError( Errno );
00349
00350 return ret;
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 BOOL PASCAL FAR
00362 ExtConnectEx(
00363 IN SOCKET s,
00364 IN const struct sockaddr FAR *name,
00365 IN int namelen,
00366 IN PVOID lpSendBuffer OPTIONAL,
00367 IN DWORD dwSendDataLength,
00368 OUT LPDWORD lpdwBytesSent,
00369 IN LPOVERLAPPED lpOverlapped
00370 )
00371 {
00372 SOCK_INFO *SocketContext = NULL;
00373 LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
00374 int Errno = NO_ERROR,
00375 ret = FALSE;
00376
00377
00378 SocketContext = FindAndRefSocketContext( s, &Errno );
00379 if ( NULL == SocketContext )
00380 {
00381 dbgprint( "ExtConnectEx: FindAndRefSocketContext failed!" );
00382 goto cleanup;
00383 }
00384
00385
00386 if ( NULL == SocketContext->Provider->NextProcTableExt.lpfnConnectEx )
00387 {
00388 GUID guidConnectEx = WSAID_CONNECTEX;
00389
00390 ret = LoadExtensionFunction(
00391 (FARPROC **)&SocketContext->Provider->NextProcTableExt.lpfnConnectEx,
00392 guidConnectEx,
00393 SocketContext->Provider->NextProcTable.lpWSPIoctl,
00394 SocketContext->ProviderSocket
00395 );
00396 if ( FALSE == ret )
00397 {
00398 dbgprint("Next proc table ConnectEx == NULL!");
00399 Errno = WSAEFAULT;
00400 goto cleanup;
00401 }
00402 }
00403
00404
00405 if ( NULL != lpOverlapped )
00406 {
00407 ProviderOverlapped = PrepareOverlappedOperation(
00408 SocketContext,
00409 LSP_OP_CONNECTEX,
00410 NULL,
00411 0,
00412 lpOverlapped,
00413 NULL,
00414 NULL,
00415 &Errno
00416 );
00417 if ( NULL == ProviderOverlapped )
00418 {
00419 dbgprint("ExtConnectEx: PrepareOverlappedOperation returned NULL");
00420 goto cleanup;
00421 }
00422
00423 __try
00424 {
00425 ProviderOverlapped->ConnectExArgs.s = s;
00426 ProviderOverlapped->ConnectExArgs.namelen = namelen;
00427 ProviderOverlapped->ConnectExArgs.lpSendBuffer = lpSendBuffer;
00428 ProviderOverlapped->ConnectExArgs.dwSendDataLength = dwSendDataLength;
00429 ProviderOverlapped->ConnectExArgs.dwBytesSent = (lpdwBytesSent ? *lpdwBytesSent : 0);
00430 if ( namelen <= sizeof( ProviderOverlapped->ConnectExArgs.name ) )
00431 CopyMemory( &ProviderOverlapped->ConnectExArgs.name, name, namelen );
00432 }
00433 __except( EXCEPTION_EXECUTE_HANDLER )
00434 {
00435 Errno = WSAEFAULT;
00436 goto cleanup;
00437 }
00438
00439 ret = QueueOverlappedOperation( ProviderOverlapped, SocketContext );
00440 if ( NO_ERROR != ret )
00441 {
00442 Errno = ret;
00443 ret = FALSE;
00444 }
00445 else
00446 {
00447 ret = TRUE;
00448 }
00449 }
00450 else
00451 {
00452 ret = SocketContext->Provider->NextProcTableExt.lpfnConnectEx(
00453 SocketContext->ProviderSocket,
00454 name,
00455 namelen,
00456 lpSendBuffer,
00457 dwSendDataLength,
00458 lpdwBytesSent,
00459 NULL
00460 );
00461 if ( FALSE == ret )
00462 Errno = WSAGetLastError();
00463 }
00464
00465 cleanup:
00466
00467 if ( NULL != SocketContext )
00468 DerefSocketContext( SocketContext, &Errno );
00469
00470 if ( FALSE == ret )
00471 WSASetLastError( Errno );
00472
00473 return ret;
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 BOOL PASCAL FAR
00485 ExtTransmitPackets(
00486 SOCKET hSocket,
00487 LPTRANSMIT_PACKETS_ELEMENT lpPacketArray,
00488 DWORD nElementCount,
00489 DWORD nSendSize,
00490 LPOVERLAPPED lpOverlapped,
00491 DWORD dwFlags)
00492 {
00493 SOCK_INFO *SocketContext = NULL;
00494 LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
00495 int Errno = NO_ERROR,
00496 ret = FALSE;
00497
00498
00499 SocketContext = FindAndRefSocketContext( hSocket, &Errno );
00500 if ( NULL == SocketContext )
00501 {
00502 dbgprint( "ExtTransmitPackets: FindAndRefSocketContext failed!" );
00503 goto cleanup;
00504 }
00505
00506
00507 if ( NULL == SocketContext->Provider->NextProcTableExt.lpfnTransmitPackets )
00508 {
00509 GUID guidTransmitPackets = WSAID_TRANSMITPACKETS;
00510
00511 ret = LoadExtensionFunction(
00512 (FARPROC **)&SocketContext->Provider->NextProcTableExt.lpfnTransmitPackets,
00513 guidTransmitPackets,
00514 SocketContext->Provider->NextProcTable.lpWSPIoctl,
00515 SocketContext->ProviderSocket
00516 );
00517 if ( FALSE == ret )
00518 {
00519 dbgprint( "Next provider's TransmitPackets function is NULL!" );
00520 Errno = WSAEFAULT;
00521 goto cleanup;
00522 }
00523 }
00524
00525
00526
00527
00528 if ( NULL != lpOverlapped )
00529 {
00530 ProviderOverlapped = PrepareOverlappedOperation(
00531 SocketContext,
00532 LSP_OP_TRANSMITPACKETS,
00533 NULL,
00534 0,
00535 lpOverlapped,
00536 NULL,
00537 NULL,
00538 &Errno
00539 );
00540 if ( NULL == ProviderOverlapped )
00541 {
00542 dbgprint("ExtTransmitPackets: PrepareOverlappedOperation returned NULL");
00543 goto cleanup;
00544 }
00545
00546 ProviderOverlapped->lpCallerCompletionRoutine = NULL;
00547 ProviderOverlapped->TransmitPacketsArgs.s = hSocket;
00548 ProviderOverlapped->TransmitPacketsArgs.lpPacketArray = lpPacketArray;
00549 ProviderOverlapped->TransmitPacketsArgs.nElementCount = nElementCount;
00550 ProviderOverlapped->TransmitPacketsArgs.nSendSize = nSendSize;
00551 ProviderOverlapped->TransmitPacketsArgs.dwFlags = dwFlags;
00552
00553 ret = QueueOverlappedOperation( ProviderOverlapped, SocketContext );
00554 if ( NO_ERROR != ret )
00555 {
00556 Errno = ret;
00557 ret = FALSE;
00558 }
00559 else
00560 {
00561 ret = TRUE;
00562 }
00563 }
00564 else
00565 {
00566 ret = SocketContext->Provider->NextProcTableExt.lpfnTransmitPackets(
00567 SocketContext->ProviderSocket,
00568 lpPacketArray,
00569 nElementCount,
00570 nSendSize,
00571 NULL,
00572 dwFlags
00573 );
00574 if ( FALSE == ret )
00575 Errno = WSAGetLastError();
00576 }
00577
00578 cleanup:
00579
00580 if ( NULL != SocketContext )
00581 DerefSocketContext( SocketContext, &Errno );
00582
00583 if ( FALSE == ret )
00584 WSASetLastError( Errno );
00585
00586 return ret;
00587 }
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 BOOL PASCAL FAR
00598 ExtDisconnectEx(
00599 IN SOCKET s,
00600 IN LPOVERLAPPED lpOverlapped,
00601 IN DWORD dwFlags,
00602 IN DWORD dwReserved
00603 )
00604 {
00605 SOCK_INFO *SocketContext = NULL;
00606 LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
00607 int Errno = NO_ERROR,
00608 ret = FALSE;
00609
00610
00611 SocketContext = FindAndRefSocketContext( s, &Errno );
00612 if ( NULL == SocketContext )
00613 {
00614 dbgprint( "ExtDisconnectEx: FindAndRefSocketContext failed!" );
00615 goto cleanup;
00616 }
00617
00618
00619 if ( NULL == SocketContext->Provider->NextProcTableExt.lpfnDisconnectEx )
00620 {
00621 GUID guidDisconnectEx = WSAID_DISCONNECTEX;
00622
00623 ret = LoadExtensionFunction(
00624 (FARPROC **)&SocketContext->Provider->NextProcTableExt.lpfnDisconnectEx,
00625 guidDisconnectEx,
00626 SocketContext->Provider->NextProcTable.lpWSPIoctl,
00627 SocketContext->ProviderSocket
00628 );
00629 if ( FALSE == ret )
00630 {
00631 dbgprint( "Next provider's DisconnectEx function is NULL!" );
00632 Errno = WSAEFAULT;
00633 goto cleanup;
00634 }
00635 }
00636
00637
00638
00639 if ( NULL != lpOverlapped )
00640 {
00641 ProviderOverlapped = PrepareOverlappedOperation(
00642 SocketContext,
00643 LSP_OP_DISCONNECTEX,
00644 NULL,
00645 0,
00646 lpOverlapped,
00647 NULL,
00648 NULL,
00649 &Errno
00650 );
00651 if ( NULL == ProviderOverlapped )
00652 {
00653 dbgprint("ExtDisconnectEx: PrepareOverlappedOperation returned NULL");
00654 goto cleanup;
00655 }
00656
00657 ProviderOverlapped->DisconnectExArgs.s = s;
00658 ProviderOverlapped->DisconnectExArgs.dwFlags = dwFlags;
00659 ProviderOverlapped->DisconnectExArgs.dwReserved = dwReserved;
00660
00661 ret = QueueOverlappedOperation( ProviderOverlapped, SocketContext );
00662 if ( NO_ERROR != ret )
00663 {
00664 Errno = ret;
00665 ret = FALSE;
00666 }
00667 else
00668 {
00669 ret = TRUE;
00670 }
00671 }
00672 else
00673 {
00674 ret = SocketContext->Provider->NextProcTableExt.lpfnDisconnectEx(
00675 SocketContext->ProviderSocket,
00676 lpOverlapped,
00677 dwFlags,
00678 dwReserved
00679 );
00680 if ( FALSE == ret )
00681 Errno = WSAGetLastError();
00682 }
00683
00684 cleanup:
00685
00686 if ( NULL != SocketContext )
00687 DerefSocketContext( SocketContext, &Errno );
00688
00689 if ( FALSE == ret )
00690 WSASetLastError( Errno );
00691
00692 return ret;
00693 }
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703 INT PASCAL FAR
00704 ExtWSARecvMsg(
00705 IN SOCKET s,
00706 IN OUT LPWSAMSG lpMsg,
00707 OUT LPDWORD lpdwNumberOfBytesRecvd,
00708 IN LPWSAOVERLAPPED lpOverlapped,
00709 IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
00710 )
00711 {
00712 SOCK_INFO *SocketContext = NULL;
00713 LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
00714 int Errno = NO_ERROR,
00715 ret = SOCKET_ERROR;
00716
00717
00718 SocketContext = FindAndRefSocketContext( s, &Errno );
00719 if ( NULL == SocketContext )
00720 {
00721 dbgprint( "ExtWSARecvMsg: FindAndRefSocketContext failed!" );
00722 goto cleanup;
00723 }
00724
00725
00726 if ( NULL == SocketContext->Provider->NextProcTableExt.lpfnWSARecvMsg )
00727 {
00728 GUID guidWSARecvMsg = WSAID_WSARECVMSG;
00729
00730 ret = LoadExtensionFunction(
00731 (FARPROC **)&SocketContext->Provider->NextProcTableExt.lpfnWSARecvMsg,
00732 guidWSARecvMsg,
00733 SocketContext->Provider->NextProcTable.lpWSPIoctl,
00734 SocketContext->ProviderSocket
00735 );
00736 if ( FALSE == ret )
00737 {
00738 dbgprint("Next proc table WSARecvMsg == NULL!");
00739 Errno = WSAEFAULT;
00740 goto cleanup;
00741 }
00742 }
00743
00744
00745
00746
00747 if ( NULL != lpOverlapped )
00748 {
00749 ProviderOverlapped = PrepareOverlappedOperation(
00750 SocketContext,
00751 LSP_OP_WSARECVMSG,
00752 NULL,
00753 0,
00754 lpOverlapped,
00755 lpCompletionRoutine,
00756 NULL,
00757 &Errno
00758 );
00759 if ( NULL == ProviderOverlapped )
00760 {
00761 dbgprint("ExtWSARecvMsg: PrepareOverlappedOperation returned NULL");
00762 goto cleanup;
00763 }
00764
00765 __try
00766 {
00767 ProviderOverlapped->WSARecvMsgArgs.dwNumberOfBytesRecvd = (lpdwNumberOfBytesRecvd ? *lpdwNumberOfBytesRecvd : 0);
00768 ProviderOverlapped->WSARecvMsgArgs.s = s;
00769 ProviderOverlapped->WSARecvMsgArgs.lpMsg = lpMsg;
00770 }
00771 __except( EXCEPTION_EXECUTE_HANDLER )
00772 {
00773 Errno = WSAEFAULT;
00774 goto cleanup;
00775 }
00776
00777 ret = QueueOverlappedOperation( ProviderOverlapped, SocketContext );
00778 if ( NO_ERROR != ret )
00779 {
00780 Errno = ret;
00781 ret = SOCKET_ERROR;
00782 }
00783 }
00784 else
00785 {
00786 ASSERT( SocketContext->Provider->NextProcTableExt.lpfnWSARecvMsg );
00787
00788 ret = SocketContext->Provider->NextProcTableExt.lpfnWSARecvMsg(
00789 SocketContext->ProviderSocket,
00790 lpMsg,
00791 lpdwNumberOfBytesRecvd,
00792 NULL,
00793 NULL
00794 );
00795 if ( SOCKET_ERROR == ret )
00796 Errno = WSAGetLastError();
00797 }
00798
00799 cleanup:
00800
00801 if ( NULL != SocketContext )
00802 DerefSocketContext( SocketContext, &Errno );
00803
00804 if ( SOCKET_ERROR == ret )
00805 WSASetLastError( Errno );
00806
00807 return ret;
00808 }