VirtualBox

source: vbox/trunk/src/VBox/Main/include/USBProxyService.h@ 31891

Last change on this file since 31891 was 31891, checked in by vboxsync, 14 years ago

Main: export USBProxyService and USBFilter to OSE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.5 KB
Line 
1/* $Id: USBProxyService.h 31891 2010-08-24 07:58:48Z vboxsync $ */
2/** @file
3 * VirtualBox USB Proxy Service (base) class.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Oracle Corporation
8 *
9 * Oracle Corporation confidential
10 * All rights reserved
11 */
12
13
14#ifndef ____H_USBPROXYSERVICE
15#define ____H_USBPROXYSERVICE
16
17#include <VBox/usb.h>
18#include <VBox/usbfilter.h>
19
20#include "VirtualBoxBase.h"
21#include "VirtualBoxImpl.h"
22#include "HostUSBDeviceImpl.h"
23class Host;
24
25/**
26 * Base class for the USB Proxy service.
27 */
28class USBProxyService
29 : public VirtualBoxTranslatable
30{
31public:
32 USBProxyService(Host *aHost);
33 virtual HRESULT init(void);
34 virtual ~USBProxyService();
35
36 /**
37 * Override of the default locking class to be used for validating lock
38 * order with the standard member lock handle.
39 */
40 virtual VBoxLockingClass getLockingClass() const
41 {
42 // the USB proxy service uses the Host object lock, so return the
43 // same locking class as the host
44 return LOCKCLASS_HOSTOBJECT;
45 }
46
47 bool isActive(void);
48 int getLastError(void);
49 HRESULT getLastErrorMessage(BSTR *aError);
50
51 RWLockHandle *lockHandle() const;
52
53 /** @name Host Interfaces
54 * @{ */
55 HRESULT getDeviceCollection(ComSafeArrayOut(IHostUSBDevice *, aUSBDevices));
56 /** @} */
57
58 /** @name SessionMachine Interfaces
59 * @{ */
60 HRESULT captureDeviceForVM(SessionMachine *aMachine, IN_GUID aId);
61 HRESULT detachDeviceFromVM(SessionMachine *aMachine, IN_GUID aId, bool aDone);
62 HRESULT autoCaptureDevicesForVM(SessionMachine *aMachine);
63 HRESULT detachAllDevicesFromVM(SessionMachine *aMachine, bool aDone, bool aAbnormal);
64 /** @} */
65
66 /** @name Interface for the USBController and the Host object.
67 * @{ */
68 virtual void *insertFilter(PCUSBFILTER aFilter);
69 virtual void removeFilter(void *aId);
70 /** @} */
71
72 /** @name Interfaces for the HostUSBDevice
73 * @{ */
74 virtual int captureDevice(HostUSBDevice *aDevice);
75 virtual void captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
76 virtual void detachingDevice(HostUSBDevice *aDevice);
77 virtual int releaseDevice(HostUSBDevice *aDevice);
78 virtual void releaseDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
79 /** @} */
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 virtual void deviceAdded(ComObjPtr<HostUSBDevice> &aDevice, SessionMachinesList &llOpenedMachines, PUSBDEVICE aUSBDevice);
91 virtual void deviceRemoved(ComObjPtr<HostUSBDevice> &aDevice);
92 virtual void deviceChanged(ComObjPtr<HostUSBDevice> &aDevice, SessionMachinesList *pllOpenedMachines, SessionMachine *aIgnoreMachine);
93 bool updateDeviceStateFake(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
94 virtual bool updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
95
96 ComObjPtr<HostUSBDevice> findDeviceById(IN_GUID aId);
97
98 static HRESULT setError(HRESULT aResultCode, const char *aText, ...);
99
100 static void initFilterFromDevice(PUSBFILTER aFilter, HostUSBDevice *aDevice);
101 static void freeDeviceMembers(PUSBDEVICE pDevice);
102public:
103 static void freeDevice(PUSBDEVICE pDevice);
104
105private:
106 HRESULT runAllFiltersOnDevice(ComObjPtr<HostUSBDevice> &aDevice,
107 SessionMachinesList &llOpenedMachines,
108 SessionMachine *aIgnoreMachine);
109 bool runMachineFilters(SessionMachine *aMachine, ComObjPtr<HostUSBDevice> &aDevice);
110 void processChanges(void);
111 static DECLCALLBACK(int) serviceThread(RTTHREAD Thread, void *pvUser);
112
113protected:
114 /** Pointer to the Host object. */
115 Host *mHost;
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 /** VBox status code of the last failure.
121 * (Only used by start(), stop() and the child constructors.) */
122 int mLastError;
123 /** Optional error message to complement mLastError. */
124 Bstr mLastErrorMessage;
125 /** List of smart HostUSBDevice pointers. */
126 typedef std::list<ComObjPtr<HostUSBDevice> > HostUSBDeviceList;
127 /** List of the known USB devices. */
128 HostUSBDeviceList mDevices;
129};
130
131
132# ifdef RT_OS_DARWIN
133# include <VBox/param.h>
134# undef PAGE_SHIFT
135# undef PAGE_SIZE
136# define OSType Carbon_OSType
137# include <Carbon/Carbon.h>
138# undef OSType
139
140/**
141 * The Darwin hosted USB Proxy Service.
142 */
143class USBProxyServiceDarwin : public USBProxyService
144{
145public:
146 USBProxyServiceDarwin(Host *aHost);
147 HRESULT init(void);
148 ~USBProxyServiceDarwin();
149
150#ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
151 virtual void *insertFilter(PCUSBFILTER aFilter);
152 virtual void removeFilter(void *aId);
153#endif
154
155 virtual int captureDevice(HostUSBDevice *aDevice);
156 virtual void captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
157 virtual void detachingDevice(HostUSBDevice *aDevice);
158 virtual int releaseDevice(HostUSBDevice *aDevice);
159 virtual void releaseDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
160
161protected:
162 virtual int wait(RTMSINTERVAL aMillies);
163 virtual int interruptWait (void);
164 virtual PUSBDEVICE getDevices (void);
165 virtual void serviceThreadInit (void);
166 virtual void serviceThreadTerm (void);
167 virtual bool updateDeviceState (HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
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#ifndef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
179 /** Whether we've got a fake async event and should return without entering the runloop. */
180 bool volatile mFakeAsync;
181#endif
182 /** Whether we've successfully initialized the USBLib and should call USBLibTerm in the destructor. */
183 bool mUSBLibInitialized;
184};
185# endif /* RT_OS_DARWIN */
186
187
188# ifdef RT_OS_LINUX
189# include <stdio.h>
190# ifdef VBOX_USB_WITH_SYSFS
191# include <HostHardwareLinux.h>
192# endif
193
194/**
195 * The Linux hosted USB Proxy Service.
196 */
197class USBProxyServiceLinux
198 : public USBProxyService
199{
200public:
201 USBProxyServiceLinux(Host *aHost,
202 const char *aUsbfsRoot = "/proc/bus/usb");
203 HRESULT init(void);
204 ~USBProxyServiceLinux();
205
206 virtual int captureDevice(HostUSBDevice *aDevice);
207 virtual int releaseDevice(HostUSBDevice *aDevice);
208
209protected:
210 int initUsbfs(void);
211 int initSysfs(void);
212 void doUsbfsCleanupAsNeeded(void);
213 virtual int wait(RTMSINTERVAL aMillies);
214 virtual int interruptWait(void);
215 virtual PUSBDEVICE getDevices(void);
216 PUSBDEVICE getDevicesFromUsbfs(void);
217 PUSBDEVICE getDevicesFromSysfs(void);
218 int addDeviceToChain(PUSBDEVICE pDev, PUSBDEVICE *ppFirst, PUSBDEVICE **pppNext, int rc);
219 virtual void deviceAdded(ComObjPtr<HostUSBDevice> &aDevice, SessionMachinesList &llOpenedMachines, PUSBDEVICE aUSBDevice);
220 virtual bool updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
221
222private:
223 int waitUsbfs(RTMSINTERVAL aMillies);
224 int waitSysfs(RTMSINTERVAL aMillies);
225
226private:
227 /** File handle to the '/proc/bus/usb/devices' file. */
228 RTFILE mFile;
229 /** Stream for mFile. */
230 FILE *mStream;
231 /** Pipe used to interrupt wait(), the read end. */
232 RTFILE mWakeupPipeR;
233 /** Pipe used to interrupt wait(), the write end. */
234 RTFILE mWakeupPipeW;
235 /** The root of usbfs. */
236 Utf8Str mUsbfsRoot;
237 /** Whether we're using <mUsbfsRoot>/devices or /sys/whatever. */
238 bool mUsingUsbfsDevices;
239 /** Number of 500ms polls left to do. See usbDeterminState for details. */
240 unsigned mUdevPolls;
241# ifdef VBOX_USB_WITH_SYSFS
242 /** Object used for querying device information from hal. */
243 VBoxMainUSBDeviceInfo mDeviceList;
244 /** Object used for polling for hotplug events from hal. */
245 VBoxMainHotplugWaiter mWaiter;
246# endif
247};
248# endif /* RT_OS_LINUX */
249
250
251# ifdef RT_OS_OS2
252# include <usbcalls.h>
253
254/**
255 * The Linux hosted USB Proxy Service.
256 */
257class USBProxyServiceOs2 : public USBProxyService
258{
259public:
260 USBProxyServiceOs2 (Host *aHost);
261 /// @todo virtual HRESULT init(void);
262 ~USBProxyServiceOs2();
263
264 virtual int captureDevice (HostUSBDevice *aDevice);
265 virtual int releaseDevice (HostUSBDevice *aDevice);
266
267protected:
268 virtual int wait(RTMSINTERVAL aMillies);
269 virtual int interruptWait(void);
270 virtual PUSBDEVICE getDevices(void);
271 int addDeviceToChain(PUSBDEVICE pDev, PUSBDEVICE *ppFirst, PUSBDEVICE **pppNext, int rc);
272 virtual bool updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
273
274private:
275 /** The notification event semaphore */
276 HEV mhev;
277 /** The notification id. */
278 USBNOTIFY mNotifyId;
279 /** The usbcalls.dll handle. */
280 HMODULE mhmod;
281 /** UsbRegisterChangeNotification */
282 APIRET (APIENTRY *mpfnUsbRegisterChangeNotification)(PUSBNOTIFY, HEV, HEV);
283 /** UsbDeregisterNotification */
284 APIRET (APIENTRY *mpfnUsbDeregisterNotification)(USBNOTIFY);
285 /** UsbQueryNumberDevices */
286 APIRET (APIENTRY *mpfnUsbQueryNumberDevices)(PULONG);
287 /** UsbQueryDeviceReport */
288 APIRET (APIENTRY *mpfnUsbQueryDeviceReport)(ULONG, PULONG, PVOID);
289};
290# endif /* RT_OS_LINUX */
291
292
293# ifdef RT_OS_SOLARIS
294# include <libdevinfo.h>
295
296/**
297 * The Solaris hosted USB Proxy Service.
298 */
299class USBProxyServiceSolaris : public USBProxyService
300{
301public:
302 USBProxyServiceSolaris(Host *aHost);
303 HRESULT init(void);
304 ~USBProxyServiceSolaris();
305
306 virtual void *insertFilter (PCUSBFILTER aFilter);
307 virtual void removeFilter (void *aID);
308
309 virtual int captureDevice (HostUSBDevice *aDevice);
310 virtual int releaseDevice (HostUSBDevice *aDevice);
311 virtual void captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
312 virtual void releaseDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
313
314protected:
315 virtual int wait(RTMSINTERVAL aMillies);
316 virtual int interruptWait(void);
317 virtual PUSBDEVICE getDevices(void);
318 virtual bool updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
319
320private:
321 RTSEMEVENT mNotifyEventSem;
322 /** Whether we've successfully initialized the USBLib and should call USBLibTerm in the destructor. */
323 bool mUSBLibInitialized;
324};
325#endif /* RT_OS_SOLARIS */
326
327
328# ifdef RT_OS_WINDOWS
329/**
330 * The Windows hosted USB Proxy Service.
331 */
332class USBProxyServiceWindows : public USBProxyService
333{
334public:
335 USBProxyServiceWindows(Host *aHost);
336 HRESULT init(void);
337 ~USBProxyServiceWindows();
338
339 virtual void *insertFilter (PCUSBFILTER aFilter);
340 virtual void removeFilter (void *aID);
341
342 virtual int captureDevice (HostUSBDevice *aDevice);
343 virtual int releaseDevice (HostUSBDevice *aDevice);
344
345protected:
346 virtual int wait(RTMSINTERVAL aMillies);
347 virtual int interruptWait(void);
348 virtual PUSBDEVICE getDevices(void);
349 virtual bool updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
350
351private:
352
353 HANDLE mhEventInterrupt;
354};
355# endif /* RT_OS_WINDOWS */
356
357# ifdef RT_OS_FREEBSD
358/**
359 * The FreeBSD hosted USB Proxy Service.
360 */
361class USBProxyServiceFreeBSD : public USBProxyService
362{
363public:
364 USBProxyServiceFreeBSD(Host *aHost);
365 HRESULT init(void);
366 ~USBProxyServiceFreeBSD();
367
368 virtual int captureDevice(HostUSBDevice *aDevice);
369 virtual int releaseDevice(HostUSBDevice *aDevice);
370
371protected:
372 int initUsbfs(void);
373 int initSysfs(void);
374 virtual int wait(RTMSINTERVAL aMillies);
375 virtual int interruptWait(void);
376 virtual PUSBDEVICE getDevices(void);
377 int addDeviceToChain(PUSBDEVICE pDev, PUSBDEVICE *ppFirst, PUSBDEVICE **pppNext, int rc);
378 virtual void deviceAdded(ComObjPtr<HostUSBDevice> &aDevice, SessionMachinesList &llOpenedMachines, PUSBDEVICE aUSBDevice);
379 virtual bool updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
380
381private:
382 RTSEMEVENT mNotifyEventSem;
383};
384# endif /* RT_OS_FREEBSD */
385
386#endif /* !____H_USBPROXYSERVICE */
387/* vi: set tabstop=4 shiftwidth=4 expandtab: */
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