VirtualBox

source: vbox/trunk/src/VBox/Main/darwin/USBProxyServiceDarwin.cpp@ 31891

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

Main: export USBProxyService and USBFilter to OSE

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 7.8 KB
 
1/* $Id: USBProxyServiceDarwin.cpp 31891 2010-08-24 07:58:48Z vboxsync $ */
2/** @file
3 * VirtualBox USB Proxy Service (in VBoxSVC), Darwin Specialization.
4 */
5
6/*
7 * Copyright (C) 2006-2010 Oracle Corporation
8 *
9 * Oracle Corporation confidential
10 * All rights reserved
11 */
12
13
14/*******************************************************************************
15* Header Files *
16*******************************************************************************/
17#include "USBProxyService.h"
18#include "Logging.h"
19#include "iokit.h"
20
21#include <VBox/usb.h>
22#include <VBox/usblib.h>
23#include <VBox/err.h>
24
25#include <iprt/string.h>
26#include <iprt/alloc.h>
27#include <iprt/assert.h>
28#include <iprt/file.h>
29#include <iprt/err.h>
30#include <iprt/asm.h>
31
32
33/**
34 * Initialize data members.
35 */
36USBProxyServiceDarwin::USBProxyServiceDarwin (Host *aHost)
37 : USBProxyService (aHost), mServiceRunLoopRef (NULL), mNotifyOpaque (NULL), mWaitABitNextTime (false), mUSBLibInitialized (false)
38{
39 LogFlowThisFunc(("aHost=%p\n", aHost));
40}
41
42
43/**
44 * Initializes the object (called right after construction).
45 *
46 * @returns S_OK on success and non-fatal failures, some COM error otherwise.
47 */
48HRESULT USBProxyServiceDarwin::init(void)
49{
50 /*
51 * Call the superclass method first.
52 */
53 HRESULT hrc = USBProxyService::init();
54 AssertComRCReturn(hrc, hrc);
55
56#ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
57 /*
58 * Initialize the USB library.
59 */
60 int rc = USBLibInit();
61 if (RT_FAILURE(rc))
62 {
63 mLastError = rc;
64 return S_OK;
65 }
66 mUSBLibInitialized = true;
67#endif
68
69 /*
70 * Start the poller thread.
71 */
72 start();
73 return S_OK;
74}
75
76
77/**
78 * Stop all service threads and free the device chain.
79 */
80USBProxyServiceDarwin::~USBProxyServiceDarwin()
81{
82 LogFlowThisFunc(("\n"));
83
84 /*
85 * Stop the service.
86 */
87 if (isActive())
88 stop();
89
90#ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
91 /*
92 * Terminate the USB library - it'll
93 */
94 if (mUSBLibInitialized)
95 {
96 USBLibTerm();
97 mUSBLibInitialized = false;
98 }
99#endif
100}
101
102
103#ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
104void *USBProxyServiceDarwin::insertFilter (PCUSBFILTER aFilter)
105{
106 return USBLibAddFilter (aFilter);
107}
108
109
110void USBProxyServiceDarwin::removeFilter (void *aId)
111{
112 USBLibRemoveFilter (aId);
113}
114#endif /* VBOX_WITH_NEW_USB_CODE_ON_DARWIN */
115
116
117int USBProxyServiceDarwin::captureDevice(HostUSBDevice *aDevice)
118{
119 /*
120 * Check preconditions.
121 */
122 AssertReturn(aDevice, VERR_GENERAL_FAILURE);
123 LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
124 AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
125 Assert(aDevice->getUnistate() == kHostUSBDeviceState_Capturing);
126
127#ifndef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
128 /*
129 * Fake it.
130 */
131 ASMAtomicWriteBool(&mFakeAsync, true);
132 interruptWait();
133 return VINF_SUCCESS;
134
135#else
136 /*
137 * Create a one-shot capture filter for the device (don't
138 * match on port) and trigger a re-enumeration of it.
139 */
140 USBFILTER Filter;
141 USBFilterInit(&Filter, USBFILTERTYPE_ONESHOT_CAPTURE);
142 initFilterFromDevice(&Filter, aDevice);
143
144 void *pvId = USBLibAddFilter(&Filter);
145 if (!pvId)
146 return VERR_GENERAL_FAILURE;
147
148 int rc = DarwinReEnumerateUSBDevice(aDevice->mUsb);
149 if (RT_SUCCESS(rc))
150 aDevice->mOneShotId = pvId;
151 else
152 {
153 USBLibRemoveFilter(pvId);
154 pvId = NULL;
155 }
156 LogFlowThisFunc(("returns %Rrc pvId=%p\n", rc, pvId));
157 return rc;
158#endif
159}
160
161
162void USBProxyServiceDarwin::captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess)
163{
164#ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
165 /*
166 * Remove the one-shot filter if necessary.
167 */
168 LogFlowThisFunc(("aDevice=%s aSuccess=%RTbool mOneShotId=%p\n", aDevice->getName().c_str(), aSuccess, aDevice->mOneShotId));
169 if (!aSuccess && aDevice->mOneShotId)
170 USBLibRemoveFilter(aDevice->mOneShotId);
171 aDevice->mOneShotId = NULL;
172#endif
173}
174
175
176int USBProxyServiceDarwin::releaseDevice(HostUSBDevice *aDevice)
177{
178 /*
179 * Check preconditions.
180 */
181 AssertReturn(aDevice, VERR_GENERAL_FAILURE);
182 LogFlowThisFunc(("aDevice=%s\n", aDevice->getName().c_str()));
183 AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
184 Assert(aDevice->getUnistate() == kHostUSBDeviceState_ReleasingToHost);
185
186#ifndef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
187 /*
188 * Fake it.
189 */
190 ASMAtomicWriteBool(&mFakeAsync, true);
191 interruptWait();
192 return VINF_SUCCESS;
193
194#else
195 /*
196 * Create a one-shot ignore filter for the device
197 * and trigger a re-enumeration of it.
198 */
199 USBFILTER Filter;
200 USBFilterInit(&Filter, USBFILTERTYPE_ONESHOT_IGNORE);
201 initFilterFromDevice(&Filter, aDevice);
202 Log(("USBFILTERIDX_PORT=%#x\n", USBFilterGetNum(&Filter, USBFILTERIDX_PORT)));
203 Log(("USBFILTERIDX_BUS=%#x\n", USBFilterGetNum(&Filter, USBFILTERIDX_BUS)));
204
205 void *pvId = USBLibAddFilter(&Filter);
206 if (!pvId)
207 return VERR_GENERAL_FAILURE;
208
209 int rc = DarwinReEnumerateUSBDevice(aDevice->mUsb);
210 if (RT_SUCCESS(rc))
211 aDevice->mOneShotId = pvId;
212 else
213 {
214 USBLibRemoveFilter(pvId);
215 pvId = NULL;
216 }
217 LogFlowThisFunc(("returns %Rrc pvId=%p\n", rc, pvId));
218 return rc;
219#endif
220}
221
222
223void USBProxyServiceDarwin::releaseDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess)
224{
225#ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
226 /*
227 * Remove the one-shot filter if necessary.
228 */
229 LogFlowThisFunc(("aDevice=%s aSuccess=%RTbool mOneShotId=%p\n", aDevice->getName().c_str(), aSuccess, aDevice->mOneShotId));
230 if (!aSuccess && aDevice->mOneShotId)
231 USBLibRemoveFilter(aDevice->mOneShotId);
232 aDevice->mOneShotId = NULL;
233#endif
234}
235
236
237void USBProxyServiceDarwin::detachingDevice(HostUSBDevice *aDevice)
238{
239#ifndef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
240 aDevice->setLogicalReconnect (HostUSBDevice::kDetachingPendingDetach);
241#else
242 NOREF(aDevice);
243#endif
244}
245
246
247bool USBProxyServiceDarwin::updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine)
248{
249#ifndef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
250 /* We're faking async state stuff. */
251 return updateDeviceStateFake(aDevice, aUSBDevice, aRunFilters, aIgnoreMachine);
252#else
253 /* Nothing special here so far, so fall back on parent */
254 return USBProxyService::updateDeviceState(aDevice, aUSBDevice, aRunFilters, aIgnoreMachine);
255#endif
256}
257
258
259int USBProxyServiceDarwin::wait(RTMSINTERVAL aMillies)
260{
261#ifndef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
262 if ( mFakeAsync
263 && ASMAtomicXchgBool(&mFakeAsync, false))
264 return VINF_SUCCESS;
265#endif
266
267 SInt32 rc = CFRunLoopRunInMode(CFSTR (VBOX_IOKIT_MODE_STRING),
268 mWaitABitNextTime && aMillies >= 1000
269 ? 1.0 /* seconds */
270 : aMillies >= 5000 /* Temporary measure to poll for status changes (MSD). */
271 ? 5.0 /* seconds */
272 : aMillies / 1000.0,
273 true);
274 mWaitABitNextTime = rc != kCFRunLoopRunTimedOut;
275
276 return VINF_SUCCESS;
277}
278
279
280int USBProxyServiceDarwin::interruptWait (void)
281{
282 if (mServiceRunLoopRef)
283 CFRunLoopStop (mServiceRunLoopRef);
284 return 0;
285}
286
287
288PUSBDEVICE USBProxyServiceDarwin::getDevices (void)
289{
290 /* call iokit.cpp */
291 return DarwinGetUSBDevices();
292}
293
294
295void USBProxyServiceDarwin::serviceThreadInit (void)
296{
297 mServiceRunLoopRef = CFRunLoopGetCurrent();
298 mNotifyOpaque = DarwinSubscribeUSBNotifications();
299}
300
301
302void USBProxyServiceDarwin::serviceThreadTerm (void)
303{
304 DarwinUnsubscribeUSBNotifications (mNotifyOpaque);
305 mServiceRunLoopRef = NULL;
306}
307
308
309/**
310 * Wrapper called from iokit.cpp.
311 *
312 * @param pCur The USB device to free.
313 */
314void DarwinFreeUSBDeviceFromIOKit (PUSBDEVICE pCur)
315{
316 USBProxyService::freeDevice (pCur);
317}
318
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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