Commit in reactos on MAIN
lib/ws2_32/makefile+1-21.17 -> 1.18
lib/ws2_32/misc/dllmain.c+42-101.17 -> 1.18
               /stubs.c-171.13 -> 1.14
lib/msafd/misc/dllmain.c+128-991.18 -> 1.19
drivers/net/afd/afd/lock.c+35-11.6 -> 1.7
                   /main.c+4-11.11 -> 1.12
                   /read.c+5-51.10 -> 1.11
                   /select.c+118-1311.5 -> 1.6
drivers/net/afd/include/afd.h+3-11.23 -> 1.24
drivers/net/tcpip/tcpip/fileobjs.c-11.22 -> 1.23
                       /main.c+1-11.41 -> 1.42
+337-269
11 modified files
tcpip: fix for udp socket close.
ws2_32: unstub WSAFDIsSet, small amount of work on select
msafd: select fixes
afd: major select overhaul
- 1 exit point for poll objects from the deviceext
- make sure to cancel the timer
- UpdatePollWithFCB now runs at DISPATCH_LEVEL in every case
- Added handle locks so we can signal and check handles properly

reactos/lib/ws2_32
makefile 1.17 -> 1.18
diff -u -r1.17 -r1.18
--- makefile	23 Oct 2004 21:05:11 -0000	1.17
+++ makefile	17 Nov 2004 05:17:21 -0000	1.18
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.17 2004/10/23 21:05:11 chorns Exp $
+# $Id: makefile,v 1.18 2004/11/17 05:17:21 arty Exp $
 
 PATH_TO_TOP = ../..
 
@@ -19,7 +19,6 @@
  -fno-builtin \
  -DUNICODE \
  -DLE \
- -DDBG \
  -D__USE_W32API
 
 # require os code to explicitly request A/W version of structs/functions

reactos/lib/ws2_32/misc
dllmain.c 1.17 -> 1.18
diff -u -r1.17 -r1.18
--- dllmain.c	23 Sep 2004 08:16:16 -0000	1.17
+++ dllmain.c	17 Nov 2004 05:17:22 -0000	1.18
@@ -7,6 +7,7 @@
  * REVISIONS:
  *   CSH 01/09-2000 Created
  */
+#include <roscfg.h>
 #include <w32api.h>
 #include <ws2_32.h>
 #include <catalog.h>
@@ -18,6 +19,7 @@
 /* See debug.h for debug/trace constants */
 DWORD DebugTraceLevel = MIN_TRACE;
 //DWORD DebugTraceLevel = MAX_TRACE;
+//DWORD DebugTraceLevel = DEBUG_ULTRA;
 
 #endif /* DBG */
 
@@ -339,6 +341,7 @@
 
   if (!WSAINITIALIZED) {
     WSASetLastError(WSANOTINITIALISED);
+    WS_DbgPrint(MID_TRACE,("Not initialized\n"));
     return SOCKET_ERROR;
   }
 
@@ -348,33 +351,48 @@
   if ((readfds != NULL) && (readfds->fd_count > 0)) {
     if (!ReferenceProviderByHandle((HANDLE)readfds->fd_array[0], &Provider)) {
       WSASetLastError(WSAENOTSOCK);
+      WS_DbgPrint(MID_TRACE,("No provider (read)\n"));
       return SOCKET_ERROR;
     }
   } else if ((writefds != NULL) && (writefds->fd_count > 0)) {
     if (!ReferenceProviderByHandle((HANDLE)writefds->fd_array[0], &Provider)) {
       WSASetLastError(WSAENOTSOCK);
+      WS_DbgPrint(MID_TRACE,("No provider (write)\n"));
       return SOCKET_ERROR;
     }
   } else if ((exceptfds != NULL) && (exceptfds->fd_count > 0)) {
     if (!ReferenceProviderByHandle((HANDLE)exceptfds->fd_array[0], &Provider)) {
       WSASetLastError(WSAENOTSOCK);
+      WS_DbgPrint(MID_TRACE,("No provider (err)\n"));
       return SOCKET_ERROR;
     }
+#if 0 /* XXX empty select is not an error */
   } else {
     WSASetLastError(WSAEINVAL);
     return SOCKET_ERROR;
+#endif
   }
 
-  Count = Provider->ProcTable.lpWSPSelect(
-    nfds, readfds, writefds, exceptfds, (LPTIMEVAL)timeout, &Errno);
-
-  WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
-
-  DereferenceProviderByPointer(Provider);
-
-  if (Errno != NO_ERROR) {
-    WSASetLastError(Errno);
-    return SOCKET_ERROR;
+  if( !Provider ) {
+      if( timeout ) {
+	  WS_DbgPrint(MID_TRACE,("Select: used as timer\n"));
+	  Sleep( timeout->tv_sec * 1000 + (timeout->tv_usec / 1000) );
+      }
+      return 0;
+  } else {
+      WS_DbgPrint(MID_TRACE,("Calling WSPSelect\n"));
+      Count = Provider->ProcTable.lpWSPSelect(
+	  nfds, readfds, writefds, exceptfds, (LPTIMEVAL)timeout, &Errno);
+      
+      WS_DbgPrint(MAX_TRACE, ("[%x] Select: Count %d Errno %x\n", 
+			      Provider, Count, Errno));
+      
+      DereferenceProviderByPointer(Provider);
+      
+      if (Errno != NO_ERROR) {
+	  WSASetLastError(Errno);
+	  return SOCKET_ERROR;
+      }
   }
 
   return Count;
@@ -630,6 +648,20 @@
   return Status;
 }
 
