Author: cgutman
Date: Sat Jun 11 12:46:04 2011
New Revision: 52186
URL:
http://svn.reactos.org/svn/reactos?rev=52186&view=rev
Log:
[AFD]
- Rewrite user-mode request locking to fix several bugs
- IRP_MJ_READ and IRP_MJ_WRITE doesn't crash
- Revert the IoModifyAccess change (the Write parameter was relevant to the buffer not the
request)
- Use GetLockedData to retrieve a locked buffer instead of accessing it manually
- Lock several requests which were not locked and could cause a crash
- ASSERT that the in flight request is the IRP being completed
- Fix a socket closure bug so shutdown(SO_SEND) will not prevent packets being received
- Don't count bytes used in the receive content
- Don't free the datagram buffer if it is a peek request
- Requeue the datagram buffer at the head of the list if it is a peek request
- Fix a bug which could cause corrupted data to be received if multiple datagrams come in
before the app receives them
- Make sure that we're not overwriting an existing in flight request when creating a
new one
- Perform an implicit bind in AfdPacketSocketWriteData if it is not already bound
- Implement batching several user-mode send IRPs into one TDI request (if there is already
one pending)
- Fix a potential crash if a connectionless send IRP is cancelled
Modified:
trunk/reactos/drivers/network/afd/afd/connect.c
trunk/reactos/drivers/network/afd/afd/context.c
trunk/reactos/drivers/network/afd/afd/info.c
trunk/reactos/drivers/network/afd/afd/listen.c
trunk/reactos/drivers/network/afd/afd/lock.c
trunk/reactos/drivers/network/afd/afd/main.c
trunk/reactos/drivers/network/afd/afd/read.c
trunk/reactos/drivers/network/afd/afd/tdi.c
trunk/reactos/drivers/network/afd/afd/write.c
trunk/reactos/drivers/network/afd/include/afd.h
Modified: trunk/reactos/drivers/network/afd/afd/connect.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/co…
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/connect.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/connect.c [iso-8859-1] Sat Jun 11 12:46:04 2011
@@ -43,10 +43,13 @@
{
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 @@
{
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 @@
{
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 @@
{
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 @@
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 ) {
Modified: trunk/reactos/drivers/network/afd/afd/context.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/co…
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/context.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/context.c [iso-8859-1] Sat Jun 11 12:46:04 2011
@@ -54,14 +54,18 @@
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 @@
FCB->ContextSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
RtlCopyMemory( FCB->Context,
- IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
+ Context,
FCB->ContextSize );
return UnlockAndMaybeComplete( FCB, STATUS_SUCCESS, Irp, 0 );
Modified: trunk/reactos/drivers/network/afd/afd/info.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/in…
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/info.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/info.c [iso-8859-1] Sat Jun 11 12:46:04 2011
@@ -17,7 +17,7 @@
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 @@
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 @@
CurrentEntry = CurrentEntry->Flink;
}
- /* Count the send in progress */
- if (FCB->SendIrp.InFlightRequest)
- InfoReq->Information.Ulong++;
-
break;
default:
@@ -93,11 +92,14 @@
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) {
Modified: trunk/reactos/drivers/network/afd/afd/listen.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/li…
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/listen.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/listen.c [iso-8859-1] Sat Jun 11 12:46:04 2011
@@ -101,6 +101,7 @@
if( !SocketAcquireStateLock( FCB ) )
return STATUS_FILE_CLOSED;
+ ASSERT(FCB->ListenIrp.InFlightRequest == Irp);
FCB->ListenIrp.InFlightRequest = NULL;
if( FCB->State == SOCKET_STATE_CLOSED ) {
Modified: trunk/reactos/drivers/network/afd/afd/lock.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/lo…
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/lock.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/lock.c [iso-8859-1] Sat Jun 11 12:46:04 2011
@@ -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);
-
- 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;
+
+ 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;
+ }
+ } 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 @@
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;
Modified: trunk/reactos/drivers/network/afd/afd/main.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/ma…
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/main.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/main.c [iso-8859-1] Sat Jun 11 12:46:04 2011
@@ -72,10 +72,13 @@
{
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 @@
{
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 @@
{
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 @@
{
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 @@
{
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 @@
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))
{
@@ -550,12 +571,6 @@
if( !NT_SUCCESS(Status) )
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;
@@ -591,11 +606,25 @@
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 @@
}
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 @@
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)
- {
- SendReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+ else if ((IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SEND ||
+ IrpSp->MajorFunction == IRP_MJ_WRITE) &&
+ !(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
+ {
+ SendReq = GetLockedData(Irp, IrpSp);
UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
}
else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SELECT)
@@ -879,7 +909,7 @@
if (Irp == Poll->Irp)
{
- CleanupPendingIrp(Irp, IrpSp, Poll);
+ CleanupPendingIrp(FCB, Irp, IrpSp, Poll);
KeReleaseSpinLock(&DeviceExt->Lock, OldIrql);
SocketStateUnlock(FCB);
return;
@@ -911,7 +941,7 @@
if (CurrentIrp == Irp)
{
RemoveEntryList(CurrentEntry);
- CleanupPendingIrp(Irp, IrpSp, NULL);
+ CleanupPendingIrp(FCB, Irp, IrpSp, NULL);
UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0);
return;
}
Modified: trunk/reactos/drivers/network/afd/afd/read.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/re…
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/read.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/read.c [iso-8859-1] Sat Jun 11 12:46:04 2011
@@ -32,7 +32,7 @@
( !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 @@
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 @@
&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 @@
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 @@
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 @@
}
}
- 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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);
@@ -511,6 +500,12 @@
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 @@
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 @@
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 @@
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;
Modified: trunk/reactos/drivers/network/afd/afd/tdi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/td…
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/tdi.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/tdi.c [iso-8859-1] Sat Jun 11 12:46:04 2011
@@ -328,17 +328,17 @@
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 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 @@
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 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 @@
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 @@
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 @@
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
if (!DeviceObject) {
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
- *Irp = NULL;
return STATUS_INVALID_PARAMETER;
}
Modified: trunk/reactos/drivers/network/afd/afd/write.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/wr…
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/write.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/write.c [iso-8859-1] Sat Jun 11 12:46:04 2011
@@ -23,7 +23,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 );
- }
- }
-
- if( SendReq->AfdFlags & AFD_IMMEDIATE ) {
- AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
- UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
- return UnlockAndMaybeComplete
+ 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( 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 @@
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,
Modified: trunk/reactos/drivers/network/afd/include/afd.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/includ…
==============================================================================
--- trunk/reactos/drivers/network/afd/include/afd.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/include/afd.h [iso-8859-1] Sat Jun 11 12:46:04 2011
@@ -300,6 +300,7 @@
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 */