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 */
}
Exemplo n.º 2
0
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 */
}