VirtualBox

source: vbox/trunk/src/VBox/Main/win/USBProxyServiceWindows.cpp@ 33696

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

*: spelling fixes, thanks Timeless!

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.9 KB
Line 
1/* $Id: USBProxyServiceWindows.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
2/** @file
3 * VirtualBox USB Proxy Service, Windows Specialization.
4 */
5
6/*
7 * Copyright (C) 2006-2010 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 "USBProxyService.h"
23#include "Logging.h"
24
25#include <VBox/usb.h>
26#include <VBox/err.h>
27
28#include <iprt/string.h>
29#include <iprt/alloc.h>
30#include <iprt/assert.h>
31#include <iprt/file.h>
32#include <iprt/err.h>
33
34#include <VBox/usblib.h>
35
36
37/**
38 * Initialize data members.
39 */
40USBProxyServiceWindows::USBProxyServiceWindows(Host *aHost)
41 : USBProxyService(aHost), mhEventInterrupt(INVALID_HANDLE_VALUE)
42{
43 LogFlowThisFunc(("aHost=%p\n", aHost));
44}
45
46
47/**
48 * Initializes the object (called right after construction).
49 *
50 * @returns S_OK on success and non-fatal failures, some COM error otherwise.
51 */
52HRESULT USBProxyServiceWindows::init(void)
53{
54 /*
55 * Call the superclass method first.
56 */
57 HRESULT hrc = USBProxyService::init();
58 AssertComRCReturn(hrc, hrc);
59
60 /*
61 * Create the semaphore (considered fatal).
62 */
63 mhEventInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);
64 AssertReturn(mhEventInterrupt != INVALID_HANDLE_VALUE, E_FAIL);
65
66 /*
67 * Initialize the USB lib and stuff.
68 */
69 int rc = USBLibInit();
70 if (RT_SUCCESS(rc))
71 {
72 /*
73 * Start the poller thread.
74 */
75 rc = start();
76 if (RT_SUCCESS(rc))
77 {
78 LogFlowThisFunc(("returns successfully\n"));
79 return S_OK;
80 }
81
82 USBLibTerm();
83 }
84
85 CloseHandle(mhEventInterrupt);
86 mhEventInterrupt = INVALID_HANDLE_VALUE;
87
88 LogFlowThisFunc(("returns failure!!! (rc=%Rrc)\n", rc));
89 mLastError = rc;
90 return S_OK;
91}
92
93
94/**
95 * Stop all service threads and free the device chain.
96 */
97USBProxyServiceWindows::~USBProxyServiceWindows()
98{
99 LogFlowThisFunc(("\n"));
100
101 /*
102 * Stop the service.
103 */
104 if (isActive())
105 stop();
106
107 if (mhEventInterrupt != INVALID_HANDLE_VALUE)
108 CloseHandle(mhEventInterrupt);
109 mhEventInterrupt = INVALID_HANDLE_VALUE;
110
111 /*
112 * Terminate the library...
113 */
114 int rc = USBLibTerm();
115 AssertRC(rc);
116}
117
118
119void *USBProxyServiceWindows::insertFilter(PCUSBFILTER aFilter)
120{
121 AssertReturn(aFilter, NULL);
122
123 LogFlow(("USBProxyServiceWindows::insertFilter()\n"));
124
125 void *pvId = USBLibAddFilter(aFilter);
126
127 LogFlow(("USBProxyServiceWindows::insertFilter(): returning pvId=%p\n", pvId));
128
129 return pvId;
130}
131
132
133void USBProxyServiceWindows::removeFilter(void *aID)
134{
135 LogFlow(("USBProxyServiceWindows::removeFilter(): id=%p\n", aID));
136
137 AssertReturnVoid(aID);
138
139 USBLibRemoveFilter(aID);
140}
141
142
143int USBProxyServiceWindows::captureDevice(HostUSBDevice *aDevice)
144{
145 AssertReturn(aDevice, VERR_GENERAL_FAILURE);
146 AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
147 Assert(aDevice->getUnistate() == kHostUSBDeviceState_Capturing);
148
149/** @todo pass up a one-shot filter like on darwin? */
150 USHORT vendorId, productId, revision;
151
152 HRESULT rc;
153
154 rc = aDevice->COMGETTER(VendorId)(&vendorId);
155 AssertComRCReturn(rc, VERR_INTERNAL_ERROR);
156
157 rc = aDevice->COMGETTER(ProductId)(&productId);
158 AssertComRCReturn(rc, VERR_INTERNAL_ERROR);
159
160 rc = aDevice->COMGETTER(Revision)(&revision);
161 AssertComRCReturn(rc, VERR_INTERNAL_ERROR);
162
163 return USBLibCaptureDevice(vendorId, productId, revision);
164}
165
166
167int USBProxyServiceWindows::releaseDevice(HostUSBDevice *aDevice)
168{
169 AssertReturn(aDevice, VERR_GENERAL_FAILURE);
170 AssertReturn(aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
171 Assert(aDevice->getUnistate() == kHostUSBDeviceState_ReleasingToHost);
172
173/** @todo pass up a one-shot filter like on darwin? */
174 USHORT vendorId, productId, revision;
175 HRESULT rc;
176
177 rc = aDevice->COMGETTER(VendorId)(&vendorId);
178 AssertComRCReturn(rc, VERR_INTERNAL_ERROR);
179
180 rc = aDevice->COMGETTER(ProductId)(&productId);
181 AssertComRCReturn(rc, VERR_INTERNAL_ERROR);
182
183 rc = aDevice->COMGETTER(Revision)(&revision);
184 AssertComRCReturn(rc, VERR_INTERNAL_ERROR);
185
186 Log(("USBProxyServiceWindows::releaseDevice\n"));
187 return USBLibReleaseDevice(vendorId, productId, revision);
188}
189
190
191bool USBProxyServiceWindows::updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine)
192{
193 /* Nothing special here so far, so fall back on parent */
194 return USBProxyService::updateDeviceState(aDevice, aUSBDevice, aRunFilters, aIgnoreMachine);
195
196/// @todo remove?
197#if 0
198 AssertReturn(aDevice, false);
199 AssertReturn(aDevice->isWriteLockOnCurrentThread(), false);
200
201 /*
202 * We're only called in the 'existing device' state, so if there is a pending async
203 * operation we can check if it completed here and suppress state changes if it hasn't.
204 */
205 /* TESTME */
206 if (aDevice->isStatePending())
207 {
208 bool fRc = aDevice->updateState(aUSBDevice);
209 if (fRc)
210 {
211 if (aDevice->state() != aDevice->pendingState())
212 fRc = false;
213 }
214 return fRc;
215 }
216
217 /* fall back on parent. */
218 return USBProxyService::updateDeviceState(aDevice, aUSBDevice, aRunFilters, aIgnoreMachine);
219#endif
220}
221
222
223int USBProxyServiceWindows::wait(unsigned aMillies)
224{
225 DWORD rc;
226
227 /* Not going to do something fancy where we block in the filter
228 * driver and are woken up when the state has changed.
229 * Would be better, but this is good enough.
230 */
231 do
232 {
233 rc = WaitForSingleObject(mhEventInterrupt, RT_MIN(aMillies, 100));
234 if (rc == WAIT_OBJECT_0)
235 return VINF_SUCCESS;
236 /** @todo handle WAIT_FAILED here */
237
238 if (USBLibHasPendingDeviceChanges() == true)
239 {
240 Log(("wait thread detected usb change\n"));
241 return VINF_SUCCESS;
242 }
243
244 if (aMillies > 100)
245 aMillies -= 100;
246 }
247 while (aMillies > 100);
248
249 return VERR_TIMEOUT;
250}
251
252
253int USBProxyServiceWindows::interruptWait(void)
254{
255 SetEvent(mhEventInterrupt);
256 return VINF_SUCCESS;
257}
258
259
260/**
261 * Gets a list of all devices the VM can grab
262 */
263PUSBDEVICE USBProxyServiceWindows::getDevices(void)
264{
265 PUSBDEVICE pDevices = NULL;
266 uint32_t cDevices = 0;
267
268 Log(("USBProxyServiceWindows::getDevices\n"));
269 USBLibGetDevices(&pDevices, &cDevices);
270 return pDevices;
271}
272
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