diff options
Diffstat (limited to 'common')
| -rw-r--r-- | common/common.vcxitems | 1 | ||||
| -rw-r--r-- | common/rawaccel-error.hpp | 27 | ||||
| -rw-r--r-- | common/rawaccel-io-def.h | 4 | ||||
| -rw-r--r-- | common/rawaccel-io.hpp | 123 | ||||
| -rw-r--r-- | common/rawaccel-validate.hpp | 168 | ||||
| -rw-r--r-- | common/rawaccel-version.h | 30 | ||||
| -rw-r--r-- | common/utility.hpp | 4 |
7 files changed, 289 insertions, 68 deletions
diff --git a/common/common.vcxitems b/common/common.vcxitems index 4cbe2b7..6d1b861 100644 --- a/common/common.vcxitems +++ b/common/common.vcxitems @@ -26,6 +26,7 @@ <ClInclude Include="$(MSBuildThisFileDirectory)rawaccel-io-def.h" /> <ClInclude Include="$(MSBuildThisFileDirectory)rawaccel-io.hpp" /> <ClInclude Include="$(MSBuildThisFileDirectory)rawaccel-base.hpp" /> + <ClInclude Include="$(MSBuildThisFileDirectory)rawaccel-validate.hpp" /> <ClInclude Include="$(MSBuildThisFileDirectory)rawaccel-version.h" /> <ClInclude Include="$(MSBuildThisFileDirectory)rawaccel.hpp" /> <ClInclude Include="$(MSBuildThisFileDirectory)utility-install.hpp" /> diff --git a/common/rawaccel-error.hpp b/common/rawaccel-error.hpp index cdbe1e5..a9cb7b8 100644 --- a/common/rawaccel-error.hpp +++ b/common/rawaccel-error.hpp @@ -1,11 +1,12 @@ #pragma once -#include <stdexcept> +#include <system_error> +#include <string> namespace rawaccel { - class error : public std::runtime_error { - using std::runtime_error::runtime_error; + class error : public std::runtime_error { + using std::runtime_error::runtime_error; }; class io_error : public error { @@ -14,7 +15,25 @@ namespace rawaccel { class install_error : public io_error { public: - install_error() : io_error("Raw Accel driver is not installed, run installer.exe") {} + install_error() : + io_error("Raw Accel is not installed, run installer.exe") {} + }; + + class sys_error : public io_error { + public: + sys_error(const char* msg, DWORD code = GetLastError()) : + io_error(build_msg(code, msg)) {} + + static std::string build_msg(DWORD code, const char* msg) + { + std::string ret = + std::system_error(code, std::system_category(), msg).what(); + ret += " ("; + ret += std::to_string(code); + ret += ")"; + return ret; + } + }; } diff --git a/common/rawaccel-io-def.h b/common/rawaccel-io-def.h index e169390..399e0f2 100644 --- a/common/rawaccel-io-def.h +++ b/common/rawaccel-io-def.h @@ -1,9 +1,11 @@ #pragma once +#define NOMINMAX + #ifdef _KERNEL_MODE #include <ntddk.h> #else -#include <winioctl.h> +#include <Windows.h> #endif #define RA_DEV_TYPE 0x8888u diff --git a/common/rawaccel-io.hpp b/common/rawaccel-io.hpp index da496fa..a80e254 100644 --- a/common/rawaccel-io.hpp +++ b/common/rawaccel-io.hpp @@ -1,67 +1,84 @@ #pragma once #include "rawaccel-io-def.h" -#include "rawaccel.hpp" #include "rawaccel-version.h" #include "rawaccel-error.hpp" - -#define NOMINMAX -#define WIN32_LEAN_AND_MEAN -#include <Windows.h> - -#include <system_error> +#include "rawaccel.hpp" #pragma warning(push) #pragma warning(disable:4245) // int -> DWORD conversion while passing CTL_CODE namespace rawaccel { - inline void io_control(DWORD code, void* in, DWORD in_size, void* out, DWORD out_size) - { - HANDLE ra_handle = INVALID_HANDLE_VALUE; - - ra_handle = CreateFileW(L"\\\\.\\rawaccel", 0, 0, 0, OPEN_EXISTING, 0, 0); - - if (ra_handle == INVALID_HANDLE_VALUE) { - throw install_error(); - } - - DWORD dummy; - - BOOL success = DeviceIoControl( - ra_handle, - code, - in, - in_size, - out, - out_size, - &dummy, // bytes returned - NULL // overlapped structure - ); - - CloseHandle(ra_handle); - - if (!success) { - throw std::system_error(GetLastError(), std::system_category(), "DeviceIoControl failed"); - } - } - - inline void read(io_t& args) - { - io_control(RA_READ, NULL, 0, &args, sizeof(io_t)); - } - - inline void write(const io_t& args) - { - io_control(RA_WRITE, const_cast<io_t*>(&args), sizeof(io_t), NULL, 0); - } - - inline version_t get_version() - { - version_t ver; - io_control(RA_GET_VERSION, NULL, 0, &ver, sizeof(version_t)); - return ver; - } + inline void io_control(DWORD code, void* in, DWORD in_size, void* out, DWORD out_size) + { + HANDLE ra_handle = INVALID_HANDLE_VALUE; + + ra_handle = CreateFileW(L"\\\\.\\rawaccel", 0, 0, 0, OPEN_EXISTING, 0, 0); + + if (ra_handle == INVALID_HANDLE_VALUE) { + throw install_error(); + } + + DWORD dummy; + + BOOL success = DeviceIoControl( + ra_handle, + code, + in, + in_size, + out, + out_size, + &dummy, // bytes returned + NULL // overlapped structure + ); + + CloseHandle(ra_handle); + + if (!success) { + throw sys_error("DeviceIoControl failed"); + } + } + + inline void read(io_t& args) + { + io_control(RA_READ, NULL, 0, &args, sizeof(io_t)); + } + + inline void write(const io_t& args) + { + io_control(RA_WRITE, const_cast<io_t*>(&args), sizeof(io_t), NULL, 0); + } + + inline version_t get_version() + { + version_t v; + + try { + io_control(RA_GET_VERSION, NULL, 0, &v, sizeof(version_t)); + } + catch (const sys_error&) { + // assume request is not implemented (< 1.3) + v = { 0 }; + } + + return v; + } + + inline version_t valid_version_or_throw() + { + auto v = get_version(); + + if (v < min_driver_version) { + throw error("reinstallation required"); + } + + if (version < v) { + throw error("newer driver is installed"); + } + + return v; + } } diff --git a/common/rawaccel-validate.hpp b/common/rawaccel-validate.hpp new file mode 100644 index 0000000..b9ee2af --- /dev/null +++ b/common/rawaccel-validate.hpp @@ -0,0 +1,168 @@ +#pragma once + +#include "rawaccel-base.hpp" +#include "utility.hpp" + +namespace rawaccel { + + struct valid_ret_t { + int count_x = 0; + int count_y = 0; + int count = 0; + + explicit operator bool() const + { + return count == 0; + } + }; + + template <typename MsgHandler = noop> + valid_ret_t valid(const settings& args, MsgHandler fn = {}) + { + valid_ret_t ret; + + auto error = [&](auto msg) { + ++ret.count; + fn(msg); + }; + + auto check_accel = [&error](const accel_args& args) { + static_assert(LUT_CAPACITY == 1025, "update error msg"); + + const auto& lut_args = args.lut_args; + + if (lut_args.partitions <= 0) { + error("lut partitions"" must be positive"); + } + + if (lut_args.mode == table_mode::linear) { + if (lut_args.start <= 0) { + error("start"" must be positive"); + } + + if (lut_args.stop <= lut_args.start) { + error("stop must be greater than start"); + } + + if (lut_args.num_elements < 2 || + lut_args.num_elements > 1025) { + error("num must be between 2 and 1025"); + } + } + else if (lut_args.mode == table_mode::binlog) { + int istart = static_cast<int>(lut_args.start); + int istop = static_cast<int>(lut_args.stop); + + if (lut_args.start < -99) { + error("start is too small"); + } + else if (lut_args.stop > 99) { + error("stop is too large"); + } + else if (istart != lut_args.start || istop != lut_args.stop) { + error("start and stop must be integers"); + } + else if (istop <= istart) { + error("stop must be greater than start"); + } + else if (lut_args.num_elements <= 0) { + error("num"" must be positive"); + } + else if (((lut_args.stop - lut_args.start) * lut_args.num_elements) >= 1025) { + error("binlog mode requires (num * (stop - start)) < 1025"); + } + } + + if (args.offset < 0) { + error("offset can not be negative"); + } + + if (args.cap <= 0) { + error("cap"" must be positive"); + } + + if (args.accel_motivity <= 0 || + args.accel_natural <= 0 || + args.accel_classic <= 0) { + error("acceleration"" must be positive"); + } + + if (args.motivity <= 1) { + error("motivity must be greater than 1"); + } + + if (args.power <= 1) { + error("power must be greater than 1"); + } + + if (args.scale <= 0) { + error("scale"" must be positive"); + } + + if (args.weight <= 0) { + error("weight"" must be positive"); + } + + if (args.exponent <= 0) { + error("exponent"" must be positive"); + } + + if (args.limit <= 0) { + error("limit"" must be positive"); + } + + if (args.midpoint <= 0) { + error("midpoint"" must be positive"); + } + + if (args.smooth < 0 || args.smooth > 1) { + error("smooth must be between 0 and 1"); + } + + }; + + check_accel(args.argsv.x); + + if (!args.combine_mags) { + ret.count_x = ret.count; + check_accel(args.argsv.y); + ret.count_y = ret.count; + } + + if (args.dpi <= 0) { + error("dpi"" must be positive"); + } + + if (args.speed_cap <= 0) { + error("speed cap"" must be positive"); + } + + if (args.sens.x == 0 || args.sens.y == 0) { + error("sens multiplier is 0"); + } + + if (args.dom_args.domain_weights.x <= 0 || + args.dom_args.domain_weights.y <= 0) { + error("domain weights"" must be positive"); + } + + if (args.dom_args.lp_norm <= 0) { + error("Lp norm can not be negative"); + } + + if (args.dir_multipliers.x < 0 || args.dir_multipliers.y < 0) { + error("directional multipliers can not be negative"); + } + + if (args.range_weights.x <= 0 || args.range_weights.y <= 0) { + error("range weights"" must be positive"); + } + + if (args.time_min <= 0) { + error("minimum time"" must be positive"); + } + + return ret; + } + +} diff --git a/common/rawaccel-version.h b/common/rawaccel-version.h index 40ff2d2..de8644b 100644 --- a/common/rawaccel-version.h +++ b/common/rawaccel-version.h @@ -6,21 +6,31 @@ #define RA_OS "Win7+" -#define M_STR_HELPER(x) #x -#define M_STR(x) M_STR_HELPER(x) +#define RA_M_STR_HELPER(x) #x +#define RA_M_STR(x) RA_M_STR_HELPER(x) -#define RA_VER_STRING M_STR(RA_VER_MAJOR) "." M_STR(RA_VER_MINOR) "." M_STR(RA_VER_PATCH) +#define RA_VER_STRING RA_M_STR(RA_VER_MAJOR) "." RA_M_STR(RA_VER_MINOR) "." RA_M_STR(RA_VER_PATCH) namespace rawaccel { - struct version_t { - int major; - int minor; - int patch; - }; - + struct version_t { + int major; + int minor; + int patch; + }; + + constexpr bool operator<(const version_t& lhs, const version_t& rhs) + { + return (lhs.major != rhs.major) ? + (lhs.major < rhs.major) : + (lhs.minor != rhs.minor) ? + (lhs.minor < rhs.minor) : + (lhs.patch < rhs.patch) ; + } + + inline constexpr version_t version = { RA_VER_MAJOR, RA_VER_MINOR, RA_VER_PATCH }; #ifndef _KERNEL_MODE - inline constexpr version_t min_driver_version = { 1, 4, 0 }; + inline constexpr version_t min_driver_version = { 1, 4, 0 }; #endif } diff --git a/common/utility.hpp b/common/utility.hpp index de90d44..5f5c186 100644 --- a/common/utility.hpp +++ b/common/utility.hpp @@ -81,4 +81,8 @@ namespace rawaccel { return ilogb(x) == 0x400; } + struct noop { + template <typename... Ts> + constexpr void operator()(Ts&&...) const noexcept {} + }; } |