Fix IO completion APIs/Structures.

Implement WSPASyncSelect and friends. Event re-enabling functionality missing and will be added tonight.

svn path=/trunk/; revision=11807
This commit is contained in:
Alex Ionescu 2004-11-25 22:18:17 +00:00
parent 3379855217
commit 1623a0079f
13 changed files with 512 additions and 73 deletions

View file

@ -52,10 +52,10 @@ typedef struct _AFD_HANDLE_ {
} AFD_HANDLE, *PAFD_HANDLE;
typedef struct _AFD_POLL_INFO {
LARGE_INTEGER Timeout;
ULONG HandleCount;
PAFD_HANDLE InternalUse;
AFD_HANDLE Handles[1];
LARGE_INTEGER Timeout;
ULONG HandleCount;
BOOLEAN Exclusive;
AFD_HANDLE Handles[1];
} AFD_POLL_INFO, *PAFD_POLL_INFO;
typedef struct _AFD_ACCEPT_DATA {

View file

@ -1,4 +1,4 @@
/* $Id: iotypes.h,v 1.69 2004/11/06 04:12:59 ion Exp $
/* $Id: iotypes.h,v 1.70 2004/11/25 22:18:15 ion Exp $
*
*/
@ -752,7 +752,7 @@ typedef struct _SECTION_OBJECT_POINTERS
typedef struct _IO_COMPLETION_CONTEXT
{
PVOID Port;
ULONG Key;
PVOID Key;
} IO_COMPLETION_CONTEXT, *PIO_COMPLETION_CONTEXT;
#define FO_FILE_OPEN 0x00000001

View file

@ -1,5 +1,5 @@
/* $Id: zw.h,v 1.35 2004/11/12 12:06:17 ekohl Exp $
/* $Id: zw.h,v 1.36 2004/11/25 22:18:15 ion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -3567,8 +3567,8 @@ NTSTATUS
STDCALL
NtRemoveIoCompletion(
IN HANDLE IoCompletionHandle,
OUT PULONG CompletionKey,
OUT PULONG CompletionValue,
OUT PVOID *CompletionKey,
OUT PVOID *CompletionContext,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER Timeout OPTIONAL
);
@ -3577,8 +3577,8 @@ NTSTATUS
STDCALL
ZwRemoveIoCompletion(
IN HANDLE IoCompletionHandle,
OUT PULONG CompletionKey,
OUT PULONG CompletionValue,
OUT PVOID *CompletionKey,
OUT PVOID *CompletionValue,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER Timeout OPTIONAL
);
@ -4094,8 +4094,8 @@ NTSTATUS
STDCALL
NtSetIoCompletion(
IN HANDLE IoCompletionPortHandle,
IN ULONG CompletionKey,
IN ULONG CompletionValue,
IN PVOID CompletionKey,
IN PVOID CompletionContext,
IN NTSTATUS CompletionStatus,
IN ULONG CompletionInformation
);
@ -4104,8 +4104,8 @@ NTSTATUS
STDCALL
ZwSetIoCompletion(
IN HANDLE IoCompletionPortHandle,
IN ULONG CompletionKey,
IN ULONG CompletionValue,
IN PVOID CompletionKey,
IN PVOID CompletionContext,
IN NTSTATUS CompletionStatus,
IN ULONG CompletionInformation
);

View file

@ -971,7 +971,7 @@ typedef struct _FILE_COMPRESSION_INFORMATION {
typedef struct _FILE_COMPLETION_INFORMATION { // Information Class 30
HANDLE IoCompletionHandle;
ULONG CompletionKey;
PVOID CompletionKey;
} FILE_COMPLETION_INFORMATION, *PFILE_COMPLETION_INFORMATION;
typedef struct _FILE_ALL_INFORMATION {

View file

@ -1,4 +1,4 @@
/* $Id: iocompl.c,v 1.15 2004/10/30 22:18:17 weiden Exp $
/* $Id: iocompl.c,v 1.16 2004/11/25 22:18:16 ion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -23,7 +23,7 @@ STDCALL
CreateIoCompletionPort(
HANDLE FileHandle,
HANDLE ExistingCompletionPort,
DWORD CompletionKey,
ULONG_PTR CompletionKey,
DWORD NumberOfConcurrentThreads
)
{
@ -62,7 +62,7 @@ CreateIoCompletionPort(
{
#ifdef __USE_W32API
CompletionInformation.Port = CompletionPort;
CompletionInformation.Key = CompletionKey;
CompletionInformation.Key = (PVOID)CompletionKey;
#else
CompletionInformation.IoCompletionHandle = CompletionPort;
CompletionInformation.CompletionKey = CompletionKey;
@ -98,7 +98,7 @@ STDCALL
GetQueuedCompletionStatus(
HANDLE CompletionHandle,
LPDWORD lpNumberOfBytesTransferred,
LPDWORD lpCompletionKey,
PULONG_PTR lpCompletionKey,
LPOVERLAPPED *lpOverlapped,
DWORD dwMilliseconds
)
@ -127,8 +127,8 @@ GetQueuedCompletionStatus(
}
errCode = NtRemoveIoCompletion(CompletionHandle,
lpCompletionKey,
lpNumberOfBytesTransferred,
(PVOID*)lpCompletionKey,
(PVOID*)lpNumberOfBytesTransferred,
&IoStatus,
&Interval);
@ -166,10 +166,10 @@ PostQueuedCompletionStatus(
NTSTATUS errCode;
errCode = NtSetIoCompletion(CompletionHandle,
dwCompletionKey,
dwNumberOfBytesTransferred,//CompletionValue
0, //IoStatusBlock->Status
(ULONG)lpOverlapped ); //IoStatusBlock->Information
(PVOID)dwCompletionKey,
(PVOID)lpOverlapped,//CompletionValue
STATUS_SUCCESS, //IoStatusBlock->Status
dwNumberOfBytesTransferred); //IoStatusBlock->Information
if ( !NT_SUCCESS(errCode) )
{

View file

@ -22,11 +22,17 @@
#include <helpers.h>
#include <debug.h>
/* Because our headers are f*cked up */
typedef LARGE_INTEGER TIME;
#include <ntos/zw.h>
extern HANDLE GlobalHeap;
extern WSPUPCALLTABLE Upcalls;
extern LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest;
extern LIST_ENTRY SockHelpersListHead;
extern HANDLE SockEvent;
extern HANDLE SockAsyncCompletionPort;
extern BOOLEAN SockAsyncSelectCalled;
typedef enum _SOCKET_STATE {
SocketOpen,
@ -74,41 +80,48 @@ typedef struct _SOCK_SHARED_INFO {
LONG Unknown;
DWORD SequenceNumber;
UINT wMsg;
LONG Event;
LONG DisabledEvents;
LONG AsyncEvents;
LONG AsyncDisabledEvents;
} SOCK_SHARED_INFO, *PSOCK_SHARED_INFO;
typedef struct _SOCKET_INFORMATION {
ULONG RefCount;
SOCKET Handle;
SOCK_SHARED_INFO SharedData;
DWORD HelperEvents;
PHELPER_DATA HelperData;
PVOID HelperContext;
PSOCKADDR LocalAddress;
PSOCKADDR RemoteAddress;
HANDLE TdiAddressHandle;
HANDLE TdiConnectionHandle;
PVOID AsyncData;
HANDLE EventObject;
LONG NetworkEvents;
CRITICAL_SECTION Lock;
PVOID SanData;
BOOL TrySAN;
SOCKADDR WSLocalAddress;
SOCKADDR WSRemoteAddress;
ULONG RefCount;
SOCKET Handle;
SOCK_SHARED_INFO SharedData;
DWORD HelperEvents;
PHELPER_DATA HelperData;
PVOID HelperContext;
PSOCKADDR LocalAddress;
PSOCKADDR RemoteAddress;
HANDLE TdiAddressHandle;
HANDLE TdiConnectionHandle;
PVOID AsyncData;
HANDLE EventObject;
LONG NetworkEvents;
CRITICAL_SECTION Lock;
PVOID SanData;
BOOL TrySAN;
SOCKADDR WSLocalAddress;
SOCKADDR WSRemoteAddress;
} SOCKET_INFORMATION, *PSOCKET_INFORMATION;
typedef struct _SOCKET_CONTEXT {
SOCK_SHARED_INFO SharedData;
ULONG SizeOfHelperData;
ULONG Padding;
SOCKADDR LocalAddress;
SOCKADDR RemoteAddress;
SOCK_SHARED_INFO SharedData;
ULONG SizeOfHelperData;
ULONG Padding;
SOCKADDR LocalAddress;
SOCKADDR RemoteAddress;
/* Plus Helper Data */
} SOCKET_CONTEXT, *PSOCKET_CONTEXT;
typedef struct _ASYNC_DATA {
PSOCKET_INFORMATION ParentSocket;
DWORD SequenceNumber;
IO_STATUS_BLOCK IoStatusBlock;
AFD_POLL_INFO AsyncSelectInfo;
} ASYNC_DATA, *PASYNC_DATA;
SOCKET
WSPAPI
WSPAccept(
@ -416,6 +429,39 @@ int SetSocketInformation(
int CreateContext(
PSOCKET_INFORMATION Socket
);
int SockAsyncThread(
PVOID ThreadParam
);
VOID
SockProcessAsyncSelect(
PSOCKET_INFORMATION Socket,
PASYNC_DATA AsyncData
);
VOID
SockAsyncSelectCompletionRoutine(
PVOID Context,
PIO_STATUS_BLOCK IoStatusBlock
);
BOOLEAN
SockCreateOrReferenceAsyncThread(
VOID
);
BOOLEAN SockGetAsyncSelectHelperAfdHandle(
VOID
);
VOID SockProcessQueuedAsyncSelect(
PVOID Context,
PIO_STATUS_BLOCK IoStatusBlock
);
typedef VOID (*PASYNC_COMPLETION_ROUTINE)(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock);
#endif /* __MSAFD_H */
/* EOF */

View file

@ -20,12 +20,16 @@
DWORD DebugTraceLevel = 0;
#endif /* DBG */
HANDLE GlobalHeap;
WSPUPCALLTABLE Upcalls;
LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest;
ULONG SocketCount;
PSOCKET_INFORMATION *Sockets = NULL;
LIST_ENTRY SockHelpersListHead = {NULL};
HANDLE GlobalHeap;
WSPUPCALLTABLE Upcalls;
LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest;
ULONG SocketCount;
PSOCKET_INFORMATION *Sockets = NULL;
LIST_ENTRY SockHelpersListHead = {NULL};
ULONG SockAsyncThreadRefCount;
HANDLE SockAsyncHelperAfdHandle;
HANDLE SockAsyncCompletionPort;
BOOLEAN SockAsyncSelectCalled;
SOCKET
WSPAPI
@ -456,7 +460,7 @@ WSPSelect(
/* Number of handles for AFD to Check */
PollInfo->HandleCount = HandleCount;
PollInfo->InternalUse = 0;
PollInfo->Exclusive = FALSE;
if (readfds != NULL) {
for (i = 0; i < readfds->fd_count; i++, j++) {
@ -1291,6 +1295,342 @@ int CreateContext(PSOCKET_INFORMATION Socket)
return 0;
}
BOOLEAN SockCreateOrReferenceAsyncThread(VOID)
{
HANDLE hAsyncThread;
DWORD AsyncThreadId;
HANDLE AsyncEvent;
OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleFlags;
NTSTATUS Status;
/* Check if the Thread Already Exists */
if (SockAsyncThreadRefCount) {
return TRUE;
}
/* Create the Completion Port */
if (!SockAsyncCompletionPort) {
Status = NtCreateIoCompletion(&SockAsyncCompletionPort,
IO_COMPLETION_ALL_ACCESS,
NULL,
2); // Allow 2 threads only
/* Protect Handle */
HandleFlags.ProtectFromClose = TRUE;
HandleFlags.Inherit = FALSE;
Status = NtSetInformationObject(SockAsyncCompletionPort,
ObjectHandleInformation,
&HandleFlags,
sizeof(HandleFlags));
}
/* Create the Async Event */
Status = NtCreateEvent(&AsyncEvent,
EVENT_ALL_ACCESS,
NULL,
NotificationEvent,
FALSE);
/* Create the Async Thread */
hAsyncThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)SockAsyncThread,
NULL,
0,
&AsyncThreadId);
/* Close the Handle */
NtClose(hAsyncThread);
/* Increase the Reference Count */
SockAsyncThreadRefCount++;
return TRUE;
}
int SockAsyncThread(PVOID ThreadParam)
{
PVOID AsyncContext;
PASYNC_COMPLETION_ROUTINE AsyncCompletionRoutine;
IO_STATUS_BLOCK IOSB;
NTSTATUS Status;
LARGE_INTEGER Timeout;
/* Make the Thread Higher Priority */
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
/* Do a KQUEUE/WorkItem Style Loop, thanks to IoCompletion Ports */
do {
Status = NtRemoveIoCompletion (SockAsyncCompletionPort,
(PVOID*)&AsyncCompletionRoutine,
&AsyncContext,
&IOSB,
&Timeout);
/* Call the Async Function */
if (NT_SUCCESS(Status)) {
//(*AsyncCompletionRoutine)(AsyncContext, IOSB);
} else {
/* It Failed, sleep for a second */
Sleep(1000);
}
} while ((Status != STATUS_TIMEOUT));
/* The Thread has Ended */
return 0;
}
BOOLEAN SockGetAsyncSelectHelperAfdHandle(VOID)
{
UNICODE_STRING AfdHelper;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoSb;
NTSTATUS Status;
FILE_COMPLETION_INFORMATION CompletionInfo;
OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleFlags;
/* First, make sure we're not already intialized */
if (SockAsyncHelperAfdHandle) {
return TRUE;
}
/* Set up Handle Name and Object */
RtlInitUnicodeString(&AfdHelper, L"\\Device\\Afd\\AsyncSelectHlp" );
InitializeObjectAttributes(&ObjectAttributes,
&AfdHelper,
OBJ_INHERIT | OBJ_CASE_INSENSITIVE,
NULL,
NULL);
/* Open the Handle to AFD */
Status = NtCreateFile(&SockAsyncHelperAfdHandle,
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
&ObjectAttributes,
&IoSb,
NULL,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN_IF,
0,
NULL,
0);
/*
* Now Set up the Completion Port Information
* This means that whenever a Poll is finished, the routine will be executed
*/
CompletionInfo.Port = SockAsyncCompletionPort;
CompletionInfo.Key = SockAsyncSelectCompletionRoutine;
Status = NtSetInformationFile(SockAsyncHelperAfdHandle,
&IoSb,
&CompletionInfo,
sizeof(CompletionInfo),
FileCompletionInformation);
/* Protect the Handle */
HandleFlags.ProtectFromClose = TRUE;
HandleFlags.Inherit = FALSE;
Status = NtSetInformationObject(SockAsyncCompletionPort,
ObjectHandleInformation,
&HandleFlags,
sizeof(HandleFlags));
/* Set this variable to true so that Send/Recv/Accept will know wether to renable disabled events */
SockAsyncSelectCalled = TRUE;
return TRUE;
}
VOID SockAsyncSelectCompletionRoutine(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
{
PASYNC_DATA AsyncData = Context;
PSOCKET_INFORMATION Socket;
ULONG x;
/* Get the Socket */
Socket = AsyncData->ParentSocket;
/* Check if the Sequence Number Changed behind our back */
if (AsyncData->SequenceNumber != Socket->SharedData.SequenceNumber ){
return;
}
/* Check we were manually called b/c of a failure */
if (!NT_SUCCESS(IoStatusBlock->Status)) {
/* FIXME: Perform Upcall */
return;
}
for (x = 1; x; x<<=1) {
switch (AsyncData->AsyncSelectInfo.Handles[0].Events & x) {
case AFD_EVENT_RECEIVE:
if ((Socket->SharedData.AsyncEvents & FD_READ) && (!Socket->SharedData.AsyncDisabledEvents & FD_READ)) {
/* Make the Notifcation */
(Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd,
Socket->SharedData.wMsg,
Socket->Handle,
WSAMAKESELECTREPLY(FD_READ, 0));
/* Disable this event until the next read(); */
Socket->SharedData.AsyncDisabledEvents |= FD_READ;
}
case AFD_EVENT_OOB_RECEIVE:
if ((Socket->SharedData.AsyncEvents & FD_OOB) && (!Socket->SharedData.AsyncDisabledEvents & FD_OOB)) {
/* Make the Notifcation */
(Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd,
Socket->SharedData.wMsg,
Socket->Handle,
WSAMAKESELECTREPLY(FD_OOB, 0));
/* Disable this event until the next read(); */
Socket->SharedData.AsyncDisabledEvents |= FD_OOB;
}
case AFD_EVENT_SEND:
if ((Socket->SharedData.AsyncEvents & FD_WRITE) && (!Socket->SharedData.AsyncDisabledEvents & FD_WRITE)) {
/* Make the Notifcation */
(Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd,
Socket->SharedData.wMsg,
Socket->Handle,
WSAMAKESELECTREPLY(FD_WRITE, 0));
/* Disable this event until the next write(); */
Socket->SharedData.AsyncDisabledEvents |= FD_WRITE;
}
case AFD_EVENT_ACCEPT:
if ((Socket->SharedData.AsyncEvents & FD_ACCEPT) && (!Socket->SharedData.AsyncDisabledEvents & FD_ACCEPT)) {
/* Make the Notifcation */
(Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd,
Socket->SharedData.wMsg,
Socket->Handle,
WSAMAKESELECTREPLY(FD_ACCEPT, 0));
/* Disable this event until the next accept(); */
Socket->SharedData.AsyncDisabledEvents |= FD_ACCEPT;
}
case AFD_EVENT_DISCONNECT:
case AFD_EVENT_ABORT:
case AFD_EVENT_CLOSE:
if ((Socket->SharedData.AsyncEvents & FD_CLOSE) && (!Socket->SharedData.AsyncDisabledEvents & FD_CLOSE)) {
/* Make the Notifcation */
(Upcalls.lpWPUPostMessage)(Socket->SharedData.hWnd,
Socket->SharedData.wMsg,
Socket->Handle,
WSAMAKESELECTREPLY(FD_CLOSE, 0));
/* Disable this event forever; */
Socket->SharedData.AsyncDisabledEvents |= FD_CLOSE;
}
/* FIXME: Support QOS */
}
}
/* Check if there are any events left for us to check */
if ((Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents)) == 0 ) {
return;
}
/* Keep Polling */
SockProcessAsyncSelect(Socket, AsyncData);
return;
}
VOID SockProcessAsyncSelect(PSOCKET_INFORMATION Socket, PASYNC_DATA AsyncData)
{
ULONG lNetworkEvents;
NTSTATUS Status;
/* Set up the Async Data Event Info */
AsyncData->AsyncSelectInfo.Timeout.HighPart = 0x7FFFFFFF;
AsyncData->AsyncSelectInfo.Timeout.LowPart = 0xFFFFFFFF;
AsyncData->AsyncSelectInfo.HandleCount = 1;
AsyncData->AsyncSelectInfo.Exclusive = TRUE;
AsyncData->AsyncSelectInfo.Handles[0].Handle = Socket->Handle;
AsyncData->AsyncSelectInfo.Handles[0].Events = 0;
/* Remove unwanted events */
lNetworkEvents = Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents);
/* Set Events to wait for */
if (lNetworkEvents & FD_READ) {
AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_RECEIVE;
}
if (lNetworkEvents & FD_WRITE) {
AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_SEND;
}
if (lNetworkEvents & FD_OOB) {
AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_OOB_RECEIVE;
}
if (lNetworkEvents & FD_ACCEPT) {
AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_ACCEPT;
}
if (lNetworkEvents & FD_CONNECT) {
AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_CONNECT | AFD_EVENT_CONNECT_FAIL;
}
if (lNetworkEvents & FD_CLOSE) {
AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT;
}
if (lNetworkEvents & FD_QOS) {
AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_QOS;
}
if (lNetworkEvents & FD_GROUP_QOS) {
AsyncData->AsyncSelectInfo.Handles[0].Events |= AFD_EVENT_GROUP_QOS;
}
/* Send IOCTL */
Status = NtDeviceIoControlFile (SockAsyncHelperAfdHandle,
NULL,
NULL,
AsyncData,
&AsyncData->IoStatusBlock,
IOCTL_AFD_SELECT,
&AsyncData->AsyncSelectInfo,
sizeof(AsyncData->AsyncSelectInfo),
&AsyncData->AsyncSelectInfo,
sizeof(AsyncData->AsyncSelectInfo));
/* I/O Manager Won't call the completion routine, let's do it manually */
if (NT_SUCCESS(Status)) {
return;
} else {
AsyncData->IoStatusBlock.Status = Status;
SockAsyncSelectCompletionRoutine(AsyncData, &AsyncData->IoStatusBlock);
}
}
VOID SockProcessQueuedAsyncSelect(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
{
PASYNC_DATA AsyncData = Context;
PSOCKET_INFORMATION Socket;
/* Get the Socket */
Socket = AsyncData->ParentSocket;
/* If someone closed it, stop the function */
if (Socket->SharedData.State != SocketClosed) {
/* Check if the Sequence Number changed by now, in which case quit */
if (AsyncData->SequenceNumber == Socket->SharedData.SequenceNumber) {
/* Do the actuall select, if needed */
if ((Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents))) {
SockProcessAsyncSelect(Socket, AsyncData);
}
}
}
/* Free the Context */
HeapFree(GetProcessHeap(), 0, AsyncData);
return;
}
BOOL
STDCALL
DllMain(HANDLE hInstDll,

View file

@ -42,7 +42,10 @@ WSPEventSelect(
/* Deactivate Async Select if there is one */
if (Socket->EventObject) {
//SockAsyncSelect(Socket, NULL, 0, 0);
Socket->SharedData.hWnd = NULL;
Socket->SharedData.wMsg = 0;
Socket->SharedData.AsyncEvents = 0;
Socket->SharedData.SequenceNumber++; // This will kill Async Select after the next completion
}
/* Set Structure Info */

View file

@ -15,15 +15,65 @@
INT
WSPAPI
WSPAsyncSelect(
IN SOCKET s,
IN SOCKET Handle,
IN HWND hWnd,
IN UINT wMsg,
IN LONG lEvent,
OUT LPINT lpErrno)
{
UNIMPLEMENTED
PSOCKET_INFORMATION Socket = NULL;
PASYNC_DATA AsyncData;
NTSTATUS Status;
ULONG BlockMode;
return 0;
/* Get the Socket Structure associated to this Socket */
Socket = GetSocketStructure(Handle);
/* Allocate the Async Data Structure to pass on to the Thread later */
HeapAlloc(GetProcessHeap(), 0, sizeof(*AsyncData));
/* Change the Socket to Non Blocking */
BlockMode = 1;
SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &BlockMode, NULL);
Socket->SharedData.NonBlocking = TRUE;
/* Deactive WSPEventSelect */
if (Socket->SharedData.AsyncEvents) {
WSPEventSelect(Handle, NULL, 0, NULL);
}
/* Create the Asynch Thread if Needed */
SockCreateOrReferenceAsyncThread();
/* Open a Handle to AFD's Async Helper */
SockGetAsyncSelectHelperAfdHandle();
/* Store Socket Data */
Socket->SharedData.hWnd = hWnd;
Socket->SharedData.wMsg = wMsg;
Socket->SharedData.AsyncEvents = lEvent;
Socket->SharedData.AsyncDisabledEvents = 0;
Socket->SharedData.SequenceNumber++;
/* Return if there are no more Events */
if ((Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents)) == 0) {
HeapFree(GetProcessHeap(), 0, AsyncData);
return 0;
}
/* Set up the Async Data */
AsyncData->ParentSocket = Socket;
AsyncData->SequenceNumber = Socket->SharedData.SequenceNumber;
/* Begin Async Select by using I/O Completion */
Status = NtSetIoCompletion(SockAsyncCompletionPort,
(PVOID)&SockProcessQueuedAsyncSelect,
AsyncData,
0,
0);
/* Return */
return 0;
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: io.h,v 1.49 2004/11/19 21:31:02 navaraf Exp $
/* $Id: io.h,v 1.50 2004/11/25 22:18:16 ion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -43,8 +43,8 @@
typedef struct _IO_COMPLETION_PACKET{
ULONG Key;
ULONG Overlapped;
PVOID Key;
PVOID Context;
IO_STATUS_BLOCK IoStatus;
LIST_ENTRY ListEntry;
} IO_COMPLETION_PACKET, *PIO_COMPLETION_PACKET;

View file

@ -271,8 +271,8 @@ NTSTATUS
STDCALL
NtRemoveIoCompletion(
IN HANDLE IoCompletionHandle,
OUT PULONG CompletionKey,
OUT PULONG CompletionValue,
OUT PVOID *CompletionKey,
OUT PVOID *CompletionContext,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER Timeout OPTIONAL
)
@ -302,7 +302,7 @@ NtRemoveIoCompletion(
Packet = CONTAINING_RECORD(ListEntry, IO_COMPLETION_PACKET, ListEntry);
if (CompletionKey) *CompletionKey = Packet->Key;
if (CompletionValue) *CompletionValue = Packet->Overlapped;
if (CompletionContext) *CompletionContext = Packet->Context;
if (IoStatusBlock) *IoStatusBlock = Packet->IoStatus;
ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside, Packet);
@ -330,8 +330,8 @@ NTSTATUS
STDCALL
NtSetIoCompletion(
IN HANDLE IoCompletionPortHandle,
IN ULONG CompletionKey,
IN ULONG CompletionValue,
IN PVOID CompletionKey,
IN PVOID CompletionContext,
IN NTSTATUS CompletionStatus,
IN ULONG CompletionInformation
)
@ -352,7 +352,7 @@ NtSetIoCompletion(
Packet = ExAllocateFromNPagedLookasideList(&IoCompletionPacketLookaside);
Packet->Key = CompletionKey;
Packet->Overlapped = CompletionValue;
Packet->Context = CompletionContext;
Packet->IoStatus.Status = CompletionStatus;
Packet->IoStatus.Information = CompletionInformation;

View file

@ -86,7 +86,7 @@
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
#include <internal/ps.h>
/************************************************************************/
/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/

View file

@ -873,7 +873,7 @@ typedef struct _FILE_BOTH_DIR_INFORMATION {
typedef struct _FILE_COMPLETION_INFORMATION {
HANDLE Port;
ULONG Key;
PVOID Key;
} FILE_COMPLETION_INFORMATION, *PFILE_COMPLETION_INFORMATION;
typedef struct _FILE_COMPRESSION_INFORMATION {