[13659] | 1 | /* $Id: RemoteUSBDeviceImpl.cpp 100521 2023-07-11 16:47:42Z vboxsync $ */
|
---|
[1] | 2 | /** @file
|
---|
[67914] | 3 | * VirtualBox IHostUSBDevice COM interface implementation for remote (VRDP) USB devices.
|
---|
[1] | 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[98103] | 7 | * Copyright (C) 2006-2023 Oracle and/or its affiliates.
|
---|
[1] | 8 | *
|
---|
[96407] | 9 | * This file is part of VirtualBox base platform packages, as
|
---|
| 10 | * available from https://www.virtualbox.org.
|
---|
| 11 | *
|
---|
| 12 | * This program is free software; you can redistribute it and/or
|
---|
| 13 | * modify it under the terms of the GNU General Public License
|
---|
| 14 | * as published by the Free Software Foundation, in version 3 of the
|
---|
| 15 | * License.
|
---|
| 16 | *
|
---|
| 17 | * This program is distributed in the hope that it will be useful, but
|
---|
| 18 | * WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
| 20 | * General Public License for more details.
|
---|
| 21 | *
|
---|
| 22 | * You should have received a copy of the GNU General Public License
|
---|
| 23 | * along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
| 24 | *
|
---|
| 25 | * SPDX-License-Identifier: GPL-3.0-only
|
---|
[1] | 26 | */
|
---|
| 27 |
|
---|
[67914] | 28 | #define LOG_GROUP LOG_GROUP_MAIN_HOSTUSBDEVICE
|
---|
| 29 | #include "LoggingNew.h"
|
---|
| 30 |
|
---|
[1] | 31 | #include "RemoteUSBDeviceImpl.h"
|
---|
[25860] | 32 |
|
---|
| 33 | #include "AutoCaller.h"
|
---|
[1] | 34 |
|
---|
[30681] | 35 | #include <iprt/cpp/utils.h>
|
---|
| 36 |
|
---|
[76474] | 37 | #include <iprt/errcore.h>
|
---|
[1] | 38 |
|
---|
[33004] | 39 | #include <VBox/RemoteDesktop/VRDE.h>
|
---|
[1] | 40 | #include <VBox/vrdpusb.h>
|
---|
| 41 |
|
---|
[67914] | 42 |
|
---|
[1] | 43 | // constructor / destructor
|
---|
| 44 | /////////////////////////////////////////////////////////////////////////////
|
---|
| 45 |
|
---|
[56584] | 46 | DEFINE_EMPTY_CTOR_DTOR(RemoteUSBDevice)
|
---|
[1] | 47 |
|
---|
| 48 | HRESULT RemoteUSBDevice::FinalConstruct()
|
---|
| 49 | {
|
---|
[35638] | 50 | return BaseFinalConstruct();
|
---|
[1] | 51 | }
|
---|
| 52 |
|
---|
| 53 | void RemoteUSBDevice::FinalRelease()
|
---|
| 54 | {
|
---|
[13659] | 55 | uninit();
|
---|
[35638] | 56 | BaseFinalRelease();
|
---|
[1] | 57 | }
|
---|
| 58 |
|
---|
| 59 | // public initializer/uninitializer for internal purposes only
|
---|
| 60 | /////////////////////////////////////////////////////////////////////////////
|
---|
| 61 |
|
---|
| 62 | /** @todo (sunlover) REMOTE_USB Device states. */
|
---|
| 63 |
|
---|
| 64 | /**
|
---|
| 65 | * Initializes the remote USB device object.
|
---|
| 66 | */
|
---|
[100521] | 67 | HRESULT RemoteUSBDevice::init(uint32_t u32ClientId, VRDEUSBDEVICEDESC const *pDevDesc, bool fDescExt)
|
---|
[1] | 68 | {
|
---|
[21878] | 69 | LogFlowThisFunc(("u32ClientId=%d,pDevDesc=%p\n", u32ClientId, pDevDesc));
|
---|
[1] | 70 |
|
---|
[13659] | 71 | /* Enclose the state transition NotReady->InInit->Ready */
|
---|
[21878] | 72 | AutoInitSpan autoInitSpan(this);
|
---|
| 73 | AssertReturn(autoInitSpan.isOk(), E_FAIL);
|
---|
[1] | 74 |
|
---|
[21878] | 75 | unconst(mData.id).create();
|
---|
[1] | 76 |
|
---|
[21878] | 77 | unconst(mData.vendorId) = pDevDesc->idVendor;
|
---|
| 78 | unconst(mData.productId) = pDevDesc->idProduct;
|
---|
| 79 | unconst(mData.revision) = pDevDesc->bcdRev;
|
---|
[1] | 80 |
|
---|
[56584] | 81 | unconst(mData.manufacturer) = pDevDesc->oManufacturer ? (char *)pDevDesc + pDevDesc->oManufacturer : "";
|
---|
| 82 | unconst(mData.product) = pDevDesc->oProduct ? (char *)pDevDesc + pDevDesc->oProduct : "";
|
---|
| 83 | unconst(mData.serialNumber) = pDevDesc->oSerialNumber ? (char *)pDevDesc + pDevDesc->oSerialNumber : "";
|
---|
[1] | 84 |
|
---|
| 85 | char id[64];
|
---|
[56584] | 86 | RTStrPrintf(id, sizeof(id), REMOTE_USB_BACKEND_PREFIX_S "0x%08X&0x%08X", pDevDesc->id, u32ClientId);
|
---|
[21878] | 87 | unconst(mData.address) = id;
|
---|
[59122] | 88 | unconst(mData.backend) = "vrdp";
|
---|
[1] | 89 |
|
---|
[81667] | 90 | char port[16];
|
---|
| 91 | RTStrPrintf(port, sizeof(port), "%u", pDevDesc->idPort);
|
---|
| 92 | unconst(mData.portPath) = port;
|
---|
| 93 |
|
---|
[21878] | 94 | unconst(mData.port) = pDevDesc->idPort;
|
---|
[62379] | 95 | unconst(mData.version) = (uint16_t)(pDevDesc->bcdUSB >> 8);
|
---|
[38911] | 96 | if (fDescExt)
|
---|
| 97 | {
|
---|
| 98 | VRDEUSBDEVICEDESCEXT *pDevDescExt = (VRDEUSBDEVICEDESCEXT *)pDevDesc;
|
---|
| 99 | switch (pDevDescExt->u16DeviceSpeed)
|
---|
| 100 | {
|
---|
| 101 | default:
|
---|
| 102 | case VRDE_USBDEVICESPEED_UNKNOWN:
|
---|
| 103 | case VRDE_USBDEVICESPEED_LOW:
|
---|
| 104 | case VRDE_USBDEVICESPEED_FULL:
|
---|
[53297] | 105 | unconst(mData.speed) = USBConnectionSpeed_Full;
|
---|
[38911] | 106 | break;
|
---|
[1] | 107 |
|
---|
[38911] | 108 | case VRDE_USBDEVICESPEED_HIGH:
|
---|
| 109 | case VRDE_USBDEVICESPEED_VARIABLE:
|
---|
[53297] | 110 | unconst(mData.speed) = USBConnectionSpeed_High;
|
---|
[38911] | 111 | break;
|
---|
[53297] | 112 |
|
---|
| 113 | case VRDE_USBDEVICESPEED_SUPERSPEED:
|
---|
| 114 | unconst(mData.speed) = USBConnectionSpeed_Super;
|
---|
| 115 | break;
|
---|
[38911] | 116 | }
|
---|
| 117 | }
|
---|
| 118 | else
|
---|
| 119 | {
|
---|
[72980] | 120 | unconst(mData.speed) = mData.version == 3 ? USBConnectionSpeed_Super
|
---|
| 121 | : mData.version == 2 ? USBConnectionSpeed_High
|
---|
| 122 | : USBConnectionSpeed_Full;
|
---|
[38911] | 123 | }
|
---|
| 124 |
|
---|
[13659] | 125 | mData.state = USBDeviceState_Available;
|
---|
[1] | 126 |
|
---|
[13659] | 127 | mData.dirty = false;
|
---|
[62379] | 128 | unconst(mData.devId) = (uint16_t)pDevDesc->id;
|
---|
[1] | 129 |
|
---|
[21878] | 130 | unconst(mData.clientId) = u32ClientId;
|
---|
[1] | 131 |
|
---|
[13659] | 132 | /* Confirm a successful initialization */
|
---|
| 133 | autoInitSpan.setSucceeded();
|
---|
| 134 |
|
---|
[1] | 135 | return S_OK;
|
---|
| 136 | }
|
---|
| 137 |
|
---|
| 138 |
|
---|
| 139 | /**
|
---|
| 140 | * Uninitializes the instance and sets the ready flag to FALSE.
|
---|
| 141 | * Called either from FinalRelease() or by the parent when it gets destroyed.
|
---|
| 142 | */
|
---|
| 143 | void RemoteUSBDevice::uninit()
|
---|
| 144 | {
|
---|
[21878] | 145 | LogFlowThisFunc(("\n"));
|
---|
[1] | 146 |
|
---|
[13659] | 147 | /* Enclose the state transition Ready->InUninit->NotReady */
|
---|
[21878] | 148 | AutoUninitSpan autoUninitSpan(this);
|
---|
[13659] | 149 | if (autoUninitSpan.uninitDone())
|
---|
| 150 | return;
|
---|
[1] | 151 |
|
---|
[21878] | 152 | unconst(mData.id).clear();
|
---|
[13659] | 153 |
|
---|
[21878] | 154 | unconst(mData.vendorId) = 0;
|
---|
| 155 | unconst(mData.productId) = 0;
|
---|
| 156 | unconst(mData.revision) = 0;
|
---|
[13659] | 157 |
|
---|
[21878] | 158 | unconst(mData.manufacturer).setNull();
|
---|
| 159 | unconst(mData.product).setNull();
|
---|
| 160 | unconst(mData.serialNumber).setNull();
|
---|
[13659] | 161 |
|
---|
[21878] | 162 | unconst(mData.address).setNull();
|
---|
[59117] | 163 | unconst(mData.backend).setNull();
|
---|
[13659] | 164 |
|
---|
[21878] | 165 | unconst(mData.port) = 0;
|
---|
[81667] | 166 | unconst(mData.portPath).setNull();
|
---|
[21878] | 167 | unconst(mData.version) = 1;
|
---|
[13659] | 168 |
|
---|
[21878] | 169 | unconst(mData.dirty) = FALSE;
|
---|
[13659] | 170 |
|
---|
[21878] | 171 | unconst(mData.devId) = 0;
|
---|
| 172 | unconst(mData.clientId) = 0;
|
---|
[1] | 173 | }
|
---|
| 174 |
|
---|
| 175 | // IUSBDevice properties
|
---|
| 176 | /////////////////////////////////////////////////////////////////////////////
|
---|
| 177 |
|
---|
[56584] | 178 | HRESULT RemoteUSBDevice::getId(com::Guid &aId)
|
---|
[1] | 179 | {
|
---|
[56584] | 180 | aId = mData.id;
|
---|
[1] | 181 |
|
---|
| 182 | return S_OK;
|
---|
| 183 | }
|
---|
| 184 |
|
---|
[56584] | 185 | HRESULT RemoteUSBDevice::getVendorId(USHORT *aVendorId)
|
---|
[1] | 186 | {
|
---|
[13659] | 187 | /* this is const, no need to lock */
|
---|
| 188 | *aVendorId = mData.vendorId;
|
---|
| 189 |
|
---|
[1] | 190 | return S_OK;
|
---|
| 191 | }
|
---|
| 192 |
|
---|
[56584] | 193 | HRESULT RemoteUSBDevice::getProductId(USHORT *aProductId)
|
---|
[1] | 194 | {
|
---|
[13659] | 195 | /* this is const, no need to lock */
|
---|
| 196 | *aProductId = mData.productId;
|
---|
| 197 |
|
---|
[1] | 198 | return S_OK;
|
---|
| 199 | }
|
---|
| 200 |
|
---|
[56584] | 201 | HRESULT RemoteUSBDevice::getRevision(USHORT *aRevision)
|
---|
[1] | 202 | {
|
---|
[13659] | 203 | /* this is const, no need to lock */
|
---|
| 204 | *aRevision = mData.revision;
|
---|
| 205 |
|
---|
[1] | 206 | return S_OK;
|
---|
| 207 | }
|
---|
| 208 |
|
---|
[56584] | 209 | HRESULT RemoteUSBDevice::getManufacturer(com::Utf8Str &aManufacturer)
|
---|
[1] | 210 | {
|
---|
[13659] | 211 | /* this is const, no need to lock */
|
---|
[56584] | 212 | aManufacturer = mData.manufacturer;
|
---|
[13659] | 213 |
|
---|
[1] | 214 | return S_OK;
|
---|
| 215 | }
|
---|
| 216 |
|
---|
[56584] | 217 | HRESULT RemoteUSBDevice::getProduct(com::Utf8Str &aProduct)
|
---|
[1] | 218 | {
|
---|
[13659] | 219 | /* this is const, no need to lock */
|
---|
[56584] | 220 | aProduct = mData.product;
|
---|
[13659] | 221 |
|
---|
[1] | 222 | return S_OK;
|
---|
| 223 | }
|
---|
| 224 |
|
---|
[56584] | 225 | HRESULT RemoteUSBDevice::getSerialNumber(com::Utf8Str &aSerialNumber)
|
---|
[1] | 226 | {
|
---|
[13659] | 227 | /* this is const, no need to lock */
|
---|
[56584] | 228 | aSerialNumber = mData.serialNumber;
|
---|
[13659] | 229 |
|
---|
[1] | 230 | return S_OK;
|
---|
| 231 | }
|
---|
| 232 |
|
---|
[56584] | 233 | HRESULT RemoteUSBDevice::getAddress(com::Utf8Str &aAddress)
|
---|
[1] | 234 | {
|
---|
[13659] | 235 | /* this is const, no need to lock */
|
---|
[56584] | 236 | aAddress = mData.address;
|
---|
[13659] | 237 |
|
---|
[1] | 238 | return S_OK;
|
---|
| 239 | }
|
---|
| 240 |
|
---|
[56584] | 241 | HRESULT RemoteUSBDevice::getPort(USHORT *aPort)
|
---|
[1] | 242 | {
|
---|
[13659] | 243 | /* this is const, no need to lock */
|
---|
| 244 | *aPort = mData.port;
|
---|
| 245 |
|
---|
[1] | 246 | return S_OK;
|
---|
| 247 | }
|
---|
| 248 |
|
---|
[81667] | 249 | HRESULT RemoteUSBDevice::getPortPath(com::Utf8Str &aPortPath)
|
---|
[5528] | 250 | {
|
---|
[13659] | 251 | /* this is const, no need to lock */
|
---|
[81667] | 252 | aPortPath = mData.portPath;
|
---|
[13659] | 253 |
|
---|
[5528] | 254 | return S_OK;
|
---|
| 255 | }
|
---|
| 256 |
|
---|
[81667] | 257 | HRESULT RemoteUSBDevice::getVersion(USHORT *aVersion)
|
---|
[5528] | 258 | {
|
---|
[13659] | 259 | /* this is const, no need to lock */
|
---|
[81667] | 260 | *aVersion = mData.version;
|
---|
[13659] | 261 |
|
---|
[5528] | 262 | return S_OK;
|
---|
| 263 | }
|
---|
| 264 |
|
---|
[56584] | 265 | HRESULT RemoteUSBDevice::getSpeed(USBConnectionSpeed_T *aSpeed)
|
---|
[53297] | 266 | {
|
---|
| 267 | /* this is const, no need to lock */
|
---|
| 268 | *aSpeed = mData.speed;
|
---|
| 269 |
|
---|
| 270 | return S_OK;
|
---|
| 271 | }
|
---|
| 272 |
|
---|
[56584] | 273 | HRESULT RemoteUSBDevice::getRemote(BOOL *aRemote)
|
---|
[1] | 274 | {
|
---|
| 275 | /* RemoteUSBDevice is always remote. */
|
---|
[13659] | 276 | /* this is const, no need to lock */
|
---|
[1] | 277 | *aRemote = TRUE;
|
---|
[13659] | 278 |
|
---|
[1] | 279 | return S_OK;
|
---|
| 280 | }
|
---|
| 281 |
|
---|
[59117] | 282 | HRESULT RemoteUSBDevice::getBackend(com::Utf8Str &aBackend)
|
---|
| 283 | {
|
---|
| 284 | /* this is const, no need to lock */
|
---|
| 285 | aBackend = mData.backend;
|
---|
| 286 |
|
---|
| 287 | return S_OK;
|
---|
| 288 | }
|
---|
| 289 |
|
---|
[59381] | 290 | HRESULT RemoteUSBDevice::getDeviceInfo(std::vector<com::Utf8Str> &aInfo)
|
---|
| 291 | {
|
---|
| 292 | /* this is const, no need to lock */
|
---|
| 293 | aInfo.resize(2);
|
---|
| 294 | aInfo[0] = mData.manufacturer;
|
---|
| 295 | aInfo[1] = mData.product;
|
---|
| 296 |
|
---|
| 297 | return S_OK;
|
---|
| 298 | }
|
---|
| 299 |
|
---|
[1] | 300 | // IHostUSBDevice properties
|
---|
[14972] | 301 | ////////////////////////////////////////////////////////////////////////////////
|
---|
[1] | 302 |
|
---|
[56584] | 303 | HRESULT RemoteUSBDevice::getState(USBDeviceState_T *aState)
|
---|
[1] | 304 | {
|
---|
[25310] | 305 | AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
|
---|
[13659] | 306 |
|
---|
| 307 | *aState = mData.state;
|
---|
| 308 |
|
---|
[1] | 309 | return S_OK;
|
---|
| 310 | }
|
---|
| 311 |
|
---|
| 312 | // public methods only for internal purposes
|
---|
| 313 | ////////////////////////////////////////////////////////////////////////////////
|
---|
[14772] | 314 | /* vi: set tabstop=4 shiftwidth=4 expandtab: */
|
---|