7 #include "include/hidusage.h"
8 #include "include/hidpi.h"
9 #include "include/hidsdi.h"
16 #define OUR_VID 0x9ac4
17 #define OUR_PID 0x4b8f
18 #define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
22 extern unsigned int current_command
;
23 extern struct partition partitions
[];
25 static void ShowError(void)
28 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, GetLastError(), 0,
29 buf
, sizeof(buf
), NULL
);
30 printf("ERROR: %s", buf
);
35 typedef void (__stdcall
*GetGuidProc
)(GUID
*);
36 typedef BOOLEAN (__stdcall
*GetAttrProc
)(HANDLE
, HIDD_ATTRIBUTES
*);
37 typedef BOOLEAN (__stdcall
*GetPreparsedProc
)(HANDLE
,
38 PHIDP_PREPARSED_DATA
*);
39 typedef NTSTATUS (__stdcall
*GetCapsProc
)(PHIDP_PREPARSED_DATA
, PHIDP_CAPS
);
42 GetPreparsedProc getPreparsed
;
45 HMODULE h
= LoadLibrary("hid.dll");
46 getGuid
= (GetGuidProc
)GetProcAddress(h
, "HidD_GetHidGuid");
47 getAttr
= (GetAttrProc
)GetProcAddress(h
, "HidD_GetAttributes");
48 getPreparsed
= (GetPreparsedProc
)GetProcAddress(h
, "HidD_GetPreparsedData");
49 getCaps
= (GetCapsProc
)GetProcAddress(h
, "HidP_GetCaps");
55 devInfo
= SetupDiGetClassDevs(&hidGuid
, NULL
, NULL
,
56 DIGCF_PRESENT
| DIGCF_INTERFACEDEVICE
);
58 SP_DEVICE_INTERFACE_DATA devInfoData
;
59 devInfoData
.cbSize
= sizeof(devInfoData
);
63 if(!SetupDiEnumDeviceInterfaces(devInfo
, 0, &hidGuid
, i
, &devInfoData
))
65 if(GetLastError() != ERROR_NO_MORE_ITEMS
) {
66 // printf("SetupDiEnumDeviceInterfaces failed\n");
68 // printf("done list\n");
69 SetupDiDestroyDeviceInfoList(devInfo
);
73 // printf("item %d:\n", i);
76 if(!SetupDiGetDeviceInterfaceDetail(devInfo
, &devInfoData
,
77 NULL
, 0, &sizeReqd
, NULL
))
79 if(GetLastError() != ERROR_INSUFFICIENT_BUFFER
) {
80 // printf("SetupDiGetDeviceInterfaceDetail (0) failed\n");
85 SP_DEVICE_INTERFACE_DETAIL_DATA
*devInfoDetailData
=
86 (SP_DEVICE_INTERFACE_DETAIL_DATA
*)malloc(sizeReqd
);
87 devInfoDetailData
->cbSize
= sizeof(*devInfoDetailData
);
89 if(!SetupDiGetDeviceInterfaceDetail(devInfo
, &devInfoData
,
90 devInfoDetailData
, 87, NULL
, NULL
))
92 // printf("SetupDiGetDeviceInterfaceDetail (1) failed\n");
96 char *path
= devInfoDetailData
->DevicePath
;
98 UsbHandle
= CreateFile(path
, /*GENERIC_READ |*/ GENERIC_WRITE
,
99 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
100 FILE_FLAG_OVERLAPPED
, NULL
);
102 if(UsbHandle
== INVALID_HANDLE_VALUE
) {
104 // printf("CreateFile failed: for '%s'\n", path);
108 HIDD_ATTRIBUTES attr
;
109 attr
.Size
= sizeof(attr
);
110 if(!getAttr(UsbHandle
, &attr
)) {
112 // printf("HidD_GetAttributes failed\n");
116 // printf("VID: %04x PID %04x\n", attr.VendorID, attr.ProductID);
118 if(attr
.VendorID
!= OUR_VID
|| attr
.ProductID
!= OUR_PID
) {
119 CloseHandle(UsbHandle
);
120 // printf(" nope, not us\n");
124 // printf ("got it!\n");
125 CloseHandle(UsbHandle
);
127 UsbHandle
= CreateFile(path
, GENERIC_READ
| GENERIC_WRITE
,
128 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
129 FILE_FLAG_OVERLAPPED
, NULL
);
131 if(UsbHandle
== INVALID_HANDLE_VALUE
) {
133 // printf("Error, couldn't open our own handle as desired.\n");
137 PHIDP_PREPARSED_DATA pp
;
138 getPreparsed(UsbHandle
, &pp
);
141 if(getCaps(pp
, &caps
) != HIDP_STATUS_SUCCESS
) {
142 // printf("getcaps failed\n");
146 // printf("input/out report %d/%d\n", caps.InputReportByteLength,
147 // caps.OutputReportByteLength);
155 bool ReceiveCommandPoll(UsbCommand
*c
)
157 static BOOL ReadInProgress
= FALSE
;
158 static OVERLAPPED Ov
;
160 static DWORD HaveRead
;
162 if(!ReadInProgress
) {
163 memset(&Ov
, 0, sizeof(Ov
));
164 ReadFile(UsbHandle
, Buf
, 65, &HaveRead
, &Ov
);
165 if(GetLastError() != ERROR_IO_PENDING
) {
169 ReadInProgress
= TRUE
;
172 if(HasOverlappedIoCompleted(&Ov
)) {
173 ReadInProgress
= FALSE
;
175 if(!GetOverlappedResult(UsbHandle
, &Ov
, &HaveRead
, FALSE
)) {
180 memcpy(c
, Buf
+1, 64);
188 void ReceiveCommand(UsbCommand
*c
)
190 while(!ReceiveCommandPoll(c
)) {
195 void SendCommand(UsbCommand
*c
)
199 memcpy(buf
+1, c
, 64);
204 memset(&ov
, 0, sizeof(ov
));
205 WriteFile(UsbHandle
, buf
, 65, &written
, &ov
);
206 if(GetLastError() != ERROR_IO_PENDING
) {
211 while(!HasOverlappedIoCompleted(&ov
)) {
215 if(!GetOverlappedResult(UsbHandle
, &ov
, &written
, FALSE
)) {
219 current_command
= c
->cmd
;
222 static void usage(char **argv
)
225 printf("Usage: %s gui\n", argv
[0]);
226 printf(" %s offline\n", argv
[0]);
227 printf(" %s areas file.elf\n", argv
[0]);
228 printf(" Known areas are:");
229 for(i
=0; partitions
[i
].name
!= NULL
; i
++) {
230 fprintf(stderr
, " %s", partitions
[i
].name
);
236 int main(int argc
, char **argv
)
245 // Only do this if NOT in offline mode
246 if (strcmp(argv
[1], "offline"))
253 printf("...no device connected, polling for it now\n");
256 printf("Could not connect to USB device; exiting.\n");
264 if(strcmp(argv
[1], "gui")==0) {
266 } else if(strcmp(argv
[1], "offline")==0) {
271 /* Count area arguments */
272 int areas
= 0, offset
=-1, length
=0;
273 while(find_next_area(argv
[1], &offset
, &length
)) areas
++;
275 if(areas
!= argc
- 2) {