I want to modify the flags field in MOUSE_INPUT_DATA which is provided by Irp, but every I set flags to 3, it gives me a blue screen. So how can I change the value of MOUSE_INPUT_DATA correctly?
Here is the code, if I delete the line input[i].Flags= 3; everything works fine, so I guess the MOUSE_INPUT_DATA I received here is only for monitoring purposes? what functions must I call before modifying them?
#include "ntddk.h"
#include "ntddmou.h"
extern POBJECT_TYPE* IoDriverObjectType;
NTKERNELAPI NTSTATUS ObReferenceObjectByName(
IN PUNICODE_STRING ObjectName,
IN ULONG Attributes,
IN PACCESS_STATE AccessState,
IN PACCESS_MASK DesiredAccess,
IN POBJECT_TYPE ObjectType,
IN KPROCESSOR_MODE AccessMode,
IN PVOID ParseConext,
OUT PVOID* Object);
typedef struct {
PDEVICE_OBJECT LowerDevice;
} DEVICE_EXTENSION, * PDEVICE_EXTENSION;
ULONG pendingKey = 0;
VOID Unload(IN PDRIVER_OBJECT DriverObject)
{
LARGE_INTEGER interval = { 0 };
PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
interval.QuadPart = -10 * 1000 * 1000;
KdPrint(("Unloading"));
while (DeviceObject) {
IoDetachDevice(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice);
DeviceObject = DeviceObject->NextDevice;
}
KdPrint(("detached"));
while (pendingKey) {
KeDelayExecutionThread(KernelMode, FALSE, &interval);
}
DeviceObject = DriverObject->DeviceObject;
while (DeviceObject)
{
IoDeleteDevice(DeviceObject);
DeviceObject = DeviceObject->NextDevice;
}
KdPrint(("Unloaded"));
}
NTSTATUS DispatchPass(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
IoCopyCurrentIrpStackLocationToNext(Irp);
return IoCallDriver(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice, Irp);
}
NTSTATUS ReadComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
PMOUSE_INPUT_DATA input = (PMOUSE_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
int structnum = Irp->IoStatus.Information / sizeof(MOUSE_INPUT_DATA);
if (NT_SUCCESS(Irp->IoStatus.Status))
{
for (int i = 0; i < structnum; i++)
{
input[i].Flags= 3;
KdPrint(("flag:%d, state:%d, x:%d, y:%d",input[i].Flags, input[i].ButtonFlags, input[i].LastX, input[i].LastY));
}
}
if (Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}
return Irp->IoStatus.Status;
}
NTSTATUS DispatchRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, ReadComplete, NULL, TRUE, TRUE, TRUE);
return IoCallDriver(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice, Irp);
}
NTSTATUS AttachMouseDevice(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING MCName = RTL_CONSTANT_STRING(L"\\Driver\\mouclass");
PDRIVER_OBJECT targetDriverObject = NULL;
PDEVICE_OBJECT currentDeviceObject = NULL, myDeviceObject = NULL;
NTSTATUS status = ObReferenceObjectByName(&MCName, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, KernelMode, NULL, (PVOID*)&targetDriverObject);
if (!NT_SUCCESS(status))
{
KdPrint(("ObReferenceObjectByName failed Error:%d", status));
return status;
}
ObDereferenceObject(targetDriverObject);
currentDeviceObject = targetDriverObject->DeviceObject;
while (currentDeviceObject)
{
status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_MOUSE, 0, FALSE, &myDeviceObject);
RtlZeroMemory(myDeviceObject->DeviceExtension, sizeof(DEVICE_EXTENSION));
status = IoAttachDeviceToDeviceStackSafe(myDeviceObject, currentDeviceObject, &((PDEVICE_EXTENSION)myDeviceObject->DeviceExtension)->LowerDevice);
if (!NT_SUCCESS(status))
{
KdPrint(("IoAttachDeviceToDeviceStackSafe failed"));
IoDeleteDevice(myDeviceObject); //此处应删除的是之前创建的所有设备,而不是只删除当前创建的设备
return status;
}
myDeviceObject->Flags |= DO_BUFFERED_IO;
myDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
currentDeviceObject = currentDeviceObject->NextDevice;
}
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
NTSTATUS status;
DriverObject->DriverUnload = Unload;
for (int i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
DriverObject->MajorFunction[i] = DispatchPass;
}
DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
status = AttachMouseDevice(DriverObject);
if (!NT_SUCCESS(status))
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "attaching mouse device failed\r\n");
else
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "attaching mouse device succeeds\r\n");
return status;
}
and also, when I unload the driver, blue screen appears. What did I do wrong ?