diff --git a/reactos/drivers/filesystems/fastfat/iface.c b/reactos/drivers/filesystems/fastfat/iface.c
index 6bf97159deb..de9bb165a33 100644
--- a/reactos/drivers/filesystems/fastfat/iface.c
+++ b/reactos/drivers/filesystems/fastfat/iface.c
@@ -100,6 +100,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest;
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = VfatBuildRequest;
+ DriverObject->MajorFunction[IRP_MJ_PNP] = VfatBuildRequest;
DriverObject->DriverUnload = NULL;
diff --git a/reactos/drivers/filesystems/fastfat/misc.c b/reactos/drivers/filesystems/fastfat/misc.c
index 688086acec2..71d94b5acb7 100644
--- a/reactos/drivers/filesystems/fastfat/misc.c
+++ b/reactos/drivers/filesystems/fastfat/misc.c
@@ -127,6 +127,8 @@ VfatDispatchRequest (IN PVFAT_IRP_CONTEXT IrpContext)
return VfatCleanup(IrpContext);
case IRP_MJ_FLUSH_BUFFERS:
return VfatFlush(IrpContext);
+ case IRP_MJ_PNP:
+ return VfatPnp(IrpContext);
default:
DPRINT1 ("Unexpected major function %x\n", IrpContext->MajorFunction);
IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
diff --git a/reactos/drivers/filesystems/fastfat/pnp.c b/reactos/drivers/filesystems/fastfat/pnp.c
new file mode 100644
index 00000000000..a1e909e7da9
--- /dev/null
+++ b/reactos/drivers/filesystems/fastfat/pnp.c
@@ -0,0 +1,42 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: drivers/filesystems/fastfat/pnp.c
+ * PURPOSE: VFAT Filesystem
+ * PROGRAMMER: Pierre Schweitzer
+ *
+ */
+
+/* INCLUDES *****************************************************************/
+
+#define NDEBUG
+#include "vfat.h"
+
+/* FUNCTIONS ****************************************************************/
+
+NTSTATUS VfatPnp(PVFAT_IRP_CONTEXT IrpContext)
+{
+ PVCB Vcb = NULL;
+ NTSTATUS Status;
+
+ /* PRECONDITION */
+ ASSERT(IrpContext);
+
+ switch (IrpContext->Stack->MinorFunction)
+ {
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ case IRP_MN_SURPRISE_REMOVAL:
+ case IRP_MN_REMOVE_DEVICE:
+ case IRP_MN_CANCEL_REMOVE_DEVICE:
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ default:
+ IoSkipCurrentIrpStackLocation(IrpContext->Irp);
+ Vcb = (PVCB)IrpContext->Stack->DeviceObject->DeviceExtension;
+ Status = IoCallDriver(Vcb->StorageDevice, IrpContext->Irp);
+ }
+
+ VfatFreeIrpContext(IrpContext);
+
+ return Status;
+}
diff --git a/reactos/drivers/filesystems/fastfat/vfat.h b/reactos/drivers/filesystems/fastfat/vfat.h
index e9c37da3d63..3521d31a36d 100644
--- a/reactos/drivers/filesystems/fastfat/vfat.h
+++ b/reactos/drivers/filesystems/fastfat/vfat.h
@@ -775,5 +775,8 @@ NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext);
NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb);
+/* --------------------------------------------------------------- pnp.c */
+
+NTSTATUS VfatPnp(PVFAT_IRP_CONTEXT IrpContext);
/* EOF */
diff --git a/reactos/drivers/filesystems/fastfat/vfatfs.rbuild b/reactos/drivers/filesystems/fastfat/vfatfs.rbuild
index 56ca836973c..a8e81d2c2c3 100644
--- a/reactos/drivers/filesystems/fastfat/vfatfs.rbuild
+++ b/reactos/drivers/filesystems/fastfat/vfatfs.rbuild
@@ -21,6 +21,7 @@
fsctl.c
iface.c
misc.c
+ pnp.c
rw.c
shutdown.c
string.c
diff --git a/reactos/ntoskrnl/io/iomgr/irp.c b/reactos/ntoskrnl/io/iomgr/irp.c
index 53649f1de70..55d316adf55 100644
--- a/reactos/ntoskrnl/io/iomgr/irp.c
+++ b/reactos/ntoskrnl/io/iomgr/irp.c
@@ -18,6 +18,8 @@
#undef IoCallDriver
#undef IoCompleteRequest
+PIRP IopDeadIrp;
+
/* PRIVATE FUNCTIONS ********************************************************/
VOID
@@ -112,10 +114,9 @@ IopAbortInterruptedIrp(IN PKEVENT EventObject,
VOID
NTAPI
-IopRemoveThreadIrp(VOID)
+IopDisassociateThreadIrp(VOID)
{
- KIRQL OldIrql;
- PIRP DeadIrp;
+ KIRQL OldIrql, LockIrql;
PETHREAD IrpThread;
PLIST_ENTRY IrpEntry;
PIO_ERROR_LOG_PACKET ErrorLogEntry;
@@ -134,36 +135,41 @@ IopRemoveThreadIrp(VOID)
return;
}
+ /* Ensure no one will come disturb */
+ LockIrql = KeAcquireQueuedSpinLock(LockQueueIoCompletionLock);
+
/* Get the misbehaving IRP */
IrpEntry = IrpThread->IrpList.Flink;
- DeadIrp = CONTAINING_RECORD(IrpEntry, IRP, ThreadListEntry);
+ IopDeadIrp = CONTAINING_RECORD(IrpEntry, IRP, ThreadListEntry);
IOTRACE(IO_IRP_DEBUG,
"%s - Deassociating IRP %p for %p\n",
__FUNCTION__,
- DeadIrp,
+ IopDeadIrp,
IrpThread);
/* Don't cancel the IRP if it's already been completed far */
- if (DeadIrp->CurrentLocation == (DeadIrp->StackCount + 2))
+ if (IopDeadIrp->CurrentLocation == (IopDeadIrp->StackCount + 2))
{
/* Return */
+ KeReleaseQueuedSpinLock(LockQueueIoCompletionLock, LockIrql);
KeLowerIrql(OldIrql);
return;
}
/* Disown the IRP! */
- DeadIrp->Tail.Overlay.Thread = NULL;
+ IopDeadIrp->Tail.Overlay.Thread = NULL;
RemoveHeadList(&IrpThread->IrpList);
- InitializeListHead(&DeadIrp->ThreadListEntry);
+ InitializeListHead(&IopDeadIrp->ThreadListEntry);
/* Get the stack location and check if it's valid */
- IoStackLocation = IoGetCurrentIrpStackLocation(DeadIrp);
- if (DeadIrp->CurrentLocation <= DeadIrp->StackCount)
+ IoStackLocation = IoGetCurrentIrpStackLocation(IopDeadIrp);
+ if (IopDeadIrp->CurrentLocation <= IopDeadIrp->StackCount)
{
/* Get the device object */
DeviceObject = IoStackLocation->DeviceObject;
}
+ KeReleaseQueuedSpinLock(LockQueueIoCompletionLock, LockIrql);
/* Lower IRQL now, since we have the pointers we need */
KeLowerIrql(OldIrql);
@@ -176,7 +182,7 @@ IopRemoveThreadIrp(VOID)
if (ErrorLogEntry)
{
/* Write the entry */
- ErrorLogEntry->ErrorCode = 0xBAADF00D; /* FIXME */
+ ErrorLogEntry->ErrorCode = IO_DRIVER_CANCEL_TIMEOUT;
IoWriteErrorLogEntry(ErrorLogEntry);
}
}
@@ -982,14 +988,12 @@ NTAPI
IoCancelIrp(IN PIRP Irp)
{
KIRQL OldIrql;
- KIRQL IrqlAtEntry;
PDRIVER_CANCEL CancelRoutine;
IOTRACE(IO_IRP_DEBUG,
"%s - Canceling IRP %p\n",
__FUNCTION__,
Irp);
ASSERT(Irp->Type == IO_TYPE_IRP);
- IrqlAtEntry = KeGetCurrentIrql();
/* Acquire the cancel lock and cancel the IRP */
IoAcquireCancelSpinLock(&OldIrql);
@@ -1005,7 +1009,7 @@ IoCancelIrp(IN PIRP Irp)
/* It is, bugcheck */
KeBugCheckEx(CANCEL_STATE_IN_COMPLETED_IRP,
(ULONG_PTR)Irp,
- 0,
+ (ULONG_PTR)CancelRoutine,
0,
0);
}
@@ -1013,7 +1017,6 @@ IoCancelIrp(IN PIRP Irp)
/* Set the cancel IRQL And call the routine */
Irp->CancelIrql = OldIrql;
CancelRoutine(IoGetCurrentIrpStackLocation(Irp)->DeviceObject, Irp);
- ASSERT(IrqlAtEntry == KeGetCurrentIrql());
return TRUE;
}
@@ -1034,6 +1037,11 @@ IoCancelThreadIo(IN PETHREAD Thread)
LARGE_INTEGER Interval;
PLIST_ENTRY ListHead, NextEntry;
PIRP Irp;
+ PAGED_CODE();
+
+ /* Windows isn't using given thread, but using current. */
+ Thread = PsGetCurrentThread();
+
IOTRACE(IO_IRP_DEBUG,
"%s - Canceling IRPs for Thread %p\n",
__FUNCTION__,
@@ -1077,7 +1085,7 @@ IoCancelThreadIo(IN PETHREAD Thread)
{
/* Print out a message and remove the IRP */
DPRINT1("Broken driver did not complete!\n");
- IopRemoveThreadIrp();
+ IopDisassociateThreadIrp();
}
/* Raise the IRQL Again */