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 | EventSet.ulCaps = 0;
|
---|
424 |
|
---|
425 | if(hDeviceAdded!=0)
|
---|
426 | {
|
---|
427 | ULONG ulCnt;
|
---|
428 | rc = DosQueryEventSem(hDeviceAdded,&ulCnt);
|
---|
429 | if(rc)
|
---|
430 | return rc;
|
---|
431 | EventSet.ulCaps |= DEV_SEM_ADD;
|
---|
432 | EventSet.ulSemDeviceAdd = hDeviceAdded;
|
---|
433 | }
|
---|
434 |
|
---|
435 | if(hDeviceRemoved!=0)
|
---|
436 | {
|
---|
437 | ULONG ulCnt;
|
---|
438 | rc = DosQueryEventSem(hDeviceRemoved,&ulCnt);
|
---|
439 | if(rc)
|
---|
440 | return rc;
|
---|
441 | EventSet.ulCaps |= DEV_SEM_REMOVE;
|
---|
442 | EventSet.ulSemDeviceRemove = hDeviceRemoved;
|
---|
443 | }
|
---|
444 |
|
---|
445 | rc = DosRequestMutexSem(g_hSemNotifytable,SEM_INDEFINITE_WAIT);
|
---|
446 | if(rc)
|
---|
447 | return rc;
|
---|
448 |
|
---|
449 | for(i=0;i<MAX_NOTIFICATIONS;i++)
|
---|
450 | {
|
---|
451 | if( g_Notifications[i].usFlags == NOTIFY_FREE)
|
---|
452 | {
|
---|
453 | g_Notifications[i].usFlags = NOTIFY_CHANGE;
|
---|
454 | g_Notifications[i].hDeviceAdded = hDeviceAdded;
|
---|
455 | g_Notifications[i].hDeviceRemoved = hDeviceRemoved;
|
---|
456 | g_Notifications[i].usVendor = 0;
|
---|
457 | g_Notifications[i].usProduct = 0;
|
---|
458 | g_Notifications[i].usBCDDevice = 0;
|
---|
459 | break;
|
---|
460 | }
|
---|
461 | }
|
---|
462 | DosReleaseMutexSem(g_hSemNotifytable);
|
---|
463 | if(i==MAX_NOTIFICATIONS)
|
---|
464 | return USB_ERROR_NO_MORE_NOTIFICATIONS;
|
---|
465 |
|
---|
466 | /* @@ToDo come up with a better way to generate IDs */
|
---|
467 | *pNotifyID = (USBNOTIFY) (&g_Notifications[i]);
|
---|
468 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
469 | IOCAT_USBRES, IOCTLF_REG_STATUSSEM,
|
---|
470 | NULL, 0, NULL,
|
---|
471 | &EventSet,ulSize, &ulSize);
|
---|
472 | if(rc)
|
---|
473 | {
|
---|
474 | g_Notifications[i].usFlags = NOTIFY_FREE;
|
---|
475 | *pNotifyID = 0;
|
---|
476 | }
|
---|
477 | return rc;
|
---|
478 | }
|
---|
479 |
|
---|
480 | APIEXPORT APIRET APIENTRY
|
---|
481 | UsbRegisterDeviceNotification( PUSBNOTIFY pNotifyID,
|
---|
482 | HEV hDeviceAdded,
|
---|
483 | HEV hDeviceRemoved,
|
---|
484 | USHORT usVendor,
|
---|
485 | USHORT usProduct,
|
---|
486 | USHORT usBCDVersion)
|
---|
487 | {
|
---|
488 | DEVEVENTSET EventSet;
|
---|
489 | ULONG ulCnt,ulSize;
|
---|
490 | int i;
|
---|
491 | APIRET rc;
|
---|
492 |
|
---|
493 | if(!g_cInit)
|
---|
494 | return USB_NOT_INIT;
|
---|
495 |
|
---|
496 | if( IsBadWritePointer(pNotifyID, sizeof(ULONG)) ||
|
---|
497 | hDeviceAdded==0 || hDeviceRemoved==0 ||
|
---|
498 | usVendor == 0 || usVendor == 0xFFFF ||
|
---|
499 | usProduct == 0 || usProduct == 0xFFFF )
|
---|
500 | return ERROR_INVALID_PARAMETER;
|
---|
501 |
|
---|
502 |
|
---|
503 | rc = DosQueryEventSem(hDeviceAdded,&ulCnt);
|
---|
504 | if(rc)
|
---|
505 | return rc;
|
---|
506 | rc = DosQueryEventSem(hDeviceRemoved,&ulCnt);
|
---|
507 | if(rc)
|
---|
508 | return rc;
|
---|
509 |
|
---|
510 | ulSize = sizeof(EventSet);
|
---|
511 | EventSet.ulSize = ulSize;
|
---|
512 | EventSet.ulCaps = DEV_SEM_ADD | DEV_SEM_REMOVE |
|
---|
513 | DEV_SEM_VENDORID | DEV_SEM_PRODUCTID |
|
---|
514 | DEV_SEM_BCDDEVICE ;
|
---|
515 | EventSet.ulSemDeviceAdd = hDeviceAdded;
|
---|
516 | EventSet.ulSemDeviceRemove = hDeviceRemoved;
|
---|
517 | EventSet.usVendorID = usVendor;
|
---|
518 | EventSet.usProductID = usProduct;
|
---|
519 | EventSet.usBCDDevice = usBCDVersion;
|
---|
520 | EventSet.usStatus = 0;
|
---|
521 |
|
---|
522 | rc = DosRequestMutexSem(g_hSemNotifytable,SEM_INDEFINITE_WAIT);
|
---|
523 |
|
---|
524 | if(rc)
|
---|
525 | return rc;
|
---|
526 |
|
---|
527 | for(i=0;i<MAX_NOTIFICATIONS;i++)
|
---|
528 | {
|
---|
529 | if( g_Notifications[i].usFlags == NOTIFY_FREE)
|
---|
530 | {
|
---|
531 | g_Notifications[i].usFlags = NOTIFY_DEVICE;
|
---|
532 | g_Notifications[i].hDeviceAdded = hDeviceAdded;
|
---|
533 | g_Notifications[i].hDeviceRemoved = hDeviceRemoved;
|
---|
534 | g_Notifications[i].usVendor = usVendor;
|
---|
535 | g_Notifications[i].usProduct = usProduct;
|
---|
536 | g_Notifications[i].usBCDDevice = usBCDVersion;
|
---|
537 | break;
|
---|
538 | }
|
---|
539 | }
|
---|
540 | DosReleaseMutexSem(g_hSemNotifytable);
|
---|
541 | if(i==MAX_NOTIFICATIONS)
|
---|
542 | return USB_ERROR_NO_MORE_NOTIFICATIONS;
|
---|
543 |
|
---|
544 | /* @@ToDo come up with a better way to generate IDs */
|
---|
545 | *pNotifyID = (USBNOTIFY) (&g_Notifications[i]);
|
---|
546 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
547 | IOCAT_USBRES, IOCTLF_REG_DEVICESEM,
|
---|
548 | NULL, 0, NULL,
|
---|
549 | &EventSet,ulSize, &ulSize);
|
---|
550 | if(rc)
|
---|
551 | {
|
---|
552 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_INVALID_PARAMETER) )
|
---|
553 | rc= ERROR_INVALID_PARAMETER;
|
---|
554 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_GEN_FAILURE) )
|
---|
555 | rc= EventSet.usStatus;
|
---|
556 |
|
---|
557 | g_Notifications[i].usFlags = NOTIFY_FREE;
|
---|
558 | *pNotifyID = 0;
|
---|
559 | }
|
---|
560 | return rc;
|
---|
561 | }
|
---|
562 |
|
---|
563 | APIEXPORT APIRET APIENTRY
|
---|
564 | UsbDeregisterNotification( USBNOTIFY NotifyID )
|
---|
565 | {
|
---|
566 | DEVEVENTSET EventSet;
|
---|
567 | USBNOTIFY MinID,MaxID;
|
---|
568 | ULONG Index, ulFunction, ulSize;
|
---|
569 | APIRET rc;
|
---|
570 |
|
---|
571 | if(!g_cInit)
|
---|
572 | return USB_NOT_INIT;
|
---|
573 |
|
---|
574 | MinID = (USBNOTIFY) (&g_Notifications[0]);
|
---|
575 | MaxID = (USBNOTIFY) (&g_Notifications[MAX_NOTIFICATIONS-1]);
|
---|
576 |
|
---|
577 | if(NotifyID<MinID || NotifyID>MaxID)
|
---|
578 | return ERROR_INVALID_PARAMETER;
|
---|
579 |
|
---|
580 | Index = NotifyID - MinID;
|
---|
581 |
|
---|
582 | if(Index % sizeof(NOTIFYENTRY))
|
---|
583 | return ERROR_INVALID_PARAMETER;
|
---|
584 |
|
---|
585 | Index /= sizeof(NOTIFYENTRY);
|
---|
586 |
|
---|
587 | rc = DosRequestMutexSem(g_hSemNotifytable,SEM_INDEFINITE_WAIT);
|
---|
588 |
|
---|
589 | switch(g_Notifications[Index].usFlags)
|
---|
590 | {
|
---|
591 | case NOTIFY_FREE:
|
---|
592 | DosReleaseMutexSem(g_hSemNotifytable);
|
---|
593 | return ERROR_INVALID_PARAMETER;
|
---|
594 | case NOTIFY_CHANGE:
|
---|
595 | ulFunction = IOCTLF_DEREG_STATUSSEM;
|
---|
596 | ulSize = sizeof(STATUSEVENTSET);
|
---|
597 | EventSet.ulSize = ulSize;
|
---|
598 | EventSet.ulCaps = DEV_SEM_ADD | DEV_SEM_REMOVE;
|
---|
599 | EventSet.ulSemDeviceAdd = g_Notifications[Index].hDeviceAdded;
|
---|
600 | EventSet.ulSemDeviceRemove = g_Notifications[Index].hDeviceRemoved;
|
---|
601 | break;
|
---|
602 | case NOTIFY_DEVICE:
|
---|
603 | ulFunction = IOCTLF_DEREG_DEVICESEM;
|
---|
604 | ulSize = sizeof(DEVEVENTSET);
|
---|
605 | EventSet.ulSize = ulSize;
|
---|
606 | EventSet.ulCaps = DEV_SEM_ADD | DEV_SEM_REMOVE |
|
---|
607 | DEV_SEM_VENDORID | DEV_SEM_PRODUCTID |
|
---|
608 | DEV_SEM_BCDDEVICE ;
|
---|
609 | EventSet.ulSemDeviceAdd = g_Notifications[Index].hDeviceAdded;
|
---|
610 | EventSet.ulSemDeviceRemove = g_Notifications[Index].hDeviceRemoved;
|
---|
611 | EventSet.usVendorID = g_Notifications[Index].usVendor;
|
---|
612 | EventSet.usProductID = g_Notifications[Index].usProduct;
|
---|
613 | EventSet.usBCDDevice = g_Notifications[Index].usBCDDevice;
|
---|
614 | EventSet.usStatus = 0;
|
---|
615 | break;
|
---|
616 | default:
|
---|
617 | DosReleaseMutexSem(g_hSemNotifytable);
|
---|
618 | return ERROR_GEN_FAILURE;
|
---|
619 | }
|
---|
620 |
|
---|
621 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
622 | IOCAT_USBRES, ulFunction,
|
---|
623 | NULL, 0, NULL,
|
---|
624 | &EventSet,ulSize, &ulSize);
|
---|
625 | if(0==rc)
|
---|
626 | {
|
---|
627 | g_Notifications[Index].usFlags = NOTIFY_FREE;
|
---|
628 | g_Notifications[Index].hDeviceAdded = 0;
|
---|
629 | g_Notifications[Index].hDeviceRemoved = 0;
|
---|
630 | g_Notifications[Index].usVendor = 0;
|
---|
631 | g_Notifications[Index].usProduct = 0;
|
---|
632 | g_Notifications[Index].usBCDDevice = 0;
|
---|
633 | } else
|
---|
634 | {
|
---|
635 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_INVALID_PARAMETER) )
|
---|
636 | rc= ERROR_INVALID_PARAMETER;
|
---|
637 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_GEN_FAILURE) )
|
---|
638 | rc= EventSet.usStatus;
|
---|
639 | }
|
---|
640 | DosReleaseMutexSem(g_hSemNotifytable);
|
---|
641 |
|
---|
642 | return rc;
|
---|
643 | }
|
---|
644 |
|
---|
645 | APIEXPORT APIRET APIENTRY
|
---|
646 | UsbOpen( PUSBHANDLE pHandle,
|
---|
647 | USHORT usVendor,
|
---|
648 | USHORT usProduct,
|
---|
649 | USHORT usBCDDevice,
|
---|
650 | USHORT usEnumDevice)
|
---|
651 | {
|
---|
652 | ULONG ulCat, ulFunc;
|
---|
653 | ULONG ulParmLen, ulDataLen;
|
---|
654 | AQUIREDEV Aquire;
|
---|
655 | APIRET rc;
|
---|
656 |
|
---|
657 | if(!g_cInit)
|
---|
658 | return USB_NOT_INIT;
|
---|
659 | if(IsBadWritePointer(pHandle,sizeof(USBHANDLE)) )
|
---|
660 | return ERROR_INVALID_PARAMETER;
|
---|
661 |
|
---|
662 | Aquire.usVendorID = usVendor;
|
---|
663 | Aquire.usProductID = usProduct;
|
---|
664 | Aquire.usBCDDevice = usBCDDevice;
|
---|
665 | Aquire.usDeviceNumber = usEnumDevice;
|
---|
666 | ulCat = 0xA0;
|
---|
667 | ulFunc = 0x33;
|
---|
668 | ulParmLen = sizeof(Aquire);
|
---|
669 | ulDataLen = sizeof(USBHANDLE);
|
---|
670 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
671 | ulCat,ulFunc, /*IOCAT_USBRES, IOCTLF_AQUIREDEVICE, */
|
---|
672 | &Aquire, ulParmLen, &ulParmLen,
|
---|
673 | pHandle, ulDataLen, &ulDataLen);
|
---|
674 |
|
---|
675 | /* @@ ToDO maybe gether some info about device here (endpoints etc for safety checks) */
|
---|
676 | return rc;
|
---|
677 |
|
---|
678 | }
|
---|
679 |
|
---|
680 | APIEXPORT APIRET APIENTRY
|
---|
681 | UsbClose( USBHANDLE Handle)
|
---|
682 | {
|
---|
683 | APIRET rc;
|
---|
684 | ULONG ulDataLen,ulParmLen;
|
---|
685 | if(!g_cInit)
|
---|
686 | return USB_NOT_INIT;
|
---|
687 |
|
---|
688 | ulParmLen = sizeof(USBHANDLE);
|
---|
689 | ulDataLen = 0;
|
---|
690 |
|
---|
691 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
692 | IOCAT_USBRES, IOCTLF_RELEASEDEVICE,
|
---|
693 | (PVOID)&Handle, ulParmLen, &ulParmLen,
|
---|
694 | NULL, ulDataLen, &ulDataLen);
|
---|
695 | return rc;
|
---|
696 | }
|
---|
697 |
|
---|
698 | APIEXPORT APIRET APIENTRY
|
---|
699 | UsbCtrlMessage( USBHANDLE Handle,
|
---|
700 | UCHAR ucRequestType,
|
---|
701 | UCHAR ucRequest,
|
---|
702 | USHORT usValue,
|
---|
703 | USHORT usIndex,
|
---|
704 | USHORT usLength,
|
---|
705 | PVOID pData,
|
---|
706 | ULONG ulTimeout)
|
---|
707 | {
|
---|
708 | APIRET rc;
|
---|
709 | USBCALLS_CTRL_REQ CtrlRequest;
|
---|
710 | ULONG ulParmLen, ulDataLen;
|
---|
711 |
|
---|
712 | if(!g_cInit)
|
---|
713 | return USB_NOT_INIT;
|
---|
714 |
|
---|
715 | ulParmLen = sizeof(USBCALLS_CTRL_REQ);
|
---|
716 | CtrlRequest.ulHandle = Handle;
|
---|
717 | CtrlRequest.bRequestType = ucRequestType;
|
---|
718 | CtrlRequest.bRequest = ucRequest;
|
---|
719 | CtrlRequest.wValue = usValue;
|
---|
720 | CtrlRequest.wIndex = usIndex;
|
---|
721 | CtrlRequest.wLength = usLength;
|
---|
722 | CtrlRequest.ulTimeout = ulTimeout;
|
---|
723 | ulDataLen = usLength;
|
---|
724 |
|
---|
725 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
726 | IOCAT_USBRES, IOCTLF_SENDCONTROLURB,
|
---|
727 | (PVOID)&CtrlRequest, ulParmLen, &ulParmLen,
|
---|
728 | ulDataLen>0?(PVOID)pData:NULL,
|
---|
729 | ulDataLen,
|
---|
730 | ulDataLen>0?&ulDataLen:NULL);
|
---|
731 | if( rc != NO_ERROR )
|
---|
732 | {
|
---|
733 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_INVALID_PARAMETER) )
|
---|
734 | rc= ERROR_INVALID_PARAMETER;
|
---|
735 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_GEN_FAILURE) )
|
---|
736 | rc= CtrlRequest.usStatus;
|
---|
737 | }
|
---|
738 | return rc;
|
---|
739 | }
|
---|
740 |
|
---|
741 | APIEXPORT APIRET APIENTRY
|
---|
742 | UsbBulkRead( USBHANDLE Handle,
|
---|
743 | UCHAR Endpoint,
|
---|
744 | UCHAR AltInterface,
|
---|
745 | ULONG *ulNumBytes,
|
---|
746 | PVOID pvData,
|
---|
747 | ULONG ulTimeout)
|
---|
748 | {
|
---|
749 | return UsbBulkRead2(Handle, Endpoint, AltInterface, TRUE /* fShortOk */, ulNumBytes, pvData, ulTimeout);
|
---|
750 | }
|
---|
751 |
|
---|
752 | APIEXPORT APIRET APIENTRY
|
---|
753 | UsbBulkRead2( USBHANDLE Handle,
|
---|
754 | UCHAR Endpoint,
|
---|
755 | UCHAR AltInterface,
|
---|
756 | BOOL fShortOk,
|
---|
757 | ULONG *ulNumBytes,
|
---|
758 | PVOID pvData,
|
---|
759 | ULONG ulTimeout)
|
---|
760 | {
|
---|
761 | APIRET rc;
|
---|
762 | ULONG ulParmLen, ulDataLen, ulToProcess, ulTotalProcessed;
|
---|
763 | USBCALLS_BULK_REQ BulkRequest;
|
---|
764 |
|
---|
765 | if(!g_cInit)
|
---|
766 | return USB_NOT_INIT;
|
---|
767 |
|
---|
768 | if(*ulNumBytes==0)
|
---|
769 | return 0;
|
---|
770 |
|
---|
771 | /* just require this */
|
---|
772 | if ((ULONG)pvData & 0xfff)
|
---|
773 | return ERROR_INVALID_ADDRESS;
|
---|
774 | if ((ULONG)pvData >= 0x20000000)
|
---|
775 | return ERROR_INVALID_ADDRESS;
|
---|
776 |
|
---|
777 | ulToProcess = *ulNumBytes;
|
---|
778 | ulTotalProcessed = 0;
|
---|
779 |
|
---|
780 | do
|
---|
781 | {
|
---|
782 | /* Process up to 64k, making sure we're working on segments. */
|
---|
783 | ulDataLen = 0x10000 - ((ULONG)pvData & 0xffff);
|
---|
784 | if (ulDataLen > ulToProcess)
|
---|
785 | ulDataLen = ulToProcess;
|
---|
786 |
|
---|
787 | ulParmLen = sizeof(USBCALLS_BULK_REQ);
|
---|
788 |
|
---|
789 | memset(&BulkRequest, 0, sizeof(BulkRequest));
|
---|
790 | BulkRequest.ulDevHandle = Handle;
|
---|
791 | BulkRequest.ucEndpoint = Endpoint;
|
---|
792 | BulkRequest.ucAltInterface = AltInterface;
|
---|
793 | BulkRequest.usStatus = 0;
|
---|
794 | BulkRequest.ulEvent = 0;
|
---|
795 | //BulkRequest.ulID = (ULONG)pvData;
|
---|
796 | BulkRequest.ulTimeout = ulTimeout;
|
---|
797 | BulkRequest.usDataProcessed = 0;
|
---|
798 | BulkRequest.usDataRemain = ulDataLen;
|
---|
799 | BulkRequest.usFlags = fShortOk && ulDataLen == ulToProcess ? 0 : USB_TRANSFER_FULL_SIZE;
|
---|
800 |
|
---|
801 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
802 | IOCAT_USBRES, IOCTLF_SENDBULKURB,
|
---|
803 | (PVOID)&BulkRequest, ulParmLen, &ulParmLen,
|
---|
804 | pvData, ulDataLen, &ulDataLen);
|
---|
805 | Log(("BulkRead: usStatus=%d rc=%ld usDataProcessed=%d usDataRemain=%d ulDataLen=%ld\n",
|
---|
806 | BulkRequest.usStatus, rc, BulkRequest.usDataProcessed, BulkRequest.usDataRemain, ulDataLen));
|
---|
807 |
|
---|
808 | if (rc != NO_ERROR)
|
---|
809 | {
|
---|
810 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_INVALID_PARAMETER) )
|
---|
811 | rc= ERROR_INVALID_PARAMETER;
|
---|
812 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_GEN_FAILURE) )
|
---|
813 | rc= BulkRequest.usStatus;
|
---|
814 | break;
|
---|
815 | }
|
---|
816 |
|
---|
817 | /* Adjust count and source pointer */
|
---|
818 | ulToProcess -= ulDataLen;
|
---|
819 | pvData = (PBYTE)pvData + ulDataLen;
|
---|
820 | ulTotalProcessed += BulkRequest.usDataProcessed;
|
---|
821 |
|
---|
822 | if (BulkRequest.usDataProcessed != ulDataLen)
|
---|
823 | {
|
---|
824 | /* Transferred less than we wanted? so something is wrong,
|
---|
825 | or device doesn't wish to send more, exit loop */
|
---|
826 | rc = USB_ERROR_LESSTRANSFERED;
|
---|
827 | break;
|
---|
828 | }
|
---|
829 | } while( ulToProcess>0 );
|
---|
830 |
|
---|
831 | *ulNumBytes = ulTotalProcessed;
|
---|
832 |
|
---|
833 | return rc;
|
---|
834 | }
|
---|
835 |
|
---|
836 | APIEXPORT APIRET APIENTRY
|
---|
837 | UsbBulkWrite( USBHANDLE Handle,
|
---|
838 | UCHAR Endpoint,
|
---|
839 | UCHAR AltInterface,
|
---|
840 | ULONG ulNumBytes,
|
---|
841 | PVOID pvData,
|
---|
842 | ULONG ulTimeout)
|
---|
843 | {
|
---|
844 | return UsbBulkWrite2(Handle, Endpoint, AltInterface, FALSE /* fShortOk */, ulNumBytes, pvData, ulTimeout);
|
---|
845 | }
|
---|
846 |
|
---|
847 | APIEXPORT APIRET APIENTRY
|
---|
848 | UsbBulkWrite2( USBHANDLE Handle,
|
---|
849 | UCHAR Endpoint,
|
---|
850 | UCHAR AltInterface,
|
---|
851 | BOOL fShortOk,
|
---|
852 | ULONG ulNumBytes,
|
---|
853 | PVOID pvData,
|
---|
854 | ULONG ulTimeout)
|
---|
855 | {
|
---|
856 | APIRET rc;
|
---|
857 | ULONG ulParmLen, ulDataLen;
|
---|
858 | USBCALLS_BULK_REQ BulkRequest;
|
---|
859 |
|
---|
860 | if(!g_cInit)
|
---|
861 | return USB_NOT_INIT;
|
---|
862 |
|
---|
863 | /* just require this */
|
---|
864 | if ((ULONG)pvData & 0xfff)
|
---|
865 | return ERROR_INVALID_ADDRESS;
|
---|
866 | if ((ULONG)pvData >= 0x20000000)
|
---|
867 | return ERROR_INVALID_ADDRESS;
|
---|
868 |
|
---|
869 | do
|
---|
870 | {
|
---|
871 | /* Process up to 64k, making sure we're working on segments. */
|
---|
872 | ulDataLen = 0x10000 - ((ULONG)pvData & 0xffff);
|
---|
873 | if (ulDataLen > ulNumBytes)
|
---|
874 | ulDataLen = ulNumBytes;
|
---|
875 |
|
---|
876 | ulParmLen = sizeof(USBCALLS_BULK_REQ);
|
---|
877 |
|
---|
878 | memset(&BulkRequest, 0, sizeof(BulkRequest));
|
---|
879 | BulkRequest.ulDevHandle = Handle;
|
---|
880 | BulkRequest.ucEndpoint = Endpoint;
|
---|
881 | BulkRequest.ucAltInterface = AltInterface;
|
---|
882 | BulkRequest.usStatus = 0;
|
---|
883 | BulkRequest.ulEvent = 0;
|
---|
884 | //BulkRequest.ulID = (ULONG)pvData;
|
---|
885 | BulkRequest.ulTimeout = ulTimeout;
|
---|
886 | BulkRequest.usDataProcessed = 0;
|
---|
887 | BulkRequest.usDataRemain = ulDataLen;
|
---|
888 | BulkRequest.usFlags = fShortOk && ulDataLen == ulNumBytes ? 0 : USB_TRANSFER_FULL_SIZE;
|
---|
889 |
|
---|
890 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
891 | IOCAT_USBRES, IOCTLF_SENDBULKURB,
|
---|
892 | &BulkRequest, ulParmLen, &ulParmLen,
|
---|
893 | pvData, ulDataLen, &ulDataLen );
|
---|
894 | Log(("BulkWrite: usStatus=%d rc=%ld usDataProcessed=%d usDataRemain=%d ulDataLen=%ld\n",
|
---|
895 | BulkRequest.usStatus, rc, BulkRequest.usDataProcessed, BulkRequest.usDataRemain, ulDataLen));
|
---|
896 | if (rc != NO_ERROR)
|
---|
897 | {
|
---|
898 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_INVALID_PARAMETER) )
|
---|
899 | rc= ERROR_INVALID_PARAMETER;
|
---|
900 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_GEN_FAILURE) )
|
---|
901 | rc= BulkRequest.usStatus;
|
---|
902 | break;
|
---|
903 | }
|
---|
904 | /* Adjust count and source pointer */
|
---|
905 | ulNumBytes -= ulDataLen;
|
---|
906 | pvData = (PBYTE)pvData + ulDataLen;
|
---|
907 | } while( ulNumBytes > 0 );
|
---|
908 |
|
---|
909 | return rc;
|
---|
910 | }
|
---|
911 |
|
---|
912 | APIRET APIENTRY
|
---|
913 | UsbIrqStart( USBHANDLE Handle,
|
---|
914 | UCHAR Endpoint,
|
---|
915 | UCHAR AltInterface,
|
---|
916 | USHORT ulNumBytes,
|
---|
917 | PVOID pData,
|
---|
918 | PHEV pHevModified)
|
---|
919 | {
|
---|
920 | APIRET rc;
|
---|
921 | ULONG ulParmLen, ulDataLen;
|
---|
922 | USBCALLS_IRQ_START IrqStart;
|
---|
923 | HEV hEvent;
|
---|
924 |
|
---|
925 | if(!g_cInit)
|
---|
926 | return USB_NOT_INIT;
|
---|
927 |
|
---|
928 | if(0==ulNumBytes || IsBadWritePointer(pData, ulNumBytes))
|
---|
929 | return ERROR_INVALID_PARAMETER;
|
---|
930 |
|
---|
931 | rc = DosCreateEventSem( NULL,
|
---|
932 | &hEvent,
|
---|
933 | DC_SEM_SHARED,
|
---|
934 | FALSE);
|
---|
935 | if(rc)
|
---|
936 | return rc;
|
---|
937 |
|
---|
938 | IrqStart.ulDevHandle = Handle;
|
---|
939 | IrqStart.ucEndpoint = Endpoint;
|
---|
940 | IrqStart.ucAltInterface = AltInterface;
|
---|
941 | IrqStart.usStatus = 0;
|
---|
942 | IrqStart.ulEvent = hEvent;
|
---|
943 | ulParmLen = sizeof(IrqStart);
|
---|
944 | ulDataLen = ulNumBytes;
|
---|
945 |
|
---|
946 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
947 | IOCAT_USBRES, IOCTLF_START_IRQ_PROC,
|
---|
948 | (PVOID)&IrqStart, ulParmLen, &ulParmLen,
|
---|
949 | pData, ulDataLen,&ulDataLen);
|
---|
950 | if(rc)
|
---|
951 | DosCloseEventSem(hEvent);
|
---|
952 | else
|
---|
953 | *pHevModified = hEvent;
|
---|
954 | return rc;
|
---|
955 | }
|
---|
956 |
|
---|
957 | APIEXPORT APIRET APIENTRY
|
---|
958 | UsbIrqStop( USBHANDLE Handle,
|
---|
959 | HEV HevModified)
|
---|
960 | {
|
---|
961 | APIRET rc;
|
---|
962 | ULONG ulParmLen, ulDataLen;
|
---|
963 |
|
---|
964 | if(!g_cInit)
|
---|
965 | return USB_NOT_INIT;
|
---|
966 |
|
---|
967 | ulParmLen = sizeof(Handle);
|
---|
968 | ulDataLen = sizeof(HevModified);
|
---|
969 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
970 | IOCAT_USBRES, IOCTLF_STOP_IRQ_PROC,
|
---|
971 | (PVOID)&Handle, ulParmLen, &ulParmLen,
|
---|
972 | &HevModified, ulDataLen, &ulDataLen);
|
---|
973 | if(!rc)
|
---|
974 | DosCloseEventSem(HevModified);
|
---|
975 |
|
---|
976 | return rc;
|
---|
977 | }
|
---|
978 |
|
---|
979 | APIEXPORT APIRET APIENTRY
|
---|
980 | UsbIsoStart( USBHANDLE Handle,
|
---|
981 | UCHAR Endpoint,
|
---|
982 | UCHAR AltInterface,
|
---|
983 | ISOHANDLE *phIso)
|
---|
984 | {
|
---|
985 | APIRET rc;
|
---|
986 | PISORINGBUFFER pIter = g_pIsoRingBuffers;
|
---|
987 | USBCALLS_ISO_START IsoStart;
|
---|
988 | ULONG ulParmLen, ulDataLen;
|
---|
989 | int i;
|
---|
990 |
|
---|
991 | if(!g_cInit)
|
---|
992 | return USB_NOT_INIT;
|
---|
993 |
|
---|
994 | rc = DosRequestMutexSem(g_hSemRingBuffers,SEM_INDEFINITE_WAIT);
|
---|
995 | if(rc)
|
---|
996 | return rc;
|
---|
997 |
|
---|
998 | for(i=0;i< g_ulNumIsoRingBuffers;i++,pIter++)
|
---|
999 | {
|
---|
1000 | if (pIter->hDevice==0)
|
---|
1001 | {
|
---|
1002 | pIter->hDevice = Handle;
|
---|
1003 | break;
|
---|
1004 | }
|
---|
1005 | }
|
---|
1006 | DosReleaseMutexSem(g_hSemRingBuffers);
|
---|
1007 |
|
---|
1008 | if(i==g_ulNumIsoRingBuffers)
|
---|
1009 | return USB_ERROR_OUTOF_RESOURCES;
|
---|
1010 |
|
---|
1011 | IsoStart.ulDevHandle = Handle;
|
---|
1012 | IsoStart.ucEndpoint = Endpoint;
|
---|
1013 | IsoStart.ucAltInterface = AltInterface;
|
---|
1014 | ulParmLen = sizeof(IsoStart);
|
---|
1015 | ulDataLen = sizeof(ISORINGBUFFER);
|
---|
1016 |
|
---|
1017 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
1018 | IOCAT_USBRES, IOCTLF_STOP_IRQ_PROC,
|
---|
1019 | (PVOID)&IsoStart, ulParmLen, &ulParmLen,
|
---|
1020 | pIter, ulDataLen, &ulDataLen);
|
---|
1021 | if(rc)
|
---|
1022 | {
|
---|
1023 | pIter->hDevice = 0;
|
---|
1024 | *phIso = 0;
|
---|
1025 | }
|
---|
1026 | else
|
---|
1027 | {
|
---|
1028 | pIter->ucEndpoint = Endpoint;
|
---|
1029 | pIter->ucAltInterface = AltInterface;
|
---|
1030 | }
|
---|
1031 | return rc;
|
---|
1032 | }
|
---|
1033 |
|
---|
1034 | static APIRET IsInvalidIsoHandle(const ISOHANDLE hIso)
|
---|
1035 | {
|
---|
1036 | PISORINGBUFFER pIter;
|
---|
1037 | ULONG i;
|
---|
1038 | pIter = g_pIsoRingBuffers;
|
---|
1039 |
|
---|
1040 | for(i=0;i<g_ulNumIsoRingBuffers;i++,pIter++)
|
---|
1041 | {
|
---|
1042 | if(pIter==(PISORINGBUFFER)hIso && pIter->hDevice)
|
---|
1043 | return 0;
|
---|
1044 | }
|
---|
1045 | return ERROR_INVALID_PARAMETER;
|
---|
1046 | }
|
---|
1047 |
|
---|
1048 | APIEXPORT APIRET APIENTRY
|
---|
1049 | UsbIsoStop( ISOHANDLE hIso)
|
---|
1050 | {
|
---|
1051 |
|
---|
1052 | APIRET rc = NO_ERROR;
|
---|
1053 | if(!g_cInit)
|
---|
1054 | return USB_NOT_INIT;
|
---|
1055 |
|
---|
1056 | /* rc = DosDevIOCtl( g_hUSBDrv, */
|
---|
1057 | return rc;
|
---|
1058 | }
|
---|
1059 |
|
---|
1060 | APIEXPORT APIRET APIENTRY
|
---|
1061 | UsbIsoDequeue( ISOHANDLE hIso,
|
---|
1062 | PVOID pBuffer,
|
---|
1063 | ULONG ulNumBytes)
|
---|
1064 | {
|
---|
1065 | APIRET rc;
|
---|
1066 | PISORINGBUFFER pRB = (PISORINGBUFFER)hIso;
|
---|
1067 |
|
---|
1068 | rc = IsInvalidIsoHandle(hIso);
|
---|
1069 | if(rc)
|
---|
1070 | return rc;
|
---|
1071 | if(!(pRB->ucEndpoint & ISO_DIRMASK))
|
---|
1072 | return ERROR_INVALID_PARAMETER;
|
---|
1073 |
|
---|
1074 | return rc;
|
---|
1075 | }
|
---|
1076 |
|
---|
1077 | APIEXPORT APIRET APIENTRY
|
---|
1078 | UsbIsoPeekQueue( ISOHANDLE hIso,
|
---|
1079 | UCHAR * pByte,
|
---|
1080 | ULONG ulOffset)
|
---|
1081 | {
|
---|
1082 | APIRET rc;
|
---|
1083 | PISORINGBUFFER pRB = (PISORINGBUFFER)hIso;
|
---|
1084 |
|
---|
1085 | rc = IsInvalidIsoHandle(hIso);
|
---|
1086 | if(rc)
|
---|
1087 | return rc;
|
---|
1088 | if(!(pRB->ucEndpoint & ISO_DIRMASK))
|
---|
1089 | return ERROR_INVALID_PARAMETER;
|
---|
1090 | return rc;
|
---|
1091 | }
|
---|
1092 |
|
---|
1093 | APIEXPORT APIRET APIENTRY
|
---|
1094 | UsbIsoEnqueue( ISOHANDLE hIso,
|
---|
1095 | const UCHAR * pBuffer,
|
---|
1096 | ULONG ulNumBytes)
|
---|
1097 | {
|
---|
1098 | APIRET rc;
|
---|
1099 | PISORINGBUFFER pRB = (PISORINGBUFFER)hIso;
|
---|
1100 |
|
---|
1101 | rc = IsInvalidIsoHandle(hIso);
|
---|
1102 | if(rc)
|
---|
1103 | return rc;
|
---|
1104 | if(pRB->ucEndpoint & ISO_DIRMASK)
|
---|
1105 | return ERROR_INVALID_PARAMETER;
|
---|
1106 |
|
---|
1107 | return rc;
|
---|
1108 | }
|
---|
1109 |
|
---|
1110 | APIEXPORT APIRET APIENTRY
|
---|
1111 | UsbIsoGetLength( ISOHANDLE hIso,
|
---|
1112 | ULONG *pulLength)
|
---|
1113 | {
|
---|
1114 | APIRET rc;
|
---|
1115 | PISORINGBUFFER pRB = (PISORINGBUFFER) hIso;
|
---|
1116 | USHORT ri,wi;
|
---|
1117 |
|
---|
1118 | rc = IsInvalidIsoHandle(hIso);
|
---|
1119 | if(rc)
|
---|
1120 | return rc;
|
---|
1121 | wi = pRB->usPosWrite;
|
---|
1122 | ri = pRB->usPosRead;
|
---|
1123 |
|
---|
1124 | if (ri == wi)
|
---|
1125 | *pulLength = 0;
|
---|
1126 | else if (ri < wi)
|
---|
1127 | *pulLength = wi - ri;
|
---|
1128 | else
|
---|
1129 | *pulLength = wi + (pRB->usBufSize - ri);
|
---|
1130 |
|
---|
1131 | return 0;
|
---|
1132 | }
|
---|
1133 |
|
---|
1134 | APIEXPORT APIRET APIENTRY
|
---|
1135 | UsbIrqRead( USBHANDLE Handle,
|
---|
1136 | UCHAR Endpoint,
|
---|
1137 | UCHAR AltInterface,
|
---|
1138 | ULONG *ulNumBytes,
|
---|
1139 | PVOID pData,
|
---|
1140 | ULONG ulTimeout)
|
---|
1141 | {
|
---|
1142 | APIRET rc;
|
---|
1143 | ULONG ulParmLen, ulDataLen;
|
---|
1144 | LIBUSB_IRQ_REQ IrqRequest;
|
---|
1145 |
|
---|
1146 | if(!g_cInit)
|
---|
1147 | return USB_NOT_INIT;
|
---|
1148 |
|
---|
1149 | /* 10 01 2003 - KIEWITZ -> Still @@ToDo Add Endpoint check based on descriptors
|
---|
1150 | We currently only allow Endpoint-addresses 80h->8Fh here */
|
---|
1151 | if ((Endpoint<0x80) || (Endpoint>0x8F))
|
---|
1152 | return USB_ERROR_INVALID_ENDPOINT;
|
---|
1153 |
|
---|
1154 | if(*ulNumBytes==0)
|
---|
1155 | return 0;
|
---|
1156 |
|
---|
1157 | IrqRequest.ulDevHandle = Handle;
|
---|
1158 | IrqRequest.ucEndpoint = Endpoint;
|
---|
1159 | IrqRequest.ucAltInterface = AltInterface;
|
---|
1160 | IrqRequest.usStatus = 0;
|
---|
1161 | IrqRequest.ulEvent = 0;
|
---|
1162 | IrqRequest.ulTimeout = ulTimeout;
|
---|
1163 | ulParmLen = sizeof(LIBUSB_IRQ_REQ);
|
---|
1164 | ulDataLen = *ulNumBytes;
|
---|
1165 |
|
---|
1166 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
1167 | IOCAT_USBRES, IOCTLF_SENDIRQURB,
|
---|
1168 | (PVOID)&IrqRequest, ulParmLen, &ulParmLen,
|
---|
1169 | pData, ulDataLen, &ulDataLen);
|
---|
1170 |
|
---|
1171 | if( rc == NO_ERROR )
|
---|
1172 | {
|
---|
1173 | *ulNumBytes = IrqRequest.usDataLen;
|
---|
1174 | } else
|
---|
1175 | {
|
---|
1176 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_INVALID_PARAMETER) )
|
---|
1177 | rc= ERROR_INVALID_PARAMETER;
|
---|
1178 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_GEN_FAILURE) )
|
---|
1179 | rc= IrqRequest.usStatus;
|
---|
1180 | }
|
---|
1181 | return rc;
|
---|
1182 | }
|
---|
1183 |
|
---|
1184 |
|
---|
1185 | APIEXPORT APIRET APIENTRY
|
---|
1186 | UsbFixupDevice( USBHANDLE Handle,
|
---|
1187 | UCHAR ucConfiguration,
|
---|
1188 | UCHAR *pucConfigurationData,
|
---|
1189 | ULONG ulConfigurationLen )
|
---|
1190 | {
|
---|
1191 | LIBUSB_FIXUP request;
|
---|
1192 | ULONG ulParmLen;
|
---|
1193 | APIRET rc;
|
---|
1194 |
|
---|
1195 | request.ulDevHandle= Handle;
|
---|
1196 | request.ucConfiguration= ucConfiguration;
|
---|
1197 | request.usStatus= 0;
|
---|
1198 | ulParmLen= sizeof(LIBUSB_FIXUP);
|
---|
1199 | rc = DosDevIOCtl( g_hUSBDrv,
|
---|
1200 | IOCAT_USBRES, IOCTLF_FIXUPDEVUCE,
|
---|
1201 | (PVOID)&request, ulParmLen, &ulParmLen,
|
---|
1202 | pucConfigurationData, ulConfigurationLen, &ulConfigurationLen);
|
---|
1203 | if( rc != NO_ERROR )
|
---|
1204 | {
|
---|
1205 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_INVALID_PARAMETER) )
|
---|
1206 | rc= ERROR_INVALID_PARAMETER;
|
---|
1207 | if( rc == (ERROR_USER_DEFINED_BASE|ERROR_I24_GEN_FAILURE) )
|
---|
1208 | rc= request.usStatus;
|
---|
1209 | }
|
---|
1210 | return rc;
|
---|
1211 | }
|
---|
1212 |
|
---|
1213 | #ifndef STATIC_USBCALLS
|
---|
1214 | /*+-------------------------------------------------------------------+*/
|
---|
1215 | /*| _CRT_init is the C run-time environment initialization function. |*/
|
---|
1216 | /*|It will return 0 to indicate success and -1 to indicate failure. |*/
|
---|
1217 | /*+-------------------------------------------------------------------+*/
|
---|
1218 |
|
---|
1219 | /* int _CRT_init (void); */
|
---|
1220 |
|
---|
1221 | /*+-------------------------------------------------------------------+*/
|
---|
1222 | /*| _CRT_term is the C run-time environment termination function. |*/
|
---|
1223 | /*+-------------------------------------------------------------------+*/
|
---|
1224 |
|
---|
1225 | /* void _CRT_term (unsigned long);*/
|
---|
1226 |
|
---|
1227 | /*+-------------------------------------------------------------------+*/
|
---|
1228 | /*| _DLL_InitTerm is the function that gets called by the operating |*/
|
---|
1229 | /*| system loader when it loads and frees this DLL for each process |*/
|
---|
1230 | /*| that accesses this DLL. However, it only gets called the first |*/
|
---|
1231 | /*| time the DLL is loaded and the last time it is freed for a |*/
|
---|
1232 | /*| particular process. The system linkage convention must be used |*/
|
---|
1233 | /*| because the operating system loader is calling this function. |*/
|
---|
1234 | /*+-------------------------------------------------------------------+*/
|
---|
1235 |
|
---|
1236 | #ifdef STATIC_LINK
|
---|
1237 | int _CRT_init (void);
|
---|
1238 | void _CRT_term(0UL);
|
---|
1239 | #endif
|
---|
1240 |
|
---|
1241 | unsigned long _System _DLL_InitTerm (unsigned long modhandle, unsigned long flag)
|
---|
1242 | {
|
---|
1243 |
|
---|
1244 | /* If flag is zero then the DLL is being loaded so initialization */
|
---|
1245 | /* should be performed. If flag is 1 then the DLL is being freed */
|
---|
1246 | /* so termination should be performed. */
|
---|
1247 |
|
---|
1248 | switch (flag)
|
---|
1249 | {
|
---|
1250 | case 0:
|
---|
1251 | /* The C run-time environment initialization function must */
|
---|
1252 | /* be called before any calls to C run-time functions that */
|
---|
1253 | /* are not inlined. */
|
---|
1254 |
|
---|
1255 | #ifdef STATIC_LINK
|
---|
1256 | if (_CRT_init () == -1)
|
---|
1257 | return 0UL;
|
---|
1258 | #endif
|
---|
1259 | InitUsbCalls();
|
---|
1260 | break;
|
---|
1261 |
|
---|
1262 | case 1:
|
---|
1263 | TermUsbCalls();
|
---|
1264 | #ifdef STATIC_LINK
|
---|
1265 | _CRT_term(0UL);
|
---|
1266 | #endif
|
---|
1267 | break;
|
---|
1268 |
|
---|
1269 | default:
|
---|
1270 | return 0UL;
|
---|
1271 |
|
---|
1272 | }
|
---|
1273 |
|
---|
1274 | /* A nonzero value must be returned to indicate success. */
|
---|
1275 | return 1UL;
|
---|
1276 | }
|
---|
1277 | #endif /* !STATIC_USBCALLS */
|
---|
1278 |
|
---|