VirtualBox

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

最後變更 在這個檔案從60107是 60107,由 vboxsync 提交於 9 年 前

Main/USBProxyService: Save any additional USB device sources in the global configuration and load them during startup

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 14.2 KB
 
1/* $Id: USBProxyBackend.h 60107 2016-03-19 10:22:46Z 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.alldomusa.eu.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 /** @name Interface for the USBController and the Host object.
60 * @{ */
61 virtual void *insertFilter(PCUSBFILTER aFilter);
62 virtual void removeFilter(void *aId);
63 /** @} */
64
65 /** @name Interfaces for the HostUSBDevice
66 * @{ */
67 virtual int captureDevice(HostUSBDevice *aDevice);
68 virtual void captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
69 /** @todo unused */
70 virtual void detachingDevice(HostUSBDevice *aDevice);
71 virtual int releaseDevice(HostUSBDevice *aDevice);
72 virtual void releaseDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
73 /** @} */
74
75 static void freeDevice(PUSBDEVICE pDevice);
76
77 HRESULT runAllFiltersOnDevice(ComObjPtr<HostUSBDevice> &aDevice,
78 SessionMachinesList &llOpenedMachines,
79 SessionMachine *aIgnoreMachine);
80 bool runMachineFilters(SessionMachine *aMachine, ComObjPtr<HostUSBDevice> &aDevice);
81
82 virtual void deviceAdded(ComObjPtr<HostUSBDevice> &aDevice, SessionMachinesList &llOpenedMachines, PUSBDEVICE aUSBDevice);
83 virtual void deviceRemoved(ComObjPtr<HostUSBDevice> &aDevice);
84 virtual void deviceChanged(ComObjPtr<HostUSBDevice> &aDevice, SessionMachinesList *pllOpenedMachines, SessionMachine *aIgnoreMachine);
85 virtual bool updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
86
87protected:
88 int start(void);
89 int stop(void);
90 virtual void serviceThreadInit(void);
91 virtual void serviceThreadTerm(void);
92
93 virtual int wait(RTMSINTERVAL aMillies);
94 virtual int interruptWait(void);
95 virtual PUSBDEVICE getDevices(void);
96 bool updateDeviceStateFake(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
97 uint32_t incRef();
98 uint32_t decRef();
99
100 static HRESULT setError(HRESULT aResultCode, const char *aText, ...);
101
102 static void initFilterFromDevice(PUSBFILTER aFilter, HostUSBDevice *aDevice);
103 static void freeDeviceMembers(PUSBDEVICE pDevice);
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
113protected:
114 /** Pointer to the owning USB Proxy Service object. */
115 USBProxyService *m_pUsbProxyService;
116 /** Thread handle of the service thread. */
117 RTTHREAD mThread;
118 /** Flag which stop() sets to cause serviceThread to return. */
119 bool volatile mTerminate;
120 /** Id of the instance. */
121 const com::Utf8Str m_strId;
122 /** Address of the instance. */
123 const com::Utf8Str m_strAddress;
124 /** Backend identifier as used in the settings. */
125 const com::Utf8Str m_strBackend;
126 /** Reference counter which prevents the backend instance from being removed. */
127 uint32_t m_cRefs;
128};
129
130
131# ifdef RT_OS_DARWIN
132# include <VBox/param.h>
133# undef PAGE_SHIFT
134# undef PAGE_SIZE
135# define OSType Carbon_OSType
136# include <Carbon/Carbon.h>
137# undef OSType
138
139/**
140 * The Darwin hosted USB Proxy Backend.
141 */
142class USBProxyBackendDarwin : public USBProxyBackend
143{
144public:
145 DECLARE_EMPTY_CTOR_DTOR (USBProxyBackendDarwin)
146
147 int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress);
148 void uninit();
149
150 const com::Utf8Str &i_getBackend();
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 /** @todo unused */
158 virtual void detachingDevice(HostUSBDevice *aDevice);
159 virtual int releaseDevice(HostUSBDevice *aDevice);
160 virtual void releaseDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
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 virtual bool updateDeviceState (HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
169
170private:
171 /** Reference to the runloop of the service thread.
172 * This is NULL if the service thread isn't running. */
173 CFRunLoopRef mServiceRunLoopRef;
174 /** The opaque value returned by DarwinSubscribeUSBNotifications. */
175 void *mNotifyOpaque;
176 /** A hack to work around the problem with the usb device enumeration
177 * not including newly attached devices. */
178 bool mWaitABitNextTime;
179 /** Whether we've successfully initialized the USBLib and should call USBLibTerm in the destructor. */
180 bool mUSBLibInitialized;
181};
182# endif /* RT_OS_DARWIN */
183
184
185# ifdef RT_OS_LINUX
186# include <stdio.h>
187# ifdef VBOX_USB_WITH_SYSFS
188# include <HostHardwareLinux.h>
189# endif
190
191/**
192 * The Linux hosted USB Proxy Backend.
193 */
194class USBProxyBackendLinux: public USBProxyBackend
195{
196public:
197 DECLARE_EMPTY_CTOR_DTOR (USBProxyBackendLinux)
198
199 int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress);
200 void uninit();
201
202 virtual int captureDevice(HostUSBDevice *aDevice);
203 virtual int releaseDevice(HostUSBDevice *aDevice);
204
205protected:
206 int initUsbfs(void);
207 int initSysfs(void);
208 void doUsbfsCleanupAsNeeded(void);
209 virtual int wait(RTMSINTERVAL aMillies);
210 virtual int interruptWait(void);
211 virtual PUSBDEVICE getDevices(void);
212 virtual void deviceAdded(ComObjPtr<HostUSBDevice> &aDevice, SessionMachinesList &llOpenedMachines, PUSBDEVICE aUSBDevice);
213 virtual bool updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
214
215private:
216 int waitUsbfs(RTMSINTERVAL aMillies);
217 int waitSysfs(RTMSINTERVAL aMillies);
218
219private:
220 /** File handle to the '/proc/bus/usb/devices' file. */
221 RTFILE mhFile;
222 /** Pipe used to interrupt wait(), the read end. */
223 RTPIPE mhWakeupPipeR;
224 /** Pipe used to interrupt wait(), the write end. */
225 RTPIPE mhWakeupPipeW;
226 /** The root of usbfs. */
227 Utf8Str mDevicesRoot;
228 /** Whether we're using <mUsbfsRoot>/devices or /sys/whatever. */
229 bool mUsingUsbfsDevices;
230 /** Number of 500ms polls left to do. See usbDeterminState for details. */
231 unsigned mUdevPolls;
232# ifdef VBOX_USB_WITH_SYSFS
233 /** Object used for polling for hotplug events from hal. */
234 VBoxMainHotplugWaiter *mpWaiter;
235# endif
236};
237# endif /* RT_OS_LINUX */
238
239
240# ifdef RT_OS_OS2
241# include <usbcalls.h>
242
243/**
244 * The Linux hosted USB Proxy Backend.
245 */
246class USBProxyBackendOs2 : public USBProxyBackend
247{
248public:
249 DECLARE_EMPTY_CTOR_DTOR (USBProxyBackend)
250
251 virtual int captureDevice (HostUSBDevice *aDevice);
252 virtual int releaseDevice (HostUSBDevice *aDevice);
253
254protected:
255 virtual int wait(RTMSINTERVAL aMillies);
256 virtual int interruptWait(void);
257 virtual PUSBDEVICE getDevices(void);
258 int addDeviceToChain(PUSBDEVICE pDev, PUSBDEVICE *ppFirst, PUSBDEVICE **pppNext, int rc);
259 virtual bool updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
260
261private:
262 /** The notification event semaphore */
263 HEV mhev;
264 /** The notification id. */
265 USBNOTIFY mNotifyId;
266 /** The usbcalls.dll handle. */
267 HMODULE mhmod;
268 /** UsbRegisterChangeNotification */
269 APIRET (APIENTRY *mpfnUsbRegisterChangeNotification)(PUSBNOTIFY, HEV, HEV);
270 /** UsbDeregisterNotification */
271 APIRET (APIENTRY *mpfnUsbDeregisterNotification)(USBNOTIFY);
272 /** UsbQueryNumberDevices */
273 APIRET (APIENTRY *mpfnUsbQueryNumberDevices)(PULONG);
274 /** UsbQueryDeviceReport */
275 APIRET (APIENTRY *mpfnUsbQueryDeviceReport)(ULONG, PULONG, PVOID);
276};
277# endif /* RT_OS_LINUX */
278
279
280# ifdef RT_OS_SOLARIS
281# include <libdevinfo.h>
282
283/**
284 * The Solaris hosted USB Proxy Backend.
285 */
286class USBProxyBackendSolaris : public USBProxyBackend
287{
288public:
289 DECLARE_EMPTY_CTOR_DTOR (USBProxyBackendSolaris)
290
291 int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress);
292 void uninit();
293
294 virtual void *insertFilter (PCUSBFILTER aFilter);
295 virtual void removeFilter (void *aID);
296
297 virtual int captureDevice (HostUSBDevice *aDevice);
298 virtual int releaseDevice (HostUSBDevice *aDevice);
299 virtual void captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
300 virtual void releaseDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
301
302protected:
303 virtual int wait(RTMSINTERVAL aMillies);
304 virtual int interruptWait(void);
305 virtual PUSBDEVICE getDevices(void);
306 virtual bool updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
307
308private:
309 RTSEMEVENT mNotifyEventSem;
310 /** Whether we've successfully initialized the USBLib and should call USBLibTerm in the destructor. */
311 bool mUSBLibInitialized;
312};
313#endif /* RT_OS_SOLARIS */
314
315
316# ifdef RT_OS_WINDOWS
317/**
318 * The Windows hosted USB Proxy Backend.
319 */
320class USBProxyBackendWindows : public USBProxyBackend
321{
322public:
323 DECLARE_EMPTY_CTOR_DTOR (USBProxyBackendWindows)
324
325 int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress);
326 void uninit();
327
328 virtual void *insertFilter (PCUSBFILTER aFilter);
329 virtual void removeFilter (void *aID);
330
331 virtual int captureDevice (HostUSBDevice *aDevice);
332 virtual int releaseDevice (HostUSBDevice *aDevice);
333
334protected:
335 virtual int wait(RTMSINTERVAL aMillies);
336 virtual int interruptWait(void);
337 virtual PUSBDEVICE getDevices(void);
338 virtual bool updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
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 virtual bool updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
370
371private:
372 RTSEMEVENT mNotifyEventSem;
373};
374# endif /* RT_OS_FREEBSD */
375
376/**
377 * USB/IP Proxy receive state.
378 */
379typedef enum USBIPRECVSTATE
380{
381 /** Invalid state. */
382 kUsbIpRecvState_Invalid = 0,
383 /** There is no request waiting for an answer. */
384 kUsbIpRecvState_None,
385 /** Waiting for the complete reception of UsbIpRetDevList. */
386 kUsbIpRecvState_Hdr,
387 /** Waiting for the complete reception of a UsbIpExportedDevice structure. */
388 kUsbIpRecvState_ExportedDevice,
389 /** Waiting for a complete reception of a UsbIpDeviceInterface structure to skip. */
390 kUsbIpRecvState_DeviceInterface,
391 /** 32bit hack. */
392 kUsbIpRecvState_32Bit_Hack = 0x7fffffff
393} USBIPRECVSTATE;
394/** Pointer to a USB/IP receive state enum. */
395typedef USBIPRECVSTATE *PUSBIPRECVSTATE;
396
397struct UsbIpExportedDevice;
398
399/**
400 * The USB/IP Proxy Backend.
401 */
402class USBProxyBackendUsbIp: public USBProxyBackend
403{
404public:
405 DECLARE_EMPTY_CTOR_DTOR (USBProxyBackendUsbIp)
406
407 int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress);
408 void uninit();
409
410 virtual int captureDevice(HostUSBDevice *aDevice);
411 virtual int releaseDevice(HostUSBDevice *aDevice);
412
413protected:
414 virtual int wait(RTMSINTERVAL aMillies);
415 virtual int interruptWait(void);
416 virtual PUSBDEVICE getDevices(void);
417 virtual bool updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
418
419private:
420 int updateDeviceList(bool *pfDeviceListChanged);
421 bool hasDevListChanged(PUSBDEVICE pDevices);
422 void freeDeviceList(PUSBDEVICE pHead);
423 void resetRecvState();
424 int reconnect();
425 void disconnect();
426 int startListExportedDevicesReq();
427 void advanceState(USBIPRECVSTATE enmRecvState);
428 int receiveData();
429 int processData();
430 int addDeviceToList(UsbIpExportedDevice *pDev);
431
432 struct Data; // opaque data struct, defined in USBProxyBackendUsbIp.cpp
433 Data *m;
434};
435
436#endif /* !____H_USBPROXYBACKEND */
437
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette