/** * Runs the USB filters of the machine on the device. * * If a match is found we will request capture for VM. This may cause * us to temporary abandon locks while doing IPC. * * @param aMachine Machine whose filters are to be run. * @param aDevice The USB device in question. * @returns @c true if the device has been or is being attached to the VM, @c false otherwise. * * @note Locks several objects temporarily for reading or writing. */ bool USBProxyService::runMachineFilters(SessionMachine *aMachine, ComObjPtr<HostUSBDevice> &aDevice) { LogFlowThisFunc(("{%s} aMachine=%p \n", aDevice->getName().c_str(), aMachine)); /* * Validate preconditions. */ AssertReturn(aMachine, false); AssertReturn(!isWriteLockOnCurrentThread(), false); AssertReturn(!aMachine->isWriteLockOnCurrentThread(), false); AssertReturn(!aDevice->isWriteLockOnCurrentThread(), false); /* Let HostUSBDevice::requestCaptureToVM() validate the state. */ /* * Do the job. */ ULONG ulMaskedIfs; if (aMachine->hasMatchingUSBFilter(aDevice, &ulMaskedIfs)) { /* try to capture the device */ HRESULT hrc = aDevice->requestCaptureForVM(aMachine, false /* aSetError */, ulMaskedIfs); return SUCCEEDED(hrc) || hrc == E_UNEXPECTED /* bad device state, give up */; } return false; }
/** * Request capture of a specific device. * * This is in an interface for SessionMachine::CaptureUSBDevice(), which is * an internal worker used by Console::AttachUSBDevice() from the VM process. * * When the request is completed, SessionMachine::onUSBDeviceAttach() will * be called for the given machine object. * * * @param aMachine The machine to attach the device to. * @param aId The UUID of the USB device to capture and attach. * * @returns COM status code and error info. * * @remarks This method may operate synchronously as well as asynchronously. In the * former case it will temporarily abandon locks because of IPC. */ HRESULT USBProxyService::captureDeviceForVM(SessionMachine *aMachine, IN_GUID aId) { ComAssertRet(aMachine, E_INVALIDARG); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); /* * Translate the device id into a device object. */ ComObjPtr<HostUSBDevice> pHostDevice = findDeviceById(aId); if (pHostDevice.isNull()) return setError(E_INVALIDARG, tr("The USB device with UUID {%RTuuid} is not currently attached to the host"), Guid(aId).raw()); /* * Try to capture the device */ alock.release(); return pHostDevice->requestCaptureForVM(aMachine, true /* aSetError */); }