+/*
+ * @implemented
+ */
+INT
+EXPORT
+__WSAFDIsSet(SOCKET s, LPFD_SET set)
+{
+    int i;
+
+    for( i = 0; i < set->fd_count; i++ )
+	if( set->fd_array[i] == s ) return TRUE;
+
+    return FALSE;
+}
 
 BOOL
 STDCALL

reactos/lib/ws2_32/misc
stubs.c 1.13 -> 1.14
diff -u -r1.13 -r1.14
--- stubs.c	3 Jul 2004 17:40:24 -0000	1.13
+++ stubs.c	17 Nov 2004 05:17:22 -0000	1.14
@@ -636,23 +636,6 @@
     return 0;
 }
 
-/*
- * @unimplemented
- */
-INT
-#if 0
-PASCAL FAR
-#else
-EXPORT
-#endif
-__WSAFDIsSet(SOCKET s, LPFD_SET set)
-{
-    UNIMPLEMENTED
-
-    return 0;
-}
-
-
 /* WinSock Service Provider support functions */
 
 /*

reactos/lib/msafd/misc
dllmain.c 1.18 -> 1.19
diff -u -r1.18 -r1.19
--- dllmain.c	15 Nov 2004 18:24:56 -0000	1.18
+++ dllmain.c	17 Nov 2004 05:17:22 -0000	1.19
@@ -413,113 +413,142 @@
 	struct timeval *timeout, 
 	LPINT lpErrno)
 {
-	IO_STATUS_BLOCK			IOSB;
-	PAFD_POLL_INFO			PollInfo;
-	NTSTATUS				Status;
-	ULONG					HandleCount;
-	ULONG					PollBufferSize;
-	LARGE_INTEGER			uSec;
-	PVOID					PollBuffer;
-	ULONG					i, j = 0;
-	HANDLE                                  SockEvent;
-
-	Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
-				NULL, 1, FALSE );
-
-	if( !NT_SUCCESS(Status) ) return -1;
+    IO_STATUS_BLOCK			IOSB;
+    PAFD_POLL_INFO			PollInfo;
+    NTSTATUS				Status;
+    ULONG				HandleCount, OutCount = 0;
+    ULONG				PollBufferSize;
+    LARGE_INTEGER			uSec;
+    PVOID				PollBuffer;
+    ULONG				i, j = 0, x;
+    HANDLE                              SockEvent;
+    
+    Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
+			    NULL, 1, FALSE );
+    
+    if( !NT_SUCCESS(Status) ) return -1;
+    
+    /* Find out how many sockets we have, and how large the buffer needs 
+     * to be */
+    
+    HandleCount = 
+	( readfds ? readfds->fd_count : 0 ) + 
+	( writefds ? writefds->fd_count : 0 ) + 
+	( exceptfds ? exceptfds->fd_count : 0 );
+    PollBufferSize = sizeof(*PollInfo) + 
+	(HandleCount * sizeof(AFD_HANDLE));
+    
+    /* Allocate */
+    PollBuffer = HeapAlloc(GlobalHeap, 0, PollBufferSize);
+    PollInfo = (PAFD_POLL_INFO)PollBuffer;
+    
+    RtlZeroMemory( PollInfo, PollBufferSize );
 
