From 1e1d4a34ac9f9127b79b1110d55f0df4413a0e82 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 22 Apr 2010 21:07:46 +0000 Subject: [PATCH] [NTOSKRNL] - Add a stub for IRP_MN_REMOVE_DEVICE in PnpRoot - Revert 2 incorrect changes from r46983 (DNF_ENUMERATED added to the DNF_ADDED assertion and setting the DNF_RESOURCE_REPORTED flag in IopStartDevice2) - Set the DNF_LEGACY_DRIVER flag if the AddDevice handler is missing - Add a helper function called IopSendRemoveDevice which sends IRP_MN_REMOVE_DEVICE to a device object - Call IopSendRemoveDevice if IRP_MN_START_DEVICE fails - Set the DNF_STARTED and DNF_ADDED flags for legacy drivers - Enable the DNF_ADDED assertion in IopStartDevice2 svn path=/trunk/; revision=46997 --- reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 54 ++++++++++++++++++---------- reactos/ntoskrnl/io/pnpmgr/pnproot.c | 5 +++ 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index dbfada18ed9..645b837de81 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -66,19 +66,20 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode, NTSTATUS Status; if (!DriverObject->DriverExtension->AddDevice) + { + DeviceNode->Flags |= DNF_LEGACY_DRIVER; + } + + if (DeviceNode->Flags & DNF_LEGACY_DRIVER) + { + DeviceNode->Flags |= DNF_ADDED + DNF_STARTED; return STATUS_SUCCESS; + } /* This is a Plug and Play driver */ DPRINT("Plug and Play driver found\n"); ASSERT(DeviceNode->PhysicalDeviceObject); - /* Check if this plug-and-play driver is used as a legacy one for this device node */ - if (IopDeviceNodeHasFlag(DeviceNode, DNF_LEGACY_DRIVER)) - { - IopDeviceNodeSetFlag(DeviceNode, DNF_ADDED); - return STATUS_SUCCESS; - } - DPRINT("Calling %wZ->AddDevice(%wZ)\n", &DriverObject->DriverName, &DeviceNode->InstancePath); @@ -122,6 +123,21 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode, return STATUS_SUCCESS; } +VOID +NTAPI +IopSendRemoveDevice(IN PDEVICE_OBJECT DeviceObject) +{ + IO_STACK_LOCATION Stack; + PVOID Dummy; + + RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION)); + Stack.MajorFunction = IRP_MJ_PNP; + Stack.MinorFunction = IRP_MN_REMOVE_DEVICE; + + /* Drivers should never fail a IRP_MN_REMOVE_DEVICE request */ + IopSynchronousCall(DeviceObject, &Stack, &Dummy); +} + VOID NTAPI IopStartDevice2(IN PDEVICE_OBJECT DeviceObject) @@ -156,10 +172,11 @@ IopStartDevice2(IN PDEVICE_OBJECT DeviceObject) Status = IopSynchronousCall(DeviceObject, &Stack, &Dummy); if (!NT_SUCCESS(Status)) { - /* We failed start */ - DeviceNode->Flags |= DNF_START_FAILED; + /* Send an IRP_MN_REMOVE_DEVICE request */ + IopSendRemoveDevice(DeviceObject); - /* TODO: Undo all the stuff we did up to this point */ + /* Set the appropriate flag */ + DeviceNode->Flags |= DNF_START_FAILED; DPRINT1("Warning: PnP Start failed (%wZ)\n", &DeviceNode->InstancePath); return; @@ -168,9 +185,6 @@ IopStartDevice2(IN PDEVICE_OBJECT DeviceObject) /* Otherwise, mark us as started */ DeviceNode->Flags |= DNF_STARTED; - /* We reported the resources */ - DeviceNode->Flags |= DNF_RESOURCE_REPORTED; - /* We now need enumeration */ DeviceNode->Flags |= DNF_NEED_ENUMERATION_ONLY; } @@ -184,10 +198,7 @@ IopStartAndEnumerateDevice(IN PDEVICE_NODE DeviceNode) PAGED_CODE(); /* Sanity check */ - // ASSERT((DeviceNode->Flags & DNF_ADDED) || (DeviceNode->Flags & DNF_ENUMERATED)); - if (!(DeviceNode->Flags & DNF_ADDED) && !(DeviceNode->Flags & DNF_ENUMERATED)) - DPRINT1("Warning: Starting a device node without DNF_ADDED or DNF_ENUMERATED (%wZ)\n", - &DeviceNode->InstancePath); + ASSERT((DeviceNode->Flags & DNF_ADDED)); ASSERT((DeviceNode->Flags & (DNF_RESOURCE_ASSIGNED | DNF_RESOURCE_REPORTED | DNF_NO_RESOURCE_REQUIRED))); @@ -243,6 +254,12 @@ IopStartDevice( UNICODE_STRING KeyName; OBJECT_ATTRIBUTES ObjectAttributes; + if (DeviceNode->Flags & (DNF_STARTED | DNF_START_REQUEST_PENDING)) + { + /* Nothing to do here */ + return STATUS_SUCCESS; + } + Status = IopAssignDeviceResources(DeviceNode); if (!NT_SUCCESS(Status)) goto ByeBye; @@ -542,8 +559,9 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, return Status; } - /* This is for drivers passed on the command line to ntoskrnl.exe */ IopDeviceNodeSetFlag(Node, DNF_LEGACY_DRIVER); + IopDeviceNodeSetFlag(Node, DNF_ADDED); + IopDeviceNodeSetFlag(Node, DNF_STARTED); } Node->PhysicalDeviceObject = PhysicalDeviceObject; diff --git a/reactos/ntoskrnl/io/pnpmgr/pnproot.c b/reactos/ntoskrnl/io/pnpmgr/pnproot.c index 30c612f1fc3..6f1834e5298 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnproot.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnproot.c @@ -1069,6 +1069,11 @@ PnpRootPdoPnpControl( DPRINT("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"); break; + case IRP_MN_REMOVE_DEVICE: + DPRINT1("IRP_MN_REMOVE_DEVICE is UNIMPLEMENTED!\n"); + Status = STATUS_SUCCESS; + break; + case IRP_MN_QUERY_ID: /* 0x13 */ Status = PdoQueryId(DeviceObject, Irp, IrpSp); break;