Commit in reactos on MAIN
include/afd/shared.h+4-41.11 -> 1.12
include/ddk/iotypes.h+2-21.69 -> 1.70
include/ntos/zw.h+9-91.35 -> 1.36
            /zwtypes.h+1-11.46 -> 1.47
lib/kernel32/file/iocompl.c+10-101.15 -> 1.16
lib/msafd/include/msafd.h+71-251.9 -> 1.10
lib/msafd/misc/dllmain.c+347-71.19 -> 1.20
              /event.c+4-11.3 -> 1.4
              /sndrcv.c+53-31.11 -> 1.12
ntoskrnl/include/internal/io.h+3-31.49 -> 1.50
ntoskrnl/io/iocomp.c+6-61.15 -> 1.16
ntoskrnl/kd/gdbstub.c+1-11.26 -> 1.27
w32api/include/ddk/ntifs.h+1-11.7 -> 1.8
+512-73
13 modified files
Fix IO completion APIs/Structures.
Implement WSPASyncSelect and friends. Event re-enabling functionality missing and will be added tonight.

reactos/include/afd
shared.h 1.11 -> 1.12
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
iotypes.h 1.69 -> 1.70
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
zw.h 1.35 -> 1.36
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
zwtypes.h 1.46 -> 1.47
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
iocompl.c 1.15 -> 1.16
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
msafd.h 1.9 -> 1.10
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
dllmain.c 1.19 -> 1.20
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
event.c 1.3 -> 1.4
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
sndrcv.c 1.11 -> 1.12
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
io.h 1.49 -> 1.50
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
iocomp.c 1.15 -> 1.16
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
gdbstub.c 1.26 -> 1.27
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
ntifs.h 1.7 -> 1.8
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