diff options
| author | Jacob Palecki <[email protected]> | 2020-08-11 21:16:50 -0700 |
|---|---|---|
| committer | Jacob Palecki <[email protected]> | 2020-08-11 21:16:50 -0700 |
| commit | 319eb45dee5b805eee976d7c2d6be0a9d090d3ed (patch) | |
| tree | d164cf52ce420c2c51aee2e9c0fe67c5fe5b56c5 | |
| parent | Further comments (diff) | |
| parent | Merge pull request #13 from a1xd/write-cd (diff) | |
| download | rawaccel-319eb45dee5b805eee976d7c2d6be0a9d090d3ed.tar.xz rawaccel-319eb45dee5b805eee976d7c2d6be0a9d090d3ed.zip | |
Merge branch 'master' into GainCap
| -rw-r--r-- | common/accel-base.hpp | 17 | ||||
| -rw-r--r-- | common/accel-classic.hpp | 2 | ||||
| -rw-r--r-- | common/accel-error.hpp | 11 | ||||
| -rw-r--r-- | common/accel-natural.hpp | 2 | ||||
| -rw-r--r-- | common/accel-power.hpp | 4 | ||||
| -rw-r--r-- | common/accel-sigmoid.hpp | 4 | ||||
| -rw-r--r-- | common/common.vcxitems | 2 | ||||
| -rw-r--r-- | common/rawaccel-error.hpp | 29 | ||||
| -rw-r--r-- | common/rawaccel-io.hpp | 9 | ||||
| -rw-r--r-- | common/rawaccel.hpp | 6 | ||||
| -rw-r--r-- | console/console.cpp | 10 | ||||
| -rw-r--r-- | console/parse.hpp | 8 | ||||
| -rw-r--r-- | driver/driver.cpp | 23 | ||||
| -rw-r--r-- | driver/driver.h | 4 | ||||
| -rw-r--r-- | wrapper/wrapper.hpp | 3 |
15 files changed, 87 insertions, 47 deletions
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 { + /// <summary> Struct to hold arguments for an acceleration function. </summary> struct accel_args { double offset = 0; @@ -60,7 +67,7 @@ namespace rawaccel { /// </summary> /// <param name="args">Arguments to verified.</param> 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 <stdexcept> - -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 @@ <ClInclude Include="$(MSBuildThisFileDirectory)accel-noaccel.hpp" /> <ClInclude Include="$(MSBuildThisFileDirectory)accel-power.hpp" /> <ClInclude Include="$(MSBuildThisFileDirectory)accel-sigmoid.hpp" /> - <ClInclude Include="$(MSBuildThisFileDirectory)accel-error.hpp" /> + <ClInclude Include="$(MSBuildThisFileDirectory)rawaccel-error.hpp" /> <ClInclude Include="$(MSBuildThisFileDirectory)rawaccel-io.hpp" /> <ClInclude Include="$(MSBuildThisFileDirectory)rawaccel.hpp" /> <ClInclude Include="$(MSBuildThisFileDirectory)tagged-union-single.h" /> 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 <stdexcept> + +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 a2ed801..fc06731 100644 --- a/common/rawaccel.hpp +++ b/common/rawaccel.hpp @@ -16,6 +16,8 @@ namespace rawaccel { + using milliseconds = double; + /// <summary> Struct to hold vector rotation details. </summary> struct rotator { @@ -184,8 +186,8 @@ namespace rawaccel { velocity_gain_cap gain_cap = velocity_gain_cap(); 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 <iostream> #include <rawaccel.hpp> -#include <accel-error.hpp> +#include <rawaccel-error.hpp> #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<typename Accel, typename StrFirst, typename... StrRest> 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/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<ra::mouse_modifier*>(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; diff --git a/wrapper/wrapper.hpp b/wrapper/wrapper.hpp index a1486f8..20ee095 100644 --- a/wrapper/wrapper.hpp +++ b/wrapper/wrapper.hpp @@ -2,9 +2,6 @@ #include <iostream> -#include <rawaccel.hpp> -#include <accel-error.hpp> - #include "wrapper_io.hpp" using namespace rawaccel; |