HostUSBDeviceImpl.cpp revision c79efcf08c72772e87ae3daeb97064f93d890e50
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/** @file
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync *
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * VirtualBox IHostUSBDevice COM interface implementation
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/*
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Copyright (C) 2006 InnoTek Systemberatung GmbH
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync *
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * available from http://www.virtualbox.org. This file is free software;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * you can redistribute it and/or modify it under the terms of the GNU
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * General Public License as published by the Free Software Foundation,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync *
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * If you received this file as part of a commercial VirtualBox
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * distribution, then only the terms of your commercial VirtualBox
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * license agreement apply instead of the previous paragraph.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#include "HostUSBDeviceImpl.h"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#include "USBProxyService.h"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#include "Logging.h"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#include <VBox/err.h>
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync// constructor / destructor
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/////////////////////////////////////////////////////////////////////////////
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncDEFINE_EMPTY_CTOR_DTOR (HostUSBDevice)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncHRESULT HostUSBDevice::FinalConstruct()
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync{
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mUSBProxyService = NULL;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mUsb = NULL;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return S_OK;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncvoid HostUSBDevice::FinalRelease()
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync{
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync uninit();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync// public initializer/uninitializer for internal purposes only
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/////////////////////////////////////////////////////////////////////////////
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/**
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Initializes the USB device object.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync *
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @returns COM result indicator
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @param aUsb Pointer to the usb device structure for which the object is to be a wrapper.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * This structure is now fully owned by the HostUSBDevice object and will be
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * freed when it is destructed.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * @param aUSBProxyService Pointer to the USB Proxy Service object.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncHRESULT HostUSBDevice::init(PUSBDEVICE aUsb, USBProxyService *aUSBProxyService)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync{
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ComAssertRet (aUsb, E_INVALIDARG);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* Enclose the state transition NotReady->InInit->Ready */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoInitSpan autoInitSpan (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AssertReturn (autoInitSpan.isOk(), E_UNEXPECTED);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /*
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * We need a unique ID for this VBoxSVC session.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * The UUID isn't stored anywhere.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync unconst (mId).create();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /*
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Convert from USBDEVICESTATE to USBDeviceState.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync *
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Note that not all proxy backend can detect the HELD_BY_PROXY
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * and USED_BY_GUEST states. But that shouldn't matter much.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync switch (aUsb->enmState)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync {
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync default:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AssertMsgFailed(("aUsb->enmState=%d\n", aUsb->enmState));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync case USBDEVICESTATE_UNSUPPORTED:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mState = USBDeviceState_USBDeviceNotSupported;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync case USBDEVICESTATE_USED_BY_HOST:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mState = USBDeviceState_USBDeviceUnavailable;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync case USBDEVICESTATE_USED_BY_HOST_CAPTURABLE:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mState = USBDeviceState_USBDeviceBusy;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync case USBDEVICESTATE_UNUSED:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mState = USBDeviceState_USBDeviceAvailable;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync case USBDEVICESTATE_HELD_BY_PROXY:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mState = USBDeviceState_USBDeviceHeld;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync case USBDEVICESTATE_USED_BY_GUEST:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mState = USBDeviceState_USBDeviceCaptured;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync }
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mPendingState = mState;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* Other data members */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mIsStatePending = false;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/// @todo remove
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#if 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mIgnored = false;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#endif
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mUSBProxyService = aUSBProxyService;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mUsb = aUsb;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* Confirm the successful initialization */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync autoInitSpan.setSucceeded();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return S_OK;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/**
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Uninitializes the instance and sets the ready flag to FALSE.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync * Called either from FinalRelease() or by the parent when it gets destroyed.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncvoid HostUSBDevice::uninit()
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync{
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* Enclose the state transition Ready->InUninit->NotReady */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoUninitSpan autoUninitSpan (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (autoUninitSpan.uninitDone())
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (mUsb != NULL)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync {
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync USBProxyService::freeDevice (mUsb);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mUsb = NULL;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync }
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mUSBProxyService = NULL;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync// IUSBDevice properties
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/////////////////////////////////////////////////////////////////////////////
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncSTDMETHODIMP HostUSBDevice::COMGETTER(Id)(GUIDPARAMOUT aId)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync{
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (!aId)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return E_INVALIDARG;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoCaller autoCaller (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync CheckComRCReturnRC (autoCaller.rc());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync /* mId is constant during life time, no need to lock */
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mId.cloneTo (aId);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return S_OK;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncSTDMETHODIMP HostUSBDevice::COMGETTER(VendorId)(USHORT *aVendorId)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync{
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (!aVendorId)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return E_INVALIDARG;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoCaller autoCaller (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync CheckComRCReturnRC (autoCaller.rc());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoReaderLock alock (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync *aVendorId = mUsb->idVendor;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return S_OK;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncSTDMETHODIMP HostUSBDevice::COMGETTER(ProductId)(USHORT *aProductId)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync{
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (!aProductId)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return E_INVALIDARG;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoCaller autoCaller (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync CheckComRCReturnRC (autoCaller.rc());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoReaderLock alock (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync *aProductId = mUsb->idProduct;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return S_OK;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncSTDMETHODIMP HostUSBDevice::COMGETTER(Revision)(USHORT *aRevision)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync{
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (!aRevision)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return E_INVALIDARG;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoCaller autoCaller (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync CheckComRCReturnRC (autoCaller.rc());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoReaderLock alock (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync *aRevision = mUsb->bcdDevice;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return S_OK;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncSTDMETHODIMP HostUSBDevice::COMGETTER(Manufacturer)(BSTR *aManufacturer)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync{
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (!aManufacturer)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return E_INVALIDARG;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoCaller autoCaller (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync CheckComRCReturnRC (autoCaller.rc());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoReaderLock alock (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Bstr (mUsb->pszManufacturer).cloneTo (aManufacturer);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return S_OK;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncSTDMETHODIMP HostUSBDevice::COMGETTER(Product)(BSTR *aProduct)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync{
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (!aProduct)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return E_INVALIDARG;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoCaller autoCaller (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync CheckComRCReturnRC (autoCaller.rc());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoReaderLock alock (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Bstr (mUsb->pszProduct).cloneTo (aProduct);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return S_OK;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncSTDMETHODIMP HostUSBDevice::COMGETTER(SerialNumber)(BSTR *aSerialNumber)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync{
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (!aSerialNumber)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return E_INVALIDARG;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoCaller autoCaller (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync CheckComRCReturnRC (autoCaller.rc());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoReaderLock alock (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Bstr (mUsb->pszSerialNumber).cloneTo (aSerialNumber);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return S_OK;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncSTDMETHODIMP HostUSBDevice::COMGETTER(Address)(BSTR *aAddress)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync{
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (!aAddress)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return E_INVALIDARG;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoCaller autoCaller (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync CheckComRCReturnRC (autoCaller.rc());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoReaderLock alock (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Bstr (mUsb->pszAddress).cloneTo (aAddress);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return S_OK;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncSTDMETHODIMP HostUSBDevice::COMGETTER(Port)(USHORT *aPort)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync{
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (!aPort)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return E_INVALIDARG;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoCaller autoCaller (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync CheckComRCReturnRC (autoCaller.rc());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoReaderLock alock (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ///@todo implement
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aPort = 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return S_OK;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncSTDMETHODIMP HostUSBDevice::COMGETTER(Remote)(BOOL *aRemote)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync{
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (!aRemote)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return E_INVALIDARG;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoCaller autoCaller (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync CheckComRCReturnRC (autoCaller.rc());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync AutoReaderLock alock (this);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync *aRemote = FALSE;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return S_OK;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync// IHostUSBDevice properties
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync/////////////////////////////////////////////////////////////////////////////
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncSTDMETHODIMP HostUSBDevice::COMGETTER(State) (USBDeviceState_T *aState)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync{
if (!aState)
return E_POINTER;
AutoCaller autoCaller (this);
CheckComRCReturnRC (autoCaller.rc());
AutoReaderLock alock (this);
*aState = mState;
return S_OK;
}
// public methods only for internal purposes
////////////////////////////////////////////////////////////////////////////////
/**
* @note Locks this object for reading.
*/
Utf8Str HostUSBDevice::name()
{
Utf8Str name;
AutoCaller autoCaller (this);
AssertComRCReturn (autoCaller.rc(), name);
AutoReaderLock alock (this);
bool haveManufacturer = mUsb->pszManufacturer && *mUsb->pszManufacturer;
bool haveProduct = mUsb->pszProduct && *mUsb->pszProduct;
if (haveManufacturer && haveProduct)
name = Utf8StrFmt ("%s %s", mUsb->pszManufacturer,
mUsb->pszProduct);
else if(haveManufacturer)
name = Utf8StrFmt ("%s", mUsb->pszManufacturer);
else if(haveProduct)
name = Utf8StrFmt ("%s", mUsb->pszManufacturer);
else
name = "<unknown>";
return name;
}
/// @todo remove
#if 0
/**
* Sets the ignored flag and returns the device to the host.
*
* @note Locks this object for writing.
*/
void HostUSBDevice::setIgnored()
{
AutoCaller autoCaller (this);
AssertComRCReturnVoid (autoCaller.rc());
AutoLock alock (this);
AssertReturnVoid (!mIgnored);
mIgnored = true;
setHostDriven();
}
#endif
/**
* @note Locks this object for writing.
*/
bool HostUSBDevice::setCaptured (SessionMachine *aMachine)
{
AssertReturn (aMachine, false);
AutoCaller autoCaller (this);
AssertComRCReturn (autoCaller.rc(), false);
AutoLock alock (this);
AssertReturn (
mState == USBDeviceState_USBDeviceBusy ||
mState == USBDeviceState_USBDeviceAvailable ||
mState == USBDeviceState_USBDeviceHeld,
false);
mState = USBDeviceState_USBDeviceCaptured;
mMachine = aMachine;
mUSBProxyService->captureDevice (this);
return true;
}
/**
* Returns the device back to the host
*
* @returns VBox status code.
*
* @note Locks this object for writing.
*/
int HostUSBDevice::setHostDriven()
{
AutoCaller autoCaller (this);
AssertComRCReturn (autoCaller.rc(), VERR_INVALID_PARAMETER);
AutoLock alock (this);
AssertReturn (mState == USBDeviceState_USBDeviceHeld, VERR_INVALID_PARAMETER);
mState = USBDeviceState_USBDeviceAvailable;
return mUSBProxyService->releaseDevice (this);
}
/**
* Resets the device as if it were just attached to the host
*
* @returns VBox status code.
*
* @note Locks this object for writing.
*/
int HostUSBDevice::reset()
{
AutoCaller autoCaller (this);
AssertComRCReturn (autoCaller.rc(), VERR_INVALID_PARAMETER);
AutoLock alock (this);
mState = USBDeviceState_USBDeviceHeld;
mMachine.setNull();
/// @todo remove
#if 0
mIgnored = false;
#endif
/** @todo this operation might fail and cause the device to the reattached with a different address and all that. */
return mUSBProxyService->resetDevice (this);
}
/// @todo remove
#if 0
/**
* Sets the state of the device, as it was reported by the host.
* This method applicable only for devices currently controlled by the host.
*
* @param aState new state
*
* @note Locks this object for writing.
*/
void HostUSBDevice::setHostState (USBDeviceState_T aState)
{
AutoCaller autoCaller (this);
AssertComRCReturnVoid (autoCaller.rc());
AutoLock alock (this);
AssertReturn (
aState == USBDeviceState_USBDeviceUnavailable ||
aState == USBDeviceState_USBDeviceBusy ||
aState == USBDeviceState_USBDeviceAvailable,
(void) 0);
AssertReturn (
mState == USBDeviceState_USBDeviceNotSupported || /* initial state */
mState == USBDeviceState_USBDeviceUnavailable ||
mState == USBDeviceState_USBDeviceBusy ||
mState == USBDeviceState_USBDeviceAvailable,
(void) 0);
if (mState != aState)
{
mState = aState;
}
}
#endif
/**
* Returns true if this device matches the given filter data.
*
* @note It is assumed, that the filter data owner is appropriately
* locked before calling this method.
*
* @note
* This method MUST correlate with
* USBController::hasMatchingFilter (IUSBDevice *)
* in the sense of the device matching logic.
*
* @note Locks this object for reading.
*/
bool HostUSBDevice::isMatch (const USBDeviceFilter::Data &aData)
{
AutoCaller autoCaller (this);
AssertComRCReturn (autoCaller.rc(), false);
AutoReaderLock alock (this);
if (!aData.mActive)
return false;
if (!aData.mVendorId.isMatch (mUsb->idVendor))
{
LogFlowMember (("HostUSBDevice::isMatch: vendor not match %04X\n",
mUsb->idVendor));
return false;
}
if (!aData.mProductId.isMatch (mUsb->idProduct))
{
LogFlowMember (("HostUSBDevice::isMatch: product id not match %04X\n",
mUsb->idProduct));
return false;
}
if (!aData.mRevision.isMatch (mUsb->bcdDevice))
{
LogFlowMember (("HostUSBDevice::isMatch: rev not match %04X\n",
mUsb->bcdDevice));
return false;
}
#if !defined (__WIN__)
// these filters are temporarily ignored on Win32
if (!aData.mManufacturer.isMatch (Bstr (mUsb->pszManufacturer)))
return false;
if (!aData.mProduct.isMatch (Bstr (mUsb->pszProduct)))
return false;
if (!aData.mSerialNumber.isMatch (Bstr (mUsb->pszSerialNumber)))
return false;
/// @todo (dmik) pusPort is yet absent
// if (!aData.mPort.isMatch (Bstr (mUsb->pusPort)))
// return false;
#endif
// Host USB devices are local, so remote is always FALSE
if (!aData.mRemote.isMatch (FALSE))
{
LogFlowMember (("Host::HostUSBDevice: remote not match FALSE\n"));
return false;
}
/// @todo (dmik): bird, I assumed isMatch() is called only for devices
// that are suitable for holding/capturing (also assuming that when the device
// is just attached it first goes to our filter driver, and only after applying
// filters goes back to the system when appropriate). So the below
// doesn't look too correct; moreover, currently there is no determinable
// "any match" state for intervalic filters, and it will be not so easy
// to determine this state for an arbitrary regexp expression...
// For now, I just check that the string filter is empty (which doesn't
// actually reflect all possible "any match" filters).
//
// bird: This method was called for any device some weeks back, and it most certainly
// should be called for 'busy' devices still. However, we do *not* want 'busy' devices
// to match empty filters (because that will for instance capture all USB keyboards & mice).
// You assumption about a filter driver is not correct on linux. We're racing with
// everyone else in the system there - see your problem with usbfs access.
//
// The customer *requires* a way of matching all devices which the host isn't using,
// if that is now difficult or the below method opens holes in the matching, this *must*
// be addresses immediately.
/*
* If all the criteria is empty, devices which are used by the host will not match.
*/
if ( mUsb->enmState == USBDEVICESTATE_USED_BY_HOST_CAPTURABLE
&& aData.mVendorId.string().isEmpty()
&& aData.mProductId.string().isEmpty()
&& aData.mRevision.string().isEmpty()
&& aData.mManufacturer.string().isEmpty()
&& aData.mProduct.string().isEmpty()
&& aData.mSerialNumber.string().isEmpty())
return false;
LogFlowMember (("HostUSBDevice::isMatch: returns true\n"));
return true;
}
/**
* Compares this device with a USBDEVICE and decides which comes first.
*
* @returns < 0 if this should come before pDev2.
* @returns 0 if this and pDev2 are equal.
* @returns > 0 if this should come after pDev2.
*
* @param pDev2 Device 2.
*/
int HostUSBDevice::compare (PCUSBDEVICE pDev2)
{
return compare (mUsb, pDev2);
}
/**
* Compares two USB devices and decides which comes first.
*
* @returns < 0 if pDev1 should come before pDev2.
* @returns 0 if pDev1 and pDev2 are equal.
* @returns > 0 if pDev1 should come after pDev2.
*
* @param pDev1 Device 1.
* @param pDev2 Device 2.
*/
/*static*/ int HostUSBDevice::compare (PCUSBDEVICE pDev1, PCUSBDEVICE pDev2)
{
int iDiff = pDev1->idVendor - pDev2->idVendor;
if (iDiff)
return iDiff;
iDiff = pDev1->idProduct - pDev2->idProduct;
if (iDiff)
return iDiff;
/** @todo Sander, will this work on windows as well? Linux won't reuse an address for quite a while. */
return strcmp(pDev1->pszAddress, pDev2->pszAddress);
}
/**
* Updates the state of the device.
*
* @return true if the state has actually changed.
* @return false if the state didn't change, or the change might have been caused by VBox.
*
* @param aDev The current device state as seen by the proxy backend.
*
* @note Locks this object for writing.
*/
bool HostUSBDevice::updateState (PCUSBDEVICE aDev)
{
AutoCaller autoCaller (this);
AssertComRCReturn (autoCaller.rc(), false);
AutoLock alock (this);
/*
* We have to be pretty conservative here because the proxy backend
* doesn't necessarily know everything that's going on. So, rather
* be overly careful than changing the state once when we shouldn't!
*/
switch (aDev->enmState)
{
default:
AssertMsgFailed (("aDev->enmState=%d\n", aDev->enmState));
case USBDEVICESTATE_UNSUPPORTED:
Assert (mState == USBDeviceState_USBDeviceNotSupported);
return false;
case USBDEVICESTATE_USED_BY_HOST:
switch (mState)
{
case USBDeviceState_USBDeviceUnavailable:
/* the proxy may confuse following states with unavailable */
case USBDeviceState_USBDeviceHeld:
case USBDeviceState_USBDeviceCaptured:
return false;
default:
LogFlowMember ((" HostUSBDevice::updateState: %d -> %d\n",
mState, USBDeviceState_USBDeviceUnavailable));
mState = USBDeviceState_USBDeviceUnavailable;
return true;
}
break;
case USBDEVICESTATE_USED_BY_HOST_CAPTURABLE:
switch (mState)
{
case USBDeviceState_USBDeviceBusy:
/* the proxy may confuse following states with capturable */
case USBDeviceState_USBDeviceHeld:
case USBDeviceState_USBDeviceCaptured:
return false;
default:
LogFlowMember ((" HostUSBDevice::updateState: %d -> %d\n",
mState, USBDeviceState_USBDeviceBusy));
mState = USBDeviceState_USBDeviceBusy;
return true;
}
break;
case USBDEVICESTATE_UNUSED:
switch (mState)
{
case USBDeviceState_USBDeviceAvailable:
/* the proxy may confuse following state(s) with available */
case USBDeviceState_USBDeviceHeld:
case USBDeviceState_USBDeviceCaptured:
return false;
default:
LogFlowMember ((" HostUSBDevice::updateState: %d -> %d\n",
mState, USBDeviceState_USBDeviceAvailable));
mState = USBDeviceState_USBDeviceAvailable;
return true;
}
break;
case USBDEVICESTATE_HELD_BY_PROXY:
switch (mState)
{
case USBDeviceState_USBDeviceHeld:
/* the proxy may confuse following state(s) with held */
case USBDeviceState_USBDeviceAvailable:
case USBDeviceState_USBDeviceBusy:
case USBDeviceState_USBDeviceCaptured:
return false;
default:
LogFlowMember ((" HostUSBDevice::updateState: %d -> %d\n",
mState, USBDeviceState_USBDeviceHeld));
mState = USBDeviceState_USBDeviceHeld;
return true;
}
break;
case USBDEVICESTATE_USED_BY_GUEST:
switch (mState)
{
case USBDeviceState_USBDeviceCaptured:
/* the proxy may confuse following state(s) with captured */
case USBDeviceState_USBDeviceHeld:
case USBDeviceState_USBDeviceAvailable:
case USBDeviceState_USBDeviceBusy:
return false;
default:
LogFlowMember ((" HostUSBDevice::updateState: %d -> %d\n",
mState, USBDeviceState_USBDeviceHeld));
mState = USBDeviceState_USBDeviceHeld;
return true;
}
break;
}
return false;
}