NtPlugPlayControl: Implement PlugPlayControlResetDevice case
Modified: trunk/reactos/include/ndk/cmtypes.h
Modified: trunk/reactos/ntoskrnl/include/internal/io.h
Modified: trunk/reactos/ntoskrnl/io/plugplay.c

Modified: trunk/reactos/include/ndk/cmtypes.h
--- trunk/reactos/include/ndk/cmtypes.h	2005-10-08 13:57:36 UTC (rev 18334)
+++ trunk/reactos/include/ndk/cmtypes.h	2005-10-08 14:47:25 UTC (rev 18335)
@@ -65,7 +65,8 @@
     PlugPlayControlProperty = 0x0A,
     PlugPlayControlGetRelatedDevice = 0x0C,
     PlugPlayControlDeviceStatus = 0x0E,
-    PlugPlayControlGetDeviceDepth
+    PlugPlayControlGetDeviceDepth,
+    PlugPlayControlResetDevice = 0x14
 } PLUGPLAY_CONTROL_CLASS;
 
 typedef enum _PLUGPLAY_BUS_CLASS
@@ -362,12 +363,18 @@
 } PLUGPLAY_CONTROL_STATUS_DATA, *PPLUGPLAY_CONTROL_STATUS_DATA;
 
 /* Class 0x0F */
-typedef struct _PLUGPLAY_CONTOL_DEPTH_DATA
+typedef struct _PLUGPLAY_CONTROL_DEPTH_DATA
 {
     UNICODE_STRING DeviceInstance;
     ULONG Depth;
 } PLUGPLAY_CONTROL_DEPTH_DATA, *PPLUGPLAY_CONTROL_DEPTH_DATA;
 
+/* Class 0x14 */
+typedef struct _PLUGPLAY_CONTROL_RESET_DEVICE_DATA
+{
+   UNICODE_STRING DeviceInstance;
+} PLUGPLAY_CONTROL_RESET_DEVICE_DATA, *PPLUGPLAY_CONTROL_RESET_DEVICE_DATA;
+
 typedef struct _PLUGPLAY_BUS_TYPE
 {
     PLUGPLAY_BUS_CLASS BusClass;

Modified: trunk/reactos/ntoskrnl/include/internal/io.h
--- trunk/reactos/ntoskrnl/include/internal/io.h	2005-10-08 13:57:36 UTC (rev 18334)
+++ trunk/reactos/ntoskrnl/include/internal/io.h	2005-10-08 14:47:25 UTC (rev 18335)
@@ -304,6 +304,22 @@
                  PUNICODE_STRING RegistryPath);
 
 
+/* pnpmgr.c */
+
+PDEVICE_NODE
+FASTCALL
+IopGetDeviceNode(PDEVICE_OBJECT DeviceObject);
+
+NTSTATUS
+IopActionConfigureChildServices(PDEVICE_NODE DeviceNode,
+                                PVOID Context);
+
+NTSTATUS
+IopActionInitChildServices(PDEVICE_NODE DeviceNode,
+                           PVOID Context,
+                           BOOLEAN BootDrivers);
+
+
 /* pnproot.c */
 
 NTSTATUS

Modified: trunk/reactos/ntoskrnl/io/plugplay.c
--- trunk/reactos/ntoskrnl/io/plugplay.c	2005-10-08 13:57:36 UTC (rev 18334)
+++ trunk/reactos/ntoskrnl/io/plugplay.c	2005-10-08 14:47:25 UTC (rev 18335)
@@ -562,7 +562,7 @@
     if (DeviceObject == NULL)
         return STATUS_NO_SUCH_DEVICE;
 
-    DeviceNode = ((PEXTENDED_DEVOBJ_EXTENSION)DeviceObject->DeviceObjectExtension)->DeviceNode;
+    DeviceNode = IopGetDeviceNode(DeviceObject);
 
     DepthData->Depth = DeviceNode->Level;
 
@@ -572,6 +572,38 @@
 }
 
 
+static NTSTATUS
+IopResetDevice(PPLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData)
+{
+    PDEVICE_OBJECT DeviceObject;
+    PDEVICE_NODE DeviceNode;
+    NTSTATUS Status;
+
+    DPRINT("IopResetDevice() called\n");
+    DPRINT("Device name: %wZ\n", &ResetDeviceData->DeviceInstance);
+
+    /* Get the device object */
+    DeviceObject = IopGetDeviceObjectFromDeviceInstance(&ResetDeviceData->DeviceInstance);
+    if (DeviceObject == NULL)
+        return STATUS_NO_SUCH_DEVICE;
+
+    DeviceNode = IopGetDeviceNode(DeviceObject);
+
+    /* FIXME: we should stop the device, before starting it again */
+
+    /* Start the device */
+    IopDeviceNodeClearFlag(DeviceNode, DNF_DISABLED);
+    Status = IopActionConfigureChildServices(DeviceNode, DeviceNode->Parent);
+
+    if (NT_SUCCESS(Status))
+        Status = IopActionInitChildServices(DeviceNode, DeviceNode->Parent, FALSE);
+
+    ObDereferenceObject(DeviceObject);
+
+    return Status;
+}
+
+
 /*
  * NtPlugPlayControl
  *
@@ -698,6 +730,11 @@
                 return STATUS_INVALID_PARAMETER;
             return IopGetDeviceDepth((PPLUGPLAY_CONTROL_DEPTH_DATA)Buffer);
 
+        case PlugPlayControlResetDevice:
+            if (!Buffer || BufferLength < sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA))
+                return STATUS_INVALID_PARAMETER;
+            return IopResetDevice((PPLUGPLAY_CONTROL_RESET_DEVICE_DATA)Buffer);
+
         default:
             return STATUS_NOT_IMPLEMENTED;
     }