VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/darwin/USBProxyBackendDarwin.cpp@ 60068

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

Revert r106058, incomplete conversion of USBProxyBackend to a COM class failing to build on Windows

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.6 KB
Line 
1/* $Id: USBProxyBackendDarwin.cpp 60068 2016-03-16 19:43:56Z vboxsync $ */
2/** @file
3 * VirtualBox USB Proxy Service (in VBoxSVC), Darwin Specialization.
4 */
5
6/*
7 * Copyright (C) 2005-2012 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/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include "USBProxyBackend.h"
23#include "Logging.h"
24#include "iokit.h"
25
26#include <VBox/usb.h>
27#include <VBox/usblib.h>
28#include <VBox/err.h>
29
30#include <iprt/string.h>
31#include <iprt/alloc.h>
32#include <iprt/assert.h>
33#include <iprt/file.h>
34#include <iprt/err.h>
35#include <iprt/asm.h>
36
37
38/**
39 * Initialize data members.
40 */
41USBProxyBackendDarwin::USBProxyBackendDarwin(USBProxyService *aUsbProxyService)
42 : USBProxyBackend(aUsbProxyService), mServiceRunLoopRef(NULL), mNotifyOpaque(NULL), mWaitABitNextTime(false), mUSBLibInitialized(false)
43{
44 LogFlowThisFunc(("aUsbProxyService=%p\n", aUsbProxyService));
45}
46
47
48/**
49 * Initializes the object (called right after construction).
50 *
51 * @returns VBox status code.
52 */
53int USBProxyBackendDarwin::init(void)
54{
55 /*
56 * Initialize the USB library.
57 */
58 int rc = USBLibInit();
59 if (RT_FAILURE(rc))
60 return rc;
61
62 mUSBLibInitialized = true;
63
64 /*
65 * Start the poller thread.
66 */
67 start();
68 return VINF_SUCCESS;
69}
70
71
72/**
73 * Stop all service threads and free the device chain.
74 */
75USBProxyBackendDarwin::~USBProxyBackendDarwin()
76{
77 LogFlowThisFunc(("\n"));
78
79 /*
80 * Stop the service.
81 */
82 if (isActive())
83 stop();
84
85 /*
86 * Terminate the USB library - it'll
87 */
88 if (mUSBLibInitialized)
89 {
90 USBLibTerm();
91 mUSBLibInitialized = false;
92 }
93}
94
95
96void *USBProxyBackendDarwin::insertFilter(PCUSBFILTER aFilter)
97{
98 return USBLibAddFilter(aFilter);
99}
100
101
102void USBProxyBackendDarwin::removeFilter(void *aId)
103{
104 USBLibRemoveFilter(aId);
105}
106
107
108int USBProxyBackendDarwin::captureDevice(HostUSBDevice *aDevice)
109{
110 /*
111 * Check preconditions.
112 */
113 AssertReturn(aDevice, VERR_GENERAL_FAILURE);
114 AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
115
116 AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
117 LogFlowThisFunc(("aDevice=%s\n", aDevice->i_getName().c_str()));
118
119 Assert(aDevice->i_getUnistate() == kHostUSBDeviceState_Capturing);
120
121 /*
122 * Create a one-shot capture filter for the device (don't
123 * match on port) and trigger a re-enumeration of it.
124 */
125 USBFILTER Filter;
126 USBFilterInit(&Filter, USBFILTERTYPE_ONESHOT_CAPTURE);
127 initFilterFromDevice(&Filter, aDevice);
128
129 void *pvId = USBLibAddFilter(&Filter);
130 if (!pvId)
131 return VERR_GENERAL_FAILURE;
132
133 int rc = DarwinReEnumerateUSBDevice(aDevice->i_getUsbData());
134 if (RT_SUCCESS(rc))
135 aDevice->i_setBackendUserData(pvId);
136 else
137 {
138 USBLibRemoveFilter(pvId);
139 pvId = NULL;
140 }
141 LogFlowThisFunc(("returns %Rrc pvId=%p\n", rc, pvId));
142 return rc;
143}
144
145
146void USBProxyBackendDarwin::captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess)
147{
148 AssertReturnVoid(aDevice->isWriteLockOnCurrentThread());
149
150 /*
151 * Remove the one-shot filter if necessary.
152 */
153 LogFlowThisFunc(("aDevice=%s aSuccess=%RTbool mOneShotId=%p\n", aDevice->i_getName().c_str(), aSuccess, aDevice->i_getBackendUserData()));
154 if (!aSuccess && aDevice->i_getBackendUserData())
155 USBLibRemoveFilter(aDevice->i_getBackendUserData());
156 aDevice->i_setBackendUserData(NULL);
157}
158
159
160int USBProxyBackendDarwin::releaseDevice(HostUSBDevice *aDevice)
161{
162 /*
163 * Check preconditions.
164 */
165 AssertReturn(aDevice, VERR_GENERAL_FAILURE);
166 AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
167
168 AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
169 LogFlowThisFunc(("aDevice=%s\n", aDevice->i_getName().c_str()));
170
171 Assert(aDevice->i_getUnistate() == kHostUSBDeviceState_ReleasingToHost);
172
173 /*
174 * Create a one-shot ignore filter for the device
175 * and trigger a re-enumeration of it.
176 */
177 USBFILTER Filter;
178 USBFilterInit(&Filter, USBFILTERTYPE_ONESHOT_IGNORE);
179 initFilterFromDevice(&Filter, aDevice);
180 Log(("USBFILTERIDX_PORT=%#x\n", USBFilterGetNum(&Filter, USBFILTERIDX_PORT)));
181 Log(("USBFILTERIDX_BUS=%#x\n", USBFilterGetNum(&Filter, USBFILTERIDX_BUS)));
182
183 void *pvId = USBLibAddFilter(&Filter);
184 if (!pvId)
185 return VERR_GENERAL_FAILURE;
186
187 int rc = DarwinReEnumerateUSBDevice(aDevice->i_getUsbData());
188 if (RT_SUCCESS(rc))
189 aDevice->i_setBackendUserData(pvId);
190 else
191 {
192 USBLibRemoveFilter(pvId);
193 pvId = NULL;
194 }
195 LogFlowThisFunc(("returns %Rrc pvId=%p\n", rc, pvId));
196 return rc;
197}
198
199
200void USBProxyBackendDarwin::releaseDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess)
201{
202 AssertReturnVoid(aDevice->isWriteLockOnCurrentThread());
203
204 /*
205 * Remove the one-shot filter if necessary.
206 */
207 LogFlowThisFunc(("aDevice=%s aSuccess=%RTbool mOneShotId=%p\n", aDevice->i_getName().c_str(), aSuccess, aDevice->i_getBackendUserData()));
208 if (!aSuccess && aDevice->i_getBackendUserData())
209 USBLibRemoveFilter(aDevice->i_getBackendUserData());
210 aDevice->i_setBackendUserData(NULL);
211}
212
213
214/** @todo unused */
215void USBProxyBackendDarwin::detachingDevice(HostUSBDevice *aDevice)
216{
217 NOREF(aDevice);
218}
219
220
221bool USBProxyBackendDarwin::updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine)
222{
223 AssertReturn(aDevice, false);
224 AssertReturn(!aDevice->isWriteLockOnCurrentThread(), false);
225 /* Nothing special here so far, so fall back on parent. */
226 return USBProxyBackend::updateDeviceState(aDevice, aUSBDevice, aRunFilters, aIgnoreMachine);
227}
228
229
230int USBProxyBackendDarwin::wait(RTMSINTERVAL aMillies)
231{
232 SInt32 rc = CFRunLoopRunInMode(CFSTR(VBOX_IOKIT_MODE_STRING),
233 mWaitABitNextTime && aMillies >= 1000
234 ? 1.0 /* seconds */
235 : aMillies >= 5000 /* Temporary measure to poll for status changes (MSD). */
236 ? 5.0 /* seconds */
237 : aMillies / 1000.0,
238 true);
239 mWaitABitNextTime = rc != kCFRunLoopRunTimedOut;
240
241 return VINF_SUCCESS;
242}
243
244
245int USBProxyBackendDarwin::interruptWait(void)
246{
247 if (mServiceRunLoopRef)
248 CFRunLoopStop(mServiceRunLoopRef);
249 return 0;
250}
251
252
253PUSBDEVICE USBProxyBackendDarwin::getDevices(void)
254{
255 /* call iokit.cpp */
256 return DarwinGetUSBDevices();
257}
258
259
260void USBProxyBackendDarwin::serviceThreadInit(void)
261{
262 mServiceRunLoopRef = CFRunLoopGetCurrent();
263 mNotifyOpaque = DarwinSubscribeUSBNotifications();
264}
265
266
267void USBProxyBackendDarwin::serviceThreadTerm(void)
268{
269 DarwinUnsubscribeUSBNotifications(mNotifyOpaque);
270 mServiceRunLoopRef = NULL;
271}
272
273
274/**
275 * Wrapper called from iokit.cpp.
276 *
277 * @param pCur The USB device to free.
278 */
279void DarwinFreeUSBDeviceFromIOKit(PUSBDEVICE pCur)
280{
281 USBProxyBackend::freeDevice(pCur);
282}
283
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