Use device::irp_mj.sys_ctl(), instead.
/* 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 */
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_,
};
/**
}
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_(
* 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,
/* 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;
{ L"GenSFloppy", L"GenDisk", L"GenCdRom" };
struct device__irp_mj disk__irp_mj_ = {
disk__power_,
+ disk__sys_ctl_,
};
static
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.
*/
{ 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,
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);
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. */
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);
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