-	/* Find out how many sockets we have, and how large the buffer needs to be */
-	HandleCount = ( readfds ? readfds->fd_count : 0 ) + 
-					( writefds ? writefds->fd_count : 0 ) + 
-					( exceptfds ? exceptfds->fd_count : 0 );
-	PollBufferSize = sizeof(*PollInfo) + (HandleCount * sizeof(AFD_HANDLE));
-
-	/* Allocate */
-	PollBuffer = HeapAlloc(GlobalHeap, 0, PollBufferSize);
-	PollInfo = (PAFD_POLL_INFO)PollBuffer;
-
-	/* Convert Timeout to NT Format */
-	if (timeout == NULL) {
-		PollInfo->Timeout.u.LowPart = -1;
-		PollInfo->Timeout.u.HighPart = 0x7FFFFFFF;
-	} else {
-		PollInfo->Timeout = RtlEnlargedIntegerMultiply(timeout->tv_sec, -10000000);
-		uSec = RtlEnlargedIntegerMultiply(timeout->tv_usec, -10);
-		PollInfo->Timeout.QuadPart += uSec.QuadPart;
+    /* Convert Timeout to NT Format */
+    if (timeout == NULL) {
+	PollInfo->Timeout.u.LowPart = -1;
+	PollInfo->Timeout.u.HighPart = 0x7FFFFFFF;
+    } else {
+	PollInfo->Timeout = RtlEnlargedIntegerMultiply
+	    ((timeout->tv_sec * 1000) + timeout->tv_usec, -10000);
+	PollInfo->Timeout.QuadPart += uSec.QuadPart;
+    }
+    
+    /* Number of handles for AFD to Check */
+    PollInfo->HandleCount = HandleCount;
+    PollInfo->InternalUse = 0;
+    
+    if (readfds != NULL) {
+	for (i = 0; i < readfds->fd_count; i++, j++) {
+	    PollInfo->Handles[j].Handle = readfds->fd_array[i];
+	    PollInfo->Handles[j].Events = AFD_EVENT_RECEIVE | AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT;
+	} 
+    }
+    if (writefds != NULL) {
+	for (i = 0; i < writefds->fd_count; i++, j++) {
+	    PollInfo->Handles[j].Handle = writefds->fd_array[i];
+	    PollInfo->Handles[j].Events |= AFD_EVENT_SEND;
 	}
 	
-	/* Number of handles for AFD to Check */
-	PollInfo->HandleCount = HandleCount;
-	PollInfo->Unknown = 0;
-
-	if (readfds != NULL) {
-		for (i = 0; i < readfds->fd_count; i++, j++) {
-			PollInfo->Handles[j].Handle = readfds->fd_array[i];
-			PollInfo->Handles[j].Events = AFD_EVENT_RECEIVE | AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT;
-		} 
-	} else if (writefds != NULL) {
-		for (i = 0; i < writefds->fd_count; i++, j++) {
-			PollInfo->Handles[j].Handle = writefds->fd_array[i];
-			PollInfo->Handles[j].Events = AFD_EVENT_SEND;
-		}
-
-	} else if (exceptfds != NULL) {
-		for (i = 0; i < exceptfds->fd_count; i++, j++) {
-			PollInfo->Handles[j].Handle = exceptfds->fd_array[i];
-			PollInfo->Handles[j].Events = AFD_EVENT_OOB_RECEIVE | AFD_EVENT_CONNECT_FAIL;
-		}
-	}
-
-	/* Send IOCTL */
-	Status = NtDeviceIoControlFile( (HANDLE)Sockets[0]->Handle,
-					SockEvent,
-					NULL,
-					NULL,
-					&IOSB,
-					IOCTL_AFD_SELECT,
-					PollInfo,
-					PollBufferSize,
-					PollInfo,
-					PollBufferSize);
-
-	/* Wait for Completition */
-	if (Status == STATUS_PENDING) {
-		WaitForSingleObject(SockEvent, 0);
+    }
+    if (exceptfds != NULL) {
+	for (i = 0; i < exceptfds->fd_count; i++, j++) {
+	    PollInfo->Handles[j].Handle = exceptfds->fd_array[i];
+	    PollInfo->Handles[j].Events |= 
+		AFD_EVENT_OOB_RECEIVE | AFD_EVENT_CONNECT_FAIL;
 	}
+    }
+    
+    /* Send IOCTL */
+    Status = NtDeviceIoControlFile( (HANDLE)Sockets[0]->Handle,
+				    SockEvent,
+				    NULL,
+				    NULL,
+				    &IOSB,
+				    IOCTL_AFD_SELECT,
+				    PollInfo,
+				    PollBufferSize,
+				    PollInfo,
+				    PollBufferSize);
 
-	/* Clear the Structures */
-	readfds ? FD_ZERO(readfds) : 0;
-	writefds ? FD_ZERO(writefds) : 0;
-	exceptfds ? FD_ZERO(exceptfds) : 0;
-
-	/* Loop through return structure */
-	HandleCount = PollInfo->HandleCount;
-
-	/* Return in FDSET Format */
-	for (i = 0; i < HandleCount; i++) {
-		switch (PollInfo->Handles[i].Events) {
-
-			case AFD_EVENT_RECEIVE: 
-			case AFD_EVENT_DISCONNECT: 
-			case AFD_EVENT_ABORT: 
-			case AFD_EVENT_ACCEPT: 
-			case AFD_EVENT_CLOSE:
-				FD_SET(PollInfo->Handles[i].Handle, readfds);
-				break;
-
-			case AFD_EVENT_SEND: case AFD_EVENT_CONNECT:
-				FD_SET(PollInfo->Handles[i].Handle, writefds);
-				break;
-
-			case AFD_EVENT_OOB_RECEIVE: case AFD_EVENT_CONNECT_FAIL:
-				FD_SET(PollInfo->Handles[i].Handle, exceptfds);
-				break;
-		}
+    AFD_DbgPrint(MID_TRACE,("DeviceIoControlFile => %x\n", Status));
+    
+    /* Wait for Completition */
+    if (Status == STATUS_PENDING) {
+	WaitForSingleObject(SockEvent, 0);
+    }
+    
+    /* Clear the Structures */
+    if( readfds ) FD_ZERO(readfds);
+    if( writefds ) FD_ZERO(writefds);
+    if( exceptfds ) FD_ZERO(exceptfds);
+    
+    /* Loop through return structure */
+    HandleCount = PollInfo->HandleCount;
+    
+    /* Return in FDSET Format */
+    for (i = 0; i < HandleCount; i++) {
+	for(x = 1; x; x<<=1) {
+	    switch (PollInfo->Handles[i].Events & x) {
+	    case AFD_EVENT_RECEIVE: 
+	    case AFD_EVENT_DISCONNECT: 
+	    case AFD_EVENT_ABORT: 
+	    case AFD_EVENT_ACCEPT: 
+	    case AFD_EVENT_CLOSE:
+		AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n",
+					PollInfo->Handles[i].Events,
+					PollInfo->Handles[i].Handle));
+		OutCount++;
+		if( readfds ) FD_SET(PollInfo->Handles[i].Handle, readfds);
+	    case AFD_EVENT_SEND: case AFD_EVENT_CONNECT:
+		AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n",
+					PollInfo->Handles[i].Events,
+					PollInfo->Handles[i].Handle));
+		OutCount++;
+		if( writefds ) FD_SET(PollInfo->Handles[i].Handle, writefds);
+		break;
+		
+	    case AFD_EVENT_OOB_RECEIVE: case AFD_EVENT_CONNECT_FAIL:
+		AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n",
+					PollInfo->Handles[i].Events,
+					PollInfo->Handles[i].Handle));
+		OutCount++;
+		if( exceptfds ) FD_SET(PollInfo->Handles[i].Handle, exceptfds);
+		break;
+	    }
 	}
