-
-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathXGMDevice.c
executable file
·246 lines (225 loc) · 8.42 KB
/
XGMDevice.c
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
/*++
Module Name:
XGMDevice.c - Command handler for XGM device.
Abstract:
This file contains the logic for XGM device.
Environment:
User-mode Driver Framework 2
--*/
#include "Driver.h"
#include "XGMDevice.h"
#include "XGMDevice.tmh"
#include <WinSock2.h>
//
// This is the default report descriptor for the virtual Hid device returned
// by the mini driver in response to IOCTL_HID_GET_REPORT_DESCRIPTOR.
//
HID_REPORT_DESCRIPTOR G_DefaultReportDescriptor[] =
{
0x06, 0x31, 0xFF, // Usage Page (Vendor Defined 0xFF31)
0x09, 0x76, // Usage (0x76)
0xA1, 0x01, // Collection (Application)
0x85, 0x5A, // Report ID (90)
0x19, 0x00, // Usage Minimum (0x00)
0x2A, 0xFF, 0x00, // Usage Maximum (0xFF)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x95, 0x05, // Report Count (5)
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x19, 0x00, // Usage Minimum (0x00)
0x2A, 0xFF, 0x00, // Usage Maximum (0xFF)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x95, 0x3F, // Report Count (63)
0xB1, 0x00, // Feature (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
0x06, 0x31, 0xFF, // Usage Page (Vendor Defined 0xFF31)
0x09, 0x80, // Usage (0x80)
0xA1, 0x01, // Collection (Application)
0x85, XGM_REPORT_ID, // Report ID (94)
0x19, 0x00, // Usage Minimum (0x00)
0x2A, 0xFF, 0x00, // Usage Maximum (0xFF)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x95, 0x05, // Report Count (5)
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x19, 0x00, // Usage Minimum (0x00)
0x2A, 0xFF, 0x00, // Usage Maximum (0xFF)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x96, 0x2B, 0x01, // Report Count (299)
0xB1, 0x00, // Feature (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
};
#define MAX_HID_REPORT_SIZE sizeof(HIDINJECTOR_INPUT_REPORT)
//
// This is the default HID descriptor returned by the mini driver
// in response to IOCTL_HID_GET_DEVICE_DESCRIPTOR. The size
// of report descriptor is currently the size of G_DefaultReportDescriptor.
//
HID_DESCRIPTOR G_DefaultHidDescriptor =
{
0x09, // length of HID descriptor
0x21, // descriptor type == HID 0x21
0x0100, // hid spec release
0x00, // country code == Not Specified
0x01, // number of HID class descriptors
{ //DescriptorList[0]
0x22, //report descriptor type 0x22
sizeof(G_DefaultReportDescriptor) //total length of report descriptor
}
};
static void ParseModel(
_In_ PCWSTR pModel,
_Out_ PUINT16 pVid,
_Out_ PUINT16 pPid,
_Out_ PUINT16 pSvid,
_Out_ PUINT16 pSsid
)
{
if (_wcsicmp(pModel, L"GC31R") == 0)
{
*pVid = ntohs(0x10de);
*pPid = ntohs(0x249d);
*pSvid = ntohs(0x1043);
*pSsid = ntohs(0x218b);
}
else if (_wcsicmp(pModel, L"GC31S") == 0)
{
*pVid = ntohs(0x10de);
*pPid = ntohs(0x249c);
*pSvid = ntohs(0x1043);
*pSsid = ntohs(0x217b);
}
else if (_wcsicmp(pModel, L"GC33Y") == 0)
{
*pVid = ntohs(0x10de);
*pPid = ntohs(0x2717);
*pSvid = ntohs(0x1043);
*pSsid = ntohs(0x21fb);
}
else if (_wcsicmp(pModel, L"GC33Z") == 0)
{
*pVid = ntohs(0x10de);
*pPid = ntohs(0x27a0);
*pSvid = ntohs(0x1043);
*pSsid = ntohs(0x220b);
}
else // if (_wcsicmp(pModel, L"GC32L") == 0)
{
*pVid = ntohs(0x1002);
*pPid = ntohs(0x73df);
*pSvid = ntohs(0x1043);
*pSsid = ntohs(0x21cb);
}
}
static void ParseSerial(
_In_ PCWSTR pInput,
_In_ USHORT inputLength,
_Out_ PSTR pOutput
)
{
memset(pOutput, '0', 8);
WideCharToMultiByte(CP_ACP, 0, pInput, inputLength, pOutput, 9, NULL, NULL);
}
static NTSTATUS
XGMDriver_Get_EGPUID(
_In_ PUCHAR InputBuffer,
_Out_ PHID_XGM_REPORT OutputReportBuffer,
_Inout_ PULONG OutputReportBufferLength
)
{
NTSTATUS status = STATUS_SUCCESS;
WDFKEY hKey;
WDFSTRING pWdfModel, pWdfSerial;
UNICODE_STRING pModel, pSerial;
DECLARE_CONST_UNICODE_STRING(pModelKey, L"Model");
DECLARE_CONST_UNICODE_STRING(pSerialKey, L"Serial");
DECLARE_CONST_UNICODE_STRING(pEmptyString, L"");
if (*OutputReportBufferLength < 24)
{
return STATUS_BUFFER_TOO_SMALL;
}
if (InputBuffer[0] != 3)
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "XGMDriver_Get_EGPUID Error: unknown argument %Xh", InputBuffer[0]);
return STATUS_INVALID_PARAMETER;
}
// get data from registry
status = WdfStringCreate(&pEmptyString, WDF_NO_OBJECT_ATTRIBUTES, &pWdfModel);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "XGMDriver_Get_EGPUID Error: WdfStringCreate failed %!STATUS!", status);
return status;
}
status = WdfStringCreate(&pEmptyString, WDF_NO_OBJECT_ATTRIBUTES, &pWdfSerial);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "XGMDriver_Get_EGPUID Error: WdfStringCreate failed %!STATUS!", status);
WdfObjectDelete(pWdfModel);
return status;
}
status = WdfDriverOpenParametersRegistryKey(WdfGetDriver(), KEY_READ, WDF_NO_OBJECT_ATTRIBUTES, &hKey);
if (NT_SUCCESS(status))
{
status = WdfRegistryQueryString(hKey, &pModelKey, pWdfModel);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "XGMDriver_Get_EGPUID Error: WdfRegistryQueryString failed %!STATUS!", status);
}
status = WdfRegistryQueryString(hKey, &pSerialKey, pWdfSerial);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "XGMDriver_Get_EGPUID Error: WdfRegistryQueryString failed %!STATUS!", status);
}
}
else
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "XGMDriver_Get_EGPUID Error: WdfDriverOpenParametersRegistryKey failed %!STATUS!", status);
}
status = STATUS_SUCCESS; // ignore error
WdfStringGetUnicodeString(pWdfSerial, &pSerial);
WdfStringGetUnicodeString(pWdfModel, &pModel);
OutputReportBuffer->ReportID = XGM_REPORT_ID;
OutputReportBuffer->Command = XGM_CMD_GET_EGPUID;
OutputReportBuffer->Data[0] = 0x03;
ParseModel(pModel.Buffer, (PUINT16)&OutputReportBuffer->Data[1], (PUINT16)&OutputReportBuffer->Data[3], (PUINT16)&OutputReportBuffer->Data[7], (PUINT16)&OutputReportBuffer->Data[5]);
ParseSerial(pSerial.Buffer, pSerial.Length, (PSTR)&OutputReportBuffer->Data[9]);
OutputReportBuffer->Data[17] = 'G';
OutputReportBuffer->Data[18] = 'E';
OutputReportBuffer->Data[19] = 'N';
OutputReportBuffer->Data[20] = ' ';
OutputReportBuffer->Data[21] = '4';
WdfObjectDelete(pWdfSerial);
WdfObjectDelete(pWdfModel);
*OutputReportBufferLength = 24;
return status;
}
NTSTATUS
XGMDriver_ProcessCommand(
_In_ UCHAR Command,
_In_ PUCHAR InputBuffer,
_Out_ PHID_XGM_REPORT OutputReportBuffer,
_Inout_ PULONG OutputReportBufferLength
)
{
NTSTATUS status = STATUS_SUCCESS;
switch (Command)
{
case XGM_CMD_GET_EGPUID:
{
status = XGMDriver_Get_EGPUID(InputBuffer, OutputReportBuffer, OutputReportBufferLength);
break;
}
default:
{
status = STATUS_INVALID_PARAMETER;
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "XGMDriver_ProcessCommand Error: command %Xh not handled", Command);
}
}
return status;
}