diff options
Diffstat (limited to 'driver')
| -rw-r--r-- | driver/driver.cpp | 173 | ||||
| -rw-r--r-- | driver/driver.h | 4 |
2 files changed, 98 insertions, 79 deletions
diff --git a/driver/driver.cpp b/driver/driver.cpp index 3096de8..2a4f460 100644 --- a/driver/driver.cpp +++ b/driver/driver.cpp @@ -20,24 +20,17 @@ using milliseconds = double; struct { + bool initialized; WDFCOLLECTION device_collection; WDFWAITLOCK collection_lock; - ra::device_config default_dev_cfg; - unsigned device_data_size; - unsigned driver_data_size; - ra::device_settings* device_data; + ra::io_base base_data; ra::driver_settings* driver_data; + ra::device_settings* device_data; milliseconds tick_interval; - ra::modifier modifier_data[ra::DRIVER_CAPACITY]; } global = {}; extern "C" PULONG InitSafeBootMode; -bool init_failed() -{ - return global.driver_data_size == 0; -}; - __declspec(guard(ignore)) VOID RawaccelCallback( @@ -105,7 +98,7 @@ Arguments: static_cast<double>(it->LastY) }; - devExt->mod_ptr->modify(input, *devExt->drv_ptr, devExt->dpi_factor, time); + devExt->mod.modify(input, devExt->drv_settings, devExt->dpi_factor, time); double carried_result_x = input.x + devExt->carry.x; double carried_result_y = input.y + devExt->carry.y; @@ -167,7 +160,7 @@ Return Value: { NTSTATUS status; void* buffer; - + size_t buffer_length; size_t bytes_out = 0; UNREFERENCED_PARAMETER(Queue); @@ -177,42 +170,50 @@ Return Value: DebugPrint(("Ioctl received into filter control object.\n")); - if (init_failed()) { + if (!global.initialized) { WdfRequestCompleteWithInformation(Request, STATUS_CANCELLED, 0); return; } + const auto SIZEOF_BASE = sizeof(ra::io_base); + switch (IoControlCode) { case ra::READ: status = WdfRequestRetrieveOutputBuffer( Request, - sizeof(ra::io_t), + SIZEOF_BASE, &buffer, - NULL + &buffer_length ); if (!NT_SUCCESS(status)) { DebugPrint(("RetrieveOutputBuffer failed: 0x%x\n", status)); } else { - ra::io_t& output = *static_cast<ra::io_t*>(buffer); + *static_cast<ra::io_base*>(buffer) = global.base_data; - output.default_dev_cfg = global.default_dev_cfg; + size_t driver_bytes = global.base_data.driver_data_size * sizeof(ra::driver_settings); + size_t device_bytes = global.base_data.device_data_size * sizeof(ra::device_settings); + size_t total_bytes = SIZEOF_BASE + driver_bytes + device_bytes; - output.device_data_size = global.device_data_size; - output.driver_data_size = global.driver_data_size; - - RtlCopyMemory(output.device_data, global.device_data, sizeof(output.device_data)); - RtlCopyMemory(output.driver_data, global.driver_data, sizeof(output.driver_data)); + if (buffer_length < total_bytes) { + bytes_out = SIZEOF_BASE; + } + else { + BYTE* output_ptr = static_cast<BYTE*>(buffer) + SIZEOF_BASE; - bytes_out = sizeof(ra::io_t); + if (global.driver_data) RtlCopyMemory(output_ptr, global.driver_data, driver_bytes); + output_ptr += driver_bytes; + if (global.device_data) RtlCopyMemory(output_ptr, global.device_data, device_bytes); + bytes_out = total_bytes; + } } break; case ra::WRITE: status = WdfRequestRetrieveInputBuffer( Request, - sizeof(ra::io_t), + SIZEOF_BASE, &buffer, - NULL + &buffer_length ); if (!NT_SUCCESS(status)) { DebugPrint(("RetrieveInputBuffer failed: 0x%x\n", status)); @@ -220,36 +221,73 @@ Return Value: else { WriteDelay(); - ra::io_t& input = *static_cast<ra::io_t*>(buffer); + ra::io_base& input = *static_cast<ra::io_base*>(buffer); - if (input.driver_data_size == 0) { + auto driver_bytes = size_t(input.driver_data_size) * sizeof(ra::driver_settings); + auto device_bytes = size_t(input.device_data_size) * sizeof(ra::device_settings); + auto alloc_size = driver_bytes + device_bytes; + auto total_size = alloc_size + SIZEOF_BASE; + + auto max_u32 = unsigned(-1); + if (driver_bytes > max_u32 || device_bytes > max_u32 || total_size > max_u32) { status = STATUS_CANCELLED; break; } - WdfWaitLockAcquire(global.collection_lock, NULL); + if (input.driver_data_size == 0) { + // clear data and disable all devices + WdfWaitLockAcquire(global.collection_lock, NULL); + + global.base_data = {}; - global.default_dev_cfg = input.default_dev_cfg; + if (global.driver_data) { + ExFreePoolWithTag(global.driver_data, 'g'); + global.driver_data = NULL; + global.device_data = NULL; + } - global.device_data_size = ra::min(input.device_data_size, ra::DEVICE_CAPACITY); - global.driver_data_size = ra::min(input.driver_data_size, ra::DRIVER_CAPACITY); + auto count = WdfCollectionGetCount(global.device_collection); - RtlCopyMemory(global.device_data, input.device_data, sizeof(input.device_data)); - RtlCopyMemory(global.driver_data, input.driver_data, sizeof(input.driver_data)); + for (auto i = 0u; i < count; i++) { + DeviceSetup(WdfCollectionGetItem(global.device_collection, i)); + } - for (auto i = 0u; i < global.driver_data_size; i++) { - global.modifier_data[i] = { global.driver_data[i] }; + WdfWaitLockRelease(global.collection_lock); } + else if (buffer_length == total_size) { + void* pool = ExAllocatePoolWithTag(PagedPool, alloc_size, 'g'); + if (!pool) { + DebugPrint(("ExAllocatePoolWithTag (PagedPool) failed")); + status = STATUS_UNSUCCESSFUL; + break; + } + RtlCopyMemory(pool, static_cast<BYTE*>(buffer) + SIZEOF_BASE, alloc_size); - auto count = WdfCollectionGetCount(global.device_collection); + WdfWaitLockAcquire(global.collection_lock, NULL); - for (auto i = 0u; i < count; i++) { - DeviceSetup(WdfCollectionGetItem(global.device_collection, i)); - } + if (global.driver_data) { + ExFreePoolWithTag(global.driver_data, 'g'); + } - WdfWaitLockRelease(global.collection_lock); - } + void* dev_data = static_cast<BYTE*>(pool) + driver_bytes; + global.device_data = input.device_data_size > 0 ? + static_cast<ra::device_settings*>(dev_data) : + NULL; + global.driver_data = static_cast<ra::driver_settings*>(pool); + global.base_data = input; + auto count = WdfCollectionGetCount(global.device_collection); + + for (auto i = 0u; i < count; i++) { + DeviceSetup(WdfCollectionGetItem(global.device_collection, i)); + } + + WdfWaitLockRelease(global.collection_lock); + } + else { + status = STATUS_CANCELLED; + } + } break; case ra::GET_VERSION: status = WdfRequestRetrieveOutputBuffer( @@ -310,34 +348,11 @@ RawaccelInit(WDFDRIVER driver) return; } - void* paged_p = ExAllocatePoolWithTag(PagedPool, ra::POOL_SIZE, 'g'); - if (paged_p) { - RtlZeroMemory(paged_p, ra::POOL_SIZE); - global.device_data = static_cast<ra::device_settings*>(paged_p); - } - else { - DebugPrint(("ExAllocatePoolWithTag (PagedPool) failed")); - return; - } - - void* nonpaged_p = ExAllocatePoolWithTag(NonPagedPool, ra::POOL_SIZE, 'g'); - if (nonpaged_p) { - RtlZeroMemory(nonpaged_p, ra::POOL_SIZE); - global.driver_data = static_cast<ra::driver_settings*>(nonpaged_p); - global.driver_data->prof.domain_weights = { 1, 1 }; - global.driver_data->prof.range_weights = { 1, 1 }; - global.driver_data->prof.sensitivity = 1; - global.driver_data->prof.yx_sens_ratio = 1; - global.driver_data_size = 1; - } - else { - DebugPrint(("ExAllocatePoolWithTag (NonPagedPool) failed")); - return; - } - LARGE_INTEGER freq; KeQueryPerformanceCounter(&freq); global.tick_interval = 1e3 / freq.QuadPart; + + global.initialized = true; } VOID @@ -360,25 +375,29 @@ DeviceSetup(WDFOBJECT hDevice) } }; - set_ext_from_cfg(global.default_dev_cfg); - devExt->counter = 0; - devExt->carry = {}; - devExt->drv_ptr = global.driver_data; - devExt->mod_ptr = global.modifier_data; - - for (auto i = 0u; i < global.device_data_size; i++) { + if (!global.driver_data) { + devExt->enable = false; + devExt->mod = {}; + return; + } + + set_ext_from_cfg(global.base_data.default_dev_cfg); + devExt->drv_settings = *global.driver_data; + devExt->mod = { devExt->drv_settings }; + + for (auto i = 0u; i < global.base_data.device_data_size; i++) { auto& dev_settings = global.device_data[i]; if (wcsncmp(devExt->dev_id, dev_settings.id, ra::MAX_DEV_ID_LEN) == 0) { set_ext_from_cfg(dev_settings.config); if (dev_settings.profile[0] != L'\0') { - for (auto j = 0u; j < global.driver_data_size; j++) { + for (auto j = 0u; j < global.base_data.driver_data_size; j++) { auto& profile = global.driver_data[j].prof; if (wcsncmp(dev_settings.profile, profile.name, ra::MAX_NAME_LEN) == 0) { - devExt->drv_ptr = &global.driver_data[j]; - devExt->mod_ptr = &global.modifier_data[j]; + devExt->drv_settings = global.driver_data[j]; + devExt->mod = { devExt->drv_settings }; return; } } @@ -624,7 +643,7 @@ Return Value: DebugPrint(("Enter FilterEvtDeviceAdd \n")); - if (init_failed()) { + if (!global.initialized) { return STATUS_SUCCESS; } diff --git a/driver/driver.h b/driver/driver.h index 4818367..d8b3162 100644 --- a/driver/driver.h +++ b/driver/driver.h @@ -25,10 +25,10 @@ typedef struct _DEVICE_EXTENSION { double dpi_factor; counter_t counter; ra::time_clamp clamp; - ra::driver_settings* drv_ptr; - ra::modifier* mod_ptr; + ra::modifier mod; vec2d carry; CONNECT_DATA UpperConnectData; + ra::driver_settings drv_settings; WCHAR dev_id[ra::MAX_DEV_ID_LEN]; } DEVICE_EXTENSION, *PDEVICE_EXTENSION; |