7 #include "include/hidusage.h"
8 #include "include/hidpi.h"
9 #include "include/hidsdi.h"
15 #define OUR_VID 0x9ac4
16 #define OUR_PID 0x4b8f
17 #define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
21 extern unsigned int current_command
;
22 extern struct partition partitions
[];
24 static void ShowError(void)
27 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, GetLastError(), 0,
28 buf
, sizeof(buf
), NULL
);
29 printf("ERROR: %s", buf
);
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
);
41 GetPreparsedProc getPreparsed
;
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");
54 devInfo
= SetupDiGetClassDevs(&hidGuid
, NULL
, NULL
,
55 DIGCF_PRESENT
| DIGCF_INTERFACEDEVICE
);
57 SP_DEVICE_INTERFACE_DATA devInfoData
;
58 devInfoData
.cbSize
= sizeof(devInfoData
);
62 if(!SetupDiEnumDeviceInterfaces(devInfo
, 0, &hidGuid
, i
, &devInfoData
))
64 if(GetLastError() != ERROR_NO_MORE_ITEMS
) {
65 // printf("SetupDiEnumDeviceInterfaces failed\n");
67 // printf("done list\n");
68 SetupDiDestroyDeviceInfoList(devInfo
);
72 // printf("item %d:\n", i);
75 if(!SetupDiGetDeviceInterfaceDetail(devInfo
, &devInfoData
,
76 NULL
, 0, &sizeReqd
, NULL
))
78 if(GetLastError() != ERROR_INSUFFICIENT_BUFFER
) {
79 // printf("SetupDiGetDeviceInterfaceDetail (0) failed\n");
84 SP_DEVICE_INTERFACE_DETAIL_DATA
*devInfoDetailData
=
85 (SP_DEVICE_INTERFACE_DETAIL_DATA
*)malloc(sizeReqd
);
86 devInfoDetailData
->cbSize
= sizeof(*devInfoDetailData
);
88 if(!SetupDiGetDeviceInterfaceDetail(devInfo
, &devInfoData
,
89 devInfoDetailData
, 87, NULL
, NULL
))
91 // printf("SetupDiGetDeviceInterfaceDetail (1) failed\n");
95 char *path
= devInfoDetailData
->DevicePath
;
97 UsbHandle
= CreateFile(path
, /*GENERIC_READ |*/ GENERIC_WRITE
,
98 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
99 FILE_FLAG_OVERLAPPED
, NULL
);
101 if(UsbHandle
== INVALID_HANDLE_VALUE
) {
103 // printf("CreateFile failed: for '%s'\n", path);
107 HIDD_ATTRIBUTES attr
;
108 attr
.Size
= sizeof(attr
);
109 if(!getAttr(UsbHandle
, &attr
)) {
111 // printf("HidD_GetAttributes failed\n");
115 // printf("VID: %04x PID %04x\n", attr.VendorID, attr.ProductID);
117 if(attr
.VendorID
!= OUR_VID
|| attr
.ProductID
!= OUR_PID
) {
118 CloseHandle(UsbHandle
);
119 // printf(" nope, not us\n");
123 // printf ("got it!\n");
124 CloseHandle(UsbHandle
);
126 UsbHandle
= CreateFile(path
, GENERIC_READ
| GENERIC_WRITE
,
127 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
128 FILE_FLAG_OVERLAPPED
, NULL
);
130 if(UsbHandle
== INVALID_HANDLE_VALUE
) {
132 // printf("Error, couldn't open our own handle as desired.\n");
136 PHIDP_PREPARSED_DATA pp
;
137 getPreparsed(UsbHandle
, &pp
);
140 if(getCaps(pp
, &caps
) != HIDP_STATUS_SUCCESS
) {
141 // printf("getcaps failed\n");
145 // printf("input/out report %d/%d\n", caps.InputReportByteLength,
146 // caps.OutputReportByteLength);
154 bool ReceiveCommandPoll(UsbCommand
*c
)
156 static BOOL ReadInProgress
= FALSE
;
157 static OVERLAPPED Ov
;
159 static DWORD HaveRead
;
161 if(!ReadInProgress
) {
162 memset(&Ov
, 0, sizeof(Ov
));
163 ReadFile(UsbHandle
, Buf
, 65, &HaveRead
, &Ov
);
164 if(GetLastError() != ERROR_IO_PENDING
) {
168 ReadInProgress
= TRUE
;
171 if(HasOverlappedIoCompleted(&Ov
)) {
172 ReadInProgress
= FALSE
;
174 if(!GetOverlappedResult(UsbHandle
, &Ov
, &HaveRead
, FALSE
)) {
179 memcpy(c
, Buf
+1, 64);
187 void ReceiveCommand(UsbCommand
*c
)
189 while(!ReceiveCommandPoll(c
)) {
194 void SendCommand(UsbCommand
*c
)
198 memcpy(buf
+1, c
, 64);
203 memset(&ov
, 0, sizeof(ov
));
204 WriteFile(UsbHandle
, buf
, 65, &written
, &ov
);
205 if(GetLastError() != ERROR_IO_PENDING
) {
210 while(!HasOverlappedIoCompleted(&ov
)) {
214 if(!GetOverlappedResult(UsbHandle
, &ov
, &written
, FALSE
)) {
218 current_command
= c
->cmd
;
221 static void usage(char **argv
)
224 printf("Usage: %s gui\n", argv
[0]);
225 printf(" %s offline\n", argv
[0]);
226 printf(" %s areas file.s19\n", argv
[0]);
227 printf(" Known areas are:");
228 for(i
=0; partitions
[i
].name
!= NULL
; i
++) {
229 fprintf(stderr
, " %s", partitions
[i
].name
);
235 int main(int argc
, char **argv
)
244 // Only do this if NOT in offline mode
245 if (strcmp(argv
[1], "offline"))
252 printf("...no device connected, polling for it now\n");
255 printf("Could not connect to USB device; exiting.\n");
263 if(strcmp(argv
[1], "gui")==0) {
265 } else if(strcmp(argv
[1], "offline")==0) {
270 /* Count area arguments */
271 int areas
= 0, offset
=-1, length
=0;
272 while(find_next_area(argv
[1], &offset
, &length
)) areas
++;
274 if(areas
!= argc
- 2) {