HostUSBDeviceImpl.cpp revision 3ae1af412a33395845eaefd272ec486551a78a25
fa9e4066f08beec538e775443c5be79dd423fcabahrens * VirtualBox IHostUSBDevice COM interface implementation
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Copyright (C) 2006-2007 innotek GmbH
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This file is part of VirtualBox Open Source Edition (OSE), as
fa9e4066f08beec538e775443c5be79dd423fcabahrens * available from http://www.virtualbox.org. This file is free software;
fa9e4066f08beec538e775443c5be79dd423fcabahrens * you can redistribute it and/or modify it under the terms of the GNU
fa9e4066f08beec538e775443c5be79dd423fcabahrens * General Public License as published by the Free Software Foundation,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * distribution. VirtualBox OSE is distributed in the hope that it will
fa9e4066f08beec538e775443c5be79dd423fcabahrens * be useful, but WITHOUT ANY WARRANTY of any kind.
fa9e4066f08beec538e775443c5be79dd423fcabahrens// constructor / destructor
fa9e4066f08beec538e775443c5be79dd423fcabahrens/////////////////////////////////////////////////////////////////////////////
fa9e4066f08beec538e775443c5be79dd423fcabahrens// public initializer/uninitializer for internal purposes only
fa9e4066f08beec538e775443c5be79dd423fcabahrens/////////////////////////////////////////////////////////////////////////////
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Initializes the USB device object.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * @returns COM result indicator
fa9e4066f08beec538e775443c5be79dd423fcabahrens * @param aUsb Pointer to the usb device structure for which the object is to be a wrapper.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This structure is now fully owned by the HostUSBDevice object and will be
fa9e4066f08beec538e775443c5be79dd423fcabahrens * freed when it is destructed.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * @param aUSBProxyService Pointer to the USB Proxy Service object.
fa9e4066f08beec538e775443c5be79dd423fcabahrensHRESULT HostUSBDevice::init(PUSBDEVICE aUsb, USBProxyService *aUSBProxyService)
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* Enclose the state transition NotReady->InInit->Ready */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * We need a unique ID for this VBoxSVC session.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The UUID isn't stored anywhere.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Convert from USBDEVICESTATE to USBDeviceState.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Note that not all proxy backend can detect the HELD_BY_PROXY
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and USED_BY_GUEST states. But that shouldn't matter much.
fa9e4066f08beec538e775443c5be79dd423fcabahrens AssertMsgFailed(("aUsb->enmState=%d\n", aUsb->enmState));
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* @todo USBDEVICESTATE_USED_BY_GUEST seems not to be used
fa9e4066f08beec538e775443c5be79dd423fcabahrens * anywhere in the proxy code; it's quite logical because the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * proxy doesn't know anything about guest VMs. */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* Other data members */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* Confirm the successful initialization */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Uninitializes the instance and sets the ready flag to FALSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Called either from FinalRelease() or by the parent when it gets destroyed.
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* Enclose the state transition Ready->InUninit->NotReady */
fa9e4066f08beec538e775443c5be79dd423fcabahrens// IUSBDevice properties
fa9e4066f08beec538e775443c5be79dd423fcabahrens/////////////////////////////////////////////////////////////////////////////
fa9e4066f08beec538e775443c5be79dd423fcabahrensSTDMETHODIMP HostUSBDevice::COMGETTER(Id)(GUIDPARAMOUT aId)
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* mId is constant during life time, no need to lock */
fa9e4066f08beec538e775443c5be79dd423fcabahrensSTDMETHODIMP HostUSBDevice::COMGETTER(VendorId)(USHORT *aVendorId)
fa9e4066f08beec538e775443c5be79dd423fcabahrensSTDMETHODIMP HostUSBDevice::COMGETTER(ProductId)(USHORT *aProductId)
fa9e4066f08beec538e775443c5be79dd423fcabahrensSTDMETHODIMP HostUSBDevice::COMGETTER(Revision)(USHORT *aRevision)
fa9e4066f08beec538e775443c5be79dd423fcabahrensSTDMETHODIMP HostUSBDevice::COMGETTER(Manufacturer)(BSTR *aManufacturer)
fa9e4066f08beec538e775443c5be79dd423fcabahrens Bstr (mUsb->pszManufacturer).cloneTo (aManufacturer);
fa9e4066f08beec538e775443c5be79dd423fcabahrensSTDMETHODIMP HostUSBDevice::COMGETTER(Product)(BSTR *aProduct)
b19a79ec1a527828a60c4d325ccd8dcbeb2b2e8bperrinSTDMETHODIMP HostUSBDevice::COMGETTER(SerialNumber)(BSTR *aSerialNumber)
fa9e4066f08beec538e775443c5be79dd423fcabahrens Bstr (mUsb->pszSerialNumber).cloneTo (aSerialNumber);
fa9e4066f08beec538e775443c5be79dd423fcabahrensSTDMETHODIMP HostUSBDevice::COMGETTER(Address)(BSTR *aAddress)
fa9e4066f08beec538e775443c5be79dd423fcabahrensSTDMETHODIMP HostUSBDevice::COMGETTER(Port)(USHORT *aPort)
fa9e4066f08beec538e775443c5be79dd423fcabahrens ///@todo implement
fa9e4066f08beec538e775443c5be79dd423fcabahrensSTDMETHODIMP HostUSBDevice::COMGETTER(Version)(USHORT *aVersion)
b19a79ec1a527828a60c4d325ccd8dcbeb2b2e8bperrinSTDMETHODIMP HostUSBDevice::COMGETTER(PortVersion)(USHORT *aPortVersion)
fa9e4066f08beec538e775443c5be79dd423fcabahrens /** @todo implement this correctly or things just won't work right, see the vista defect. */
fa9e4066f08beec538e775443c5be79dd423fcabahrensSTDMETHODIMP HostUSBDevice::COMGETTER(Remote)(BOOL *aRemote)
fa9e4066f08beec538e775443c5be79dd423fcabahrens// IHostUSBDevice properties
fa9e4066f08beec538e775443c5be79dd423fcabahrens/////////////////////////////////////////////////////////////////////////////
b19a79ec1a527828a60c4d325ccd8dcbeb2b2e8bperrinSTDMETHODIMP HostUSBDevice::COMGETTER(State) (USBDeviceState_T *aState)
fa9e4066f08beec538e775443c5be79dd423fcabahrens// public methods only for internal purposes
fa9e4066f08beec538e775443c5be79dd423fcabahrens////////////////////////////////////////////////////////////////////////////////
fa9e4066f08beec538e775443c5be79dd423fcabahrens * @note Locks this object for reading.
fa9e4066f08beec538e775443c5be79dd423fcabahrens bool haveManufacturer = mUsb->pszManufacturer && *mUsb->pszManufacturer;
fa9e4066f08beec538e775443c5be79dd423fcabahrens bool haveProduct = mUsb->pszProduct && *mUsb->pszProduct;
return name;
mIsStatePending = true;
mPendingSince = 0;
mIsStatePending = false;
mIsStatePending = true;
mIsStatePending = true;
mIsStatePending = true;
mIsStatePending = true;
mPendingSince = 0;
mIsStatePending = false;
AssertReturnVoid (mState != USBDeviceState_USBDeviceCaptured || mPendingStateEx != kNothingPending);
bool wasCapture = false;
switch (mPendingStateEx)
case kNothingPending:
switch (mPendingState)
wasCapture = true;
wasCapture = true;
AssertFailed();
case kDetachingPendingAttach:
case kDetachingPendingDetach:
if (wasCapture)
mIsStatePending = false;
mIsStatePending = false;
switch (mPendingStateEx)
case kNothingPending:
switch (mPendingState)
if (!aTimeout)
if (aTimeout)
mIsStatePending = false;
AssertFailed();
case kDetachingPendingDetach:
case kDetachingPendingAttach:
mIsStatePending = false;
#ifndef VBOX_WITH_USBFILTER
#if !defined (RT_OS_WINDOWS)
if (iDiff)
return iDiff;
if (iDiff)
return iDiff;
if (iDiff)
return iDiff;
if (!aIsStrict)
bool isImportant = false;
switch (mState)
return isImportant;
switch (mState)
isImportant = false;
#ifndef RT_OS_WINDOWS /* Only windows really knows whether the device is unavailable or captured. */
if (!mIsStatePending)
isImportant = true;
return isImportant;
switch (mState)
isImportant = false;
if (!mIsStatePending)
isImportant = true;
return isImportant;
case USBDEVICESTATE_UNUSED:
switch (mState)
#if defined(RT_OS_LINUX) /* Hack for /proc/bus/usb/devices not necessarily putting up a driver. */ \
if ( !mIsStatePending
isImportant = true;
isImportant = false;
isImportant = true;
return isImportant;
switch (mState)
if (!mIsStatePending)
AssertFailed();
switch (mState)
LogRel (("USB: Async operation timed out; mPendingState=%d mPendingStateEx=%d idVendor=%04x (%s) idProduct=%04x (%s) bcdDevice=%04x\n",
mPendingState, mPendingStateEx, mUsb->idVendor, mUsb->pszManufacturer, mUsb->idProduct, mUsb->pszProduct, mUsb->bcdDevice));
cancelPendingState (true);
switch (aStage)
case kDetachingPendingDetach:
mIsStatePending = true;
case kDetachingPendingAttach:
AssertFailedReturn (false);