mirror of
https://github.com/reactos/reactos.git
synced 2025-05-08 03:07:05 +00:00
[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. svn path=/trunk/; revision=63360
This commit is contained in:
parent
05f75e278b
commit
0e26222a74
6 changed files with 118 additions and 16 deletions
|
@ -644,6 +644,26 @@ i8042PnpStartDevice(
|
||||||
return Status;
|
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
|
NTSTATUS NTAPI
|
||||||
i8042Pnp(
|
i8042Pnp(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
@ -710,6 +730,23 @@ i8042Pnp(
|
||||||
TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n");
|
TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n");
|
||||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
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:
|
default:
|
||||||
{
|
{
|
||||||
ERR_(I8042PRT, "IRP_MJ_PNP / unknown minor function 0x%x\n", MinorFunction);
|
ERR_(I8042PRT, "IRP_MJ_PNP / unknown minor function 0x%x\n", MinorFunction);
|
||||||
|
|
|
@ -606,7 +606,7 @@ DestroyPortDriver(
|
||||||
|
|
||||||
/* Remove from ClassDeviceExtension->ListHead list */
|
/* Remove from ClassDeviceExtension->ListHead list */
|
||||||
KeAcquireSpinLock(&ClassDeviceExtension->ListSpinLock, &OldIrql);
|
KeAcquireSpinLock(&ClassDeviceExtension->ListSpinLock, &OldIrql);
|
||||||
RemoveHeadList(DeviceExtension->ListEntry.Blink);
|
RemoveEntryList(&DeviceExtension->ListEntry);
|
||||||
KeReleaseSpinLock(&ClassDeviceExtension->ListSpinLock, OldIrql);
|
KeReleaseSpinLock(&ClassDeviceExtension->ListSpinLock, OldIrql);
|
||||||
|
|
||||||
/* Remove entry from HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\[DeviceBaseName] */
|
/* Remove entry from HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\[DeviceBaseName] */
|
||||||
|
@ -865,7 +865,6 @@ ClassPnp(
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
return Status;
|
return Status;
|
||||||
|
|
||||||
case IRP_MN_REMOVE_DEVICE:
|
|
||||||
case IRP_MN_STOP_DEVICE:
|
case IRP_MN_STOP_DEVICE:
|
||||||
if (DeviceExtension->FileHandle)
|
if (DeviceExtension->FileHandle)
|
||||||
{
|
{
|
||||||
|
@ -874,6 +873,17 @@ ClassPnp(
|
||||||
}
|
}
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
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:
|
default:
|
||||||
Status = Irp->IoStatus.Status;
|
Status = Irp->IoStatus.Status;
|
||||||
|
|
|
@ -582,7 +582,7 @@ DestroyPortDriver(
|
||||||
|
|
||||||
/* Remove from ClassDeviceExtension->ListHead list */
|
/* Remove from ClassDeviceExtension->ListHead list */
|
||||||
KeAcquireSpinLock(&ClassDeviceExtension->ListSpinLock, &OldIrql);
|
KeAcquireSpinLock(&ClassDeviceExtension->ListSpinLock, &OldIrql);
|
||||||
RemoveHeadList(DeviceExtension->ListEntry.Blink);
|
RemoveEntryList(&DeviceExtension->ListEntry);
|
||||||
KeReleaseSpinLock(&ClassDeviceExtension->ListSpinLock, OldIrql);
|
KeReleaseSpinLock(&ClassDeviceExtension->ListSpinLock, OldIrql);
|
||||||
|
|
||||||
/* Remove entry from HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\[DeviceBaseName] */
|
/* Remove entry from HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\[DeviceBaseName] */
|
||||||
|
@ -841,7 +841,6 @@ ClassPnp(
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
return Status;
|
return Status;
|
||||||
|
|
||||||
case IRP_MN_REMOVE_DEVICE:
|
|
||||||
case IRP_MN_STOP_DEVICE:
|
case IRP_MN_STOP_DEVICE:
|
||||||
if (DeviceExtension->FileHandle)
|
if (DeviceExtension->FileHandle)
|
||||||
{
|
{
|
||||||
|
@ -850,6 +849,17 @@ ClassPnp(
|
||||||
}
|
}
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
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:
|
default:
|
||||||
Status = Irp->IoStatus.Status;
|
Status = Irp->IoStatus.Status;
|
||||||
|
|
|
@ -558,6 +558,10 @@ IopAttachFilterDriversCallback(
|
||||||
PLDR_DATA_TABLE_ENTRY ModuleObject;
|
PLDR_DATA_TABLE_ENTRY ModuleObject;
|
||||||
PDRIVER_OBJECT DriverObject;
|
PDRIVER_OBJECT DriverObject;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* No filter value present */
|
||||||
|
if (ValueType == REG_NONE)
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
for (Filters = ValueData;
|
for (Filters = ValueData;
|
||||||
((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength &&
|
((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength &&
|
||||||
|
@ -578,18 +582,21 @@ IopAttachFilterDriversCallback(
|
||||||
/* Load and initialize the filter driver */
|
/* Load and initialize the filter driver */
|
||||||
Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
|
Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
continue;
|
return Status;
|
||||||
|
|
||||||
Status = IopInitializeDriverModule(DeviceNode, ModuleObject, &ServiceName,
|
Status = IopInitializeDriverModule(DeviceNode, ModuleObject, &ServiceName,
|
||||||
FALSE, &DriverObject);
|
FALSE, &DriverObject);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
continue;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = IopInitializeDevice(DeviceNode, DriverObject);
|
Status = IopInitializeDevice(DeviceNode, DriverObject);
|
||||||
|
|
||||||
/* Remove extra reference */
|
/* Remove extra reference */
|
||||||
ObDereferenceObject(DriverObject);
|
ObDereferenceObject(DriverObject);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -645,14 +652,23 @@ IopAttachFilterDrivers(
|
||||||
QueryTable[0].Name = L"LowerFilters";
|
QueryTable[0].Name = L"LowerFilters";
|
||||||
else
|
else
|
||||||
QueryTable[0].Name = L"UpperFilters";
|
QueryTable[0].Name = L"UpperFilters";
|
||||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
|
QueryTable[0].Flags = 0;
|
||||||
|
QueryTable[0].DefaultType = REG_NONE;
|
||||||
|
|
||||||
RtlQueryRegistryValues(
|
Status = RtlQueryRegistryValues(
|
||||||
RTL_REGISTRY_HANDLE,
|
RTL_REGISTRY_HANDLE,
|
||||||
(PWSTR)SubKey,
|
(PWSTR)SubKey,
|
||||||
QueryTable,
|
QueryTable,
|
||||||
DeviceNode,
|
DeviceNode,
|
||||||
NULL);
|
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
|
* Now get the class GUID
|
||||||
|
@ -696,9 +712,10 @@ IopAttachFilterDrivers(
|
||||||
&Class, KEY_READ);
|
&Class, KEY_READ);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* It's okay if there's no class key */
|
||||||
DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
|
DPRINT1("ZwOpenKey() failed with Status %08X\n", Status);
|
||||||
ZwClose(EnumRootKey);
|
ZwClose(EnumRootKey);
|
||||||
return Status;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback;
|
QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback;
|
||||||
|
@ -707,9 +724,10 @@ IopAttachFilterDrivers(
|
||||||
else
|
else
|
||||||
QueryTable[0].Name = L"UpperFilters";
|
QueryTable[0].Name = L"UpperFilters";
|
||||||
QueryTable[0].EntryContext = NULL;
|
QueryTable[0].EntryContext = NULL;
|
||||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
|
QueryTable[0].Flags = 0;
|
||||||
|
QueryTable[0].DefaultType = REG_NONE;
|
||||||
|
|
||||||
RtlQueryRegistryValues(
|
Status = RtlQueryRegistryValues(
|
||||||
RTL_REGISTRY_HANDLE,
|
RTL_REGISTRY_HANDLE,
|
||||||
(PWSTR)SubKey,
|
(PWSTR)SubKey,
|
||||||
QueryTable,
|
QueryTable,
|
||||||
|
@ -719,6 +737,15 @@ IopAttachFilterDrivers(
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
ZwClose(SubKey);
|
ZwClose(SubKey);
|
||||||
ZwClose(EnumRootKey);
|
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;
|
return STATUS_SUCCESS;
|
||||||
|
|
|
@ -275,10 +275,10 @@ PipCallDriverAddDevice(IN PDEVICE_NODE DeviceNode,
|
||||||
EnumRootKey,
|
EnumRootKey,
|
||||||
&DeviceNode->InstancePath,
|
&DeviceNode->InstancePath,
|
||||||
KEY_READ);
|
KEY_READ);
|
||||||
|
ZwClose(EnumRootKey);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
|
DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
|
||||||
ZwClose(EnumRootKey);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,12 +330,17 @@ PipCallDriverAddDevice(IN PDEVICE_NODE DeviceNode,
|
||||||
ClassKey,
|
ClassKey,
|
||||||
&Properties,
|
&Properties,
|
||||||
KEY_READ);
|
KEY_READ);
|
||||||
|
ZwClose(ClassKey);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* No properties */
|
/* No properties */
|
||||||
DPRINT("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
|
DPRINT("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
|
||||||
PropertiesKey = NULL;
|
PropertiesKey = NULL;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ZwClose(PropertiesKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free the registry data */
|
/* Free the registry data */
|
||||||
|
@ -343,11 +348,22 @@ PipCallDriverAddDevice(IN PDEVICE_NODE DeviceNode,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do ReactOS-style setup */
|
/* Do ReactOS-style setup */
|
||||||
IopAttachFilterDrivers(DeviceNode, TRUE);
|
Status = IopAttachFilterDrivers(DeviceNode, TRUE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
IopRemoveDevice(DeviceNode);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
Status = IopInitializeDevice(DeviceNode, DriverObject);
|
Status = IopInitializeDevice(DeviceNode, DriverObject);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
IopAttachFilterDrivers(DeviceNode, FALSE);
|
Status = IopAttachFilterDrivers(DeviceNode, FALSE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
IopRemoveDevice(DeviceNode);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
Status = IopStartDevice(DeviceNode);
|
Status = IopStartDevice(DeviceNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -580,7 +580,11 @@ IopSendRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
IO_STACK_LOCATION Stack;
|
IO_STACK_LOCATION Stack;
|
||||||
PVOID Dummy;
|
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));
|
RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
|
||||||
Stack.MajorFunction = IRP_MJ_PNP;
|
Stack.MajorFunction = IRP_MJ_PNP;
|
||||||
Stack.MinorFunction = IRP_MN_REMOVE_DEVICE;
|
Stack.MinorFunction = IRP_MN_REMOVE_DEVICE;
|
||||||
|
@ -4537,8 +4541,6 @@ IopPrepareDeviceForRemoval(IN PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceNode->Flags |= DNF_WILL_BE_REMOVED;
|
|
||||||
DeviceNode->Problem = CM_PROB_WILL_BE_REMOVED;
|
|
||||||
if (DeviceRelations)
|
if (DeviceRelations)
|
||||||
IopSendRemoveDeviceRelations(DeviceRelations);
|
IopSendRemoveDeviceRelations(DeviceRelations);
|
||||||
IopSendRemoveChildDevices(DeviceNode);
|
IopSendRemoveChildDevices(DeviceNode);
|
||||||
|
|
Loading…
Reference in a new issue