+    }
 
-	NtClose( SockEvent );
+    NtClose( SockEvent );
+    switch( IOSB.Status ) {
+    case STATUS_SUCCESS: 
+    case STATUS_TIMEOUT: *lpErrno = 0; break;
+    default: *lpErrno = WSAEINVAL;
+    }
 
-	return 0;
+    AFD_DbgPrint(MID_TRACE,("%d events\n", OutCount));
+    
+    return OutCount;
 }
 
 SOCKET

reactos/drivers/net/afd/afd
lock.c 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- lock.c	15 Nov 2004 18:24:57 -0000	1.6
+++ lock.c	17 Nov 2004 05:17:22 -0000	1.7
@@ -1,4 +1,4 @@
-/* $Id: lock.c,v 1.6 2004/11/15 18:24:57 arty Exp $
+/* $Id: lock.c,v 1.7 2004/11/17 05:17:22 arty Exp $
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/net/afd/afd/lock.c
@@ -114,6 +114,40 @@
     ExFreePool( Buf );
 }
 
+/* Produce a kernel-land handle array with handles replaced by object
+ * pointers.  This will allow the system to do proper alerting */
+PAFD_HANDLE LockHandles( PAFD_HANDLE HandleArray, UINT HandleCount ) {
+    UINT i;
+    NTSTATUS Status;
+
+    PAFD_HANDLE FileObjects = ExAllocatePool
+	( NonPagedPool, HandleCount * sizeof(AFD_HANDLE) );
+
+    for( i = 0; FileObjects && i < HandleCount; i++ ) {
+	HandleArray[i].Status = 0;
+	HandleArray[i].Events = HandleArray[i].Events;
+	Status = ObReferenceObjectByHandle
+	    ( (PVOID)HandleArray[i].Handle,
+	      FILE_ALL_ACCESS,
+	      NULL,
+	      KernelMode,
+	      (PVOID*)&FileObjects[i].Handle,
+	      NULL );
+    }
+
+    return FileObjects;
+}
+
+VOID UnlockHandles( PAFD_HANDLE HandleArray, UINT HandleCount ) {
+    UINT i;
+
+    for( i = 0; i < HandleCount; i++ ) {
+	ObDereferenceObject( (PVOID)HandleArray[i].Handle );
+    }
+
+    ExFreePool( HandleArray );
+}
+
 /* Returns transitioned state or SOCKET_STATE_INVALID_TRANSITION */
 UINT SocketAcquireStateLock( PAFD_FCB FCB ) {
     NTSTATUS Status = STATUS_SUCCESS;

reactos/drivers/net/afd/afd
main.c 1.11 -> 1.12
diff -u -r1.11 -r1.12
--- main.c	16 Nov 2004 18:07:57 -0000	1.11
+++ main.c	17 Nov 2004 05:17:22 -0000	1.12
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.11 2004/11/16 18:07:57 chorns Exp $
+/* $Id: main.c,v 1.12 2004/11/17 05:17:22 arty Exp $
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/net/afd/afd/main.c
@@ -212,6 +212,9 @@
     AFD_DbgPrint(MID_TRACE,("FCB %x\n", FCB));
 
     FileObject->FsContext = NULL;
+    FCB->PollState |= AFD_EVENT_CLOSE;
+    PollReeval( FCB->DeviceExt, FileObject );
+
     DestroySocket( FCB );
     
     Irp->IoStatus.Status = STATUS_SUCCESS;

reactos/drivers/net/afd/afd
read.c 1.10 -> 1.11
diff -u -r1.10 -r1.11
--- read.c	15 Nov 2004 18:24:57 -0000	1.10
+++ read.c	17 Nov 2004 05:17:22 -0000	1.11
@@ -1,4 +1,4 @@
-/* $Id: read.c,v 1.10 2004/11/15 18:24:57 arty Exp $
+/* $Id: read.c,v 1.11 2004/11/17 05:17:22 arty Exp $
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/net/afd/afd/read.c
@@ -416,7 +416,8 @@
 	AFD_DbgPrint(MID_TRACE,("Signalling\n"));
 	FCB->PollState |= AFD_EVENT_RECEIVE;
 	PollReeval( FCB->DeviceExt, FCB->FileObject );
-    }
+    } else 
+	FCB->PollState &= ~AFD_EVENT_RECEIVE;
 
     if( NT_SUCCESS(Irp->IoStatus.Status) ) {
 	/* Now relaunch the datagram request */
@@ -483,9 +484,6 @@
 	    return UnlockAndMaybeComplete
 		( FCB, Status, Irp, RecvReq->BufferArray[0].len, NULL, TRUE );
 	} else {
-	    if( IsListEmpty( &FCB->DatagramList ) ) 
-		FCB->PollState &= ~AFD_EVENT_RECEIVE;
-
 	    Status = SatisfyPacketRecvRequest
 		( FCB, Irp, DatagramRecv, 
 		  (PUINT)&Irp->IoStatus.Information );
@@ -493,10 +491,12 @@
 		( FCB, Status, Irp, Irp->IoStatus.Information, NULL, TRUE );
 	}
     } else if( RecvReq->AfdFlags & AFD_IMMEDIATE ) {
+	FCB->PollState &= ~AFD_EVENT_RECEIVE;
 	AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
 	Status = STATUS_CANT_WAIT;
 	return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, TRUE );
     } else {
+	FCB->PollState &= ~AFD_EVENT_RECEIVE;
 	return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV );
     }
 }

