mirror of
https://github.com/reactos/reactos.git
synced 2024-07-02 02:34:53 +00:00
[MSAFD] Implement WSPIoctl overlapped. CORE-12162 #resolve
svn path=/trunk/; revision=73030
This commit is contained in:
parent
04442ae74c
commit
ca5719a178
|
@ -352,7 +352,13 @@ WSPSocket(int AddressFamily,
|
|||
/* Save Group Info */
|
||||
if (g != 0)
|
||||
{
|
||||
GetSocketInformation(Socket, AFD_INFO_GROUP_ID_TYPE, NULL, NULL, &GroupData);
|
||||
GetSocketInformation(Socket,
|
||||
AFD_INFO_GROUP_ID_TYPE,
|
||||
NULL,
|
||||
NULL,
|
||||
&GroupData,
|
||||
NULL,
|
||||
NULL);
|
||||
Socket->SharedData->GroupID = GroupData.u.LowPart;
|
||||
Socket->SharedData->GroupType = GroupData.u.HighPart;
|
||||
}
|
||||
|
@ -362,12 +368,16 @@ WSPSocket(int AddressFamily,
|
|||
AFD_INFO_SEND_WINDOW_SIZE,
|
||||
NULL,
|
||||
&Socket->SharedData->SizeOfSendBuffer,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
GetSocketInformation (Socket,
|
||||
AFD_INFO_RECEIVE_WINDOW_SIZE,
|
||||
NULL,
|
||||
&Socket->SharedData->SizeOfRecvBuffer,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
ok:
|
||||
|
||||
|
@ -614,7 +624,7 @@ WSPCloseSocket(IN SOCKET Handle,
|
|||
if (!Socket)
|
||||
{
|
||||
NtClose(SockEvent);
|
||||
*lpErrno = WSAENOTSOCK;
|
||||
if (lpErrno) *lpErrno = WSAENOTSOCK;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -640,7 +650,7 @@ WSPCloseSocket(IN SOCKET Handle,
|
|||
{
|
||||
WARN("Socket is closing.\n");
|
||||
NtClose(SockEvent);
|
||||
*lpErrno = WSAENOTSOCK;
|
||||
if (lpErrno) *lpErrno = WSAENOTSOCK;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
/* Set the state to close */
|
||||
|
@ -671,6 +681,8 @@ WSPCloseSocket(IN SOCKET Handle,
|
|||
AFD_INFO_SENDS_IN_PROGRESS,
|
||||
NULL,
|
||||
&SendsInProgress,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL))
|
||||
{
|
||||
/* Bail out if anything but NO_ERROR */
|
||||
|
@ -696,7 +708,7 @@ WSPCloseSocket(IN SOCKET Handle,
|
|||
WARN("Would block!\n");
|
||||
NtClose(SockEvent);
|
||||
Socket->SharedData->State = OldState;
|
||||
*lpErrno = WSAEWOULDBLOCK;
|
||||
if (lpErrno) *lpErrno = WSAEWOULDBLOCK;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -2182,132 +2194,154 @@ WSPIoctl(IN SOCKET Handle,
|
|||
OUT LPINT lpErrno)
|
||||
{
|
||||
PSOCKET_INFORMATION Socket = NULL;
|
||||
BOOLEAN NeedsCompletion;
|
||||
BOOLEAN NeedsCompletion = lpOverlapped != NULL;
|
||||
BOOLEAN NonBlocking;
|
||||
|
||||
if (!lpcbBytesReturned)
|
||||
{
|
||||
*lpErrno = WSAEFAULT;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
INT Errno = NO_ERROR, Ret = SOCKET_ERROR;
|
||||
DWORD cbRet = 0;
|
||||
|
||||
/* Get the Socket Structure associate to this Socket*/
|
||||
Socket = GetSocketStructure(Handle);
|
||||
if (!Socket)
|
||||
{
|
||||
*lpErrno = WSAENOTSOCK;
|
||||
return SOCKET_ERROR;
|
||||
if(lpErrno)
|
||||
*lpErrno = WSAENOTSOCK;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
*lpcbBytesReturned = 0;
|
||||
if (!lpcbBytesReturned && !lpOverlapped)
|
||||
{
|
||||
if(lpErrno)
|
||||
*lpErrno = WSAEFAULT;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
switch( dwIoControlCode )
|
||||
{
|
||||
case FIONBIO:
|
||||
if( cbInBuffer < sizeof(INT) || IS_INTRESOURCE(lpvInBuffer) )
|
||||
{
|
||||
*lpErrno = WSAEFAULT;
|
||||
return SOCKET_ERROR;
|
||||
Errno = WSAEFAULT;
|
||||
break;
|
||||
}
|
||||
NonBlocking = *((PULONG)lpvInBuffer) ? TRUE : FALSE;
|
||||
Socket->SharedData->NonBlocking = NonBlocking ? 1 : 0;
|
||||
*lpErrno = SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &NonBlocking, NULL, NULL);
|
||||
if (*lpErrno != NO_ERROR)
|
||||
return SOCKET_ERROR;
|
||||
else
|
||||
return NO_ERROR;
|
||||
NeedsCompletion = FALSE;
|
||||
Errno = SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &NonBlocking, NULL, NULL, lpOverlapped, lpCompletionRoutine);
|
||||
if (Errno == NO_ERROR)
|
||||
Ret = NO_ERROR;
|
||||
break;
|
||||
case FIONREAD:
|
||||
if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
|
||||
{
|
||||
*lpcbBytesReturned = sizeof(ULONG);
|
||||
*lpErrno = WSAEFAULT;
|
||||
return SOCKET_ERROR;
|
||||
cbRet = sizeof(ULONG);
|
||||
Errno = WSAEFAULT;
|
||||
break;
|
||||
}
|
||||
if (cbOutBuffer < sizeof(ULONG))
|
||||
{
|
||||
*lpErrno = WSAEINVAL;
|
||||
return SOCKET_ERROR;
|
||||
Errno = WSAEINVAL;
|
||||
break;
|
||||
}
|
||||
*lpErrno = GetSocketInformation(Socket, AFD_INFO_RECEIVE_CONTENT_SIZE, NULL, (PULONG)lpvOutBuffer, NULL);
|
||||
if (*lpErrno != NO_ERROR)
|
||||
return SOCKET_ERROR;
|
||||
else
|
||||
{
|
||||
*lpcbBytesReturned = sizeof(ULONG);
|
||||
return NO_ERROR;
|
||||
}
|
||||
NeedsCompletion = FALSE;
|
||||
Errno = GetSocketInformation(Socket, AFD_INFO_RECEIVE_CONTENT_SIZE, NULL, (PULONG)lpvOutBuffer, NULL, lpOverlapped, lpCompletionRoutine);
|
||||
if (Errno == NO_ERROR)
|
||||
{
|
||||
cbRet = sizeof(ULONG);
|
||||
Ret = NO_ERROR;
|
||||
}
|
||||
break;
|
||||
case SIOCATMARK:
|
||||
if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
|
||||
{
|
||||
*lpcbBytesReturned = sizeof(BOOL);
|
||||
*lpErrno = WSAEFAULT;
|
||||
return SOCKET_ERROR;
|
||||
cbRet = sizeof(BOOL);
|
||||
Errno = WSAEFAULT;
|
||||
break;
|
||||
}
|
||||
if (cbOutBuffer < sizeof(BOOL))
|
||||
{
|
||||
*lpErrno = WSAEINVAL;
|
||||
return SOCKET_ERROR;
|
||||
Errno = WSAEINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* FIXME: Return false for now */
|
||||
*(BOOL*)lpvOutBuffer = FALSE;
|
||||
|
||||
*lpcbBytesReturned = sizeof(BOOL);
|
||||
*lpErrno = NO_ERROR;
|
||||
return NO_ERROR;
|
||||
cbRet = sizeof(BOOL);
|
||||
Errno = NO_ERROR;
|
||||
Ret = NO_ERROR;
|
||||
break;
|
||||
case SIO_GET_EXTENSION_FUNCTION_POINTER:
|
||||
*lpErrno = WSAEINVAL;
|
||||
return SOCKET_ERROR;
|
||||
|
||||
Errno = WSAEINVAL;
|
||||
break;
|
||||
case SIO_ADDRESS_LIST_QUERY:
|
||||
if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
|
||||
{
|
||||
*lpcbBytesReturned = sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress);
|
||||
*lpErrno = WSAEFAULT;
|
||||
return SOCKET_ERROR;
|
||||
cbRet = sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress);
|
||||
Errno = WSAEFAULT;
|
||||
break;
|
||||
}
|
||||
if (cbOutBuffer < sizeof(INT))
|
||||
{
|
||||
*lpErrno = WSAEINVAL;
|
||||
return SOCKET_ERROR;
|
||||
Errno = WSAEINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
*lpcbBytesReturned = sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress);
|
||||
cbRet = sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress);
|
||||
|
||||
((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->iAddressCount = 1;
|
||||
|
||||
if (cbOutBuffer < (sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress)))
|
||||
{
|
||||
*lpErrno = WSAEFAULT;
|
||||
return SOCKET_ERROR;
|
||||
Errno = WSAEFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].iSockaddrLength = sizeof(Socket->SharedData->WSLocalAddress);
|
||||
((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].lpSockaddr = &Socket->SharedData->WSLocalAddress;
|
||||
|
||||
*lpErrno = NO_ERROR;
|
||||
return NO_ERROR;
|
||||
|
||||
Errno = NO_ERROR;
|
||||
Ret = NO_ERROR;
|
||||
break;
|
||||
default:
|
||||
*lpErrno = Socket->HelperData->WSHIoctl(Socket->HelperContext,
|
||||
Handle,
|
||||
Socket->TdiAddressHandle,
|
||||
Socket->TdiConnectionHandle,
|
||||
dwIoControlCode,
|
||||
lpvInBuffer,
|
||||
cbInBuffer,
|
||||
lpvOutBuffer,
|
||||
cbOutBuffer,
|
||||
lpcbBytesReturned,
|
||||
lpOverlapped,
|
||||
lpCompletionRoutine,
|
||||
(LPBOOL)&NeedsCompletion);
|
||||
Errno = Socket->HelperData->WSHIoctl(Socket->HelperContext,
|
||||
Handle,
|
||||
Socket->TdiAddressHandle,
|
||||
Socket->TdiConnectionHandle,
|
||||
dwIoControlCode,
|
||||
lpvInBuffer,
|
||||
cbInBuffer,
|
||||
lpvOutBuffer,
|
||||
cbOutBuffer,
|
||||
&cbRet,
|
||||
lpOverlapped,
|
||||
lpCompletionRoutine,
|
||||
(LPBOOL)&NeedsCompletion);
|
||||
|
||||
if (*lpErrno != NO_ERROR)
|
||||
return SOCKET_ERROR;
|
||||
else
|
||||
return NO_ERROR;
|
||||
if (Errno == NO_ERROR)
|
||||
Ret = NO_ERROR;
|
||||
break;
|
||||
}
|
||||
if (lpOverlapped && NeedsCompletion)
|
||||
{
|
||||
lpOverlapped->Internal = Errno;
|
||||
lpOverlapped->InternalHigh = cbRet;
|
||||
if (lpCompletionRoutine != NULL)
|
||||
{
|
||||
lpCompletionRoutine(Errno, cbRet, lpOverlapped, 0);
|
||||
}
|
||||
if (lpOverlapped->hEvent)
|
||||
SetEvent(lpOverlapped->hEvent);
|
||||
if (!PostQueuedCompletionStatus((HANDLE)Handle, cbRet, 0, lpOverlapped))
|
||||
{
|
||||
ERR("PostQueuedCompletionStatus failed %d\n", GetLastError());
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
if (lpErrno)
|
||||
*lpErrno = Errno;
|
||||
if (lpcbBytesReturned)
|
||||
*lpcbBytesReturned = cbRet;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2852,18 +2886,34 @@ WSPCleanup(OUT LPINT lpErrno)
|
|||
return 0;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
AfdInfoAPC(PVOID ApcContext,
|
||||
PIO_STATUS_BLOCK IoStatusBlock,
|
||||
ULONG Reserved)
|
||||
{
|
||||
PAFDAPCCONTEXT Context = ApcContext;
|
||||
|
||||
Context->lpCompletionRoutine(IoStatusBlock->Status, IoStatusBlock->Information, Context->lpOverlapped, 0);
|
||||
HeapFree(GlobalHeap, 0, ApcContext);
|
||||
}
|
||||
|
||||
int
|
||||
GetSocketInformation(PSOCKET_INFORMATION Socket,
|
||||
ULONG AfdInformationClass,
|
||||
PBOOLEAN Boolean OPTIONAL,
|
||||
PULONG Ulong OPTIONAL,
|
||||
PLARGE_INTEGER LargeInteger OPTIONAL)
|
||||
PLARGE_INTEGER LargeInteger OPTIONAL,
|
||||
LPWSAOVERLAPPED Overlapped OPTIONAL,
|
||||
LPWSAOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine OPTIONAL)
|
||||
{
|
||||
IO_STATUS_BLOCK IOSB;
|
||||
PIO_STATUS_BLOCK IOSB;
|
||||
IO_STATUS_BLOCK DummyIOSB;
|
||||
AFD_INFO InfoData;
|
||||
NTSTATUS Status;
|
||||
PVOID APCContext;
|
||||
PIO_APC_ROUTINE APCFunction;
|
||||
HANDLE Event = NULL;
|
||||
HANDLE SockEvent;
|
||||
|
||||
Status = NtCreateEvent(&SockEvent,
|
||||
|
@ -2878,12 +2928,56 @@ GetSocketInformation(PSOCKET_INFORMATION Socket,
|
|||
/* Set Info Class */
|
||||
InfoData.InformationClass = AfdInformationClass;
|
||||
|
||||
/* Verify if we should use APC */
|
||||
if (Overlapped == NULL)
|
||||
{
|
||||
/* Not using Overlapped structure, so use normal blocking on event */
|
||||
APCContext = NULL;
|
||||
APCFunction = NULL;
|
||||
Event = SockEvent;
|
||||
IOSB = &DummyIOSB;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Overlapped request for non overlapped opened socket */
|
||||
if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
|
||||
{
|
||||
TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
|
||||
return 0;
|
||||
}
|
||||
if (CompletionRoutine == NULL)
|
||||
{
|
||||
/* Using Overlapped Structure, but no Completition Routine, so no need for APC */
|
||||
APCContext = Overlapped;
|
||||
APCFunction = NULL;
|
||||
Event = Overlapped->hEvent;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Using Overlapped Structure and a Completition Routine, so use an APC */
|
||||
APCFunction = &AfdInfoAPC; // should be a private io completition function inside us
|
||||
APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
|
||||
if (!APCContext)
|
||||
{
|
||||
ERR("Not enough memory for APC Context\n");
|
||||
return WSAEFAULT;
|
||||
}
|
||||
((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = CompletionRoutine;
|
||||
((PAFDAPCCONTEXT)APCContext)->lpOverlapped = Overlapped;
|
||||
((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket;
|
||||
}
|
||||
|
||||
IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal;
|
||||
}
|
||||
|
||||
IOSB->Status = STATUS_PENDING;
|
||||
|
||||
/* Send IOCTL */
|
||||
Status = NtDeviceIoControlFile((HANDLE)Socket->Handle,
|
||||
SockEvent,
|
||||
NULL,
|
||||
NULL,
|
||||
&IOSB,
|
||||
Event,
|
||||
APCFunction,
|
||||
APCContext,
|
||||
IOSB,
|
||||
IOCTL_AFD_GET_INFO,
|
||||
&InfoData,
|
||||
sizeof(InfoData),
|
||||
|
@ -2891,10 +2985,18 @@ GetSocketInformation(PSOCKET_INFORMATION Socket,
|
|||
sizeof(InfoData));
|
||||
|
||||
/* Wait for return */
|
||||
if (Status == STATUS_PENDING)
|
||||
if (Status == STATUS_PENDING && Overlapped == NULL)
|
||||
{
|
||||
WaitForSingleObject(SockEvent, INFINITE);
|
||||
Status = IOSB.Status;
|
||||
Status = IOSB->Status;
|
||||
}
|
||||
|
||||
TRACE("Status %x Information %d\n", Status, IOSB->Information);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
TRACE("Leaving (Pending)\n");
|
||||
return WSA_IO_PENDING;
|
||||
}
|
||||
|
||||
if (Status != STATUS_SUCCESS)
|
||||
|
@ -2926,11 +3028,17 @@ SetSocketInformation(PSOCKET_INFORMATION Socket,
|
|||
ULONG AfdInformationClass,
|
||||
PBOOLEAN Boolean OPTIONAL,
|
||||
PULONG Ulong OPTIONAL,
|
||||
PLARGE_INTEGER LargeInteger OPTIONAL)
|
||||
PLARGE_INTEGER LargeInteger OPTIONAL,
|
||||
LPWSAOVERLAPPED Overlapped OPTIONAL,
|
||||
LPWSAOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine OPTIONAL)
|
||||
{
|
||||
IO_STATUS_BLOCK IOSB;
|
||||
PIO_STATUS_BLOCK IOSB;
|
||||
IO_STATUS_BLOCK DummyIOSB;
|
||||
AFD_INFO InfoData;
|
||||
NTSTATUS Status;
|
||||
PVOID APCContext;
|
||||
PIO_APC_ROUTINE APCFunction;
|
||||
HANDLE Event = NULL;
|
||||
HANDLE SockEvent;
|
||||
|
||||
Status = NtCreateEvent(&SockEvent,
|
||||
|
@ -2959,12 +3067,56 @@ SetSocketInformation(PSOCKET_INFORMATION Socket,
|
|||
InfoData.Information.Boolean = *Boolean;
|
||||
}
|
||||
|
||||
/* Verify if we should use APC */
|
||||
if (Overlapped == NULL)
|
||||
{
|
||||
/* Not using Overlapped structure, so use normal blocking on event */
|
||||
APCContext = NULL;
|
||||
APCFunction = NULL;
|
||||
Event = SockEvent;
|
||||
IOSB = &DummyIOSB;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Overlapped request for non overlapped opened socket */
|
||||
if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
|
||||
{
|
||||
TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
|
||||
return 0;
|
||||
}
|
||||
if (CompletionRoutine == NULL)
|
||||
{
|
||||
/* Using Overlapped Structure, but no Completition Routine, so no need for APC */
|
||||
APCContext = Overlapped;
|
||||
APCFunction = NULL;
|
||||
Event = Overlapped->hEvent;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Using Overlapped Structure and a Completition Routine, so use an APC */
|
||||
APCFunction = &AfdInfoAPC; // should be a private io completition function inside us
|
||||
APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
|
||||
if (!APCContext)
|
||||
{
|
||||
ERR("Not enough memory for APC Context\n");
|
||||
return WSAEFAULT;
|
||||
}
|
||||
((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = CompletionRoutine;
|
||||
((PAFDAPCCONTEXT)APCContext)->lpOverlapped = Overlapped;
|
||||
((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket;
|
||||
}
|
||||
|
||||
IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal;
|
||||
}
|
||||
|
||||
IOSB->Status = STATUS_PENDING;
|
||||
|
||||
/* Send IOCTL */
|
||||
Status = NtDeviceIoControlFile((HANDLE)Socket->Handle,
|
||||
SockEvent,
|
||||
NULL,
|
||||
NULL,
|
||||
&IOSB,
|
||||
Event,
|
||||
APCFunction,
|
||||
APCContext,
|
||||
IOSB,
|
||||
IOCTL_AFD_SET_INFO,
|
||||
&InfoData,
|
||||
sizeof(InfoData),
|
||||
|
@ -2972,14 +3124,22 @@ SetSocketInformation(PSOCKET_INFORMATION Socket,
|
|||
0);
|
||||
|
||||
/* Wait for return */
|
||||
if (Status == STATUS_PENDING)
|
||||
if (Status == STATUS_PENDING && Overlapped == NULL)
|
||||
{
|
||||
WaitForSingleObject(SockEvent, INFINITE);
|
||||
Status = IOSB.Status;
|
||||
Status = IOSB->Status;
|
||||
}
|
||||
|
||||
NtClose( SockEvent );
|
||||
|
||||
TRACE("Status %x Information %d\n", Status, IOSB->Information);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
TRACE("Leaving (Pending)\n");
|
||||
return WSA_IO_PENDING;
|
||||
}
|
||||
|
||||
return Status == STATUS_SUCCESS ? 0 : -1;
|
||||
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ WSPEventSelect(
|
|||
|
||||
/* Set Socket to Non-Blocking */
|
||||
BlockMode = TRUE;
|
||||
SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &BlockMode, NULL, NULL);
|
||||
SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &BlockMode, NULL, NULL, NULL, NULL);
|
||||
Socket->SharedData->NonBlocking = TRUE;
|
||||
|
||||
/* Deactivate Async Select if there is one */
|
||||
|
|
|
@ -45,7 +45,7 @@ WSPAsyncSelect(IN SOCKET Handle,
|
|||
|
||||
/* Change the Socket to Non Blocking */
|
||||
BlockMode = TRUE;
|
||||
SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &BlockMode, NULL, NULL);
|
||||
SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &BlockMode, NULL, NULL, NULL, NULL);
|
||||
Socket->SharedData->NonBlocking = TRUE;
|
||||
|
||||
/* Deactive WSPEventSelect */
|
||||
|
@ -104,9 +104,8 @@ WSPGetOverlappedResult(
|
|||
OUT LPDWORD lpdwFlags,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
PIO_STATUS_BLOCK IOSB;
|
||||
NTSTATUS Status;
|
||||
PSOCKET_INFORMATION Socket;
|
||||
BOOL Ret;
|
||||
|
||||
TRACE("Called (%x)\n", Handle);
|
||||
|
||||
|
@ -124,43 +123,19 @@ WSPGetOverlappedResult(
|
|||
*lpErrno = WSAEFAULT;
|
||||
return FALSE;
|
||||
}
|
||||
IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
|
||||
if (!IOSB)
|
||||
{
|
||||
if (lpErrno)
|
||||
*lpErrno = WSAEFAULT;
|
||||
return FALSE;
|
||||
}
|
||||
Status = IOSB->Status;
|
||||
Ret = GetOverlappedResult((HANDLE)Handle, lpOverlapped, lpdwBytes, fWait);
|
||||
|
||||
/* Wait for completition of overlapped */
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
/* It's up to the protocol to time out recv. We must wait
|
||||
* until the protocol decides it's had enough.
|
||||
*/
|
||||
if (fWait)
|
||||
{
|
||||
WaitForSingleObject(lpOverlapped->hEvent, INFINITE);
|
||||
Status = IOSB->Status;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("Status %x Information %d\n", Status, IOSB->Information);
|
||||
|
||||
if (Status != STATUS_PENDING)
|
||||
if (Ret)
|
||||
{
|
||||
*lpdwFlags = 0;
|
||||
|
||||
*lpdwBytes = IOSB->Information;
|
||||
|
||||
/* Re-enable Async Event */
|
||||
SockReenableAsyncSelectEvent(Socket, FD_OOB);
|
||||
SockReenableAsyncSelectEvent(Socket, FD_WRITE);
|
||||
SockReenableAsyncSelectEvent(Socket, FD_READ);
|
||||
}
|
||||
|
||||
return Status == STATUS_SUCCESS;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
VOID
|
||||
|
|
|
@ -434,7 +434,9 @@ int GetSocketInformation(
|
|||
ULONG AfdInformationClass,
|
||||
PBOOLEAN Boolean OPTIONAL,
|
||||
PULONG Ulong OPTIONAL,
|
||||
PLARGE_INTEGER LargeInteger OPTIONAL
|
||||
PLARGE_INTEGER LargeInteger OPTIONAL,
|
||||
LPWSAOVERLAPPED Overlapped OPTIONAL,
|
||||
LPWSAOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine OPTIONAL
|
||||
);
|
||||
|
||||
int SetSocketInformation(
|
||||
|
@ -442,7 +444,9 @@ int SetSocketInformation(
|
|||
ULONG AfdInformationClass,
|
||||
PBOOLEAN Boolean OPTIONAL,
|
||||
PULONG Ulong OPTIONAL,
|
||||
PLARGE_INTEGER LargeInteger OPTIONAL
|
||||
PLARGE_INTEGER LargeInteger OPTIONAL,
|
||||
LPWSAOVERLAPPED Overlapped OPTIONAL,
|
||||
LPWSAOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine OPTIONAL
|
||||
);
|
||||
|
||||
int CreateContext(
|
||||
|
|
Loading…
Reference in a new issue