VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/win/USBProxyBackendWindows.cpp@ 60067

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

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

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.7 KB
Line 
1/* $Id: USBProxyBackendWindows.cpp 60067 2016-03-16 19:17:22Z vboxsync $ */
2/** @file
3 * VirtualBox USB Proxy Service, Windows 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.215389.xyz. 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
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 */
40USBProxyBackendWindows::USBProxyBackendWindows(USBProxyService *aUsbProxyService, const com::Utf8Str &strId)
41 : USBProxyBackend(aUsbProxyService, strId), mhEventInterrupt(INVALID_HANDLE_VALUE)
42{
43 LogFlowThisFunc(("aUsbProxyService=%p\n", aUsbProxyService));
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 */
52int USBProxyBackendWindows::init(const com::Utf8Str &strAddress)
53{
54 NOREF(strAddress);
55
56 /*
57 * Create the semaphore (considered fatal).
58 */
59 mhEventInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);
60 AssertReturn(mhEventInterrupt != INVALID_HANDLE_VALUE, VERR_OUT_OF_RESOURCES);
61
62 /*
63 * Initialize the USB lib and stuff.
64 */
65 int rc = USBLibInit();
66 if (RT_SUCCESS(rc))
67 {
68 /*
69 * Start the poller thread.
70 */
71 rc = start();
72 if (RT_SUCCESS(rc))
73 {
74 LogFlowThisFunc(("returns successfully\n"));
75 return VINF_SUCCESS;
76 }
77
78 USBLibTerm();
79 }
80
81 CloseHandle(mhEventInterrupt);
82 mhEventInterrupt = INVALID_HANDLE_VALUE;
83
84 LogFlowThisFunc(("returns failure!!! (rc=%Rrc)\n", rc));
85 return rc;
86}
87
88
89/**
90 * Stop all service threads and free the device chain.
91 */
92USBProxyBackendWindows::~USBProxyBackendWindows()
93{
94 LogFlowThisFunc(("\n"));
95
96 /*
97 * Stop the service.
98 */
99 if (isActive())
100 stop();
101
102 if (mhEventInterrupt != INVALID_HANDLE_VALUE)
103 CloseHandle(mhEventInterrupt);
104 mhEventInterrupt = INVALID_HANDLE_VALUE;
105
106 /*
107 * Terminate the library...
108 */
109 int rc = USBLibTerm();
110 AssertRC(rc);
111}
112
113
114void *USBProxyBackendWindows::insertFilter(PCUSBFILTER aFilter)
115{
116 AssertReturn(aFilter, NULL);
117
118 LogFlow(("USBProxyBackendWindows::insertFilter()\n"));
119
120 void *pvId = USBLibAddFilter(aFilter);
121
122 LogFlow(("USBProxyBackendWindows::insertFilter(): returning pvId=%p\n", pvId));
123
124 return pvId;
125}
126
127
128void USBProxyBackendWindows::removeFilter(void *aID)
129{
130 LogFlow(("USBProxyBackendWindows::removeFilter(): id=%p\n", aID));
131
132 AssertReturnVoid(aID);
133
134 USBLibRemoveFilter(aID);
135}
136
137
138int USBProxyBackendWindows::captureDevice(HostUSBDevice *aDevice)
139{
140 /*
141 * Check preconditions.
142 */
143 AssertReturn(aDevice, VERR_GENERAL_FAILURE);
144 AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
145
146 AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
147 LogFlowThisFunc(("aDevice=%s\n", aDevice->i_getName().c_str()));
148
149 Assert(aDevice->i_getUnistate() == kHostUSBDeviceState_Capturing);
150
151 /*
152 * Create a one-shot ignore filter for the device
153 * and trigger a re-enumeration of it.
154 */
155 USBFILTER Filter;
156 USBFilterInit(&Filter, USBFILTERTYPE_ONESHOT_CAPTURE);
157 initFilterFromDevice(&Filter, aDevice);
158 Log(("USBFILTERIDX_PORT=%#x\n", USBFilterGetNum(&Filter, USBFILTERIDX_PORT)));
159 Log(("USBFILTERIDX_BUS=%#x\n", USBFilterGetNum(&Filter, USBFILTERIDX_BUS)));
160
161 void *pvId = USBLibAddFilter(&Filter);
162 if (!pvId)
163 {
164 AssertMsgFailed(("Add one-shot Filter failed\n"));
165 return VERR_GENERAL_FAILURE;
166 }
167
168 int rc = USBLibRunFilters();
169 if (!RT_SUCCESS(rc))
170 {
171 AssertMsgFailed(("Run Filters failed\n"));
172 USBLibRemoveFilter(pvId);
173 return rc;
174 }
175
176 return VINF_SUCCESS;
177}
178
179
180int USBProxyBackendWindows::releaseDevice(HostUSBDevice *aDevice)
181{
182 /*
183 * Check preconditions.
184 */
185 AssertReturn(aDevice, VERR_GENERAL_FAILURE);
186 AssertReturn(!aDevice->isWriteLockOnCurrentThread(), VERR_GENERAL_FAILURE);
187
188 AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
189 LogFlowThisFunc(("aDevice=%s\n", aDevice->i_getName().c_str()));
190
191 Assert(aDevice->i_getUnistate() == kHostUSBDeviceState_ReleasingToHost);
192
193 /*
194 * Create a one-shot ignore filter for the device
195 * and trigger a re-enumeration of it.
196 */
197 USBFILTER Filter;
198 USBFilterInit(&Filter, USBFILTERTYPE_ONESHOT_IGNORE);
199 initFilterFromDevice(&Filter, aDevice);
200 Log(("USBFILTERIDX_PORT=%#x\n", USBFilterGetNum(&Filter, USBFILTERIDX_PORT)));
201 Log(("USBFILTERIDX_BUS=%#x\n", USBFilterGetNum(&Filter, USBFILTERIDX_BUS)));
202
203 void *pvId = USBLibAddFilter(&Filter);
204 if (!pvId)
205 {
206 AssertMsgFailed(("Add one-shot Filter failed\n"));
207 return VERR_GENERAL_FAILURE;
208 }
209
210 int rc = USBLibRunFilters();
211 if (!RT_SUCCESS(rc))
212 {
213 AssertMsgFailed(("Run Filters failed\n"));
214 USBLibRemoveFilter(pvId);
215 return rc;
216 }
217
218
219 return VINF_SUCCESS;
220}
221
222
223bool USBProxyBackendWindows::updateDeviceState(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters,
224 SessionMachine **aIgnoreMachine)
225{
226 AssertReturn(aDevice, false);
227 AssertReturn(!aDevice->isWriteLockOnCurrentThread(), false);
228 /* Nothing special here so far, so fall back on parent */
229 return USBProxyBackend::updateDeviceState(aDevice, aUSBDevice, aRunFilters, aIgnoreMachine);
230}
231
232
233int USBProxyBackendWindows::wait(unsigned aMillies)
234{
235 return USBLibWaitChange(aMillies);
236}
237
238
239int USBProxyBackendWindows::interruptWait(void)
240{
241 return USBLibInterruptWaitChange();
242}
243
244/**
245 * Gets a list of all devices the VM can grab
246 */
247PUSBDEVICE USBProxyBackendWindows::getDevices(void)
248{
249 PUSBDEVICE pDevices = NULL;
250 uint32_t cDevices = 0;
251
252 Log(("USBProxyBackendWindows::getDevices\n"));
253 USBLibGetDevices(&pDevices, &cDevices);
254 return pDevices;
255}
256
Note: See TracBrowser for help on using the repository browser.

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