From 6f1098372b2016db9744ad13dffbb55b77102671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pazdiora?= Date: Tue, 5 Jan 2021 03:50:45 +0100 Subject: add "Device Hardware ID" setting, to affect only specific device --- driver/driver.cpp | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) (limited to 'driver/driver.cpp') diff --git a/driver/driver.cpp b/driver/driver.cpp index a99a70b..2c234ba 100644 --- a/driver/driver.cpp +++ b/driver/driver.cpp @@ -54,6 +54,11 @@ Arguments: WDFDEVICE hDevice = WdfWdmDeviceGetWdfDeviceHandle(DeviceObject); PDEVICE_EXTENSION devExt = FilterGetData(hDevice); + bool devMatch = true; + if (wcsncmp(L"", global.args.device_hw_id, sizeof(global.args.device_hw_id)) != 0) { + devMatch = wcsncmp(devExt->hwid, global.args.device_hw_id, sizeof(global.args.device_hw_id)) == 0; + } + if (!(InputDataStart->Flags & MOUSE_MOVE_ABSOLUTE)) { auto num_packets = InputDataEnd - InputDataStart; @@ -63,28 +68,29 @@ Arguments: vec2d carry = devExt->carry; - auto it = InputDataStart; - do { + for (auto it = InputDataStart; it != InputDataEnd; ++it) { vec2d input = { static_cast(it->LastX), static_cast(it->LastY) }; - global.modifier.apply_rotation(input); + if (devMatch) { + global.modifier.apply_rotation(input); - if (enable_accel) { - auto time_supplier = [=] { - counter_t now = KeQueryPerformanceCounter(NULL).QuadPart; - counter_t ticks = now - devExt->counter; - devExt->counter = now; - milliseconds time = ticks * global.tick_interval; - return clampsd(time, global.args.time_min, 100); - }; + if (enable_accel) { + auto time_supplier = [=] { + counter_t now = KeQueryPerformanceCounter(NULL).QuadPart; + counter_t ticks = now - devExt->counter; + devExt->counter = now; + milliseconds time = ticks * global.tick_interval; + return clampsd(time, global.args.time_min, 100); + }; - global.modifier.apply_acceleration(input, time_supplier); - } + global.modifier.apply_acceleration(input, time_supplier); + } - global.modifier.apply_sensitivity(input); + global.modifier.apply_sensitivity(input); + } double carried_result_x = input.x + carry.x; double carried_result_y = input.y + carry.y; @@ -98,7 +104,7 @@ Arguments: it->LastX = out_x; it->LastY = out_y; - } while (++it != InputDataEnd); + } devExt->carry = carry; } @@ -581,7 +587,16 @@ Routine Description: DebugPrint(("WdfRequestRetrieveInputBuffer failed %x\n", status)); break; } - + + ULONG resultLen; + status = WdfDeviceQueryProperty(hDevice, DevicePropertyHardwareID, + sizeof(devExt->hwid), devExt->hwid, &resultLen); + + if (!NT_SUCCESS(status)) { + DebugPrint(("WdfDeviceQueryProperty failed: 0x%x\n", status)); + break; + } + devExt->counter = 0; devExt->carry = {}; devExt->UpperConnectData = *connectData; -- cgit v1.2.3 From e11971e733d4b35cb6cdfe907b7a1f191ff4a97a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pazdiora?= Date: Tue, 5 Jan 2021 19:11:48 +0100 Subject: simplify checking for configuration without specific device --- driver/driver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'driver/driver.cpp') diff --git a/driver/driver.cpp b/driver/driver.cpp index 2c234ba..38d127b 100644 --- a/driver/driver.cpp +++ b/driver/driver.cpp @@ -55,7 +55,7 @@ Arguments: PDEVICE_EXTENSION devExt = FilterGetData(hDevice); bool devMatch = true; - if (wcsncmp(L"", global.args.device_hw_id, sizeof(global.args.device_hw_id)) != 0) { + if (global.args.device_hw_id[0] != 0) { devMatch = wcsncmp(devExt->hwid, global.args.device_hw_id, sizeof(global.args.device_hw_id)) == 0; } -- cgit v1.2.3 From b9c79a8d13aaae30950da318526e2f4707062c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pazdiora?= Date: Tue, 5 Jan 2021 19:18:40 +0100 Subject: revert for loop -> do while (according to a1xd's conclusion) --- driver/driver.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'driver/driver.cpp') diff --git a/driver/driver.cpp b/driver/driver.cpp index 38d127b..1cdfadf 100644 --- a/driver/driver.cpp +++ b/driver/driver.cpp @@ -68,7 +68,8 @@ Arguments: vec2d carry = devExt->carry; - for (auto it = InputDataStart; it != InputDataEnd; ++it) { + auto it = InputDataStart; + do { vec2d input = { static_cast(it->LastX), static_cast(it->LastY) @@ -104,7 +105,7 @@ Arguments: it->LastX = out_x; it->LastY = out_y; - } + } while (++it != InputDataEnd); devExt->carry = carry; } -- cgit v1.2.3 From b4749bfb8480ed5c9e6151c0c899027cdc20c22b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pazdiora?= Date: Tue, 5 Jan 2021 19:34:31 +0100 Subject: bugfix --- driver/driver.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'driver/driver.cpp') diff --git a/driver/driver.cpp b/driver/driver.cpp index 1cdfadf..8b72562 100644 --- a/driver/driver.cpp +++ b/driver/driver.cpp @@ -56,7 +56,8 @@ Arguments: bool devMatch = true; if (global.args.device_hw_id[0] != 0) { - devMatch = wcsncmp(devExt->hwid, global.args.device_hw_id, sizeof(global.args.device_hw_id)) == 0; + size_t max_cnt = sizeof(global.args.device_hw_id) / sizeof(global.args.device_hw_id[0]); + devMatch = wcsncmp(devExt->hwid, global.args.device_hw_id, max_cnt) == 0; } if (!(InputDataStart->Flags & MOUSE_MOVE_ABSOLUTE)) { -- cgit v1.2.3 From 6969310edd56edb555dd98acbc1478caa5728593 Mon Sep 17 00:00:00 2001 From: a1xd <68629610+a1xd@users.noreply.github.com> Date: Tue, 5 Jan 2021 18:05:48 -0500 Subject: size device id/hwids based on docs this also changes the connect ioctl to not abort when hwid query fails --- driver/driver.cpp | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) (limited to 'driver/driver.cpp') diff --git a/driver/driver.cpp b/driver/driver.cpp index 8b72562..ad837e7 100644 --- a/driver/driver.cpp +++ b/driver/driver.cpp @@ -56,8 +56,7 @@ Arguments: bool devMatch = true; if (global.args.device_hw_id[0] != 0) { - size_t max_cnt = sizeof(global.args.device_hw_id) / sizeof(global.args.device_hw_id[0]); - devMatch = wcsncmp(devExt->hwid, global.args.device_hw_id, max_cnt) == 0; + devMatch = wcsncmp(devExt->hwid, global.args.device_hw_id, MAX_HWID_LEN) == 0; } if (!(InputDataStart->Flags & MOUSE_MOVE_ABSOLUTE)) { @@ -569,7 +568,7 @@ Routine Description: // // Connect a mouse class device driver to the port driver. // - case IOCTL_INTERNAL_MOUSE_CONNECT: + case IOCTL_INTERNAL_MOUSE_CONNECT: { // // Only allow one connection. // @@ -577,26 +576,42 @@ Routine Description: status = STATUS_SHARING_VIOLATION; break; } - + // // Copy the connection parameters to the device extension. // - status = WdfRequestRetrieveInputBuffer(Request, - sizeof(CONNECT_DATA), - reinterpret_cast(&connectData), - &length); - if(!NT_SUCCESS(status)){ + status = WdfRequestRetrieveInputBuffer(Request, + sizeof(CONNECT_DATA), + reinterpret_cast(&connectData), + &length); + if (!NT_SUCCESS(status)) { DebugPrint(("WdfRequestRetrieveInputBuffer failed %x\n", status)); break; } - ULONG resultLen; - status = WdfDeviceQueryProperty(hDevice, DevicePropertyHardwareID, - sizeof(devExt->hwid), devExt->hwid, &resultLen); + // taken from REGSTR_VAL_MAX_HCID_LEN defined in um/RegStr.h + const size_t POOL_SIZE = sizeof(wchar_t) * 1024; - if (!NT_SUCCESS(status)) { - DebugPrint(("WdfDeviceQueryProperty failed: 0x%x\n", status)); - break; + auto pool = ExAllocatePoolWithTag(NonPagedPool, POOL_SIZE, 'AR'); + + if (!pool) { + DebugPrint(("RA - failed to allocate pool for hwid list\n")); + } + else { + RtlZeroMemory(pool, POOL_SIZE); + + ULONG resultLen; + NTSTATUS tmp = WdfDeviceQueryProperty(hDevice, DevicePropertyHardwareID, + POOL_SIZE, pool, &resultLen); + + if (!NT_SUCCESS(tmp)) { + DebugPrint(("WdfDeviceQueryProperty failed: 0x%x\n", tmp)); + } + else { + wcsncpy(devExt->hwid, reinterpret_cast(pool), MAX_HWID_LEN); + } + + ExFreePoolWithTag(pool, 'AR'); } devExt->counter = 0; @@ -612,7 +627,7 @@ Routine Description: connectData->ClassService = RawaccelCallback; break; - + } // // Disconnect a mouse class device driver from the port driver. // -- cgit v1.2.3 From dc38efedbefe8753643a57e8ae3edb989632f2de Mon Sep 17 00:00:00 2001 From: a1xd <68629610+a1xd@users.noreply.github.com> Date: Wed, 6 Jan 2021 12:36:14 -0500 Subject: get hwid when adding device --- driver/driver.cpp | 48 ++++++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 26 deletions(-) (limited to 'driver/driver.cpp') diff --git a/driver/driver.cpp b/driver/driver.cpp index ad837e7..e3ffb4d 100644 --- a/driver/driver.cpp +++ b/driver/driver.cpp @@ -472,7 +472,7 @@ Return Value: WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_EXTENSION); - + // // Create a framework device object. This call will in turn create // a WDM deviceobject, attach to the lower stack and set the @@ -484,6 +484,27 @@ Return Value: return status; } + // + // get device hwid + // + WDFMEMORY memory = NULL; + + NTSTATUS hwid_query = WdfDeviceAllocAndQueryProperty( + hDevice, + DevicePropertyHardwareID, + PagedPool, + WDF_NO_OBJECT_ATTRIBUTES, + &memory); + + if (!NT_SUCCESS(hwid_query)) { + DebugPrint(("WdfDeviceAllocAndQueryProperty failed: 0x%x\n", hwid_query)); + } + else { + auto dev_ext = FilterGetData(hDevice); + void* buffer = WdfMemoryGetBuffer(memory, NULL); + wcsncpy(dev_ext->hwid, reinterpret_cast(buffer), MAX_HWID_LEN); + WdfObjectDelete(memory); + } // // Configure the default queue to be Parallel. Do not use sequential queue @@ -589,31 +610,6 @@ Routine Description: break; } - // taken from REGSTR_VAL_MAX_HCID_LEN defined in um/RegStr.h - const size_t POOL_SIZE = sizeof(wchar_t) * 1024; - - auto pool = ExAllocatePoolWithTag(NonPagedPool, POOL_SIZE, 'AR'); - - if (!pool) { - DebugPrint(("RA - failed to allocate pool for hwid list\n")); - } - else { - RtlZeroMemory(pool, POOL_SIZE); - - ULONG resultLen; - NTSTATUS tmp = WdfDeviceQueryProperty(hDevice, DevicePropertyHardwareID, - POOL_SIZE, pool, &resultLen); - - if (!NT_SUCCESS(tmp)) { - DebugPrint(("WdfDeviceQueryProperty failed: 0x%x\n", tmp)); - } - else { - wcsncpy(devExt->hwid, reinterpret_cast(pool), MAX_HWID_LEN); - } - - ExFreePoolWithTag(pool, 'AR'); - } - devExt->counter = 0; devExt->carry = {}; devExt->UpperConnectData = *connectData; -- cgit v1.2.3 From be22e78f96fd34245bdad03b68cfd4e60ded1ba6 Mon Sep 17 00:00:00 2001 From: a1xd <68629610+a1xd@users.noreply.github.com> Date: Thu, 7 Jan 2021 12:52:51 -0500 Subject: refactor main callback check for empty input as suggested by @aroidzap --- driver/driver.cpp | 51 +++++++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 28 deletions(-) (limited to 'driver/driver.cpp') diff --git a/driver/driver.cpp b/driver/driver.cpp index e3ffb4d..4f108bd 100644 --- a/driver/driver.cpp +++ b/driver/driver.cpp @@ -54,20 +54,18 @@ Arguments: WDFDEVICE hDevice = WdfWdmDeviceGetWdfDeviceHandle(DeviceObject); PDEVICE_EXTENSION devExt = FilterGetData(hDevice); - bool devMatch = true; - if (global.args.device_hw_id[0] != 0) { - devMatch = wcsncmp(devExt->hwid, global.args.device_hw_id, MAX_HWID_LEN) == 0; - } + auto num_packets = InputDataEnd - InputDataStart; + + bool any = num_packets > 0; + bool rel_move = !(InputDataStart->Flags & MOUSE_MOVE_ABSOLUTE); + bool dev_match = global.args.device_hw_id[0] == 0 || + wcsncmp(devExt->hwid, global.args.device_hw_id, MAX_HWID_LEN) == 0; - if (!(InputDataStart->Flags & MOUSE_MOVE_ABSOLUTE)) { - auto num_packets = InputDataEnd - InputDataStart; - + if (any && rel_move && dev_match) { // if IO is backed up to the point where we get more than 1 packet here // then applying accel is pointless as we can't get an accurate timing bool enable_accel = num_packets == 1; - vec2d carry = devExt->carry; - auto it = InputDataStart; do { vec2d input = { @@ -75,39 +73,36 @@ Arguments: static_cast(it->LastY) }; - if (devMatch) { - global.modifier.apply_rotation(input); + global.modifier.apply_rotation(input); - if (enable_accel) { - auto time_supplier = [=] { - counter_t now = KeQueryPerformanceCounter(NULL).QuadPart; - counter_t ticks = now - devExt->counter; - devExt->counter = now; - milliseconds time = ticks * global.tick_interval; - return clampsd(time, global.args.time_min, 100); - }; + if (enable_accel) { + auto time_supplier = [=] { + counter_t now = KeQueryPerformanceCounter(NULL).QuadPart; + counter_t ticks = now - devExt->counter; + devExt->counter = now; + milliseconds time = ticks * global.tick_interval; + return clampsd(time, global.args.time_min, 100); + }; - global.modifier.apply_acceleration(input, time_supplier); - } - - global.modifier.apply_sensitivity(input); + global.modifier.apply_acceleration(input, time_supplier); } - double carried_result_x = input.x + carry.x; - double carried_result_y = input.y + carry.y; + global.modifier.apply_sensitivity(input); + + double carried_result_x = input.x + devExt->carry.x; + double carried_result_y = input.y + devExt->carry.y; LONG out_x = static_cast(carried_result_x); LONG out_y = static_cast(carried_result_y); - carry.x = carried_result_x - out_x; - carry.y = carried_result_y - out_y; + devExt->carry.x = carried_result_x - out_x; + devExt->carry.y = carried_result_y - out_y; it->LastX = out_x; it->LastY = out_y; } while (++it != InputDataEnd); - devExt->carry = carry; } (*(PSERVICE_CALLBACK_ROUTINE)devExt->UpperConnectData.ClassService)( -- cgit v1.2.3 From 0e60e22b73dd0693b349cbb63cf9a390c01fd5dd Mon Sep 17 00:00:00 2001 From: a1xd <68629610+a1xd@users.noreply.github.com> Date: Tue, 12 Jan 2021 17:01:18 -0500 Subject: filter raw input based on id use device id (from device instance) over first hardware id use buffered method for all ioctls update gui/DeviceIDManager to match driver behavior respond to device change events desync MouseData and PointData accessors --- driver/driver.cpp | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) (limited to 'driver/driver.cpp') diff --git a/driver/driver.cpp b/driver/driver.cpp index 4f108bd..a92f773 100644 --- a/driver/driver.cpp +++ b/driver/driver.cpp @@ -58,8 +58,8 @@ Arguments: bool any = num_packets > 0; bool rel_move = !(InputDataStart->Flags & MOUSE_MOVE_ABSOLUTE); - bool dev_match = global.args.device_hw_id[0] == 0 || - wcsncmp(devExt->hwid, global.args.device_hw_id, MAX_HWID_LEN) == 0; + bool dev_match = global.args.device_id[0] == 0 || + wcsncmp(devExt->dev_id, global.args.device_id, MAX_DEV_ID_LEN) == 0; if (any && rel_move && dev_match) { // if IO is backed up to the point where we get more than 1 packet here @@ -146,6 +146,8 @@ Return Value: NTSTATUS status; void* buffer; + size_t bytes_out = 0; + UNREFERENCED_PARAMETER(Queue); UNREFERENCED_PARAMETER(OutputBufferLength); UNREFERENCED_PARAMETER(InputBufferLength); @@ -166,6 +168,7 @@ Return Value: } else { *reinterpret_cast(buffer) = global.args; + bytes_out = sizeof(ra::settings); } break; case RA_WRITE: @@ -205,6 +208,7 @@ Return Value: } else { *reinterpret_cast(buffer) = { RA_VER_MAJOR, RA_VER_MINOR, RA_VER_PATCH }; + bytes_out = sizeof(ra::version_t); } break; default: @@ -212,7 +216,7 @@ Return Value: break; } - WdfRequestComplete(Request, status); + WdfRequestCompleteWithInformation(Request, status, bytes_out); } #pragma warning(pop) // enable 28118 again @@ -480,25 +484,31 @@ Return Value: } // - // get device hwid + // get device id from bus driver // - WDFMEMORY memory = NULL; + DEVICE_OBJECT* pdo = WdfDeviceWdmGetPhysicalDevice(hDevice); - NTSTATUS hwid_query = WdfDeviceAllocAndQueryProperty( - hDevice, - DevicePropertyHardwareID, - PagedPool, - WDF_NO_OBJECT_ATTRIBUTES, - &memory); + KEVENT ke; + KeInitializeEvent(&ke, NotificationEvent, FALSE); + IO_STATUS_BLOCK iosb = {}; + PIRP Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, + pdo, NULL, 0, NULL, &ke, &iosb); + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(Irp); + stack->MinorFunction = IRP_MN_QUERY_ID; + stack->Parameters.QueryId.IdType = BusQueryDeviceID; + + NTSTATUS nts = IoCallDriver(pdo, Irp); - if (!NT_SUCCESS(hwid_query)) { - DebugPrint(("WdfDeviceAllocAndQueryProperty failed: 0x%x\n", hwid_query)); + if (nts == STATUS_PENDING) { + KeWaitForSingleObject(&ke, Executive, KernelMode, FALSE, NULL); } - else { - auto dev_ext = FilterGetData(hDevice); - void* buffer = WdfMemoryGetBuffer(memory, NULL); - wcsncpy(dev_ext->hwid, reinterpret_cast(buffer), MAX_HWID_LEN); - WdfObjectDelete(memory); + + if (NT_SUCCESS(nts)) { + auto* id_ptr = reinterpret_cast(iosb.Information); + wcsncpy(FilterGetData(hDevice)->dev_id, id_ptr, MAX_DEV_ID_LEN); + DebugPrint(("Device ID = %ws\n", id_ptr)); + ExFreePool(id_ptr); } // -- cgit v1.2.3