summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Palecki <[email protected]>2020-08-11 21:16:50 -0700
committerJacob Palecki <[email protected]>2020-08-11 21:16:50 -0700
commit319eb45dee5b805eee976d7c2d6be0a9d090d3ed (patch)
treed164cf52ce420c2c51aee2e9c0fe67c5fe5b56c5
parentFurther comments (diff)
parentMerge pull request #13 from a1xd/write-cd (diff)
downloadrawaccel-319eb45dee5b805eee976d7c2d6be0a9d090d3ed.tar.xz
rawaccel-319eb45dee5b805eee976d7c2d6be0a9d090d3ed.zip
Merge branch 'master' into GainCap
-rw-r--r--common/accel-base.hpp17
-rw-r--r--common/accel-classic.hpp2
-rw-r--r--common/accel-error.hpp11
-rw-r--r--common/accel-natural.hpp2
-rw-r--r--common/accel-power.hpp4
-rw-r--r--common/accel-sigmoid.hpp4
-rw-r--r--common/common.vcxitems2
-rw-r--r--common/rawaccel-error.hpp29
-rw-r--r--common/rawaccel-io.hpp9
-rw-r--r--common/rawaccel.hpp6
-rw-r--r--console/console.cpp10
-rw-r--r--console/parse.hpp8
-rw-r--r--driver/driver.cpp23
-rw-r--r--driver/driver.h4
-rw-r--r--wrapper/wrapper.hpp3
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;