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