- 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:
Cameron Gutman 2011-06-11 12:46:04 +00:00
parent a7abbd0f7e
commit dcf65c0e08
10 changed files with 343 additions and 210 deletions

View file

@ -43,10 +43,13 @@ 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)
{ {
@ -75,10 +78,13 @@ 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,10 +135,13 @@ 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)
{ {
@ -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 ) {

View file

@ -54,14 +54,18 @@ AfdGetContextSize( PDEVICE_OBJECT DeviceObject, PIRP Irp,
return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, sizeof(ULONG)); return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, sizeof(ULONG));
} }
NTSTATUS NTAPI NTSTATUS NTAPI
AfdSetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp, 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 );
@ -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 );

View file

@ -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;
@ -26,6 +26,9 @@ AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
InfoReq ? InfoReq->InformationClass : 0)); InfoReq ? InfoReq->InformationClass : 0));
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 ) {
@ -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,11 +92,14 @@ 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) {

View file

@ -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 ) {

View file

@ -13,49 +13,85 @@
#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(IrpSp->Parameters.DeviceIoControl.Type3InputBuffer);
ASSERT(IrpSp->Parameters.DeviceIoControl.InputBufferLength);
ASSERT(!Irp->MdlAddress); 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, Irp->MdlAddress =
IrpSp->Parameters.DeviceIoControl.InputBufferLength, IoAllocateMdl( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
FALSE, IrpSp->Parameters.DeviceIoControl.InputBufferLength,
FALSE, FALSE,
NULL ); FALSE,
if( Irp->MdlAddress ) { NULL );
_SEH2_TRY { if( Irp->MdlAddress ) {
MmProbeAndLockPages( Irp->MdlAddress, Irp->RequestorMode, IoModifyAccess ); _SEH2_TRY {
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { MmProbeAndLockPages( Irp->MdlAddress, Irp->RequestorMode, IoModifyAccess );
LockFailed = TRUE; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
} _SEH2_END; LockFailed = TRUE;
} _SEH2_END;
if( LockFailed ) {
IoFreeMdl( Irp->MdlAddress ); if( LockFailed ) {
Irp->MdlAddress = NULL; IoFreeMdl( Irp->MdlAddress );
return NULL; Irp->MdlAddress = NULL;
} return NULL;
}
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer = } else return NULL;
MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority ); break;
if( !IrpSp->Parameters.DeviceIoControl.Type3InputBuffer ) { case IRP_MJ_READ:
MmUnlockPages( Irp->MdlAddress ); case IRP_MJ_WRITE:
IoFreeMdl( Irp->MdlAddress ); ASSERT(Irp->UserBuffer);
Irp->MdlAddress = NULL;
return NULL; Irp->MdlAddress =
} IoAllocateMdl(Irp->UserBuffer,
(IrpSp->MajorFunction == IRP_MJ_READ) ?
return IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; IrpSp->Parameters.Read.Length : IrpSp->Parameters.Write.Length,
} else return NULL; 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 ) 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;

View file

@ -72,10 +72,13 @@ 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)
{ {
@ -104,10 +107,13 @@ 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,10 +164,13 @@ 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)
{ {
@ -190,10 +199,13 @@ 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,10 +231,13 @@ 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))
@ -535,6 +550,12 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
if( !(DisReq = LockRequest( Irp, IrpSp )) ) if( !(DisReq = LockRequest( Irp, IrpSp )) )
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))
{ {
@ -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 );
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; 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;
} }

View file