reactos/drivers/net/afd/afd
select.c 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- select.c	15 Nov 2004 18:24:57 -0000	1.5
+++ select.c	17 Nov 2004 05:17:22 -0000	1.6
@@ -1,4 +1,4 @@
-/* $Id: select.c,v 1.5 2004/11/15 18:24:57 arty Exp $
+/* $Id: select.c,v 1.6 2004/11/17 05:17:22 arty Exp $
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * FILE:             drivers/net/afd/afd/select.c
@@ -26,58 +26,36 @@
 		 UINT HandleCount ) {
     UINT i;
     
-    for( i = 0; i < HandleCount; i++ ) {
-	HandleArray[i].Events = 0;
+    for( i = 0; i < HandleCount; i++ )
 	HandleArray[i].Status = 0;
-    }
 }
 
-NTSTATUS STDCALL
-ScanForImmediateTrigger( PAFD_HANDLE HandleArray,
-			 UINT HandleCount,
-			 PUINT HandlesSet ) {
-    NTSTATUS Status = STATUS_SUCCESS;
-    PFILE_OBJECT FileObject;
-    PAFD_FCB FCB;
-    UINT i;
-    BOOLEAN ShouldReturnNow = FALSE;
+VOID RemoveSelect( PAFD_ACTIVE_POLL Poll ) {
+    AFD_DbgPrint(MID_TRACE,("Called\n"));
 
-    for( i = 0; i < HandleCount && NT_SUCCESS(Status); i++ ) {
-        HandleArray[i].Status = 0;
-	Status = 
-	    ObReferenceObjectByHandle
-	    ( (PVOID)HandleArray[i].Handle,
-	      FILE_ALL_ACCESS,
-	      NULL,
-	      KernelMode,
-	      (PVOID*)&FileObject,
-	      NULL );
+    RemoveEntryList( &Poll->ListEntry );
+    KeCancelTimer( &Poll->Timer );
 
-	if( NT_SUCCESS(Status) ) {
-	    FCB = FileObject->FsContext;
-	    /* Check select bits */
-	    
-	    AFD_DbgPrint(MID_TRACE,("Locking socket state\n"));
+    ExFreePool( Poll );
 
