mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +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;
|
||||
}
|
||||
|
||||
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 @@ i8042Pnp(
|
|||
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);
|
||||
|
|
|
@ -606,7 +606,7 @@ DestroyPortDriver(
|
|||
|
||||
/* 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 @@ ClassPnp(
|
|||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
case IRP_MN_STOP_DEVICE:
|
||||
if (DeviceExtension->FileHandle)
|
||||
{
|
||||
|
@ -874,6 +873,17 @@ ClassPnp(
|
|||
}
|
||||
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;
|
||||
|
|
|
@ -582,7 +582,7 @@ DestroyPortDriver(
|
|||
|
||||
/* 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 @@ ClassPnp(
|
|||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
case IRP_MN_STOP_DEVICE:
|
||||
if (DeviceExtension->FileHandle)
|
||||
{
|
||||
|
@ -850,6 +849,17 @@ ClassPnp(
|
|||
}
|
||||
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;
|
||||
|
|
|
@ -558,6 +558,10 @@ IopAttachFilterDriversCallback(
|
|||
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 @@ IopAttachFilterDriversCallback(
|
|||
/* 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 @@ IopAttachFilterDrivers(
|
|||
QueryTable[0].Name = L"LowerFilters";
|
||||
else
|
||||
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,
|
||||
(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 @@ IopAttachFilterDrivers(
|
|||
&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 @@ IopAttachFilterDrivers(
|
|||
else
|
||||
QueryTable[0].Name = L"UpperFilters";
|
||||
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,
|
||||
(PWSTR)SubKey,
|
||||
QueryTable,
|
||||
|
@ -719,6 +737,15 @@ IopAttachFilterDrivers(
|
|||
/* 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;
|
||||
|
|
|
@ -275,10 +275,10 @@ PipCallDriverAddDevice(IN PDEVICE_NODE DeviceNode,
|
|||
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 @@ PipCallDriverAddDevice(IN PDEVICE_NODE DeviceNode,
|
|||
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 @@ PipCallDriverAddDevice(IN PDEVICE_NODE DeviceNode,
|
|||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -580,7 +580,11 @@ IopSendRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
|
|||
{
|
||||
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 @@ IopPrepareDeviceForRemoval(IN PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
|
|||
return Status;
|
||||
}
|
||||
|
||||
DeviceNode->Flags |= DNF_WILL_BE_REMOVED;
|
||||
DeviceNode->Problem = CM_PROB_WILL_BE_REMOVED;
|
||||
if (DeviceRelations)
|
||||
IopSendRemoveDeviceRelations(DeviceRelations);
|
||||
IopSendRemoveChildDevices(DeviceNode);
|
||||
|
|
Loading…
Reference in a new issue