VirtualBox

source: vbox/trunk/src/VBox/Main/src-client/RemoteUSBDeviceImpl.cpp@ 53401

Last change on this file since 53401 was 53297, checked in by vboxsync, 10 years ago

Main: Added API to report actual USB device speed.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.3 KB
Line 
1/* $Id: RemoteUSBDeviceImpl.cpp 53297 2014-11-10 21:57:22Z vboxsync $ */
2
3/** @file
4 *
5 * VirtualBox IHostUSBDevice COM interface implementation
6 * for remote (VRDP) USB devices
7 */
8
9/*
10 * Copyright (C) 2006-2011 Oracle Corporation
11 *
12 * This file is part of VirtualBox Open Source Edition (OSE), as
13 * available from http://www.virtualbox.org. This file is free software;
14 * you can redistribute it and/or modify it under the terms of the GNU
15 * General Public License (GPL) as published by the Free Software
16 * Foundation, in version 2 as it comes in the "COPYING" file of the
17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19 */
20
21#include "RemoteUSBDeviceImpl.h"
22
23#include "AutoCaller.h"
24#include "Logging.h"
25
26#include <iprt/cpp/utils.h>
27
28#include <VBox/err.h>
29
30#include <VBox/RemoteDesktop/VRDE.h>
31#include <VBox/vrdpusb.h>
32
33// constructor / destructor
34/////////////////////////////////////////////////////////////////////////////
35
36DEFINE_EMPTY_CTOR_DTOR (RemoteUSBDevice)
37
38HRESULT RemoteUSBDevice::FinalConstruct()
39{
40 return BaseFinalConstruct();
41}
42
43void RemoteUSBDevice::FinalRelease()
44{
45 uninit();
46 BaseFinalRelease();
47}
48
49// public initializer/uninitializer for internal purposes only
50/////////////////////////////////////////////////////////////////////////////
51
52/** @todo (sunlover) REMOTE_USB Device states. */
53
54/**
55 * Initializes the remote USB device object.
56 */
57HRESULT RemoteUSBDevice::init (uint32_t u32ClientId, VRDEUSBDEVICEDESC *pDevDesc, bool fDescExt)
58{
59 LogFlowThisFunc(("u32ClientId=%d,pDevDesc=%p\n", u32ClientId, pDevDesc));
60
61 /* Enclose the state transition NotReady->InInit->Ready */
62 AutoInitSpan autoInitSpan(this);
63 AssertReturn(autoInitSpan.isOk(), E_FAIL);
64
65 unconst(mData.id).create();
66
67 unconst(mData.vendorId) = pDevDesc->idVendor;
68 unconst(mData.productId) = pDevDesc->idProduct;
69 unconst(mData.revision) = pDevDesc->bcdRev;
70
71 unconst(mData.manufacturer) = pDevDesc->oManufacturer? (char *)pDevDesc + pDevDesc->oManufacturer: "";
72 unconst(mData.product) = pDevDesc->oProduct? (char *)pDevDesc + pDevDesc->oProduct: "";
73 unconst(mData.serialNumber) = pDevDesc->oSerialNumber? (char *)pDevDesc + pDevDesc->oSerialNumber: "";
74
75 char id[64];
76 RTStrPrintf(id, sizeof (id), REMOTE_USB_BACKEND_PREFIX_S "0x%08X&0x%08X", pDevDesc->id, u32ClientId);
77 unconst(mData.address) = id;
78
79 unconst(mData.port) = pDevDesc->idPort;
80 unconst(mData.version) = pDevDesc->bcdUSB >> 8;
81 if (fDescExt)
82 {
83 VRDEUSBDEVICEDESCEXT *pDevDescExt = (VRDEUSBDEVICEDESCEXT *)pDevDesc;
84 switch (pDevDescExt->u16DeviceSpeed)
85 {
86 default:
87 case VRDE_USBDEVICESPEED_UNKNOWN:
88 case VRDE_USBDEVICESPEED_LOW:
89 case VRDE_USBDEVICESPEED_FULL:
90 unconst(mData.portVersion) = 1;
91 unconst(mData.speed) = USBConnectionSpeed_Full;
92 break;
93
94 case VRDE_USBDEVICESPEED_HIGH:
95 case VRDE_USBDEVICESPEED_VARIABLE:
96 unconst(mData.portVersion) = 2;
97 unconst(mData.speed) = USBConnectionSpeed_High;
98 break;
99
100 case VRDE_USBDEVICESPEED_SUPERSPEED:
101 unconst(mData.portVersion) = 3;
102 unconst(mData.speed) = USBConnectionSpeed_Super;
103 break;
104 }
105 }
106 else
107 {
108 unconst(mData.portVersion) = mData.version;
109 unconst(mData.speed) = mData.version == 3 ? USBConnectionSpeed_Super :
110 mData.version == 2 ? USBConnectionSpeed_High :
111 USBConnectionSpeed_Full;
112 }
113
114 mData.state = USBDeviceState_Available;
115
116 mData.dirty = false;
117 unconst(mData.devId) = pDevDesc->id;
118
119 unconst(mData.clientId) = u32ClientId;
120
121 /* Confirm a successful initialization */
122 autoInitSpan.setSucceeded();
123
124 return S_OK;
125}
126
127
128/**
129 * Uninitializes the instance and sets the ready flag to FALSE.
130 * Called either from FinalRelease() or by the parent when it gets destroyed.
131 */
132void RemoteUSBDevice::uninit()
133{
134 LogFlowThisFunc(("\n"));
135
136 /* Enclose the state transition Ready->InUninit->NotReady */
137 AutoUninitSpan autoUninitSpan(this);
138 if (autoUninitSpan.uninitDone())
139 return;
140
141 unconst(mData.id).clear();
142
143 unconst(mData.vendorId) = 0;
144 unconst(mData.productId) = 0;
145 unconst(mData.revision) = 0;
146
147 unconst(mData.manufacturer).setNull();
148 unconst(mData.product).setNull();
149 unconst(mData.serialNumber).setNull();
150
151 unconst(mData.address).setNull();
152
153 unconst(mData.port) = 0;
154 unconst(mData.version) = 1;
155 unconst(mData.portVersion) = 1;
156
157 unconst(mData.dirty) = FALSE;
158
159 unconst(mData.devId) = 0;
160 unconst(mData.clientId) = 0;
161}
162
163// IUSBDevice properties
164/////////////////////////////////////////////////////////////////////////////
165
166STDMETHODIMP RemoteUSBDevice::COMGETTER(Id) (BSTR *aId)
167{
168 CheckComArgOutPointerValid(aId);
169
170 AutoCaller autoCaller(this);
171 if (FAILED(autoCaller.rc())) return autoCaller.rc();
172
173 /* this is const, no need to lock */
174 mData.id.toUtf16().detachTo(aId);
175
176 return S_OK;
177}
178
179STDMETHODIMP RemoteUSBDevice::COMGETTER(VendorId) (USHORT *aVendorId)
180{
181 CheckComArgOutPointerValid(aVendorId);
182
183 AutoCaller autoCaller(this);
184 if (FAILED(autoCaller.rc())) return autoCaller.rc();
185
186 /* this is const, no need to lock */
187 *aVendorId = mData.vendorId;
188
189 return S_OK;
190}
191
192STDMETHODIMP RemoteUSBDevice::COMGETTER(ProductId) (USHORT *aProductId)
193{
194 CheckComArgOutPointerValid(aProductId);
195
196 AutoCaller autoCaller(this);
197 if (FAILED(autoCaller.rc())) return autoCaller.rc();
198
199 /* this is const, no need to lock */
200 *aProductId = mData.productId;
201
202 return S_OK;
203}
204
205STDMETHODIMP RemoteUSBDevice::COMGETTER(Revision) (USHORT *aRevision)
206{
207 CheckComArgOutPointerValid(aRevision);
208
209 AutoCaller autoCaller(this);
210 if (FAILED(autoCaller.rc())) return autoCaller.rc();
211
212 /* this is const, no need to lock */
213 *aRevision = mData.revision;
214
215 return S_OK;
216}
217
218STDMETHODIMP RemoteUSBDevice::COMGETTER(Manufacturer) (BSTR *aManufacturer)
219{
220 CheckComArgOutPointerValid(aManufacturer);
221
222 AutoCaller autoCaller(this);
223 if (FAILED(autoCaller.rc())) return autoCaller.rc();
224
225 /* this is const, no need to lock */
226 mData.manufacturer.cloneTo(aManufacturer);
227
228 return S_OK;
229}
230
231STDMETHODIMP RemoteUSBDevice::COMGETTER(Product) (BSTR *aProduct)
232{
233 CheckComArgOutPointerValid(aProduct);
234
235 AutoCaller autoCaller(this);
236 if (FAILED(autoCaller.rc())) return autoCaller.rc();
237
238 /* this is const, no need to lock */
239 mData.product.cloneTo(aProduct);
240
241 return S_OK;
242}
243
244STDMETHODIMP RemoteUSBDevice::COMGETTER(SerialNumber) (BSTR *aSerialNumber)
245{
246 CheckComArgOutPointerValid(aSerialNumber);
247
248 AutoCaller autoCaller(this);
249 if (FAILED(autoCaller.rc())) return autoCaller.rc();
250
251 /* this is const, no need to lock */
252 mData.serialNumber.cloneTo(aSerialNumber);
253
254 return S_OK;
255}
256
257STDMETHODIMP RemoteUSBDevice::COMGETTER(Address) (BSTR *aAddress)
258{
259 CheckComArgOutPointerValid(aAddress);
260
261 AutoCaller autoCaller(this);
262 if (FAILED(autoCaller.rc())) return autoCaller.rc();
263
264 /* this is const, no need to lock */
265 mData.address.cloneTo(aAddress);
266
267 return S_OK;
268}
269
270STDMETHODIMP RemoteUSBDevice::COMGETTER(Port) (USHORT *aPort)
271{
272 CheckComArgOutPointerValid(aPort);
273
274 AutoCaller autoCaller(this);
275 if (FAILED(autoCaller.rc())) return autoCaller.rc();
276
277 /* this is const, no need to lock */
278 *aPort = mData.port;
279
280 return S_OK;
281}
282
283STDMETHODIMP RemoteUSBDevice::COMGETTER(Version) (USHORT *aVersion)
284{
285 CheckComArgOutPointerValid(aVersion);
286
287 AutoCaller autoCaller(this);
288 if (FAILED(autoCaller.rc())) return autoCaller.rc();
289
290 /* this is const, no need to lock */
291 *aVersion = mData.version;
292
293 return S_OK;
294}
295
296STDMETHODIMP RemoteUSBDevice::COMGETTER(PortVersion) (USHORT *aPortVersion)
297{
298 CheckComArgOutPointerValid(aPortVersion);
299
300 AutoCaller autoCaller(this);
301 if (FAILED(autoCaller.rc())) return autoCaller.rc();
302
303 /* this is const, no need to lock */
304 *aPortVersion = mData.portVersion;
305
306 return S_OK;
307}
308
309STDMETHODIMP RemoteUSBDevice::COMGETTER(Speed) (USBConnectionSpeed_T *aSpeed)
310{
311 CheckComArgOutPointerValid(aSpeed);
312
313 AutoCaller autoCaller(this);
314 if (FAILED(autoCaller.rc())) return autoCaller.rc();
315
316 /* this is const, no need to lock */
317 *aSpeed = mData.speed;
318
319 return S_OK;
320}
321
322STDMETHODIMP RemoteUSBDevice::COMGETTER(Remote) (BOOL *aRemote)
323{
324 CheckComArgOutPointerValid(aRemote);
325
326 AutoCaller autoCaller(this);
327 if (FAILED(autoCaller.rc())) return autoCaller.rc();
328
329 /* RemoteUSBDevice is always remote. */
330 /* this is const, no need to lock */
331 *aRemote = TRUE;
332
333 return S_OK;
334}
335
336// IHostUSBDevice properties
337////////////////////////////////////////////////////////////////////////////////
338
339STDMETHODIMP RemoteUSBDevice::COMGETTER(State) (USBDeviceState_T *aState)
340{
341 CheckComArgOutPointerValid(aState);
342
343 AutoCaller autoCaller(this);
344 if (FAILED(autoCaller.rc())) return autoCaller.rc();
345
346 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
347
348 *aState = mData.state;
349
350 return S_OK;
351}
352
353// public methods only for internal purposes
354////////////////////////////////////////////////////////////////////////////////
355/* vi: set tabstop=4 shiftwidth=4 expandtab: */
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