mirror of
https://github.com/reactos/reactos.git
synced 2024-06-15 17:11:52 +00:00
[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 svn path=/trunk/; revision=52186
This commit is contained in:
parent
a7abbd0f7e
commit
dcf65c0e08
|
@ -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 ) {
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in a new issue