VirtualBox

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

Last change on this file since 61202 was 60758, checked in by vboxsync, 9 years ago

Main/{USBProxyBackend|HostUSBDeviceImpl}: Don't hardcode certain host OS specific behavior during attach/release now that we can mix several backends with different requirements but make the backends report which behavior they need (should fix USB testing on Windows, OS X and Solaris hosts)

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