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 */ }
static void collectTo(ProcessArguments &arguments, const T &arg, Args &&... args) { arguments.push_back(toString(arg)); collectTo(arguments, std::forward<Args>(args)...); }
static void collectTo(ProcessArguments &arguments, const std::vector<std::string> &arg, Args &&... args) { arguments.insert(arguments.end(), arg.begin(), arg.end()); collectTo(arguments, std::forward<Args>(args)...); }
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 */ }