From 703e2aa5f9bcbc33e9eb9df5969b69f23e52dc8e Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 5 Sep 2004 04:26:30 +0000 Subject: [PATCH] Fixes: Socket destruction is correct. When IRPs are left to cancel, the socket will remain until all pending irps complete. The DestroySocket function does this. It is always safe to call DestroySocket at any time after the FsContext member of the FileObject has been nulled. Fixed UDP data delivery in. UDP send still has a problem but it seems to be in tcpip.sys more than likely. I've sliced another 6000 lines out of tcpip.sys that i will debug as a userspace library and link to tcpip. Fixed poll reeval (old reported bug fix I hadn't committed yet). Miscellaneously better sanity in a few rough spots. svn path=/trunk/; revision=10785 --- reactos/drivers/net/afd/afd/bind.c | 13 ++++- reactos/drivers/net/afd/afd/listen.c | 18 +++++- reactos/drivers/net/afd/afd/main.c | 82 ++++++++++++++++++--------- reactos/drivers/net/afd/afd/read.c | 76 ++++++++++++++++++++----- reactos/drivers/net/afd/afd/select.c | 4 +- reactos/drivers/net/afd/afd/tdi.c | 48 ++++++---------- reactos/drivers/net/afd/afd/write.c | 47 +++++++++++++-- reactos/drivers/net/afd/include/afd.h | 3 +- 8 files changed, 207 insertions(+), 84 deletions(-) diff --git a/reactos/drivers/net/afd/afd/bind.c b/reactos/drivers/net/afd/afd/bind.c index 53bb8a342ea..77f122823e6 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.3 2004/07/18 22:53:59 arty Exp $ +/* $Id: bind.c,v 1.4 2004/09/05 04:26:29 arty Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/bind.c @@ -16,7 +16,8 @@ NTSTATUS WarmSocketForBind( PAFD_FCB FCB ) { NTSTATUS Status = STATUS_UNSUCCESSFUL; - AFD_DbgPrint(MID_TRACE,("Called\n")); + AFD_DbgPrint(MID_TRACE,("Called (AF %d)\n", + FCB->LocalAddress->Address[0].AddressType)); if( FCB->LocalAddress ) { Status = TdiOpenAddressFile @@ -60,6 +61,9 @@ AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, if( NT_SUCCESS(Status) ) FCB->State = SOCKET_STATE_BOUND; + else return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, FALSE ); + + AFD_DbgPrint(MID_TRACE,("FCB->Flags %x\n", FCB->Flags)); if( FCB->Flags & SGID_CONNECTIONLESS ) { /* This will be the from address for subsequent recvfrom calls */ @@ -69,6 +73,8 @@ AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, FCB->Recv.Window = ExAllocatePool( NonPagedPool, FCB->Recv.Size ); FCB->PollState |= AFD_EVENT_SEND; /* A datagram socket is always sendable */ + + AFD_DbgPrint(MID_TRACE,("Calling TdiReceiveDatagram\n")); Status = TdiReceiveDatagram ( &FCB->ReceiveIrp.InFlightRequest, @@ -80,6 +86,9 @@ AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, &FCB->ReceiveIrp.Iosb, PacketSocketRecvComplete, FCB ); + + /* We don't want to wait for this read to complete. */ + if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS; } return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, TRUE ); diff --git a/reactos/drivers/net/afd/afd/listen.c b/reactos/drivers/net/afd/afd/listen.c index 3f474ca544d..bb2cfcc9180 100644 --- a/reactos/drivers/net/afd/afd/listen.c +++ b/reactos/drivers/net/afd/afd/listen.c @@ -1,4 +1,4 @@ -/* $Id: listen.c,v 1.3 2004/07/18 22:53:59 arty Exp $ +/* $Id: listen.c,v 1.4 2004/09/05 04:26:29 arty Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/listen.c @@ -16,10 +16,25 @@ NTSTATUS DDKAPI ListenComplete ( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) { + NTSTATUS Status = STATUS_UNSUCCESSFUL; PAFD_FCB FCB = (PAFD_FCB)Context; + + if( !SocketAcquireStateLock( FCB ) ) return Status; + + FCB->ListenIrp.InFlightRequest = NULL; + + if( FCB->State == SOCKET_STATE_CLOSED ) { + SocketStateUnlock( FCB ); + DestroySocket( FCB ); + return STATUS_SUCCESS; + } + AFD_DbgPrint(MID_TRACE,("Completing listen request.\n")); AFD_DbgPrint(MID_TRACE,("IoStatus was %x\n", FCB->ListenIrp.Iosb.Status)); AFD_DbgPrint(MID_TRACE,("Doing nothing as yet.\n")); + + SocketStateUnlock( FCB ); + return STATUS_SUCCESS; } @@ -33,6 +48,7 @@ NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, AFD_DbgPrint(MID_TRACE,("Called\n")); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, TRUE ); + if( !(ListenReq = LockRequest( Irp, IrpSp )) ) return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0, NULL, FALSE ); diff --git a/reactos/drivers/net/afd/afd/main.c b/reactos/drivers/net/afd/afd/main.c index bd44c4c6c26..b569086e2a3 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.5 2004/08/22 18:42:42 arty Exp $ +/* $Id: main.c,v 1.6 2004/09/05 04:26:29 arty Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/main.c @@ -22,8 +22,8 @@ extern NTSTATUS DDKAPI MmCopyFromCaller( PVOID Dst, PVOID Src, UINT Size ); /* See debug.h for debug/trace constants */ -//DWORD DebugTraceLevel = DEBUG_ULTRA; -DWORD DebugTraceLevel = 0; +DWORD DebugTraceLevel = DEBUG_ULTRA; +//DWORD DebugTraceLevel = 0; #endif /* DBG */ @@ -88,7 +88,7 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, return STATUS_NO_MEMORY; } - AFD_DbgPrint(MID_TRACE,("Initializing the new FCB @ %x (FileObject %x)\n", FCB, FileObject)); + AFD_DbgPrint(MID_TRACE,("Initializing the new FCB @ %x (FileObject %x Flags %x)\n", FCB, FileObject, ConnectInfo->EndpointFlags)); RtlZeroMemory( FCB, sizeof( *FCB ) ); @@ -107,6 +107,8 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, InitializeListHead( &FCB->PendingIrpList[i] ); } + InitializeListHead( &FCB->DatagramList ); + AFD_DbgPrint(MID_TRACE,("%x: Checking command channel\n", FCB)); FCB->TdiDeviceName.Length = ConnectInfo->SizeOfTransportName; @@ -134,27 +136,31 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, return STATUS_SUCCESS; } -NTSTATUS STDCALL -AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, - PIO_STACK_LOCATION IrpSp) -{ - PFILE_OBJECT FileObject = IrpSp->FileObject; - PAFD_FCB FCB = FileObject->FsContext; +VOID DestroySocket( PAFD_FCB FCB ) { UINT i; PAFD_IN_FLIGHT_REQUEST InFlightRequest[IN_FLIGHT_REQUESTS]; + BOOLEAN DontDeleteYet = FALSE; - if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE ); + AFD_DbgPrint(MIN_TRACE,("Called (%x)\n", FCB)); + + if( !SocketAcquireStateLock( FCB ) ) return; + + FCB->State = SOCKET_STATE_CLOSED; InFlightRequest[0] = &FCB->ListenIrp; InFlightRequest[1] = &FCB->ReceiveIrp; InFlightRequest[2] = &FCB->SendIrp; - AFD_DbgPrint(MID_TRACE, - ("AfdClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp)); - - AFD_DbgPrint(MID_TRACE,("FCB %x\n", FCB)); + if( FCB->ListenIrp.InFlightRequest || + FCB->ReceiveIrp.InFlightRequest || + FCB->SendIrp.InFlightRequest ) { + AFD_DbgPrint(MIN_TRACE,("Leaving socket alive (%x %x %x)\n", + FCB->ListenIrp.InFlightRequest, + FCB->ReceiveIrp.InFlightRequest, + FCB->SendIrp.InFlightRequest)); + DontDeleteYet = TRUE; + } - FileObject->FsContext = NULL; FCB->PollState |= AFD_EVENT_CLOSE; PollReeval( FCB->DeviceExt, FCB->FileObject ); /* After PoolReeval, this FCB should not be involved in any outstanding @@ -174,22 +180,44 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, SocketStateUnlock( FCB ); - if( FCB->Recv.Window ) - ExFreePool( FCB->Recv.Window ); - if( FCB->Send.Window ) - ExFreePool( FCB->Send.Window ); - if( FCB->AddressFrom ) - ExFreePool( FCB->AddressFrom ); - if( FCB->LocalAddress ) - ExFreePool( FCB->LocalAddress ); + if( !DontDeleteYet ) { + if( FCB->Recv.Window ) + ExFreePool( FCB->Recv.Window ); + if( FCB->Send.Window ) + ExFreePool( FCB->Send.Window ); + if( FCB->AddressFrom ) + ExFreePool( FCB->AddressFrom ); + if( FCB->LocalAddress ) + ExFreePool( FCB->LocalAddress ); + + ExFreePool(FCB->TdiDeviceName.Buffer); + + ExFreePool(FCB); + AFD_DbgPrint(MIN_TRACE,("Deleted (%x)\n", FCB)); + } - ExFreePool(FCB->TdiDeviceName.Buffer); - ExFreePool(FCB); + AFD_DbgPrint(MIN_TRACE,("Leaving\n")); +} + +NTSTATUS STDCALL +AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, + PIO_STACK_LOCATION IrpSp) +{ + PFILE_OBJECT FileObject = IrpSp->FileObject; + PAFD_FCB FCB = FileObject->FsContext; + + AFD_DbgPrint(MID_TRACE, + ("AfdClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp)); + + AFD_DbgPrint(MID_TRACE,("FCB %x\n", FCB)); + + FileObject->FsContext = NULL; + DestroySocket( FCB ); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); - + AFD_DbgPrint(MID_TRACE, ("Returning success.\n")); return STATUS_SUCCESS; diff --git a/reactos/drivers/net/afd/afd/read.c b/reactos/drivers/net/afd/afd/read.c index dc5dc1b66e6..5933c91a958 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.4 2004/08/22 18:42:42 arty Exp $ +/* $Id: read.c,v 1.5 2004/09/05 04:26:29 arty Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/read.c @@ -77,6 +77,14 @@ NTSTATUS DDKAPI ReceiveComplete if( !SocketAcquireStateLock( FCB ) ) return Status; + FCB->ReceiveIrp.InFlightRequest = NULL; + + if( FCB->State == SOCKET_STATE_CLOSED ) { + SocketStateUnlock( FCB ); + DestroySocket( FCB ); + return STATUS_SUCCESS; + } + /* Reset in flight request because the last has been completed */ FCB->ReceiveIrp.InFlightRequest = NULL; @@ -216,19 +224,39 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, NTSTATUS STDCALL SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp, - PAFD_STORED_DATAGRAM DatagramRecv ) { + PAFD_STORED_DATAGRAM DatagramRecv, + PUINT TotalBytesCopied ) { NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); PAFD_RECV_INFO RecvReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; - UINT CopyLen = 0; + UINT BytesToCopy = 0, BytesAvailable = DatagramRecv->Len; + PAFD_MAPBUF Map; - CopyLen = MIN(DatagramRecv->Len, RecvReq->BufferArray[0].len); - RtlCopyMemory( RecvReq->BufferArray[0].buf, DatagramRecv->Buffer, - CopyLen ); + Map = (PAFD_MAPBUF)(RecvReq->BufferArray + RecvReq->BufferCount); + + BytesToCopy = + MIN( RecvReq->BufferArray[0].len, BytesAvailable ); + if( Map[0].Mdl ) { + Map[0].BufferAddress = MmMapLockedPages( Map[0].Mdl, KernelMode ); + + AFD_DbgPrint(MID_TRACE,("Buffer %d: %x:%d\n", + 0, + Map[0].BufferAddress, + BytesToCopy)); + RtlCopyMemory( Map[0].BufferAddress, + FCB->Recv.Window + FCB->Recv.BytesUsed, + BytesToCopy ); + + MmUnmapLockedPages( Map[0].BufferAddress, Map[0].Mdl ); + + FCB->Recv.BytesUsed = 0; + *TotalBytesCopied = BytesToCopy; + } + Status = Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = CopyLen; + Irp->IoStatus.Information = BytesToCopy; ExFreePool( DatagramRecv ); return Status; @@ -242,6 +270,7 @@ PacketSocketRecvComplete( NTSTATUS Status = STATUS_SUCCESS; PAFD_FCB FCB = Context; PIRP NextIrp; + PIO_STACK_LOCATION NextIrpSp; PLIST_ENTRY ListEntry; PAFD_RECV_INFO RecvReq; PAFD_STORED_DATAGRAM DatagramRecv; @@ -249,9 +278,14 @@ PacketSocketRecvComplete( AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); - if( !SocketAcquireStateLock( FCB ) ) { + if( !SocketAcquireStateLock( FCB ) ) return STATUS_UNSUCCESSFUL; + + FCB->ReceiveIrp.InFlightRequest = NULL; + + if( FCB->State == SOCKET_STATE_CLOSED ) { SocketStateUnlock( FCB ); - return STATUS_UNSUCCESSFUL; + DestroySocket( FCB ); + return STATUS_SUCCESS; } DatagramRecv = ExAllocatePool( NonPagedPool, DGSize ); @@ -274,7 +308,13 @@ PacketSocketRecvComplete( ListEntry = RemoveHeadList ( &FCB->PendingIrpList[FUNCTION_RECV_DATAGRAM] ); NextIrp = CONTAINING_RECORD( ListEntry, IRP, Tail.Overlay.ListEntry ); - RecvReq = NextIrp->AssociatedIrp.SystemBuffer; + NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); + RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + + AFD_DbgPrint(MID_TRACE,("RecvReq: %x, DatagramRecv: %x\n", + RecvReq, DatagramRecv)); + AFD_DbgPrint(MID_TRACE,("RecvReq->BufferArray %x\n", + RecvReq->BufferArray[0])); if( DatagramRecv->Len > RecvReq->BufferArray[0].len && !(RecvReq->TdiFlags & TDI_RECEIVE_PARTIAL) ) { @@ -285,7 +325,9 @@ PacketSocketRecvComplete( UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount ); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } else { - Status = SatisfyPacketRecvRequest( FCB, NextIrp, DatagramRecv ); + Status = SatisfyPacketRecvRequest + ( FCB, NextIrp, DatagramRecv, + (PUINT)&NextIrp->IoStatus.Information ); UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount ); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } @@ -326,14 +368,18 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE ); + /* Check that the socket is bound */ + if( FCB->State != SOCKET_STATE_BOUND ) + return UnlockAndMaybeComplete + ( FCB, STATUS_UNSUCCESSFUL, Irp, 0, NULL, FALSE ); if( !(RecvReq = LockRequest( Irp, IrpSp )) ) return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0, NULL, FALSE ); if( !IsListEmpty( &FCB->DatagramList ) ) { ListEntry = RemoveHeadList( &FCB->DatagramList ); - DatagramRecv = CONTAINING_RECORD( ListEntry, AFD_STORED_DATAGRAM, - ListEntry ); + DatagramRecv = CONTAINING_RECORD + ( ListEntry, AFD_STORED_DATAGRAM, ListEntry ); if( DatagramRecv->Len > RecvReq->BufferArray[0].len && !(RecvReq->TdiFlags & TDI_RECEIVE_PARTIAL) ) { InsertHeadList( &FCB->DatagramList, @@ -346,7 +392,9 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, if( IsListEmpty( &FCB->DatagramList ) ) FCB->PollState &= ~AFD_EVENT_RECEIVE; - Status = SatisfyPacketRecvRequest( FCB, Irp, DatagramRecv ); + Status = SatisfyPacketRecvRequest + ( FCB, Irp, DatagramRecv, + (PUINT)&Irp->IoStatus.Information ); return UnlockAndMaybeComplete ( FCB, Status, Irp, Irp->IoStatus.Information, NULL, TRUE ); } diff --git a/reactos/drivers/net/afd/afd/select.c b/reactos/drivers/net/afd/afd/select.c index 761f37b3400..cb3141d7c09 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.2 2004/07/18 22:49:17 arty Exp $ +/* $Id: select.c,v 1.3 2004/09/05 04:26:29 arty Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/select.c @@ -233,5 +233,5 @@ VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) { KeReleaseSpinLock( &DeviceExt->Lock, OldIrql ); - AFD_DbgPrint(MID_TRACE,("Leaving")); + AFD_DbgPrint(MID_TRACE,("Leaving\n")); } diff --git a/reactos/drivers/net/afd/afd/tdi.c b/reactos/drivers/net/afd/afd/tdi.c index 7f291f15d0f..70898723eb6 100644 --- a/reactos/drivers/net/afd/afd/tdi.c +++ b/reactos/drivers/net/afd/afd/tdi.c @@ -8,6 +8,9 @@ * CSH 01/09-2000 Created */ #include +#ifndef _MSC_VER +#include +#endif #include "debug.h" #include "tdiconn.h" @@ -821,17 +824,13 @@ NTSTATUS TdiSend return STATUS_INSUFFICIENT_RESOURCES; } -#ifdef _MSC_VER - try { -#endif + _SEH_TRY { MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess); -#ifdef _MSC_VER - } except (EXCEPTION_EXECUTE_HANDLER) { + } _SEH_HANDLE { AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n")); IoFreeIrp(*Irp); return STATUS_INSUFFICIENT_RESOURCES; - } -#endif + } _SEH_END; AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl)); @@ -896,18 +895,13 @@ NTSTATUS TdiReceive( return STATUS_INSUFFICIENT_RESOURCES; } -#ifdef _MSC_VER - try { -#endif + _SEH_TRY { MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess); -#ifdef _MSC_VER - } except (EXCEPTION_EXECUTE_HANDLER) { + } _SEH_HANDLE { AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n")); - IoFreeMdl(Mdl); IoFreeIrp(*Irp); return STATUS_INSUFFICIENT_RESOURCES; - } -#endif + } _SEH_END; AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl)); @@ -985,18 +979,13 @@ NTSTATUS TdiReceiveDatagram( return STATUS_INSUFFICIENT_RESOURCES; } -#ifdef _MSC_VER - try { -#endif + _SEH_TRY { MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess); -#ifdef _MSC_VER - } except (EXCEPTION_EXECUTE_HANDLER) { + } _SEH_HANDLE { AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n")); - IoFreeMdl(Mdl); IoFreeIrp(*Irp); return STATUS_INSUFFICIENT_RESOURCES; - } -#endif + } _SEH_END; AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl)); @@ -1045,6 +1034,8 @@ NTSTATUS TdiSendDatagram( NTSTATUS Status; PMDL Mdl; + AFD_DbgPrint(MID_TRACE,("Called(TransportObject %x)\n", TransportObject)); + DeviceObject = IoGetRelatedDeviceObject(TransportObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); @@ -1076,18 +1067,13 @@ NTSTATUS TdiSendDatagram( return STATUS_INSUFFICIENT_RESOURCES; } -#ifdef _MSC_VER - try { -#endif + _SEH_TRY { MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess); -#ifdef _MSC_VER - } except (EXCEPTION_EXECUTE_HANDLER) { + } _SEH_HANDLE { AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n")); - IoFreeMdl(Mdl); IoFreeIrp(*Irp); return STATUS_INSUFFICIENT_RESOURCES; - } -#endif + } _SEH_END; AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl)); diff --git a/reactos/drivers/net/afd/afd/write.c b/reactos/drivers/net/afd/afd/write.c index 5575addff23..0bd56751ee9 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.4 2004/08/22 18:42:42 arty Exp $ +/* $Id: write.c,v 1.5 2004/09/05 04:26:29 arty Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/write.c @@ -35,6 +35,12 @@ NTSTATUS DDKAPI SendComplete FCB->SendIrp.InFlightRequest = NULL; /* Request is not in flight any longer */ + if( FCB->State == SOCKET_STATE_CLOSED ) { + SocketStateUnlock( FCB ); + DestroySocket( FCB ); + return STATUS_SUCCESS; + } + if( !NT_SUCCESS(Status) ) { /* Complete all following send IRPs with error */ @@ -236,6 +242,31 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND ); } +NTSTATUS DDKAPI PacketSocketSendComplete +( PDEVICE_OBJECT DeviceObject, + PIRP Irp, + PVOID Context ) { + PAFD_FCB FCB = (PAFD_FCB)Context; + + AFD_DbgPrint(MID_TRACE,("Called, status %x, %d bytes used\n", + Irp->IoStatus.Status, + Irp->IoStatus.Information)); + + /* It's ok if the FCB already died */ + if( !SocketAcquireStateLock( FCB ) ) return STATUS_SUCCESS; + + FCB->SendIrp.InFlightRequest = NULL; + /* Request is not in flight any longer */ + + if( FCB->State == SOCKET_STATE_CLOSED ) { + SocketStateUnlock( FCB ); + DestroySocket( FCB ); + return STATUS_SUCCESS; + } + + return STATUS_SUCCESS; +} + NTSTATUS STDCALL AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { @@ -247,9 +278,13 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE ); + /* Check that the socket is bound */ + if( FCB->State != SOCKET_STATE_BOUND ) + return UnlockAndMaybeComplete + ( FCB, STATUS_UNSUCCESSFUL, Irp, 0, NULL, FALSE ); if( !(SendReq = LockRequest( Irp, IrpSp )) ) - return UnlockAndMaybeComplete - ( FCB, STATUS_NO_MEMORY, Irp, 0, NULL, FALSE ); + return UnlockAndMaybeComplete + ( FCB, STATUS_NO_MEMORY, Irp, 0, NULL, FALSE ); /* Check the size of the Address given ... */ @@ -260,11 +295,11 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, SendReq->BufferArray[0].len, SendReq->RemoteAddress, &FCB->SendIrp.Iosb, - NULL, - NULL ); + PacketSocketSendComplete, + FCB ); if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS; - + AFD_DbgPrint(MID_TRACE,("Dismissing request: %x\n", Status)); return UnlockAndMaybeComplete diff --git a/reactos/drivers/net/afd/include/afd.h b/reactos/drivers/net/afd/include/afd.h index ad443f0de8a..74ef4553f85 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.19 2004/07/18 22:49:17 arty Exp $ +/* $Id: afd.h,v 1.20 2004/09/05 04:26:30 arty Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -187,6 +187,7 @@ VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ); VOID OskitDumpBuffer( PCHAR Buffer, UINT Len ); NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function ); +VOID DestroySocket( PAFD_FCB FCB ); /* read.c */