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);