]> git.zerfleddert.de Git - proxmark3-svn/blame_incremental - client/prox.c
Clean up data types, some header cleanup, etc.
[proxmark3-svn] / client / prox.c
... / ...
CommitLineData
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
6//extern "C" {\r
7#include "include/hidusage.h"\r
8#include "include/hidpi.h"\r
9#include "include/hidsdi.h"\r
10//}\r
11\r
12#include "flash.h"\r
13#include "usb_cmd.h"\r
14#include "ui.h"\r
15\r
16#define OUR_VID 0x9ac4\r
17#define OUR_PID 0x4b8f\r
18#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)\r
19\r
20int offline = 0;\r
21HANDLE UsbHandle;\r
22extern unsigned int current_command;\r
23extern struct partition partitions[];\r
24\r
25static void ShowError(void)\r
26{\r
27 char buf[1024];\r
28 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,\r
29 buf, sizeof(buf), NULL);\r
30 printf("ERROR: %s", buf);\r
31}\r
32\r
33BOOL UsbConnect(void)\r
34{\r
35 typedef void (__stdcall *GetGuidProc)(GUID *);\r
36 typedef BOOLEAN (__stdcall *GetAttrProc)(HANDLE, HIDD_ATTRIBUTES *);\r
37 typedef BOOLEAN (__stdcall *GetPreparsedProc)(HANDLE,\r
38 PHIDP_PREPARSED_DATA *);\r
39 typedef NTSTATUS (__stdcall *GetCapsProc)(PHIDP_PREPARSED_DATA, PHIDP_CAPS);\r
40 GetGuidProc getGuid;\r
41 GetAttrProc getAttr;\r
42 GetPreparsedProc getPreparsed;\r
43 GetCapsProc getCaps;\r
44\r
45 HMODULE h = LoadLibrary("hid.dll");\r
46 getGuid = (GetGuidProc)GetProcAddress(h, "HidD_GetHidGuid");\r
47 getAttr = (GetAttrProc)GetProcAddress(h, "HidD_GetAttributes");\r
48 getPreparsed = (GetPreparsedProc)GetProcAddress(h, "HidD_GetPreparsedData");\r
49 getCaps = (GetCapsProc)GetProcAddress(h, "HidP_GetCaps");\r
50\r
51 GUID hidGuid;\r
52 getGuid(&hidGuid);\r
53\r
54 HDEVINFO devInfo;\r
55 devInfo = SetupDiGetClassDevs(&hidGuid, NULL, NULL,\r
56 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);\r
57\r
58 SP_DEVICE_INTERFACE_DATA devInfoData;\r
59 devInfoData.cbSize = sizeof(devInfoData);\r
60\r
61 int i;\r
62 for(i = 0;; i++) {\r
63 if(!SetupDiEnumDeviceInterfaces(devInfo, 0, &hidGuid, i, &devInfoData))\r
64 {\r
65 if(GetLastError() != ERROR_NO_MORE_ITEMS) {\r
66// printf("SetupDiEnumDeviceInterfaces failed\n");\r
67 }\r
68// printf("done list\n");\r
69 SetupDiDestroyDeviceInfoList(devInfo);\r
70 return FALSE;\r
71 }\r
72\r
73// printf("item %d:\n", i);\r
74\r
75 DWORD sizeReqd = 0;\r
76 if(!SetupDiGetDeviceInterfaceDetail(devInfo, &devInfoData,\r
77 NULL, 0, &sizeReqd, NULL))\r
78 {\r
79 if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) {\r
80// printf("SetupDiGetDeviceInterfaceDetail (0) failed\n");\r
81 continue;\r
82 }\r
83 }\r
84\r
85 SP_DEVICE_INTERFACE_DETAIL_DATA *devInfoDetailData =\r
86 (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(sizeReqd);\r
87 devInfoDetailData->cbSize = sizeof(*devInfoDetailData);\r
88\r
89 if(!SetupDiGetDeviceInterfaceDetail(devInfo, &devInfoData,\r
90 devInfoDetailData, 87, NULL, NULL))\r
91 {\r
92// printf("SetupDiGetDeviceInterfaceDetail (1) failed\n");\r
93 continue;\r
94 }\r
95\r
96 char *path = devInfoDetailData->DevicePath;\r
97\r
98 UsbHandle = CreateFile(path, /*GENERIC_READ |*/ GENERIC_WRITE,\r
99 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,\r
100 FILE_FLAG_OVERLAPPED, NULL);\r
101\r
102 if(UsbHandle == INVALID_HANDLE_VALUE) {\r
103 ShowError();\r
104// printf("CreateFile failed: for '%s'\n", path);\r
105 continue;\r
106 }\r
107\r
108 HIDD_ATTRIBUTES attr;\r
109 attr.Size = sizeof(attr);\r
110 if(!getAttr(UsbHandle, &attr)) {\r
111 ShowError();\r
112// printf("HidD_GetAttributes failed\n");\r
113 continue;\r
114 }\r
115\r
116// printf("VID: %04x PID %04x\n", attr.VendorID, attr.ProductID);\r
117\r
118 if(attr.VendorID != OUR_VID || attr.ProductID != OUR_PID) {\r
119 CloseHandle(UsbHandle);\r
120// printf(" nope, not us\n");\r
121 continue;\r
122 }\r
123\r
124// printf ("got it!\n");\r
125 CloseHandle(UsbHandle);\r
126\r
127 UsbHandle = CreateFile(path, GENERIC_READ | GENERIC_WRITE,\r
128 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,\r
129 FILE_FLAG_OVERLAPPED, NULL);\r
130\r
131 if(UsbHandle == INVALID_HANDLE_VALUE) {\r
132 ShowError();\r
133// printf("Error, couldn't open our own handle as desired.\n");\r
134 return FALSE;\r
135 }\r
136\r
137 PHIDP_PREPARSED_DATA pp;\r
138 getPreparsed(UsbHandle, &pp);\r
139 HIDP_CAPS caps;\r
140\r
141 if(getCaps(pp, &caps) != HIDP_STATUS_SUCCESS) {\r
142// printf("getcaps failed\n");\r
143 return FALSE;\r
144 }\r
145\r
146// printf("input/out report %d/%d\n", caps.InputReportByteLength,\r
147// caps.OutputReportByteLength);\r
148\r
149\r
150 return TRUE;\r
151 }\r
152 return FALSE;\r
153}\r
154\r
155bool ReceiveCommandPoll(UsbCommand *c)\r
156{\r
157 static BOOL ReadInProgress = FALSE;\r
158 static OVERLAPPED Ov;\r
159 static BYTE Buf[65];\r
160 static DWORD HaveRead;\r
161\r
162 if(!ReadInProgress) {\r
163 memset(&Ov, 0, sizeof(Ov));\r
164 ReadFile(UsbHandle, Buf, 65, &HaveRead, &Ov);\r
165 if(GetLastError() != ERROR_IO_PENDING) {\r
166 ShowError();\r
167 exit(-1);\r
168 }\r
169 ReadInProgress = TRUE;\r
170 }\r
171\r
172 if(HasOverlappedIoCompleted(&Ov)) {\r
173 ReadInProgress = FALSE;\r
174\r
175 if(!GetOverlappedResult(UsbHandle, &Ov, &HaveRead, FALSE)) {\r
176 ShowError();\r
177 exit(-1);\r
178 }\r
179\r
180 memcpy(c, Buf+1, 64);\r
181\r
182 return TRUE;\r
183 } else {\r
184 return FALSE;\r
185 }\r
186}\r
187\r
188void ReceiveCommand(UsbCommand *c)\r
189{\r
190 while(!ReceiveCommandPoll(c)) {\r
191 Sleep(0);\r
192 }\r
193}\r
194\r
195void SendCommand(UsbCommand *c)\r
196{\r
197 BYTE buf[65];\r
198 buf[0] = 0;\r
199 memcpy(buf+1, c, 64);\r
200\r
201 DWORD written;\r
202 OVERLAPPED ov;\r
203\r
204 memset(&ov, 0, sizeof(ov));\r
205 WriteFile(UsbHandle, buf, 65, &written, &ov);\r
206 if(GetLastError() != ERROR_IO_PENDING) {\r
207 ShowError();\r
208 exit(-1);\r
209 }\r
210\r
211 while(!HasOverlappedIoCompleted(&ov)) {\r
212 Sleep(0);\r
213 }\r
214\r
215 if(!GetOverlappedResult(UsbHandle, &ov, &written, FALSE)) {\r
216 ShowError();\r
217 exit(-1);\r
218 }\r
219 current_command = c->cmd;\r
220}\r
221\r
222static void usage(char **argv)\r
223{\r
224 int i;\r
225 printf("Usage: %s gui\n", argv[0]);\r
226 printf(" %s offline\n", argv[0]);\r
227 printf(" %s areas file.elf\n", argv[0]);\r
228 printf(" Known areas are:");\r
229 for(i=0; partitions[i].name != NULL; i++) {\r
230 fprintf(stderr, " %s", partitions[i].name);\r
231 }\r
232\r
233 printf("\n");\r
234}\r
235\r
236int main(int argc, char **argv)\r
237{\r
238 int i = 0;\r
239\r
240 if(argc < 2) {\r
241 usage(argv);\r
242 exit(-1);\r
243 }\r
244\r
245 // Only do this if NOT in offline mode\r
246 if (strcmp(argv[1], "offline"))\r
247 {\r
248 for(;;) {\r
249 if(UsbConnect()) {\r
250 break;\r
251 }\r
252 if(i == 0) {\r
253 printf("...no device connected, polling for it now\n");\r
254 }\r
255 if(i > 50000) {\r
256 printf("Could not connect to USB device; exiting.\n");\r
257 return -1;\r
258 }\r
259 i++;\r
260 Sleep(5);\r
261 }\r
262 }\r
263\r
264 if(strcmp(argv[1], "gui")==0) {\r
265 ShowGui();\r
266 } else if(strcmp(argv[1], "offline")==0) {\r
267 offline = 1;\r
268 ShowGui();\r
269 }\r
270\r
271 /* Count area arguments */\r
272 int areas = 0, offset=-1, length=0;\r
273 while(find_next_area(argv[1], &offset, &length)) areas++;\r
274\r
275 if(areas != argc - 2) {\r
276 usage(argv);\r
277 exit(-1);\r
278 }\r
279\r
280 do_flash(argv);\r
281 return 0;\r
282}\r
Impressum, Datenschutz