-	    if( !SocketAcquireStateLock( FCB ) ) {
-		AFD_DbgPrint(MID_TRACE,("Failed to get a socket state\n"));
-		Status = STATUS_UNSUCCESSFUL;
-	    } else {
-		AFD_DbgPrint(MID_TRACE,("Got a socket state\n"));
-		Status = STATUS_SUCCESS;
-		HandleArray[i].Status = 
-		    FCB->PollState & HandleArray[i].Events;
-		if( HandleArray[i].Status ) ShouldReturnNow = TRUE;
-		ObDereferenceObject( (PVOID)HandleArray[i].Handle );
-		AFD_DbgPrint(MID_TRACE,("Unlocking\n"));
-		SocketStateUnlock( FCB );
-		AFD_DbgPrint(MID_TRACE,("Unlocked\n"));
-	    }
-	}
-    }
+    AFD_DbgPrint(MID_TRACE,("Done\n"));
+}
 
-    if( !NT_SUCCESS(Status) || ShouldReturnNow ) return Status; 
-    else return STATUS_PENDING;
+VOID SignalSocket( PAFD_ACTIVE_POLL Poll, PAFD_POLL_INFO PollReq, 
+		   NTSTATUS Status, UINT Collected ) {
+    PIRP Irp = Poll->Irp;
+    AFD_DbgPrint(MID_TRACE,("Called (Status %x Events %d)\n", 
+			    Status, Collected));
+    Poll->Irp->IoStatus.Status = Status;
+    Poll->Irp->IoStatus.Information = Collected;
+    CopyBackStatus( PollReq->Handles,
+		    PollReq->HandleCount );
+    UnlockHandles( PollReq->InternalUse, PollReq->HandleCount );
+    AFD_DbgPrint(MID_TRACE,("Completing\n"));
+    IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
+    RemoveEntryList( &Poll->ListEntry );
+    RemoveSelect( Poll );
+    AFD_DbgPrint(MID_TRACE,("Done\n"));
 }
 
 VOID SelectTimeout( PKDPC Dpc,
@@ -86,33 +64,31 @@
 		    PVOID SystemArgument2 ) {
     PAFD_ACTIVE_POLL Poll = DeferredContext;
     PAFD_POLL_INFO PollReq;
-    PAFD_DEVICE_EXTENSION DeviceExt;
     PIRP Irp;
     KIRQL OldIrql;
+    PAFD_DEVICE_EXTENSION DeviceExt;
+
+    AFD_DbgPrint(MID_TRACE,("Called\n"));
 
     Irp = Poll->Irp;
     DeviceExt = Poll->DeviceExt;
-
     PollReq = Irp->AssociatedIrp.SystemBuffer;
 
-    KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
-    RemoveEntryList( &Poll->ListEntry );
-    KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
-
-    ExFreePool( Poll );
-
     ZeroEvents( PollReq->Handles, PollReq->HandleCount );
 
-    Irp->IoStatus.Status = STATUS_TIMEOUT;
-    Irp->IoStatus.Information = -1;
+    KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
+    SignalSocket( Poll, PollReq, STATUS_TIMEOUT, 0 );
+    KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
 
-    IoCompleteRequest( Irp, IO_NO_INCREMENT );
+    AFD_DbgPrint(MID_TRACE,("Timeout\n"));
 }
 
 NTSTATUS STDCALL
 AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, 
 	   PIO_STACK_LOCATION IrpSp ) {
     NTSTATUS Status = STATUS_NO_MEMORY;
+    PAFD_FCB FCB;
+    PFILE_OBJECT FileObject;
     PAFD_POLL_INFO PollReq = Irp->AssociatedIrp.SystemBuffer;
     PAFD_DEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
     PAFD_ACTIVE_POLL Poll = NULL;
@@ -120,115 +96,122 @@
     UINT AllocSize = 
 	CopySize + sizeof(AFD_ACTIVE_POLL) - sizeof(AFD_POLL_INFO);
     KIRQL OldIrql;
-    UINT HandlesSignalled; 
+    UINT i, Signalled = 0;
 
     AFD_DbgPrint(MID_TRACE,("Called (HandleCount %d Timeout %d)\n", 
 			    PollReq->HandleCount,
-			    (INT)(PollReq->Timeout.QuadPart * -1)));
+			    (INT)(PollReq->Timeout.QuadPart)));
 
-    Status = ScanForImmediateTrigger( PollReq->Handles,
-				      PollReq->HandleCount,
-				      &HandlesSignalled );
+    PollReq->InternalUse = 
+	LockHandles( PollReq->Handles, PollReq->HandleCount );
+
+    if( !PollReq->InternalUse ) {
+	Irp->IoStatus.Status = STATUS_NO_MEMORY;
+	Irp->IoStatus.Information = -1;
+	IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
+	return Irp->IoStatus.Status;
+    }
+
+    ZeroEvents( PollReq->Handles,
+		PollReq->HandleCount );
+
+    Poll = ExAllocatePool( NonPagedPool, AllocSize );
     
