summaryrefslogtreecommitdiff
path: root/common/rawaccel-io.hpp
blob: 0d3ddee7748ab526e48b8010eeef096253d2696c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#pragma once

#include <system_error>

#define NOMINMAX
#include <Windows.h>

#include "rawaccel-io-def.h"
#include "rawaccel-base.hpp"
#include "rawaccel-version.h"
#include "rawaccel-error.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 settings read() 
	{
		settings args;
		io_control(RA_READ, NULL, 0, &args, sizeof(settings));
		return args;
	}


	inline void write(const settings& args) 
	{
		auto in_ptr = const_cast<settings*>(&args);
		io_control(RA_WRITE, in_ptr, sizeof(settings), NULL, 0);
	}

	inline version_t get_version() 
	{
		version_t ver;
		io_control(RA_GET_VERSION, NULL, 0, &ver, sizeof(version_t));
		return ver;
	}

}

#pragma warning(pop)