VirtualBox

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

最後變更 在這個檔案從44809是 33540,由 vboxsync 提交於 14 年 前

*: spelling fixes, thanks Timeless!

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 34.6 KB
 
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
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
479APIEXPORT APIRET APIENTRY
480UsbRegisterDeviceNotification( 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
562APIEXPORT APIRET APIENTRY
563UsbDeregisterNotification( 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
644APIEXPORT APIRET APIENTRY
645UsbOpen( 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
679APIEXPORT APIRET APIENTRY
680UsbClose( 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
697APIEXPORT APIRET APIENTRY
698UsbCtrlMessage( 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
740APIEXPORT APIRET APIENTRY
741UsbBulkRead( 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
751APIEXPORT APIRET APIENTRY
752UsbBulkRead2( 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
835APIEXPORT APIRET APIENTRY
836UsbBulkWrite( 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
846APIEXPORT APIRET APIENTRY
847UsbBulkWrite2( 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
911APIRET APIENTRY
912UsbIrqStart( 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
956APIEXPORT APIRET APIENTRY
957UsbIrqStop( 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
978APIEXPORT APIRET APIENTRY
979UsbIsoStart( 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
1033static 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
1047APIEXPORT APIRET APIENTRY
1048UsbIsoStop( 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
1059APIEXPORT APIRET APIENTRY
1060UsbIsoDequeue( 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
1076APIEXPORT APIRET APIENTRY
1077UsbIsoPeekQueue( 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
1092APIEXPORT APIRET APIENTRY
1093UsbIsoEnqueue( 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
1109APIEXPORT APIRET APIENTRY
1110UsbIsoGetLength( 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
1133APIEXPORT APIRET APIENTRY
1134UsbIrqRead( 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
1184APIEXPORT APIRET APIENTRY
1185UsbFixupDevice( 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
1236int _CRT_init (void);
1237void _CRT_term(0UL);
1238#endif
1239
1240unsigned 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
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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