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