Author: cgutman
Date: Sun May 18 20:39:54 2014
New Revision: 63360
URL:
http://svn.reactos.org/svn/reactos?rev=63360&view=rev
Log:
[NTOSKRNL]
- Fail device initialization if a filter fails to load so the PnP manager can try again
later
- Fix some handle leaks
- Reset device node flags after a remove IRP is sent
[I8042PRT|MOUCLASS|KBDCLASS]
- Implement proper support for PnP remove IRPs
See issue #8238 for more details.
Modified:
trunk/reactos/drivers/input/i8042prt/pnp.c
trunk/reactos/drivers/input/kbdclass/kbdclass.c
trunk/reactos/drivers/input/mouclass/mouclass.c
trunk/reactos/ntoskrnl/io/iomgr/driver.c
trunk/reactos/ntoskrnl/io/pnpmgr/pnpinit.c
trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
Modified: trunk/reactos/drivers/input/i8042prt/pnp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/i8042prt/pnp…
==============================================================================
--- trunk/reactos/drivers/input/i8042prt/pnp.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/input/i8042prt/pnp.c [iso-8859-1] Sun May 18 20:39:54 2014
@@ -644,6 +644,26 @@
return Status;
}
+static VOID
+i8042RemoveDevice(
+ IN PDEVICE_OBJECT DeviceObject)
+{
+ PI8042_DRIVER_EXTENSION DriverExtension;
+ KIRQL OldIrql;
+ PFDO_DEVICE_EXTENSION DeviceExtension;
+
+ DriverExtension =
(PI8042_DRIVER_EXTENSION)IoGetDriverObjectExtension(DeviceObject->DriverObject,
DeviceObject->DriverObject);
+ DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ KeAcquireSpinLock(&DriverExtension->DeviceListLock, &OldIrql);
+ RemoveEntryList(&DeviceExtension->ListEntry);
+ KeReleaseSpinLock(&DriverExtension->DeviceListLock, OldIrql);
+
+ IoDetachDevice(DeviceExtension->LowerDevice);
+
+ IoDeleteDevice(DeviceObject);
+}
+
NTSTATUS NTAPI
i8042Pnp(
IN PDEVICE_OBJECT DeviceObject,
@@ -710,6 +730,23 @@
TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n");
return ForwardIrpAndForget(DeviceObject, Irp);
}
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ {
+ TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_REMOVE_DEVICE\n");
+ return ForwardIrpAndForget(DeviceObject, Irp);
+ }
+ case IRP_MN_CANCEL_REMOVE_DEVICE:
+ {
+ TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_CANCEL_REMOVE_DEVICE\n");
+ return ForwardIrpAndForget(DeviceObject, Irp);
+ }
+ case IRP_MN_REMOVE_DEVICE:
+ {
+ TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
+ Status = ForwardIrpAndForget(DeviceObject, Irp);
+ i8042RemoveDevice(DeviceObject);
+ return Status;
+ }
default:
{
ERR_(I8042PRT, "IRP_MJ_PNP / unknown minor function 0x%x\n",
MinorFunction);
Modified: trunk/reactos/drivers/input/kbdclass/kbdclass.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/kbdclass/kbd…
==============================================================================
--- trunk/reactos/drivers/input/kbdclass/kbdclass.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/input/kbdclass/kbdclass.c [iso-8859-1] Sun May 18 20:39:54 2014
@@ -606,7 +606,7 @@
/* Remove from ClassDeviceExtension->ListHead list */
KeAcquireSpinLock(&ClassDeviceExtension->ListSpinLock, &OldIrql);
- RemoveHeadList(DeviceExtension->ListEntry.Blink);
+ RemoveEntryList(&DeviceExtension->ListEntry);
KeReleaseSpinLock(&ClassDeviceExtension->ListSpinLock, OldIrql);
/* Remove entry from HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\[DeviceBaseName] */
@@ -865,7 +865,6 @@
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
- case IRP_MN_REMOVE_DEVICE:
case IRP_MN_STOP_DEVICE:
if (DeviceExtension->FileHandle)
{
@@ -874,6 +873,17 @@
}
Status = STATUS_SUCCESS;
break;
+
+ case IRP_MN_REMOVE_DEVICE:
+ if (DeviceExtension->FileHandle)
+ {
+ ZwClose(DeviceExtension->FileHandle);
+ DeviceExtension->FileHandle = NULL;
+ }
+ IoSkipCurrentIrpStackLocation(Irp);
+ Status = IoCallDriver(DeviceExtension->LowerDevice, Irp);
+ DestroyPortDriver(DeviceObject);
+ return Status;
default:
Status = Irp->IoStatus.Status;
Modified: trunk/reactos/drivers/input/mouclass/mouclass.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/mouclass/mou…
==============================================================================
--- trunk/reactos/drivers/input/mouclass/mouclass.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/input/mouclass/mouclass.c [iso-8859-1] Sun May 18 20:39:54 2014
@@ -582,7 +582,7 @@
/* Remove from ClassDeviceExtension->ListHead list */
KeAcquireSpinLock(&ClassDeviceExtension->ListSpinLock, &OldIrql);
- RemoveHeadList(DeviceExtension->ListEntry.Blink);
+ RemoveEntryList(&DeviceExtension->ListEntry);
KeReleaseSpinLock(&ClassDeviceExtension->ListSpinLock, OldIrql);
/* Remove entry from HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\[DeviceBaseName] */
@@ -841,7 +841,6 @@
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
- case IRP_MN_REMOVE_DEVICE:
case IRP_MN_STOP_DEVICE:
if (DeviceExtension->FileHandle)
{
@@ -850,6 +849,17 @@
}
Status = STATUS_SUCCESS;
break;
+
+ case IRP_MN_REMOVE_DEVICE:
+ if (DeviceExtension->FileHandle)
+ {
+ ZwClose(DeviceExtension->FileHandle);
+ DeviceExtension->FileHandle = NULL;
+ }
+ IoSkipCurrentIrpStackLocation(Irp);
+ Status = IoCallDriver(DeviceExtension->LowerDevice, Irp);
+ DestroyPortDriver(DeviceObject);
+ return Status;
default:
Status = Irp->IoStatus.Status;
Modified: trunk/reactos/ntoskrnl/io/iomgr/driver.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/driver.c…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/driver.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/driver.c [iso-8859-1] Sun May 18 20:39:54 2014
@@ -558,6 +558,10 @@
PLDR_DATA_TABLE_ENTRY ModuleObject;
PDRIVER_OBJECT DriverObject;
NTSTATUS Status;
+
+ /* No filter value present */
+ if (ValueType == REG_NONE)
+ return STATUS_SUCCESS;
for (Filters = ValueData;
((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength &&
@@ -578,18 +582,21 @@
/* Load and initialize the filter driver */
Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
if (!NT_SUCCESS(Status))
- continue;
+ return Status;
Status = IopInitializeDriverModule(DeviceNode, ModuleObject,
&ServiceName,
FALSE, &DriverObject);
if (!NT_SUCCESS(Status))
- continue;
+ return Status;
}
Status = IopInitializeDevice(DeviceNode, DriverObject);
/* Remove extra reference */
ObDereferenceObject(DriverObject);
+
+ if (!NT_SUCCESS(Status))
+ return Status;
}
return STATUS_SUCCESS;
@@ -645,14 +652,23 @@
QueryTable[0].Name = L"LowerFilters";
else
QueryTable[0].Name = L"UpperFilters";
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
-
- RtlQueryRegistryValues(
+ QueryTable[0].Flags = 0;
+ QueryTable[0].DefaultType = REG_NONE;
+
+ Status = RtlQueryRegistryValues(
RTL_REGISTRY_HANDLE,
(PWSTR)SubKey,
QueryTable,
DeviceNode,
NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to load device %s filters: %08X\n",
+ Lower ? "lower" : "upper", Status);
+ ZwClose(SubKey);
+ ZwClose(EnumRootKey);
+ return Status;
+ }
/*
* Now get the class GUID
@@ -696,9 +712,10 @@
&Class, KEY_READ);
if (!NT_SUCCESS(Status))
{
+ /* It's okay if there's no class key */
DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
ZwClose(EnumRootKey);
- return Status;
+ return STATUS_SUCCESS;
}
QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback;
@@ -707,9 +724,10 @@
else
QueryTable[0].Name = L"UpperFilters";
QueryTable[0].EntryContext = NULL;
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
-
- RtlQueryRegistryValues(
+ QueryTable[0].Flags = 0;
+ QueryTable[0].DefaultType = REG_NONE;
+
+ Status = RtlQueryRegistryValues(
RTL_REGISTRY_HANDLE,
(PWSTR)SubKey,
QueryTable,
@@ -719,6 +737,15 @@
/* Clean up */
ZwClose(SubKey);
ZwClose(EnumRootKey);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to load class %s filters: %08X\n",
+ Lower ? "lower" : "upper", Status);
+ ZwClose(SubKey);
+ ZwClose(EnumRootKey);
+ return Status;
+ }
}
return STATUS_SUCCESS;
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpinit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpinit…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpinit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpinit.c [iso-8859-1] Sun May 18 20:39:54 2014
@@ -275,10 +275,10 @@
EnumRootKey,
&DeviceNode->InstancePath,
KEY_READ);
+ ZwClose(EnumRootKey);
if (!NT_SUCCESS(Status))
{
DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
- ZwClose(EnumRootKey);
return Status;
}
@@ -330,12 +330,17 @@
ClassKey,
&Properties,
KEY_READ);
+ ZwClose(ClassKey);
if (!NT_SUCCESS(Status))
{
/* No properties */
DPRINT("IopOpenRegistryKeyEx() failed with Status %08X\n",
Status);
PropertiesKey = NULL;
}
+ else
+ {
+ ZwClose(PropertiesKey);
+ }
}
/* Free the registry data */
@@ -343,11 +348,22 @@
}
/* Do ReactOS-style setup */
- IopAttachFilterDrivers(DeviceNode, TRUE);
+ Status = IopAttachFilterDrivers(DeviceNode, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ IopRemoveDevice(DeviceNode);
+ return Status;
+ }
Status = IopInitializeDevice(DeviceNode, DriverObject);
if (NT_SUCCESS(Status))
{
- IopAttachFilterDrivers(DeviceNode, FALSE);
+ Status = IopAttachFilterDrivers(DeviceNode, FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ IopRemoveDevice(DeviceNode);
+ return Status;
+ }
+
Status = IopStartDevice(DeviceNode);
}
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] Sun May 18 20:39:54 2014
@@ -580,7 +580,11 @@
{
IO_STACK_LOCATION Stack;
PVOID Dummy;
-
+ PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
+
+ /* Drop all our state for this device in case it isn't really going away */
+ DeviceNode->Flags &= DNF_ENUMERATED | DNF_PROCESSED;
+
RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
Stack.MajorFunction = IRP_MJ_PNP;
Stack.MinorFunction = IRP_MN_REMOVE_DEVICE;
@@ -4537,8 +4541,6 @@
return Status;
}
- DeviceNode->Flags |= DNF_WILL_BE_REMOVED;
- DeviceNode->Problem = CM_PROB_WILL_BE_REMOVED;
if (DeviceRelations)
IopSendRemoveDeviceRelations(DeviceRelations);
IopSendRemoveChildDevices(DeviceNode);