-    if( Status == STATUS_PENDING ) {
-	Poll = ExAllocatePool( NonPagedPool, AllocSize );
+    if( Poll ) {
+	Poll->Irp = Irp;
+	Poll->DeviceExt = DeviceExt;
+
+	KeInitializeTimerEx( &Poll->Timer, NotificationTimer );
+	KeSetTimer( &Poll->Timer, PollReq->Timeout, &Poll->TimeoutDpc );
+
+	KeInitializeDpc( (PRKDPC)&Poll->TimeoutDpc, 
+			 (PKDEFERRED_ROUTINE)SelectTimeout,
+			 Poll );
 	
-	if( Poll ) {
-	    KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
+	KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
+	InsertTailList( &DeviceExt->Polls, &Poll->ListEntry );
+
+	for( i = 0; i < PollReq->HandleCount; i++ ) {
+	    if( !PollReq->InternalUse[i].Handle ) continue;
 	    
-	    KeInitializeDpc( (PRKDPC)&Poll->TimeoutDpc, 
-			     (PKDEFERRED_ROUTINE)SelectTimeout,
-			     Poll );
-	    PollReq->Timeout.QuadPart *= -1;
-	    /* Negative values are relative */
-	    KeInitializeTimerEx( &Poll->Timer, NotificationTimer );
-	    KeSetTimer( &Poll->Timer, PollReq->Timeout, &Poll->TimeoutDpc );
+	    FileObject = (PFILE_OBJECT)PollReq->InternalUse[i].Handle;
+	    FCB = FileObject->FsContext;
 	    
-	    Poll->Irp = Irp;
-	    Poll->DeviceExt = DeviceExt;
+	    if( (FCB->PollState & AFD_EVENT_CLOSE) ||
+		(PollReq->Handles[i].Status & AFD_EVENT_CLOSE) ) {
+		PollReq->InternalUse[i].Handle = 0;
+		PollReq->Handles[i].Events = 0;
+		PollReq->Handles[i].Status = AFD_EVENT_CLOSE;
+		Signalled++;
+	    } else {
+		PollReq->Handles[i].Status = 
+		    PollReq->Handles[i].Events & FCB->PollState;
+		if( PollReq->Handles[i].Status ) {
+		    AFD_DbgPrint(MID_TRACE,("Signalling %x with %x\n", 
+					    FCB, FCB->PollState));
+		    Signalled++;
+		}
+	    }
+	}
 
-	    InsertTailList( &DeviceExt->Polls, &Poll->ListEntry );
+	if( Signalled ) {
+	    Status = STATUS_SUCCESS;
+	    Irp->IoStatus.Status = Status;
+	    Irp->IoStatus.Information = Signalled;
+	    SignalSocket( Poll, PollReq, Status, Signalled );
+	} else {
 	    Status = STATUS_PENDING;
+	    IoMarkIrpPending( Irp );
+	}
 
-	    KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
-	} else Status = STATUS_NO_MEMORY;
-    } else if( Status == STATUS_SUCCESS ) {
-	CopyBackStatus( PollReq->Handles,
-			PollReq->HandleCount );
-    } else {
-	ZeroEvents( PollReq->Handles,
-		    PollReq->HandleCount );
-    }
+	KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
+    } else Status = STATUS_NO_MEMORY;
 
     AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
 
-    if( Status == STATUS_PENDING )
-	IoMarkIrpPending( Irp );
-    else {
-	Irp->IoStatus.Status = Status;
-	Irp->IoStatus.Information = HandlesSignalled;
-	IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
-    }
-
     return Status;
 }
 
