mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 05:26:58 +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,11 +43,14 @@ AfdSetConnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = FileObject->FsContext;
|
||||||
PVOID ConnectOptions = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
PVOID ConnectOptions = LockRequest(Irp, IrpSp);
|
||||||
UINT ConnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
UINT ConnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
||||||
|
|
||||||
|
if (!ConnectOptions)
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
if (FCB->ConnectOptions)
|
if (FCB->ConnectOptions)
|
||||||
{
|
{
|
||||||
ExFreePool(FCB->ConnectOptions);
|
ExFreePool(FCB->ConnectOptions);
|
||||||
|
@ -75,11 +78,14 @@ AfdSetConnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = FileObject->FsContext;
|
||||||
PUINT ConnectOptionsSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
PUINT ConnectOptionsSize = LockRequest(Irp, IrpSp);
|
||||||
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
||||||
|
|
||||||
|
if (!ConnectOptionsSize)
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
if (BufferSize < sizeof(UINT))
|
if (BufferSize < sizeof(UINT))
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
|
||||||
|
|
||||||
|
@ -129,11 +135,14 @@ AfdSetConnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = FileObject->FsContext;
|
||||||
PVOID ConnectData = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
PVOID ConnectData = LockRequest(Irp, IrpSp);
|
||||||
UINT ConnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
UINT ConnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
||||||
|
|
||||||
|
if (!ConnectData)
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
if (FCB->ConnectData)
|
if (FCB->ConnectData)
|
||||||
{
|
{
|
||||||
ExFreePool(FCB->ConnectData);
|
ExFreePool(FCB->ConnectData);
|
||||||
|
@ -161,11 +170,14 @@ AfdSetConnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = FileObject->FsContext;
|
||||||
PUINT ConnectDataSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
PUINT ConnectDataSize = LockRequest(Irp, IrpSp);
|
||||||
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
||||||
|
|
||||||
|
if (!ConnectDataSize)
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
if (BufferSize < sizeof(UINT))
|
if (BufferSize < sizeof(UINT))
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
|
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",
|
AFD_DbgPrint(MID_TRACE,("Irp->IoStatus.Status = %x\n",
|
||||||
Irp->IoStatus.Status));
|
Irp->IoStatus.Status));
|
||||||
|
|
||||||
|
ASSERT(FCB->ConnectIrp.InFlightRequest == Irp);
|
||||||
FCB->ConnectIrp.InFlightRequest = NULL;
|
FCB->ConnectIrp.InFlightRequest = NULL;
|
||||||
|
|
||||||
if( FCB->State == SOCKET_STATE_CLOSED ) {
|
if( FCB->State == SOCKET_STATE_CLOSED ) {
|
||||||
|
|
|
@ -60,9 +60,13 @@ AfdSetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp ) {
|
PIO_STACK_LOCATION IrpSp ) {
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = FileObject->FsContext;
|
||||||
|
PVOID Context = LockRequest(Irp, IrpSp);
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
||||||
|
|
||||||
|
if (!Context)
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
if( FCB->Context ) {
|
if( FCB->Context ) {
|
||||||
ExFreePool( FCB->Context );
|
ExFreePool( FCB->Context );
|
||||||
FCB->ContextSize = 0;
|
FCB->ContextSize = 0;
|
||||||
|
@ -76,7 +80,7 @@ AfdSetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
FCB->ContextSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
FCB->ContextSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
RtlCopyMemory( FCB->Context,
|
RtlCopyMemory( FCB->Context,
|
||||||
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
|
Context,
|
||||||
FCB->ContextSize );
|
FCB->ContextSize );
|
||||||
|
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_SUCCESS, Irp, 0 );
|
return UnlockAndMaybeComplete( FCB, STATUS_SUCCESS, Irp, 0 );
|
||||||
|
|
|
@ -17,7 +17,7 @@ NTSTATUS NTAPI
|
||||||
AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp ) {
|
PIO_STACK_LOCATION IrpSp ) {
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PAFD_INFO InfoReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
PAFD_INFO InfoReq = LockRequest(Irp, IrpSp);
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = FileObject->FsContext;
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
@ -27,6 +27,9 @@ AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
||||||
|
|
||||||
|
if (!InfoReq)
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
_SEH2_TRY {
|
_SEH2_TRY {
|
||||||
switch( InfoReq->InformationClass ) {
|
switch( InfoReq->InformationClass ) {
|
||||||
case AFD_INFO_RECEIVE_WINDOW_SIZE:
|
case AFD_INFO_RECEIVE_WINDOW_SIZE:
|
||||||
|
@ -67,10 +70,6 @@ AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
CurrentEntry = CurrentEntry->Flink;
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Count the send in progress */
|
|
||||||
if (FCB->SendIrp.InFlightRequest)
|
|
||||||
InfoReq->Information.Ulong++;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -93,12 +92,15 @@ NTSTATUS NTAPI
|
||||||
AfdSetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
AfdSetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp ) {
|
PIO_STACK_LOCATION IrpSp ) {
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PAFD_INFO InfoReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
PAFD_INFO InfoReq = LockRequest(Irp, IrpSp);
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = FileObject->FsContext;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
||||||
|
|
||||||
|
if (!InfoReq)
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
_SEH2_TRY {
|
_SEH2_TRY {
|
||||||
switch (InfoReq->InformationClass) {
|
switch (InfoReq->InformationClass) {
|
||||||
case AFD_INFO_BLOCKING_MODE:
|
case AFD_INFO_BLOCKING_MODE:
|
||||||
|
|
|
@ -101,6 +101,7 @@ static NTSTATUS NTAPI ListenComplete
|
||||||
if( !SocketAcquireStateLock( FCB ) )
|
if( !SocketAcquireStateLock( FCB ) )
|
||||||
return STATUS_FILE_CLOSED;
|
return STATUS_FILE_CLOSED;
|
||||||
|
|
||||||
|
ASSERT(FCB->ListenIrp.InFlightRequest == Irp);
|
||||||
FCB->ListenIrp.InFlightRequest = NULL;
|
FCB->ListenIrp.InFlightRequest = NULL;
|
||||||
|
|
||||||
if( FCB->State == SOCKET_STATE_CLOSED ) {
|
if( FCB->State == SOCKET_STATE_CLOSED ) {
|
||||||
|
|
|
@ -13,13 +13,26 @@
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "pseh/pseh2.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 */
|
/* Lock a method_neither request so it'll be available from DISPATCH_LEVEL */
|
||||||
PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
|
PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
|
||||||
BOOLEAN LockFailed = FALSE;
|
BOOLEAN LockFailed = FALSE;
|
||||||
|
|
||||||
|
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.Type3InputBuffer);
|
||||||
ASSERT(IrpSp->Parameters.DeviceIoControl.InputBufferLength);
|
ASSERT(IrpSp->Parameters.DeviceIoControl.InputBufferLength);
|
||||||
ASSERT(!Irp->MdlAddress);
|
|
||||||
|
|
||||||
Irp->MdlAddress =
|
Irp->MdlAddress =
|
||||||
IoAllocateMdl( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
|
IoAllocateMdl( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
|
||||||
|
@ -39,23 +52,46 @@ PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
|
||||||
Irp->MdlAddress = NULL;
|
Irp->MdlAddress = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
} else return NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer =
|
case IRP_MJ_READ:
|
||||||
MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
|
case IRP_MJ_WRITE:
|
||||||
|
ASSERT(Irp->UserBuffer);
|
||||||
|
|
||||||
if( !IrpSp->Parameters.DeviceIoControl.Type3InputBuffer ) {
|
Irp->MdlAddress =
|
||||||
MmUnlockPages( 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 );
|
IoFreeMdl( Irp->MdlAddress );
|
||||||
Irp->MdlAddress = NULL;
|
Irp->MdlAddress = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
|
||||||
} else return NULL;
|
} else return NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetLockedData(Irp, IrpSp);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp )
|
VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp )
|
||||||
{
|
{
|
||||||
|
ASSERT(Irp->MdlAddress);
|
||||||
MmUnlockPages( Irp->MdlAddress );
|
MmUnlockPages( Irp->MdlAddress );
|
||||||
IoFreeMdl( Irp->MdlAddress );
|
IoFreeMdl( Irp->MdlAddress );
|
||||||
Irp->MdlAddress = NULL;
|
Irp->MdlAddress = NULL;
|
||||||
|
@ -123,7 +159,7 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count,
|
||||||
AFD_DbgPrint(MID_TRACE,("Probe and lock pages\n"));
|
AFD_DbgPrint(MID_TRACE,("Probe and lock pages\n"));
|
||||||
_SEH2_TRY {
|
_SEH2_TRY {
|
||||||
MmProbeAndLockPages( MapBuf[i].Mdl, KernelMode,
|
MmProbeAndLockPages( MapBuf[i].Mdl, KernelMode,
|
||||||
Write ? IoReadAccess : IoModifyAccess );
|
Write ? IoModifyAccess : IoReadAccess );
|
||||||
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
|
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
|
||||||
LockFailed = TRUE;
|
LockFailed = TRUE;
|
||||||
} _SEH2_END;
|
} _SEH2_END;
|
||||||
|
|
|
@ -72,11 +72,14 @@ AfdSetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = FileObject->FsContext;
|
||||||
PVOID DisconnectOptions = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
PVOID DisconnectOptions = LockRequest(Irp, IrpSp);
|
||||||
UINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
UINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
||||||
|
|
||||||
|
if (!DisconnectOptions)
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
if (FCB->DisconnectOptions)
|
if (FCB->DisconnectOptions)
|
||||||
{
|
{
|
||||||
ExFreePool(FCB->DisconnectOptions);
|
ExFreePool(FCB->DisconnectOptions);
|
||||||
|
@ -104,11 +107,14 @@ AfdSetDisconnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = FileObject->FsContext;
|
||||||
PUINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
PUINT DisconnectOptionsSize = LockRequest(Irp, IrpSp);
|
||||||
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
||||||
|
|
||||||
|
if (!DisconnectOptionsSize)
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
if (BufferSize < sizeof(UINT))
|
if (BufferSize < sizeof(UINT))
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
|
||||||
|
|
||||||
|
@ -158,11 +164,14 @@ AfdSetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = FileObject->FsContext;
|
||||||
PVOID DisconnectData = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
PVOID DisconnectData = LockRequest(Irp, IrpSp);
|
||||||
UINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
UINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
||||||
|
|
||||||
|
if (!DisconnectData)
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
if (FCB->DisconnectData)
|
if (FCB->DisconnectData)
|
||||||
{
|
{
|
||||||
ExFreePool(FCB->DisconnectData);
|
ExFreePool(FCB->DisconnectData);
|
||||||
|
@ -190,11 +199,14 @@ AfdSetDisconnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = FileObject->FsContext;
|
||||||
PUINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
PUINT DisconnectDataSize = LockRequest(Irp, IrpSp);
|
||||||
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
||||||
|
|
||||||
|
if (!DisconnectDataSize)
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
if (BufferSize < sizeof(UINT))
|
if (BufferSize < sizeof(UINT))
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
|
||||||
|
|
||||||
|
@ -219,11 +231,14 @@ AfdGetTdiHandles(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = FileObject->FsContext;
|
||||||
PULONG HandleFlags = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
PULONG HandleFlags = LockRequest(Irp, IrpSp);
|
||||||
PAFD_TDI_HANDLE_DATA HandleData = Irp->UserBuffer;
|
PAFD_TDI_HANDLE_DATA HandleData = Irp->UserBuffer;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
||||||
|
|
||||||
|
if (!HandleFlags)
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG) ||
|
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG) ||
|
||||||
IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(*HandleData))
|
IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(*HandleData))
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
|
||||||
|
@ -536,6 +551,12 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
|
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
|
||||||
Irp, 0 );
|
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))
|
if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
|
||||||
{
|
{
|
||||||
if( !FCB->ConnectInfo )
|
if( !FCB->ConnectInfo )
|
||||||
|
@ -551,12 +572,6 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
return UnlockAndMaybeComplete( FCB, Status,
|
return UnlockAndMaybeComplete( FCB, Status,
|
||||||
Irp, 0 );
|
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->UserData = FCB->DisconnectData;
|
||||||
FCB->ConnectInfo->UserDataLength = FCB->DisconnectDataSize;
|
FCB->ConnectInfo->UserDataLength = FCB->DisconnectDataSize;
|
||||||
FCB->ConnectInfo->Options = FCB->DisconnectOptions;
|
FCB->ConnectInfo->Options = FCB->DisconnectOptions;
|
||||||
|
@ -591,11 +606,25 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
ExFreePool( ConnectionReturnInfo );
|
ExFreePool( ConnectionReturnInfo );
|
||||||
|
|
||||||
|
if (Flags & TDI_DISCONNECT_RELEASE)
|
||||||
FCB->PollState |= AFD_EVENT_DISCONNECT;
|
FCB->PollState |= AFD_EVENT_DISCONNECT;
|
||||||
|
else
|
||||||
|
FCB->PollState |= AFD_EVENT_ABORT;
|
||||||
FCB->PollStatus[FD_CLOSE_BIT] = STATUS_SUCCESS;
|
FCB->PollStatus[FD_CLOSE_BIT] = STATUS_SUCCESS;
|
||||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
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 );
|
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
||||||
}
|
}
|
||||||
|
@ -784,7 +813,7 @@ AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
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_RECV_INFO RecvReq;
|
||||||
PAFD_SEND_INFO SendReq;
|
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 ||
|
if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_RECV ||
|
||||||
IrpSp->MajorFunction == IRP_MJ_READ)
|
IrpSp->MajorFunction == IRP_MJ_READ)
|
||||||
{
|
{
|
||||||
RecvReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
RecvReq = GetLockedData(Irp, IrpSp);
|
||||||
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
||||||
}
|
}
|
||||||
else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SEND ||
|
else if ((IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SEND ||
|
||||||
IrpSp->MajorFunction == IRP_MJ_WRITE)
|
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);
|
UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
|
||||||
}
|
}
|
||||||
else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SELECT)
|
else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SELECT)
|
||||||
|
@ -879,7 +909,7 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
if (Irp == Poll->Irp)
|
if (Irp == Poll->Irp)
|
||||||
{
|
{
|
||||||
CleanupPendingIrp(Irp, IrpSp, Poll);
|
CleanupPendingIrp(FCB, Irp, IrpSp, Poll);
|
||||||
KeReleaseSpinLock(&DeviceExt->Lock, OldIrql);
|
KeReleaseSpinLock(&DeviceExt->Lock, OldIrql);
|
||||||
SocketStateUnlock(FCB);
|
SocketStateUnlock(FCB);
|
||||||
return;
|
return;
|
||||||
|
@ -911,7 +941,7 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
|
||||||
if (CurrentIrp == Irp)
|
if (CurrentIrp == Irp)
|
||||||
{
|
{
|
||||||
RemoveEntryList(CurrentEntry);
|
RemoveEntryList(CurrentEntry);
|
||||||
CleanupPendingIrp(Irp, IrpSp, NULL);
|
CleanupPendingIrp(FCB, Irp, IrpSp, NULL);
|
||||||
UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0);
|
UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ static VOID HandleEOFOnIrp( PAFD_FCB FCB, NTSTATUS Status, ULONG_PTR Information
|
||||||
( !NT_SUCCESS( Status ) ) )
|
( !NT_SUCCESS( Status ) ) )
|
||||||
{
|
{
|
||||||
/* The socket has been closed */
|
/* The socket has been closed */
|
||||||
FCB->PollState |= AFD_EVENT_DISCONNECT;
|
FCB->PollState |= AFD_EVENT_CLOSE;
|
||||||
FCB->PollStatus[FD_CLOSE_BIT] = Status;
|
FCB->PollStatus[FD_CLOSE_BIT] = Status;
|
||||||
|
|
||||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||||
|
@ -43,7 +43,7 @@ static BOOLEAN CantReadMore( PAFD_FCB FCB ) {
|
||||||
UINT BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed;
|
UINT BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed;
|
||||||
|
|
||||||
return !BytesAvailable &&
|
return !BytesAvailable &&
|
||||||
(FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_DISCONNECT));
|
(FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_ABORT));
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID RefillSocketBuffer( PAFD_FCB FCB ) {
|
static VOID RefillSocketBuffer( PAFD_FCB FCB ) {
|
||||||
|
@ -60,18 +60,8 @@ static VOID RefillSocketBuffer( PAFD_FCB FCB ) {
|
||||||
&FCB->ReceiveIrp.Iosb,
|
&FCB->ReceiveIrp.Iosb,
|
||||||
ReceiveComplete,
|
ReceiveComplete,
|
||||||
FCB );
|
FCB );
|
||||||
|
if (Status != STATUS_PENDING)
|
||||||
if( Status == STATUS_SUCCESS && FCB->ReceiveIrp.Iosb.Information )
|
|
||||||
{
|
{
|
||||||
FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information;
|
|
||||||
FCB->PollState |= AFD_EVENT_RECEIVE;
|
|
||||||
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Check for EOF */
|
|
||||||
HandleEOFOnIrp(FCB, Status, FCB->ReceiveIrp.Iosb.Information);
|
HandleEOFOnIrp(FCB, Status, FCB->ReceiveIrp.Iosb.Information);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,7 +156,7 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) {
|
||||||
NextIrp =
|
NextIrp =
|
||||||
CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
||||||
RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
RecvReq = GetLockedData(NextIrp, NextIrpSp);
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp,
|
AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp,
|
||||||
TotalBytesCopied));
|
TotalBytesCopied));
|
||||||
|
@ -196,7 +186,7 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) {
|
||||||
NextIrp =
|
NextIrp =
|
||||||
CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
||||||
RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
RecvReq = GetLockedData(NextIrp, NextIrpSp);
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("RecvReq @ %x\n", RecvReq));
|
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->PollState |= AFD_EVENT_RECEIVE;
|
||||||
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
||||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||||
|
@ -259,6 +249,7 @@ NTSTATUS NTAPI ReceiveComplete
|
||||||
if( !SocketAcquireStateLock( FCB ) )
|
if( !SocketAcquireStateLock( FCB ) )
|
||||||
return STATUS_FILE_CLOSED;
|
return STATUS_FILE_CLOSED;
|
||||||
|
|
||||||
|
ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp);
|
||||||
FCB->ReceiveIrp.InFlightRequest = NULL;
|
FCB->ReceiveIrp.InFlightRequest = NULL;
|
||||||
|
|
||||||
FCB->Recv.Content = Irp->IoStatus.Information;
|
FCB->Recv.Content = Irp->IoStatus.Information;
|
||||||
|
@ -271,7 +262,7 @@ NTSTATUS NTAPI ReceiveComplete
|
||||||
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
|
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
|
||||||
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
NextIrpSp = IoGetCurrentIrpStackLocation(NextIrp);
|
NextIrpSp = IoGetCurrentIrpStackLocation(NextIrp);
|
||||||
RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
RecvReq = GetLockedData(NextIrp, NextIrpSp);
|
||||||
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
|
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
|
||||||
NextIrp->IoStatus.Information = 0;
|
NextIrp->IoStatus.Information = 0;
|
||||||
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
||||||
|
@ -378,7 +369,7 @@ SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
|
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
|
||||||
PAFD_RECV_INFO RecvReq =
|
PAFD_RECV_INFO RecvReq =
|
||||||
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
GetLockedData(Irp, IrpSp);
|
||||||
UINT BytesToCopy = 0, BytesAvailable = DatagramRecv->Len, AddrLen = 0;
|
UINT BytesToCopy = 0, BytesAvailable = DatagramRecv->Len, AddrLen = 0;
|
||||||
PAFD_MAPBUF Map;
|
PAFD_MAPBUF Map;
|
||||||
|
|
||||||
|
@ -438,26 +429,23 @@ SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
|
||||||
Map[0].BufferAddress,
|
Map[0].BufferAddress,
|
||||||
BytesToCopy));
|
BytesToCopy));
|
||||||
|
|
||||||
/* OskitDumpBuffer
|
|
||||||
( FCB->Recv.Window + FCB->Recv.BytesUsed, BytesToCopy ); */
|
|
||||||
|
|
||||||
RtlCopyMemory( Map[0].BufferAddress,
|
RtlCopyMemory( Map[0].BufferAddress,
|
||||||
FCB->Recv.Window + FCB->Recv.BytesUsed,
|
DatagramRecv->Buffer,
|
||||||
BytesToCopy );
|
BytesToCopy );
|
||||||
|
|
||||||
MmUnmapLockedPages( Map[0].BufferAddress, Map[0].Mdl );
|
MmUnmapLockedPages( Map[0].BufferAddress, Map[0].Mdl );
|
||||||
|
|
||||||
*TotalBytesCopied = BytesToCopy;
|
*TotalBytesCopied = BytesToCopy;
|
||||||
|
|
||||||
if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK)) {
|
|
||||||
FCB->Recv.BytesUsed = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
|
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
Irp->IoStatus.Information = BytesToCopy;
|
Irp->IoStatus.Information = BytesToCopy;
|
||||||
|
|
||||||
|
if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK))
|
||||||
|
{
|
||||||
ExFreePool( DatagramRecv->Address );
|
ExFreePool( DatagramRecv->Address );
|
||||||
ExFreePool( DatagramRecv );
|
ExFreePool( DatagramRecv );
|
||||||
|
}
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Done\n"));
|
AFD_DbgPrint(MID_TRACE,("Done\n"));
|
||||||
|
|
||||||
|
@ -484,6 +472,7 @@ PacketSocketRecvComplete(
|
||||||
if( !SocketAcquireStateLock( FCB ) )
|
if( !SocketAcquireStateLock( FCB ) )
|
||||||
return STATUS_FILE_CLOSED;
|
return STATUS_FILE_CLOSED;
|
||||||
|
|
||||||
|
ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp);
|
||||||
FCB->ReceiveIrp.InFlightRequest = NULL;
|
FCB->ReceiveIrp.InFlightRequest = NULL;
|
||||||
|
|
||||||
if( FCB->State == SOCKET_STATE_CLOSED ) {
|
if( FCB->State == SOCKET_STATE_CLOSED ) {
|
||||||
|
@ -492,7 +481,7 @@ PacketSocketRecvComplete(
|
||||||
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
|
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
|
||||||
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
||||||
RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
RecvReq = GetLockedData(NextIrp, NextIrpSp);
|
||||||
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
|
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
|
||||||
NextIrp->IoStatus.Information = 0;
|
NextIrp->IoStatus.Information = 0;
|
||||||
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
||||||
|
@ -513,6 +502,12 @@ PacketSocketRecvComplete(
|
||||||
return STATUS_FILE_CLOSED;
|
return STATUS_FILE_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Irp->IoStatus.Status != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
SocketStateUnlock(FCB);
|
||||||
|
return Irp->IoStatus.Status;
|
||||||
|
}
|
||||||
|
|
||||||
DatagramRecv = ExAllocatePool( NonPagedPool, DGSize );
|
DatagramRecv = ExAllocatePool( NonPagedPool, DGSize );
|
||||||
|
|
||||||
if( DatagramRecv ) {
|
if( DatagramRecv ) {
|
||||||
|
@ -547,7 +542,7 @@ PacketSocketRecvComplete(
|
||||||
ListEntry = RemoveHeadList( &FCB->PendingIrpList[FUNCTION_RECV] );
|
ListEntry = RemoveHeadList( &FCB->PendingIrpList[FUNCTION_RECV] );
|
||||||
NextIrp = CONTAINING_RECORD( ListEntry, IRP, Tail.Overlay.ListEntry );
|
NextIrp = CONTAINING_RECORD( ListEntry, IRP, Tail.Overlay.ListEntry );
|
||||||
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
||||||
RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
RecvReq = GetLockedData(NextIrp, NextIrpSp);
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("RecvReq: %x, DatagramRecv: %x\n",
|
AFD_DbgPrint(MID_TRACE,("RecvReq: %x, DatagramRecv: %x\n",
|
||||||
RecvReq, DatagramRecv));
|
RecvReq, DatagramRecv));
|
||||||
|
@ -567,6 +562,11 @@ PacketSocketRecvComplete(
|
||||||
Status = SatisfyPacketRecvRequest
|
Status = SatisfyPacketRecvRequest
|
||||||
( FCB, NextIrp, DatagramRecv,
|
( FCB, NextIrp, DatagramRecv,
|
||||||
(PUINT)&NextIrp->IoStatus.Information );
|
(PUINT)&NextIrp->IoStatus.Information );
|
||||||
|
if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK)
|
||||||
|
{
|
||||||
|
InsertHeadList(&FCB->DatagramList,
|
||||||
|
&DatagramRecv->ListEntry);
|
||||||
|
}
|
||||||
AFD_DbgPrint(MID_TRACE,("Unlocking\n"));
|
AFD_DbgPrint(MID_TRACE,("Unlocking\n"));
|
||||||
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
|
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
|
||||||
if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
||||||
|
@ -665,6 +665,12 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
( FCB, Irp, DatagramRecv,
|
( FCB, Irp, DatagramRecv,
|
||||||
(PUINT)&Irp->IoStatus.Information );
|
(PUINT)&Irp->IoStatus.Information );
|
||||||
|
|
||||||
|
if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK)
|
||||||
|
{
|
||||||
|
InsertHeadList(&FCB->DatagramList,
|
||||||
|
&DatagramRecv->ListEntry);
|
||||||
|
}
|
||||||
|
|
||||||
if( !IsListEmpty( &FCB->DatagramList ) ) {
|
if( !IsListEmpty( &FCB->DatagramList ) ) {
|
||||||
FCB->PollState |= AFD_EVENT_RECEIVE;
|
FCB->PollState |= AFD_EVENT_RECEIVE;
|
||||||
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
||||||
|
|
|
@ -329,16 +329,16 @@ NTSTATUS TdiConnect(
|
||||||
|
|
||||||
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
|
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
|
||||||
|
|
||||||
|
ASSERT(*Irp == NULL);
|
||||||
|
|
||||||
if (!ConnectionObject) {
|
if (!ConnectionObject) {
|
||||||
AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n"));
|
AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n"));
|
||||||
*Irp = NULL;
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
|
DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
|
||||||
if (!DeviceObject) {
|
if (!DeviceObject) {
|
||||||
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
|
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
|
||||||
*Irp = NULL;
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,16 +493,16 @@ NTSTATUS TdiListen
|
||||||
|
|
||||||
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
|
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
|
||||||
|
|
||||||
|
ASSERT(*Irp == NULL);
|
||||||
|
|
||||||
if (!ConnectionObject) {
|
if (!ConnectionObject) {
|
||||||
AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n"));
|
AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n"));
|
||||||
*Irp = NULL;
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
|
DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
|
||||||
if (!DeviceObject) {
|
if (!DeviceObject) {
|
||||||
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
|
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
|
||||||
*Irp = NULL;
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -900,16 +900,16 @@ NTSTATUS TdiSend
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PMDL Mdl;
|
PMDL Mdl;
|
||||||
|
|
||||||
|
ASSERT(*Irp == NULL);
|
||||||
|
|
||||||
if (!TransportObject) {
|
if (!TransportObject) {
|
||||||
AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n"));
|
AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n"));
|
||||||
*Irp = NULL;
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
|
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
|
||||||
if (!DeviceObject) {
|
if (!DeviceObject) {
|
||||||
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
|
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
|
||||||
*Irp = NULL;
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -981,16 +981,16 @@ NTSTATUS TdiReceive(
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
PMDL Mdl;
|
PMDL Mdl;
|
||||||
|
|
||||||
|
ASSERT(*Irp == NULL);
|
||||||
|
|
||||||
if (!TransportObject) {
|
if (!TransportObject) {
|
||||||
AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n"));
|
AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n"));
|
||||||
*Irp = NULL;
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
|
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
|
||||||
if (!DeviceObject) {
|
if (!DeviceObject) {
|
||||||
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
|
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
|
||||||
*Irp = NULL;
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1081,16 +1081,16 @@ NTSTATUS TdiReceiveDatagram(
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PMDL Mdl;
|
PMDL Mdl;
|
||||||
|
|
||||||
|
ASSERT(*Irp == NULL);
|
||||||
|
|
||||||
if (!TransportObject) {
|
if (!TransportObject) {
|
||||||
AFD_DbgPrint(MIN_TRACE, ("Bad tranport object.\n"));
|
AFD_DbgPrint(MIN_TRACE, ("Bad tranport object.\n"));
|
||||||
*Irp = NULL;
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
|
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
|
||||||
if (!DeviceObject) {
|
if (!DeviceObject) {
|
||||||
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
|
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
|
||||||
*Irp = NULL;
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1177,9 +1177,10 @@ NTSTATUS TdiSendDatagram(
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PMDL Mdl;
|
PMDL Mdl;
|
||||||
|
|
||||||
|
ASSERT(*Irp == NULL);
|
||||||
|
|
||||||
if (!TransportObject) {
|
if (!TransportObject) {
|
||||||
AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n"));
|
AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n"));
|
||||||
*Irp = NULL;
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1188,7 +1189,6 @@ NTSTATUS TdiSendDatagram(
|
||||||
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
|
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
|
||||||
if (!DeviceObject) {
|
if (!DeviceObject) {
|
||||||
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
|
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
|
||||||
*Irp = NULL;
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ static NTSTATUS NTAPI SendComplete
|
||||||
PIO_STACK_LOCATION NextIrpSp;
|
PIO_STACK_LOCATION NextIrpSp;
|
||||||
PAFD_SEND_INFO SendReq = NULL;
|
PAFD_SEND_INFO SendReq = NULL;
|
||||||
PAFD_MAPBUF Map;
|
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
|
* 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 ) )
|
if( !SocketAcquireStateLock( FCB ) )
|
||||||
return STATUS_FILE_CLOSED;
|
return STATUS_FILE_CLOSED;
|
||||||
|
|
||||||
|
ASSERT(FCB->SendIrp.InFlightRequest == Irp);
|
||||||
FCB->SendIrp.InFlightRequest = NULL;
|
FCB->SendIrp.InFlightRequest = NULL;
|
||||||
/* Request is not in flight any longer */
|
/* Request is not in flight any longer */
|
||||||
|
|
||||||
|
@ -50,7 +51,7 @@ static NTSTATUS NTAPI SendComplete
|
||||||
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
|
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
|
||||||
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
||||||
SendReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
SendReq = GetLockedData(NextIrp, NextIrpSp);
|
||||||
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
|
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
|
||||||
NextIrp->IoStatus.Information = 0;
|
NextIrp->IoStatus.Information = 0;
|
||||||
UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
|
UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
|
||||||
|
@ -71,7 +72,7 @@ static NTSTATUS NTAPI SendComplete
|
||||||
NextIrp =
|
NextIrp =
|
||||||
CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
||||||
SendReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
SendReq = GetLockedData(NextIrp, NextIrpSp);
|
||||||
|
|
||||||
UnlockBuffers( SendReq->BufferArray,
|
UnlockBuffers( SendReq->BufferArray,
|
||||||
SendReq->BufferCount,
|
SendReq->BufferCount,
|
||||||
|
@ -95,37 +96,60 @@ static NTSTATUS NTAPI SendComplete
|
||||||
FCB->Send.BytesUsed - Irp->IoStatus.Information );
|
FCB->Send.BytesUsed - Irp->IoStatus.Information );
|
||||||
FCB->Send.BytesUsed -= Irp->IoStatus.Information;
|
FCB->Send.BytesUsed -= Irp->IoStatus.Information;
|
||||||
|
|
||||||
if( !FCB->Send.BytesUsed &&
|
while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
|
||||||
!IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
|
|
||||||
NextIrpEntry =
|
NextIrpEntry =
|
||||||
RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
|
RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
|
||||||
NextIrp =
|
NextIrp =
|
||||||
CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
||||||
SendReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
SendReq = GetLockedData(NextIrp, NextIrpSp);
|
||||||
Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount);
|
Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount);
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("SendReq @ %x\n", SendReq));
|
AFD_DbgPrint(MID_TRACE,("SendReq @ %x\n", SendReq));
|
||||||
|
|
||||||
SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed;
|
SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed;
|
||||||
|
TotalBytesCopied = 0;
|
||||||
|
|
||||||
for( i = 0; i < SendReq->BufferCount; i++ ) {
|
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 =
|
Map[i].BufferAddress =
|
||||||
MmMapLockedPages( Map[i].Mdl, KernelMode );
|
MmMapLockedPages( Map[i].Mdl, KernelMode );
|
||||||
|
|
||||||
CopySize = MIN( SpaceAvail,
|
|
||||||
SendReq->BufferArray[i].len );
|
|
||||||
|
|
||||||
RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed,
|
RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed,
|
||||||
Map[i].BufferAddress,
|
Map[i].BufferAddress,
|
||||||
CopySize );
|
SendReq->BufferArray[i].len );
|
||||||
|
|
||||||
MmUnmapLockedPages( Map[i].BufferAddress, Map[i].Mdl );
|
MmUnmapLockedPages( Map[i].BufferAddress, Map[i].Mdl );
|
||||||
|
|
||||||
FCB->Send.BytesUsed += CopySize;
|
TotalBytesCopied += SendReq->BufferArray[i].len;
|
||||||
TotalBytesCopied += CopySize;
|
SpaceAvail -= SendReq->BufferArray[i].len;
|
||||||
SpaceAvail -= CopySize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 */
|
/* Some data is still waiting */
|
||||||
|
@ -146,22 +170,6 @@ static NTSTATUS NTAPI SendComplete
|
||||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
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 );
|
SocketStateUnlock( FCB );
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -182,6 +190,7 @@ static NTSTATUS NTAPI PacketSocketSendComplete
|
||||||
if( !SocketAcquireStateLock( FCB ) )
|
if( !SocketAcquireStateLock( FCB ) )
|
||||||
return STATUS_FILE_CLOSED;
|
return STATUS_FILE_CLOSED;
|
||||||
|
|
||||||
|
ASSERT(FCB->SendIrp.InFlightRequest == Irp);
|
||||||
FCB->SendIrp.InFlightRequest = NULL;
|
FCB->SendIrp.InFlightRequest = NULL;
|
||||||
/* Request is not in flight any longer */
|
/* Request is not in flight any longer */
|
||||||
|
|
||||||
|
@ -220,8 +229,8 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = FileObject->FsContext;
|
||||||
PAFD_SEND_INFO SendReq;
|
PAFD_SEND_INFO SendReq;
|
||||||
ULONG Information;
|
ULONG Information;
|
||||||
UINT TotalBytesCopied = 0, i, CopySize = 0,
|
UINT TotalBytesCopied = 0, i, SpaceAvail = 0;
|
||||||
SpaceAvail = 0, TotalBytesEncountered = 0;
|
BOOLEAN NoSpace = FALSE;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
|
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
|
||||||
|
|
||||||
|
@ -309,7 +318,6 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
AFD_DbgPrint(MID_TRACE,("FCB->Send.BytesUsed = %d\n",
|
AFD_DbgPrint(MID_TRACE,("FCB->Send.BytesUsed = %d\n",
|
||||||
FCB->Send.BytesUsed));
|
FCB->Send.BytesUsed));
|
||||||
|
|
||||||
if( !FCB->Send.BytesUsed ) {
|
|
||||||
SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed;
|
SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("We can accept %d bytes\n",
|
AFD_DbgPrint(MID_TRACE,("We can accept %d bytes\n",
|
||||||
|
@ -317,39 +325,62 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
for( i = 0; FCB->Send.BytesUsed < FCB->Send.Size &&
|
for( i = 0; FCB->Send.BytesUsed < FCB->Send.Size &&
|
||||||
i < SendReq->BufferCount; i++ ) {
|
i < SendReq->BufferCount; i++ ) {
|
||||||
CopySize = MIN( SpaceAvail,
|
|
||||||
SendReq->BufferArray[i].len );
|
|
||||||
|
|
||||||
TotalBytesEncountered += SendReq->BufferArray[i].len;
|
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",
|
AFD_DbgPrint(MID_TRACE,("Copying Buffer %d, %x:%d to %x\n",
|
||||||
i,
|
i,
|
||||||
SendReq->BufferArray[i].buf,
|
SendReq->BufferArray[i].buf,
|
||||||
CopySize,
|
SendReq->BufferArray[i].len,
|
||||||
FCB->Send.Window + FCB->Send.BytesUsed));
|
FCB->Send.Window + FCB->Send.BytesUsed));
|
||||||
|
|
||||||
RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed,
|
RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed,
|
||||||
SendReq->BufferArray[i].buf,
|
SendReq->BufferArray[i].buf,
|
||||||
CopySize );
|
SendReq->BufferArray[i].len );
|
||||||
|
|
||||||
FCB->Send.BytesUsed += CopySize;
|
TotalBytesCopied += SendReq->BufferArray[i].len;
|
||||||
TotalBytesCopied += CopySize;
|
SpaceAvail -= SendReq->BufferArray[i].len;
|
||||||
SpaceAvail -= CopySize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( TotalBytesEncountered == 0 ) {
|
if( TotalBytesCopied == 0 ) {
|
||||||
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
|
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Empty send\n"));
|
AFD_DbgPrint(MID_TRACE,("Empty send\n"));
|
||||||
|
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
|
||||||
return UnlockAndMaybeComplete
|
return UnlockAndMaybeComplete
|
||||||
( FCB, Status, Irp, TotalBytesCopied );
|
( FCB, STATUS_SUCCESS, Irp, TotalBytesCopied );
|
||||||
}
|
}
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Completed %d bytes\n", TotalBytesCopied));
|
if (!NoSpace)
|
||||||
|
{
|
||||||
if( TotalBytesCopied > 0 ) {
|
|
||||||
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FCB->SendIrp.InFlightRequest)
|
||||||
|
{
|
||||||
Status = TdiSend( &FCB->SendIrp.InFlightRequest,
|
Status = TdiSend( &FCB->SendIrp.InFlightRequest,
|
||||||
FCB->Connection.Object,
|
FCB->Connection.Object,
|
||||||
0,
|
0,
|
||||||
|
@ -364,21 +395,10 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Dismissing request: %x (%d)\n",
|
AFD_DbgPrint(MID_TRACE,("Dismissing request: %x (%d)\n",
|
||||||
Status, TotalBytesCopied));
|
Status, TotalBytesCopied));
|
||||||
|
}
|
||||||
|
|
||||||
return UnlockAndMaybeComplete
|
return UnlockAndMaybeComplete
|
||||||
( FCB, Status, Irp, TotalBytesCopied );
|
( FCB, Status, Irp, TotalBytesCopied );
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
|
@ -396,13 +416,33 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
||||||
|
|
||||||
/* Check that the socket is bound */
|
/* 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
|
return UnlockAndMaybeComplete
|
||||||
( FCB, STATUS_INVALID_PARAMETER, Irp, 0 );
|
( FCB, STATUS_INVALID_PARAMETER, Irp, 0 );
|
||||||
if( !(SendReq = LockRequest( Irp, IrpSp )) )
|
if( !(SendReq = LockRequest( Irp, IrpSp )) )
|
||||||
return UnlockAndMaybeComplete
|
return UnlockAndMaybeComplete
|
||||||
( FCB, STATUS_NO_MEMORY, Irp, 0 );
|
( 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->BufferArray = LockBuffers( SendReq->BufferArray,
|
||||||
SendReq->BufferCount,
|
SendReq->BufferCount,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
|
|
|
@ -300,6 +300,7 @@ PAFD_HANDLE LockHandles( PAFD_HANDLE HandleArray, UINT HandleCount );
|
||||||
VOID UnlockHandles( PAFD_HANDLE HandleArray, UINT HandleCount );
|
VOID UnlockHandles( PAFD_HANDLE HandleArray, UINT HandleCount );
|
||||||
PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
|
PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
|
||||||
VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
|
VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
|
||||||
|
PVOID GetLockedData( PIRP Irp, PIO_STACK_LOCATION IrpSp );
|
||||||
|
|
||||||
/* main.c */
|
/* main.c */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue