From 9d39a2bf6b521576f20b52e95956e4b194a8b307 Mon Sep 17 00:00:00 2001 From: a1xd <68629610+a1xd@users.noreply.github.com> Date: Thu, 6 Aug 2020 21:43:44 -0400 Subject: add a cooldown on write (one second) --- driver/driver.cpp | 23 +++++++++++++++++++---- driver/driver.h | 4 +++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/driver/driver.cpp b/driver/driver.cpp index c893b8b..3e67539 100644 --- a/driver/driver.cpp +++ b/driver/driver.cpp @@ -16,6 +16,7 @@ using milliseconds = double; struct { milliseconds tick_interval = 0; // set in DriverEntry ra::mouse_modifier modifier; + counter_t last_write = 0; } global; VOID @@ -70,9 +71,9 @@ Arguments: }; if (global.modifier.apply_accel && local_apply_accel) { - auto now = KeQueryPerformanceCounter(NULL).QuadPart; - auto ticks = now - devExt->counter.QuadPart; - devExt->counter.QuadPart = now; + counter_t now = KeQueryPerformanceCounter(NULL).QuadPart; + counter_t ticks = now - devExt->counter; + devExt->counter = now; milliseconds time = ticks * global.tick_interval; if (time < global.modifier.accel_fn.time_min) { @@ -154,6 +155,19 @@ Return Value: DebugPrint(("Ioctl received into filter control object.\n")); if (InputBufferLength == sizeof(ra::mouse_modifier)) { + constexpr milliseconds WRITE_COOLDOWN_TIME = 1000; + + counter_t now = KeQueryPerformanceCounter(NULL).QuadPart; + counter_t ticks = now - global.last_write; + milliseconds time = ticks * global.tick_interval; + + if (global.last_write > 0 && time < WRITE_COOLDOWN_TIME) { + DebugPrint(("RA write on cooldown\n")); + // status maps to win32 error code 170: ERROR_BUSY + WdfRequestComplete(Request, STATUS_ENCOUNTERED_WRITE_IN_PROGRESS); + return; + } + status = WdfRequestRetrieveInputBuffer( Request, sizeof(ra::mouse_modifier), @@ -169,6 +183,7 @@ Return Value: } global.modifier = *reinterpret_cast(buffer); + global.last_write = now; WdfRequestComplete(Request, STATUS_SUCCESS); } @@ -550,7 +565,7 @@ Routine Description: break; } - devExt->counter = KeQueryPerformanceCounter(NULL); + devExt->counter = 0; devExt->carry = {}; devExt->UpperConnectData = *connectData; diff --git a/driver/driver.h b/driver/driver.h index 2a400de..8554f8c 100644 --- a/driver/driver.h +++ b/driver/driver.h @@ -15,8 +15,10 @@ #define NTDEVICE_NAME L"\\Device\\rawaccel" #define SYMBOLIC_NAME_STRING L"\\DosDevices\\rawaccel" +using counter_t = long long; + typedef struct _DEVICE_EXTENSION { - LARGE_INTEGER counter; + counter_t counter; vec2d carry; CONNECT_DATA UpperConnectData; } DEVICE_EXTENSION, *PDEVICE_EXTENSION; -- cgit v1.2.3 From c7f881c86913f309f00f79289b2f3c88ce6919eb Mon Sep 17 00:00:00 2001 From: a1xd <68629610+a1xd@users.noreply.github.com> Date: Tue, 11 Aug 2020 23:15:02 -0400 Subject: define exceptions for invalid arg & io errors --- common/accel-base.hpp | 17 ++++++++++++----- common/accel-classic.hpp | 2 +- common/accel-error.hpp | 11 ----------- common/accel-natural.hpp | 2 +- common/accel-power.hpp | 4 ++-- common/accel-sigmoid.hpp | 4 ++-- common/common.vcxitems | 2 +- common/rawaccel-error.hpp | 29 +++++++++++++++++++++++++++++ common/rawaccel-io.hpp | 9 ++++++--- common/rawaccel.hpp | 6 ++++-- console/console.cpp | 10 ++++------ console/parse.hpp | 8 +++----- wrapper/wrapper.hpp | 3 --- 13 files changed, 65 insertions(+), 42 deletions(-) delete mode 100644 common/accel-error.hpp create mode 100644 common/rawaccel-error.hpp diff --git a/common/accel-base.hpp b/common/accel-base.hpp index da2c96b..91510a4 100644 --- a/common/accel-base.hpp +++ b/common/accel-base.hpp @@ -2,13 +2,20 @@ #include "vec2.h" -namespace rawaccel { +void bad_arg(const char*); + +#ifndef _KERNEL_MODE - // Error throwing calls std libraries which are unavailable in kernel mode. - void error(const char* s); +#include "rawaccel-error.hpp" - using milliseconds = double; +inline void bad_arg(const char* s) { + throw rawaccel::invalid_argument(s); +} +#endif + +namespace rawaccel { + /// Struct to hold arguments for an acceleration function. struct accel_args { double offset = 0; @@ -60,7 +67,7 @@ namespace rawaccel { /// /// Arguments to verified. void verify(const accel_args& args) const { - if (args.accel < 0) error("accel can not be negative, use a negative weight to compensate"); + if (args.accel < 0) bad_arg("accel can not be negative, use a negative weight to compensate"); } accel_base() = default; diff --git a/common/accel-classic.hpp b/common/accel-classic.hpp index 1a2adca..0a380dd 100644 --- a/common/accel-classic.hpp +++ b/common/accel-classic.hpp @@ -22,7 +22,7 @@ namespace rawaccel { } void verify(const accel_args& args) const { - if (args.exponent <= 1) error("exponent must be greater than 1"); + if (args.exponent <= 1) bad_arg("exponent must be greater than 1"); } }; diff --git a/common/accel-error.hpp b/common/accel-error.hpp deleted file mode 100644 index fa1f999..0000000 --- a/common/accel-error.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include - -namespace rawaccel { - - void error(const char* s) { - throw std::domain_error(s); - } - -} diff --git a/common/accel-natural.hpp b/common/accel-natural.hpp index c87fda8..8f002e4 100644 --- a/common/accel-natural.hpp +++ b/common/accel-natural.hpp @@ -24,7 +24,7 @@ namespace rawaccel { } void verify(const accel_args& args) const { - if (args.limit <= 1) error("limit must be greater than 1"); + if (args.limit <= 1) bad_arg("limit must be greater than 1"); } }; diff --git a/common/accel-power.hpp b/common/accel-power.hpp index 7f4c220..0d5e265 100644 --- a/common/accel-power.hpp +++ b/common/accel-power.hpp @@ -33,8 +33,8 @@ namespace rawaccel { } void verify(const accel_args& args) const { - if (args.power_scale <= 0) error("scale must be positive"); - if (args.exponent <= 0) error("exponent must be greater than 0"); + if (args.power_scale <= 0) bad_arg("scale must be positive"); + if (args.exponent <= 0) bad_arg("exponent must be greater than 0"); } }; diff --git a/common/accel-sigmoid.hpp b/common/accel-sigmoid.hpp index 7cfa6c4..5bbe58f 100644 --- a/common/accel-sigmoid.hpp +++ b/common/accel-sigmoid.hpp @@ -24,8 +24,8 @@ namespace rawaccel { } void verify(const accel_args& args) const { - if (args.limit <= 1) error("exponent must be greater than 1"); - if (args.midpoint < 0) error("midpoint must not be negative"); + if (args.limit <= 1) bad_arg("exponent must be greater than 1"); + if (args.midpoint < 0) bad_arg("midpoint must not be negative"); } }; diff --git a/common/common.vcxitems b/common/common.vcxitems index 7102164..9696ac6 100644 --- a/common/common.vcxitems +++ b/common/common.vcxitems @@ -22,7 +22,7 @@ - + diff --git a/common/rawaccel-error.hpp b/common/rawaccel-error.hpp new file mode 100644 index 0000000..f5498f9 --- /dev/null +++ b/common/rawaccel-error.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include + +namespace rawaccel { + + class error : public std::runtime_error { + using std::runtime_error::runtime_error; + }; + + class invalid_argument : public error { + using error::error; + }; + + class io_error : public error { + using error::error; + }; + + class install_error : public io_error { + public: + install_error() : io_error("rawaccel is not installed") {} + }; + + class cooldown_error : public io_error { + public: + cooldown_error() : io_error("write is on cooldown") {} + }; + +} diff --git a/common/rawaccel-io.hpp b/common/rawaccel-io.hpp index fc64c7d..7f55392 100644 --- a/common/rawaccel-io.hpp +++ b/common/rawaccel-io.hpp @@ -21,7 +21,7 @@ namespace rawaccel { ra_handle = CreateFileW(L"\\\\.\\rawaccel", 0, 0, 0, OPEN_EXISTING, 0, 0); if (ra_handle == INVALID_HANDLE_VALUE) { - throw std::system_error(GetLastError(), std::system_category(), "CreateFile failed"); + throw install_error(); } mouse_modifier mod; @@ -54,7 +54,7 @@ namespace rawaccel { ra_handle = CreateFileW(L"\\\\.\\rawaccel", 0, 0, 0, OPEN_EXISTING, 0, 0); if (ra_handle == INVALID_HANDLE_VALUE) { - throw std::system_error(GetLastError(), std::system_category(), "CreateFile failed"); + throw install_error(); } DWORD dummy; @@ -73,7 +73,10 @@ namespace rawaccel { CloseHandle(ra_handle); if (!success) { - throw std::system_error(GetLastError(), std::system_category(), "DeviceIoControl failed"); + if (auto err = GetLastError(); err != ERROR_BUSY) { + throw std::system_error(err, std::system_category(), "DeviceIoControl failed"); + } + throw cooldown_error(); } } diff --git a/common/rawaccel.hpp b/common/rawaccel.hpp index 474f2aa..7aa1eb2 100644 --- a/common/rawaccel.hpp +++ b/common/rawaccel.hpp @@ -16,6 +16,8 @@ namespace rawaccel { + using milliseconds = double; + /// Struct to hold vector rotation details. struct rotator { @@ -104,8 +106,8 @@ namespace rawaccel { vec2 clamp; accel_function(const accel_fn_args& args) { - if (args.time_min <= 0) error("min time must be positive"); - if (args.acc_args.offset < 0) error("offset must not be negative"); + if (args.time_min <= 0) bad_arg("min time must be positive"); + if (args.acc_args.offset < 0) bad_arg("offset must not be negative"); accel.tag = args.accel_mode; accel.visit([&](auto& impl){ impl = { args.acc_args }; }); diff --git a/console/console.cpp b/console/console.cpp index 9a1d66f..f86dfc2 100644 --- a/console/console.cpp +++ b/console/console.cpp @@ -10,12 +10,10 @@ int main(int argc, char** argv) { try { ra::write(ra::parse(argc, argv)); } - catch (std::domain_error e) { - std::cerr << e.what() << '\n'; - return ra::INVALID_ARGUMENT; + catch (const std::system_error& e) { + std::cerr << e.what() << " (" << e.code() << ")\n"; } - catch (std::system_error e) { - std::cerr << "Error: " << e.what() << " (" << e.code() << ")\n"; - return ra::SYSTEM_ERROR; + catch (const std::exception& e) { + std::cerr << e.what() << '\n'; } } diff --git a/console/parse.hpp b/console/parse.hpp index 1cdb3fb..abdd36c 100644 --- a/console/parse.hpp +++ b/console/parse.hpp @@ -3,16 +3,12 @@ #include #include -#include +#include #include "external/clipp.h" namespace rawaccel { - inline constexpr int SYSTEM_ERROR = -1; - inline constexpr int PARSE_ERROR = 1; - inline constexpr int INVALID_ARGUMENT = 2; - template clipp::parameter make_accel_cmd(modifier_args& args, StrFirst&& first_flag, StrRest&&... rest) { return clipp::command(first_flag, rest...) @@ -113,6 +109,8 @@ namespace rawaccel { ); if (!clipp::parse(argc, argv, cli)) { + constexpr int PARSE_ERROR = 1; + std::cout << clipp::usage_lines(cli, "rawaccel", make_doc_fmt()); std::exit(PARSE_ERROR); } diff --git a/wrapper/wrapper.hpp b/wrapper/wrapper.hpp index 22a1b1e..1933ccc 100644 --- a/wrapper/wrapper.hpp +++ b/wrapper/wrapper.hpp @@ -2,9 +2,6 @@ #include -#include -#include - #include "wrapper_io.hpp" using namespace rawaccel; -- cgit v1.2.3