13 modified files
reactos/include/afd
diff -u -r1.11 -r1.12
--- shared.h 21 Nov 2004 20:54:51 -0000 1.11
+++ shared.h 25 Nov 2004 22:18:13 -0000 1.12
@@ -52,10 +52,10 @@
} 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 {
reactos/include/ddk
diff -u -r1.69 -r1.70
--- iotypes.h 6 Nov 2004 04:12:59 -0000 1.69
+++ iotypes.h 25 Nov 2004 22:18:15 -0000 1.70
@@ -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 _IO_COMPLETION_CONTEXT
{
PVOID Port;
- ULONG Key;
+ PVOID Key;
} IO_COMPLETION_CONTEXT, *PIO_COMPLETION_CONTEXT;
#define FO_FILE_OPEN 0x00000001
reactos/include/ntos
diff -u -r1.35 -r1.36
--- zw.h 12 Nov 2004 12:06:17 -0000 1.35
+++ zw.h 25 Nov 2004 22:18:15 -0000 1.36
@@ -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 @@
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 @@
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 @@
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 @@
STDCALL
ZwSetIoCompletion(
IN HANDLE IoCompletionPortHandle,
- IN ULONG CompletionKey,
- IN ULONG CompletionValue,
+ IN PVOID CompletionKey,
+ IN PVOID CompletionContext,
IN NTSTATUS CompletionStatus,
IN ULONG CompletionInformation
);
reactos/include/ntos
diff -u -r1.46 -r1.47
--- zwtypes.h 21 Nov 2004 06:51:17 -0000 1.46
+++ zwtypes.h 25 Nov 2004 22:18:16 -0000 1.47
@@ -971,7 +971,7 @@
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 {
reactos/lib/kernel32/file
diff -u -r1.15 -r1.16
--- iocompl.c 30 Oct 2004 22:18:17 -0000 1.15
+++ iocompl.c 25 Nov 2004 22:18:16 -0000 1.16
@@ -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 @@
CreateIoCompletionPort(
HANDLE FileHandle,
HANDLE ExistingCompletionPort,
- DWORD CompletionKey,
+ ULONG_PTR CompletionKey,
DWORD NumberOfConcurrentThreads
)
{
@@ -62,7 +62,7 @@
{
#ifdef __USE_W32API
CompletionInformation.Port = CompletionPort;
- CompletionInformation.Key = CompletionKey;
+ CompletionInformation.Key = (PVOID)CompletionKey;
#else
CompletionInformation.IoCompletionHandle = CompletionPort;
CompletionInformation.CompletionKey = CompletionKey;
@@ -98,7 +98,7 @@
GetQueuedCompletionStatus(
HANDLE CompletionHandle,
LPDWORD lpNumberOfBytesTransferred,
- LPDWORD lpCompletionKey,
+ PULONG_PTR lpCompletionKey,
LPOVERLAPPED *lpOverlapped,
DWORD dwMilliseconds
)
@@ -127,8 +127,8 @@
}
errCode = NtRemoveIoCompletion(CompletionHandle,
- lpCompletionKey,
- lpNumberOfBytesTransferred,
+ (PVOID*)lpCompletionKey,
+ (PVOID*)lpNumberOfBytesTransferred,
&IoStatus,
&Interval);
@@ -166,10 +166,10 @@
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) )
{
reactos/lib/msafd/include
diff -u -r1.9 -r1.10
--- msafd.h 15 Nov 2004 18:24:56 -0000 1.9
+++ msafd.h 25 Nov 2004 22:18:16 -0000 1.10
@@ -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 @@
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 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 */
reactos/lib/msafd/misc
diff -u -r1.19 -r1.20
--- dllmain.c 17 Nov 2004 05:17:22 -0000 1.19
+++ dllmain.c 25 Nov 2004 22:18:16 -0000 1.20
@@ -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 @@
/* 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 @@
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,
reactos/lib/msafd/misc
diff -u -r1.3 -r1.4
--- event.c 26 Sep 2004 07:55:32 -0000 1.3
+++ event.c 25 Nov 2004 22:18:16 -0000 1.4
@@ -42,7 +42,10 @@
/* 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 */
reactos/lib/msafd/misc
diff -u -r1.11 -r1.12
--- sndrcv.c 15 Nov 2004 18:24:56 -0000 1.11
+++ sndrcv.c 25 Nov 2004 22:18:16 -0000 1.12
@@ -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;
}
reactos/ntoskrnl/include/internal
diff -u -r1.49 -r1.50
--- io.h 19 Nov 2004 21:31:02 -0000 1.49
+++ io.h 25 Nov 2004 22:18:16 -0000 1.50
@@ -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;
reactos/ntoskrnl/io
diff -u -r1.15 -r1.16
--- iocomp.c 21 Aug 2004 20:51:26 -0000 1.15
+++ iocomp.c 25 Nov 2004 22:18:16 -0000 1.16
@@ -271,8 +271,8 @@
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 @@
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 @@
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 @@
Packet = ExAllocateFromNPagedLookasideList(&IoCompletionPacketLookaside);
Packet->Key = CompletionKey;
- Packet->Overlapped = CompletionValue;
+ Packet->Context = CompletionContext;
Packet->IoStatus.Status = CompletionStatus;
Packet->IoStatus.Information = CompletionInformation;
reactos/ntoskrnl/kd
diff -u -r1.26 -r1.27
--- gdbstub.c 14 Nov 2004 16:00:02 -0000 1.26
+++ gdbstub.c 25 Nov 2004 22:18:17 -0000 1.27
@@ -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*/
reactos/w32api/include/ddk
diff -u -r1.7 -r1.8
--- ntifs.h 24 Oct 2004 15:26:14 -0000 1.7
+++ ntifs.h 25 Nov 2004 22:18:17 -0000 1.8
@@ -873,7 +873,7 @@
typedef struct _FILE_COMPLETION_INFORMATION {
HANDLE Port;
- ULONG Key;
+ PVOID Key;
} FILE_COMPLETION_INFORMATION, *PFILE_COMPLETION_INFORMATION;
typedef struct _FILE_COMPRESSION_INFORMATION {
CVSspam 0.2.8