Author: cgutman Date: Tue May 31 19:34:08 2011 New Revision: 52029
URL: http://svn.reactos.org/svn/reactos?rev=52029&view=rev Log: [NTOSKRNL] - Implement IopRemoveDevice and IopStopDevice - Do a graceful remove before installing new drivers (like Windows does) - Debug log warnings abound (don't be alarmed ;)) because drivers aren't used to receiving IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_REMOVE_DEVICE and IRP_MN_QUERY_PNP_DEVICE_STATE from our (formly) crippled PnP manager
Modified: trunk/reactos/ntoskrnl/include/internal/io.h trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
Modified: trunk/reactos/ntoskrnl/include/internal/io.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/i... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] Tue May 31 19:34:08 2011 @@ -790,6 +790,16 @@ IN PDEVICE_NODE DeviceNode );
+NTSTATUS +IopStopDevice( + IN PDEVICE_NODE DeviceNode +); + +NTSTATUS +IopRemoveDevice( + IN PDEVICE_NODE DeviceNode +); + PVPB NTAPI IopCheckVpbMounted(
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/plugplay... ============================================================================== --- trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c [iso-8859-1] Tue May 31 19:34:08 2011 @@ -551,10 +551,18 @@
DeviceNode = IopGetDeviceNode(DeviceObject);
- /* FIXME: we should stop the device, before starting it again */ - - /* Start the device */ - IopDeviceNodeClearFlag(DeviceNode, DNF_DISABLED); + /* Remove the device */ + if (DeviceNode->Flags & DNF_ENUMERATED) + { + Status = IopRemoveDevice(DeviceNode); + if (!NT_SUCCESS(Status)) + { + DPRINT1("WARNING: Ignoring failed IopRemoveDevice() for %wZ (likely a driver bug)\n", &DeviceNode->InstancePath); + } + } + + /* Reenumerate the device and its children */ + DeviceNode->Flags &= ~DNF_DISABLED; Status = IopActionConfigureChildServices(DeviceNode, DeviceNode->Parent);
if (NT_SUCCESS(Status))
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] Tue May 31 19:34:08 2011 @@ -335,6 +335,24 @@
/* Return */ return Status; +} + +NTSTATUS +IopStopDevice( + PDEVICE_NODE DeviceNode) +{ + NTSTATUS Status; + + DPRINT("Stopping device: %wZ\n", &DeviceNode->InstancePath); + + Status = IopQueryStopDevice(DeviceNode->PhysicalDeviceObject); + if (!NT_SUCCESS(Status)) + { + IopSendStopDevice(DeviceNode->PhysicalDeviceObject); + return STATUS_SUCCESS; + } + + return Status; }
NTSTATUS @@ -420,7 +438,7 @@ return Status; }
- DeviceNode->CapabilityFlags = *(PULONG)((ULONG_PTR)&DeviceCaps + 4); + DeviceNode->CapabilityFlags = *(PULONG)((ULONG_PTR)&DeviceCaps->Version + sizeof(DeviceCaps->Version));;
if (DeviceCaps->NoDisplayInUI) DeviceNode->UserFlags |= DNUF_DONT_SHOW_IN_UI; @@ -3873,6 +3891,12 @@ PDEVICE_RELATIONS DeviceRelations; NTSTATUS Status; ULONG i; + + if (DeviceNode->UserFlags & DNUF_NOT_DISABLEABLE) + { + DPRINT1("Removal not allowed for %wZ\n", &DeviceNode->InstancePath); + return STATUS_UNSUCCESSFUL; + }
IopQueueTargetDeviceEvent(&GUID_DEVICE_REMOVE_PENDING, &DeviceNode->InstancePath); @@ -3958,6 +3982,23 @@ return Status; }
+NTSTATUS +IopRemoveDevice(PDEVICE_NODE DeviceNode) +{ + NTSTATUS Status; + + DPRINT("Removing device: %wZ\n", &DeviceNode->InstancePath); + + Status = IopPrepareDeviceForRemoval(DeviceNode->PhysicalDeviceObject); + if (NT_SUCCESS(Status)) + { + IopSendRemoveDevice(DeviceNode->PhysicalDeviceObject); + return STATUS_SUCCESS; + } + + return Status; +} + /* * @implemented */