mirror of
https://github.com/reactos/reactos.git
synced 2024-06-01 10:11:43 +00:00
[AFD]
- Fix a nasty datagram corruption bug that would result in an uninitialized buffer data being returned instead of packet data if the client read buffer was smaller than the datagram received - Fix broken user-mode send datagram IRP completion code which didn't set the completion status - Implement disabling/enabling event select triggers svn path=/trunk/; revision=52723
This commit is contained in:
parent
521309797d
commit
e37e340708
|
@ -367,13 +367,16 @@ NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
AFD_DbgPrint(MID_TRACE,("Completed a wait for accept\n"));
|
||||
|
||||
ExFreePool( PendingConnObj );
|
||||
|
||||
FCB->EventSelectDisabled &= ~AFD_EVENT_ACCEPT;
|
||||
|
||||
if( !IsListEmpty( &FCB->PendingConnections ) ) {
|
||||
FCB->PollState |= AFD_EVENT_ACCEPT;
|
||||
FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
|
||||
if( !IsListEmpty( &FCB->PendingConnections ) )
|
||||
{
|
||||
FCB->PollState |= AFD_EVENT_ACCEPT;
|
||||
FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
|
||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||
} else
|
||||
FCB->PollState &= ~AFD_EVENT_ACCEPT;
|
||||
} else
|
||||
FCB->PollState &= ~AFD_EVENT_ACCEPT;
|
||||
|
||||
SocketStateUnlock( FCB );
|
||||
return Status;
|
||||
|
|
|
@ -408,9 +408,19 @@ SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
|
|||
|
||||
*TotalBytesCopied = BytesToCopy;
|
||||
}
|
||||
|
||||
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = BytesToCopy;
|
||||
|
||||
if (*TotalBytesCopied == DatagramRecv->Len)
|
||||
{
|
||||
/* We copied the whole datagram */
|
||||
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We only copied part of the datagram */
|
||||
Status = Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = *TotalBytesCopied;
|
||||
|
||||
if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK))
|
||||
{
|
||||
|
@ -464,62 +474,46 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
Irp, 0 );
|
||||
}
|
||||
|
||||
FCB->EventSelectDisabled &= ~AFD_EVENT_RECEIVE;
|
||||
|
||||
if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS )
|
||||
{
|
||||
if( !IsListEmpty( &FCB->DatagramList ) ) {
|
||||
ListEntry = RemoveHeadList( &FCB->DatagramList );
|
||||
DatagramRecv = CONTAINING_RECORD
|
||||
( ListEntry, AFD_STORED_DATAGRAM, ListEntry );
|
||||
if( DatagramRecv->Len > RecvReq->BufferArray[0].len &&
|
||||
!(RecvReq->TdiFlags & TDI_RECEIVE_PARTIAL) ) {
|
||||
InsertHeadList( &FCB->DatagramList,
|
||||
&DatagramRecv->ListEntry );
|
||||
Status = Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
|
||||
Irp->IoStatus.Information = DatagramRecv->Len;
|
||||
|
||||
if( !IsListEmpty( &FCB->DatagramList ) ) {
|
||||
FCB->PollState |= AFD_EVENT_RECEIVE;
|
||||
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||
} else
|
||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||
|
||||
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE );
|
||||
|
||||
AFD_DbgPrint(MIN_TRACE,("Partial datagram not read\n"));
|
||||
|
||||
return UnlockAndMaybeComplete
|
||||
( FCB, Status, Irp, Irp->IoStatus.Information );
|
||||
} else {
|
||||
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;
|
||||
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||
} else
|
||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||
|
||||
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE );
|
||||
|
||||
return UnlockAndMaybeComplete
|
||||
( FCB, Status, Irp, Irp->IoStatus.Information );
|
||||
if (!IsListEmpty(&FCB->DatagramList))
|
||||
{
|
||||
ListEntry = RemoveHeadList(&FCB->DatagramList);
|
||||
DatagramRecv = CONTAINING_RECORD(ListEntry, AFD_STORED_DATAGRAM, ListEntry);
|
||||
Status = SatisfyPacketRecvRequest(FCB, Irp, DatagramRecv,
|
||||
(PUINT)&Irp->IoStatus.Information);
|
||||
|
||||
if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK)
|
||||
{
|
||||
InsertHeadList(&FCB->DatagramList,
|
||||
&DatagramRecv->ListEntry);
|
||||
}
|
||||
} else if( (RecvReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking) ) {
|
||||
|
||||
if (IsListEmpty(&FCB->DatagramList))
|
||||
{
|
||||
FCB->PollState |= AFD_EVENT_RECEIVE;
|
||||
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||
}
|
||||
else
|
||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||
|
||||
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
||||
|
||||
return UnlockAndMaybeComplete(FCB, Status, Irp, Irp->IoStatus.Information);
|
||||
}
|
||||
else if( (RecvReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking) )
|
||||
{
|
||||
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
|
||||
Status = STATUS_CANT_WAIT;
|
||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE );
|
||||
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV );
|
||||
}
|
||||
|
@ -652,34 +646,26 @@ PacketSocketRecvComplete(
|
|||
AFD_DbgPrint(MID_TRACE,("RecvReq: %x, DatagramRecv: %x\n",
|
||||
RecvReq, DatagramRecv));
|
||||
|
||||
if( DatagramRecv->Len > RecvReq->BufferArray[0].len &&
|
||||
!(RecvReq->TdiFlags & TDI_RECEIVE_PARTIAL) ) {
|
||||
InsertHeadList( &FCB->DatagramList,
|
||||
&DatagramRecv->ListEntry );
|
||||
Status = NextIrp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
|
||||
NextIrp->IoStatus.Information = DatagramRecv->Len;
|
||||
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, CheckUnlockExtraBuffers(FCB, NextIrpSp) );
|
||||
if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
||||
(void)IoSetCancelRoutine(NextIrp, NULL);
|
||||
AFD_DbgPrint(MIN_TRACE,("Partial datagram failed\n"));
|
||||
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
||||
} else {
|
||||
AFD_DbgPrint(MID_TRACE,("Satisfying\n"));
|
||||
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, CheckUnlockExtraBuffers(FCB, NextIrpSp) );
|
||||
if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
||||
AFD_DbgPrint(MID_TRACE,("Completing\n"));
|
||||
(void)IoSetCancelRoutine(NextIrp, NULL);
|
||||
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
||||
}
|
||||
AFD_DbgPrint(MID_TRACE,("Satisfying\n"));
|
||||
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, CheckUnlockExtraBuffers(FCB, NextIrpSp) );
|
||||
if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
||||
|
||||
AFD_DbgPrint(MID_TRACE,("Completing\n"));
|
||||
(void)IoSetCancelRoutine(NextIrp, NULL);
|
||||
NextIrp->IoStatus.Status = Status;
|
||||
|
||||
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
||||
}
|
||||
|
||||
if( !IsListEmpty( &FCB->DatagramList ) && IsListEmpty(&FCB->PendingIrpList[FUNCTION_RECV]) ) {
|
||||
|
@ -747,61 +733,45 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
( FCB, STATUS_ACCESS_VIOLATION, Irp, 0 );
|
||||
}
|
||||
|
||||
if( !IsListEmpty( &FCB->DatagramList ) ) {
|
||||
ListEntry = RemoveHeadList( &FCB->DatagramList );
|
||||
DatagramRecv = CONTAINING_RECORD
|
||||
( ListEntry, AFD_STORED_DATAGRAM, ListEntry );
|
||||
if( DatagramRecv->Len > RecvReq->BufferArray[0].len &&
|
||||
!(RecvReq->TdiFlags & TDI_RECEIVE_PARTIAL) ) {
|
||||
InsertHeadList( &FCB->DatagramList,
|
||||
&DatagramRecv->ListEntry );
|
||||
Status = Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
|
||||
Irp->IoStatus.Information = DatagramRecv->Len;
|
||||
FCB->EventSelectDisabled &= ~AFD_EVENT_RECEIVE;
|
||||
|
||||
if( !IsListEmpty( &FCB->DatagramList ) ) {
|
||||
FCB->PollState |= AFD_EVENT_RECEIVE;
|
||||
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||
} else
|
||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||
|
||||
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
|
||||
|
||||
AFD_DbgPrint(MIN_TRACE,("Partial datagram failed\n"));
|
||||
|
||||
return UnlockAndMaybeComplete
|
||||
( FCB, Status, Irp, Irp->IoStatus.Information );
|
||||
} else {
|
||||
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;
|
||||
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||
} else
|
||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||
|
||||
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
|
||||
|
||||
return UnlockAndMaybeComplete
|
||||
( FCB, Status, Irp, Irp->IoStatus.Information );
|
||||
}
|
||||
} else if( (RecvReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking) ) {
|
||||
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
|
||||
Status = STATUS_CANT_WAIT;
|
||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
|
||||
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
||||
} else {
|
||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV );
|
||||
if (!IsListEmpty(&FCB->DatagramList))
|
||||
{
|
||||
ListEntry = RemoveHeadList(&FCB->DatagramList);
|
||||
DatagramRecv = CONTAINING_RECORD(ListEntry, AFD_STORED_DATAGRAM, ListEntry);
|
||||
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;
|
||||
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||
}
|
||||
else
|
||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||
|
||||
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
||||
|
||||
return UnlockAndMaybeComplete(FCB, Status, Irp, Irp->IoStatus.Information);
|
||||
}
|
||||
else if( (RecvReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking) )
|
||||
{
|
||||
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
|
||||
Status = STATUS_CANT_WAIT;
|
||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE );
|
||||
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -305,8 +305,15 @@ AfdEventSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if( FCB->EventSelect && (FCB->PollState & FCB->EventSelectTriggers) ) {
|
||||
if((FCB->EventSelect) &&
|
||||
(FCB->PollState & (FCB->EventSelectTriggers & ~FCB->EventSelectDisabled)))
|
||||
{
|
||||
AFD_DbgPrint(MID_TRACE,("Setting event %x\n", FCB->EventSelect));
|
||||
|
||||
/* Disable the events that triggered the select until the reenabling function is called */
|
||||
FCB->EventSelectDisabled |= (FCB->PollState & (FCB->EventSelectTriggers & ~FCB->EventSelectDisabled));
|
||||
|
||||
/* Set the application's event */
|
||||
KeSetEvent( FCB->EventSelect, IO_NETWORK_INCREMENT, FALSE );
|
||||
}
|
||||
|
||||
|
@ -408,8 +415,15 @@ VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) {
|
|||
|
||||
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
||||
|
||||
if( FCB->EventSelect && (FCB->PollState & FCB->EventSelectTriggers) ) {
|
||||
if((FCB->EventSelect) &&
|
||||
(FCB->PollState & (FCB->EventSelectTriggers & ~FCB->EventSelectDisabled)))
|
||||
{
|
||||
AFD_DbgPrint(MID_TRACE,("Setting event %x\n", FCB->EventSelect));
|
||||
|
||||
/* Disable the events that triggered the select until the reenabling function is called */
|
||||
FCB->EventSelectDisabled |= (FCB->PollState & (FCB->EventSelectTriggers & ~FCB->EventSelectDisabled));
|
||||
|
||||
/* Set the application's event */
|
||||
KeSetEvent( FCB->EventSelect, IO_NETWORK_INCREMENT, FALSE );
|
||||
}
|
||||
|
||||
|
|
|
@ -322,6 +322,7 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
Status = TdiBuildConnectionInfo( &TargetAddress, FCB->RemoteAddress );
|
||||
|
||||
if( NT_SUCCESS(Status) ) {
|
||||
FCB->EventSelectDisabled &= ~AFD_EVENT_SEND;
|
||||
FCB->PollState &= ~AFD_EVENT_SEND;
|
||||
|
||||
Status = QueueUserModeIrp(FCB, Irp, FUNCTION_SEND);
|
||||
|
@ -438,6 +439,8 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
SpaceAvail -= SendReq->BufferArray[i].len;
|
||||
}
|
||||
|
||||
FCB->EventSelectDisabled &= ~AFD_EVENT_SEND;
|
||||
|
||||
if( TotalBytesCopied == 0 ) {
|
||||
AFD_DbgPrint(MID_TRACE,("Empty send\n"));
|
||||
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
|
||||
|
@ -558,6 +561,7 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
/* Check the size of the Address given ... */
|
||||
|
||||
if( NT_SUCCESS(Status) ) {
|
||||
FCB->EventSelectDisabled &= ~AFD_EVENT_RECEIVE;
|
||||
FCB->PollState &= ~AFD_EVENT_SEND;
|
||||
|
||||
Status = QueueUserModeIrp(FCB, Irp, FUNCTION_SEND);
|
||||
|
|
|
@ -193,6 +193,7 @@ typedef struct _AFD_FCB {
|
|||
KMUTEX Mutex;
|
||||
PKEVENT EventSelect;
|
||||
DWORD EventSelectTriggers;
|
||||
DWORD EventSelectDisabled;
|
||||
UNICODE_STRING TdiDeviceName;
|
||||
PVOID Context;
|
||||
DWORD PollState;
|
||||
|
|
Loading…
Reference in a new issue