[project] Don't use mini IRP handling for IRP_MJ_SYSTEM_CONTROL
authorShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Mon, 13 Dec 2010 05:43:06 +0000 (00:43 -0500)
committerShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Mon, 13 Dec 2010 05:43:06 +0000 (00:43 -0500)
Use device::irp_mj.sys_ctl(), instead.

src/include/device.h
src/winvblock/bus/bus.c
src/winvblock/disk/disk.c
src/winvblock/driver.c

index 21f0848..44ef06e 100644 (file)
@@ -121,6 +121,7 @@ typedef NTSTATUS STDCALL device__dispatch_func(
 /* IRP major function handler table. */
 struct device__irp_mj {
     device__dispatch_func * power;
+    device__dispatch_func * sys_ctl;
   };
 
 /* Details common to all devices this driver works with */
index 93e6635..a673a12 100644 (file)
 static device__free_func bus__free_;
 static device__create_pdo_func bus__create_pdo_;
 static device__dispatch_func bus__power_;
+static device__dispatch_func bus__sys_ctl_;
 
 /* Globals. */
 struct device__irp_mj bus__irp_mj_ = {
     bus__power_,
+    bus__sys_ctl_,
   };
 
 /**
@@ -129,19 +131,18 @@ winvblock__lib_func winvblock__bool STDCALL bus__add_child(
   }
 
 static NTSTATUS STDCALL bus__sys_ctl_(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PIO_STACK_LOCATION Stack,
-    IN struct device__type * dev_ptr,
-    OUT winvblock__bool_ptr completion_ptr
+    IN struct device__type * dev,
+    IN PIRP irp
   ) {
-    struct bus__type * bus_ptr = bus__get(dev_ptr);
-    PDEVICE_OBJECT lower = bus_ptr->LowerDeviceObject;
+    struct bus__type * bus = bus__get(dev);
+    PDEVICE_OBJECT lower = bus->LowerDeviceObject;
 
-    DBG("...\n");
-    IoSkipCurrentIrpStackLocation(Irp);
-    *completion_ptr = TRUE;
-    return lower ? IoCallDriver(lower, Irp) : STATUS_SUCCESS;
+    if (lower) {
+        DBG("Passing IRP_MJ_SYSTEM_CONTROL down\n");
+        IoSkipCurrentIrpStackLocation(irp);
+        return IoCallDriver(lower, irp);
+      }
+    return driver__complete_irp(irp, 0, STATUS_SUCCESS);
   }
 
 static NTSTATUS STDCALL bus__power_(
@@ -228,7 +229,6 @@ static NTSTATUS STDCALL bus_dispatch(
          * Why? It sets completion to true, so others won't be called.
          */
         {                     0, 0,  TRUE, TRUE, driver__not_supported },
-        { IRP_MJ_SYSTEM_CONTROL, 0, FALSE, TRUE,         bus__sys_ctl_ },
         { IRP_MJ_DEVICE_CONTROL, 0, FALSE, TRUE, bus_dev_ctl__dispatch },
         {            IRP_MJ_PNP, 0, FALSE, TRUE,       bus_pnp__simple },
         {            IRP_MJ_PNP,
index ebcb1f6..f6a4cbc 100644 (file)
@@ -53,6 +53,7 @@ __divdi3 (
 /* Forward declarations. */
 static device__free_func free_disk;
 static device__dispatch_func disk__power_;
+static device__dispatch_func disk__sys_ctl_;
 
 /* Globals. */
 static LIST_ENTRY disk_list;
@@ -62,6 +63,7 @@ PWCHAR disk__compat_ids[disk__media_count] =
   { L"GenSFloppy", L"GenDisk", L"GenCdRom" };
 struct device__irp_mj disk__irp_mj_ = {
     disk__power_,
+    disk__sys_ctl_,
   };
 
 static
@@ -102,19 +104,12 @@ static NTSTATUS STDCALL disk__power_(
     return driver__complete_irp(irp, 0, STATUS_NOT_SUPPORTED);
   }
 
-static NTSTATUS STDCALL sys_ctl(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PIO_STACK_LOCATION Stack,
-    IN struct device__type * dev_ptr,
-    OUT winvblock__bool_ptr completion_ptr
-  )
-{
-  NTSTATUS status = Irp->IoStatus.Status;
-  IoCompleteRequest ( Irp, IO_NO_INCREMENT );
-  *completion_ptr = TRUE;
-  return status;
-}
+static NTSTATUS STDCALL disk__sys_ctl_(
+    IN struct device__type * dev,
+    IN PIRP irp
+  ) {
+    return driver__complete_irp(irp, 0, irp->IoStatus.Status);
+  }
 
 /**
  * Create a disk PDO filled with the given disk parameters.
@@ -360,7 +355,6 @@ static NTSTATUS STDCALL (disk_dispatch)(
          */
         {                     0, 0,  TRUE,  TRUE,  driver__not_supported },
         { IRP_MJ_DEVICE_CONTROL, 0, FALSE,  TRUE, disk_dev_ctl__dispatch },
-        { IRP_MJ_SYSTEM_CONTROL, 0, FALSE,  TRUE,                sys_ctl },
         {           IRP_MJ_SCSI, 0, FALSE,  TRUE,    disk_scsi__dispatch },
         {            IRP_MJ_PNP, 0, FALSE,  TRUE,       disk_pnp__simple },
         {            IRP_MJ_PNP,
index 46043da..955e7f7 100644 (file)
@@ -58,6 +58,7 @@ static LPWSTR driver__os_load_opts_ = NULL;
 static driver__dispatch_func driver__dispatch_not_supported_;
 static driver__dispatch_func driver__dispatch_power_;
 static driver__dispatch_func driver__dispatch_create_close_;
+static driver__dispatch_func driver__dispatch_sys_ctl_;
 static driver__dispatch_func driver__dispatch_;
 static void STDCALL driver__unload_(IN PDRIVER_OBJECT);
 
@@ -309,7 +310,8 @@ NTSTATUS STDCALL DriverEntry(
     DriverObject->MajorFunction[IRP_MJ_POWER] = driver__dispatch_power_;
     DriverObject->MajorFunction[IRP_MJ_CREATE] = driver__dispatch_create_close_;
     DriverObject->MajorFunction[IRP_MJ_CLOSE] = driver__dispatch_create_close_;
-    DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = driver__dispatch_;
+    DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =
+      driver__dispatch_sys_ctl_;
     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = driver__dispatch_;
     DriverObject->MajorFunction[IRP_MJ_SCSI] = driver__dispatch_;
     /* Set the driver Unload callback. */
@@ -405,7 +407,7 @@ static NTSTATUS driver__dispatch_power_(
         return driver__complete_irp(irp, 0, STATUS_NO_SUCH_DEVICE);
       }
     /* Call the particular device's power handler. */
-    if (dev->irp_mj && dev->irp_mj->power)            
+    if (dev->irp_mj && dev->irp_mj->power)
       return dev->irp_mj->power(dev, irp);
     /* Otherwise, we don't support the IRP. */
     return driver__complete_irp(irp, 0, STATUS_NOT_SUPPORTED);
@@ -429,6 +431,27 @@ static NTSTATUS driver__dispatch_create_close_(
     return driver__complete_irp(irp, 0, STATUS_SUCCESS);
   }
 
+/* Handle an IRP_MJ_SYSTEM_CONTROL IRP. */
+static NTSTATUS driver__dispatch_sys_ctl_(
+    IN PDEVICE_OBJECT dev_obj,
+    IN PIRP irp
+  ) {
+    /* device__get() checks for a NULL dev_obj */
+    struct device__type * dev = device__get(dev_obj);
+
+    #ifdef DEBUGIRPS
+    Debug_IrpStart(dev_obj, irp);
+    #endif
+    /* Check that the device exists. */
+    if (!dev || dev->state == device__state_deleted)
+      return driver__complete_irp(irp, 0, STATUS_NO_SUCH_DEVICE);
+    /* Call the particular device's power handler. */
+    if (dev->irp_mj && dev->irp_mj->sys_ctl)
+      return dev->irp_mj->sys_ctl(dev, irp);
+    /* Otherwise, we don't support the IRP. */
+    return driver__complete_irp(irp, 0, STATUS_NOT_SUPPORTED);
+  }
+
 static NTSTATUS STDCALL driver__dispatch_(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp