diff --git a/reactos/drivers/network/afd/afd/connect.c b/reactos/drivers/network/afd/afd/connect.c index 9df1eb6815c..2c7185e00d9 100644 --- a/reactos/drivers/network/afd/afd/connect.c +++ b/reactos/drivers/network/afd/afd/connect.c @@ -43,10 +43,13 @@ AfdSetConnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp, { PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; - PVOID ConnectOptions = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + PVOID ConnectOptions = LockRequest(Irp, IrpSp); UINT ConnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); + + if (!ConnectOptions) + return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); if (FCB->ConnectOptions) { @@ -75,10 +78,13 @@ AfdSetConnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp, { PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; - PUINT ConnectOptionsSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + PUINT ConnectOptionsSize = LockRequest(Irp, IrpSp); UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); + + if (!ConnectOptionsSize) + return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); if (BufferSize < sizeof(UINT)) return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0); @@ -129,10 +135,13 @@ AfdSetConnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp, { PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; - PVOID ConnectData = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + PVOID ConnectData = LockRequest(Irp, IrpSp); UINT ConnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); + + if (!ConnectData) + return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); if (FCB->ConnectData) { @@ -161,11 +170,14 @@ AfdSetConnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp, { PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; - PUINT ConnectDataSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + PUINT ConnectDataSize = LockRequest(Irp, IrpSp); UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); + if (!ConnectDataSize) + return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); + if (BufferSize < sizeof(UINT)) return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0); @@ -274,6 +286,7 @@ static NTSTATUS NTAPI StreamSocketConnectComplete AFD_DbgPrint(MID_TRACE,("Irp->IoStatus.Status = %x\n", Irp->IoStatus.Status)); + ASSERT(FCB->ConnectIrp.InFlightRequest == Irp); FCB->ConnectIrp.InFlightRequest = NULL; if( FCB->State == SOCKET_STATE_CLOSED ) { diff --git a/reactos/drivers/network/afd/afd/context.c b/reactos/drivers/network/afd/afd/context.c index e612cb9ff39..e58398d1727 100644 --- a/reactos/drivers/network/afd/afd/context.c +++ b/reactos/drivers/network/afd/afd/context.c @@ -54,14 +54,18 @@ AfdGetContextSize( PDEVICE_OBJECT DeviceObject, PIRP Irp, return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, sizeof(ULONG)); } - + NTSTATUS NTAPI AfdSetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp ) { PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; + PVOID Context = LockRequest(Irp, IrpSp); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); + + if (!Context) + return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); if( FCB->Context ) { ExFreePool( FCB->Context ); @@ -76,7 +80,7 @@ AfdSetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp, FCB->ContextSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; RtlCopyMemory( FCB->Context, - IrpSp->Parameters.DeviceIoControl.Type3InputBuffer, + Context, FCB->ContextSize ); return UnlockAndMaybeComplete( FCB, STATUS_SUCCESS, Irp, 0 ); diff --git a/reactos/drivers/network/afd/afd/info.c b/reactos/drivers/network/afd/afd/info.c index a5eabcb0d5c..3d502a9e632 100644 --- a/reactos/drivers/network/afd/afd/info.c +++ b/reactos/drivers/network/afd/afd/info.c @@ -17,7 +17,7 @@ NTSTATUS NTAPI AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp ) { NTSTATUS Status = STATUS_SUCCESS; - PAFD_INFO InfoReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + PAFD_INFO InfoReq = LockRequest(Irp, IrpSp); PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; PLIST_ENTRY CurrentEntry; @@ -26,6 +26,9 @@ AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp, InfoReq ? InfoReq->InformationClass : 0)); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); + + if (!InfoReq) + return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); _SEH2_TRY { switch( InfoReq->InformationClass ) { @@ -67,10 +70,6 @@ AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp, CurrentEntry = CurrentEntry->Flink; } - /* Count the send in progress */ - if (FCB->SendIrp.InFlightRequest) - InfoReq->Information.Ulong++; - break; default: @@ -93,11 +92,14 @@ NTSTATUS NTAPI AfdSetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp ) { NTSTATUS Status = STATUS_SUCCESS; - PAFD_INFO InfoReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + PAFD_INFO InfoReq = LockRequest(Irp, IrpSp); PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); + + if (!InfoReq) + return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); _SEH2_TRY { switch (InfoReq->InformationClass) { diff --git a/reactos/drivers/network/afd/afd/listen.c b/reactos/drivers/network/afd/afd/listen.c index 7e09535e12b..734b440cf65 100644 --- a/reactos/drivers/network/afd/afd/listen.c +++ b/reactos/drivers/network/afd/afd/listen.c @@ -101,6 +101,7 @@ static NTSTATUS NTAPI ListenComplete if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED; + ASSERT(FCB->ListenIrp.InFlightRequest == Irp); FCB->ListenIrp.InFlightRequest = NULL; if( FCB->State == SOCKET_STATE_CLOSED ) { diff --git a/reactos/drivers/network/afd/afd/lock.c b/reactos/drivers/network/afd/afd/lock.c index 55b8fc0f264..09f73615e5a 100644 --- a/reactos/drivers/network/afd/afd/lock.c +++ b/reactos/drivers/network/afd/afd/lock.c @@ -13,49 +13,85 @@ #include "debug.h" #include "pseh/pseh2.h" +PVOID GetLockedData(PIRP Irp, PIO_STACK_LOCATION IrpSp) +{ + ASSERT(Irp->MdlAddress); + + return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); +} + /* Lock a method_neither request so it'll be available from DISPATCH_LEVEL */ PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) { BOOLEAN LockFailed = FALSE; - - ASSERT(IrpSp->Parameters.DeviceIoControl.Type3InputBuffer); - ASSERT(IrpSp->Parameters.DeviceIoControl.InputBufferLength); + ASSERT(!Irp->MdlAddress); + + switch (IrpSp->MajorFunction) + { + case IRP_MJ_DEVICE_CONTROL: + case IRP_MJ_INTERNAL_DEVICE_CONTROL: + ASSERT(IrpSp->Parameters.DeviceIoControl.Type3InputBuffer); + ASSERT(IrpSp->Parameters.DeviceIoControl.InputBufferLength); - Irp->MdlAddress = - IoAllocateMdl( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer, - IrpSp->Parameters.DeviceIoControl.InputBufferLength, - FALSE, - FALSE, - NULL ); - if( Irp->MdlAddress ) { - _SEH2_TRY { - MmProbeAndLockPages( Irp->MdlAddress, Irp->RequestorMode, IoModifyAccess ); - } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - LockFailed = TRUE; - } _SEH2_END; - - if( LockFailed ) { - IoFreeMdl( Irp->MdlAddress ); - Irp->MdlAddress = NULL; - return NULL; - } - - IrpSp->Parameters.DeviceIoControl.Type3InputBuffer = - MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority ); - - if( !IrpSp->Parameters.DeviceIoControl.Type3InputBuffer ) { - MmUnlockPages( Irp->MdlAddress ); - IoFreeMdl( Irp->MdlAddress ); - Irp->MdlAddress = NULL; - return NULL; - } - - return IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; - } else return NULL; + + Irp->MdlAddress = + IoAllocateMdl( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer, + IrpSp->Parameters.DeviceIoControl.InputBufferLength, + FALSE, + FALSE, + NULL ); + if( Irp->MdlAddress ) { + _SEH2_TRY { + MmProbeAndLockPages( Irp->MdlAddress, Irp->RequestorMode, IoModifyAccess ); + } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + LockFailed = TRUE; + } _SEH2_END; + + if( LockFailed ) { + IoFreeMdl( Irp->MdlAddress ); + Irp->MdlAddress = NULL; + return NULL; + } + } else return NULL; + break; + + case IRP_MJ_READ: + case IRP_MJ_WRITE: + ASSERT(Irp->UserBuffer); + + Irp->MdlAddress = + IoAllocateMdl(Irp->UserBuffer, + (IrpSp->MajorFunction == IRP_MJ_READ) ? + IrpSp->Parameters.Read.Length : IrpSp->Parameters.Write.Length, + FALSE, + FALSE, + NULL ); + if( Irp->MdlAddress ) { + _SEH2_TRY { + MmProbeAndLockPages( Irp->MdlAddress, Irp->RequestorMode, IoModifyAccess ); + } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + LockFailed = TRUE; + } _SEH2_END; + + if( LockFailed ) { + IoFreeMdl( Irp->MdlAddress ); + Irp->MdlAddress = NULL; + return NULL; + } + } else return NULL; + break; + + default: + ASSERT(FALSE); + return NULL; + } + + return GetLockedData(Irp, IrpSp); } VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) { + ASSERT(Irp->MdlAddress); MmUnlockPages( Irp->MdlAddress ); IoFreeMdl( Irp->MdlAddress ); Irp->MdlAddress = NULL; @@ -123,7 +159,7 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count, AFD_DbgPrint(MID_TRACE,("Probe and lock pages\n")); _SEH2_TRY { MmProbeAndLockPages( MapBuf[i].Mdl, KernelMode, - Write ? IoReadAccess : IoModifyAccess ); + Write ? IoModifyAccess : IoReadAccess ); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { LockFailed = TRUE; } _SEH2_END; diff --git a/reactos/drivers/network/afd/afd/main.c b/reactos/drivers/network/afd/afd/main.c index bf981e3f542..3002c655d3d 100644 --- a/reactos/drivers/network/afd/afd/main.c +++ b/reactos/drivers/network/afd/afd/main.c @@ -72,10 +72,13 @@ AfdSetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp, { PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; - PVOID DisconnectOptions = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + PVOID DisconnectOptions = LockRequest(Irp, IrpSp); UINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); + + if (!DisconnectOptions) + return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); if (FCB->DisconnectOptions) { @@ -104,10 +107,13 @@ AfdSetDisconnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp, { PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; - PUINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + PUINT DisconnectOptionsSize = LockRequest(Irp, IrpSp); UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); + + if (!DisconnectOptionsSize) + return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); if (BufferSize < sizeof(UINT)) return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0); @@ -158,10 +164,13 @@ AfdSetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp, { PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; - PVOID DisconnectData = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + PVOID DisconnectData = LockRequest(Irp, IrpSp); UINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); + + if (!DisconnectData) + return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); if (FCB->DisconnectData) { @@ -190,10 +199,13 @@ AfdSetDisconnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp, { PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; - PUINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + PUINT DisconnectDataSize = LockRequest(Irp, IrpSp); UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); + + if (!DisconnectDataSize) + return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); if (BufferSize < sizeof(UINT)) return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0); @@ -219,10 +231,13 @@ AfdGetTdiHandles(PDEVICE_OBJECT DeviceObject, PIRP Irp, { PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; - PULONG HandleFlags = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + PULONG HandleFlags = LockRequest(Irp, IrpSp); PAFD_TDI_HANDLE_DATA HandleData = Irp->UserBuffer; if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); + + if (!HandleFlags) + return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG) || IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(*HandleData)) @@ -535,6 +550,12 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, if( !(DisReq = LockRequest( Irp, IrpSp )) ) return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 ); + + if( DisReq->DisconnectType & AFD_DISCONNECT_SEND ) + Flags |= TDI_DISCONNECT_RELEASE; + if( DisReq->DisconnectType & AFD_DISCONNECT_RECV || + DisReq->DisconnectType & AFD_DISCONNECT_ABORT ) + Flags |= TDI_DISCONNECT_ABORT; if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)) { @@ -551,12 +572,6 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); - if( DisReq->DisconnectType & AFD_DISCONNECT_SEND ) - Flags |= TDI_DISCONNECT_RELEASE; - if( DisReq->DisconnectType & AFD_DISCONNECT_RECV || - DisReq->DisconnectType & AFD_DISCONNECT_ABORT ) - Flags |= TDI_DISCONNECT_ABORT; - FCB->ConnectInfo->UserData = FCB->DisconnectData; FCB->ConnectInfo->UserDataLength = FCB->DisconnectDataSize; FCB->ConnectInfo->Options = FCB->DisconnectOptions; @@ -591,11 +606,25 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, ExFreePool( ConnectionReturnInfo ); - FCB->PollState |= AFD_EVENT_DISCONNECT; + if (Flags & TDI_DISCONNECT_RELEASE) + FCB->PollState |= AFD_EVENT_DISCONNECT; + else + FCB->PollState |= AFD_EVENT_ABORT; FCB->PollStatus[FD_CLOSE_BIT] = STATUS_SUCCESS; PollReeval( FCB->DeviceExt, FCB->FileObject ); - } else - Status = STATUS_INVALID_PARAMETER; + } + else + { + if (!(Flags & TDI_DISCONNECT_RELEASE)) + { + if (!FCB->RemoteAddress) + return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0); + + ExFreePool(FCB->RemoteAddress); + + FCB->RemoteAddress = NULL; + } + } return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); } @@ -784,7 +813,7 @@ AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) } VOID -CleanupPendingIrp(PIRP Irp, PIO_STACK_LOCATION IrpSp, PAFD_ACTIVE_POLL Poll) +CleanupPendingIrp(PAFD_FCB FCB, PIRP Irp, PIO_STACK_LOCATION IrpSp, PAFD_ACTIVE_POLL Poll) { PAFD_RECV_INFO RecvReq; PAFD_SEND_INFO SendReq; @@ -793,13 +822,14 @@ CleanupPendingIrp(PIRP Irp, PIO_STACK_LOCATION IrpSp, PAFD_ACTIVE_POLL Poll) if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_RECV || IrpSp->MajorFunction == IRP_MJ_READ) { - RecvReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + RecvReq = GetLockedData(Irp, IrpSp); UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE); } - else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SEND || - IrpSp->MajorFunction == IRP_MJ_WRITE) + else if ((IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SEND || + IrpSp->MajorFunction == IRP_MJ_WRITE) && + !(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)) { - SendReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + SendReq = GetLockedData(Irp, IrpSp); UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); } else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SELECT) @@ -879,7 +909,7 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject, if (Irp == Poll->Irp) { - CleanupPendingIrp(Irp, IrpSp, Poll); + CleanupPendingIrp(FCB, Irp, IrpSp, Poll); KeReleaseSpinLock(&DeviceExt->Lock, OldIrql); SocketStateUnlock(FCB); return; @@ -911,7 +941,7 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject, if (CurrentIrp == Irp) { RemoveEntryList(CurrentEntry); - CleanupPendingIrp(Irp, IrpSp, NULL); + CleanupPendingIrp(FCB, Irp, IrpSp, NULL); UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0); return; } diff --git a/reactos/drivers/network/afd/afd/read.c b/reactos/drivers/network/afd/afd/read.c index 91b20b2390e..728b72434e1 100644 --- a/reactos/drivers/network/afd/afd/read.c +++ b/reactos/drivers/network/afd/afd/read.c @@ -32,7 +32,7 @@ static VOID HandleEOFOnIrp( PAFD_FCB FCB, NTSTATUS Status, ULONG_PTR Information ( !NT_SUCCESS( Status ) ) ) { /* The socket has been closed */ - FCB->PollState |= AFD_EVENT_DISCONNECT; + FCB->PollState |= AFD_EVENT_CLOSE; FCB->PollStatus[FD_CLOSE_BIT] = Status; PollReeval( FCB->DeviceExt, FCB->FileObject ); @@ -43,7 +43,7 @@ static BOOLEAN CantReadMore( PAFD_FCB FCB ) { UINT BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed; return !BytesAvailable && - (FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_DISCONNECT)); + (FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_ABORT)); } static VOID RefillSocketBuffer( PAFD_FCB FCB ) { @@ -60,20 +60,10 @@ static VOID RefillSocketBuffer( PAFD_FCB FCB ) { &FCB->ReceiveIrp.Iosb, ReceiveComplete, FCB ); - - if( Status == STATUS_SUCCESS && FCB->ReceiveIrp.Iosb.Information ) + if (Status != STATUS_PENDING) { - FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information; - FCB->PollState |= AFD_EVENT_RECEIVE; - FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS; - - PollReeval( FCB->DeviceExt, FCB->FileObject ); + HandleEOFOnIrp(FCB, Status, FCB->ReceiveIrp.Iosb.Information); } - else - { - /* Check for EOF */ - HandleEOFOnIrp(FCB, Status, FCB->ReceiveIrp.Iosb.Information); - } } } @@ -166,7 +156,7 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) { NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); - RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + RecvReq = GetLockedData(NextIrp, NextIrpSp); AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp, TotalBytesCopied)); @@ -196,7 +186,7 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) { NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); - RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + RecvReq = GetLockedData(NextIrp, NextIrpSp); AFD_DbgPrint(MID_TRACE,("RecvReq @ %x\n", RecvReq)); @@ -226,7 +216,7 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) { } } - if( FCB->Recv.Content ) { + if( FCB->Recv.Content - FCB->Recv.BytesUsed ) { FCB->PollState |= AFD_EVENT_RECEIVE; FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS; PollReeval( FCB->DeviceExt, FCB->FileObject ); @@ -259,6 +249,7 @@ NTSTATUS NTAPI ReceiveComplete if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED; + ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp); FCB->ReceiveIrp.InFlightRequest = NULL; FCB->Recv.Content = Irp->IoStatus.Information; @@ -271,7 +262,7 @@ NTSTATUS NTAPI ReceiveComplete NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrpSp = IoGetCurrentIrpStackLocation(NextIrp); - RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + RecvReq = GetLockedData(NextIrp, NextIrpSp); NextIrp->IoStatus.Status = STATUS_FILE_CLOSED; NextIrp->IoStatus.Information = 0; UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE); @@ -378,7 +369,7 @@ SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp, NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); PAFD_RECV_INFO RecvReq = - IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + GetLockedData(Irp, IrpSp); UINT BytesToCopy = 0, BytesAvailable = DatagramRecv->Len, AddrLen = 0; PAFD_MAPBUF Map; @@ -438,26 +429,23 @@ SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp, Map[0].BufferAddress, BytesToCopy)); - /* OskitDumpBuffer - ( FCB->Recv.Window + FCB->Recv.BytesUsed, BytesToCopy ); */ - RtlCopyMemory( Map[0].BufferAddress, - FCB->Recv.Window + FCB->Recv.BytesUsed, + DatagramRecv->Buffer, BytesToCopy ); MmUnmapLockedPages( Map[0].BufferAddress, Map[0].Mdl ); *TotalBytesCopied = BytesToCopy; - - if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK)) { - FCB->Recv.BytesUsed = 0; - } } Status = Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = BytesToCopy; - ExFreePool( DatagramRecv->Address ); - ExFreePool( DatagramRecv ); + + if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK)) + { + ExFreePool( DatagramRecv->Address ); + ExFreePool( DatagramRecv ); + } AFD_DbgPrint(MID_TRACE,("Done\n")); @@ -484,6 +472,7 @@ PacketSocketRecvComplete( if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED; + ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp); FCB->ReceiveIrp.InFlightRequest = NULL; if( FCB->State == SOCKET_STATE_CLOSED ) { @@ -492,7 +481,7 @@ PacketSocketRecvComplete( NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); - RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + RecvReq = GetLockedData(NextIrp, NextIrpSp); NextIrp->IoStatus.Status = STATUS_FILE_CLOSED; NextIrp->IoStatus.Information = 0; UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE); @@ -512,6 +501,12 @@ PacketSocketRecvComplete( SocketStateUnlock( FCB ); return STATUS_FILE_CLOSED; } + + if (Irp->IoStatus.Status != STATUS_SUCCESS) + { + SocketStateUnlock(FCB); + return Irp->IoStatus.Status; + } DatagramRecv = ExAllocatePool( NonPagedPool, DGSize ); @@ -547,7 +542,7 @@ PacketSocketRecvComplete( ListEntry = RemoveHeadList( &FCB->PendingIrpList[FUNCTION_RECV] ); NextIrp = CONTAINING_RECORD( ListEntry, IRP, Tail.Overlay.ListEntry ); NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); - RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + RecvReq = GetLockedData(NextIrp, NextIrpSp); AFD_DbgPrint(MID_TRACE,("RecvReq: %x, DatagramRecv: %x\n", RecvReq, DatagramRecv)); @@ -567,6 +562,11 @@ PacketSocketRecvComplete( Status = SatisfyPacketRecvRequest ( FCB, NextIrp, DatagramRecv, (PUINT)&NextIrp->IoStatus.Information ); + if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK) + { + InsertHeadList(&FCB->DatagramList, + &DatagramRecv->ListEntry); + } AFD_DbgPrint(MID_TRACE,("Unlocking\n")); UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE ); if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); @@ -664,6 +664,12 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, Status = SatisfyPacketRecvRequest ( FCB, Irp, DatagramRecv, (PUINT)&Irp->IoStatus.Information ); + + if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK) + { + InsertHeadList(&FCB->DatagramList, + &DatagramRecv->ListEntry); + } if( !IsListEmpty( &FCB->DatagramList ) ) { FCB->PollState |= AFD_EVENT_RECEIVE; diff --git a/reactos/drivers/network/afd/afd/tdi.c b/reactos/drivers/network/afd/afd/tdi.c index 10ad6660cbf..8443b39136a 100644 --- a/reactos/drivers/network/afd/afd/tdi.c +++ b/reactos/drivers/network/afd/afd/tdi.c @@ -328,17 +328,17 @@ NTSTATUS TdiConnect( NTSTATUS Status; AFD_DbgPrint(MAX_TRACE, ("Called\n")); + + ASSERT(*Irp == NULL); if (!ConnectionObject) { AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n")); - *Irp = NULL; return STATUS_INVALID_PARAMETER; } DeviceObject = IoGetRelatedDeviceObject(ConnectionObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); - *Irp = NULL; return STATUS_INVALID_PARAMETER; } @@ -492,17 +492,17 @@ NTSTATUS TdiListen NTSTATUS Status; AFD_DbgPrint(MAX_TRACE, ("Called\n")); + + ASSERT(*Irp == NULL); if (!ConnectionObject) { AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n")); - *Irp = NULL; return STATUS_INVALID_PARAMETER; } DeviceObject = IoGetRelatedDeviceObject(ConnectionObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); - *Irp = NULL; return STATUS_INVALID_PARAMETER; } @@ -899,17 +899,17 @@ NTSTATUS TdiSend PDEVICE_OBJECT DeviceObject; NTSTATUS Status = STATUS_SUCCESS; PMDL Mdl; + + ASSERT(*Irp == NULL); if (!TransportObject) { AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n")); - *Irp = NULL; return STATUS_INVALID_PARAMETER; } DeviceObject = IoGetRelatedDeviceObject(TransportObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); - *Irp = NULL; return STATUS_INVALID_PARAMETER; } @@ -980,17 +980,17 @@ NTSTATUS TdiReceive( NTSTATUS Status = STATUS_SUCCESS; PDEVICE_OBJECT DeviceObject; PMDL Mdl; + + ASSERT(*Irp == NULL); if (!TransportObject) { AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n")); - *Irp = NULL; return STATUS_INVALID_PARAMETER; } DeviceObject = IoGetRelatedDeviceObject(TransportObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); - *Irp = NULL; return STATUS_INVALID_PARAMETER; } @@ -1080,17 +1080,17 @@ NTSTATUS TdiReceiveDatagram( PDEVICE_OBJECT DeviceObject; NTSTATUS Status; PMDL Mdl; + + ASSERT(*Irp == NULL); if (!TransportObject) { AFD_DbgPrint(MIN_TRACE, ("Bad tranport object.\n")); - *Irp = NULL; return STATUS_INVALID_PARAMETER; } DeviceObject = IoGetRelatedDeviceObject(TransportObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); - *Irp = NULL; return STATUS_INVALID_PARAMETER; } @@ -1176,10 +1176,11 @@ NTSTATUS TdiSendDatagram( PDEVICE_OBJECT DeviceObject; NTSTATUS Status; PMDL Mdl; + + ASSERT(*Irp == NULL); if (!TransportObject) { AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n")); - *Irp = NULL; return STATUS_INVALID_PARAMETER; } @@ -1188,7 +1189,6 @@ NTSTATUS TdiSendDatagram( DeviceObject = IoGetRelatedDeviceObject(TransportObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); - *Irp = NULL; return STATUS_INVALID_PARAMETER; } diff --git a/reactos/drivers/network/afd/afd/write.c b/reactos/drivers/network/afd/afd/write.c index e10b386ba7e..961df02ae1b 100644 --- a/reactos/drivers/network/afd/afd/write.c +++ b/reactos/drivers/network/afd/afd/write.c @@ -23,7 +23,7 @@ static NTSTATUS NTAPI SendComplete PIO_STACK_LOCATION NextIrpSp; PAFD_SEND_INFO SendReq = NULL; PAFD_MAPBUF Map; - UINT TotalBytesCopied = 0, SpaceAvail, i, CopySize = 0; + UINT TotalBytesCopied = 0, SpaceAvail, i; /* * The Irp parameter passed in is the IRP of the stream between AFD and @@ -41,6 +41,7 @@ static NTSTATUS NTAPI SendComplete if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED; + ASSERT(FCB->SendIrp.InFlightRequest == Irp); FCB->SendIrp.InFlightRequest = NULL; /* Request is not in flight any longer */ @@ -50,7 +51,7 @@ static NTSTATUS NTAPI SendComplete NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); - SendReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + SendReq = GetLockedData(NextIrp, NextIrpSp); NextIrp->IoStatus.Status = STATUS_FILE_CLOSED; NextIrp->IoStatus.Information = 0; UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); @@ -71,7 +72,7 @@ static NTSTATUS NTAPI SendComplete NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); - SendReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + SendReq = GetLockedData(NextIrp, NextIrpSp); UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, @@ -95,37 +96,60 @@ static NTSTATUS NTAPI SendComplete FCB->Send.BytesUsed - Irp->IoStatus.Information ); FCB->Send.BytesUsed -= Irp->IoStatus.Information; - if( !FCB->Send.BytesUsed && - !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) { + while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) { NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); - SendReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + SendReq = GetLockedData(NextIrp, NextIrpSp); Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount); AFD_DbgPrint(MID_TRACE,("SendReq @ %x\n", SendReq)); SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed; + TotalBytesCopied = 0; for( i = 0; i < SendReq->BufferCount; i++ ) { + if (SpaceAvail < SendReq->BufferArray[i].len) + { + InsertHeadList(&FCB->PendingIrpList[FUNCTION_SEND], + &NextIrp->Tail.Overlay.ListEntry); + NextIrp = NULL; + break; + } Map[i].BufferAddress = MmMapLockedPages( Map[i].Mdl, KernelMode ); - CopySize = MIN( SpaceAvail, - SendReq->BufferArray[i].len ); - RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed, Map[i].BufferAddress, - CopySize ); + SendReq->BufferArray[i].len ); MmUnmapLockedPages( Map[i].BufferAddress, Map[i].Mdl ); - FCB->Send.BytesUsed += CopySize; - TotalBytesCopied += CopySize; - SpaceAvail -= CopySize; + TotalBytesCopied += SendReq->BufferArray[i].len; + SpaceAvail -= SendReq->BufferArray[i].len; } + + if (NextIrp != NULL) + { + FCB->Send.BytesUsed += TotalBytesCopied; + + NextIrp->IoStatus.Status = STATUS_SUCCESS; + NextIrp->IoStatus.Information = TotalBytesCopied; + + (void)IoSetCancelRoutine(NextIrp, NULL); + + UnlockBuffers( SendReq->BufferArray, + SendReq->BufferCount, + FALSE ); + + if (NextIrp->MdlAddress) UnlockRequest(NextIrp, NextIrpSp); + + IoCompleteRequest(NextIrp, IO_NETWORK_INCREMENT); + } + else + break; } /* Some data is still waiting */ @@ -146,22 +170,6 @@ static NTSTATUS NTAPI SendComplete PollReeval( FCB->DeviceExt, FCB->FileObject ); } - if( TotalBytesCopied > 0 ) { - UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); - - if( Status == STATUS_PENDING ) - Status = STATUS_SUCCESS; - - AFD_DbgPrint(MID_TRACE,("Dismissing request: %x\n", Status)); - - return UnlockAndMaybeComplete( FCB, Status, NextIrp, TotalBytesCopied ); - } else if( NextIrp ) { - AFD_DbgPrint(MID_TRACE,("Could not do any more with Irp %x\n", - NextIrp)); - InsertHeadList( &FCB->PendingIrpList[FUNCTION_SEND], - &NextIrp->Tail.Overlay.ListEntry ); - } - SocketStateUnlock( FCB ); return STATUS_SUCCESS; @@ -182,6 +190,7 @@ static NTSTATUS NTAPI PacketSocketSendComplete if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED; + ASSERT(FCB->SendIrp.InFlightRequest == Irp); FCB->SendIrp.InFlightRequest = NULL; /* Request is not in flight any longer */ @@ -220,8 +229,8 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_FCB FCB = FileObject->FsContext; PAFD_SEND_INFO SendReq; ULONG Information; - UINT TotalBytesCopied = 0, i, CopySize = 0, - SpaceAvail = 0, TotalBytesEncountered = 0; + UINT TotalBytesCopied = 0, i, SpaceAvail = 0; + BOOLEAN NoSpace = FALSE; AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); @@ -309,76 +318,87 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, AFD_DbgPrint(MID_TRACE,("FCB->Send.BytesUsed = %d\n", FCB->Send.BytesUsed)); - if( !FCB->Send.BytesUsed ) { - SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed; - - AFD_DbgPrint(MID_TRACE,("We can accept %d bytes\n", - SpaceAvail)); - - for( i = 0; FCB->Send.BytesUsed < FCB->Send.Size && - i < SendReq->BufferCount; i++ ) { - CopySize = MIN( SpaceAvail, - SendReq->BufferArray[i].len ); - - TotalBytesEncountered += SendReq->BufferArray[i].len; - - AFD_DbgPrint(MID_TRACE,("Copying Buffer %d, %x:%d to %x\n", - i, - SendReq->BufferArray[i].buf, - CopySize, - FCB->Send.Window + FCB->Send.BytesUsed)); - - RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed, - SendReq->BufferArray[i].buf, - CopySize ); - - FCB->Send.BytesUsed += CopySize; - TotalBytesCopied += CopySize; - SpaceAvail -= CopySize; - } - - if( TotalBytesEncountered == 0 ) { - UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); - - AFD_DbgPrint(MID_TRACE,("Empty send\n")); - return UnlockAndMaybeComplete - ( FCB, Status, Irp, TotalBytesCopied ); - } - - AFD_DbgPrint(MID_TRACE,("Completed %d bytes\n", TotalBytesCopied)); - - if( TotalBytesCopied > 0 ) { - UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); - - Status = TdiSend( &FCB->SendIrp.InFlightRequest, - FCB->Connection.Object, - 0, - FCB->Send.Window, - FCB->Send.BytesUsed, - &FCB->SendIrp.Iosb, - SendComplete, - FCB ); - - if( Status == STATUS_PENDING ) - Status = STATUS_SUCCESS; - - AFD_DbgPrint(MID_TRACE,("Dismissing request: %x (%d)\n", - Status, TotalBytesCopied)); - - return UnlockAndMaybeComplete - ( FCB, Status, Irp, TotalBytesCopied ); - } + SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed; + + AFD_DbgPrint(MID_TRACE,("We can accept %d bytes\n", + SpaceAvail)); + + for( i = 0; FCB->Send.BytesUsed < FCB->Send.Size && + i < SendReq->BufferCount; i++ ) { + + if (SpaceAvail < SendReq->BufferArray[i].len) + { + if (FCB->Send.BytesUsed + TotalBytesCopied + + SendReq->BufferArray[i].len > FCB->Send.Size) + { + UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); + + return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_OVERFLOW, Irp, 0); + } + NoSpace = TRUE; + break; + } + + AFD_DbgPrint(MID_TRACE,("Copying Buffer %d, %x:%d to %x\n", + i, + SendReq->BufferArray[i].buf, + SendReq->BufferArray[i].len, + FCB->Send.Window + FCB->Send.BytesUsed)); + + RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed, + SendReq->BufferArray[i].buf, + SendReq->BufferArray[i].len ); + + TotalBytesCopied += SendReq->BufferArray[i].len; + SpaceAvail -= SendReq->BufferArray[i].len; } - - if( SendReq->AfdFlags & AFD_IMMEDIATE ) { - AFD_DbgPrint(MID_TRACE,("Nonblocking\n")); - UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); - return UnlockAndMaybeComplete + + if( TotalBytesCopied == 0 ) { + AFD_DbgPrint(MID_TRACE,("Empty send\n")); + UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); + return UnlockAndMaybeComplete + ( FCB, STATUS_SUCCESS, Irp, TotalBytesCopied ); + } + + if (!NoSpace) + { + UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); + FCB->Send.BytesUsed += TotalBytesCopied; + AFD_DbgPrint(MID_TRACE,("Completed %d bytes\n", TotalBytesCopied)); + } + else + { + if( SendReq->AfdFlags & AFD_IMMEDIATE ) { + AFD_DbgPrint(MID_TRACE,("Nonblocking\n")); + UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); + return UnlockAndMaybeComplete ( FCB, STATUS_CANT_WAIT, Irp, 0 ); - } else { - AFD_DbgPrint(MID_TRACE,("Queuing request\n")); - return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND ); + } else { + AFD_DbgPrint(MID_TRACE,("Queuing request\n")); + return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND ); + } } + + if (!FCB->SendIrp.InFlightRequest) + { + Status = TdiSend( &FCB->SendIrp.InFlightRequest, + FCB->Connection.Object, + 0, + FCB->Send.Window, + FCB->Send.BytesUsed, + &FCB->SendIrp.Iosb, + SendComplete, + FCB ); + + if( Status == STATUS_PENDING ) + Status = STATUS_SUCCESS; + + AFD_DbgPrint(MID_TRACE,("Dismissing request: %x (%d)\n", + Status, TotalBytesCopied)); + } + + return UnlockAndMaybeComplete + ( FCB, Status, Irp, TotalBytesCopied ); } NTSTATUS NTAPI @@ -396,12 +416,32 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); /* Check that the socket is bound */ - if( FCB->State != SOCKET_STATE_BOUND ) + if( FCB->State != SOCKET_STATE_BOUND && + FCB->State != SOCKET_STATE_CREATED) return UnlockAndMaybeComplete ( FCB, STATUS_INVALID_PARAMETER, Irp, 0 ); if( !(SendReq = LockRequest( Irp, IrpSp )) ) return UnlockAndMaybeComplete ( FCB, STATUS_NO_MEMORY, Irp, 0 ); + + if (FCB->State == SOCKET_STATE_CREATED) + { + if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress ); + FCB->LocalAddress = + TaBuildNullTransportAddress( ((PTRANSPORT_ADDRESS)SendReq->TdiConnection.RemoteAddress)-> + Address[0].AddressType ); + + if( FCB->LocalAddress ) { + Status = WarmSocketForBind( FCB ); + + if( NT_SUCCESS(Status) ) + FCB->State = SOCKET_STATE_BOUND; + else + return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); + } else + return UnlockAndMaybeComplete + ( FCB, STATUS_NO_MEMORY, Irp, 0 ); + } SendReq->BufferArray = LockBuffers( SendReq->BufferArray, SendReq->BufferCount, diff --git a/reactos/drivers/network/afd/include/afd.h b/reactos/drivers/network/afd/include/afd.h index 5eb882d2908..0780cf975ee 100644 --- a/reactos/drivers/network/afd/include/afd.h +++ b/reactos/drivers/network/afd/include/afd.h @@ -300,6 +300,7 @@ 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 ); +PVOID GetLockedData( PIRP Irp, PIO_STACK_LOCATION IrpSp ); /* main.c */