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/kbdc... ============================================================================== --- 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/mouc... ============================================================================== --- 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.c... ============================================================================== --- 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);