Author: cgutman Date: Thu May 26 20:39:15 2011 New Revision: 51930
URL: http://svn.reactos.org/svn/reactos?rev=51930&view=rev Log: [NTOSKRNL] - Implement the kernel side of surprise device removal including sending the appropriate IRPs and notifying the user-mode PnP manager - Fix the completely broken GUID_DEVICE_ARRIVAL notification (we were sending it for the parent not the children and we were sending regardless of whether any device had actually arrived)
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
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] Thu May 26 20:39:15 2011 @@ -123,6 +123,21 @@ IopDeviceNodeSetFlag(DeviceNode, DNF_ADDED);
return STATUS_SUCCESS; +} + +VOID +NTAPI +IopSendSurpriseRemoval(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_SURPRISE_REMOVAL; + + /* Drivers should never fail a IRP_MN_SURPRISE_REMOVAL request */ + IopSynchronousCall(DeviceObject, &Stack, &Dummy); }
VOID @@ -1566,6 +1581,44 @@ return STATUS_SUCCESS; }
+static +VOID +IopHandleDeviceRemoval( + IN PDEVICE_NODE DeviceNode, + IN PDEVICE_RELATIONS DeviceRelations) +{ + PDEVICE_NODE Child = DeviceNode->Child, NextChild; + ULONG i; + BOOLEAN Found; + + while (Child != NULL) + { + NextChild = Child->Sibling; + Found = FALSE; + + for (i = 0; i < DeviceRelations->Count; i++) + { + if (IopGetDeviceNode(DeviceRelations->Objects[i]) == Child) + { + Found = TRUE; + break; + } + } + + if (!Found) + { + IopSendSurpriseRemoval(Child->PhysicalDeviceObject); + + /* Tell the user-mode PnP manager that a device was removed */ + IopQueueTargetDeviceEvent(&GUID_DEVICE_SURPRISE_REMOVAL, + &Child->InstancePath); + + IopSendRemoveDevice(Child->PhysicalDeviceObject); + } + + Child = NextChild; + } +}
NTSTATUS IopEnumerateDevice( @@ -1583,12 +1636,6 @@
DPRINT("DeviceObject 0x%p\n", DeviceObject);
- DPRINT("Sending GUID_DEVICE_ARRIVAL\n"); - - /* Report the device to the user-mode pnp manager */ - IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL, - &DeviceNode->InstancePath); - DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
Stack.Parameters.QueryDeviceRelations.Type = BusRelations; @@ -1613,6 +1660,11 @@ }
DPRINT("Got %u PDOs\n", DeviceRelations->Count); + + /* + * Send removal IRPs for devices that have disappeared + */ + IopHandleDeviceRemoval(DeviceNode, DeviceRelations);
/* * Create device nodes for all discovered devices @@ -1633,6 +1685,12 @@ &ChildDeviceNode); if (NT_SUCCESS(Status)) { + DPRINT("Sending GUID_DEVICE_ARRIVAL\n"); + + /* Report the device to the user-mode pnp manager */ + IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL, + &ChildDeviceNode->InstancePath); + /* Mark the node as enumerated */ ChildDeviceNode->Flags |= DNF_ENUMERATED;