// implementation of public methods ///////////////////////////////////////////////////////////////////////////// HRESULT Guest::createSession(const com::Utf8Str &aUser, const com::Utf8Str &aPassword, const com::Utf8Str &aDomain, const com::Utf8Str &aSessionName, ComPtr<IGuestSession> &aGuestSession) { #ifndef VBOX_WITH_GUEST_CONTROL ReturnComNotImplemented(); #else /* VBOX_WITH_GUEST_CONTROL */ LogFlowFuncEnter(); /* Do not allow anonymous sessions (with system rights) with public API. */ if (RT_UNLIKELY(!aUser.length())) return setError(E_INVALIDARG, tr("No user name specified")); GuestSessionStartupInfo startupInfo; startupInfo.mName = aSessionName; GuestCredentials guestCreds; guestCreds.mUser = aUser; guestCreds.mPassword = aPassword; guestCreds.mDomain = aDomain; ComObjPtr<GuestSession> pSession; int rc = i_sessionCreate(startupInfo, guestCreds, pSession); if (RT_SUCCESS(rc)) { /* Return guest session to the caller. */ HRESULT hr2 = pSession.queryInterfaceTo(aGuestSession.asOutParam()); if (FAILED(hr2)) rc = VERR_COM_OBJECT_NOT_FOUND; } if (RT_SUCCESS(rc)) /* Start (fork) the session asynchronously * on the guest. */ rc = pSession->i_startSessionAsync(); HRESULT hr = S_OK; if (RT_FAILURE(rc)) { switch (rc) { case VERR_MAX_PROCS_REACHED: hr = setError(VBOX_E_IPRT_ERROR, tr("Maximum number of concurrent guest sessions (%ld) reached"), VBOX_GUESTCTRL_MAX_SESSIONS); break; /** @todo Add more errors here. */ default: hr = setError(VBOX_E_IPRT_ERROR, tr("Could not create guest session: %Rrc"), rc); break; } } LogFlowThisFunc(("Returning rc=%Rhrc\n", hr)); return hr; #endif /* VBOX_WITH_GUEST_CONTROL */ }
HRESULT USBDeviceFilters::createDeviceFilter(const com::Utf8Str &aName, ComPtr<IUSBDeviceFilter> &aFilter) { #ifdef VBOX_WITH_USB /* the machine needs to be mutable */ AutoMutableStateDependency adep(m->pParent); if (FAILED(adep.rc())) return adep.rc(); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); ComObjPtr<USBDeviceFilter> pFilter; pFilter.createObject(); HRESULT rc = pFilter->init(this, Bstr(aName).raw()); ComAssertComRCRetRC(rc); rc = pFilter.queryInterfaceTo(aFilter.asOutParam()); AssertComRCReturnRC(rc); return S_OK; #else NOREF(aName); NOREF(aFilter); ReturnComNotImplemented(); #endif }
STDMETHODIMP NetworkAdapter::COMGETTER(BandwidthGroup)(IBandwidthGroup **aBwGroup) { LogFlowThisFuncEnter(); CheckComArgOutPointerValid(aBwGroup); HRESULT hrc = S_OK; AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); if (mData->mBandwidthGroup.isNotEmpty()) { ComObjPtr<BandwidthGroup> pBwGroup; hrc = mParent->getBandwidthGroup(mData->mBandwidthGroup, pBwGroup, true /* fSetError */); Assert(SUCCEEDED(hrc)); /* This is not allowed to fail because the existence of the group was checked when it was attached. */ if (SUCCEEDED(hrc)) pBwGroup.queryInterfaceTo(aBwGroup); } LogFlowThisFuncLeave(); return hrc; }
STDMETHODIMP USBController::CreateDeviceFilter (IN_BSTR aName, IUSBDeviceFilter **aFilter) { #ifdef VBOX_WITH_USB CheckComArgOutPointerValid(aFilter); CheckComArgStrNotEmptyOrNull(aName); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); /* the machine needs to be mutable */ AutoMutableStateDependency adep(m->pParent); if (FAILED(adep.rc())) return adep.rc(); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); ComObjPtr<USBDeviceFilter> filter; filter.createObject(); HRESULT rc = filter->init (this, aName); ComAssertComRCRetRC (rc); rc = filter.queryInterfaceTo(aFilter); AssertComRCReturnRC(rc); return S_OK; #else NOREF(aName); NOREF(aFilter); ReturnComNotImplemented(); #endif }
STDMETHODIMP Guest::DirectoryRead(ULONG aHandle, IGuestDirEntry **aDirEntry) { #ifndef VBOX_WITH_GUEST_CONTROL ReturnComNotImplemented(); #else /* VBOX_WITH_GUEST_CONTROL */ using namespace guestControl; CheckComArgOutPointerValid(aDirEntry); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); HRESULT hr = S_OK; try { GuestProcessStreamBlock streamBlock; int rc = directoryGetNextEntry(aHandle, streamBlock); if (RT_SUCCESS(rc)) { if (streamBlock.GetCount()) { ComObjPtr <GuestDirEntry> pDirEntry; hr = pDirEntry.createObject(); ComAssertComRC(hr); hr = pDirEntry->init(this, streamBlock); if (SUCCEEDED(hr)) { pDirEntry.queryInterfaceTo(aDirEntry); } else { #ifdef DEBUG streamBlock.DumpToLog(); #endif hr = VBOX_E_FILE_ERROR; } } else { /* No more directory entries to read. That's fine. */ hr = E_ABORT; /** @todo Find/define a better rc! */ } } else hr = setError(VBOX_E_IPRT_ERROR, Guest::tr("Failed getting next directory entry (%Rrc)"), rc); } catch (std::bad_alloc &) { hr = E_OUTOFMEMORY; } return hr; #endif }
STDMETHODIMP Guest::CreateSession(IN_BSTR aUser, IN_BSTR aPassword, IN_BSTR aDomain, IN_BSTR aSessionName, IGuestSession **aGuestSession) { #ifndef VBOX_WITH_GUEST_CONTROL ReturnComNotImplemented(); #else /* VBOX_WITH_GUEST_CONTROL */ LogFlowFuncEnter(); /* Do not allow anonymous sessions (with system rights) with official API. */ if (RT_UNLIKELY((aUser) == NULL || *(aUser) == '\0')) return setError(E_INVALIDARG, tr("No user name specified")); CheckComArgOutPointerValid(aGuestSession); /* Rest is optional. */ AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); HRESULT hr = S_OK; ComObjPtr<GuestSession> pSession; int rc = sessionCreate(aUser, aPassword, aDomain, aSessionName, pSession); if (RT_SUCCESS(rc)) { /* Return guest session to the caller. */ HRESULT hr2 = pSession.queryInterfaceTo(aGuestSession); if (FAILED(hr2)) rc = VERR_COM_OBJECT_NOT_FOUND; if (RT_SUCCESS(rc)) rc = pSession->queryInfo(); } if (RT_FAILURE(rc)) { switch (rc) { case VERR_MAX_PROCS_REACHED: hr = setError(VBOX_E_IPRT_ERROR, tr("Maximum number of guest sessions (%ld) reached"), VBOX_GUESTCTRL_MAX_SESSIONS); break; /** @todo Add more errors here. */ default: hr = setError(VBOX_E_IPRT_ERROR, tr("Could not create guest session, rc=%Rrc"), rc); break; } } LogFlowFuncLeaveRC(rc); return hr; #endif /* VBOX_WITH_GUEST_CONTROL */ }
STDMETHODIMP VFSExplorer::Remove(ComSafeArrayIn(IN_BSTR, aNames), IProgress **aProgress) { CheckComArgSafeArrayNotNull(aNames); CheckComArgOutPointerValid(aProgress); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); HRESULT rc = S_OK; com::SafeArray<IN_BSTR> sfaNames(ComSafeArrayInArg(aNames)); ComObjPtr<Progress> progress; try { /* Create the progress object */ progress.createObject(); rc = progress->init(mVirtualBox, static_cast<IVFSExplorer*>(this), Bstr(tr("Delete files")).raw(), TRUE /* aCancelable */); if (FAILED(rc)) throw rc; /* Initialize our worker task */ std::auto_ptr<TaskVFSExplorer> task(new TaskVFSExplorer(TaskVFSExplorer::Delete, this, progress)); /* Add all filenames to delete as task data */ for (size_t a=0; a < sfaNames.size(); ++a) task->filenames.push_back(Utf8Str(sfaNames[a])); rc = task->startThread(); if (FAILED(rc)) throw rc; /* Don't destruct on success */ task.release(); } catch (HRESULT aRC) { rc = aRC; } if (SUCCEEDED(rc)) /* Return progress to the caller */ progress.queryInterfaceTo(aProgress); return rc; }
int NetIfRemoveHostOnlyNetworkInterface(VirtualBox *pVirtualBox, IN_GUID aId, IProgress **aProgress) { #if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) /* create a progress object */ ComObjPtr<Progress> progress; progress.createObject(); ComPtr<IHost> host; int rc = VINF_SUCCESS; HRESULT hr = pVirtualBox->COMGETTER(Host)(host.asOutParam()); if (SUCCEEDED(hr)) { Bstr ifname; ComPtr<IHostNetworkInterface> iface; if (FAILED(host->FindHostNetworkInterfaceById(Guid(aId).toUtf16().raw(), iface.asOutParam()))) return VERR_INVALID_PARAMETER; iface->COMGETTER(Name)(ifname.asOutParam()); if (ifname.isEmpty()) return VERR_INTERNAL_ERROR; rc = progress->init(pVirtualBox, host, Bstr("Removing host network interface").raw(), FALSE /* aCancelable */); if (SUCCEEDED(rc)) { progress.queryInterfaceTo(aProgress); rc = NetIfAdpCtl(Utf8Str(ifname).c_str(), "remove", NULL, NULL); if (RT_FAILURE(rc)) progress->i_notifyComplete(E_FAIL, COM_IIDOF(IHostNetworkInterface), HostNetworkInterface::getStaticComponentName(), "Failed to execute '" VBOXNETADPCTL_NAME "' (exit status: %d)", rc); else progress->i_notifyComplete(S_OK); } } else { progress->i_notifyComplete(hr); rc = VERR_INTERNAL_ERROR; } return rc; #else NOREF(pVirtualBox); NOREF(aId); NOREF(aProgress); return VERR_NOT_IMPLEMENTED; #endif }
void BusAssignmentManager::State::listAttachedPCIDevices(std::vector<ComPtr<IPCIDeviceAttachment> > &aAttached) { aAttached.resize(mPCIMap.size()); size_t i = 0; ComObjPtr<PCIDeviceAttachment> dev; for (PCIMap::const_iterator it = mPCIMap.begin(); it != mPCIMap.end(); ++it, ++i) { dev.createObject(); com::Bstr devname(it->second.szDevName); dev->init(NULL, devname, it->second.HostAddress.valid() ? it->second.HostAddress.asLong() : -1, it->first.asLong(), it->second.HostAddress.valid()); dev.queryInterfaceTo(aAttached[i].asOutParam()); } }
STDMETHODIMP VFSExplorer::Update(IProgress **aProgress) { CheckComArgOutPointerValid(aProgress); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); HRESULT rc = S_OK; ComObjPtr<Progress> progress; try { Bstr progressDesc = BstrFmt(tr("Update directory info for '%s'"), m->strPath.c_str()); /* Create the progress object */ progress.createObject(); rc = progress->init(mVirtualBox, static_cast<IVFSExplorer*>(this), progressDesc.raw(), TRUE /* aCancelable */); if (FAILED(rc)) throw rc; /* Initialize our worker task */ std::auto_ptr<TaskVFSExplorer> task(new TaskVFSExplorer(TaskVFSExplorer::Update, this, progress)); rc = task->startThread(); if (FAILED(rc)) throw rc; /* Don't destruct on success */ task.release(); } catch (HRESULT aRC) { rc = aRC; } if (SUCCEEDED(rc)) /* Return progress to the caller */ progress.queryInterfaceTo(aProgress); return rc; }
HRESULT VFSExplorer::remove(const std::vector<com::Utf8Str> &aNames, ComPtr<IProgress> &aProgress) { AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); HRESULT rc = S_OK; ComObjPtr<Progress> progress; try { /* Create the progress object */ progress.createObject(); rc = progress->init(mVirtualBox, static_cast<IVFSExplorer*>(this), Bstr(tr("Delete files")).raw(), TRUE /* aCancelable */); if (FAILED(rc)) throw rc; /* Initialize our worker task */ std::auto_ptr<TaskVFSExplorer> task(new TaskVFSExplorer(TaskVFSExplorer::Delete, this, progress)); /* Add all filenames to delete as task data */ for (size_t i = 0; i < aNames.size(); ++i) task->filenames.push_back(aNames[i]); rc = task->startThread(); if (FAILED(rc)) throw rc; /* Don't destruct on success */ task.release(); } catch (HRESULT aRC) { rc = aRC; } if (SUCCEEDED(rc)) /* Return progress to the caller */ progress.queryInterfaceTo(aProgress.asOutParam()); return rc; }
/** * Marks the operation as complete and attaches full error info. * * See VirtualBoxBase::setError(HRESULT, const GUID &, const wchar_t * *, const char *, ...) for more info. * * @param aResultCode Operation result (error) code, must not be S_OK. * @param aIID IID of the interface that defines the error. * @param aComponent Name of the component that generates the error. * @param aText Error message (must not be null), an RTStrPrintf-like * format string in UTF-8 encoding. * @param va List of arguments for the format string. */ HRESULT Progress::i_notifyCompleteV(HRESULT aResultCode, const GUID &aIID, const char *pcszComponent, const char *aText, va_list va) { Utf8Str text(aText, va); AutoCaller autoCaller(this); AssertComRCReturnRC(autoCaller.rc()); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); AssertReturn(mCompleted == FALSE, E_FAIL); if (mCanceled && SUCCEEDED(aResultCode)) aResultCode = E_FAIL; mCompleted = TRUE; mResultCode = aResultCode; AssertReturn(FAILED(aResultCode), E_FAIL); ComObjPtr<VirtualBoxErrorInfo> errorInfo; HRESULT rc = errorInfo.createObject(); AssertComRC(rc); if (SUCCEEDED(rc)) { errorInfo->init(aResultCode, aIID, pcszComponent, text); errorInfo.queryInterfaceTo(mErrorInfo.asOutParam()); } #if !defined VBOX_COM_INPROC /* remove from the global collection of pending progress operations */ if (mParent) mParent->i_removeProgress(mId.ref()); #endif /* wake up all waiting threads */ if (mWaitersCount > 0) RTSemEventMultiSignal(mCompletedSem); return rc; }
HRESULT MediumAttachment::getBandwidthGroup(ComPtr<IBandwidthGroup> &aBandwidthGroup) { LogFlowThisFuncEnter(); AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); HRESULT hrc = S_OK; if (m->bd->mData.strBwGroup.isNotEmpty()) { ComObjPtr<BandwidthGroup> pBwGroup; hrc = m->pMachine->i_getBandwidthGroup(m->bd->mData.strBwGroup, pBwGroup, true /* fSetError */); Assert(SUCCEEDED(hrc)); /* This is not allowed to fail because the existence of the group was checked when it was attached. */ if (SUCCEEDED(hrc)) pBwGroup.queryInterfaceTo(aBandwidthGroup.asOutParam()); } LogFlowThisFuncLeave(); return hrc; }
STDMETHODIMP GuestDirectory::Read(IFsObjInfo **aInfo) { #ifndef VBOX_WITH_GUEST_CONTROL ReturnComNotImplemented(); #else LogFlowThisFuncEnter(); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); ComObjPtr<GuestProcess> pProcess = mData.mProcess; Assert(!pProcess.isNull()); GuestProcessStreamBlock streamBlock; GuestFsObjData objData; int rc = parseData(streamBlock); if ( RT_FAILURE(rc) || streamBlock.IsEmpty()) /* More data needed. */ { rc = pProcess->waitForStart(30 * 1000 /* 30s timeout */); } if (RT_SUCCESS(rc)) { BYTE byBuf[_64K]; size_t cbRead = 0; /** @todo Merge with GuestSession::queryFileInfoInternal. */ for (;RT_SUCCESS(rc);) { GuestProcessWaitResult waitRes; rc = pProcess->waitFor( ProcessWaitForFlag_Terminate | ProcessWaitForFlag_StdOut, 30 * 1000 /* Timeout */, waitRes); if ( RT_FAILURE(rc) || waitRes.mResult == ProcessWaitResult_Terminate || waitRes.mResult == ProcessWaitResult_Error || waitRes.mResult == ProcessWaitResult_Timeout) { if (RT_FAILURE(waitRes.mRC)) rc = waitRes.mRC; break; } rc = pProcess->readData(OUTPUT_HANDLE_ID_STDOUT, sizeof(byBuf), 30 * 1000 /* Timeout */, byBuf, sizeof(byBuf), &cbRead); if (RT_FAILURE(rc)) break; if (cbRead) { AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); rc = mData.mStream.AddData(byBuf, cbRead); if (RT_FAILURE(rc)) break; LogFlowThisFunc(("rc=%Rrc, cbRead=%RU64, cbStreamOut=%RU32\n", rc, cbRead, mData.mStream.GetSize())); rc = parseData(streamBlock); if (RT_SUCCESS(rc)) { /* Parsing the current stream block succeeded so * we don't need more at the moment. */ break; } } } LogFlowThisFunc(("Reading done with rc=%Rrc, cbRead=%RU64, cbStream=%RU32\n", rc, cbRead, mData.mStream.GetSize())); if (RT_SUCCESS(rc)) { rc = parseData(streamBlock); if (rc == VERR_NO_DATA) /* Since this is the last parsing call, this is ok. */ rc = VINF_SUCCESS; } /* * Note: The guest process can still be around to serve the next * upcoming stream block next time. */ if (RT_SUCCESS(rc)) { /** @todo Move into common function. */ ProcessStatus_T procStatus = ProcessStatus_Undefined; LONG exitCode = 0; HRESULT hr2 = pProcess->COMGETTER(Status(&procStatus)); ComAssertComRC(hr2); hr2 = pProcess->COMGETTER(ExitCode(&exitCode)); ComAssertComRC(hr2); if ( ( procStatus != ProcessStatus_Started && procStatus != ProcessStatus_Paused && procStatus != ProcessStatus_Terminating ) && exitCode != 0) { rc = VERR_ACCESS_DENIED; } } } if (RT_SUCCESS(rc)) { if (streamBlock.GetCount()) /* Did we get content? */ { rc = objData.FromLs(streamBlock); if (RT_FAILURE(rc)) rc = VERR_PATH_NOT_FOUND; if (RT_SUCCESS(rc)) { /* Create the object. */ ComObjPtr<GuestFsObjInfo> pFsObjInfo; HRESULT hr2 = pFsObjInfo.createObject(); if (FAILED(hr2)) rc = VERR_COM_UNEXPECTED; if (RT_SUCCESS(rc)) rc = pFsObjInfo->init(objData); if (RT_SUCCESS(rc)) { /* Return info object to the caller. */ hr2 = pFsObjInfo.queryInterfaceTo(aInfo); if (FAILED(hr2)) rc = VERR_COM_UNEXPECTED; } } } else { /* Nothing to read anymore. Tell the caller. */ rc = VERR_NO_MORE_FILES; } } HRESULT hr = S_OK; if (RT_FAILURE(rc)) /** @todo Add more errors here. */ { switch (rc) { case VERR_ACCESS_DENIED: hr = setError(VBOX_E_IPRT_ERROR, tr("Reading directory \"%s\" failed: Unable to read / access denied"), mData.mName.c_str()); break; case VERR_PATH_NOT_FOUND: hr = setError(VBOX_E_IPRT_ERROR, tr("Reading directory \"%s\" failed: Path not found"), mData.mName.c_str()); break; case VERR_NO_MORE_FILES: hr = setError(VBOX_E_OBJECT_NOT_FOUND, tr("No more entries for directory \"%s\""), mData.mName.c_str()); break; default: hr = setError(VBOX_E_IPRT_ERROR, tr("Error while reading directory \"%s\": %Rrc\n"), mData.mName.c_str(), rc); break; } } LogFlowFuncLeaveRC(rc); return hr; #endif /* VBOX_WITH_GUEST_CONTROL */ }
int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVirtualBox, IHostNetworkInterface **aHostNetworkInterface, IProgress **aProgress, const char *pcszName) { #if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) /* create a progress object */ ComObjPtr<Progress> progress; progress.createObject(); ComPtr<IHost> host; HRESULT hrc = pVirtualBox->COMGETTER(Host)(host.asOutParam()); if (SUCCEEDED(hrc)) { hrc = progress->init(pVirtualBox, host, Bstr("Creating host only network interface").raw(), FALSE /* aCancelable */); if (SUCCEEDED(hrc)) { progress.queryInterfaceTo(aProgress); char szAdpCtl[RTPATH_MAX]; int rc = RTPathExecDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " add")); if (RT_FAILURE(rc)) { progress->i_notifyComplete(E_FAIL, COM_IIDOF(IHostNetworkInterface), HostNetworkInterface::getStaticComponentName(), "Failed to get program path, rc=%Rrc\n", rc); return rc; } strcat(szAdpCtl, "/" VBOXNETADPCTL_NAME " "); if (pcszName && strlen(pcszName) <= RTPATH_MAX - strlen(szAdpCtl) - sizeof(" add")) { strcat(szAdpCtl, pcszName); strcat(szAdpCtl, " add"); } else strcat(szAdpCtl, "add"); if (strlen(szAdpCtl) < RTPATH_MAX - sizeof(" 2>&1")) strcat(szAdpCtl, " 2>&1"); FILE *fp = popen(szAdpCtl, "r"); if (fp) { char szBuf[128]; /* We are not interested in long error messages. */ if (fgets(szBuf, sizeof(szBuf), fp)) { /* Remove trailing new line characters. */ char *pLast = szBuf + strlen(szBuf) - 1; if (pLast >= szBuf && *pLast == '\n') *pLast = 0; if (!strncmp(VBOXNETADPCTL_NAME ":", szBuf, sizeof(VBOXNETADPCTL_NAME))) { progress->i_notifyComplete(E_FAIL, COM_IIDOF(IHostNetworkInterface), HostNetworkInterface::getStaticComponentName(), "%s", szBuf); pclose(fp); return E_FAIL; } size_t cbNameLen = strlen(szBuf) + 1; PNETIFINFO pInfo = (PNETIFINFO)RTMemAllocZ(RT_OFFSETOF(NETIFINFO, szName[cbNameLen])); if (!pInfo) rc = VERR_NO_MEMORY; else { strcpy(pInfo->szShortName, szBuf); strcpy(pInfo->szName, szBuf); rc = NetIfGetConfigByName(pInfo); if (RT_FAILURE(rc)) { progress->i_notifyComplete(E_FAIL, COM_IIDOF(IHostNetworkInterface), HostNetworkInterface::getStaticComponentName(), "Failed to get config info for %s (as reported by '" VBOXNETADPCTL_NAME " add')\n", szBuf); } else { Bstr IfName(szBuf); /* create a new uninitialized host interface object */ ComObjPtr<HostNetworkInterface> iface; iface.createObject(); iface->init(IfName, HostNetworkInterfaceType_HostOnly, pInfo); iface->i_setVirtualBox(pVirtualBox); iface.queryInterfaceTo(aHostNetworkInterface); } RTMemFree(pInfo); } if ((rc = pclose(fp)) != 0) { progress->i_notifyComplete(E_FAIL, COM_IIDOF(IHostNetworkInterface), HostNetworkInterface::getStaticComponentName(), "Failed to execute '" VBOXNETADPCTL_NAME " add' (exit status: %d)", rc); rc = VERR_INTERNAL_ERROR; } } else { /* Failed to add an interface */ rc = VERR_PERMISSION_DENIED; progress->i_notifyComplete(E_FAIL, COM_IIDOF(IHostNetworkInterface), HostNetworkInterface::getStaticComponentName(), "Failed to execute '" VBOXNETADPCTL_NAME " add' (exit status: %d). Check permissions!", rc); pclose(fp); } } if (RT_SUCCESS(rc)) progress->i_notifyComplete(rc); else hrc = E_FAIL; } } return hrc; #else NOREF(pVirtualBox); NOREF(aHostNetworkInterface); NOREF(aProgress); NOREF(pcszName); return VERR_NOT_IMPLEMENTED; #endif }
STDMETHODIMP GuestDirectory::Read(IFsObjInfo **aInfo) { #ifndef VBOX_WITH_GUEST_CONTROL ReturnComNotImplemented(); #else LogFlowThisFuncEnter(); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); GuestProcessStreamBlock curBlock; int guestRc; int rc = mData.mProcessTool.WaitEx(GUESTPROCESSTOOL_FLAG_STDOUT_BLOCK, &curBlock, &guestRc); /* * Note: The guest process can still be around to serve the next * upcoming stream block next time. */ if ( RT_SUCCESS(rc) && !mData.mProcessTool.IsRunning()) { rc = mData.mProcessTool.TerminatedOk(NULL /* Exit code */); if (rc == VERR_NOT_EQUAL) rc = VERR_ACCESS_DENIED; } if (RT_SUCCESS(rc)) { if (curBlock.GetCount()) /* Did we get content? */ { GuestFsObjData objData; rc = objData.FromLs(curBlock); if (RT_FAILURE(rc)) rc = VERR_PATH_NOT_FOUND; if (RT_SUCCESS(rc)) { /* Create the object. */ ComObjPtr<GuestFsObjInfo> pFsObjInfo; HRESULT hr2 = pFsObjInfo.createObject(); if (FAILED(hr2)) rc = VERR_COM_UNEXPECTED; if (RT_SUCCESS(rc)) rc = pFsObjInfo->init(objData); if (RT_SUCCESS(rc)) { /* Return info object to the caller. */ hr2 = pFsObjInfo.queryInterfaceTo(aInfo); if (FAILED(hr2)) rc = VERR_COM_UNEXPECTED; } } } else { /* Nothing to read anymore. Tell the caller. */ rc = VERR_NO_MORE_FILES; } } HRESULT hr = S_OK; if (RT_FAILURE(rc)) /** @todo Add more errors here. */ { switch (rc) { case VERR_GSTCTL_GUEST_ERROR: hr = GuestProcess::setErrorExternal(this, guestRc); break; case VERR_ACCESS_DENIED: hr = setError(VBOX_E_IPRT_ERROR, tr("Reading directory \"%s\" failed: Unable to read / access denied"), mData.mName.c_str()); break; case VERR_PATH_NOT_FOUND: hr = setError(VBOX_E_IPRT_ERROR, tr("Reading directory \"%s\" failed: Path not found"), mData.mName.c_str()); break; case VERR_NO_MORE_FILES: /* See SDK reference. */ hr = setError(VBOX_E_OBJECT_NOT_FOUND, tr("No more entries for directory \"%s\""), mData.mName.c_str()); break; default: hr = setError(VBOX_E_IPRT_ERROR, tr("Error while reading directory \"%s\": %Rrc\n"), mData.mName.c_str(), rc); break; } } LogFlowThisFunc(("Returning rc=%Rrc\n", rc)); return hr; #endif /* VBOX_WITH_GUEST_CONTROL */ }
STDMETHODIMP USBController::RemoveDeviceFilter(ULONG aPosition, IUSBDeviceFilter **aFilter) { #ifdef VBOX_WITH_USB CheckComArgOutPointerValid(aFilter); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); /* the machine needs to be mutable */ AutoMutableStateDependency adep(m->pParent); if (FAILED(adep.rc())) return adep.rc(); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); if (!m->llDeviceFilters->size()) return setError(E_INVALIDARG, tr("The USB device filter list is empty")); if (aPosition >= m->llDeviceFilters->size()) return setError(E_INVALIDARG, tr("Invalid position: %lu (must be in range [0, %lu])"), aPosition, m->llDeviceFilters->size() - 1); /* backup the list before modification */ m->llDeviceFilters.backup(); ComObjPtr<USBDeviceFilter> filter; { /* iterate to the position... */ DeviceFilterList::iterator it = m->llDeviceFilters->begin(); std::advance (it, aPosition); /* ...get an element from there... */ filter = *it; /* ...and remove */ filter->mInList = false; m->llDeviceFilters->erase (it); } /* cancel sharing (make an independent copy of data) */ filter->unshare(); filter.queryInterfaceTo(aFilter); /* notify the proxy (only when it makes sense) */ if (filter->getData().mActive && Global::IsOnline(adep.machineState()) && filter->getData().mRemote.isMatch (false)) { USBProxyService *service = m->pHost->usbProxyService(); ComAssertRet(service, E_FAIL); ComAssertRet(filter->getId() != NULL, E_FAIL); service->removeFilter(filter->getId()); filter->getId() = NULL; } alock.release(); AutoWriteLock mlock(m->pParent COMMA_LOCKVAL_SRC_POS); m->pParent->setModified(Machine::IsModified_USB); mlock.release(); return S_OK; #else /* VBOX_WITH_USB */ NOREF(aPosition); NOREF(aFilter); ReturnComNotImplemented(); #endif /* VBOX_WITH_USB */ }
HRESULT Guest::updateGuestAdditions(const com::Utf8Str &aSource, const std::vector<com::Utf8Str> &aArguments, const std::vector<AdditionsUpdateFlag_T> &aFlags, ComPtr<IProgress> &aProgress) { #ifndef VBOX_WITH_GUEST_CONTROL ReturnComNotImplemented(); #else /* VBOX_WITH_GUEST_CONTROL */ /* Validate flags. */ uint32_t fFlags = AdditionsUpdateFlag_None; if (aFlags.size()) for (size_t i = 0; i < aFlags.size(); ++i) fFlags |= aFlags[i]; if (fFlags && !(fFlags & AdditionsUpdateFlag_WaitForUpdateStartOnly)) return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), fFlags); int rc = VINF_SUCCESS; ProcessArguments aArgs; aArgs.resize(0); if (aArguments.size()) { try { for (size_t i = 0; i < aArguments.size(); ++i) aArgs.push_back(aArguments[i]); } catch(std::bad_alloc &) { rc = VERR_NO_MEMORY; } } HRESULT hr = S_OK; /* * Create an anonymous session. This is required to run the Guest Additions * update process with administrative rights. */ GuestSessionStartupInfo startupInfo; startupInfo.mName = "Updating Guest Additions"; GuestCredentials guestCreds; RT_ZERO(guestCreds); ComObjPtr<GuestSession> pSession; if (RT_SUCCESS(rc)) rc = i_sessionCreate(startupInfo, guestCreds, pSession); if (RT_FAILURE(rc)) { switch (rc) { case VERR_MAX_PROCS_REACHED: hr = setError(VBOX_E_IPRT_ERROR, tr("Maximum number of concurrent guest sessions (%ld) reached"), VBOX_GUESTCTRL_MAX_SESSIONS); break; /** @todo Add more errors here. */ default: hr = setError(VBOX_E_IPRT_ERROR, tr("Could not create guest session: %Rrc"), rc); break; } } else { Assert(!pSession.isNull()); int guestRc; rc = pSession->i_startSessionInternal(&guestRc); if (RT_FAILURE(rc)) { /** @todo Handle guestRc! */ hr = setError(VBOX_E_IPRT_ERROR, tr("Could not open guest session: %Rrc"), rc); } else { try { ComObjPtr<Progress> pProgress; SessionTaskUpdateAdditions *pTask = new SessionTaskUpdateAdditions(pSession /* GuestSession */, aSource, aArgs, fFlags); rc = pSession->i_startTaskAsync(tr("Updating Guest Additions"), pTask, pProgress); if (RT_SUCCESS(rc)) { /* Return progress to the caller. */ hr = pProgress.queryInterfaceTo(aProgress.asOutParam()); } else hr = setError(VBOX_E_IPRT_ERROR, tr("Starting task for updating Guest Additions on the guest failed: %Rrc"), rc); } catch(std::bad_alloc &) { hr = E_OUTOFMEMORY; } } } return hr; #endif /* VBOX_WITH_GUEST_CONTROL */ }
HRESULT Guest::updateGuestAdditions(const com::Utf8Str &aSource, const std::vector<com::Utf8Str> &aArguments, const std::vector<AdditionsUpdateFlag_T> &aFlags, ComPtr<IProgress> &aProgress) { #ifndef VBOX_WITH_GUEST_CONTROL ReturnComNotImplemented(); #else /* VBOX_WITH_GUEST_CONTROL */ /* Validate flags. */ uint32_t fFlags = AdditionsUpdateFlag_None; if (aFlags.size()) for (size_t i = 0; i < aFlags.size(); ++i) fFlags |= aFlags[i]; if (fFlags && !(fFlags & AdditionsUpdateFlag_WaitForUpdateStartOnly)) return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), fFlags); int vrc = VINF_SUCCESS; ProcessArguments aArgs; aArgs.resize(0); if (aArguments.size()) { try { for (size_t i = 0; i < aArguments.size(); ++i) aArgs.push_back(aArguments[i]); } catch(std::bad_alloc &) { vrc = VERR_NO_MEMORY; } } HRESULT hr = S_OK; /* * Create an anonymous session. This is required to run the Guest Additions * update process with administrative rights. */ GuestSessionStartupInfo startupInfo; startupInfo.mName = "Updating Guest Additions"; GuestCredentials guestCreds; RT_ZERO(guestCreds); ComObjPtr<GuestSession> pSession; if (RT_SUCCESS(vrc)) vrc = i_sessionCreate(startupInfo, guestCreds, pSession); if (RT_FAILURE(vrc)) { switch (vrc) { case VERR_MAX_PROCS_REACHED: hr = setErrorBoth(VBOX_E_IPRT_ERROR, vrc, tr("Maximum number of concurrent guest sessions (%d) reached"), VBOX_GUESTCTRL_MAX_SESSIONS); break; /** @todo Add more errors here. */ default: hr = setErrorBoth(VBOX_E_IPRT_ERROR, vrc, tr("Could not create guest session: %Rrc"), vrc); break; } } else { Assert(!pSession.isNull()); int rcGuest; vrc = pSession->i_startSession(&rcGuest); if (RT_FAILURE(vrc)) { /** @todo Handle rcGuest! */ hr = setErrorBoth(VBOX_E_IPRT_ERROR, vrc, tr("Could not open guest session: %Rrc"), vrc); } else { ComObjPtr<Progress> pProgress; GuestSessionTaskUpdateAdditions *pTask = NULL; try { try { pTask = new GuestSessionTaskUpdateAdditions(pSession /* GuestSession */, aSource, aArgs, fFlags); } catch(...) { hr = setError(E_OUTOFMEMORY, tr("Failed to create SessionTaskUpdateAdditions object ")); throw; } hr = pTask->Init(Utf8StrFmt(tr("Updating Guest Additions"))); if (FAILED(hr)) { delete pTask; hr = setError(hr, tr("Creating progress object for SessionTaskUpdateAdditions object failed")); throw hr; } hr = pTask->createThreadWithType(RTTHREADTYPE_MAIN_HEAVY_WORKER); if (SUCCEEDED(hr)) { /* Return progress to the caller. */ pProgress = pTask->GetProgressObject(); hr = pProgress.queryInterfaceTo(aProgress.asOutParam()); } else hr = setError(hr, tr("Starting thread for updating Guest Additions on the guest failed ")); } catch(std::bad_alloc &) { hr = E_OUTOFMEMORY; } catch(...) { LogFlowThisFunc(("Exception was caught in the function\n")); } } } LogFlowFunc(("Returning hr=%Rhrc\n", hr)); return hr; #endif /* VBOX_WITH_GUEST_CONTROL */ }
/** * Start teleporter to the specified target. * * @returns COM status code. * * @param aHostname The name of the target host. * @param aPort The TCP port number. * @param aPassword The password. * @param aMaxDowntime Max allowed "downtime" in milliseconds. * @param aProgress Where to return the progress object. */ STDMETHODIMP Console::Teleport(IN_BSTR aHostname, ULONG aPort, IN_BSTR aPassword, ULONG aMaxDowntime, IProgress **aProgress) { /* * Validate parameters, check+hold object status, write lock the object * and validate the state. */ CheckComArgOutPointerValid(aProgress); CheckComArgStrNotEmptyOrNull(aHostname); CheckComArgStrNotEmptyOrNull(aPassword); CheckComArgExprMsg(aPort, aPort > 0 && aPort <= 65535, ("is %u", aPort)); CheckComArgExprMsg(aMaxDowntime, aMaxDowntime > 0, ("is %u", aMaxDowntime)); Utf8Str strPassword(aPassword); if (!strPassword.isEmpty()) { if (VBoxIsPasswordHashed(&strPassword)) return setError(E_INVALIDARG, tr("The specified password resembles a hashed password, expected plain text")); VBoxHashPassword(&strPassword); } AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS); LogFlowThisFunc(("mMachineState=%d\n", mMachineState)); switch (mMachineState) { case MachineState_Running: case MachineState_Paused: break; default: return setError(VBOX_E_INVALID_VM_STATE, tr("Invalid machine state: %s (must be Running or Paused)"), Global::stringifyMachineState(mMachineState)); } /* * Create a progress object, spawn a worker thread and change the state. * Note! The thread won't start working until we release the lock. */ LogFlowThisFunc(("Initiating TELEPORT request...\n")); ComObjPtr<Progress> ptrProgress; HRESULT hrc = ptrProgress.createObject(); if (SUCCEEDED(hrc)) hrc = ptrProgress->init(static_cast<IConsole *>(this), Bstr(tr("Teleporter")).raw(), TRUE /*aCancelable*/); if (FAILED(hrc)) return hrc; TeleporterStateSrc *pState = new TeleporterStateSrc(this, mpUVM, ptrProgress, mMachineState); pState->mstrPassword = strPassword; pState->mstrHostname = aHostname; pState->muPort = aPort; pState->mcMsMaxDowntime = aMaxDowntime; void *pvUser = static_cast<void *>(static_cast<TeleporterState *>(pState)); ptrProgress->setCancelCallback(teleporterProgressCancelCallback, pvUser); int vrc = RTThreadCreate(NULL, Console::teleporterSrcThreadWrapper, (void *)pState, 0 /*cbStack*/, RTTHREADTYPE_EMULATION, 0 /*fFlags*/, "Teleport"); if (RT_SUCCESS(vrc)) { if (mMachineState == MachineState_Running) hrc = setMachineState(MachineState_Teleporting); else hrc = setMachineState(MachineState_TeleportingPausedVM); if (SUCCEEDED(hrc)) { ptrProgress.queryInterfaceTo(aProgress); mptrCancelableProgress = ptrProgress; } else ptrProgress->Cancel(); } else { ptrProgress->setCancelCallback(NULL, NULL); delete pState; hrc = setError(E_FAIL, tr("RTThreadCreate -> %Rrc"), vrc); } return hrc; }
STDMETHODIMP Guest::UpdateGuestAdditions(IN_BSTR aSource, ComSafeArrayIn(AdditionsUpdateFlag_T, aFlags), IProgress **aProgress) { #ifndef VBOX_WITH_GUEST_CONTROL ReturnComNotImplemented(); #else /* VBOX_WITH_GUEST_CONTROL */ CheckComArgStrNotEmptyOrNull(aSource); CheckComArgOutPointerValid(aProgress); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); /* Validate flags. */ uint32_t fFlags = AdditionsUpdateFlag_None; if (aFlags) { com::SafeArray<CopyFileFlag_T> flags(ComSafeArrayInArg(aFlags)); for (size_t i = 0; i < flags.size(); i++) fFlags |= flags[i]; } if (fFlags) { if (!(fFlags & AdditionsUpdateFlag_WaitForUpdateStartOnly)) return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), aFlags); } HRESULT hr = S_OK; /* Create an anonymous session. This is required to run the Guest Additions * update process with administrative rights. */ ComObjPtr<GuestSession> pSession; int rc = sessionCreate("" /* User */, "" /* Password */, "" /* Domain */, "Updating Guest Additions" /* Name */, pSession); if (RT_FAILURE(rc)) { switch (rc) { case VERR_MAX_PROCS_REACHED: hr = setError(VBOX_E_IPRT_ERROR, tr("Maximum number of guest sessions (%ld) reached"), VBOX_GUESTCTRL_MAX_SESSIONS); break; /** @todo Add more errors here. */ default: hr = setError(VBOX_E_IPRT_ERROR, tr("Could not create guest session: %Rrc"), rc); break; } } else { Assert(!pSession.isNull()); rc = pSession->queryInfo(); if (RT_FAILURE(rc)) { hr = setError(VBOX_E_IPRT_ERROR, tr("Could not query guest session information: %Rrc"), rc); } else { ComObjPtr<Progress> pProgress; SessionTaskUpdateAdditions *pTask = new SessionTaskUpdateAdditions(pSession /* GuestSession */, Utf8Str(aSource), fFlags); AssertPtrReturn(pTask, VERR_NO_MEMORY); rc = pSession->startTaskAsync(tr("Updating Guest Additions"), pTask, pProgress); if (RT_SUCCESS(rc)) { /* Return progress to the caller. */ hr = pProgress.queryInterfaceTo(aProgress); } else hr = setError(VBOX_E_IPRT_ERROR, tr("Starting task for updating Guest Additions on the guest failed: %Rrc"), rc); } } return hr; #endif /* VBOX_WITH_GUEST_CONTROL */ }