VirtualBox

source: vbox/trunk/src/VBox/Main/os2/USBProxyServiceOs2.cpp@ 31891

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

Main: export USBProxyService and USBFilter to OSE

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 7.8 KB
 
1/* $Id: USBProxyServiceOs2.cpp 31891 2010-08-24 07:58:48Z vboxsync $ */
2/** @file
3 * VirtualBox USB Proxy Service, OS/2 Specialization.
4 */
5
6/*
7 * Copyright (C) 2006-2010 Oracle Corporation
8 *
9 * Oracle Corporation confidential
10 * All rights reserved
11 */
12
13
14/*******************************************************************************
15* Header Files *
16*******************************************************************************/
17#define INCL_BASE
18#define INCL_ERRORS
19#include "USBProxyService.h"
20#include "Logging.h"
21
22#include <VBox/usb.h>
23#include <VBox/err.h>
24
25#include <iprt/string.h>
26#include <iprt/alloc.h>
27#include <iprt/assert.h>
28#include <iprt/file.h>
29#include <iprt/err.h>
30
31
32/**
33 * Initialize data members.
34 */
35USBProxyServiceOs2::USBProxyServiceOs2 (Host *aHost)
36 : USBProxyService (aHost), mhev (NULLHANDLE), mhmod (NULLHANDLE),
37 mpfnUsbRegisterChangeNotification (NULL), mpfnUsbDeregisterNotification (NULL),
38 mpfnUsbQueryNumberDevices (NULL), mpfnUsbQueryDeviceReport (NULL)
39{
40 LogFlowThisFunc(("aHost=%p\n", aHost));
41
42 /*
43 * Try initialize the usbcalls stuff.
44 */
45 int rc = DosCreateEventSem (NULL, &mhev, 0, FALSE);
46 rc = RTErrConvertFromOS2 (rc);
47 if (RT_SUCCESS(rc))
48 {
49 rc = DosLoadModule (NULL, 0, (PCSZ)"usbcalls", &mhmod);
50 rc = RTErrConvertFromOS2 (rc);
51 if (RT_SUCCESS(rc))
52 {
53 if ( (rc = DosQueryProcAddr (mhmod, 0, (PCSZ)"UsbQueryNumberDevices", (PPFN)&mpfnUsbQueryNumberDevices)) == NO_ERROR
54 && (rc = DosQueryProcAddr (mhmod, 0, (PCSZ)"UsbQueryDeviceReport", (PPFN)&mpfnUsbQueryDeviceReport)) == NO_ERROR
55 && (rc = DosQueryProcAddr (mhmod, 0, (PCSZ)"UsbRegisterChangeNotification", (PPFN)&mpfnUsbRegisterChangeNotification)) == NO_ERROR
56 && (rc = DosQueryProcAddr (mhmod, 0, (PCSZ)"UsbDeregisterNotification", (PPFN)&mpfnUsbDeregisterNotification)) == NO_ERROR
57 )
58 {
59 rc = mpfnUsbRegisterChangeNotification (&mNotifyId, mhev, mhev);
60 if (!rc)
61 {
62 /*
63 * Start the poller thread.
64 */
65 rc = start();
66 if (RT_SUCCESS(rc))
67 {
68 LogFlowThisFunc(("returns successfully - mNotifyId=%d\n", mNotifyId));
69 mLastError = VINF_SUCCESS;
70 return;
71 }
72 }
73
74 LogRel (("USBProxyServiceOs2: failed to register change notification, rc=%d\n", rc));
75 }
76 else
77 LogRel (("USBProxyServiceOs2: failed to load usbcalls\n"));
78
79 DosFreeModule (mhmod);
80 }
81 else
82 LogRel (("USBProxyServiceOs2: failed to load usbcalls, rc=%d\n", rc));
83 mhmod = NULLHANDLE;
84 }
85 else
86 mhev = NULLHANDLE;
87
88 mLastError = rc;
89 LogFlowThisFunc(("returns failure!!! (rc=%Rrc)\n", rc));
90}
91
92
93/**
94 * Stop all service threads and free the device chain.
95 */
96USBProxyServiceOs2::~USBProxyServiceOs2()
97{
98 LogFlowThisFunc(("\n"));
99
100 /*
101 * Stop the service.
102 */
103 if (isActive())
104 stop();
105
106 /*
107 * Free resources.
108 */
109 if (mhmod)
110 {
111 if (mpfnUsbDeregisterNotification)
112 mpfnUsbDeregisterNotification (mNotifyId);
113
114 mpfnUsbRegisterChangeNotification = NULL;
115 mpfnUsbDeregisterNotification = NULL;
116 mpfnUsbQueryNumberDevices = NULL;
117 mpfnUsbQueryDeviceReport = NULL;
118
119 DosFreeModule (mhmod);
120 mhmod = NULLHANDLE;
121 }
122}
123
124
125int USBProxyServiceOs2::captureDevice (HostUSBDevice *aDevice)
126{
127 Log (("USBProxyServiceOs2::captureDevice: %p\n", aDevice));
128 AssertReturn(aDevice, VERR_GENERAL_FAILURE);
129 AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
130
131 /*
132 * Don't think we need to do anything when the device is held... fake it.
133 */
134 Assert(aDevice->isStatePending());
135 interruptWait();
136
137 return VINF_SUCCESS;
138}
139
140
141int USBProxyServiceOs2::releaseDevice (HostUSBDevice *aDevice)
142{
143 Log (("USBProxyServiceOs2::releaseDevice: %p\n", aDevice));
144 AssertReturn(aDevice, VERR_GENERAL_FAILURE);
145 AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
146
147 /*
148 * We're not really holding it atm., just fake it.
149 */
150 Assert(aDevice->isStatePending());
151 interruptWait();
152
153 return VINF_SUCCESS;
154}
155
156
157bool USBProxyServiceOs2::updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine)
158{
159 return updateDeviceStateFake(aDevice, aUSBDevice, aRunFilters, aIgnoreMachine);
160}
161
162
163
164int USBProxyServiceOs2::wait(RTMSINTERVAL aMillies)
165{
166 int rc = DosWaitEventSem(mhev, aMillies);
167 return RTErrConvertFromOS2(rc);
168}
169
170
171int USBProxyServiceOs2::interruptWait (void)
172{
173 int rc = DosPostEventSem (mhev);
174 return rc == NO_ERROR || rc == ERROR_ALREADY_POSTED
175 ? VINF_SUCCESS
176 : RTErrConvertFromOS2 (rc);
177}
178
179#include <stdio.h>
180
181PUSBDEVICE USBProxyServiceOs2::getDevices (void)
182{
183 /*
184 * Count the devices.
185 */
186 ULONG cDevices = 0;
187 int rc = mpfnUsbQueryNumberDevices ((PULONG)&cDevices); /* Thanks to com/xpcom, PULONG and ULONG * aren't the same. */
188 if (rc)
189 return NULL;
190
191 /*
192 * Retrieve information about each device.
193 */
194 PUSBDEVICE pFirst = NULL;
195 PUSBDEVICE *ppNext = &pFirst;
196 for (ULONG i = 0; i < cDevices; i++)
197 {
198 /*
199 * Query the device and config descriptors.
200 */
201 uint8_t abBuf[1024];
202 ULONG cb = sizeof(abBuf);
203 rc = mpfnUsbQueryDeviceReport(i + 1, (PULONG)&cb, &abBuf[0]); /* see above (PULONG) */
204 if (rc)
205 continue;
206 PUSBDEVICEDESC pDevDesc = (PUSBDEVICEDESC)&abBuf[0];
207 if ( cb < sizeof(*pDevDesc)
208 || pDevDesc->bDescriptorType != USB_DT_DEVICE
209 || pDevDesc->bLength < sizeof(*pDevDesc)
210 || pDevDesc->bLength > sizeof(*pDevDesc) * 2)
211 continue;
212 PUSBCONFIGDESC pCfgDesc = (PUSBCONFIGDESC)&abBuf[pDevDesc->bLength];
213 if ( pCfgDesc->bDescriptorType != USB_DT_CONFIG
214 || pCfgDesc->bLength >= sizeof(*pCfgDesc))
215 pCfgDesc = NULL;
216
217 /*
218 * Skip it if it's some kind of hub.
219 */
220 if (pDevDesc->bDeviceClass == USB_HUB_CLASSCODE)
221 continue;
222
223 /*
224 * Allocate a new device node and initialize it with the basic stuff.
225 */
226 PUSBDEVICE pCur = (PUSBDEVICE)RTMemAlloc(sizeof(*pCur));
227 pCur->bcdUSB = pDevDesc->bcdUSB;
228 pCur->bDeviceClass = pDevDesc->bDeviceClass;
229 pCur->bDeviceSubClass = pDevDesc->bDeviceSubClass;
230 pCur->bDeviceProtocol = pDevDesc->bDeviceProtocol;
231 pCur->idVendor = pDevDesc->idVendor;
232 pCur->idProduct = pDevDesc->idProduct;
233 pCur->bcdDevice = pDevDesc->bcdDevice;
234 pCur->pszManufacturer = RTStrDup("");
235 pCur->pszProduct = RTStrDup("");
236 pCur->pszSerialNumber = NULL;
237 pCur->u64SerialHash = 0;
238 //pCur->bNumConfigurations = pDevDesc->bNumConfigurations;
239 pCur->bNumConfigurations = 0;
240 pCur->paConfigurations = NULL;
241 pCur->enmState = USBDEVICESTATE_USED_BY_HOST_CAPTURABLE;
242 pCur->enmSpeed = USBDEVICESPEED_UNKNOWN;
243 pCur->pszAddress = NULL;
244 RTStrAPrintf((char **)&pCur->pszAddress, "p=0x%04RX16;v=0x%04RX16;r=0x%04RX16;e=0x%08RX32",
245 pDevDesc->idProduct, pDevDesc->idVendor, pDevDesc->bcdDevice, i);
246
247 pCur->bBus = 0;
248 pCur->bLevel = 0;
249 pCur->bDevNum = 0;
250 pCur->bDevNumParent = 0;
251 pCur->bPort = 0;
252 pCur->bNumDevices = 0;
253 pCur->bMaxChildren = 0;
254
255 /* link it */
256 pCur->pNext = NULL;
257 pCur->pPrev = *ppNext;
258 *ppNext = pCur;
259 ppNext = &pCur->pNext;
260 }
261
262 return pFirst;
263}
264
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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