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