我有以下自定义鼠标驱动程序的Windows,我不能正确加载在Windows内核
#include <ntddk.h>
#include <ntstrsafe.h>
#pragma warning(disable : 4201)
typedef struct
{
PDEVICE_OBJECT LowerKbdDevice;
} DEVICE_EXTENSION, * PDEVICE_EXTENSION;
PDEVICE_OBJECT myKbdDevice = NULL;
ULONG pendingkey = 0;
int first_time = TRUE;
typedef struct _MOUSE_INPUT_DATA {
USHORT UnitId;
USHORT Flags;
union {
ULONG Buttons;
struct {
USHORT ButtonFlags;
USHORT ButtonData;
};
};
ULONG RawButtons;
LONG LastX;
LONG LastY;
ULONG ExtraInformation;
} MOUSE_INPUT_DATA, * PMOUSE_INPUT_DATA;
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
LARGE_INTEGER interval = { 0 };
interval.QuadPart = -10 * 1000 * 1000; // 1 second
PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
IoDetachDevice(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerKbdDevice);
while (pendingkey)
{
KeDelayExecutionThread(KernelMode, FALSE, &interval);
}
IoDeleteDevice(myKbdDevice);
DbgPrintEx(0, 0, "Mouse filter unloaded\n");
}
NTSTATUS DispatchPass(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION sl = IoGetCurrentIrpStackLocation(Irp);
DbgPrintEx(0, 0, "DispatchPass: %d\n", sl->MajorFunction);
UNREFERENCED_PARAMETER(DeviceObject);
IoCopyCurrentIrpStackLocationToNext(Irp);
NTSTATUS status = IoCallDriver(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerKbdDevice, Irp);
return status;
}
NTSTATUS ReadComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
UNREFERENCED_PARAMETER(DeviceObject);
UNREFERENCED_PARAMETER(Context);
PMOUSE_INPUT_DATA Keys = (PMOUSE_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
int structnum = (ULONG)Irp->IoStatus.Information / sizeof(PMOUSE_INPUT_DATA);
if (structnum == 0) {
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
if (Irp->IoStatus.Status == STATUS_SUCCESS) {
for (int i = 0; i < structnum; i++)
{
DbgPrintEx(0, 0, "The button state is %x\n", Keys->ButtonFlags);
}
}
else {
DbgPrintEx(0, 0, "Complete status not success: %d\n", Irp->IoStatus.Status);
}
if (Irp->PendingReturned) {
IoMarkIrpPending(Irp);
}
pendingkey--;
return STATUS_CONTINUE_COMPLETION;
}
NTSTATUS DispatchRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
IoCopyCurrentIrpStackLocationToNext(Irp);
pendingkey++;
IoSetCompletionRoutineEx(DeviceObject, Irp, ReadComplete, NULL, TRUE, TRUE, TRUE);
NTSTATUS status = IoCallDriver(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerKbdDevice, Irp);
DbgPrintEx(0, 0, "DispatchRead: IoCallDriver status is %d\n", status);
return status;
}
NTSTATUS MyAttachDevice(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING TargetDevice = RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
PAGED_CODE();
NTSTATUS status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_MOUSE, 0, FALSE, &myKbdDevice);
if (!NT_SUCCESS(status)) {
DbgPrintEx(0, 0, "IoCreateDevice failed\n");
return status;
}
RtlZeroMemory(myKbdDevice->DeviceExtension, sizeof(DEVICE_EXTENSION));
myKbdDevice->Flags |= DO_BUFFERED_IO;
myKbdDevice->Flags &= ~DO_DEVICE_INITIALIZING;
status = IoAttachDevice(myKbdDevice,&TargetDevice,&((PDEVICE_EXTENSION)myKbdDevice->DeviceExtension)->LowerKbdDevice);
if (!NT_SUCCESS(status)) {
DbgPrintEx(0, 0, "IoAttachDevice failed with status %d\n", status);
IoDeleteDevice(myKbdDevice);
return status;
}
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
UNREFERENCED_PARAMETER(RegistryPath);
DriverObject->DriverUnload = DriverUnload;
for (int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
DriverObject->MajorFunction[i] = DispatchPass;
}
DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
NTSTATUS status = MyAttachDevice(DriverObject);
if (!NT_SUCCESS(status)) {
DbgPrintEx(0, 0, "MyAttachDevice failed\n");
return status;
}
return STATUS_SUCCESS;
}
通过OSR加载器启动驱动程序后,我立即得到IRP_MJ_CLOSE IRP,不明白为什么。我用的是内置触摸板的笔记本电脑。据我所知,在这种情况下,PointerClass0设备应该代表笔记本电脑的触摸板(鼠标)。也许我需要使用其他类而不是PointerClass0?我也有PointerClass1和PointerClass2,但对于这些类,IoAttachDevice总是失败。有谁知道吗?
1条答案
按热度按时间j2cgzkjk1#
解决了。我改变了MyAttachDevice函数如下:
简而言之:我们需要将设备连接到“\Driver\Mouclass”而不是“\Device\PointerClass0”中的设备
卸载函数应该是这样的:
此外,我们应该为未文档化的函数ObReferenceObjectByName添加原型