VirtualBox

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

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

Main: export USBProxyService and USBFilter to OSE

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

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