]> cvs.zerfleddert.de Git - proxmark3-svn/blob - winsrc/prox.cpp
add extended help feature
[proxmark3-svn] / winsrc / prox.cpp
1 #include <windows.h>
2 #include <setupapi.h>
3 #include <stdio.h>
4 #include <ctype.h>
5 #include <stdlib.h>
6 extern "C" {
7 #include "include/hidsdi.h"
8 #include "include/hidpi.h"
9 }
10
11 #include "prox.h"
12
13 #define OUR_VID 0x9ac4
14 #define OUR_PID 0x4b8f
15
16 int offline = 0;
17 HANDLE UsbHandle;
18
19 static void ShowError(void)
20 {
21 char buf[1024];
22 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
23 buf, sizeof(buf), NULL);
24 printf("ERROR: %s", buf);
25 }
26
27 static BOOL UsbConnect(void)
28 {
29 typedef void (__stdcall *GetGuidProc)(GUID *);
30 typedef BOOLEAN (__stdcall *GetAttrProc)(HANDLE, HIDD_ATTRIBUTES *);
31 typedef BOOLEAN (__stdcall *GetPreparsedProc)(HANDLE,
32 PHIDP_PREPARSED_DATA *);
33 typedef NTSTATUS (__stdcall *GetCapsProc)(PHIDP_PREPARSED_DATA, PHIDP_CAPS);
34 GetGuidProc getGuid;
35 GetAttrProc getAttr;
36 GetPreparsedProc getPreparsed;
37 GetCapsProc getCaps;
38
39 HMODULE h = LoadLibrary("hid.dll");
40 getGuid = (GetGuidProc)GetProcAddress(h, "HidD_GetHidGuid");
41 getAttr = (GetAttrProc)GetProcAddress(h, "HidD_GetAttributes");
42 getPreparsed = (GetPreparsedProc)GetProcAddress(h, "HidD_GetPreparsedData");
43 getCaps = (GetCapsProc)GetProcAddress(h, "HidP_GetCaps");
44
45 GUID hidGuid;
46 getGuid(&hidGuid);
47
48 HDEVINFO devInfo;
49 devInfo = SetupDiGetClassDevs(&hidGuid, NULL, NULL,
50 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
51
52 SP_DEVICE_INTERFACE_DATA devInfoData;
53 devInfoData.cbSize = sizeof(devInfoData);
54
55 int i;
56 for(i = 0;; i++) {
57 if(!SetupDiEnumDeviceInterfaces(devInfo, 0, &hidGuid, i, &devInfoData))
58 {
59 if(GetLastError() != ERROR_NO_MORE_ITEMS) {
60 // printf("SetupDiEnumDeviceInterfaces failed\n");
61 }
62 // printf("done list\n");
63 SetupDiDestroyDeviceInfoList(devInfo);
64 return FALSE;
65 }
66
67 // printf("item %d:\n", i);
68
69 DWORD sizeReqd = 0;
70 if(!SetupDiGetDeviceInterfaceDetail(devInfo, &devInfoData,
71 NULL, 0, &sizeReqd, NULL))
72 {
73 if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
74 // printf("SetupDiGetDeviceInterfaceDetail (0) failed\n");
75 continue;
76 }
77 }
78
79 SP_DEVICE_INTERFACE_DETAIL_DATA *devInfoDetailData =
80 (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(sizeReqd);
81 devInfoDetailData->cbSize = sizeof(*devInfoDetailData);
82
83 if(!SetupDiGetDeviceInterfaceDetail(devInfo, &devInfoData,
84 devInfoDetailData, 87, NULL, NULL))
85 {
86 // printf("SetupDiGetDeviceInterfaceDetail (1) failed\n");
87 continue;
88 }
89
90 char *path = devInfoDetailData->DevicePath;
91
92 UsbHandle = CreateFile(path, /*GENERIC_READ |*/ GENERIC_WRITE,
93 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
94 FILE_FLAG_OVERLAPPED, NULL);
95
96 if(UsbHandle == INVALID_HANDLE_VALUE) {
97 ShowError();
98 // printf("CreateFile failed: for '%s'\n", path);
99 continue;
100 }
101
102 HIDD_ATTRIBUTES attr;
103 attr.Size = sizeof(attr);
104 if(!getAttr(UsbHandle, &attr)) {
105 ShowError();
106 // printf("HidD_GetAttributes failed\n");
107 continue;
108 }
109
110 // printf("VID: %04x PID %04x\n", attr.VendorID, attr.ProductID);
111
112 if(attr.VendorID != OUR_VID || attr.ProductID != OUR_PID) {
113 CloseHandle(UsbHandle);
114 // printf(" nope, not us\n");
115 continue;
116 }
117
118 // printf ("got it!\n");
119 CloseHandle(UsbHandle);
120
121 UsbHandle = CreateFile(path, GENERIC_READ | GENERIC_WRITE,
122 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
123 FILE_FLAG_OVERLAPPED, NULL);
124
125 if(UsbHandle == INVALID_HANDLE_VALUE) {
126 ShowError();
127 // printf("Error, couldn't open our own handle as desired.\n");
128 return FALSE;
129 }
130
131 PHIDP_PREPARSED_DATA pp;
132 getPreparsed(UsbHandle, &pp);
133 HIDP_CAPS caps;
134
135 if(getCaps(pp, &caps) != HIDP_STATUS_SUCCESS) {
136 // printf("getcaps failed\n");
137 return FALSE;
138 }
139
140 // printf("input/out report %d/%d\n", caps.InputReportByteLength,
141 // caps.OutputReportByteLength);
142
143
144 return TRUE;
145 }
146 return FALSE;
147 }
148
149 BOOL ReceiveCommandPoll(UsbCommand *c)
150 {
151 static BOOL ReadInProgress = FALSE;
152 static OVERLAPPED Ov;
153 static BYTE Buf[65];
154 static DWORD HaveRead;
155
156 if(!ReadInProgress) {
157 memset(&Ov, 0, sizeof(Ov));
158 ReadFile(UsbHandle, Buf, 65, &HaveRead, &Ov);
159 if(GetLastError() != ERROR_IO_PENDING) {
160 ShowError();
161 exit(-1);
162 }
163 ReadInProgress = TRUE;
164 }
165
166 if(HasOverlappedIoCompleted(&Ov)) {
167 ReadInProgress = FALSE;
168
169 if(!GetOverlappedResult(UsbHandle, &Ov, &HaveRead, FALSE)) {
170 ShowError();
171 exit(-1);
172 }
173
174 memcpy(c, Buf+1, 64);
175
176 return TRUE;
177 } else {
178 return FALSE;
179 }
180 }
181
182 void ReceiveCommand(UsbCommand *c)
183 {
184 while(!ReceiveCommandPoll(c)) {
185 Sleep(0);
186 }
187 }
188
189 void SendCommand(UsbCommand *c, BOOL wantAck)
190 {
191 BYTE buf[65];
192 buf[0] = 0;
193 memcpy(buf+1, c, 64);
194
195 DWORD written;
196 OVERLAPPED ov;
197 memset(&ov, 0, sizeof(ov));
198 WriteFile(UsbHandle, buf, 65, &written, &ov);
199 if(GetLastError() != ERROR_IO_PENDING) {
200 ShowError();
201 exit(-1);
202 }
203
204 while(!HasOverlappedIoCompleted(&ov)) {
205 Sleep(0);
206 }
207
208 if(!GetOverlappedResult(UsbHandle, &ov, &written, FALSE)) {
209 ShowError();
210 exit(-1);
211 }
212
213 if(wantAck) {
214 UsbCommand ack;
215 ReceiveCommand(&ack);
216 if(ack.cmd != CMD_ACK) {
217 printf("bad ACK\n");
218 exit(-1);
219 }
220 }
221 }
222
223 static DWORD ExpectedAddr;
224 static BYTE QueuedToSend[256];
225 static BOOL AllWritten;
226
227 static void FlushPrevious(void)
228 {
229 UsbCommand c;
230 memset(&c, 0, sizeof(c));
231
232 printf("expected = %08x flush, ", ExpectedAddr);
233
234 int i;
235 for(i = 0; i < 240; i += 48) {
236 c.cmd = CMD_SETUP_WRITE;
237 memcpy(c.d.asBytes, QueuedToSend+i, 48);
238 c.ext1 = (i/4);
239 SendCommand(&c, TRUE);
240 }
241
242 c.cmd = CMD_FINISH_WRITE;
243 c.ext1 = (ExpectedAddr-1) & (~255);
244 printf("c.ext1 = %08x\r", c.ext1);
245 memcpy(c.d.asBytes, QueuedToSend+240, 16);
246 SendCommand(&c, TRUE);
247
248 AllWritten = TRUE;
249 }
250
251 static void GotByte(DWORD where, BYTE which)
252 {
253 AllWritten = FALSE;
254
255 if(where != ExpectedAddr) {
256 printf("bad: got at %08x, expected at %08x\n", where, ExpectedAddr);
257 exit(-1);
258 }
259 QueuedToSend[where & 255] = which;
260 ExpectedAddr++;
261
262 if((where & 255) == 255) {
263 // we have completed a full page
264 FlushPrevious();
265 }
266 }
267
268 static int HexVal(int c)
269 {
270 c = tolower(c);
271 if(c >= '0' && c <= '9') {
272 return c - '0';
273 } else if(c >= 'a' && c <= 'f') {
274 return (c - 'a') + 10;
275 } else {
276 printf("bad hex digit '%c'\n", c);
277 exit(-1);
278 }
279 }
280
281 static BYTE HexByte(char *s)
282 {
283 return (HexVal(s[0]) << 4) | HexVal(s[1]);
284 }
285
286 static void LoadFlashFromSRecords(char *file, int addr)
287 {
288 ExpectedAddr = addr;
289
290 FILE *f = fopen(file, "r");
291 if(!f) {
292 printf("couldn't open file\n");
293 exit(-1);
294 }
295
296 char line[512];
297 while(fgets(line, sizeof(line), f)) {
298 if(memcmp(line, "S3", 2)==0) {
299 char *s = line + 2;
300 int len = HexByte(s) - 5;
301 s += 2;
302
303 char addrStr[9];
304 memcpy(addrStr, s, 8);
305 addrStr[8] = '\0';
306 DWORD addr;
307 sscanf(addrStr, "%x", &addr);
308 s += 8;
309
310 int i;
311 for(i = 0; i < len; i++) {
312 while((addr+i) > ExpectedAddr) {
313 GotByte(ExpectedAddr, 0xff);
314 }
315 GotByte(addr+i, HexByte(s));
316 s += 2;
317 }
318 }
319 }
320
321 if(!AllWritten) FlushPrevious();
322
323 fclose(f);
324 printf("\ndone.\n");
325 }
326
327 int main(int argc, char **argv)
328 {
329 int i = 0;
330
331 if(argc < 2) {
332 printf("Usage: %s bootrom file.s19\n", argv[0]);
333 printf(" %s load osimage.s19\n", argv[0]);
334 printf(" %s fpga fpgaimg.s19\n", argv[0]);
335 printf(" %s gui\n", argv[0]);
336 printf(" %s offline\n", argv[0]);
337 return -1;
338 }
339
340 // Only do this if NOT in offline mode
341 if (strcmp(argv[1], "offline"))
342 {
343 for(;;) {
344 if(UsbConnect()) {
345 break;
346 }
347 if(i == 0) {
348 printf("...no device connected, polling for it now\n");
349 }
350 if(i > 50000) {
351 printf("Could not connect to USB device; exiting.\n");
352 return -1;
353 }
354 i++;
355 Sleep(5);
356 }
357 }
358
359 if(strcmp(argv[1], "bootrom")==0 || strcmp(argv[1], "load")==0 || strcmp(argv[1], "fpga")==0) {
360 if(argc != 3) {
361 printf("Need filename.\n");
362 return -1;
363 }
364 if(strcmp(argv[1], "bootrom")==0) {
365 LoadFlashFromSRecords(argv[2], 0);
366 } else if(strcmp(argv[1], "fpga")==0) {
367 LoadFlashFromSRecords(argv[2], 0x2000);
368 } else {
369 LoadFlashFromSRecords(argv[2], 0x10000);
370 }
371 } else if(strcmp(argv[1], "gui")==0) {
372 ShowGui();
373 } else if(strcmp(argv[1], "offline")==0) {
374 offline = 1;
375 ShowGui();
376 } else if(strcmp(argv[1], "cmd")==0) {
377 if(argc != 3) {
378 printf("Need command.\n");
379 return -1;
380 }
381 ExecCmd(argv[2]);
382 } else {
383 printf("Command '%s' not recognized.\n", argv[1]);
384 return -1;
385 }
386
387 return 0;
388 }
Impressum, Datenschutz