VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxUSB/os2/usbcalls.c@ 101359

Last change on this file since 101359 was 73066, checked in by vboxsync, 6 years ago

VBoxUSB/os2: use NO_ERROR instead of literal 0 in previous.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 34.6 KB
Line 
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
84typedef 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
101typedef struct{
102 ULONG ulSize;
103 ULONG ulCaps;
104 ULONG ulSemDeviceAdd;
105 ULONG ulSemDeviceRemove;
106} STATUSEVENTSET, * PSTATUSEVENTSET;
107
108
109typedef 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
120typedef 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
129typedef 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
139typedef 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
151typedef 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
164typedef 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
176typedef USBCALLS_ISO_START USBCALLS_ISO_STOP, * NPUSBCALLS_ISO_STOP, FAR *PUSBCALLS_ISO_STOP;
177typedef USBCALLS_ISO_START USBCALLS_IRQ_STOP, * NPUSBCALLS_IRQ_STOP, FAR *PUSBCALLS_IRQ_STOP;
178
179#define USB_TRANSFER_FULL_SIZE 0x01
180
181typedef 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
195typedef 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
207typedef 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
219HFILE g_hUSBDrv;
220ULONG g_cInit;
221ULONG g_ulFreeNotifys;
222HMTX g_hSemNotifytable;
223NOTIFYENTRY g_Notifications[MAX_NOTIFICATIONS];
224
225HMTX g_hSemRingBuffers;
226PISORINGBUFFER g_pIsoRingBuffers;
227ULONG g_ulNumIsoRingBuffers;
228
229APIEXPORT APIRET APIENTRY
230InitUsbCalls(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
311APIEXPORT APIRET APIENTRY
312TermUsbCalls(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
342static 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
351static 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
361APIEXPORT APIRET APIENTRY
362UsbQueryNumberDevices(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
380APIEXPORT APIRET APIENTRY
381UsbQueryDeviceReport(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
404APIEXPORT APIRET APIENTRY
405UsbRegisterChangeNotification( 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
480APIEXPORT APIRET APIENTRY
481UsbRegisterDeviceNotification( 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
563APIEXPORT APIRET APIENTRY
564UsbDeregisterNotification( 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
645APIEXPORT APIRET APIENTRY
646UsbOpen( 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
680APIEXPORT APIRET APIENTRY
681UsbClose( 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
698APIEXPORT APIRET APIENTRY
699UsbCtrlMessage( 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
741APIEXPORT APIRET APIENTRY
742UsbBulkRead( 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
752APIEXPORT APIRET APIENTRY
753UsbBulkRead2( 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
836APIEXPORT APIRET APIENTRY
837UsbBulkWrite( 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
847APIEXPORT APIRET APIENTRY
848UsbBulkWrite2( 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
912APIRET APIENTRY
913UsbIrqStart( 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
957APIEXPORT APIRET APIENTRY
958UsbIrqStop( 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
979APIEXPORT APIRET APIENTRY
980UsbIsoStart( 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
1034static 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
1048APIEXPORT APIRET APIENTRY
1049UsbIsoStop( 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
1060APIEXPORT APIRET APIENTRY
1061UsbIsoDequeue( 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
1077APIEXPORT APIRET APIENTRY
1078UsbIsoPeekQueue( 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
1093APIEXPORT APIRET APIENTRY
1094UsbIsoEnqueue( 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
1110APIEXPORT APIRET APIENTRY
1111UsbIsoGetLength( 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
1134APIEXPORT APIRET APIENTRY
1135UsbIrqRead( 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
1185APIEXPORT APIRET APIENTRY
1186UsbFixupDevice( 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
1237int _CRT_init (void);
1238void _CRT_term(0UL);
1239#endif
1240
1241unsigned 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
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette