- 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;
PAFD_FCB FCB = FileObject->FsContext;
PVOID ConnectOptions = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
PVOID ConnectOptions = LockRequest(Irp, IrpSp);
UINT ConnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
if (!ConnectOptions)
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
if (FCB->ConnectOptions)
{
@ -75,10 +78,13 @@ AfdSetConnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
{
PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_FCB FCB = FileObject->FsContext;
PUINT ConnectOptionsSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
PUINT ConnectOptionsSize = LockRequest(Irp, IrpSp);
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
if (!ConnectOptionsSize)
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
if (BufferSize < sizeof(UINT))
return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
@ -129,10 +135,13 @@ AfdSetConnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
{
PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_FCB FCB = FileObject->FsContext;
PVOID ConnectData = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
PVOID ConnectData = LockRequest(Irp, IrpSp);
UINT ConnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
if (!ConnectData)
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
if (FCB->ConnectData)
{
@ -161,11 +170,14 @@ AfdSetConnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
{
PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_FCB FCB = FileObject->FsContext;
PUINT ConnectDataSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
PUINT ConnectDataSize = LockRequest(Irp, IrpSp);
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
if (!ConnectDataSize)
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
if (BufferSize < sizeof(UINT))
return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
@ -274,6 +286,7 @@ static NTSTATUS NTAPI StreamSocketConnectComplete
AFD_DbgPrint(MID_TRACE,("Irp->IoStatus.Status = %x\n",
Irp->IoStatus.Status));
ASSERT(FCB->ConnectIrp.InFlightRequest == Irp);
FCB->ConnectIrp.InFlightRequest = NULL;
if( FCB->State == SOCKET_STATE_CLOSED ) {

View file

@ -54,14 +54,18 @@ AfdGetContextSize( PDEVICE_OBJECT DeviceObject, PIRP Irp,
return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, sizeof(ULONG));
}
NTSTATUS NTAPI
AfdSetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp ) {
PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_FCB FCB = FileObject->FsContext;
PVOID Context = LockRequest(Irp, IrpSp);
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
if (!Context)
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
if( FCB->Context ) {
ExFreePool( FCB->Context );
@ -76,7 +80,7 @@ AfdSetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp,
FCB->ContextSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
RtlCopyMemory( FCB->Context,
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
Context,
FCB->ContextSize );
return UnlockAndMaybeComplete( FCB, STATUS_SUCCESS, Irp, 0 );

View file

@ -17,7 +17,7 @@ NTSTATUS NTAPI
AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp ) {
NTSTATUS Status = STATUS_SUCCESS;
PAFD_INFO InfoReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
PAFD_INFO InfoReq = LockRequest(Irp, IrpSp);
PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_FCB FCB = FileObject->FsContext;
PLIST_ENTRY CurrentEntry;
@ -26,6 +26,9 @@ AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
InfoReq ? InfoReq->InformationClass : 0));
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
if (!InfoReq)
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
_SEH2_TRY {
switch( InfoReq->InformationClass ) {
@ -67,10 +70,6 @@ AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
CurrentEntry = CurrentEntry->Flink;
}
/* Count the send in progress */
if (FCB->SendIrp.InFlightRequest)
InfoReq->Information.Ulong++;
break;
default:
@ -93,11 +92,14 @@ NTSTATUS NTAPI
AfdSetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp ) {
NTSTATUS Status = STATUS_SUCCESS;
PAFD_INFO InfoReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
PAFD_INFO InfoReq = LockRequest(Irp, IrpSp);
PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_FCB FCB = FileObject->FsContext;
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
if (!InfoReq)
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
_SEH2_TRY {
switch (InfoReq->InformationClass) {

View file

@ -101,6 +101,7 @@ static NTSTATUS NTAPI ListenComplete
if( !SocketAcquireStateLock( FCB ) )
return STATUS_FILE_CLOSED;
ASSERT(FCB->ListenIrp.InFlightRequest == Irp);
FCB->ListenIrp.InFlightRequest = NULL;
if( FCB->State == SOCKET_STATE_CLOSED ) {

View file

@ -13,49 +13,85 @@
#include "debug.h"
#include "pseh/pseh2.h"
PVOID GetLockedData(PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
ASSERT(Irp->MdlAddress);
return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
}
/* Lock a method_neither request so it'll be available from DISPATCH_LEVEL */
PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
BOOLEAN LockFailed = FALSE;
ASSERT(IrpSp->Parameters.DeviceIoControl.Type3InputBuffer);
ASSERT(IrpSp->Parameters.DeviceIoControl.InputBufferLength);
ASSERT(!Irp->MdlAddress);
switch (IrpSp->MajorFunction)
{
case IRP_MJ_DEVICE_CONTROL:
case IRP_MJ_INTERNAL_DEVICE_CONTROL:
ASSERT(IrpSp->Parameters.DeviceIoControl.Type3InputBuffer);
ASSERT(IrpSp->Parameters.DeviceIoControl.InputBufferLength);
Irp->MdlAddress =
IoAllocateMdl( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
IrpSp->Parameters.DeviceIoControl.InputBufferLength,
FALSE,
FALSE,
NULL );
if( Irp->MdlAddress ) {
_SEH2_TRY {
MmProbeAndLockPages( Irp->MdlAddress, Irp->RequestorMode, IoModifyAccess );
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
LockFailed = TRUE;
} _SEH2_END;
if( LockFailed ) {
IoFreeMdl( Irp->MdlAddress );
Irp->MdlAddress = NULL;
return NULL;
}
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer =
MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
if( !IrpSp->Parameters.DeviceIoControl.Type3InputBuffer ) {
MmUnlockPages( Irp->MdlAddress );
IoFreeMdl( Irp->MdlAddress );
Irp->MdlAddress = NULL;
return NULL;
}
return IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
} else return NULL;
Irp->MdlAddress =
IoAllocateMdl( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
IrpSp->Parameters.DeviceIoControl.InputBufferLength,
FALSE,
FALSE,
NULL );
if( Irp->MdlAddress ) {
_SEH2_TRY {
MmProbeAndLockPages( Irp->MdlAddress, Irp->RequestorMode, IoModifyAccess );
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
LockFailed = TRUE;
} _SEH2_END;
if( LockFailed ) {
IoFreeMdl( Irp->MdlAddress );
Irp->MdlAddress = NULL;
return NULL;
}
} else return NULL;
break;
case IRP_MJ_READ:
case IRP_MJ_WRITE:
ASSERT(Irp->UserBuffer);
Irp->MdlAddress =
IoAllocateMdl(Irp->UserBuffer,
(IrpSp->MajorFunction == IRP_MJ_READ) ?
IrpSp->Parameters.Read.Length : IrpSp->Parameters.Write.Length,
FALSE,
FALSE,
NULL );
if( Irp->MdlAddress ) {
_SEH2_TRY {
MmProbeAndLockPages( Irp->MdlAddress, Irp->RequestorMode, IoModifyAccess );
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
LockFailed = TRUE;
} _SEH2_END;
if( LockFailed ) {
IoFreeMdl( Irp->MdlAddress );
Irp->MdlAddress = NULL;
return NULL;
}
} else return NULL;
break;
default:
ASSERT(FALSE);
return NULL;
}
return GetLockedData(Irp, IrpSp);
}
VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp )
{
ASSERT(Irp->MdlAddress);
MmUnlockPages( Irp->MdlAddress );
IoFreeMdl( Irp->MdlAddress );
Irp->MdlAddress = NULL;
@ -123,7 +159,7 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count,
AFD_DbgPrint(MID_TRACE,("Probe and lock pages\n"));
_SEH2_TRY {
MmProbeAndLockPages( MapBuf[i].Mdl, KernelMode,
Write ? IoReadAccess : IoModifyAccess );
Write ? IoModifyAccess : IoReadAccess );
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
LockFailed = TRUE;
} _SEH2_END;

View file

@ -72,10 +72,13 @@ AfdSetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
{
PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_FCB FCB = FileObject->FsContext;
PVOID DisconnectOptions = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
PVOID DisconnectOptions = LockRequest(Irp, IrpSp);
UINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
if (!DisconnectOptions)
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
if (FCB->DisconnectOptions)
{
@ -104,10 +107,13 @@ AfdSetDisconnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
{
PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_FCB FCB = FileObject->FsContext;
PUINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
PUINT DisconnectOptionsSize = LockRequest(Irp, IrpSp);
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
if (!DisconnectOptionsSize)
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
if (BufferSize < sizeof(UINT))
return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
@ -158,10 +164,13 @@ AfdSetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
{
PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_FCB FCB = FileObject->FsContext;
PVOID DisconnectData = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
PVOID DisconnectData = LockRequest(Irp, IrpSp);
UINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
if (!DisconnectData)
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
if (FCB->DisconnectData)
{
@ -190,10 +199,13 @@ AfdSetDisconnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
{
PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_FCB FCB = FileObject->FsContext;
PUINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
PUINT DisconnectDataSize = LockRequest(Irp, IrpSp);
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
if (!DisconnectDataSize)
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
if (BufferSize < sizeof(UINT))
return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
@ -219,10 +231,13 @@ AfdGetTdiHandles(PDEVICE_OBJECT DeviceObject, PIRP Irp,
{
PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_FCB FCB = FileObject->FsContext;
PULONG HandleFlags = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
PULONG HandleFlags = LockRequest(Irp, IrpSp);
PAFD_TDI_HANDLE_DATA HandleData = Irp->UserBuffer;
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
if (!HandleFlags)
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG) ||
IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(*HandleData))
@ -535,6 +550,12 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
if( !(DisReq = LockRequest( Irp, IrpSp )) )
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
Irp, 0 );
if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
Flags |= TDI_DISCONNECT_RELEASE;
if( DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
DisReq->DisconnectType & AFD_DISCONNECT_ABORT )
Flags |= TDI_DISCONNECT_ABORT;
if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
{
@ -551,12 +572,6 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
return UnlockAndMaybeComplete( FCB, Status,
Irp, 0 );
if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
Flags |= TDI_DISCONNECT_RELEASE;
if( DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
DisReq->DisconnectType & AFD_DISCONNECT_ABORT )
Flags |= TDI_DISCONNECT_ABORT;
FCB->ConnectInfo->UserData = FCB->DisconnectData;
FCB->ConnectInfo->UserDataLength = FCB->DisconnectDataSize;
FCB->ConnectInfo->Options = FCB->DisconnectOptions;
@ -591,11 +606,25 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
ExFreePool( ConnectionReturnInfo );
FCB->PollState |= AFD_EVENT_DISCONNECT;
if (Flags & TDI_DISCONNECT_RELEASE)
FCB->PollState |= AFD_EVENT_DISCONNECT;
else
FCB->PollState |= AFD_EVENT_ABORT;
FCB->PollStatus[FD_CLOSE_BIT] = STATUS_SUCCESS;
PollReeval( FCB->DeviceExt, FCB->FileObject );
} else
Status = STATUS_INVALID_PARAMETER;
}
else
{
if (!(Flags & TDI_DISCONNECT_RELEASE))
{
if (!FCB->RemoteAddress)
return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
ExFreePool(FCB->RemoteAddress);
FCB->RemoteAddress = NULL;
}
}
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
}
@ -784,7 +813,7 @@ AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
}
VOID
CleanupPendingIrp(PIRP Irp, PIO_STACK_LOCATION IrpSp, PAFD_ACTIVE_POLL Poll)
CleanupPendingIrp(PAFD_FCB FCB, PIRP Irp, PIO_STACK_LOCATION IrpSp, PAFD_ACTIVE_POLL Poll)
{
PAFD_RECV_INFO RecvReq;
PAFD_SEND_INFO SendReq;
@ -793,13 +822,14 @@ CleanupPendingIrp(PIRP Irp, PIO_STACK_LOCATION IrpSp, PAFD_ACTIVE_POLL Poll)
if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_RECV ||
IrpSp->MajorFunction == IRP_MJ_READ)
{
RecvReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
RecvReq = GetLockedData(Irp, IrpSp);
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
}
else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SEND ||
IrpSp->MajorFunction == IRP_MJ_WRITE)
else if ((IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SEND ||
IrpSp->MajorFunction == IRP_MJ_WRITE) &&
!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
{
SendReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
SendReq = GetLockedData(Irp, IrpSp);
UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
}
else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SELECT)
@ -879,7 +909,7 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
if (Irp == Poll->Irp)
{
CleanupPendingIrp(Irp, IrpSp, Poll);
CleanupPendingIrp(FCB, Irp, IrpSp, Poll);
KeReleaseSpinLock(&DeviceExt->Lock, OldIrql);
SocketStateUnlock(FCB);
return;
@ -911,7 +941,7 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
if (CurrentIrp == Irp)
{
RemoveEntryList(CurrentEntry);
CleanupPendingIrp(Irp, IrpSp, NULL);
CleanupPendingIrp(FCB, Irp, IrpSp, NULL);
UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0);
return;
}

View file

@ -32,7 +32,7 @@ static VOID HandleEOFOnIrp( PAFD_FCB FCB, NTSTATUS Status, ULONG_PTR Information
( !NT_SUCCESS( Status ) ) )
{
/* The socket has been closed */
FCB->PollState |= AFD_EVENT_DISCONNECT;
FCB->PollState |= AFD_EVENT_CLOSE;
FCB->PollStatus[FD_CLOSE_BIT] = Status;
PollReeval( FCB->DeviceExt, FCB->FileObject );
@ -43,7 +43,7 @@ static BOOLEAN CantReadMore( PAFD_FCB FCB ) {
UINT BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed;
return !BytesAvailable &&
(FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_DISCONNECT));
(FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_ABORT));
}
static VOID RefillSocketBuffer( PAFD_FCB FCB ) {
@ -60,20 +60,10 @@ static VOID RefillSocketBuffer( PAFD_FCB FCB ) {
&FCB->ReceiveIrp.Iosb,
ReceiveComplete,
FCB );
if( Status == STATUS_SUCCESS && FCB->ReceiveIrp.Iosb.Information )
if (Status != STATUS_PENDING)
{
FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information;
FCB->PollState |= AFD_EVENT_RECEIVE;
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
PollReeval( FCB->DeviceExt, FCB->FileObject );
HandleEOFOnIrp(FCB, Status, FCB->ReceiveIrp.Iosb.Information);
}
else
{
/* Check for EOF */
HandleEOFOnIrp(FCB, Status, FCB->ReceiveIrp.Iosb.Information);
}
}
}
@ -166,7 +156,7 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) {
NextIrp =
CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
RecvReq = GetLockedData(NextIrp, NextIrpSp);
AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp,
TotalBytesCopied));
@ -196,7 +186,7 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) {
NextIrp =
CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
RecvReq = GetLockedData(NextIrp, NextIrpSp);
AFD_DbgPrint(MID_TRACE,("RecvReq @ %x\n", RecvReq));
@ -226,7 +216,7 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) {
}
}
if( FCB->Recv.Content ) {
if( FCB->Recv.Content - FCB->Recv.BytesUsed ) {
FCB->PollState |= AFD_EVENT_RECEIVE;
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
PollReeval( FCB->DeviceExt, FCB->FileObject );
@ -259,6 +249,7 @@ NTSTATUS NTAPI ReceiveComplete
if( !SocketAcquireStateLock( FCB ) )
return STATUS_FILE_CLOSED;
ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp);
FCB->ReceiveIrp.InFlightRequest = NULL;
FCB->Recv.Content = Irp->IoStatus.Information;
@ -271,7 +262,7 @@ NTSTATUS NTAPI ReceiveComplete
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
NextIrpSp = IoGetCurrentIrpStackLocation(NextIrp);
RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
RecvReq = GetLockedData(NextIrp, NextIrpSp);
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
NextIrp->IoStatus.Information = 0;
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
@ -378,7 +369,7 @@ SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
NTSTATUS Status = STATUS_SUCCESS;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
PAFD_RECV_INFO RecvReq =
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
GetLockedData(Irp, IrpSp);
UINT BytesToCopy = 0, BytesAvailable = DatagramRecv->Len, AddrLen = 0;
PAFD_MAPBUF Map;
@ -438,26 +429,23 @@ SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
Map[0].BufferAddress,
BytesToCopy));
/* OskitDumpBuffer
( FCB->Recv.Window + FCB->Recv.BytesUsed, BytesToCopy ); */
RtlCopyMemory( Map[0].BufferAddress,
FCB->Recv.Window + FCB->Recv.BytesUsed,
DatagramRecv->Buffer,
BytesToCopy );
MmUnmapLockedPages( Map[0].BufferAddress, Map[0].Mdl );
*TotalBytesCopied = BytesToCopy;
if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK)) {
FCB->Recv.BytesUsed = 0;
}
}
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = BytesToCopy;
ExFreePool( DatagramRecv->Address );
ExFreePool( DatagramRecv );
if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK))
{
ExFreePool( DatagramRecv->Address );
ExFreePool( DatagramRecv );
}
AFD_DbgPrint(MID_TRACE,("Done\n"));
@ -484,6 +472,7 @@ PacketSocketRecvComplete(
if( !SocketAcquireStateLock( FCB ) )
return STATUS_FILE_CLOSED;
ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp);
FCB->ReceiveIrp.InFlightRequest = NULL;
if( FCB->State == SOCKET_STATE_CLOSED ) {
@ -492,7 +481,7 @@ PacketSocketRecvComplete(
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
RecvReq = GetLockedData(NextIrp, NextIrpSp);
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
NextIrp->IoStatus.Information = 0;
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
@ -512,6 +501,12 @@ PacketSocketRecvComplete(
SocketStateUnlock( FCB );
return STATUS_FILE_CLOSED;
}
if (Irp->IoStatus.Status != STATUS_SUCCESS)
{
SocketStateUnlock(FCB);
return Irp->IoStatus.Status;
}
DatagramRecv = ExAllocatePool( NonPagedPool, DGSize );
@ -547,7 +542,7 @@ PacketSocketRecvComplete(
ListEntry = RemoveHeadList( &FCB->PendingIrpList[FUNCTION_RECV] );
NextIrp = CONTAINING_RECORD( ListEntry, IRP, Tail.Overlay.ListEntry );
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
RecvReq = GetLockedData(NextIrp, NextIrpSp);
AFD_DbgPrint(MID_TRACE,("RecvReq: %x, DatagramRecv: %x\n",
RecvReq, DatagramRecv));
@ -567,6 +562,11 @@ PacketSocketRecvComplete(
Status = SatisfyPacketRecvRequest
( FCB, NextIrp, DatagramRecv,
(PUINT)&NextIrp->IoStatus.Information );
if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK)
{
InsertHeadList(&FCB->DatagramList,
&DatagramRecv->ListEntry);
}
AFD_DbgPrint(MID_TRACE,("Unlocking\n"));
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
@ -664,6 +664,12 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
Status = SatisfyPacketRecvRequest
( FCB, Irp, DatagramRecv,
(PUINT)&Irp->IoStatus.Information );
if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK)
{
InsertHeadList(&FCB->DatagramList,
&DatagramRecv->ListEntry);
}
if( !IsListEmpty( &FCB->DatagramList ) ) {
FCB->PollState |= AFD_EVENT_RECEIVE;

View file

@ -328,17 +328,17 @@ NTSTATUS TdiConnect(
NTSTATUS Status;
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
ASSERT(*Irp == NULL);
if (!ConnectionObject) {
AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n"));
*Irp = NULL;
return STATUS_INVALID_PARAMETER;
}
DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
if (!DeviceObject) {
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
*Irp = NULL;
return STATUS_INVALID_PARAMETER;
}
@ -492,17 +492,17 @@ NTSTATUS TdiListen
NTSTATUS Status;
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
ASSERT(*Irp == NULL);
if (!ConnectionObject) {
AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n"));
*Irp = NULL;
return STATUS_INVALID_PARAMETER;
}
DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
if (!DeviceObject) {
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
*Irp = NULL;
return STATUS_INVALID_PARAMETER;
}
@ -899,17 +899,17 @@ NTSTATUS TdiSend
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status = STATUS_SUCCESS;
PMDL Mdl;
ASSERT(*Irp == NULL);
if (!TransportObject) {
AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n"));
*Irp = NULL;
return STATUS_INVALID_PARAMETER;
}
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
if (!DeviceObject) {
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
*Irp = NULL;
return STATUS_INVALID_PARAMETER;
}
@ -980,17 +980,17 @@ NTSTATUS TdiReceive(
NTSTATUS Status = STATUS_SUCCESS;
PDEVICE_OBJECT DeviceObject;
PMDL Mdl;
ASSERT(*Irp == NULL);
if (!TransportObject) {
AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n"));
*Irp = NULL;
return STATUS_INVALID_PARAMETER;
}
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
if (!DeviceObject) {
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
*Irp = NULL;
return STATUS_INVALID_PARAMETER;
}
@ -1080,17 +1080,17 @@ NTSTATUS TdiReceiveDatagram(
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status;
PMDL Mdl;
ASSERT(*Irp == NULL);
if (!TransportObject) {
AFD_DbgPrint(MIN_TRACE, ("Bad tranport object.\n"));
*Irp = NULL;
return STATUS_INVALID_PARAMETER;
}
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
if (!DeviceObject) {
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
*Irp = NULL;
return STATUS_INVALID_PARAMETER;
}
@ -1176,10 +1176,11 @@ NTSTATUS TdiSendDatagram(
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status;
PMDL Mdl;
ASSERT(*Irp == NULL);
if (!TransportObject) {
AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n"));
*Irp = NULL;
return STATUS_INVALID_PARAMETER;
}
@ -1188,7 +1189,6 @@ NTSTATUS TdiSendDatagram(
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
if (!DeviceObject) {
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
*Irp = NULL;
return STATUS_INVALID_PARAMETER;
}

View file

@ -23,7 +23,7 @@ static NTSTATUS NTAPI SendComplete
PIO_STACK_LOCATION NextIrpSp;
PAFD_SEND_INFO SendReq = NULL;
PAFD_MAPBUF Map;
UINT TotalBytesCopied = 0, SpaceAvail, i, CopySize = 0;
UINT TotalBytesCopied = 0, SpaceAvail, i;
/*
* The Irp parameter passed in is the IRP of the stream between AFD and
@ -41,6 +41,7 @@ static NTSTATUS NTAPI SendComplete
if( !SocketAcquireStateLock( FCB ) )
return STATUS_FILE_CLOSED;
ASSERT(FCB->SendIrp.InFlightRequest == Irp);
FCB->SendIrp.InFlightRequest = NULL;
/* Request is not in flight any longer */
@ -50,7 +51,7 @@ static NTSTATUS NTAPI SendComplete
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
SendReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
SendReq = GetLockedData(NextIrp, NextIrpSp);
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
NextIrp->IoStatus.Information = 0;
UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
@ -71,7 +72,7 @@ static NTSTATUS NTAPI SendComplete
NextIrp =
CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
SendReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
SendReq = GetLockedData(NextIrp, NextIrpSp);
UnlockBuffers( SendReq->BufferArray,
SendReq->BufferCount,
@ -95,37 +96,60 @@ static NTSTATUS NTAPI SendComplete
FCB->Send.BytesUsed - Irp->IoStatus.Information );
FCB->Send.BytesUsed -= Irp->IoStatus.Information;
if( !FCB->Send.BytesUsed &&
!IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
NextIrpEntry =
RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
NextIrp =
CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
SendReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
SendReq = GetLockedData(NextIrp, NextIrpSp);
Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount);
AFD_DbgPrint(MID_TRACE,("SendReq @ %x\n", SendReq));
SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed;
TotalBytesCopied = 0;
for( i = 0; i < SendReq->BufferCount; i++ ) {
if (SpaceAvail < SendReq->BufferArray[i].len)
{
InsertHeadList(&FCB->PendingIrpList[FUNCTION_SEND],
&NextIrp->Tail.Overlay.ListEntry);
NextIrp = NULL;
break;
}
Map[i].BufferAddress =
MmMapLockedPages( Map[i].Mdl, KernelMode );
CopySize = MIN( SpaceAvail,
SendReq->BufferArray[i].len );
RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed,
Map[i].BufferAddress,
CopySize );
SendReq->BufferArray[i].len );
MmUnmapLockedPages( Map[i].BufferAddress, Map[i].Mdl );
FCB->Send.BytesUsed += CopySize;
TotalBytesCopied += CopySize;
SpaceAvail -= CopySize;
TotalBytesCopied += SendReq->BufferArray[i].len;
SpaceAvail -= SendReq->BufferArray[i].len;
}
if (NextIrp != NULL)
{
FCB->Send.BytesUsed += TotalBytesCopied;
NextIrp->IoStatus.Status = STATUS_SUCCESS;
NextIrp->IoStatus.Information = TotalBytesCopied;
(void)IoSetCancelRoutine(NextIrp, NULL);
UnlockBuffers( SendReq->BufferArray,
SendReq->BufferCount,
FALSE );
if (NextIrp->MdlAddress) UnlockRequest(NextIrp, NextIrpSp);
IoCompleteRequest(NextIrp, IO_NETWORK_INCREMENT);
}
else
break;
}
/* Some data is still waiting */
@ -146,22 +170,6 @@ static NTSTATUS NTAPI SendComplete
PollReeval( FCB->DeviceExt, FCB->FileObject );
}
if( TotalBytesCopied > 0 ) {
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
if( Status == STATUS_PENDING )
Status = STATUS_SUCCESS;
AFD_DbgPrint(MID_TRACE,("Dismissing request: %x\n", Status));
return UnlockAndMaybeComplete( FCB, Status, NextIrp, TotalBytesCopied );
} else if( NextIrp ) {
AFD_DbgPrint(MID_TRACE,("Could not do any more with Irp %x\n",
NextIrp));
InsertHeadList( &FCB->PendingIrpList[FUNCTION_SEND],
&NextIrp->Tail.Overlay.ListEntry );
}
SocketStateUnlock( FCB );
return STATUS_SUCCESS;
@ -182,6 +190,7 @@ static NTSTATUS NTAPI PacketSocketSendComplete
if( !SocketAcquireStateLock( FCB ) )
return STATUS_FILE_CLOSED;
ASSERT(FCB->SendIrp.InFlightRequest == Irp);
FCB->SendIrp.InFlightRequest = NULL;
/* Request is not in flight any longer */
@ -220,8 +229,8 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
PAFD_FCB FCB = FileObject->FsContext;
PAFD_SEND_INFO SendReq;
ULONG Information;
UINT TotalBytesCopied = 0, i, CopySize = 0,
SpaceAvail = 0, TotalBytesEncountered = 0;
UINT TotalBytesCopied = 0, i, SpaceAvail = 0;
BOOLEAN NoSpace = FALSE;
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
@ -309,76 +318,87 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
AFD_DbgPrint(MID_TRACE,("FCB->Send.BytesUsed = %d\n",
FCB->Send.BytesUsed));
if( !FCB->Send.BytesUsed ) {
SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed;
AFD_DbgPrint(MID_TRACE,("We can accept %d bytes\n",
SpaceAvail));
for( i = 0; FCB->Send.BytesUsed < FCB->Send.Size &&
i < SendReq->BufferCount; i++ ) {
CopySize = MIN( SpaceAvail,
SendReq->BufferArray[i].len );
TotalBytesEncountered += SendReq->BufferArray[i].len;
AFD_DbgPrint(MID_TRACE,("Copying Buffer %d, %x:%d to %x\n",
i,
SendReq->BufferArray[i].buf,
CopySize,
FCB->Send.Window + FCB->Send.BytesUsed));
RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed,
SendReq->BufferArray[i].buf,
CopySize );
FCB->Send.BytesUsed += CopySize;
TotalBytesCopied += CopySize;
SpaceAvail -= CopySize;
}
if( TotalBytesEncountered == 0 ) {
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
AFD_DbgPrint(MID_TRACE,("Empty send\n"));
return UnlockAndMaybeComplete
( FCB, Status, Irp, TotalBytesCopied );
}
AFD_DbgPrint(MID_TRACE,("Completed %d bytes\n", TotalBytesCopied));
if( TotalBytesCopied > 0 ) {
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
Status = TdiSend( &FCB->SendIrp.InFlightRequest,
FCB->Connection.Object,
0,
FCB->Send.Window,
FCB->Send.BytesUsed,
&FCB->SendIrp.Iosb,
SendComplete,
FCB );
if( Status == STATUS_PENDING )
Status = STATUS_SUCCESS;
AFD_DbgPrint(MID_TRACE,("Dismissing request: %x (%d)\n",
Status, TotalBytesCopied));
return UnlockAndMaybeComplete
( FCB, Status, Irp, TotalBytesCopied );
}
SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed;
AFD_DbgPrint(MID_TRACE,("We can accept %d bytes\n",
SpaceAvail));
for( i = 0; FCB->Send.BytesUsed < FCB->Send.Size &&
i < SendReq->BufferCount; i++ ) {
if (SpaceAvail < SendReq->BufferArray[i].len)
{
if (FCB->Send.BytesUsed + TotalBytesCopied +
SendReq->BufferArray[i].len > FCB->Send.Size)
{
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_OVERFLOW, Irp, 0);
}
NoSpace = TRUE;
break;
}
AFD_DbgPrint(MID_TRACE,("Copying Buffer %d, %x:%d to %x\n",
i,
SendReq->BufferArray[i].buf,
SendReq->BufferArray[i].len,
FCB->Send.Window + FCB->Send.BytesUsed));
RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed,
SendReq->BufferArray[i].buf,
SendReq->BufferArray[i].len );
TotalBytesCopied += SendReq->BufferArray[i].len;
SpaceAvail -= SendReq->BufferArray[i].len;
}
if( SendReq->AfdFlags & AFD_IMMEDIATE ) {
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
return UnlockAndMaybeComplete
if( TotalBytesCopied == 0 ) {
AFD_DbgPrint(MID_TRACE,("Empty send\n"));
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
return UnlockAndMaybeComplete
( FCB, STATUS_SUCCESS, Irp, TotalBytesCopied );
}
if (!NoSpace)
{
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
FCB->Send.BytesUsed += TotalBytesCopied;
AFD_DbgPrint(MID_TRACE,("Completed %d bytes\n", TotalBytesCopied));
}
else
{
if( SendReq->AfdFlags & AFD_IMMEDIATE ) {
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
return UnlockAndMaybeComplete
( FCB, STATUS_CANT_WAIT, Irp, 0 );
} else {
AFD_DbgPrint(MID_TRACE,("Queuing request\n"));
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND );
} else {
AFD_DbgPrint(MID_TRACE,("Queuing request\n"));
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND );
}
}
if (!FCB->SendIrp.InFlightRequest)
{
Status = TdiSend( &FCB->SendIrp.InFlightRequest,
FCB->Connection.Object,
0,
FCB->Send.Window,
FCB->Send.BytesUsed,
&FCB->SendIrp.Iosb,
SendComplete,
FCB );
if( Status == STATUS_PENDING )
Status = STATUS_SUCCESS;
AFD_DbgPrint(MID_TRACE,("Dismissing request: %x (%d)\n",
Status, TotalBytesCopied));
}
return UnlockAndMaybeComplete
( FCB, Status, Irp, TotalBytesCopied );
}
NTSTATUS NTAPI
@ -396,12 +416,32 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
/* Check that the socket is bound */
if( FCB->State != SOCKET_STATE_BOUND )
if( FCB->State != SOCKET_STATE_BOUND &&
FCB->State != SOCKET_STATE_CREATED)
return UnlockAndMaybeComplete
( FCB, STATUS_INVALID_PARAMETER, Irp, 0 );
if( !(SendReq = LockRequest( Irp, IrpSp )) )
return UnlockAndMaybeComplete
( FCB, STATUS_NO_MEMORY, Irp, 0 );
if (FCB->State == SOCKET_STATE_CREATED)
{
if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress );
FCB->LocalAddress =
TaBuildNullTransportAddress( ((PTRANSPORT_ADDRESS)SendReq->TdiConnection.RemoteAddress)->
Address[0].AddressType );
if( FCB->LocalAddress ) {
Status = WarmSocketForBind( FCB );
if( NT_SUCCESS(Status) )
FCB->State = SOCKET_STATE_BOUND;
else
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
} else
return UnlockAndMaybeComplete
( FCB, STATUS_NO_MEMORY, Irp, 0 );
}
SendReq->BufferArray = LockBuffers( SendReq->BufferArray,
SendReq->BufferCount,

View file

@ -300,6 +300,7 @@ PAFD_HANDLE LockHandles( PAFD_HANDLE HandleArray, UINT HandleCount );
VOID UnlockHandles( PAFD_HANDLE HandleArray, UINT HandleCount );
PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
PVOID GetLockedData( PIRP Irp, PIO_STACK_LOCATION IrpSp );
/* main.c */