VirtualBox

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

Last change on this file since 69731 was 69500, checked in by vboxsync, 7 years ago

*: scm --update-copyright-year

  • 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 69500 2017-10-28 15:14:05Z vboxsync $ */
2/** @file
3 * VirtualBox USB Proxy Service, OS/2 Specialization.
4 */
5
6/*
7 * Copyright (C) 2005-2017 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(("USBProxyBackendOs2: failed to register change notification, rc=%d\n", rc));
80 }
81 else
82 LogRel(("USBProxyBackendOs2: failed to load usbcalls\n"));
83
84 DosFreeModule(mhmod);
85 }
86 else
87 LogRel(("USBProxyBackendOs2: 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 */
101USBProxyBackendOs2::~USBProxyBackendOs2()
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 USBProxyBackendOs2::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 USBProxyBackendOs2::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
168#if 0
169bool USBProxyBackendOs2::updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters,
170 SessionMachine **aIgnoreMachine)
171{
172 AssertReturn(aDevice, false);
173 AssertReturn(!aDevice->isWriteLockOnCurrentThread(), false);
174 return updateDeviceStateFake(aDevice, aUSBDevice, aRunFilters, aIgnoreMachine);
175}
176#endif
177
178
179
180int USBProxyBackendOs2::wait(RTMSINTERVAL aMillies)
181{
182 int rc = DosWaitEventSem(mhev, aMillies);
183 return RTErrConvertFromOS2(rc);
184}
185
186
187int USBProxyBackendOs2::interruptWait(void)
188{
189 int rc = DosPostEventSem(mhev);
190 return rc == NO_ERROR || rc == ERROR_ALREADY_POSTED
191 ? VINF_SUCCESS
192 : RTErrConvertFromOS2(rc);
193}
194
195#include <stdio.h>
196
197PUSBDEVICE USBProxyBackendOs2::getDevices(void)
198{
199 /*
200 * Count the devices.
201 */
202 ULONG cDevices = 0;
203 int rc = mpfnUsbQueryNumberDevices((PULONG)&cDevices); /* Thanks to com/xpcom, PULONG and ULONG * aren't the same. */
204 if (rc)
205 return NULL;
206
207 /*
208 * Retrieve information about each device.
209 */
210 PUSBDEVICE pFirst = NULL;
211 PUSBDEVICE *ppNext = &pFirst;
212 for (ULONG i = 0; i < cDevices; i++)
213 {
214 /*
215 * Query the device and config descriptors.
216 */
217 uint8_t abBuf[1024];
218 ULONG cb = sizeof(abBuf);
219 rc = mpfnUsbQueryDeviceReport(i + 1, (PULONG)&cb, &abBuf[0]); /* see above (PULONG) */
220 if (rc)
221 continue;
222 PUSBDEVICEDESC pDevDesc = (PUSBDEVICEDESC)&abBuf[0];
223 if ( cb < sizeof(*pDevDesc)
224 || pDevDesc->bDescriptorType != USB_DT_DEVICE
225 || pDevDesc->bLength < sizeof(*pDevDesc)
226 || pDevDesc->bLength > sizeof(*pDevDesc) * 2)
227 continue;
228 PUSBCONFIGDESC pCfgDesc = (PUSBCONFIGDESC)&abBuf[pDevDesc->bLength];
229 if ( pCfgDesc->bDescriptorType != USB_DT_CONFIG
230 || pCfgDesc->bLength >= sizeof(*pCfgDesc))
231 pCfgDesc = NULL;
232
233 /*
234 * Skip it if it's some kind of hub.
235 */
236 if (pDevDesc->bDeviceClass == USB_HUB_CLASSCODE)
237 continue;
238
239 /*
240 * Allocate a new device node and initialize it with the basic stuff.
241 */
242 PUSBDEVICE pCur = (PUSBDEVICE)RTMemAlloc(sizeof(*pCur));
243 pCur->bcdUSB = pDevDesc->bcdUSB;
244 pCur->bDeviceClass = pDevDesc->bDeviceClass;
245 pCur->bDeviceSubClass = pDevDesc->bDeviceSubClass;
246 pCur->bDeviceProtocol = pDevDesc->bDeviceProtocol;
247 pCur->idVendor = pDevDesc->idVendor;
248 pCur->idProduct = pDevDesc->idProduct;
249 pCur->bcdDevice = pDevDesc->bcdDevice;
250 pCur->pszManufacturer = RTStrDup("");
251 pCur->pszProduct = RTStrDup("");
252 pCur->pszSerialNumber = NULL;
253 pCur->u64SerialHash = 0;
254 //pCur->bNumConfigurations = pDevDesc->bNumConfigurations;
255 pCur->bNumConfigurations = 0;
256 pCur->paConfigurations = NULL;
257 pCur->enmState = USBDEVICESTATE_USED_BY_HOST_CAPTURABLE;
258 pCur->enmSpeed = USBDEVICESPEED_UNKNOWN;
259 pCur->pszAddress = NULL;
260 RTStrAPrintf((char **)&pCur->pszAddress, "p=0x%04RX16;v=0x%04RX16;r=0x%04RX16;e=0x%08RX32",
261 pDevDesc->idProduct, pDevDesc->idVendor, pDevDesc->bcdDevice, i);
262
263 pCur->bBus = 0;
264 pCur->bLevel = 0;
265 pCur->bDevNum = 0;
266 pCur->bDevNumParent = 0;
267 pCur->bPort = 0;
268 pCur->bNumDevices = 0;
269 pCur->bMaxChildren = 0;
270
271 /* link it */
272 pCur->pNext = NULL;
273 pCur->pPrev = *ppNext;
274 *ppNext = pCur;
275 ppNext = &pCur->pNext;
276 }
277
278 return pFirst;
279}
280
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