diff --git a/reactos/drivers/lib/ip/transport/tcp/event.c b/reactos/drivers/lib/ip/transport/tcp/event.c index 160107ac798..c34af83b254 100644 --- a/reactos/drivers/lib/ip/transport/tcp/event.c +++ b/reactos/drivers/lib/ip/transport/tcp/event.c @@ -19,37 +19,47 @@ int TCPSocketState(void *ClientData, void *WhichSocket, void *WhichConnection, OSK_UINT NewState ) { + NTSTATUS Status = STATUS_SUCCESS; PCONNECTION_ENDPOINT Connection = WhichConnection; PTCP_COMPLETION_ROUTINE Complete; PTDI_BUCKET Bucket; PLIST_ENTRY Entry; - TI_DbgPrint(MID_TRACE,("Called: NewState %x (Conn %x)\n", - NewState, Connection)); - - if( !Connection ) { - TI_DbgPrint(MID_TRACE,("Socket closing.\n")); - return 0; - } + TI_DbgPrint(MID_TRACE,("Called: NewState %x (Conn %x) (Change %x)\n", + NewState, Connection, + Connection ? Connection->State ^ NewState : + NewState)); TcpipRecursiveMutexEnter( &TCPLock, TRUE ); - if( (NewState & SEL_CONNECT) && - !(Connection->State & SEL_CONNECT) ) { + if( !Connection ) { + TI_DbgPrint(MID_TRACE,("Socket closing.\n")); + Connection = FileFindConnectionByContext( WhichSocket ); + if( !Connection ) { + TcpipRecursiveMutexLeave( &TCPLock ); + return 0; + } else + TI_DbgPrint(MID_TRACE,("Found socket %x\n", Connection)); + } + + if( ((NewState & SEL_CONNECT) || (NewState & SEL_FIN)) && + !(Connection->State & (SEL_CONNECT | SEL_FIN)) ) { while( !IsListEmpty( &Connection->ConnectRequest ) ) { - Connection->State |= SEL_CONNECT; + Connection->State |= NewState & (SEL_CONNECT | SEL_FIN); Entry = RemoveHeadList( &Connection->ConnectRequest ); Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); Complete = Bucket->Request.RequestNotifyObject; TI_DbgPrint(MID_TRACE, ("Completing Connect Request %x\n", Bucket->Request)); + if( NewState & SEL_FIN ) Status = STATUS_CONNECTION_REFUSED; TcpipRecursiveMutexLeave( &TCPLock ); - Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 ); + Complete( Bucket->Request.RequestContext, Status, 0 ); TcpipRecursiveMutexEnter( &TCPLock, TRUE ); /* Frees the bucket allocated in TCPConnect */ PoolFreeBuffer( Bucket ); } - } else if( (NewState & SEL_READ) || (NewState & SEL_FIN) ) { + } + if( (NewState & SEL_READ) || (NewState & SEL_FIN) ) { TI_DbgPrint(MID_TRACE,("Readable (or closed): irp list %s\n", IsListEmpty(&Connection->ReceiveRequest) ? "empty" : "nonempty")); @@ -81,6 +91,7 @@ int TCPSocketState(void *ClientData, ("Reading %d bytes to %x\n", RecvLen, RecvBuffer)); if( (NewState & SEL_FIN) && !RecvLen ) { + TI_DbgPrint(MID_TRACE, ("EOF From socket\n")); Status = STATUS_END_OF_FILE; Received = 0; } else { diff --git a/reactos/drivers/lib/oskittcp/oskittcp/interface.c b/reactos/drivers/lib/oskittcp/oskittcp/interface.c index e8d074aa81b..73a5476d309 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/interface.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/interface.c @@ -155,9 +155,7 @@ int OskitTCPRecv( void *connection, &tcp_flags ); if( error == 0 ) { - OS_DbgPrint(OSK_MID_TRACE,("Successful read from TCP:\n")); *OutLen = Len - uio.uio_resid; - OskitDumpBuffer( Data, *OutLen ); } return error; @@ -203,8 +201,6 @@ int OskitTCPBind( void *socket, void *connection, addr.sa_family = addr.sa_len; addr.sa_len = sizeof(struct sockaddr); - OskitDumpBuffer( (OSK_PCHAR)&addr, sizeof(addr) ); - error = sobind(so, &sabuf); OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error)); @@ -274,7 +270,6 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len, int error = 0; if ( !m ) return ENOBUFS; - OskitDumpBuffer( Data, Len ); error = sosend( socket, NULL, NULL, m, NULL, 0 ); *OutLen = Len; return error; @@ -318,8 +313,6 @@ void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len, ("OskitTCPReceiveDatagram: %d (%d header) Bytes\n", Len, IpHeaderLen)); - OskitDumpBuffer( Data, Len ); - tcp_input(Ip, IpHeaderLen); /* The buffer Ip is freed by tcp_input */ diff --git a/reactos/drivers/lib/oskittcp/oskittcp/tcp_input.c b/reactos/drivers/lib/oskittcp/oskittcp/tcp_input.c index 50b01cfa71b..a914b1f98cf 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/tcp_input.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/tcp_input.c @@ -289,12 +289,14 @@ tcp_input(m, iphlen) ti->ti_x1 = 0; ti->ti_len = (u_short)tlen; HTONS(ti->ti_len); +#ifndef __REACTOS__ /* Checksum already done in IPReceive */ ti->ti_sum = in_cksum(m, len); if (ti->ti_sum) { printf("TCP: Bad Checksum\n"); tcpstat.tcps_rcvbadsum++; goto drop; } +#endif #endif /* TUBA_INCLUDE */ /* diff --git a/reactos/drivers/lib/oskittcp/oskittcp/uipc_mbuf.c b/reactos/drivers/lib/oskittcp/oskittcp/uipc_mbuf.c index 19fbc98b903..7b48b7e4f77 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/uipc_mbuf.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/uipc_mbuf.c @@ -417,8 +417,6 @@ m_copydata(m, off, len, cp) panic("m_copydata"); count = min(m->m_len - off, len); bcopy(mtod(m, caddr_t) + off, cp, count); - OS_DbgPrint(OSK_MID_TRACE,("buf %x, len %d\n", m, count)); - OskitDumpBuffer(m->m_data, count); len -= count; cp += count; off = 0; diff --git a/reactos/drivers/net/afd/afd/bind.c b/reactos/drivers/net/afd/afd/bind.c index 306db10b76f..c8897e159c0 100644 --- a/reactos/drivers/net/afd/afd/bind.c +++ b/reactos/drivers/net/afd/afd/bind.c @@ -1,4 +1,4 @@ -/* $Id: bind.c,v 1.5 2004/10/03 20:36:45 arty Exp $ +/* $Id: bind.c,v 1.6 2004/11/21 20:54:52 arty Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/bind.c @@ -19,6 +19,11 @@ NTSTATUS WarmSocketForBind( PAFD_FCB FCB ) { AFD_DbgPrint(MID_TRACE,("Called (AF %d)\n", FCB->LocalAddress->Address[0].AddressType)); + if( !FCB->TdiDeviceName.Length || !FCB->TdiDeviceName.Buffer ) { + AFD_DbgPrint(MID_TRACE,("Null Device\n")); + return STATUS_NO_SUCH_DEVICE; + } + if( FCB->LocalAddress ) { Status = TdiOpenAddressFile ( &FCB->TdiDeviceName, diff --git a/reactos/drivers/net/afd/afd/connect.c b/reactos/drivers/net/afd/afd/connect.c index 208d17c614e..a8844a386a9 100644 --- a/reactos/drivers/net/afd/afd/connect.c +++ b/reactos/drivers/net/afd/afd/connect.c @@ -1,4 +1,4 @@ -/* $Id: connect.c,v 1.4 2004/10/03 21:16:27 arty Exp $ +/* $Id: connect.c,v 1.5 2004/11/21 20:54:52 arty Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/connect.c @@ -13,7 +13,14 @@ #include "debug.h" NTSTATUS WarmSocketForConnection( PAFD_FCB FCB ) { - NTSTATUS Status = TdiOpenConnectionEndpointFile + NTSTATUS Status; + + if( !FCB->TdiDeviceName.Length || !FCB->TdiDeviceName.Buffer ) { + AFD_DbgPrint(MID_TRACE,("Null Device\n")); + return STATUS_NO_SUCH_DEVICE; + } + + Status = TdiOpenConnectionEndpointFile ( &FCB->TdiDeviceName, &FCB->Connection.Handle, &FCB->Connection.Object ); @@ -55,12 +62,12 @@ NTSTATUS DDKAPI StreamSocketConnectComplete Irp->IoStatus.Status)); if( NT_SUCCESS(Irp->IoStatus.Status) ) { - FCB->PollState |= AFD_EVENT_CONNECT; + FCB->PollState |= AFD_EVENT_CONNECT | AFD_EVENT_SEND; FCB->State = SOCKET_STATE_CONNECTED; AFD_DbgPrint(MID_TRACE,("Going to connected state %d\n", FCB->State)); PollReeval( FCB->DeviceExt, FCB->FileObject ); } else { - FCB->PollState |= AFD_EVENT_CONNECT_FAIL; + FCB->PollState |= AFD_EVENT_CONNECT_FAIL | AFD_EVENT_RECEIVE; AFD_DbgPrint(MID_TRACE,("Going to bound state\n")); FCB->State = SOCKET_STATE_BOUND; PollReeval( FCB->DeviceExt, FCB->FileObject ); diff --git a/reactos/drivers/net/afd/afd/main.c b/reactos/drivers/net/afd/afd/main.c index a8fa98f6d58..c3855eb9464 100644 --- a/reactos/drivers/net/afd/afd/main.c +++ b/reactos/drivers/net/afd/afd/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.12 2004/11/17 05:17:22 arty Exp $ +/* $Id: main.c,v 1.13 2004/11/21 20:54:52 arty Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/main.c @@ -163,8 +163,6 @@ VOID DestroySocket( PAFD_FCB FCB ) { return; } - FCB->PollState |= AFD_EVENT_CLOSE; - PollReeval( FCB->DeviceExt, FCB->FileObject ); /* After PoolReeval, this FCB should not be involved in any outstanding * poll requests */ @@ -211,10 +209,11 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, AFD_DbgPrint(MID_TRACE,("FCB %x\n", FCB)); - FileObject->FsContext = NULL; FCB->PollState |= AFD_EVENT_CLOSE; PollReeval( FCB->DeviceExt, FileObject ); + if( FCB->EventSelect ) ObDereferenceObject( FCB->EventSelect ); + FileObject->FsContext = NULL; DestroySocket( FCB ); Irp->IoStatus.Status = STATUS_SUCCESS; @@ -280,6 +279,12 @@ AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) case IOCTL_AFD_SELECT: return AfdSelect( DeviceObject, Irp, IrpSp ); + case IOCTL_AFD_EVENT_SELECT: + return AfdEventSelect( DeviceObject, Irp, IrpSp ); + + case IOCTL_AFD_ENUM_NETWORK_EVENTS: + return AfdEnumEvents( DeviceObject, Irp, IrpSp ); + case IOCTL_AFD_RECV_DATAGRAM: return AfdPacketSocketReadData( DeviceObject, Irp, IrpSp ); @@ -333,8 +338,6 @@ AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_DISCONNECT_DATA_SIZE\n")); case IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE\n")); - case IOCTL_AFD_EVENT_SELECT: - AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_EVENT_SELECT\n")); case IOCTL_AFD_DEFER_ACCEPT: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_DEFER_ACCEPT\n")); case IOCTL_AFD_GET_PENDING_CONNECT_DATA: diff --git a/reactos/drivers/net/afd/afd/read.c b/reactos/drivers/net/afd/afd/read.c index d2e19df75b1..743eec450f9 100644 --- a/reactos/drivers/net/afd/afd/read.c +++ b/reactos/drivers/net/afd/afd/read.c @@ -1,4 +1,4 @@ -/* $Id: read.c,v 1.11 2004/11/17 05:17:22 arty Exp $ +/* $Id: read.c,v 1.12 2004/11/21 20:54:52 arty Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/read.c @@ -88,9 +88,6 @@ NTSTATUS DDKAPI ReceiveComplete DestroySocket( FCB ); return STATUS_SUCCESS; } - - /* Reset in flight request because the last has been completed */ - FCB->ReceiveIrp.InFlightRequest = NULL; if( NT_SUCCESS(Irp->IoStatus.Status) ) { /* Update the receive window */ @@ -153,8 +150,10 @@ NTSTATUS DDKAPI ReceiveComplete FCB ); SocketCalloutLeave( FCB ); - } + } else + FCB->PollState |= AFD_EVENT_RECEIVE; } else { + /* Kill remaining recv irps */ while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) { NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]); @@ -166,14 +165,18 @@ NTSTATUS DDKAPI ReceiveComplete Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); } + + /* Handle closing signal */ + FCB->PollState |= AFD_EVENT_CLOSE; } if( FCB->Recv.Content ) { FCB->PollState |= AFD_EVENT_RECEIVE; - PollReeval( FCB->DeviceExt, FCB->FileObject ); } else FCB->PollState &= ~AFD_EVENT_RECEIVE; + PollReeval( FCB->DeviceExt, FCB->FileObject ); + SocketStateUnlock( FCB ); if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS; @@ -195,6 +198,10 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE ); + + FCB->EventsFired &= ~AFD_EVENT_RECEIVE; + PollReeval( FCB->DeviceExt, FCB->FileObject ); + if( !(RecvReq = LockRequest( Irp, IrpSp )) ) return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0, NULL, FALSE ); @@ -415,10 +422,11 @@ PacketSocketRecvComplete( if( !IsListEmpty( &FCB->DatagramList ) ) { AFD_DbgPrint(MID_TRACE,("Signalling\n")); FCB->PollState |= AFD_EVENT_RECEIVE; - PollReeval( FCB->DeviceExt, FCB->FileObject ); } else FCB->PollState &= ~AFD_EVENT_RECEIVE; + PollReeval( FCB->DeviceExt, FCB->FileObject ); + if( NT_SUCCESS(Irp->IoStatus.Status) ) { /* Now relaunch the datagram request */ SocketCalloutEnter( FCB ); @@ -455,6 +463,9 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE ); + + FCB->EventsFired &= ~AFD_EVENT_RECEIVE; + /* Check that the socket is bound */ if( FCB->State != SOCKET_STATE_BOUND ) return UnlockAndMaybeComplete @@ -481,22 +492,38 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, &DatagramRecv->ListEntry ); Status = Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = DatagramRecv->Len; + + if( IsListEmpty( &FCB->DatagramList ) ) + FCB->PollState &= ~AFD_EVENT_RECEIVE; + else + FCB->PollState |= AFD_EVENT_RECEIVE; + + PollReeval( FCB->DeviceExt, FCB->FileObject ); + return UnlockAndMaybeComplete ( FCB, Status, Irp, RecvReq->BufferArray[0].len, NULL, TRUE ); } else { Status = SatisfyPacketRecvRequest ( FCB, Irp, DatagramRecv, (PUINT)&Irp->IoStatus.Information ); + + if( IsListEmpty( &FCB->DatagramList ) ) + FCB->PollState &= ~AFD_EVENT_RECEIVE; + else + FCB->PollState |= AFD_EVENT_RECEIVE; + + PollReeval( FCB->DeviceExt, FCB->FileObject ); + return UnlockAndMaybeComplete ( 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; + PollReeval( FCB->DeviceExt, FCB->FileObject ); return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, TRUE ); } else { - FCB->PollState &= ~AFD_EVENT_RECEIVE; + PollReeval( FCB->DeviceExt, FCB->FileObject ); return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV ); } } diff --git a/reactos/drivers/net/afd/afd/select.c b/reactos/drivers/net/afd/afd/select.c index 9258643b1d3..d3562557a6a 100644 --- a/reactos/drivers/net/afd/afd/select.c +++ b/reactos/drivers/net/afd/afd/select.c @@ -1,4 +1,4 @@ -/* $Id: select.c,v 1.6 2004/11/17 05:17:22 arty Exp $ +/* $Id: select.c,v 1.7 2004/11/21 20:54:52 arty Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/select.c @@ -172,6 +172,72 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, return Status; } +NTSTATUS STDCALL +AfdEventSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, + PIO_STACK_LOCATION IrpSp ) { + PFILE_OBJECT FileObject = IrpSp->FileObject; + NTSTATUS Status = STATUS_NO_MEMORY; + PAFD_EVENT_SELECT_INFO EventSelectInfo = + (PAFD_EVENT_SELECT_INFO)LockRequest( Irp, IrpSp ); + PAFD_FCB FCB = FileObject->FsContext; + + AFD_DbgPrint(MID_TRACE,("Called (Event %x Triggers %x)\n", + EventSelectInfo->EventObject, + EventSelectInfo->Events)); + + if( !SocketAcquireStateLock( FCB ) ) { + UnlockRequest( Irp, IrpSp ); + return LostSocket( Irp, FALSE ); + } + + FCB->EventSelectTriggers = FCB->EventsFired = 0; + if( FCB->EventSelect ) ObDereferenceObject( FCB->EventSelect ); + FCB->EventSelect = NULL; + + if( EventSelectInfo->EventObject && EventSelectInfo->Events ) { + Status = ObReferenceObjectByHandle( (PVOID)EventSelectInfo-> + EventObject, + FILE_ALL_ACCESS, + NULL, + KernelMode, + (PVOID *)&FCB->EventSelect, + NULL ); + + if( !NT_SUCCESS(Status) ) + FCB->EventSelect = NULL; + else + FCB->EventSelectTriggers = EventSelectInfo->Events; + } else /* Work done, cancelling select */ + Status = STATUS_SUCCESS; + + AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status)); + + return UnlockAndMaybeComplete( FCB, STATUS_SUCCESS, Irp, + 0, NULL, TRUE ); +} + +NTSTATUS STDCALL +AfdEnumEvents( PDEVICE_OBJECT DeviceObject, PIRP Irp, + PIO_STACK_LOCATION IrpSp ) { + PFILE_OBJECT FileObject = IrpSp->FileObject; + PAFD_ENUM_NETWORK_EVENTS_INFO EnumReq = + (PAFD_ENUM_NETWORK_EVENTS_INFO)LockRequest( Irp, IrpSp ); + PAFD_FCB FCB = FileObject->FsContext; + + AFD_DbgPrint(MID_TRACE,("Called (FCB %x)\n", FCB)); + + if( !SocketAcquireStateLock( FCB ) ) { + UnlockRequest( Irp, IrpSp ); + return LostSocket( Irp, FALSE ); + } + + EnumReq->PollEvents = FCB->PollState; + RtlZeroMemory( EnumReq->EventStatus, sizeof(EnumReq->EventStatus) ); + + return UnlockAndMaybeComplete( FCB, STATUS_SUCCESS, Irp, + 0, NULL, TRUE ); +} + /* * * NOTE ALWAYS CALLED AT DISPATCH_LEVEL * * */ BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject ) { UINT i; @@ -186,7 +252,7 @@ BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject ) { FileObject = (PFILE_OBJECT)PollReq->InternalUse[i].Handle; FCB = FileObject->FsContext; - + if( (FCB->PollState & AFD_EVENT_CLOSE) || (PollReq->Handles[i].Status & AFD_EVENT_CLOSE) ) { PollReq->InternalUse[i].Handle = 0; @@ -210,14 +276,35 @@ BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject ) { VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) { PAFD_ACTIVE_POLL Poll = NULL; PLIST_ENTRY ThePollEnt = NULL; + PAFD_FCB FCB; KIRQL OldIrql; PAFD_POLL_INFO PollReq; + PKEVENT EventSelect = NULL; AFD_DbgPrint(MID_TRACE,("Called: DeviceExt %x FileObject %x\n", DeviceExt, FileObject)); - + KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql ); + /* Take care of any event select signalling */ + FCB = (PAFD_FCB)FileObject->FsContext; + + /* Not sure if i can do this at DISPATCH_LEVEL ... try it at passive */ + AFD_DbgPrint(MID_TRACE,("Current State: %x, Events Fired: %x, " + "Select Triggers %x\n", + FCB->PollState, FCB->EventsFired, + FCB->EventSelectTriggers)); + if( FCB->PollState & ~FCB->EventsFired & FCB->EventSelectTriggers ) { + FCB->EventsFired |= FCB->PollState; + EventSelect = FCB->EventSelect; + } + + if( !FCB ) { + KeReleaseSpinLock( &DeviceExt->Lock, OldIrql ); + return; + } + + /* Now signal normal select irps */ ThePollEnt = DeviceExt->Polls.Flink; while( ThePollEnt != &DeviceExt->Polls ) { @@ -235,5 +322,8 @@ VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) { KeReleaseSpinLock( &DeviceExt->Lock, OldIrql ); + AFD_DbgPrint(MID_TRACE,("Setting event %x\n", EventSelect)); + if( EventSelect ) KeSetEvent( EventSelect, IO_NETWORK_INCREMENT, FALSE ); + AFD_DbgPrint(MID_TRACE,("Leaving\n")); } diff --git a/reactos/drivers/net/afd/afd/write.c b/reactos/drivers/net/afd/afd/write.c index 1a0c3d1a25f..b4cc4ba14c4 100644 --- a/reactos/drivers/net/afd/afd/write.c +++ b/reactos/drivers/net/afd/afd/write.c @@ -1,4 +1,4 @@ -/* $Id: write.c,v 1.11 2004/11/15 18:24:57 arty Exp $ +/* $Id: write.c,v 1.12 2004/11/21 20:54:52 arty Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/write.c @@ -163,6 +163,9 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE ); + + FCB->EventsFired &= ~AFD_EVENT_SEND; + if( !(SendReq = LockRequest( Irp, IrpSp )) ) return UnlockAndMaybeComplete ( FCB, STATUS_NO_MEMORY, Irp, TotalBytesCopied, NULL, FALSE ); @@ -307,6 +310,9 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE ); + + FCB->EventsFired &= ~AFD_EVENT_SEND; + /* Check that the socket is bound */ if( FCB->State != SOCKET_STATE_BOUND ) return UnlockAndMaybeComplete diff --git a/reactos/drivers/net/afd/include/afd.h b/reactos/drivers/net/afd/include/afd.h index 73fbb191628..f8c7c307b99 100644 --- a/reactos/drivers/net/afd/include/afd.h +++ b/reactos/drivers/net/afd/include/afd.h @@ -1,4 +1,4 @@ -/* $Id: afd.h,v 1.24 2004/11/17 05:17:22 arty Exp $ +/* $Id: afd.h,v 1.25 2004/11/21 20:54:52 arty Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -82,6 +82,7 @@ typedef struct _AFD_ACTIVE_POLL { PAFD_DEVICE_EXTENSION DeviceExt; KDPC TimeoutDpc; KTIMER Timer; + PKEVENT EventObject; } AFD_ACTIVE_POLL, *PAFD_ACTIVE_POLL; typedef struct _IRP_LIST { @@ -129,6 +130,9 @@ typedef struct _AFD_FCB { AFD_DATA_WINDOW Send, Recv; FAST_MUTEX Mutex; KEVENT StateLockedEvent; + PKEVENT EventSelect; + DWORD EventSelectTriggers; + DWORD EventsFired; UNICODE_STRING TdiDeviceName; PVOID Context; DWORD PollState; @@ -223,6 +227,12 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, NTSTATUS STDCALL AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp ); +NTSTATUS STDCALL +AfdEventSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, + PIO_STACK_LOCATION IrpSp ); +NTSTATUS STDCALL +AfdEnumEvents( PDEVICE_OBJECT DeviceObject, PIRP Irp, + PIO_STACK_LOCATION IrpSp ); VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceObject, PFILE_OBJECT FileObject ); /* tdi.c */ diff --git a/reactos/drivers/net/tcpip/include/fileobjs.h b/reactos/drivers/net/tcpip/include/fileobjs.h index 59deaa10f26..bff07a64b40 100644 --- a/reactos/drivers/net/tcpip/include/fileobjs.h +++ b/reactos/drivers/net/tcpip/include/fileobjs.h @@ -27,6 +27,8 @@ NTSTATUS FileOpenConnection( PTDI_REQUEST Request, PVOID ClientContext); +PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context ); + NTSTATUS FileCloseConnection( PTDI_REQUEST Request); diff --git a/reactos/drivers/net/tcpip/tcpip/fileobjs.c b/reactos/drivers/net/tcpip/tcpip/fileobjs.c index 142bf3f8e07..933c3beea83 100644 --- a/reactos/drivers/net/tcpip/tcpip/fileobjs.c +++ b/reactos/drivers/net/tcpip/tcpip/fileobjs.c @@ -402,6 +402,36 @@ TI_DbgPrint(MIN_TRACE, ("X1 Blink 0x%x\n", Connection->ReceivedSegments.Blink)); } +/* + * FUNCTION: Find a connection by examining the context field. This + * is needed in some situations where a FIN reply is needed after a + * socket is formally broken. + * ARGUMENTS: + * Request = Pointer to TDI request structure for this request + * RETURNS: + * Status of operation + */ +PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context ) { + PLIST_ENTRY Entry; + KIRQL OldIrql; + PCONNECTION_ENDPOINT Connection = NULL; + + KeAcquireSpinLock( &ConnectionEndpointListLock, &OldIrql ); + + for( Entry = ConnectionEndpointListHead.Flink; + Entry != &ConnectionEndpointListHead; + Entry = Entry->Flink ) { + Connection = + CONTAINING_RECORD( Entry, CONNECTION_ENDPOINT, ListEntry ); + if( Connection->SocketContext == Context ) break; + else Connection = NULL; + } + + KeReleaseSpinLock( &ConnectionEndpointListLock, OldIrql ); + + return Connection; +} + /* * FUNCTION: Closes an connection file object * ARGUMENTS: @@ -468,7 +498,6 @@ NTSTATUS FileOpenControlChannel( return STATUS_SUCCESS; } - /* * FUNCTION: Closes a control channel file object * ARGUMENTS: diff --git a/reactos/include/afd/shared.h b/reactos/include/afd/shared.h index 611a706086f..4fdef6ce377 100644 --- a/reactos/include/afd/shared.h +++ b/reactos/include/afd/shared.h @@ -7,6 +7,7 @@ #ifndef __AFD_SHARED_H #define __AFD_SHARED_H +#define AFD_MAX_EVENTS 10 #define AFD_PACKET_COMMAND_LENGTH 15 #define AfdCommand "AfdOpenPacketXX" @@ -123,6 +124,12 @@ typedef struct _AFD_EVENT_SELECT_INFO { ULONG Events; } AFD_EVENT_SELECT_INFO, *PAFD_EVENT_SELECT_INFO; +typedef struct _AFD_ENUM_NETWORK_EVENTS_INFO { + HANDLE Event; + ULONG PollEvents; + NTSTATUS EventStatus[AFD_MAX_EVENTS]; +} AFD_ENUM_NETWORK_EVENTS_INFO, *PAFD_ENUM_NETWORK_EVENTS_INFO; + typedef struct _AFD_DISCONNECT_INFO { ULONG DisconnectType; LARGE_INTEGER Timeout; @@ -205,6 +212,7 @@ typedef struct _AFD_DISCONNECT_INFO { #define AFD_SET_DISCONNECT_OPTIONS_SIZE 29 #define AFD_GET_INFO 30 #define AFD_EVENT_SELECT 33 +#define AFD_ENUM_NETWORK_EVENTS 34 #define AFD_DEFER_ACCEPT 35 #define AFD_GET_PENDING_CONNECT_DATA 41 @@ -272,6 +280,8 @@ typedef struct _AFD_DISCONNECT_INFO { _AFD_CONTROL_CODE(AFD_DEFER_ACCEPT, METHOD_NEITHER) #define IOCTL_AFD_GET_PENDING_CONNECT_DATA \ _AFD_CONTROL_CODE(AFD_GET_PENDING_CONNECT_DATA, METHOD_NEITHER) +#define IOCTL_AFD_ENUM_NETWORK_EVENTS \ + _AFD_CONTROL_CODE(AFD_ENUM_NETWORK_EVENTS, METHOD_NEITHER) typedef struct _AFD_SOCKET_INFORMATION { BOOL CommandChannel; @@ -352,17 +362,6 @@ typedef struct _FILE_REPLY_EVENTSELECT { INT Status; } FILE_REPLY_EVENTSELECT, *PFILE_REPLY_EVENTSELECT; - -typedef struct _FILE_REQUEST_ENUMNETWORKEVENTS { - WSAEVENT hEventObject; -} FILE_REQUEST_ENUMNETWORKEVENTS, *PFILE_REQUEST_ENUMNETWORKEVENTS; - -typedef struct _FILE_REPLY_ENUMNETWORKEVENTS { - INT Status; - WSANETWORKEVENTS NetworkEvents; -} FILE_REPLY_ENUMNETWORKEVENTS, *PFILE_REPLY_ENUMNETWORKEVENTS; - - typedef struct _FILE_REQUEST_RECV { LPWSABUF Buffers; DWORD BufferCount;