예제 #1
0
STDMETHODIMP EventSource::FireEvent(IEvent * aEvent,
                                    LONG     aTimeout,
                                    BOOL     *aProcessed)
{
    CheckComArgNotNull(aEvent);
    CheckComArgOutPointerValid(aProcessed);

    AutoCaller autoCaller(this);
    if (FAILED(autoCaller.rc())) return autoCaller.rc();

    HRESULT hrc;
    BOOL aWaitable = FALSE;
    aEvent->COMGETTER(Waitable)(&aWaitable);

    do {
        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

        VBoxEventType_T evType;
        hrc = aEvent->COMGETTER(Type)(&evType);
        AssertComRCReturn(hrc, hrc);

        EventMapList &listeners = m->mEvMap[(int)evType - FirstEvent];

        /* Anyone interested in this event? */
        uint32_t cListeners = listeners.size();
        if (cListeners == 0)
        {
            aEvent->SetProcessed();
            break; // just leave the lock and update event object state
        }

        PendingEventsMap::iterator pit;

        if (aWaitable)
        {
            m->mPendingMap.insert(PendingEventsMap::value_type(aEvent, cListeners));
            // we keep iterator here to allow processing active listeners without
            // pending events lookup
            pit = m->mPendingMap.find(aEvent);
        }
        for (EventMapList::iterator it = listeners.begin();
             it != listeners.end();
             ++it)
        {
            HRESULT cbRc;
            // keep listener record reference, in case someone will remove it while in callback
            RecordHolder<ListenerRecord> record(*it);

            /*
             * We pass lock here to allow modifying ops on EventSource inside callback
             * in active mode. Note that we expect list iterator stability as 'alock'
             * could be temporary released when calling event handler.
             */
            cbRc = record.obj()->process(aEvent, aWaitable, pit, alock);

            /* Note that E_ABORT is used above to signal that a passive
             * listener was unregistered due to not picking up its event.
             * This overlaps with XPCOM specific use of E_ABORT to signal
             * death of an active listener, but that's irrelevant here. */
            if (FAILED_DEAD_INTERFACE(cbRc) || cbRc == E_ABORT)
            {
                Listeners::iterator lit = m->mListeners.find(record.obj()->mListener);
                if (lit != m->mListeners.end())
                    m->mListeners.erase(lit);
            }
            // anything else to do with cbRc?
        }
    } while (0);
    /* We leave the lock here */

    if (aWaitable)
        hrc = aEvent->WaitProcessed(aTimeout, aProcessed);
    else
        *aProcessed = TRUE;

    return hrc;
}
/**
 * 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;
}
예제 #3
0
STDMETHODIMP Guest::InternalGetStatistics(ULONG *aCpuUser, ULONG *aCpuKernel, ULONG *aCpuIdle,
                                          ULONG *aMemTotal, ULONG *aMemFree, ULONG *aMemBalloon, ULONG *aMemShared,
                                          ULONG *aMemCache, ULONG *aPageTotal,
                                          ULONG *aMemAllocTotal, ULONG *aMemFreeTotal, ULONG *aMemBalloonTotal, ULONG *aMemSharedTotal)
{
    CheckComArgOutPointerValid(aCpuUser);
    CheckComArgOutPointerValid(aCpuKernel);
    CheckComArgOutPointerValid(aCpuIdle);
    CheckComArgOutPointerValid(aMemTotal);
    CheckComArgOutPointerValid(aMemFree);
    CheckComArgOutPointerValid(aMemBalloon);
    CheckComArgOutPointerValid(aMemShared);
    CheckComArgOutPointerValid(aMemCache);
    CheckComArgOutPointerValid(aPageTotal);
    CheckComArgOutPointerValid(aMemAllocTotal);
    CheckComArgOutPointerValid(aMemFreeTotal);
    CheckComArgOutPointerValid(aMemBalloonTotal);
    CheckComArgOutPointerValid(aMemSharedTotal);

    AutoCaller autoCaller(this);
    if (FAILED(autoCaller.rc())) return autoCaller.rc();

    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);

    *aCpuUser    = mCurrentGuestStat[GUESTSTATTYPE_CPUUSER];
    *aCpuKernel  = mCurrentGuestStat[GUESTSTATTYPE_CPUKERNEL];
    *aCpuIdle    = mCurrentGuestStat[GUESTSTATTYPE_CPUIDLE];
    *aMemTotal   = mCurrentGuestStat[GUESTSTATTYPE_MEMTOTAL] * (_4K/_1K);     /* page (4K) -> 1KB units */
    *aMemFree    = mCurrentGuestStat[GUESTSTATTYPE_MEMFREE] * (_4K/_1K);       /* page (4K) -> 1KB units */
    *aMemBalloon = mCurrentGuestStat[GUESTSTATTYPE_MEMBALLOON] * (_4K/_1K); /* page (4K) -> 1KB units */
    *aMemCache   = mCurrentGuestStat[GUESTSTATTYPE_MEMCACHE] * (_4K/_1K);     /* page (4K) -> 1KB units */
    *aPageTotal  = mCurrentGuestStat[GUESTSTATTYPE_PAGETOTAL] * (_4K/_1K);   /* page (4K) -> 1KB units */

    /* MUST release all locks before calling any PGM statistics queries,
     * as they are executed by EMT and that might deadlock us by VMM device
     * activity which waits for the Guest object lock. */
    alock.release();
    Console::SafeVMPtr pVM (mParent);
    if (pVM.isOk())
    {
        uint64_t uFreeTotal, uAllocTotal, uBalloonedTotal, uSharedTotal;
        *aMemFreeTotal = 0;
        int rc = PGMR3QueryGlobalMemoryStats(pVM.raw(), &uAllocTotal, &uFreeTotal, &uBalloonedTotal, &uSharedTotal);
        AssertRC(rc);
        if (rc == VINF_SUCCESS)
        {
            *aMemAllocTotal   = (ULONG)(uAllocTotal / _1K);  /* bytes -> KB */
            *aMemFreeTotal    = (ULONG)(uFreeTotal / _1K);
            *aMemBalloonTotal = (ULONG)(uBalloonedTotal / _1K);
            *aMemSharedTotal  = (ULONG)(uSharedTotal / _1K);
        }
        else
            return E_FAIL;

        /* Query the missing per-VM memory statistics. */
        *aMemShared  = 0;
        uint64_t uTotalMem, uPrivateMem, uSharedMem, uZeroMem;
        rc = PGMR3QueryMemoryStats(pVM.raw(), &uTotalMem, &uPrivateMem, &uSharedMem, &uZeroMem);
        if (rc == VINF_SUCCESS)
        {
            *aMemShared = (ULONG)(uSharedMem / _1K);
        }
        else
            return E_FAIL;
    }
    else
    {
        *aMemAllocTotal   = 0;
        *aMemFreeTotal    = 0;
        *aMemBalloonTotal = 0;
        *aMemSharedTotal  = 0;
        *aMemShared       = 0;
        return E_FAIL;
    }

    return S_OK;
}
STDMETHODIMP USBDeviceFilters::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 pFilter 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> pFilter;
    {
        /* iterate to the position... */
        DeviceFilterList::iterator it = m->llDeviceFilters->begin();
        std::advance(it, aPosition);
        /* ...get an element from there... */
        pFilter = *it;
        /* ...and remove */
        pFilter->mInList = false;
        m->llDeviceFilters->erase(it);
    }

    /* cancel sharing (make an independent copy of data) */
    pFilter->unshare();

    pFilter.queryInterfaceTo(aFilter);

    /* notify the proxy (only when it makes sense) */
    if (pFilter->getData().mActive && Global::IsOnline(adep.machineState())
        && pFilter->getData().mRemote.isMatch(false))
    {
        USBProxyService *pProxySvc = m->pHost->usbProxyService();
        ComAssertRet(pProxySvc, E_FAIL);

        ComAssertRet(pFilter->getId() != NULL, E_FAIL);
        pProxySvc->removeFilter(pFilter->getId());
        pFilter->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 */
}
예제 #5
0
STDMETHODIMP SystemProperties::COMGETTER(FreeDiskSpacePercentError)(ULONG *aFreeSpacePercent)
{
    CheckComArgOutPointerValid(aFreeSpacePercent);

    ReturnComNotImplemented();
}
예제 #6
0
STDMETHODIMP SystemProperties::COMGETTER(FreeDiskSpaceWarning)(LONG64 *aFreeSpace)
{
    CheckComArgOutPointerValid(aFreeSpace);

    ReturnComNotImplemented();
}