VirtualBox

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

Last change on this file since 96407 was 96407, checked in by vboxsync, 2 years ago

scm copyright and license note update

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