1 | #define INCL_DOSERRORS
|
---|
2 | #define INCL_DOSMEMMGR
|
---|
3 | #define INCL_DOSSEMAPHORES
|
---|
4 | #define INCL_DOSDEVICES
|
---|
5 | #define INCL_DOSDEVIOCTL
|
---|
6 | #define INCL_DOSMODULEMGR
|
---|
7 | #include <os2.h>
|
---|
8 |
|
---|
9 | #if !defined(__GNUC__) || defined(STATIC_USBCALLS)
|
---|
10 | #include <string.h>
|
---|
11 | #else
|
---|
12 | #define memcpy __builtin_memcpy
|
---|
13 | #endif
|
---|
14 | #include <stdlib.h>
|
---|
15 | #include <stdio.h>
|
---|
16 |
|
---|
17 | #define LOG_GROUP LOG_GROUP_DRV_USBPROXY
|
---|
18 | #include <VBox/log.h>
|
---|
19 |
|
---|
20 | #ifdef __GNUC__
|
---|
21 | # define APIEXPORT __declspec(dllexport)
|
---|
22 | #else
|
---|
23 | # define APIEXPORT
|
---|
24 | #endif
|
---|
25 |
|
---|
26 | #ifndef ERROR_USER_DEFINED_BASE
|
---|
27 | /*#define ERROR_USER_DEFINED_BASE 0xFF00 */
|
---|
28 |
|
---|
29 | #define ERROR_I24_WRITE_PROTECT 0
|
---|
30 | #define ERROR_I24_BAD_UNIT 1
|
---|
31 | #define ERROR_I24_NOT_READY 2
|
---|
32 | #define ERROR_I24_BAD_COMMAND 3
|
---|
33 | #define ERROR_I24_CRC 4
|
---|
34 | #define ERROR_I24_BAD_LENGTH 5
|
---|
35 | #define ERROR_I24_SEEK 6
|
---|
36 | #define ERROR_I24_NOT_DOS_DISK 7
|
---|
37 | #define ERROR_I24_SECTOR_NOT_FOUND 8
|
---|
38 | #define ERROR_I24_OUT_OF_PAPER 9
|
---|
39 | #define ERROR_I24_WRITE_FAULT 10
|
---|
40 | #define ERROR_I24_READ_FAULT 11
|
---|
41 | #define ERROR_I24_GEN_FAILURE 12
|
---|
42 | #define ERROR_I24_DISK_CHANGE 13
|
---|
43 | #define ERROR_I24_WRONG_DISK 15
|
---|
44 | #define ERROR_I24_UNCERTAIN_MEDIA 16
|
---|
45 | #define ERROR_I24_CHAR_CALL_INTERRUPTED 17
|
---|
46 | #define ERROR_I24_NO_MONITOR_SUPPORT 18
|
---|
47 | #define ERROR_I24_INVALID_PARAMETER 19
|
---|
48 | #define ERROR_I24_DEVICE_IN_USE 20
|
---|
49 | #define ERROR_I24_QUIET_INIT_FAIL 21
|
---|
50 | #endif
|
---|
51 |
|
---|
52 | #include "usbcalls.h"
|
---|
53 |
|
---|
54 | #define IOCAT_USBRES 0x000000A0 /* USB Resource device control */
|
---|
55 | #define IOCTLF_NUMDEVICE 0x00000031 /* Get Number of plugged in Devices */
|
---|
56 | #define IOCTLF_GETINFO 0x00000032 /* Get Info About a device */
|
---|
57 | #define IOCTLF_AQUIREDEVICE 0x00000033
|
---|
58 | #define IOCTLF_RELEASEDEVICE 0x00000034
|
---|
59 | #define IOCTLF_GETSTRING 0x00000035
|
---|
60 | #define IOCTLF_SENDCONTROLURB 0x00000036
|
---|
61 | #define IOCTLF_SENDBULKURB 0x00000037 /* Send */
|
---|
62 | #define IOCTLF_START_IRQ_PROC 0x00000038 /* Start IRQ polling in a buffer */
|
---|
63 | #define IOCTLF_GETDEVINFO 0x00000039 /* Get information about device */
|
---|
64 | #define IOCTLF_STOP_IRQ_PROC 0x0000003A /* Stop IRQ Polling */
|
---|
65 | #define IOCTLF_START_ISO_PROC 0x0000003B /* Start ISO buffering in a Ringbuffer */
|
---|
66 | #define IOCTLF_STOP_ISO_PROC 0x0000003C /* Stop ISO buffering */
|
---|
67 | #define IOCTLF_CANCEL_IORB 0x0000003D /* Abort an IORB; */
|
---|
68 | #define IOCTLF_SELECT_BULKPIPE 0x0000003E /* Select which Bulk endpoints can be used via Read/Write */
|
---|
69 | #define IOCTLF_SENDIRQURB 0x0000003F /* Start IRQ polling in a buffer */
|
---|
70 | #define IOCTLF_FIXUPDEVUCE 0x00000040 /* Fixup USB device configuration data */
|
---|
71 | #define IOCTLF_REG_STATUSSEM 0x00000041 /* Register Semaphore for general Statuschange */
|
---|
72 | #define IOCTLF_DEREG_STATUSSEM 0x00000042 /* Deregister Semaphore */
|
---|
73 | #define IOCTLF_REG_DEVICESEM 0x00000043 /* Register Semaphore for a vendor&deviceID */
|
---|
74 | #define IOCTLF_DEREG_DEVICESEM 0x00000044 /* Deregister Semaphore */
|
---|
75 |
|
---|
76 |
|
---|
77 | #define NOTIFY_FREE 0
|
---|
78 | #define NOTIFY_CHANGE 1
|
---|
79 | #define NOTIFY_DEVICE 2
|
---|
80 | #define MAX_NOTIFICATIONS 256
|
---|
81 |
|
---|
82 | #pragma pack(1)
|
---|
83 |
|
---|
84 | typedef struct
|
---|
85 | {
|
---|
86 | HEV hDeviceAdded;
|
---|
87 | HEV hDeviceRemoved;
|
---|
88 | USHORT usFlags;
|
---|
89 | USHORT usVendor;
|
---|
90 | USHORT usProduct;
|
---|
91 | USHORT usBCDDevice;
|
---|
92 | } NOTIFYENTRY, *PNOTIFYENTRY;
|
---|
93 |
|
---|
94 | #define DEV_SEM_ADD 0x00000001
|
---|
95 | #define DEV_SEM_REMOVE 0x00000002
|
---|
96 | #define DEV_SEM_MASK 0x00000003
|
---|
97 | #define DEV_SEM_VENDORID 0x00000004
|
---|
98 | #define DEV_SEM_PRODUCTID 0x00000008
|
---|
99 | #define DEV_SEM_BCDDEVICE 0x00000010
|
---|
100 |
|
---|
101 | typedef struct{
|
---|
102 | ULONG ulSize;
|
---|
103 | ULONG ulCaps;
|
---|
104 | ULONG ulSemDeviceAdd;
|
---|
105 | ULONG ulSemDeviceRemove;
|
---|
106 | } STATUSEVENTSET, * PSTATUSEVENTSET;
|
---|
107 |
|
---|
108 |
|
---|
109 | typedef struct{
|
---|
110 | ULONG ulSize;
|
---|
111 | ULONG ulCaps;
|
---|
112 | ULONG ulSemDeviceAdd;
|
---|
113 | ULONG ulSemDeviceRemove;
|
---|
114 | USHORT usVendorID;
|
---|
115 | USHORT usProductID;
|
---|
116 | USHORT usBCDDevice;
|
---|
117 | USHORT usStatus;
|
---|
118 | } DEVEVENTSET, * PDEVEVENTSET;
|
---|
119 |
|
---|
120 | typedef struct
|
---|
121 | {
|
---|
122 | USHORT usVendorID;
|
---|
123 | USHORT usProductID;
|
---|
124 | USHORT usBCDDevice;
|
---|
125 | USHORT usDeviceNumber; /* Get the usDeviceNumber device in the system fi. if 2 acquire the 2nd device
|
---|
126 | 0 means first not acquired device. */
|
---|
127 | } AQUIREDEV, *PAQUIREDEV;
|
---|
128 |
|
---|
129 | typedef struct
|
---|
130 | {
|
---|
131 | UCHAR bRequestType;
|
---|
132 | UCHAR bRequest;
|
---|
133 | USHORT wValue;
|
---|
134 | USHORT wIndex;
|
---|
135 | USHORT wLength;
|
---|
136 | ULONG ulTimeout; /* in milliseconds */
|
---|
137 | } SETUPPACKET, *PSETUPPACKET;
|
---|
138 |
|
---|
139 | typedef struct
|
---|
140 | {
|
---|
141 | ULONG ulHandle;
|
---|
142 | UCHAR bRequestType;
|
---|
143 | UCHAR bRequest;
|
---|
144 | USHORT wValue;
|
---|
145 | USHORT wIndex;
|
---|
146 | USHORT wLength;
|
---|
147 | ULONG ulTimeout; /* in milliseconds */
|
---|
148 | USHORT usStatus;
|
---|
149 | } USBCALLS_CTRL_REQ, *PUSBCALLS_CTRL_REQ;
|
---|
150 |
|
---|
151 | typedef struct
|
---|
152 | {
|
---|
153 | ULONG ulDevHandle;
|
---|
154 | UCHAR ucEndpoint;
|
---|
155 | UCHAR ucAltInterface;
|
---|
156 | USHORT usStatus;
|
---|
157 | ULONG ulEvent;
|
---|
158 | ULONG ulID;
|
---|
159 | } USBCALLS_ISO_START, *NPUSBCALLS_ISO_START, FAR *PUSBCALLS_ISO_START,
|
---|
160 | USBCALLS_IRQ_START, *NPUSBCALLS_IRQ_START, FAR *PUSBCALLS_IRQ_START,
|
---|
161 | USBCALLS_CANCEL_REQ, *NPUSBCALLS_CANCEL_REQ, FAR *PUSBCALLS_CANCEL_REQ;
|
---|
162 |
|
---|
163 | #define ISO_DIRMASK 0x80
|
---|
164 | typedef struct
|
---|
165 | {
|
---|
166 | ULONG hSemAccess; /* Synchronise access to the Pos values */
|
---|
167 | ULONG hDevice;
|
---|
168 | USHORT usPosWrite;
|
---|
169 | USHORT usPosRead;
|
---|
170 | USHORT usBufSize;
|
---|
171 | UCHAR ucEndpoint;
|
---|
172 | UCHAR ucAltInterface;
|
---|
173 | UCHAR ucBuffer[16*1023];
|
---|
174 | } ISORINGBUFFER, *PISORINGBUFFER;
|
---|
175 |
|
---|
176 | typedef USBCALLS_ISO_START USBCALLS_ISO_STOP, * NPUSBCALLS_ISO_STOP, FAR *PUSBCALLS_ISO_STOP;
|
---|
177 | typedef USBCALLS_ISO_START USBCALLS_IRQ_STOP, * NPUSBCALLS_IRQ_STOP, FAR *PUSBCALLS_IRQ_STOP;
|
---|
178 |
|
---|
179 | #define USB_TRANSFER_FULL_SIZE 0x01
|
---|
180 |
|
---|
181 | typedef struct
|
---|
182 | {
|
---|
183 | ULONG ulDevHandle;
|
---|
184 | UCHAR ucEndpoint;
|
---|
185 | UCHAR ucAltInterface;
|
---|
186 | USHORT usStatus;
|
---|
187 | ULONG ulEvent;
|
---|
188 | /* ULONG ulID; - yeah, right */
|
---|
189 | ULONG ulTimeout;
|
---|
190 | USHORT usDataProcessed;
|
---|
191 | USHORT usDataRemain;
|
---|
192 | USHORT usFlags;
|
---|
193 | } USBCALLS_BULK_REQ, *PUSBCALLS_BULK_REQ;
|
---|
194 |
|
---|
195 | typedef struct
|
---|
196 | {
|
---|
197 | ULONG ulDevHandle;
|
---|
198 | UCHAR ucEndpoint;
|
---|
199 | UCHAR ucAltInterface;
|
---|
200 | USHORT usStatus;
|
---|
201 | ULONG ulEvent;
|
---|
202 | ULONG ulID;
|
---|
203 | ULONG ulTimeout;
|
---|
204 | USHORT usDataLen;
|
---|
205 | } LIBUSB_IRQ_REQ, *NPLIBUSB_IRQ_REQ, FAR *PLIBUSB_IRQ_REQ;
|
---|
206 |
|
---|
207 | typedef struct
|
---|
208 | {
|
---|
209 | ULONG ulDevHandle;
|
---|
210 | UCHAR ucConfiguration;
|
---|
211 | UCHAR ucAltInterface;
|
---|
212 | USHORT usStatus;
|
---|
213 | } LIBUSB_FIXUP, *NPLIBUSB_FIXUP, FAR *PLIBUSB_FIXUP;
|
---|
214 |
|
---|
215 | #pragma pack()
|
---|
216 |
|
---|
217 | /******************************************************************************/
|
---|
218 |
|
---|
219 | HFILE g_hUSBDrv;
|
---|
220 | ULONG g_cInit;
|
---|
221 | ULONG g_ulFreeNotifys;
|
---|
222 | HMTX g_hSemNotifytable;
|
---|
223 | NOTIFYENTRY g_Notifications[MAX_NOTIFICATIONS];
|
---|
224 |
|
---|
225 | HMTX g_hSemRingBuffers;
|
---|
226 | PISORINGBUFFER g_pIsoRingBuffers;
|
---|
227 | ULONG g_ulNumIsoRingBuffers;
|
---|
228 |
|
---|
229 | APIEXPORT APIRET APIENTRY
|
---|
230 | InitUsbCalls(void)
|
---|
231 | {
|
---|
232 | int i;
|
---|
233 | ULONG ulAction;
|
---|
234 | APIRET rc;
|
---|
235 |
|
---|
236 | if (++g_cInit > 1)
|
---|
237 | return NO_ERROR;
|
---|
238 |
|
---|
239 | rc = DosOpen( (PCSZ)"USBRESM$",
|
---|
240 | &g_hUSBDrv,
|
---|
241 | &ulAction,
|
---|
242 | 0,
|
---|
243 | FILE_NORMAL,
|
---|
244 | OPEN_ACTION_OPEN_IF_EXISTS,
|
---|
245 | OPEN_ACCESS_READWRITE |
|
---|
246 | OPEN_FLAGS_NOINHERIT |
|
---|
247 | OPEN_SHARE_DENYNONE,
|
---|
248 | 0 );
|
---|
249 | if(rc)
|
---|
250 | {
|
---|
251 | g_hUSBDrv = 0;
|
---|
252 | g_cInit = 0;
|
---|
253 |
|
---|
254 | }
|
---|
255 | else
|
---|
256 | {
|
---|
257 | /* @@ToDO Add EnvVar or INI for dynamically setting the number */
|
---|
258 | g_ulNumIsoRingBuffers = 8;
|
---|
259 | for(i=0;i<MAX_NOTIFICATIONS;i++)
|
---|
260 | {
|
---|
261 | g_Notifications[i].usFlags = NOTIFY_FREE;
|
---|
262 | g_Notifications[i].hDeviceAdded = 0;
|
---|
263 | g_Notifications[i].hDeviceRemoved = 0;
|
---|
264 | g_Notifications[i].usVendor = 0;
|
---|
265 | g_Notifications[i].usProduct = 0;
|
---|
266 | g_Notifications[i].usBCDDevice = 0;
|
---|
267 | }
|
---|
268 | rc = DosAllocMem( (PPVOID)&g_pIsoRingBuffers,
|
---|
269 | g_ulNumIsoRingBuffers * sizeof(ISORINGBUFFER),
|
---|
270 | PAG_WRITE | PAG_COMMIT | OBJ_TILE);
|
---|
271 | if(!rc)
|
---|
272 | {
|
---|
273 | PISORINGBUFFER pIter = g_pIsoRingBuffers;
|
---|
274 | for(i=0;i< g_ulNumIsoRingBuffers;i++,pIter++)
|
---|
275 | {
|
---|
276 | pIter->hDevice = 0;
|
---|
277 | pIter->hSemAccess = 0; /* Synchronise access to the Pos values */
|
---|
278 | pIter->usPosWrite = 0;
|
---|
279 | pIter->usPosRead = 0;
|
---|
280 | pIter->usBufSize = 16*1023;
|
---|
281 | pIter->ucEndpoint = 0;
|
---|
282 | pIter->ucAltInterface = 0;
|
---|
283 | /*pIter->ucBuffer */
|
---|
284 | }
|
---|
285 | rc=DosCreateMutexSem(NULL,&g_hSemRingBuffers,DC_SEM_SHARED,FALSE);
|
---|
286 | if(!rc)
|
---|
287 | {
|
---|
288 | rc=DosCreateMutexSem(NULL,&g_hSemNotifytable,DC_SEM_SHARED,FALSE);
|
---|
289 | if(rc)
|
---|
290 | {
|
---|
291 | DosCloseMutexSem(g_hSemRingBuffers);
|
---|
292 | DosFreeMem(g_pIsoRingBuffers);
|
---|
293 | }
|
---|
294 | }
|
---|
295 | else
|
---|
296 | {
|
---|
297 | DosFreeMem(g_pIsoRingBuffers);
|
---|
298 | }
|
---|
299 | }
|
---|
300 |
|
---|
301 | if(rc)
|
---|
302 | {
|
---|
303 | DosClose(g_hUSBDrv);
|
---|
304 | g_hUSBDrv = 0;
|
---|
305 | g_cInit = 0;
|
---|
306 | }
|
---|
307 | }
|
---|
308 | return g_cInit ? NO_ERROR : rc ? rc : ERROR_GEN_FAILURE;
|
---|
309 | }
|
---|
310 |
|
---|
311 | APIEXPORT APIRET APIENTRY
|
---|
312 | TermUsbCalls(void)
|
---|
313 | {
|
---|
314 | if (!g_cInit)
|
---|
315 | return ERROR_GEN_FAILURE;
|
---|
316 | if(!--g_cInit)
|
---|
317 | {
|
---|
318 | int i;
|
---|
319 | for(i=0;i<MAX_NOTIFICATIONS;i++)
|
---|
320 | if( g_Notifications[i].usFlags != NOTIFY_FREE);
|
---|
321 | UsbDeregisterNotification((USBNOTIFY)(&g_Notifications[i]));
|
---|
322 |
|
---|
323 | DosClose(g_hUSBDrv);
|
---|
324 | g_hUSBDrv = NULLHANDLE;
|
---|
325 |
|
---|
326 | if (g_pIsoRingBuffers)
|
---|
327 | DosFreeMem(g_pIsoRingBuffers);
|
---|
328 |
|
---|
329 | DosCloseMutexSem(g_hSemRingBuffers);
|
---|
330 | g_hSemRingBuffers = NULLHANDLE;
|
---|
331 | DosCloseMutexSem(g_hSemNotifytable);
|
---|
332 | g_hSemNotifytable = NULLHANDLE;
|
---|
333 | }
|
---|
334 | return NO_ERROR;
|
---|
335 | }
|
---|
336 |
|
---|
337 |
|
---|
338 | #ifdef VBOX /* complete wast of time */
|
---|
339 | # define IsBadReadPointer(pBase, ulSize) (FALSE)
|
---|
340 | # define IsBadWritePointer(pBase, ulSize) (FALSE)
|
---|
341 | #else
|
---|
342 | static BOOL IsBadReadPointer(PVOID pBase, ULONG ulSize)
|
---|
343 | {
|
---|
344 | APIRET rc;
|
---|
345 | ULONG ulFlags;
|
---|
346 | rc = DosQueryMem(pBase, &ulSize, &ulFlags);
|
---|
347 |
|
---|
348 | return rc!=0?TRUE:(ulFlags&PAG_READ)&&(ulFlags&PAG_COMMIT)?FALSE:TRUE;
|
---|
349 | }
|
---|
350 |
|
---|
351 | static BOOL IsBadWritePointer(PVOID pBase, ULONG ulSize)
|
---|
352 | {
|
---|
353 | APIRET rc;
|
---|
354 | ULONG ulFlags;
|
---|
355 | rc = DosQueryMem(pBase, &ulSize, &ulFlags);
|
---|
356 |
|
---|
357 | return rc!=0?TRUE:((ulFlags&PAG_WRITE)==PAG_WRITE&&(ulFlags&PAG_COMMIT)==PAG_COMMIT)?FALSE:TRUE;
|
---|
358 | }
|
---|
359 | #endif
|
---|
360 |
|
---|
361 | APIEXPORT APIRET APIENTRY
|
---|
362 | UsbQueryNumberDevices(ULONG *pulNumDev)
|
---|
363 | {
|
---|
364 | APIRET rc;
|
---|
365 | ULONG ulLength;
|
---|
366 | if(!g_cInit)
|
---|
367 | return USB_NOT_INIT;
|
---|
368 |
|
---|
369 | if( IsBadWritePointer(pulNumDev,sizeof(ULONG)) )
|
---|
370 | return ERROR_INVALID_PARAMETER;
|
---|
371 | ulLength=sizeof(ULONG);
|
---|
372 | *pulNumDev = 0;
|
---|
373 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
374 | IOCAT_USBRES, IOCTLF_NUMDEVICE,
|
---|
375 | NULL, 0, NULL,
|
---|
376 | pulNumDev, ulLength, &ulLength);
|
---|
377 | return rc;
|
---|
378 | }
|
---|
379 |
|
---|
380 | APIEXPORT APIRET APIENTRY
|
---|
381 | UsbQueryDeviceReport(ULONG ulDevNumber, ULONG *pulBufLen, PVOID pData)
|
---|
382 | {
|
---|
383 | APIRET rc;
|
---|
384 | ULONG ulParmLen;
|
---|
385 |
|
---|
386 | if(!g_cInit)
|
---|
387 | return USB_NOT_INIT;
|
---|
388 |
|
---|
389 | if( IsBadWritePointer(pulBufLen, sizeof(ULONG)) )
|
---|
390 | return ERROR_INVALID_PARAMETER;
|
---|
391 |
|
---|
392 | if( pData!=NULL && IsBadWritePointer(pData,*pulBufLen) )
|
---|
393 | return ERROR_INVALID_PARAMETER;
|
---|
394 | if(pData==NULL)
|
---|
395 | *pulBufLen = 0;
|
---|
396 | ulParmLen = sizeof(ulDevNumber);
|
---|
397 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
398 | IOCAT_USBRES, IOCTLF_GETINFO,
|
---|
399 | (PVOID)&ulDevNumber, ulParmLen, &ulParmLen,
|
---|
400 | pData, *pulBufLen, pulBufLen);
|
---|
401 | return rc;
|
---|
402 | }
|
---|
403 |
|
---|
404 | APIEXPORT APIRET APIENTRY
|
---|
405 | UsbRegisterChangeNotification( PUSBNOTIFY pNotifyID,
|
---|
406 | HEV hDeviceAdded,
|
---|
407 | HEV hDeviceRemoved)
|
---|
408 | {
|
---|
409 | APIRET rc;
|
---|
410 | int i;
|
---|
411 | STATUSEVENTSET EventSet;
|
---|
412 | ULONG ulSize;
|
---|
413 |
|
---|
414 | if(!g_cInit)
|
---|
415 | return USB_NOT_INIT;
|
---|
416 |
|
---|
417 | if( IsBadWritePointer(pNotifyID, sizeof(ULONG)) ||
|
---|
418 | (hDeviceAdded==0 && hDeviceRemoved==0) )
|
---|
419 | return ERROR_INVALID_PARAMETER;
|
---|
420 |
|
---|
421 | ulSize = sizeof(EventSet);
|
---|
422 | EventSet.ulSize = ulSize;
|
---|
423 |
|
---|
424 | if(hDeviceAdded!=0)
|
---|
425 | {
|
---|
426 | ULONG ulCnt;
|
---|
427 | rc = DosQueryEventSem(hDeviceAdded,&ulCnt);
|
---|
428 | if(rc)
|
---|
429 | return rc;
|
---|
430 | EventSet.ulCaps = DEV_SEM_ADD;
|
---|
431 | EventSet.ulSemDeviceAdd = hDeviceAdded;
|
---|
432 | }
|
---|
433 |
|
---|
434 | if(hDeviceRemoved!=0)
|
---|
435 | {
|
---|
436 | ULONG ulCnt;
|
---|
437 | rc = DosQueryEventSem(hDeviceRemoved,&ulCnt);
|
---|
438 | if(rc)
|
---|
439 | return rc;
|
---|
440 | EventSet.ulCaps |= DEV_SEM_REMOVE;
|
---|
441 | EventSet.ulSemDeviceRemove = hDeviceRemoved;
|
---|
442 | }
|
---|
443 |
|
---|
444 | rc = DosRequestMutexSem(g_hSemNotifytable,SEM_INDEFINITE_WAIT);
|
---|
445 | if(rc)
|
---|
446 | return rc;
|
---|
447 |
|
---|
448 | for(i=0;i<MAX_NOTIFICATIONS;i++)
|
---|
449 | {
|
---|
450 | if( g_Notifications[i].usFlags == NOTIFY_FREE)
|
---|
451 | {
|
---|
452 | g_Notifications[i].usFlags = NOTIFY_CHANGE;
|
---|
453 | g_Notifications[i].hDeviceAdded = hDeviceAdded;
|
---|
454 | g_Notifications[i].hDeviceRemoved = hDeviceRemoved;
|
---|
455 | g_Notifications[i].usVendor = 0;
|
---|
456 | g_Notifications[i].usProduct = 0;
|
---|
457 | g_Notifications[i].usBCDDevice = 0;
|
---|
458 | break;
|
---|
459 | }
|
---|
460 | }
|
---|
461 | DosReleaseMutexSem(g_hSemNotifytable);
|
---|
462 | if(i==MAX_NOTIFICATIONS)
|
---|
463 | return USB_ERROR_NO_MORE_NOTIFICATIONS;
|
---|
464 |
|
---|
465 | /* @@ToDo come up with a better way to generate IDs */
|
---|
466 | *pNotifyID = (USBNOTIFY) (&g_Notifications[i]);
|
---|
467 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
468 | IOCAT_USBRES, IOCTLF_REG_STATUSSEM,
|
---|
469 | NULL, 0, NULL,
|
---|
470 | &EventSet,ulSize, &ulSize);
|
---|
471 | if(rc)
|
---|
472 | {
|
---|
473 | g_Notifications[i].usFlags = NOTIFY_FREE;
|
---|
474 | *pNotifyID = 0;
|
---|
475 | }
|
---|
476 | return rc;
|
---|
477 | }
|
---|
478 |
|
---|
479 | APIEXPORT APIRET APIENTRY
|
---|
480 | UsbRegisterDeviceNotification( PUSBNOTIFY pNotifyID,
|
---|
481 | HEV hDeviceAdded,
|
---|
482 | HEV hDeviceRemoved,
|
---|
483 | USHORT usVendor,
|
---|
484 | USHORT usProduct,
|
---|
485 | USHORT usBCDVersion)
|
---|
486 | {
|
---|
487 | DEVEVENTSET EventSet;
|
---|
488 | ULONG ulCnt,ulSize;
|
---|
489 | int i;
|
---|
490 | APIRET rc;
|
---|
491 |
|
---|
492 | if(!g_cInit)
|
---|
493 | return USB_NOT_INIT;
|
---|
494 |
|
---|
495 | if( IsBadWritePointer(pNotifyID, sizeof(ULONG)) ||
|
---|
496 | hDeviceAdded==0 || hDeviceRemoved==0 ||
|
---|
497 | usVendor == 0 || usVendor == 0xFFFF ||
|
---|
498 | usProduct == 0 || usProduct == 0xFFFF )
|
---|
499 | return ERROR_INVALID_PARAMETER;
|
---|
500 |
|
---|
501 |
|
---|
502 | rc = DosQueryEventSem(hDeviceAdded,&ulCnt);
|
---|
503 | if(rc)
|
---|
504 | return rc;
|
---|
505 | rc = DosQueryEventSem(hDeviceRemoved,&ulCnt);
|
---|
506 | if(rc)
|
---|
507 | return rc;
|
---|
508 |
|
---|
509 | ulSize = sizeof(EventSet);
|
---|
510 | EventSet.ulSize = ulSize;
|
---|
511 | EventSet.ulCaps = DEV_SEM_ADD | DEV_SEM_REMOVE |
|
---|
512 | DEV_SEM_VENDORID | DEV_SEM_PRODUCTID |
|
---|
513 | DEV_SEM_BCDDEVICE ;
|
---|
514 | EventSet.ulSemDeviceAdd = hDeviceAdded;
|
---|
515 | EventSet.ulSemDeviceRemove = hDeviceRemoved;
|
---|
516 | EventSet.usVendorID = usVendor;
|
---|
517 | EventSet.usProductID = usProduct;
|
---|
518 | EventSet.usBCDDevice = usBCDVersion;
|
---|
519 | EventSet.usStatus = 0;
|
---|
520 |
|
---|
521 | rc = DosRequestMutexSem(g_hSemNotifytable,SEM_INDEFINITE_WAIT);
|
---|
522 |
|
---|
523 | if(rc)
|
---|
524 | return rc;
|
---|
525 |
|
---|
526 | for(i=0;i<MAX_NOTIFICATIONS;i++)
|
---|
527 | {
|
---|
528 | if( g_Notifications[i].usFlags == NOTIFY_FREE)
|
---|
529 | {
|
---|
530 | g_Notifications[i].usFlags = NOTIFY_DEVICE;
|
---|
531 | g_Notifications[i].hDeviceAdded = hDeviceAdded;
|
---|
532 | g_Notifications[i].hDeviceRemoved = hDeviceRemoved;
|
---|
533 | g_Notifications[i].usVendor = usVendor;
|
---|
534 | g_Notifications[i].usProduct = usProduct;
|
---|
535 | g_Notifications[i].usBCDDevice = usBCDVersion;
|
---|
536 | break;
|
---|
537 | }
|
---|
538 | }
|
---|
539 | DosReleaseMutexSem(g_hSemNotifytable);
|
---|
540 | if(i==MAX_NOTIFICATIONS)
|
---|
541 | return USB_ERROR_NO_MORE_NOTIFICATIONS;
|
---|
542 |
|
---|
543 | /* @@ToDo come up with a better way to generate IDs */
|
---|
544 | *pNotifyID = (USBNOTIFY) (&g_Notifications[i]);
|
---|
545 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
546 | IOCAT_USBRES, IOCTLF_REG_DEVICESEM,
|
---|
547 | NULL, 0, NULL,
|
---|
548 | &EventSet,ulSize, &ulSize);
|
---|
549 | if(rc)
|
---|
550 | {
|
---|
551 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_INVALID_PARAMETER) )
|
---|
552 | rc= ERROR_INVALID_PARAMETER;
|
---|
553 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_GEN_FAILURE) )
|
---|
554 | rc= EventSet.usStatus;
|
---|
555 |
|
---|
556 | g_Notifications[i].usFlags = NOTIFY_FREE;
|
---|
557 | *pNotifyID = 0;
|
---|
558 | }
|
---|
559 | return rc;
|
---|
560 | }
|
---|
561 |
|
---|
562 | APIEXPORT APIRET APIENTRY
|
---|
563 | UsbDeregisterNotification( USBNOTIFY NotifyID )
|
---|
564 | {
|
---|
565 | DEVEVENTSET EventSet;
|
---|
566 | USBNOTIFY MinID,MaxID;
|
---|
567 | ULONG Index, ulFunction, ulSize;
|
---|
568 | APIRET rc;
|
---|
569 |
|
---|
570 | if(!g_cInit)
|
---|
571 | return USB_NOT_INIT;
|
---|
572 |
|
---|
573 | MinID = (USBNOTIFY) (&g_Notifications[0]);
|
---|
574 | MaxID = (USBNOTIFY) (&g_Notifications[MAX_NOTIFICATIONS-1]);
|
---|
575 |
|
---|
576 | if(NotifyID<MinID || NotifyID>MaxID)
|
---|
577 | return ERROR_INVALID_PARAMETER;
|
---|
578 |
|
---|
579 | Index = NotifyID - MinID;
|
---|
580 |
|
---|
581 | if(Index % sizeof(NOTIFYENTRY))
|
---|
582 | return ERROR_INVALID_PARAMETER;
|
---|
583 |
|
---|
584 | Index /= sizeof(NOTIFYENTRY);
|
---|
585 |
|
---|
586 | rc = DosRequestMutexSem(g_hSemNotifytable,SEM_INDEFINITE_WAIT);
|
---|
587 |
|
---|
588 | switch(g_Notifications[Index].usFlags)
|
---|
589 | {
|
---|
590 | case NOTIFY_FREE:
|
---|
591 | DosReleaseMutexSem(g_hSemNotifytable);
|
---|
592 | return ERROR_INVALID_PARAMETER;
|
---|
593 | case NOTIFY_CHANGE:
|
---|
594 | ulFunction = IOCTLF_DEREG_STATUSSEM;
|
---|
595 | ulSize = sizeof(STATUSEVENTSET);
|
---|
596 | EventSet.ulSize = ulSize;
|
---|
597 | EventSet.ulCaps = DEV_SEM_ADD | DEV_SEM_REMOVE;
|
---|
598 | EventSet.ulSemDeviceAdd = g_Notifications[Index].hDeviceAdded;
|
---|
599 | EventSet.ulSemDeviceRemove = g_Notifications[Index].hDeviceRemoved;
|
---|
600 | break;
|
---|
601 | case NOTIFY_DEVICE:
|
---|
602 | ulFunction = IOCTLF_DEREG_DEVICESEM;
|
---|
603 | ulSize = sizeof(DEVEVENTSET);
|
---|
604 | EventSet.ulSize = ulSize;
|
---|
605 | EventSet.ulCaps = DEV_SEM_ADD | DEV_SEM_REMOVE |
|
---|
606 | DEV_SEM_VENDORID | DEV_SEM_PRODUCTID |
|
---|
607 | DEV_SEM_BCDDEVICE ;
|
---|
608 | EventSet.ulSemDeviceAdd = g_Notifications[Index].hDeviceAdded;
|
---|
609 | EventSet.ulSemDeviceRemove = g_Notifications[Index].hDeviceRemoved;
|
---|
610 | EventSet.usVendorID = g_Notifications[Index].usVendor;
|
---|
611 | EventSet.usProductID = g_Notifications[Index].usProduct;
|
---|
612 | EventSet.usBCDDevice = g_Notifications[Index].usBCDDevice;
|
---|
613 | EventSet.usStatus = 0;
|
---|
614 | break;
|
---|
615 | default:
|
---|
616 | DosReleaseMutexSem(g_hSemNotifytable);
|
---|
617 | return ERROR_GEN_FAILURE;
|
---|
618 | }
|
---|
619 |
|
---|
620 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
621 | IOCAT_USBRES, ulFunction,
|
---|
622 | NULL, 0, NULL,
|
---|
623 | &EventSet,ulSize, &ulSize);
|
---|
624 | if(0==rc)
|
---|
625 | {
|
---|
626 | g_Notifications[Index].usFlags = NOTIFY_FREE;
|
---|
627 | g_Notifications[Index].hDeviceAdded = 0;
|
---|
628 | g_Notifications[Index].hDeviceRemoved = 0;
|
---|
629 | g_Notifications[Index].usVendor = 0;
|
---|
630 | g_Notifications[Index].usProduct = 0;
|
---|
631 | g_Notifications[Index].usBCDDevice = 0;
|
---|
632 | } else
|
---|
633 | {
|
---|
634 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_INVALID_PARAMETER) )
|
---|
635 | rc= ERROR_INVALID_PARAMETER;
|
---|
636 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_GEN_FAILURE) )
|
---|
637 | rc= EventSet.usStatus;
|
---|
638 | }
|
---|
639 | DosReleaseMutexSem(g_hSemNotifytable);
|
---|
640 |
|
---|
641 | return rc;
|
---|
642 | }
|
---|
643 |
|
---|
644 | APIEXPORT APIRET APIENTRY
|
---|
645 | UsbOpen( PUSBHANDLE pHandle,
|
---|
646 | USHORT usVendor,
|
---|
647 | USHORT usProduct,
|
---|
648 | USHORT usBCDDevice,
|
---|
649 | USHORT usEnumDevice)
|
---|
650 | {
|
---|
651 | ULONG ulCat, ulFunc;
|
---|
652 | ULONG ulParmLen, ulDataLen;
|
---|
653 | AQUIREDEV Aquire;
|
---|
654 | APIRET rc;
|
---|
655 |
|
---|
656 | if(!g_cInit)
|
---|
657 | return USB_NOT_INIT;
|
---|
658 | if(IsBadWritePointer(pHandle,sizeof(USBHANDLE)) )
|
---|
659 | return ERROR_INVALID_PARAMETER;
|
---|
660 |
|
---|
661 | Aquire.usVendorID = usVendor;
|
---|
662 | Aquire.usProductID = usProduct;
|
---|
663 | Aquire.usBCDDevice = usBCDDevice;
|
---|
664 | Aquire.usDeviceNumber = usEnumDevice;
|
---|
665 | ulCat = 0xA0;
|
---|
666 | ulFunc = 0x33;
|
---|
667 | ulParmLen = sizeof(Aquire);
|
---|
668 | ulDataLen = sizeof(USBHANDLE);
|
---|
669 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
670 | ulCat,ulFunc, /*IOCAT_USBRES, IOCTLF_AQUIREDEVICE, */
|
---|
671 | &Aquire, ulParmLen, &ulParmLen,
|
---|
672 | pHandle, ulDataLen, &ulDataLen);
|
---|
673 |
|
---|
674 | /* @@ ToDO maybe gether some info about device here (endpoints etc for safety checks) */
|
---|
675 | return rc;
|
---|
676 |
|
---|
677 | }
|
---|
678 |
|
---|
679 | APIEXPORT APIRET APIENTRY
|
---|
680 | UsbClose( USBHANDLE Handle)
|
---|
681 | {
|
---|
682 | APIRET rc;
|
---|
683 | ULONG ulDataLen,ulParmLen;
|
---|
684 | if(!g_cInit)
|
---|
685 | return USB_NOT_INIT;
|
---|
686 |
|
---|
687 | ulParmLen = sizeof(USBHANDLE);
|
---|
688 | ulDataLen = 0;
|
---|
689 |
|
---|
690 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
691 | IOCAT_USBRES, IOCTLF_RELEASEDEVICE,
|
---|
692 | (PVOID)&Handle, ulParmLen, &ulParmLen,
|
---|
693 | NULL, ulDataLen, &ulDataLen);
|
---|
694 | return rc;
|
---|
695 | }
|
---|
696 |
|
---|
697 | APIEXPORT APIRET APIENTRY
|
---|
698 | UsbCtrlMessage( USBHANDLE Handle,
|
---|
699 | UCHAR ucRequestType,
|
---|
700 | UCHAR ucRequest,
|
---|
701 | USHORT usValue,
|
---|
702 | USHORT usIndex,
|
---|
703 | USHORT usLength,
|
---|
704 | PVOID pData,
|
---|
705 | ULONG ulTimeout)
|
---|
706 | {
|
---|
707 | APIRET rc;
|
---|
708 | USBCALLS_CTRL_REQ CtrlRequest;
|
---|
709 | ULONG ulParmLen, ulDataLen;
|
---|
710 |
|
---|
711 | if(!g_cInit)
|
---|
712 | return USB_NOT_INIT;
|
---|
713 |
|
---|
714 | ulParmLen = sizeof(USBCALLS_CTRL_REQ);
|
---|
715 | CtrlRequest.ulHandle = Handle;
|
---|
716 | CtrlRequest.bRequestType = ucRequestType;
|
---|
717 | CtrlRequest.bRequest = ucRequest;
|
---|
718 | CtrlRequest.wValue = usValue;
|
---|
719 | CtrlRequest.wIndex = usIndex;
|
---|
720 | CtrlRequest.wLength = usLength;
|
---|
721 | CtrlRequest.ulTimeout = ulTimeout;
|
---|
722 | ulDataLen = usLength;
|
---|
723 |
|
---|
724 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
725 | IOCAT_USBRES, IOCTLF_SENDCONTROLURB,
|
---|
726 | (PVOID)&CtrlRequest, ulParmLen, &ulParmLen,
|
---|
727 | ulDataLen>0?(PVOID)pData:NULL,
|
---|
728 | ulDataLen,
|
---|
729 | ulDataLen>0?&ulDataLen:NULL);
|
---|
730 | if( rc != NO_ERROR )
|
---|
731 | {
|
---|
732 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_INVALID_PARAMETER) )
|
---|
733 | rc= ERROR_INVALID_PARAMETER;
|
---|
734 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_GEN_FAILURE) )
|
---|
735 | rc= CtrlRequest.usStatus;
|
---|
736 | }
|
---|
737 | return rc;
|
---|
738 | }
|
---|
739 |
|
---|
740 | APIEXPORT APIRET APIENTRY
|
---|
741 | UsbBulkRead( USBHANDLE Handle,
|
---|
742 | UCHAR Endpoint,
|
---|
743 | UCHAR AltInterface,
|
---|
744 | ULONG *ulNumBytes,
|
---|
745 | PVOID pvData,
|
---|
746 | ULONG ulTimeout)
|
---|
747 | {
|
---|
748 | return UsbBulkRead2(Handle, Endpoint, AltInterface, TRUE /* fShortOk */, ulNumBytes, pvData, ulTimeout);
|
---|
749 | }
|
---|
750 |
|
---|
751 | APIEXPORT APIRET APIENTRY
|
---|
752 | UsbBulkRead2( USBHANDLE Handle,
|
---|
753 | UCHAR Endpoint,
|
---|
754 | UCHAR AltInterface,
|
---|
755 | BOOL fShortOk,
|
---|
756 | ULONG *ulNumBytes,
|
---|
757 | PVOID pvData,
|
---|
758 | ULONG ulTimeout)
|
---|
759 | {
|
---|
760 | APIRET rc;
|
---|
761 | ULONG ulParmLen, ulDataLen, ulToProcess, ulTotalProcessed;
|
---|
762 | USBCALLS_BULK_REQ BulkRequest;
|
---|
763 |
|
---|
764 | if(!g_cInit)
|
---|
765 | return USB_NOT_INIT;
|
---|
766 |
|
---|
767 | if(*ulNumBytes==0)
|
---|
768 | return 0;
|
---|
769 |
|
---|
770 | /* just require this */
|
---|
771 | if ((ULONG)pvData & 0xfff)
|
---|
772 | return ERROR_INVALID_ADDRESS;
|
---|
773 | if ((ULONG)pvData >= 0x20000000)
|
---|
774 | return ERROR_INVALID_ADDRESS;
|
---|
775 |
|
---|
776 | ulToProcess = *ulNumBytes;
|
---|
777 | ulTotalProcessed = 0;
|
---|
778 |
|
---|
779 | do
|
---|
780 | {
|
---|
781 | /* Process up to 64k, making sure we're working on segments. */
|
---|
782 | ulDataLen = 0x10000 - ((ULONG)pvData & 0xffff);
|
---|
783 | if (ulDataLen > ulToProcess)
|
---|
784 | ulDataLen = ulToProcess;
|
---|
785 |
|
---|
786 | ulParmLen = sizeof(USBCALLS_BULK_REQ);
|
---|
787 |
|
---|
788 | memset(&BulkRequest, 0, sizeof(BulkRequest));
|
---|
789 | BulkRequest.ulDevHandle = Handle;
|
---|
790 | BulkRequest.ucEndpoint = Endpoint;
|
---|
791 | BulkRequest.ucAltInterface = AltInterface;
|
---|
792 | BulkRequest.usStatus = 0;
|
---|
793 | BulkRequest.ulEvent = 0;
|
---|
794 | //BulkRequest.ulID = (ULONG)pvData;
|
---|
795 | BulkRequest.ulTimeout = ulTimeout;
|
---|
796 | BulkRequest.usDataProcessed = 0;
|
---|
797 | BulkRequest.usDataRemain = ulDataLen;
|
---|
798 | BulkRequest.usFlags = fShortOk && ulDataLen == ulToProcess ? 0 : USB_TRANSFER_FULL_SIZE;
|
---|
799 |
|
---|
800 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
801 | IOCAT_USBRES, IOCTLF_SENDBULKURB,
|
---|
802 | (PVOID)&BulkRequest, ulParmLen, &ulParmLen,
|
---|
803 | pvData, ulDataLen, &ulDataLen);
|
---|
804 | Log(("BulkRead: usStatus=%d rc=%ld usDataProcessed=%d usDataRemain=%d ulDataLen=%ld\n",
|
---|
805 | BulkRequest.usStatus, rc, BulkRequest.usDataProcessed, BulkRequest.usDataRemain, ulDataLen));
|
---|
806 |
|
---|
807 | if (rc != NO_ERROR)
|
---|
808 | {
|
---|
809 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_INVALID_PARAMETER) )
|
---|
810 | rc= ERROR_INVALID_PARAMETER;
|
---|
811 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_GEN_FAILURE) )
|
---|
812 | rc= BulkRequest.usStatus;
|
---|
813 | break;
|
---|
814 | }
|
---|
815 |
|
---|
816 | /* Adjust count and source pointer */
|
---|
817 | ulToProcess -= ulDataLen;
|
---|
818 | pvData = (PBYTE)pvData + ulDataLen;
|
---|
819 | ulTotalProcessed += BulkRequest.usDataProcessed;
|
---|
820 |
|
---|
821 | if (BulkRequest.usDataProcessed != ulDataLen)
|
---|
822 | {
|
---|
823 | /* Transferred less than we wanted? so something is wrong,
|
---|
824 | or device doesn't wish to send more, exit loop */
|
---|
825 | rc = USB_ERROR_LESSTRANSFERED;
|
---|
826 | break;
|
---|
827 | }
|
---|
828 | } while( ulToProcess>0 );
|
---|
829 |
|
---|
830 | *ulNumBytes = ulTotalProcessed;
|
---|
831 |
|
---|
832 | return rc;
|
---|
833 | }
|
---|
834 |
|
---|
835 | APIEXPORT APIRET APIENTRY
|
---|
836 | UsbBulkWrite( USBHANDLE Handle,
|
---|
837 | UCHAR Endpoint,
|
---|
838 | UCHAR AltInterface,
|
---|
839 | ULONG ulNumBytes,
|
---|
840 | PVOID pvData,
|
---|
841 | ULONG ulTimeout)
|
---|
842 | {
|
---|
843 | return UsbBulkWrite2(Handle, Endpoint, AltInterface, FALSE /* fShortOk */, ulNumBytes, pvData, ulTimeout);
|
---|
844 | }
|
---|
845 |
|
---|
846 | APIEXPORT APIRET APIENTRY
|
---|
847 | UsbBulkWrite2( USBHANDLE Handle,
|
---|
848 | UCHAR Endpoint,
|
---|
849 | UCHAR AltInterface,
|
---|
850 | BOOL fShortOk,
|
---|
851 | ULONG ulNumBytes,
|
---|
852 | PVOID pvData,
|
---|
853 | ULONG ulTimeout)
|
---|
854 | {
|
---|
855 | APIRET rc;
|
---|
856 | ULONG ulParmLen, ulDataLen;
|
---|
857 | USBCALLS_BULK_REQ BulkRequest;
|
---|
858 |
|
---|
859 | if(!g_cInit)
|
---|
860 | return USB_NOT_INIT;
|
---|
861 |
|
---|
862 | /* just require this */
|
---|
863 | if ((ULONG)pvData & 0xfff)
|
---|
864 | return ERROR_INVALID_ADDRESS;
|
---|
865 | if ((ULONG)pvData >= 0x20000000)
|
---|
866 | return ERROR_INVALID_ADDRESS;
|
---|
867 |
|
---|
868 | do
|
---|
869 | {
|
---|
870 | /* Process up to 64k, making sure we're working on segments. */
|
---|
871 | ulDataLen = 0x10000 - ((ULONG)pvData & 0xffff);
|
---|
872 | if (ulDataLen > ulNumBytes)
|
---|
873 | ulDataLen = ulNumBytes;
|
---|
874 |
|
---|
875 | ulParmLen = sizeof(USBCALLS_BULK_REQ);
|
---|
876 |
|
---|
877 | memset(&BulkRequest, 0, sizeof(BulkRequest));
|
---|
878 | BulkRequest.ulDevHandle = Handle;
|
---|
879 | BulkRequest.ucEndpoint = Endpoint;
|
---|
880 | BulkRequest.ucAltInterface = AltInterface;
|
---|
881 | BulkRequest.usStatus = 0;
|
---|
882 | BulkRequest.ulEvent = 0;
|
---|
883 | //BulkRequest.ulID = (ULONG)pvData;
|
---|
884 | BulkRequest.ulTimeout = ulTimeout;
|
---|
885 | BulkRequest.usDataProcessed = 0;
|
---|
886 | BulkRequest.usDataRemain = ulDataLen;
|
---|
887 | BulkRequest.usFlags = fShortOk && ulDataLen == ulNumBytes ? 0 : USB_TRANSFER_FULL_SIZE;
|
---|
888 |
|
---|
889 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
890 | IOCAT_USBRES, IOCTLF_SENDBULKURB,
|
---|
891 | &BulkRequest, ulParmLen, &ulParmLen,
|
---|
892 | pvData, ulDataLen, &ulDataLen );
|
---|
893 | Log(("BulkWrite: usStatus=%d rc=%ld usDataProcessed=%d usDataRemain=%d ulDataLen=%ld\n",
|
---|
894 | BulkRequest.usStatus, rc, BulkRequest.usDataProcessed, BulkRequest.usDataRemain, ulDataLen));
|
---|
895 | if (rc != NO_ERROR)
|
---|
896 | {
|
---|
897 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_INVALID_PARAMETER) )
|
---|
898 | rc= ERROR_INVALID_PARAMETER;
|
---|
899 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_GEN_FAILURE) )
|
---|
900 | rc= BulkRequest.usStatus;
|
---|
901 | break;
|
---|
902 | }
|
---|
903 | /* Adjust count and source pointer */
|
---|
904 | ulNumBytes -= ulDataLen;
|
---|
905 | pvData = (PBYTE)pvData + ulDataLen;
|
---|
906 | } while( ulNumBytes > 0 );
|
---|
907 |
|
---|
908 | return rc;
|
---|
909 | }
|
---|
910 |
|
---|
911 | APIRET APIENTRY
|
---|
912 | UsbIrqStart( USBHANDLE Handle,
|
---|
913 | UCHAR Endpoint,
|
---|
914 | UCHAR AltInterface,
|
---|
915 | USHORT ulNumBytes,
|
---|
916 | PVOID pData,
|
---|
917 | PHEV pHevModified)
|
---|
918 | {
|
---|
919 | APIRET rc;
|
---|
920 | ULONG ulParmLen, ulDataLen;
|
---|
921 | USBCALLS_IRQ_START IrqStart;
|
---|
922 | HEV hEvent;
|
---|
923 |
|
---|
924 | if(!g_cInit)
|
---|
925 | return USB_NOT_INIT;
|
---|
926 |
|
---|
927 | if(0==ulNumBytes || IsBadWritePointer(pData, ulNumBytes))
|
---|
928 | return ERROR_INVALID_PARAMETER;
|
---|
929 |
|
---|
930 | rc = DosCreateEventSem( NULL,
|
---|
931 | &hEvent,
|
---|
932 | DC_SEM_SHARED,
|
---|
933 | FALSE);
|
---|
934 | if(rc)
|
---|
935 | return rc;
|
---|
936 |
|
---|
937 | IrqStart.ulDevHandle = Handle;
|
---|
938 | IrqStart.ucEndpoint = Endpoint;
|
---|
939 | IrqStart.ucAltInterface = AltInterface;
|
---|
940 | IrqStart.usStatus = 0;
|
---|
941 | IrqStart.ulEvent = hEvent;
|
---|
942 | ulParmLen = sizeof(IrqStart);
|
---|
943 | ulDataLen = ulNumBytes;
|
---|
944 |
|
---|
945 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
946 | IOCAT_USBRES, IOCTLF_START_IRQ_PROC,
|
---|
947 | (PVOID)&IrqStart, ulParmLen, &ulParmLen,
|
---|
948 | pData, ulDataLen,&ulDataLen);
|
---|
949 | if(rc)
|
---|
950 | DosCloseEventSem(hEvent);
|
---|
951 | else
|
---|
952 | *pHevModified = hEvent;
|
---|
953 | return rc;
|
---|
954 | }
|
---|
955 |
|
---|
956 | APIEXPORT APIRET APIENTRY
|
---|
957 | UsbIrqStop( USBHANDLE Handle,
|
---|
958 | HEV HevModified)
|
---|
959 | {
|
---|
960 | APIRET rc;
|
---|
961 | ULONG ulParmLen, ulDataLen;
|
---|
962 |
|
---|
963 | if(!g_cInit)
|
---|
964 | return USB_NOT_INIT;
|
---|
965 |
|
---|
966 | ulParmLen = sizeof(Handle);
|
---|
967 | ulDataLen = sizeof(HevModified);
|
---|
968 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
969 | IOCAT_USBRES, IOCTLF_STOP_IRQ_PROC,
|
---|
970 | (PVOID)&Handle, ulParmLen, &ulParmLen,
|
---|
971 | &HevModified, ulDataLen, &ulDataLen);
|
---|
972 | if(!rc)
|
---|
973 | DosCloseEventSem(HevModified);
|
---|
974 |
|
---|
975 | return rc;
|
---|
976 | }
|
---|
977 |
|
---|
978 | APIEXPORT APIRET APIENTRY
|
---|
979 | UsbIsoStart( USBHANDLE Handle,
|
---|
980 | UCHAR Endpoint,
|
---|
981 | UCHAR AltInterface,
|
---|
982 | ISOHANDLE *phIso)
|
---|
983 | {
|
---|
984 | APIRET rc;
|
---|
985 | PISORINGBUFFER pIter = g_pIsoRingBuffers;
|
---|
986 | USBCALLS_ISO_START IsoStart;
|
---|
987 | ULONG ulParmLen, ulDataLen;
|
---|
988 | int i;
|
---|
989 |
|
---|
990 | if(!g_cInit)
|
---|
991 | return USB_NOT_INIT;
|
---|
992 |
|
---|
993 | rc = DosRequestMutexSem(g_hSemRingBuffers,SEM_INDEFINITE_WAIT);
|
---|
994 | if(rc)
|
---|
995 | return rc;
|
---|
996 |
|
---|
997 | for(i=0;i< g_ulNumIsoRingBuffers;i++,pIter++)
|
---|
998 | {
|
---|
999 | if (pIter->hDevice==0)
|
---|
1000 | {
|
---|
1001 | pIter->hDevice = Handle;
|
---|
1002 | break;
|
---|
1003 | }
|
---|
1004 | }
|
---|
1005 | DosReleaseMutexSem(g_hSemRingBuffers);
|
---|
1006 |
|
---|
1007 | if(i==g_ulNumIsoRingBuffers)
|
---|
1008 | return USB_ERROR_OUTOF_RESOURCES;
|
---|
1009 |
|
---|
1010 | IsoStart.ulDevHandle = Handle;
|
---|
1011 | IsoStart.ucEndpoint = Endpoint;
|
---|
1012 | IsoStart.ucAltInterface = AltInterface;
|
---|
1013 | ulParmLen = sizeof(IsoStart);
|
---|
1014 | ulDataLen = sizeof(ISORINGBUFFER);
|
---|
1015 |
|
---|
1016 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
1017 | IOCAT_USBRES, IOCTLF_STOP_IRQ_PROC,
|
---|
1018 | (PVOID)&IsoStart, ulParmLen, &ulParmLen,
|
---|
1019 | pIter, ulDataLen, &ulDataLen);
|
---|
1020 | if(rc)
|
---|
1021 | {
|
---|
1022 | pIter->hDevice = 0;
|
---|
1023 | *phIso = 0;
|
---|
1024 | }
|
---|
1025 | else
|
---|
1026 | {
|
---|
1027 | pIter->ucEndpoint = Endpoint;
|
---|
1028 | pIter->ucAltInterface = AltInterface;
|
---|
1029 | }
|
---|
1030 | return rc;
|
---|
1031 | }
|
---|
1032 |
|
---|
1033 | static APIRET IsInvalidIsoHandle(const ISOHANDLE hIso)
|
---|
1034 | {
|
---|
1035 | PISORINGBUFFER pIter;
|
---|
1036 | ULONG i;
|
---|
1037 | pIter = g_pIsoRingBuffers;
|
---|
1038 |
|
---|
1039 | for(i=0;i<g_ulNumIsoRingBuffers;i++,pIter++)
|
---|
1040 | {
|
---|
1041 | if(pIter==(PISORINGBUFFER)hIso && pIter->hDevice)
|
---|
1042 | return 0;
|
---|
1043 | }
|
---|
1044 | return ERROR_INVALID_PARAMETER;
|
---|
1045 | }
|
---|
1046 |
|
---|
1047 | APIEXPORT APIRET APIENTRY
|
---|
1048 | UsbIsoStop( ISOHANDLE hIso)
|
---|
1049 | {
|
---|
1050 |
|
---|
1051 | APIRET rc;
|
---|
1052 | if(!g_cInit)
|
---|
1053 | return USB_NOT_INIT;
|
---|
1054 |
|
---|
1055 | /* rc = DosDevIOCtl( g_hUSBDrv, */
|
---|
1056 | return rc;
|
---|
1057 | }
|
---|
1058 |
|
---|
1059 | APIEXPORT APIRET APIENTRY
|
---|
1060 | UsbIsoDequeue( ISOHANDLE hIso,
|
---|
1061 | PVOID pBuffer,
|
---|
1062 | ULONG ulNumBytes)
|
---|
1063 | {
|
---|
1064 | APIRET rc;
|
---|
1065 | PISORINGBUFFER pRB = (PISORINGBUFFER)hIso;
|
---|
1066 |
|
---|
1067 | rc = IsInvalidIsoHandle(hIso);
|
---|
1068 | if(rc)
|
---|
1069 | return rc;
|
---|
1070 | if(!(pRB->ucEndpoint & ISO_DIRMASK))
|
---|
1071 | return ERROR_INVALID_PARAMETER;
|
---|
1072 |
|
---|
1073 | return rc;
|
---|
1074 | }
|
---|
1075 |
|
---|
1076 | APIEXPORT APIRET APIENTRY
|
---|
1077 | UsbIsoPeekQueue( ISOHANDLE hIso,
|
---|
1078 | UCHAR * pByte,
|
---|
1079 | ULONG ulOffset)
|
---|
1080 | {
|
---|
1081 | APIRET rc;
|
---|
1082 | PISORINGBUFFER pRB = (PISORINGBUFFER)hIso;
|
---|
1083 |
|
---|
1084 | rc = IsInvalidIsoHandle(hIso);
|
---|
1085 | if(rc)
|
---|
1086 | return rc;
|
---|
1087 | if(!(pRB->ucEndpoint & ISO_DIRMASK))
|
---|
1088 | return ERROR_INVALID_PARAMETER;
|
---|
1089 | return rc;
|
---|
1090 | }
|
---|
1091 |
|
---|
1092 | APIEXPORT APIRET APIENTRY
|
---|
1093 | UsbIsoEnqueue( ISOHANDLE hIso,
|
---|
1094 | const UCHAR * pBuffer,
|
---|
1095 | ULONG ulNumBytes)
|
---|
1096 | {
|
---|
1097 | APIRET rc;
|
---|
1098 | PISORINGBUFFER pRB = (PISORINGBUFFER)hIso;
|
---|
1099 |
|
---|
1100 | rc = IsInvalidIsoHandle(hIso);
|
---|
1101 | if(rc)
|
---|
1102 | return rc;
|
---|
1103 | if(pRB->ucEndpoint & ISO_DIRMASK)
|
---|
1104 | return ERROR_INVALID_PARAMETER;
|
---|
1105 |
|
---|
1106 | return rc;
|
---|
1107 | }
|
---|
1108 |
|
---|
1109 | APIEXPORT APIRET APIENTRY
|
---|
1110 | UsbIsoGetLength( ISOHANDLE hIso,
|
---|
1111 | ULONG *pulLength)
|
---|
1112 | {
|
---|
1113 | APIRET rc;
|
---|
1114 | PISORINGBUFFER pRB = (PISORINGBUFFER) hIso;
|
---|
1115 | USHORT ri,wi;
|
---|
1116 |
|
---|
1117 | rc = IsInvalidIsoHandle(hIso);
|
---|
1118 | if(rc)
|
---|
1119 | return rc;
|
---|
1120 | wi = pRB->usPosWrite;
|
---|
1121 | ri = pRB->usPosRead;
|
---|
1122 |
|
---|
1123 | if (ri == wi)
|
---|
1124 | *pulLength = 0;
|
---|
1125 | else if (ri < wi)
|
---|
1126 | *pulLength = wi - ri;
|
---|
1127 | else
|
---|
1128 | *pulLength = wi + (pRB->usBufSize - ri);
|
---|
1129 |
|
---|
1130 | return 0;
|
---|
1131 | }
|
---|
1132 |
|
---|
1133 | APIEXPORT APIRET APIENTRY
|
---|
1134 | UsbIrqRead( USBHANDLE Handle,
|
---|
1135 | UCHAR Endpoint,
|
---|
1136 | UCHAR AltInterface,
|
---|
1137 | ULONG *ulNumBytes,
|
---|
1138 | PVOID pData,
|
---|
1139 | ULONG ulTimeout)
|
---|
1140 | {
|
---|
1141 | APIRET rc;
|
---|
1142 | ULONG ulParmLen, ulDataLen;
|
---|
1143 | LIBUSB_IRQ_REQ IrqRequest;
|
---|
1144 |
|
---|
1145 | if(!g_cInit)
|
---|
1146 | return USB_NOT_INIT;
|
---|
1147 |
|
---|
1148 | /* 10 01 2003 - KIEWITZ -> Still @@ToDo Add Endpoint check based on descriptors
|
---|
1149 | We currently only allow Endpoint-addresses 80h->8Fh here */
|
---|
1150 | if ((Endpoint<0x80) || (Endpoint>0x8F))
|
---|
1151 | return USB_ERROR_INVALID_ENDPOINT;
|
---|
1152 |
|
---|
1153 | if(*ulNumBytes==0)
|
---|
1154 | return 0;
|
---|
1155 |
|
---|
1156 | IrqRequest.ulDevHandle = Handle;
|
---|
1157 | IrqRequest.ucEndpoint = Endpoint;
|
---|
1158 | IrqRequest.ucAltInterface = AltInterface;
|
---|
1159 | IrqRequest.usStatus = 0;
|
---|
1160 | IrqRequest.ulEvent = 0;
|
---|
1161 | IrqRequest.ulTimeout = ulTimeout;
|
---|
1162 | ulParmLen = sizeof(LIBUSB_IRQ_REQ);
|
---|
1163 | ulDataLen = *ulNumBytes;
|
---|
1164 |
|
---|
1165 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
1166 | IOCAT_USBRES, IOCTLF_SENDIRQURB,
|
---|
1167 | (PVOID)&IrqRequest, ulParmLen, &ulParmLen,
|
---|
1168 | pData, ulDataLen, &ulDataLen);
|
---|
1169 |
|
---|
1170 | if( rc == NO_ERROR )
|
---|
1171 | {
|
---|
1172 | *ulNumBytes = IrqRequest.usDataLen;
|
---|
1173 | } else
|
---|
1174 | {
|
---|
1175 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_INVALID_PARAMETER) )
|
---|
1176 | rc= ERROR_INVALID_PARAMETER;
|
---|
1177 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_GEN_FAILURE) )
|
---|
1178 | rc= IrqRequest.usStatus;
|
---|
1179 | }
|
---|
1180 | return rc;
|
---|
1181 | }
|
---|
1182 |
|
---|
1183 |
|
---|
1184 | APIEXPORT APIRET APIENTRY
|
---|
1185 | UsbFixupDevice( USBHANDLE Handle,
|
---|
1186 | UCHAR ucConfiguration,
|
---|
1187 | UCHAR *pucConfigurationData,
|
---|
1188 | ULONG ulConfigurationLen )
|
---|
1189 | {
|
---|
1190 | LIBUSB_FIXUP request;
|
---|
1191 | ULONG ulParmLen;
|
---|
1192 | APIRET rc;
|
---|
1193 |
|
---|
1194 | request.ulDevHandle= Handle;
|
---|
1195 | request.ucConfiguration= ucConfiguration;
|
---|
1196 | request.usStatus= 0;
|
---|
1197 | ulParmLen= sizeof(LIBUSB_FIXUP);
|
---|
1198 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
1199 | IOCAT_USBRES, IOCTLF_FIXUPDEVUCE,
|
---|
1200 | (PVOID)&request, ulParmLen, &ulParmLen,
|
---|
1201 | pucConfigurationData, ulConfigurationLen, &ulConfigurationLen);
|
---|
1202 | if( rc != NO_ERROR )
|
---|
1203 | {
|
---|
1204 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_INVALID_PARAMETER) )
|
---|
1205 | rc= ERROR_INVALID_PARAMETER;
|
---|
1206 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_GEN_FAILURE) )
|
---|
1207 | rc= request.usStatus;
|
---|
1208 | }
|
---|
1209 | return rc;
|
---|
1210 | }
|
---|
1211 |
|
---|
1212 | #ifndef STATIC_USBCALLS
|
---|
1213 | /*+-------------------------------------------------------------------+*/
|
---|
1214 | /*| _CRT_init is the C run-time environment initialization function. |*/
|
---|
1215 | /*|It will return 0 to indicate success and -1 to indicate failure. |*/
|
---|
1216 | /*+-------------------------------------------------------------------+*/
|
---|
1217 |
|
---|
1218 | /* int _CRT_init (void); */
|
---|
1219 |
|
---|
1220 | /*+-------------------------------------------------------------------+*/
|
---|
1221 | /*| _CRT_term is the C run-time environment termination function. |*/
|
---|
1222 | /*+-------------------------------------------------------------------+*/
|
---|
1223 |
|
---|
1224 | /* void _CRT_term (unsigned long);*/
|
---|
1225 |
|
---|
1226 | /*+-------------------------------------------------------------------+*/
|
---|
1227 | /*| _DLL_InitTerm is the function that gets called by the operating |*/
|
---|
1228 | /*| system loader when it loads and frees this DLL for each process |*/
|
---|
1229 | /*| that accesses this DLL. However, it only gets called the first |*/
|
---|
1230 | /*| time the DLL is loaded and the last time it is freed for a |*/
|
---|
1231 | /*| particular process. The system linkage convention must be used |*/
|
---|
1232 | /*| because the operating system loader is calling this function. |*/
|
---|
1233 | /*+-------------------------------------------------------------------+*/
|
---|
1234 |
|
---|
1235 | #ifdef STATIC_LINK
|
---|
1236 | int _CRT_init (void);
|
---|
1237 | void _CRT_term(0UL);
|
---|
1238 | #endif
|
---|
1239 |
|
---|
1240 | unsigned long _System _DLL_InitTerm (unsigned long modhandle, unsigned long flag)
|
---|
1241 | {
|
---|
1242 |
|
---|
1243 | /* If flag is zero then the DLL is being loaded so initialization */
|
---|
1244 | /* should be performed. If flag is 1 then the DLL is being freed */
|
---|
1245 | /* so termination should be performed. */
|
---|
1246 |
|
---|
1247 | switch (flag)
|
---|
1248 | {
|
---|
1249 | case 0:
|
---|
1250 | /* The C run-time environment initialization function must */
|
---|
1251 | /* be called before any calls to C run-time functions that */
|
---|
1252 | /* are not inlined. */
|
---|
1253 |
|
---|
1254 | #ifdef STATIC_LINK
|
---|
1255 | if (_CRT_init () == -1)
|
---|
1256 | return 0UL;
|
---|
1257 | #endif
|
---|
1258 | InitUsbCalls();
|
---|
1259 | break;
|
---|
1260 |
|
---|
1261 | case 1:
|
---|
1262 | TermUsbCalls();
|
---|
1263 | #ifdef STATIC_LINK
|
---|
1264 | _CRT_term(0UL);
|
---|
1265 | #endif
|
---|
1266 | break;
|
---|
1267 |
|
---|
1268 | default:
|
---|
1269 | return 0UL;
|
---|
1270 |
|
---|
1271 | }
|
---|
1272 |
|
---|
1273 | /* A nonzero value must be returned to indicate success. */
|
---|
1274 | return 1UL;
|
---|
1275 | }
|
---|
1276 | #endif /* !STATIC_USBCALLS */
|
---|
1277 |
|
---|