[USB]
[reactos.git] / reactos / ntoskrnl / io / pnpmgr / plugplay.c
index 492d4a1..b3ead8b 100644 (file)
@@ -98,7 +98,7 @@ IopRemovePlugPlayEvent(VOID)
     /* Remove a pnp event entry from the tail of the queue */
     if (!IsListEmpty(&IopPnpEventQueueHead))
     {
-        ExFreePool(RemoveTailList(&IopPnpEventQueueHead));
+        ExFreePool(CONTAINING_RECORD(RemoveTailList(&IopPnpEventQueueHead), PNP_EVENT_ENTRY, ListEntry));
     }
 
     /* Signal the next pnp event in the queue */
@@ -549,16 +549,42 @@ IopResetDevice(PPLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData)
     if (DeviceObject == NULL)
         return STATUS_NO_SUCH_DEVICE;
 
+    /* Get the device node */
     DeviceNode = IopGetDeviceNode(DeviceObject);
 
-    /* FIXME: we should stop the device, before starting it again */
+    /* Check if an FDO has been added to the stack */
+    if (DeviceNode->Flags & DNF_ADDED)
+    {
+        /* Remove the device node */
+        Status = IopRemoveDevice(DeviceNode);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("WARNING: Ignoring failed IopRemoveDevice() for %wZ (likely a driver bug)\n", &DeviceNode->InstancePath);
+        }
 
-    /* Start the device */
-    IopDeviceNodeClearFlag(DeviceNode, DNF_DISABLED);
-    Status = IopActionConfigureChildServices(DeviceNode, DeviceNode->Parent);
+        /* Invalidate device relations for the parent to reenumerate the device */
+        Status = IoSynchronousInvalidateDeviceRelations(DeviceNode->Parent->PhysicalDeviceObject, BusRelations);
 
-    if (NT_SUCCESS(Status))
-        Status = IopActionInitChildServices(DeviceNode, DeviceNode->Parent);
+        DPRINT1("Reset PDO with FDO present: 0x%x\n", Status);
+    }
+    else
+    {
+        /* FIXME: We might clear some important flags */
+        ASSERT(DeviceNode->Flags & DNF_ENUMERATED);
+        ASSERT(DeviceNode->Flags & DNF_PROCESSED);
+        DeviceNode->Flags = DNF_ENUMERATED | DNF_PROCESSED;
+
+        /* Load service data from the registry */
+        Status = IopActionConfigureChildServices(DeviceNode, DeviceNode->Parent);
+
+        if (NT_SUCCESS(Status))
+        {
+            /* Start the service and begin PnP initialization of the device again */
+            Status = IopActionInitChildServices(DeviceNode, DeviceNode->Parent);
+        }
+
+        DPRINT1("Reset PDO with no FDO present: 0x%x\n", Status);
+    }
 
     ObDereferenceObject(DeviceObject);