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