8 #include "include/hidusage.h"
9 #include "include/hidpi.h"
10 #include "include/hidsdi.h"
17 #define OUR_VID 0x9ac4
18 #define OUR_PID 0x4b8f
19 #define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
23 extern unsigned int current_command
;
24 extern struct partition partitions
[];
26 static void ShowError(void)
29 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, GetLastError(), 0,
30 buf
, sizeof(buf
), NULL
);
31 printf("ERROR: %s", buf
);
36 typedef void (__stdcall
*GetGuidProc
)(GUID
*);
37 typedef BOOLEAN (__stdcall
*GetAttrProc
)(HANDLE
, HIDD_ATTRIBUTES
*);
38 typedef BOOLEAN (__stdcall
*GetPreparsedProc
)(HANDLE
,
39 PHIDP_PREPARSED_DATA
*);
40 typedef NTSTATUS (__stdcall
*GetCapsProc
)(PHIDP_PREPARSED_DATA
, PHIDP_CAPS
);
43 GetPreparsedProc getPreparsed
;
46 HMODULE h
= LoadLibrary("hid.dll");
47 getGuid
= (GetGuidProc
)GetProcAddress(h
, "HidD_GetHidGuid");
48 getAttr
= (GetAttrProc
)GetProcAddress(h
, "HidD_GetAttributes");
49 getPreparsed
= (GetPreparsedProc
)GetProcAddress(h
, "HidD_GetPreparsedData");
50 getCaps
= (GetCapsProc
)GetProcAddress(h
, "HidP_GetCaps");
56 devInfo
= SetupDiGetClassDevs(&hidGuid
, NULL
, NULL
,
57 DIGCF_PRESENT
| DIGCF_INTERFACEDEVICE
);
59 SP_DEVICE_INTERFACE_DATA devInfoData
;
60 devInfoData
.cbSize
= sizeof(devInfoData
);
64 if(!SetupDiEnumDeviceInterfaces(devInfo
, 0, &hidGuid
, i
, &devInfoData
))
66 if(GetLastError() != ERROR_NO_MORE_ITEMS
) {
67 // printf("SetupDiEnumDeviceInterfaces failed\n");
69 // printf("done list\n");
70 SetupDiDestroyDeviceInfoList(devInfo
);
74 // printf("item %d:\n", i);
77 if(!SetupDiGetDeviceInterfaceDetail(devInfo
, &devInfoData
,
78 NULL
, 0, &sizeReqd
, NULL
))
80 if(GetLastError() != ERROR_INSUFFICIENT_BUFFER
) {
81 // printf("SetupDiGetDeviceInterfaceDetail (0) failed\n");
86 SP_DEVICE_INTERFACE_DETAIL_DATA
*devInfoDetailData
=
87 (SP_DEVICE_INTERFACE_DETAIL_DATA
*)malloc(sizeReqd
);
88 devInfoDetailData
->cbSize
= sizeof(*devInfoDetailData
);
90 if(!SetupDiGetDeviceInterfaceDetail(devInfo
, &devInfoData
,
91 devInfoDetailData
, 87, NULL
, NULL
))
93 // printf("SetupDiGetDeviceInterfaceDetail (1) failed\n");
97 char *path
= devInfoDetailData
->DevicePath
;
99 UsbHandle
= CreateFile(path
, /*GENERIC_READ |*/ GENERIC_WRITE
,
100 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
101 FILE_FLAG_OVERLAPPED
, NULL
);
103 if(UsbHandle
== INVALID_HANDLE_VALUE
) {
105 // printf("CreateFile failed: for '%s'\n", path);
109 HIDD_ATTRIBUTES attr
;
110 attr
.Size
= sizeof(attr
);
111 if(!getAttr(UsbHandle
, &attr
)) {
113 // printf("HidD_GetAttributes failed\n");
117 // printf("VID: %04x PID %04x\n", attr.VendorID, attr.ProductID);
119 if(attr
.VendorID
!= OUR_VID
|| attr
.ProductID
!= OUR_PID
) {
120 CloseHandle(UsbHandle
);
121 // printf(" nope, not us\n");
125 // printf ("got it!\n");
126 CloseHandle(UsbHandle
);
128 UsbHandle
= CreateFile(path
, GENERIC_READ
| GENERIC_WRITE
,
129 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
130 FILE_FLAG_OVERLAPPED
, NULL
);
132 if(UsbHandle
== INVALID_HANDLE_VALUE
) {
134 // printf("Error, couldn't open our own handle as desired.\n");
138 PHIDP_PREPARSED_DATA pp
;
139 getPreparsed(UsbHandle
, &pp
);
142 if(getCaps(pp
, &caps
) != HIDP_STATUS_SUCCESS
) {
143 // printf("getcaps failed\n");
147 // printf("input/out report %d/%d\n", caps.InputReportByteLength,
148 // caps.OutputReportByteLength);
156 bool ReceiveCommandPoll(UsbCommand
*c
)
158 static BOOL ReadInProgress
= FALSE
;
159 static OVERLAPPED Ov
;
161 static DWORD HaveRead
;
163 if(!ReadInProgress
) {
164 memset(&Ov
, 0, sizeof(Ov
));
165 ReadFile(UsbHandle
, Buf
, 65, &HaveRead
, &Ov
);
166 if(GetLastError() != ERROR_IO_PENDING
) {
170 ReadInProgress
= TRUE
;
173 if(HasOverlappedIoCompleted(&Ov
)) {
174 ReadInProgress
= FALSE
;
176 if(!GetOverlappedResult(UsbHandle
, &Ov
, &HaveRead
, FALSE
)) {
181 memcpy(c
, Buf
+1, 64);
189 void ReceiveCommand(UsbCommand
*c
)
191 while(!ReceiveCommandPoll(c
)) {
196 void SendCommand(UsbCommand
*c
)
200 memcpy(buf
+1, c
, 64);
205 memset(&ov
, 0, sizeof(ov
));
206 WriteFile(UsbHandle
, buf
, 65, &written
, &ov
);
207 if(GetLastError() != ERROR_IO_PENDING
) {
212 while(!HasOverlappedIoCompleted(&ov
)) {
216 if(!GetOverlappedResult(UsbHandle
, &ov
, &written
, FALSE
)) {
220 current_command
= c
->cmd
;
223 static void usage(char **argv
)
226 printf("Usage: %s gui\n", argv
[0]);
227 printf(" %s offline\n", argv
[0]);
228 printf(" %s areas file.elf\n", argv
[0]);
229 printf(" Known areas are:");
230 for(i
=0; partitions
[i
].name
!= NULL
; i
++) {
231 fprintf(stderr
, " %s", partitions
[i
].name
);
237 int main(int argc
, char **argv
)
246 // Only do this if NOT in offline mode
247 if (strcmp(argv
[1], "offline"))
254 printf("...no device connected, polling for it now\n");
257 printf("Could not connect to USB device; exiting.\n");
265 if(strcmp(argv
[1], "gui")==0) {
267 } else if(strcmp(argv
[1], "offline")==0) {
272 /* Count area arguments */
273 int areas
= 0, offset
=-1, length
=0;
274 while(find_next_area(argv
[1], &offset
, &length
)) areas
++;
276 if(areas
!= argc
- 2) {