VirtualBox

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

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

Main: Add API to IHost for adding and removing USB device sources in addition to the default host one (only USB/IP backend supported so far which will be used in the future for automatic USB testing). Add support for it in VBoxManage

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

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