@ -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,20 +60,10 @@ 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; HandleEOFOnIrp(FCB, Status, 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);
}
} }
} }
@ -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;
ExFreePool( DatagramRecv->Address );
ExFreePool( DatagramRecv ); if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK))
{
ExFreePool( DatagramRecv->Address );
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);
@ -512,6 +501,12 @@ PacketSocketRecvComplete(
SocketStateUnlock( FCB ); SocketStateUnlock( FCB );
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 );
@ -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 ) );
@ -664,6 +664,12 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
Status = SatisfyPacketRecvRequest Status = SatisfyPacketRecvRequest
( 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;

View file

@ -328,17 +328,17 @@ NTSTATUS TdiConnect(
NTSTATUS Status; NTSTATUS Status;
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;
} }
@ -492,17 +492,17 @@ NTSTATUS TdiListen
NTSTATUS Status; NTSTATUS Status;
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;
} }
@ -899,17 +899,17 @@ NTSTATUS TdiSend
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
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;
} }
@ -980,17 +980,17 @@ NTSTATUS TdiReceive(
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
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;
} }
@ -1080,17 +1080,17 @@ NTSTATUS TdiReceiveDatagram(
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
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;
} }
@ -1176,10 +1176,11 @@ NTSTATUS TdiSendDatagram(
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
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;
} }

View file

@ -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,76 +318,87 @@ 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", SpaceAvail));
SpaceAvail));
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, if (SpaceAvail < SendReq->BufferArray[i].len)
SendReq->BufferArray[i].len ); {
if (FCB->Send.BytesUsed + TotalBytesCopied +
TotalBytesEncountered += SendReq->BufferArray[i].len; SendReq->BufferArray[i].len > FCB->Send.Size)
{
AFD_DbgPrint(MID_TRACE,("Copying Buffer %d, %x:%d to %x\n", UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
i,
SendReq->BufferArray[i].buf, return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_OVERFLOW, Irp, 0);
CopySize, }
FCB->Send.Window + FCB->Send.BytesUsed)); NoSpace = TRUE;
break;
RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed, }
SendReq->BufferArray[i].buf,
CopySize ); AFD_DbgPrint(MID_TRACE,("Copying Buffer %d, %x:%d to %x\n",
i,
FCB->Send.BytesUsed += CopySize; SendReq->BufferArray[i].buf,
TotalBytesCopied += CopySize; SendReq->BufferArray[i].len,
SpaceAvail -= CopySize; FCB->Send.Window + FCB->Send.BytesUsed));
}
RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed,
if( TotalBytesEncountered == 0 ) { SendReq->BufferArray[i].buf,
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); SendReq->BufferArray[i].len );
AFD_DbgPrint(MID_TRACE,("Empty send\n")); TotalBytesCopied += SendReq->BufferArray[i].len;
return UnlockAndMaybeComplete SpaceAvail -= SendReq->BufferArray[i].len;
( FCB, Status, Irp, TotalBytesCopied );
}
AFD_DbgPrint(MID_TRACE,("Completed %d bytes\n", TotalBytesCopied));
if( TotalBytesCopied > 0 ) {
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
Status = TdiSend( &FCB->SendIrp.InFlightRequest,
FCB->Connection.Object,
0,
FCB->Send.Window,
FCB->Send.BytesUsed,
&FCB->SendIrp.Iosb,
SendComplete,
FCB );
if( Status == STATUS_PENDING )
Status = STATUS_SUCCESS;
AFD_DbgPrint(MID_TRACE,("Dismissing request: %x (%d)\n",
Status, TotalBytesCopied));
return UnlockAndMaybeComplete
( FCB, Status, Irp, TotalBytesCopied );
}
} }
if( SendReq->AfdFlags & AFD_IMMEDIATE ) { if( TotalBytesCopied == 0 ) {
AFD_DbgPrint(MID_TRACE,("Nonblocking\n")); AFD_DbgPrint(MID_TRACE,("Empty send\n"));
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
return UnlockAndMaybeComplete 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 ); ( FCB, STATUS_CANT_WAIT, Irp, 0 );
} else { } else {
AFD_DbgPrint(MID_TRACE,("Queuing request\n")); AFD_DbgPrint(MID_TRACE,("Queuing request\n"));
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND ); 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 NTSTATUS NTAPI
@ -396,12 +416,32 @@ 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,

View file

@ -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 */