VirtualBox

Changeset 39890 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Jan 26, 2012 7:42:19 PM (13 years ago)
Author:
vboxsync
Message:

VMMDev,IGuest,IAdditionsFacility,VBoxGuest,iprt/types.h: VMMDev must track the guest facility reports so they can be saved and restored correctly. Also fixed a reset bug related to guestInfo2. Restrict who can report the status of which facilities. Recalc the runlevel based on which facilities are active. Restrict the number of facilities main tracks.

Location:
trunk/src/VBox/Main
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/AdditionsFacilityImpl.h

    r39805 r39890  
    4141
    4242    // public initializer/uninitializer for internal purposes only
    43     HRESULT init(Guest *aParent, AdditionsFacilityType_T enmFacility, AdditionsFacilityStatus_T enmStatus);
     43    HRESULT init(Guest *a_pParent, AdditionsFacilityType_T a_enmFacility, AdditionsFacilityStatus_T a_enmStatus,
     44                 uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS);
    4445    void uninit();
    4546
     
    6566        AdditionsFacilityClass_T mClass;
    6667    };
    67     static const FacilityInfo sFacilityInfo[8];
     68    static const FacilityInfo s_aFacilityInfo[8];
    6869
    6970    // public internal methods
     
    7475    AdditionsFacilityStatus_T getStatus() const;
    7576    AdditionsFacilityType_T getType() const;
    76     HRESULT update(AdditionsFacilityStatus_T aStatus, RTTIMESPEC aTimestamp);
     77    void update(AdditionsFacilityStatus_T a_enmStatus, uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS);
    7778
    7879private:
  • trunk/src/VBox/Main/include/GuestImpl.h

    r39882 r39890  
    136136    void setAdditionsInfo2(uint32_t a_uFullVersion, const char *a_pszName, uint32_t a_uRevision, uint32_t a_fFeatures);
    137137    bool facilityIsActive(VBoxGuestFacilityType enmFacility);
    138     HRESULT facilityUpdate(VBoxGuestFacilityType enmFacility, VBoxGuestFacilityStatus enmStatus);
    139     void setAdditionsStatus(VBoxGuestFacilityType enmFacility, VBoxGuestFacilityStatus enmStatus, ULONG aFlags);
     138    void facilityUpdate(VBoxGuestFacilityType a_enmFacility, VBoxGuestFacilityStatus a_enmStatus, uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS);
     139    void setAdditionsStatus(VBoxGuestFacilityType a_enmFacility, VBoxGuestFacilityStatus a_enmStatus, uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS);
    140140    void setSupportedFeatures(uint32_t aCaps);
    141141    HRESULT setStatistic(ULONG aCpuId, GUESTSTATTYPE enmType, ULONG aVal);
  • trunk/src/VBox/Main/src-client/AdditionsFacilityImpl.cpp

    r36037 r39890  
    2323
    2424/* static */
    25 const AdditionsFacility::FacilityInfo AdditionsFacility::sFacilityInfo[8] =
     25const AdditionsFacility::FacilityInfo AdditionsFacility::s_aFacilityInfo[8] =
    2626{
    2727    /* NOTE: We assume that unknown is always the first entry! */
     
    5656/////////////////////////////////////////////////////////////////////////////
    5757
    58 HRESULT AdditionsFacility::init(Guest *aParent, AdditionsFacilityType_T enmFacility, AdditionsFacilityStatus_T enmStatus)
    59 {
    60     LogFlowThisFunc(("aParent=%p\n", aParent));
     58HRESULT AdditionsFacility::init(Guest *a_pParent, AdditionsFacilityType_T a_enmFacility, AdditionsFacilityStatus_T a_enmStatus,
     59                                uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS)
     60{
     61    LogFlowThisFunc(("a_pParent=%p\n", a_pParent));
    6162
    6263    /* Enclose the state transition NotReady->InInit->Ready. */
     
    6465    AssertReturn(autoInitSpan.isOk(), E_FAIL);
    6566
    66     RTTimeNow(&mData.mLastUpdated);
    67     mData.mStatus = enmStatus;
    68     mData.mType = enmFacility;
     67    mData.mStatus       = a_enmStatus;
     68    mData.mType         = a_enmFacility;
     69    mData.mLastUpdated  = *a_pTimeSpecTS;
    6970    /** @todo mClass is not initialized here. */
     71    NOREF(a_fFlags);
    7072
    7173    /* Confirm a successful initialization when it's the case. */
     
    171173const AdditionsFacility::FacilityInfo &AdditionsFacility::typeToInfo(AdditionsFacilityType_T aType)
    172174{
    173     for (size_t i = 0; i < RT_ELEMENTS(sFacilityInfo); ++i)
     175    for (size_t i = 0; i < RT_ELEMENTS(s_aFacilityInfo); ++i)
    174176    {
    175         if (sFacilityInfo[i].mType == aType)
    176             return sFacilityInfo[i];
     177        if (s_aFacilityInfo[i].mType == aType)
     178            return s_aFacilityInfo[i];
    177179    }
    178     return sFacilityInfo[0]; /* Return unknown type. */
     180    return s_aFacilityInfo[0]; /* Return unknown type. */
    179181}
    180182
     
    204206}
    205207
    206 HRESULT AdditionsFacility::update(AdditionsFacilityStatus_T aStatus, RTTIMESPEC aTimestamp)
    207 {
    208     mData.mStatus = aStatus;
    209     mData.mLastUpdated = aTimestamp;
    210 
    211     return S_OK;
    212 }
    213 
     208/**
     209 * Method used by IGuest::facilityUpdate to make updates.
     210 */
     211void AdditionsFacility::update(AdditionsFacilityStatus_T a_enmStatus, uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS)
     212{
     213    mData.mStatus       = a_enmStatus;
     214    mData.mLastUpdated  = *a_pTimeSpecTS;
     215    NOREF(a_fFlags);
     216}
     217
  • trunk/src/VBox/Main/src-client/GuestImpl.cpp

    r39882 r39890  
    290290STDMETHODIMP Guest::COMGETTER(Facilities)(ComSafeArrayOut(IAdditionsFacility*, aFacilities))
    291291{
    292     CheckComArgOutPointerValid(aFacilities);
     292    CheckComArgOutSafeArrayPointerValid(aFacilities);
    293293
    294294    AutoCaller autoCaller(this);
     
    726726void Guest::setAdditionsInfo(Bstr aInterfaceVersion, VBOXOSTYPE aOsType)
    727727{
     728    RTTIMESPEC TimeSpecTS;
     729    RTTimeNow(&TimeSpecTS);
     730
    728731    AutoCaller autoCaller(this);
    729732    AssertComRCReturnVoid(autoCaller.rc());
    730733
    731734    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     735
    732736
    733737    /*
     
    765769             * interface version.
    766770             */
    767             facilityUpdate(VBoxGuestFacilityType_Graphics, VBoxGuestFacilityStatus_Active);
     771            facilityUpdate(VBoxGuestFacilityType_Graphics, VBoxGuestFacilityStatus_Active,  0 /*fFlags*/, &TimeSpecTS);
    768772        }
    769773    }
     
    774778     * and use the setSupportedFeatures function instead.
    775779     */
    776     facilityUpdate(VBoxGuestFacilityType_Graphics, facilityIsActive(VBoxGuestFacilityType_VBoxGuestDriver) ?
    777                    VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive);
     780    /** @todo r=bird: I don't get the above comment nor the code below...
     781     * One talks about capability bits, the one always does something to a facility.
     782     * Then there is the comment below it all, which is placed like it addresses the
     783     * mOSTypeId, but talks about something which doesn't remotely like mOSTypeId...
     784     *
     785     * Andy, could you please try clarify and make the comments shorter and more
     786     * coherent! Also, explain why this is important and what depends on it.
     787     *
     788     * PS. There is the VMMDEV_GUEST_SUPPORTS_GRAPHICS capability* report... It
     789     * should come in pretty quickly after this update, normally.
     790     */
     791    facilityUpdate(VBoxGuestFacilityType_Graphics,
     792                   facilityIsActive(VBoxGuestFacilityType_VBoxGuestDriver)
     793                   ? VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive,
     794                   0 /*fFlags*/, &TimeSpecTS); /** @todo the timestamp isn't gonna be right here on saved state restore. */
    778795
    779796    /*
     
    844861}
    845862
    846 HRESULT Guest::facilityUpdate(VBoxGuestFacilityType enmFacility, VBoxGuestFacilityStatus enmStatus)
    847 {
    848     ComAssertRet(enmFacility < INT32_MAX, E_INVALIDARG);
    849 
    850     HRESULT rc;
    851     RTTIMESPEC tsNow;
    852     RTTimeNow(&tsNow);
    853 
    854     FacilityMapIter it = mData.mFacilityMap.find((AdditionsFacilityType_T)enmFacility);
     863void Guest::facilityUpdate(VBoxGuestFacilityType a_enmFacility, VBoxGuestFacilityStatus a_enmStatus,
     864                           uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS)
     865{
     866    AssertReturnVoid(   a_enmFacility < VBoxGuestFacilityType_All
     867                     && a_enmFacility > VBoxGuestFacilityType_Unknown);
     868
     869    FacilityMapIter it = mData.mFacilityMap.find((AdditionsFacilityType_T)a_enmFacility);
    855870    if (it != mData.mFacilityMap.end())
    856871    {
    857872        AdditionsFacility *pFac = it->second;
    858         rc = pFac->update((AdditionsFacilityStatus_T)enmStatus, tsNow);
     873        pFac->update((AdditionsFacilityStatus_T)a_enmStatus, a_fFlags, a_pTimeSpecTS);
    859874    }
    860875    else
    861876    {
    862         ComObjPtr<AdditionsFacility> pFacility;
    863         pFacility.createObject();
    864         ComAssert(!pFacility.isNull());
    865         rc = pFacility->init(this,
    866                              (AdditionsFacilityType_T)enmFacility,
    867                              (AdditionsFacilityStatus_T)enmStatus);
    868         if (SUCCEEDED(rc))
    869             mData.mFacilityMap.insert(std::make_pair((AdditionsFacilityType_T)enmFacility, pFacility));
    870     }
    871 
    872     LogFlowFunc(("Returned with rc=%Rrc\n"));
    873     return rc;
     877        if (mData.mFacilityMap.size() > 64)
     878        {
     879            /* The easy way out for now. We could automatically destroy
     880               inactive facilities like VMMDev does if we like... */
     881            AssertFailedReturnVoid();
     882        }
     883
     884        ComObjPtr<AdditionsFacility> ptrFac;
     885        ptrFac.createObject();
     886        AssertReturnVoid(!ptrFac.isNull());
     887
     888        HRESULT hrc = ptrFac->init(this, (AdditionsFacilityType_T)a_enmFacility, (AdditionsFacilityStatus_T)a_enmStatus,
     889                                   a_fFlags, a_pTimeSpecTS);
     890        if (SUCCEEDED(hrc))
     891            mData.mFacilityMap.insert(std::make_pair((AdditionsFacilityType_T)a_enmFacility, ptrFac));
     892    }
    874893}
    875894
    876895/**
    877896 * Sets the status of a certain Guest Additions facility.
    878  * Gets called by vmmdevUpdateGuestStatus.
    879897 *
    880  * @param enmFacility   Facility to set the status for.
    881  * @param enmStatus     Actual status to set.
    882  * @param aFlags
     898 * Gets called by vmmdevUpdateGuestStatus, which just passes the report along.
     899 *
     900 * @param   a_pInterface        Pointer to this interface.
     901 * @param   a_enmFacility       The facility.
     902 * @param   a_enmStatus         The status.
     903 * @param   a_fFlags            Flags assoicated with the update. Currently
     904 *                              reserved and should be ignored.
     905 * @param   a_pTimeSpecTS       Pointer to the timestamp of this report.
     906 * @sa      PDMIVMMDEVCONNECTOR::pfnUpdateGuestStatus, vmmdevUpdateGuestStatus
     907 * @thread  The emulation thread.
    883908 */
    884 void Guest::setAdditionsStatus(VBoxGuestFacilityType enmFacility, VBoxGuestFacilityStatus enmStatus, ULONG aFlags)
    885 {
     909void Guest::setAdditionsStatus(VBoxGuestFacilityType a_enmFacility, VBoxGuestFacilityStatus a_enmStatus,
     910                               uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS)
     911{
     912    Assert(   a_enmFacility > VBoxGuestFacilityType_Unknown
     913           && a_enmFacility <= VBoxGuestFacilityType_All); /* Paranoia, VMMDev checks for this. */
     914
    886915    AutoCaller autoCaller(this);
    887916    AssertComRCReturnVoid(autoCaller.rc());
    888917
    889918    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    890 
    891     /*
    892      * Set overall additions run level.
    893      */
    894 
    895     /* First check for disabled status. */
    896     uint32_t uCurFacility = enmFacility + (enmStatus == VBoxGuestFacilityStatus_Active ? 0 : -1);
    897     if (   enmFacility < VBoxGuestFacilityType_VBoxGuestDriver
    898         || (   enmFacility == VBoxGuestFacilityType_All
    899             && enmStatus   == VBoxGuestFacilityStatus_Inactive)
    900        )
    901     {
    902         mData.mAdditionsRunLevel = AdditionsRunLevelType_None;
    903     }
    904     else if (uCurFacility >= VBoxGuestFacilityType_VBoxTrayClient)
    905     {
    906         mData.mAdditionsRunLevel = AdditionsRunLevelType_Desktop;
    907     }
    908     else if (uCurFacility >= VBoxGuestFacilityType_VBoxService)
    909     {
    910         mData.mAdditionsRunLevel = AdditionsRunLevelType_Userland;
    911     }
    912     else if (uCurFacility >= VBoxGuestFacilityType_VBoxGuestDriver)
    913     {
    914         mData.mAdditionsRunLevel = AdditionsRunLevelType_System;
    915     }
    916     else /* Should never happen! */
    917         AssertMsgFailed(("Invalid facility status/run level detected! uCurFacility=%d\n", uCurFacility));
    918 
    919     /** @todo Above is wrong. The runlevel has to be recalculated from the
    920      *        facilities.  A user can stop VBoxService before logging out.
    921      *        The runlevel should then drop to System, not Userland.
    922      *
    923      * Also, if given enmFacility = VBoxGuestFacilityType_Unknown, we'll be
    924      * bosting the runlevel to Desktop (0 - 1 = UINT32_MAX; UINT32_MAX >=
    925      * VBoxGuestFacilityType_VBoxTrayClient). */
    926 
    927     /** @todo VBoxGuest (the driver) should track VMMDevReq_ReportGuestStatus
    928      * calls per session and automatically send VBoxGuestFacilityStatus_Failed
    929      * for the facilites that does not have the status
    930      * VBoxGuestFacilityStatus_Terminated, VBoxGuestFacilityStatus_Failed or
    931      * VBoxGuestFacilityStatus_Inactive.  Not doing so means this
    932      * information is not reliable. */
    933919
    934920    /*
    935921     * Set a specific facility status.
    936922     */
    937     if (enmFacility > VBoxGuestFacilityType_Unknown)
    938     {
    939         if (enmFacility == VBoxGuestFacilityType_All)
    940         {
    941             FacilityMapIter it = mData.mFacilityMap.begin();
    942             while (it != mData.mFacilityMap.end())
    943             {
    944                 facilityUpdate((VBoxGuestFacilityType)it->first, enmStatus);
    945                 it++;
    946             }
    947         }
    948         else /* Update one facility only. */
    949             facilityUpdate(enmFacility, enmStatus);
    950     }
     923    if (a_enmFacility == VBoxGuestFacilityType_All)
     924        for (FacilityMapIter it = mData.mFacilityMap.begin(); it != mData.mFacilityMap.end(); ++it)
     925            facilityUpdate((VBoxGuestFacilityType)it->first, a_enmStatus, a_fFlags, a_pTimeSpecTS);
     926    else /* Update one facility only. */
     927        facilityUpdate(a_enmFacility, a_enmStatus, a_fFlags, a_pTimeSpecTS);
     928
     929    /*
     930     * Recalc the runlevel.
     931     */
     932    if (facilityIsActive(VBoxGuestFacilityType_VBoxTrayClient))
     933        mData.mAdditionsRunLevel = AdditionsRunLevelType_Desktop;
     934    else if (facilityIsActive(VBoxGuestFacilityType_VBoxService))
     935        mData.mAdditionsRunLevel = AdditionsRunLevelType_Userland;
     936    else if (facilityIsActive(VBoxGuestFacilityType_VBoxGuestDriver))
     937        mData.mAdditionsRunLevel = AdditionsRunLevelType_System;
     938    else
     939        mData.mAdditionsRunLevel = AdditionsRunLevelType_None;
    951940}
    952941
     
    963952    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    964953
    965     facilityUpdate(VBoxGuestFacilityType_Seamless, aCaps & VMMDEV_GUEST_SUPPORTS_SEAMLESS ?
    966                    VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive);
     954    /** @todo A nit: The timestamp is wrong on saved state restore. Would be better
     955     *  to move the graphics and seamless capability -> facility translation to
     956     *  VMMDev so this could be saved.  */
     957    RTTIMESPEC TimeSpecTS;
     958    RTTimeNow(&TimeSpecTS);
     959
     960    facilityUpdate(VBoxGuestFacilityType_Seamless,
     961                   aCaps & VMMDEV_GUEST_SUPPORTS_SEAMLESS ? VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive,
     962                   0 /*fFlags*/, &TimeSpecTS);
    967963    /** @todo Add VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING */
    968     facilityUpdate(VBoxGuestFacilityType_Graphics, aCaps & VMMDEV_GUEST_SUPPORTS_GRAPHICS ?
    969                    VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive);
     964    facilityUpdate(VBoxGuestFacilityType_Graphics,
     965                   aCaps & VMMDEV_GUEST_SUPPORTS_GRAPHICS ? VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive,
     966                   0 /*fFlags*/, &TimeSpecTS);
    970967}
    971968/* vi: set tabstop=4 shiftwidth=4 expandtab: */
  • trunk/src/VBox/Main/src-client/VMMDevInterface.cpp

    r39882 r39890  
    158158
    159159/**
    160  * Reports Guest Additions status.
    161  * Called whenever the Additions issue a guest status report request or the VM is reset.
    162  *
    163  * @param   pInterface          Pointer to this interface.
    164  * @param   guestInfo           Pointer to guest information structure
    165  * @thread  The emulation thread.
    166  */
    167 DECLCALLBACK(void) vmmdevUpdateGuestStatus(PPDMIVMMDEVCONNECTOR pInterface, const VBoxGuestStatus *guestStatus)
    168 {
    169     PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
    170 
    171     Assert(guestStatus);
    172     if (!guestStatus)
    173         return;
    174 
     160 * @interface_method_impl{PDMIVMMDEVCONNECTOR,pfnUpdateGuestStatus}
     161 */
     162DECLCALLBACK(void) vmmdevUpdateGuestStatus(PPDMIVMMDEVCONNECTOR pInterface, uint32_t uFacility, uint16_t uStatus,
     163                                           uint32_t fFlags, PCRTTIMESPEC pTimeSpecTS)
     164{
     165    PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
    175166    Console *pConsole = pDrv->pVMMDev->getParent();
    176167
     
    181172        return;
    182173
    183     guest->setAdditionsStatus(guestStatus->facility, guestStatus->status, guestStatus->flags);
     174    guest->setAdditionsStatus((VBoxGuestFacilityType)uFacility, (VBoxGuestFacilityStatus)uStatus, fFlags, pTimeSpecTS);
    184175    pConsole->onAdditionsStateChange();
    185176}
     
    237228         *        while holding down the. */
    238229        guest->setAdditionsInfo2(0, "", 0,  0); /* Clear Guest Additions version. */
    239         guest->setAdditionsStatus(VBoxGuestFacilityType_All,
    240                                   VBoxGuestFacilityStatus_Inactive,
    241                                   0); /* Flags; not used. */
     230        RTTIMESPEC TimeSpecTS;
     231        RTTimeNow(&TimeSpecTS);
     232        guest->setAdditionsStatus(VBoxGuestFacilityType_All, VBoxGuestFacilityStatus_Inactive, 0 /*fFlags*/, &TimeSpecTS);
    242233        pConsole->onAdditionsStateChange();
    243234    }
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette