VirtualBox

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

Last change on this file since 90434 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

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