VirtualBox

source: vbox/trunk/src/VBox/Main/include/USBProxyBackend.h@ 76553

Last change on this file since 76553 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.5 KB
Line 
1/* $Id: USBProxyBackend.h 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * VirtualBox USB Proxy Backend (base) class.
4 */
5
6/*
7 * Copyright (C) 2005-2019 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#ifndef ____H_USBPROXYBACKEND
20#define ____H_USBPROXYBACKEND
21#ifndef RT_WITHOUT_PRAGMA_ONCE
22# pragma once
23#endif
24
25#include <VBox/usb.h>
26#include <VBox/usbfilter.h>
27
28#include <iprt/socket.h>
29#include <iprt/poll.h>
30#include <iprt/semaphore.h>
31#include <iprt/cpp/utils.h>
32
33#include "VirtualBoxBase.h"
34#include "VirtualBoxImpl.h"
35#include "HostUSBDeviceImpl.h"
36#include "USBProxyBackendWrap.h"
37class USBProxyService;
38
39/**
40 * Base class for the USB Proxy Backend.
41 */
42class ATL_NO_VTABLE USBProxyBackend
43 : public USBProxyBackendWrap
44{
45public:
46
47 DECLARE_EMPTY_CTOR_DTOR(USBProxyBackend)
48
49 HRESULT FinalConstruct();
50 void FinalRelease();
51
52 // public initializer/uninitializer for internal purposes only
53 virtual int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId,
54 const com::Utf8Str &strAddress, bool fLoadingSettings);
55 virtual void uninit();
56
57 bool isActive(void);
58 const com::Utf8Str &i_getId();
59 const com::Utf8Str &i_getAddress();
60 virtual const com::Utf8Str &i_getBackend();
61 uint32_t i_getRefCount();
62
63 virtual bool i_isDevReEnumerationRequired();
64
65 /** @name Interface for the USBController and the Host object.
66 * @{ */
67 virtual void *insertFilter(PCUSBFILTER aFilter);
68 virtual void removeFilter(void *aId);
69 /** @} */
70
71 /** @name Interfaces for the HostUSBDevice
72 * @{ */
73 virtual int captureDevice(HostUSBDevice *aDevice);
74 virtual void captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
75 virtual int releaseDevice(HostUSBDevice *aDevice);
76 virtual void releaseDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
77 /** @} */
78
79 static void freeDevice(PUSBDEVICE pDevice);
80
81protected:
82 int start(void);
83 int stop(void);
84 virtual void serviceThreadInit(void);
85 virtual void serviceThreadTerm(void);
86
87 virtual int wait(RTMSINTERVAL aMillies);
88 virtual int interruptWait(void);
89 virtual PUSBDEVICE getDevices(void);
90 uint32_t incRef();
91 uint32_t decRef();
92
93 static HRESULT setError(HRESULT aResultCode, const char *aText, ...);
94
95 static void initFilterFromDevice(PUSBFILTER aFilter, HostUSBDevice *aDevice);
96 static void freeDeviceMembers(PUSBDEVICE pDevice);
97
98 /**
99 * Backend specific callback when a device was added.
100 * (Currently only Linux uses it to adjust the udev polling).
101 */
102 virtual void deviceAdded(ComObjPtr<HostUSBDevice> &aDevice, PUSBDEVICE pDev);
103 virtual bool isFakeUpdateRequired();
104
105private:
106
107 // wrapped IUSBProxyBackend properties
108 HRESULT getName(com::Utf8Str &aName);
109 HRESULT getType(com::Utf8Str &aType);
110
111 static DECLCALLBACK(int) serviceThread(RTTHREAD Thread, void *pvUser);
112
113 void updateDeviceList(PUSBDEVICE pDevices);
114
115protected:
116 /** Pointer to the owning USB Proxy Service object. */
117 USBProxyService *m_pUsbProxyService;
118 /** Thread handle of the service thread. */
119 RTTHREAD mThread;
120 /** Flag which stop() sets to cause serviceThread to return. */
121 bool volatile mTerminate;
122 /** Id of the instance. */
123 const com::Utf8Str m_strId;
124 /** Address of the instance. */
125 const com::Utf8Str m_strAddress;
126 /** Backend identifier as used in the settings. */
127 const com::Utf8Str m_strBackend;
128 /** Reference counter which prevents the backend instance from being removed. */
129 uint32_t m_cRefs;
130 /** List of smart HostUSBDevice pointers. */
131 typedef std::list<ComObjPtr<HostUSBDevice> > HostUSBDeviceList;
132 /** List of the known USB devices for this backend. */
133 HostUSBDeviceList m_llDevices;
134};
135
136
137# if defined(RT_OS_DARWIN) || defined(DOXYGEN_RUNNING)
138# include <VBox/param.h>
139# undef PAGE_SHIFT
140# undef PAGE_SIZE
141# define OSType Carbon_OSType
142# include <Carbon/Carbon.h>
143# undef OSType
144
145/**
146 * The Darwin hosted USB Proxy Backend.
147 */
148class USBProxyBackendDarwin : public USBProxyBackend
149{
150public:
151 DECLARE_EMPTY_CTOR_DTOR(USBProxyBackendDarwin)
152
153 int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId,
154 const com::Utf8Str &strAddress, bool fLoadingSettings);
155 void uninit();
156
157 virtual void *insertFilter(PCUSBFILTER aFilter);
158 virtual void removeFilter(void *aId);
159
160 virtual int captureDevice(HostUSBDevice *aDevice);
161 virtual void captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
162 virtual int releaseDevice(HostUSBDevice *aDevice);
163 virtual void releaseDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
164
165 virtual bool i_isDevReEnumerationRequired();
166
167protected:
168 virtual int wait(RTMSINTERVAL aMillies);
169 virtual int interruptWait (void);
170 virtual PUSBDEVICE getDevices (void);
171 virtual void serviceThreadInit (void);
172 virtual void serviceThreadTerm (void);
173
174private:
175 /** Reference to the runloop of the service thread.
176 * This is NULL if the service thread isn't running. */
177 CFRunLoopRef mServiceRunLoopRef;
178 /** The opaque value returned by DarwinSubscribeUSBNotifications. */
179 void *mNotifyOpaque;
180 /** A hack to work around the problem with the usb device enumeration
181 * not including newly attached devices. */
182 bool mWaitABitNextTime;
183 /** Whether we've successfully initialized the USBLib and should call USBLibTerm in the destructor. */
184 bool mUSBLibInitialized;
185};
186# endif /* RT_OS_DARWIN */
187
188
189# if defined(RT_OS_LINUX) || defined(DOXYGEN_RUNNING)
190# include <stdio.h>
191# ifdef VBOX_USB_WITH_SYSFS
192# include <HostHardwareLinux.h>
193# endif
194
195/**
196 * The Linux hosted USB Proxy Backend.
197 */
198class USBProxyBackendLinux: public USBProxyBackend
199{
200public:
201 DECLARE_EMPTY_CTOR_DTOR(USBProxyBackendLinux)
202
203 int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId,
204 const com::Utf8Str &strAddress, bool fLoadingSettings);
205 void uninit();
206
207 virtual int captureDevice(HostUSBDevice *aDevice);
208 virtual int releaseDevice(HostUSBDevice *aDevice);
209
210protected:
211 int initUsbfs(void);
212 int initSysfs(void);
213 void doUsbfsCleanupAsNeeded(void);
214 virtual int wait(RTMSINTERVAL aMillies);
215 virtual int interruptWait(void);
216 virtual PUSBDEVICE getDevices(void);
217 virtual void deviceAdded(ComObjPtr<HostUSBDevice> &aDevice, PUSBDEVICE aUSBDevice);
218 virtual bool isFakeUpdateRequired();
219
220private:
221 int waitUsbfs(RTMSINTERVAL aMillies);
222 int waitSysfs(RTMSINTERVAL aMillies);
223
224private:
225 /** File handle to the '/proc/bus/usb/devices' file. */
226 RTFILE mhFile;
227 /** Pipe used to interrupt wait(), the read end. */
228 RTPIPE mhWakeupPipeR;
229 /** Pipe used to interrupt wait(), the write end. */
230 RTPIPE mhWakeupPipeW;
231 /** The root of usbfs. */
232 Utf8Str mDevicesRoot;
233 /** Whether we're using \<mUsbfsRoot\>/devices or /sys/whatever. */
234 bool mUsingUsbfsDevices;
235 /** Number of 500ms polls left to do. See usbDeterminState for details. */
236 unsigned mUdevPolls;
237# ifdef VBOX_USB_WITH_SYSFS
238 /** Object used for polling for hotplug events from hal. */
239 VBoxMainHotplugWaiter *mpWaiter;
240# endif
241};
242# endif /* RT_OS_LINUX */
243
244
245# if defined(RT_OS_OS2) || defined(DOXYGEN_RUNNING)
246# include <usbcalls.h>
247
248/**
249 * The Linux hosted USB Proxy Backend.
250 */
251class USBProxyBackendOs2 : public USBProxyBackend
252{
253public:
254 DECLARE_EMPTY_CTOR_DTOR(USBProxyBackendOs2)
255
256 virtual int captureDevice(HostUSBDevice *aDevice);
257 virtual int releaseDevice(HostUSBDevice *aDevice);
258
259protected:
260 virtual int wait(RTMSINTERVAL aMillies);
261 virtual int interruptWait(void);
262 virtual PUSBDEVICE getDevices(void);
263 int addDeviceToChain(PUSBDEVICE pDev, PUSBDEVICE *ppFirst, PUSBDEVICE **pppNext, int rc);
264
265private:
266 /** The notification event semaphore */
267 HEV mhev;
268 /** The notification id. */
269 USBNOTIFY mNotifyId;
270 /** The usbcalls.dll handle. */
271 HMODULE mhmod;
272 /** UsbRegisterChangeNotification */
273 APIRET (APIENTRY *mpfnUsbRegisterChangeNotification)(PUSBNOTIFY, HEV, HEV);
274 /** UsbDeregisterNotification */
275 APIRET (APIENTRY *mpfnUsbDeregisterNotification)(USBNOTIFY);
276 /** UsbQueryNumberDevices */
277 APIRET (APIENTRY *mpfnUsbQueryNumberDevices)(PULONG);
278 /** UsbQueryDeviceReport */
279 APIRET (APIENTRY *mpfnUsbQueryDeviceReport)(ULONG, PULONG, PVOID);
280};
281# endif /* RT_OS_OS2 */
282
283
284# if defined(RT_OS_SOLARIS) || defined(DOXYGEN_RUNNING)
285# include <libdevinfo.h>
286
287/**
288 * The Solaris hosted USB Proxy Backend.
289 */
290class USBProxyBackendSolaris : public USBProxyBackend
291{
292public:
293 DECLARE_EMPTY_CTOR_DTOR(USBProxyBackendSolaris)
294
295 int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId,
296 const com::Utf8Str &strAddress, bool fLoadingSettings);
297 void uninit();
298
299 virtual void *insertFilter (PCUSBFILTER aFilter);
300 virtual void removeFilter (void *aID);
301
302 virtual int captureDevice(HostUSBDevice *aDevice);
303 virtual int releaseDevice(HostUSBDevice *aDevice);
304 virtual void captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
305 virtual void releaseDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
306
307 virtual bool i_isDevReEnumerationRequired();
308
309protected:
310 virtual int wait(RTMSINTERVAL aMillies);
311 virtual int interruptWait(void);
312 virtual PUSBDEVICE getDevices(void);
313
314private:
315 RTSEMEVENT mNotifyEventSem;
316 /** Whether we've successfully initialized the USBLib and should call USBLibTerm in the destructor. */
317 bool mUSBLibInitialized;
318};
319#endif /* RT_OS_SOLARIS */
320
321
322# if defined(RT_OS_WINDOWS) || defined(DOXYGEN_RUNNING)
323/**
324 * The Windows hosted USB Proxy Backend.
325 */
326class USBProxyBackendWindows : public USBProxyBackend
327{
328public:
329 DECLARE_EMPTY_CTOR_DTOR(USBProxyBackendWindows)
330
331 int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId,
332 const com::Utf8Str &strAddress, bool fLoadingSettings);
333 void uninit();
334
335 virtual void *insertFilter (PCUSBFILTER aFilter);
336 virtual void removeFilter (void *aID);
337
338 virtual int captureDevice(HostUSBDevice *aDevice);
339 virtual int releaseDevice(HostUSBDevice *aDevice);
340
341 virtual bool i_isDevReEnumerationRequired();
342
343protected:
344 virtual int wait(RTMSINTERVAL aMillies);
345 virtual int interruptWait(void);
346 virtual PUSBDEVICE getDevices(void);
347
348private:
349
350 HANDLE mhEventInterrupt;
351};
352# endif /* RT_OS_WINDOWS */
353
354# if defined(RT_OS_FREEBSD) || defined(DOXYGEN_RUNNING)
355/**
356 * The FreeBSD hosted USB Proxy Backend.
357 */
358class USBProxyBackendFreeBSD : public USBProxyBackend
359{
360public:
361 DECLARE_EMPTY_CTOR_DTOR(USBProxyBackendFreeBSD)
362
363 int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId,
364 const com::Utf8Str &strAddress, bool fLoadingSettings);
365 void uninit();
366
367 virtual int captureDevice(HostUSBDevice *aDevice);
368 virtual int releaseDevice(HostUSBDevice *aDevice);
369
370protected:
371 int initUsbfs(void);
372 int initSysfs(void);
373 virtual int wait(RTMSINTERVAL aMillies);
374 virtual int interruptWait(void);
375 virtual PUSBDEVICE getDevices(void);
376 int addDeviceToChain(PUSBDEVICE pDev, PUSBDEVICE *ppFirst, PUSBDEVICE **pppNext, int rc);
377 virtual void deviceAdded(ComObjPtr<HostUSBDevice> &aDevice, SessionMachinesList &llOpenedMachines, PUSBDEVICE aUSBDevice);
378
379private:
380 RTSEMEVENT mNotifyEventSem;
381};
382# endif /* RT_OS_FREEBSD */
383
384/**
385 * USB/IP Proxy receive state.
386 */
387typedef enum USBIPRECVSTATE
388{
389 /** Invalid state. */
390 kUsbIpRecvState_Invalid = 0,
391 /** There is no request waiting for an answer. */
392 kUsbIpRecvState_None,
393 /** Waiting for the complete reception of UsbIpRetDevList. */
394 kUsbIpRecvState_Hdr,
395 /** Waiting for the complete reception of a UsbIpExportedDevice structure. */
396 kUsbIpRecvState_ExportedDevice,
397 /** Waiting for a complete reception of a UsbIpDeviceInterface structure to skip. */
398 kUsbIpRecvState_DeviceInterface,
399 /** 32bit hack. */
400 kUsbIpRecvState_32Bit_Hack = 0x7fffffff
401} USBIPRECVSTATE;
402/** Pointer to a USB/IP receive state enum. */
403typedef USBIPRECVSTATE *PUSBIPRECVSTATE;
404
405struct UsbIpExportedDevice;
406
407/**
408 * The USB/IP Proxy Backend.
409 */
410class USBProxyBackendUsbIp: public USBProxyBackend
411{
412public:
413 DECLARE_EMPTY_CTOR_DTOR(USBProxyBackendUsbIp)
414
415 int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId,
416 const com::Utf8Str &strAddress, bool fLoadingSettings);
417 void uninit();
418
419 virtual int captureDevice(HostUSBDevice *aDevice);
420 virtual int releaseDevice(HostUSBDevice *aDevice);
421
422protected:
423 virtual int wait(RTMSINTERVAL aMillies);
424 virtual int interruptWait(void);
425 virtual PUSBDEVICE getDevices(void);
426 virtual bool isFakeUpdateRequired();
427
428private:
429 int updateDeviceList(bool *pfDeviceListChanged);
430 bool hasDevListChanged(PUSBDEVICE pDevices);
431 void freeDeviceList(PUSBDEVICE pHead);
432 void resetRecvState();
433 int reconnect();
434 void disconnect();
435 int startListExportedDevicesReq();
436 void advanceState(USBIPRECVSTATE enmRecvState);
437 int receiveData();
438 int processData();
439 int addDeviceToList(UsbIpExportedDevice *pDev);
440
441 struct Data; // opaque data struct, defined in USBProxyBackendUsbIp.cpp
442 Data *m;
443};
444
445#endif /* !____H_USBPROXYBACKEND */
446
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