-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEcCommunication.cpp
More file actions
151 lines (129 loc) · 3.63 KB
/
EcCommunication.cpp
File metadata and controls
151 lines (129 loc) · 3.63 KB
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright (C) Framework Computer Inc, All Rights Reserved.
//
// Abstract:
//
// This module contains the implementation of communication with the embedded controller.
//
// Only need EC commands to use EC_CMD_MOTION_SENSE_CMD to determine which
// accel sensors there are and which position they are. ALl the rest can be
// done using memory map reads.
//
// Environment:
//
// Windows User-Mode Driver Framework (UMDF)
#include "EcCommunication.h"
#include <windows.h>
#include <wdf.h>
#include "EcCommunication.tmh"
NTSTATUS ConnectToEc(
_Inout_ HANDLE* Handle
) {
if (Handle == NULL) {
TraceError("%!FUNC! Handle pointer is NULL");
return STATUS_INVALID_PARAMETER;
}
if (*Handle != INVALID_HANDLE_VALUE) {
// Already connected
TraceError("%!FUNC! Already connected");
return STATUS_SUCCESS;
}
*Handle = CreateFileW(
LR"(\\.\GLOBALROOT\Device\CrosEC)",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
if (*Handle == INVALID_HANDLE_VALUE) {
TraceError("%!FUNC! CreateFileW failed");
return STATUS_INVALID_HANDLE;
}
TraceInformation("%!FUNC! Got Handle");
return STATUS_SUCCESS;
}
int CrosEcSendCommand(
HANDLE Handle,
UINT16 command,
UINT8 version,
LPVOID outdata,
unsigned int outlen,
LPVOID indata,
unsigned int inlen
)
{
DWORD retb{};
CROSEC_COMMAND cmd{};
if (Handle == INVALID_HANDLE_VALUE) {
TraceError("%!FUNC! Invalid Handle");
return 0;
}
if (outlen > CROS_EC_CMD_MAX_REQUEST || inlen > CROS_EC_CMD_MAX_REQUEST) {
TraceError("%!FUNC! outlen %d or inlen %d too large", outlen, inlen);
return 0;
}
if (outlen == 0) {
TraceError("%!FUNC! outlen is 0");
return 0;
}
if (outdata == nullptr) {
TraceError("%!FUNC! Invalid outdata - NULL");
return 0;
}
cmd.command = command;
cmd.version = version;
cmd.result = 0xFF;
cmd.outlen = outlen;
cmd.inlen = CROS_EC_CMD_MAX_REQUEST - 8; // 8 is the header length
RtlCopyMemory(cmd.data, outdata, outlen);
if (!DeviceIoControl(Handle,
(DWORD) IOCTL_CROSEC_XCMD,
&cmd,
sizeof(cmd),
&cmd,
sizeof(cmd),
&retb,
nullptr)) {
DWORD err = GetLastError();
TraceError("%!FUNC! DeviceIoControl XCMD failed, error=%d", err);
return 0;
}
if (cmd.result != EC_RES_SUCCESS) {
TraceError("%!FUNC! Host command failed - EC result %d", cmd.result);
return 0;
}
if (inlen > 0) {
if (indata == nullptr) {
TraceError("%!FUNC! inlen is %d. But indata is NULL", inlen);
return 0;
}
RtlCopyMemory(indata, cmd.data, inlen);
}
return cmd.inlen;
}
int CrosEcReadMemU8(HANDLE Handle, unsigned int offset, UINT8* dest)
{
DWORD retb{};
CROSEC_READMEM rm{};
if (Handle == INVALID_HANDLE_VALUE) {
TraceError("%!FUNC! Invalid Handle");
return 0;
}
rm.bytes = 0x01;
rm.offset = offset;
if (!DeviceIoControl(Handle,
(DWORD) IOCTL_CROSEC_RDMEM,
&rm,
sizeof(rm),
&rm,
sizeof(rm),
&retb,
nullptr)) {
DWORD err = GetLastError();
TraceError("%!FUNC! DeviceIoControl RDMEM failed, error=%d", err);
return 0;
}
TraceInformation("%!FUNC! Successfully read %d bytes from EC memory at %02x. First one %02x. retb=%d", rm.bytes, rm.offset, rm.buffer[0], retb);
*dest = rm.buffer[0];
return rm.bytes;
}