From: Cameron Gutman Date: Sat, 3 Oct 2009 20:52:54 +0000 (+0000) Subject: - Implement IRP cancellation for AFD X-Git-Tag: ReactOS-0.3.11~658 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=5920b78ec2b54f593b37d1862713921ec709de44 - Implement IRP cancellation for AFD - Fixes "Broken driver did not complete!" showing up in the debug log (especially during winetests) svn path=/trunk/; revision=43274 --- diff --git a/reactos/drivers/network/afd/afd/connect.c b/reactos/drivers/network/afd/afd/connect.c index 984ed492255..bcc7873f92a 100644 --- a/reactos/drivers/network/afd/afd/connect.c +++ b/reactos/drivers/network/afd/afd/connect.c @@ -99,6 +99,7 @@ static NTSTATUS NTAPI StreamSocketConnectComplete NextIrp->IoStatus.Status = STATUS_FILE_CLOSED; NextIrp->IoStatus.Information = 0; if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); + (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } SocketStateUnlock( FCB ); @@ -120,6 +121,7 @@ static NTSTATUS NTAPI StreamSocketConnectComplete NextIrp->IoStatus.Status = Status; NextIrp->IoStatus.Information = 0; if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); + (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } diff --git a/reactos/drivers/network/afd/afd/listen.c b/reactos/drivers/network/afd/afd/listen.c index 6aaad3a1f7f..76d90e8fa0b 100644 --- a/reactos/drivers/network/afd/afd/listen.c +++ b/reactos/drivers/network/afd/afd/listen.c @@ -60,6 +60,7 @@ static NTSTATUS SatisfyPreAccept( PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt ) { if( Irp->MdlAddress ) UnlockRequest( Irp, IoGetCurrentIrpStackLocation( Irp ) ); Irp->IoStatus.Status = STATUS_NO_MEMORY; Irp->IoStatus.Information = 0; + (void)IoSetCancelRoutine(Irp, NULL); IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); return STATUS_NO_MEMORY; } @@ -79,6 +80,7 @@ static NTSTATUS SatisfyPreAccept( PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt ) { Irp->IoStatus.Information = ((PCHAR)&IPAddr[1]) - ((PCHAR)ListenReceive); Irp->IoStatus.Status = STATUS_SUCCESS; + (void)IoSetCancelRoutine(Irp, NULL); IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); return STATUS_SUCCESS; } @@ -106,6 +108,7 @@ static NTSTATUS NTAPI ListenComplete NextIrp->IoStatus.Status = STATUS_FILE_CLOSED; NextIrp->IoStatus.Information = 0; if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); + (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } diff --git a/reactos/drivers/network/afd/afd/lock.c b/reactos/drivers/network/afd/afd/lock.c index 18e1084d177..62263aa1fde 100644 --- a/reactos/drivers/network/afd/afd/lock.c +++ b/reactos/drivers/network/afd/afd/lock.c @@ -302,6 +302,7 @@ NTSTATUS NTAPI UnlockAndMaybeComplete SocketStateUnlock( FCB ); } else { if ( Irp->MdlAddress ) UnlockRequest( Irp, IoGetCurrentIrpStackLocation( Irp ) ); + (void)IoSetCancelRoutine(Irp, NULL); SocketStateUnlock( FCB ); IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); } @@ -322,7 +323,7 @@ NTSTATUS LostSocket( PIRP Irp ) { NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function ) { InsertTailList( &FCB->PendingIrpList[Function], &Irp->Tail.Overlay.ListEntry ); - IoMarkIrpPending(Irp); - Irp->IoStatus.Status = STATUS_PENDING; + IoMarkIrpPending(Irp); + (void)IoSetCancelRoutine(Irp, AfdCancelHandler); return UnlockAndMaybeComplete( FCB, STATUS_PENDING, Irp, 0 ); } diff --git a/reactos/drivers/network/afd/afd/main.c b/reactos/drivers/network/afd/afd/main.c index 5618f3a9f7d..a20c47bbfe7 100644 --- a/reactos/drivers/network/afd/afd/main.c +++ b/reactos/drivers/network/afd/afd/main.c @@ -505,6 +505,78 @@ AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) return (Status); } +VOID NTAPI +AfdCancelHandler(PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + PFILE_OBJECT FileObject = IrpSp->FileObject; + PAFD_FCB FCB = FileObject->FsContext; + UINT Function; + PAFD_RECV_INFO RecvReq; + PAFD_SEND_INFO SendReq; + PLIST_ENTRY CurrentEntry; + PIRP CurrentIrp; + + IoReleaseCancelSpinLock(Irp->CancelIrql); + + if (!SocketAcquireStateLock(FCB)) + return; + + ASSERT(IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL); + + switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_AFD_RECV: + RecvReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE); + /* Fall through */ + + case IOCTL_AFD_RECV_DATAGRAM: + Function = FUNCTION_RECV; + break; + + case IOCTL_AFD_SEND: + SendReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); + /* Fall through */ + + case IOCTL_AFD_SEND_DATAGRAM: + Function = FUNCTION_SEND; + break; + + case IOCTL_AFD_CONNECT: + Function = FUNCTION_CONNECT; + break; + + case IOCTL_AFD_WAIT_FOR_LISTEN: + Function = FUNCTION_PREACCEPT; + break; + + default: + ASSERT(FALSE); + break; + } + + CurrentEntry = FCB->PendingIrpList[Function].Flink; + while (CurrentEntry != &FCB->PendingIrpList[Function]) + { + CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry); + + if (CurrentIrp == Irp) + { + RemoveEntryList(CurrentEntry); + break; + } + else + { + CurrentEntry = CurrentEntry->Flink; + } + } + + UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0); +} + static VOID NTAPI AfdUnload(PDRIVER_OBJECT DriverObject) { diff --git a/reactos/drivers/network/afd/afd/read.c b/reactos/drivers/network/afd/afd/read.c index 10d2ea93c5e..0c690733d6d 100644 --- a/reactos/drivers/network/afd/afd/read.c +++ b/reactos/drivers/network/afd/afd/read.c @@ -154,6 +154,7 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) { RetBytesCopied = TotalBytesCopied; } if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); + (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } } @@ -210,6 +211,7 @@ NTSTATUS NTAPI ReceiveComplete NextIrp->IoStatus.Information = 0; UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE); if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); + (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } SocketStateUnlock( FCB ); @@ -292,6 +294,7 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, } else if( Status == STATUS_PENDING ) { AFD_DbgPrint(MID_TRACE,("Leaving read irp\n")); IoMarkIrpPending( Irp ); + (void)IoSetCancelRoutine(Irp, AfdCancelHandler); } else { AFD_DbgPrint(MID_TRACE,("Completed with status %x\n", Status)); } @@ -427,6 +430,7 @@ PacketSocketRecvComplete( NextIrp->IoStatus.Information = 0; UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE); if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); + (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } @@ -489,6 +493,7 @@ PacketSocketRecvComplete( NextIrp->IoStatus.Information = DatagramRecv->Len; UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE ); if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); + (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } else { AFD_DbgPrint(MID_TRACE,("Satisfying\n")); @@ -499,6 +504,7 @@ PacketSocketRecvComplete( UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE ); if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); AFD_DbgPrint(MID_TRACE,("Completing\n")); + (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } } diff --git a/reactos/drivers/network/afd/afd/write.c b/reactos/drivers/network/afd/afd/write.c index e7c5c36303f..fffde265420 100644 --- a/reactos/drivers/network/afd/afd/write.c +++ b/reactos/drivers/network/afd/afd/write.c @@ -57,6 +57,7 @@ static NTSTATUS NTAPI SendComplete NextIrp->IoStatus.Information = 0; UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); + (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } SocketStateUnlock( FCB ); @@ -82,7 +83,7 @@ static NTSTATUS NTAPI SendComplete NextIrp->IoStatus.Information = 0; if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); - + (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } @@ -197,6 +198,7 @@ static NTSTATUS NTAPI PacketSocketSendComplete NextIrp->IoStatus.Status = STATUS_FILE_CLOSED; NextIrp->IoStatus.Information = 0; if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); + (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } SocketStateUnlock( FCB ); diff --git a/reactos/drivers/network/afd/include/afd.h b/reactos/drivers/network/afd/include/afd.h index b45fe382b5f..c4db6018ae6 100644 --- a/reactos/drivers/network/afd/include/afd.h +++ b/reactos/drivers/network/afd/include/afd.h @@ -279,6 +279,8 @@ VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ); VOID OskitDumpBuffer( PCHAR Buffer, UINT Len ); NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function ); VOID DestroySocket( PAFD_FCB FCB ); +VOID NTAPI AfdCancelHandler(PDEVICE_OBJECT DeviceObject, + PIRP Irp); /* read.c */