VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/os2/USBProxyBackendOs2.cpp@ 61644

Last change on this file since 61644 was 60089, checked in by vboxsync, 9 years ago

Main,VBoxManage: Add API to IHost for adding and removing USB device sources in addition to the default host one (only USB/IP backend supported so far which will be used in the future for automatic USB testing). Add support for it in VBoxManage

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