-VOID SignalSocket( PAFD_ACTIVE_POLL Poll, PAFD_POLL_INFO PollReq, UINT i ) {
-    /* One of the files was destroyed.  We return now with error. */
-    Poll->Irp->IoStatus.Status = STATUS_SUCCESS; /* XXX REVISIT */
-    Poll->Irp->IoStatus.Information = 1;
-    CopyBackStatus( PollReq->Handles,
-		    PollReq->HandleCount );
-    IoCompleteRequest( Poll->Irp, IO_NETWORK_INCREMENT );
-}
-
+/* * * NOTE ALWAYS CALLED AT DISPATCH_LEVEL * * */
 BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject ) {
     UINT i;
-    NTSTATUS Status;
-    PFILE_OBJECT TargetFile;
     PAFD_FCB FCB;
+    UINT Signalled = 0;
     PAFD_POLL_INFO PollReq = Poll->Irp->AssociatedIrp.SystemBuffer;
 
+    ASSERT( KeGetCurrentIrql() == DISPATCH_LEVEL );
+
     for( i = 0; i < PollReq->HandleCount; i++ ) {
-	Status = 
-	    ObReferenceObjectByHandle
-	    ( (PVOID)PollReq->Handles[i].Handle,
-	      FILE_ALL_ACCESS,
-	      NULL,
-	      KernelMode,
-	      (PVOID*)&TargetFile,
-	      NULL );
+	if( !PollReq->InternalUse[i].Handle ) continue;
+
+	FileObject = (PFILE_OBJECT)PollReq->InternalUse[i].Handle;
+	FCB = FileObject->FsContext;
 	
-	if( !NT_SUCCESS(Status) ) { 
+	if( (FCB->PollState & AFD_EVENT_CLOSE) ||
+	    (PollReq->Handles[i].Status & AFD_EVENT_CLOSE) ) {
+	    PollReq->InternalUse[i].Handle = 0;
+	    PollReq->Handles[i].Events = 0;
 	    PollReq->Handles[i].Status = AFD_EVENT_CLOSE;
-	    SignalSocket( Poll, PollReq, i );
-	    return TRUE;
+	    Signalled++;
 	} else {
-	    FCB = FileObject->FsContext;
-
-	    AFD_DbgPrint(MID_TRACE,("Locking socket state\n"));
-
-	    if( !SocketAcquireStateLock( FCB ) ) {
-		PollReq->Handles[i].Status = AFD_EVENT_CLOSE;
-		SignalSocket( Poll, PollReq, i );
-	    } else {
-		PollReq->Handles[i].Status = 
-		    PollReq->Handles[i].Events & FCB->PollState;
-		if( PollReq->Handles[i].Status )
-		    SignalSocket( Poll, PollReq, i );
-		SocketStateUnlock( FCB );
+	    PollReq->Handles[i].Status = 
+		PollReq->Handles[i].Events & FCB->PollState;
+	    if( PollReq->Handles[i].Status ) {
+		AFD_DbgPrint(MID_TRACE,("Signalling %x with %x\n", 
+					FCB, FCB->PollState));
+		Signalled++;
 	    }
-	    return TRUE;
 	}
     }
 
-    return FALSE;
+    return Signalled ? 1 : 0;
 }
 
 VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) {
     PAFD_ACTIVE_POLL Poll = NULL;
     PLIST_ENTRY ThePollEnt = NULL;
     KIRQL OldIrql;
+    PAFD_POLL_INFO PollReq;
 
     AFD_DbgPrint(MID_TRACE,("Called: DeviceExt %x FileObject %x\n", 
 			    DeviceExt, FileObject));
@@ -239,9 +222,13 @@
 
     while( ThePollEnt != &DeviceExt->Polls ) {
 	Poll = CONTAINING_RECORD( ThePollEnt, AFD_ACTIVE_POLL, ListEntry );
+	PollReq = Poll->Irp->AssociatedIrp.SystemBuffer;
+	AFD_DbgPrint(MID_TRACE,("Checking poll %x\n", Poll));
+
 	if( UpdatePollWithFCB( Poll, FileObject ) ) {
 	    ThePollEnt = ThePollEnt->Flink;
-	    RemoveEntryList( &Poll->ListEntry );
+	    AFD_DbgPrint(MID_TRACE,("Signalling socket\n"));
+	    SignalSocket( Poll, PollReq, STATUS_SUCCESS, 1 );
 	} else 
 	    ThePollEnt = ThePollEnt->Flink;
     }

reactos/drivers/net/afd/include
afd.h 1.23 -> 1.24
diff -u -r1.23 -r1.24
--- afd.h	15 Nov 2004 18:24:57 -0000	1.23
+++ afd.h	17 Nov 2004 05:17:22 -0000	1.24
@@ -1,4 +1,4 @@
-/* $Id: afd.h,v 1.23 2004/11/15 18:24:57 arty Exp $
+/* $Id: afd.h,v 1.24 2004/11/17 05:17:22 arty Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -186,6 +186,8 @@
   BOOL ShouldUnlockIrp );
 VOID SocketStateUnlock( PAFD_FCB FCB );
 NTSTATUS LostSocket( PIRP Irp, BOOL ShouldUnlockIrp );
+PAFD_HANDLE LockHandles( PAFD_HANDLE HandleArray, UINT HandleCount );
+VOID UnlockHandles( PAFD_HANDLE HandleArray, UINT HandleCount );
 PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
 VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
 VOID SocketCalloutEnter( PAFD_FCB FCB );

reactos/drivers/net/tcpip/tcpip
fileobjs.c 1.22 -> 1.23
diff -u -r1.22 -r1.23
--- fileobjs.c	14 Nov 2004 19:45:16 -0000	1.22
+++ fileobjs.c	17 Nov 2004 05:17:22 -0000	1.23
@@ -160,7 +160,6 @@
     /* Abort the request and free its resources */
     TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
     (*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_ADDRESS_CLOSED, 0);
-    ExFreePool(ReceiveRequest);
     TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
     CurrentEntry = NextEntry;
   }

reactos/drivers/net/tcpip/tcpip
main.c 1.41 -> 1.42
diff -u -r1.41 -r1.42
--- main.c	15 Nov 2004 18:24:57 -0000	1.41
+++ main.c	17 Nov 2004 05:17:22 -0000	1.42
@@ -9,7 +9,7 @@
  */
 #include "precomp.h"
 
-//#define NDEBUG
+#define NDEBUG
 
 #ifndef NDEBUG
 DWORD DebugTraceLevel = 0x7fffffff;
CVSspam 0.2.8