VirtualBox

Changeset 27818 in vbox for trunk/src


Ignore:
Timestamp:
Mar 30, 2010 11:50:21 AM (15 years ago)
Author:
vboxsync
Message:

Main/GuestProperties: cleaned up and fixed a problem with accessibility of properties after a VM shutdown

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/MachineImpl.cpp

    r27798 r27818  
    110110
    111111    mCurrentStateModified = TRUE;
     112    mGuestPropertiesModified = FALSE;
    112113    mHandleCfgFile = NIL_RTFILE;
    113114
     
    184185#endif
    185186    mSyntheticCpu = false;
    186     mPropertyServiceActive = false;
    187     mGuestPropertiesModified = false;
    188187    mHpetEnabled = false;
    189188
     
    38223821}
    38233822
     3823#ifdef VBOX_WITH_GUEST_PROPS
     3824/**
     3825 * Look up a guest property in VBoxSVC's internal structures.
     3826 */
     3827HRESULT Machine::GetGuestPropertyFromService(IN_BSTR aName,
     3828                                             BSTR *aValue,
     3829                                             ULONG64 *aTimestamp,
     3830                                             BSTR *aFlags)
     3831{
     3832    using namespace guestProp;
     3833
     3834    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     3835    Utf8Str strName(aName);
     3836    HWData::GuestPropertyList::const_iterator it;
     3837
     3838    for (it = mHWData->mGuestProperties.begin();
     3839         it != mHWData->mGuestProperties.end(); ++it)
     3840    {
     3841        if (it->strName == strName)
     3842        {
     3843            char szFlags[MAX_FLAGS_LEN + 1];
     3844            it->strValue.cloneTo(aValue);
     3845            *aTimestamp = it->mTimestamp;
     3846            writeFlags(it->mFlags, szFlags);
     3847            Bstr(szFlags).cloneTo(aFlags);
     3848            break;
     3849        }
     3850    }
     3851    return S_OK;
     3852}
     3853
     3854/**
     3855 * Query the VM that a guest property belongs to for the property.
     3856 * @returns E_ACCESSDENIED if the VM process is not available or not
     3857 *          currently handling queries and the lookup should then be done in
     3858 *          VBoxSVC.
     3859 */
     3860HRESULT Machine::GetGuestPropertyFromVM(IN_BSTR aName,
     3861                                        BSTR *aValue,
     3862                                        ULONG64 *aTimestamp,
     3863                                        BSTR *aFlags)
     3864{
     3865    HRESULT rc;
     3866    ComPtr<IInternalSessionControl> directControl;
     3867    directControl = mData->mSession.mDirectControl;
     3868
     3869    /* fail if we were called after #OnSessionEnd() is called.  This is a
     3870     * silly race condition. */
     3871
     3872    if (!directControl)
     3873        rc = E_ACCESSDENIED;
     3874    else
     3875        rc = directControl->AccessGuestProperty(aName, NULL, NULL,
     3876                                                false /* isSetter */,
     3877                                                aValue, aTimestamp, aFlags);
     3878    return rc;
     3879}
     3880#endif // VBOX_WITH_GUEST_PROPS
     3881
    38243882STDMETHODIMP Machine::GetGuestProperty(IN_BSTR aName,
    38253883                                       BSTR *aValue,
     
    38383896    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    38393897
    3840     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    3841 
    3842     using namespace guestProp;
    3843     HRESULT rc = E_FAIL;
    3844 
    3845     Utf8Str strName(aName);
    3846 
    3847     if (!mHWData->mPropertyServiceActive)
    3848     {
    3849         bool found = false;
    3850         for (HWData::GuestPropertyList::const_iterator it = mHWData->mGuestProperties.begin();
    3851              (it != mHWData->mGuestProperties.end()) && !found;
    3852              ++it)
    3853         {
    3854             if (it->strName == strName)
    3855             {
    3856                 char szFlags[MAX_FLAGS_LEN + 1];
    3857                 it->strValue.cloneTo(aValue);
    3858                 *aTimestamp = it->mTimestamp;
    3859                 writeFlags(it->mFlags, szFlags);
    3860                 Bstr(szFlags).cloneTo(aFlags);
    3861                 found = true;
    3862             }
    3863         }
    3864         rc = S_OK;
    3865     }
    3866     else
    3867     {
    3868         ComPtr<IInternalSessionControl> directControl =
    3869             mData->mSession.mDirectControl;
    3870 
    3871         /* just be on the safe side when calling another process */
    3872         alock.release();
    3873 
    3874         /* fail if we were called after #OnSessionEnd() is called.  This is a
    3875          * silly race condition. */
    3876 
    3877         if (!directControl)
    3878             rc = E_FAIL;
    3879         else
    3880             rc = directControl->AccessGuestProperty(aName, NULL, NULL,
    3881                                                     false /* isSetter */,
    3882                                                     aValue, aTimestamp, aFlags);
    3883     }
     3898    HRESULT rc = GetGuestPropertyFromVM(aName, aValue, aTimestamp, aFlags);
     3899    if (rc == E_ACCESSDENIED)
     3900        /* The VM is not running or the service is not (yet) accessible */
     3901        rc = GetGuestPropertyFromService(aName, aValue, aTimestamp, aFlags);
    38843902    return rc;
    38853903#endif // VBOX_WITH_GUEST_PROPS
     
    39003918}
    39013919
    3902 STDMETHODIMP Machine::SetGuestProperty(IN_BSTR aName,
    3903                                        IN_BSTR aValue,
    3904                                        IN_BSTR aFlags)
    3905 {
    3906 #ifndef VBOX_WITH_GUEST_PROPS
    3907     ReturnComNotImplemented();
    3908 #else // VBOX_WITH_GUEST_PROPS
     3920#ifdef VBOX_WITH_GUEST_PROPS
     3921/**
     3922 * Set a guest property in VBoxSVC's internal structures.
     3923 */
     3924HRESULT Machine::SetGuestPropertyToService(IN_BSTR aName, IN_BSTR aValue,
     3925                                           IN_BSTR aFlags)
     3926{
    39093927    using namespace guestProp;
    39103928
    3911     CheckComArgStrNotEmptyOrNull(aName);
    3912     if ((aFlags != NULL) && !VALID_PTR(aFlags))
    3913         return E_INVALIDARG;
    3914 
     3929    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    39153930    HRESULT rc = S_OK;
     3931    HWData::GuestProperty property;
     3932    property.mFlags = NILFLAG;
     3933    bool found = false;
     3934
     3935    rc = checkStateDependency(MutableStateDep);
     3936    if (FAILED(rc)) return rc;
    39163937
    39173938    try
     
    39193940        Utf8Str utf8Name(aName);
    39203941        Utf8Str utf8Flags(aFlags);
    3921 
    3922         AutoCaller autoCaller(this);
    3923         if (FAILED(autoCaller.rc())) return autoCaller.rc();
    3924 
    3925         AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    3926 
    3927         rc = checkStateDependency(MutableStateDep);
    3928         if (FAILED(rc)) return rc;
    3929 
    3930         rc = S_OK;
    39313942        uint32_t fFlags = NILFLAG;
    39323943        if (    (aFlags != NULL)
     
    39373948                            aFlags);
    39383949
    3939         if (!mHWData->mPropertyServiceActive)
    3940         {
    3941             bool found = false;
    3942             HWData::GuestProperty property;
    3943             property.mFlags = NILFLAG;
    3944 
    3945             /** @todo r=bird: see efficiency rant in PushGuestProperty. (Yeah, I know,
    3946              *        this is simple and do an OK job atm.) */
    3947             for (HWData::GuestPropertyList::iterator it = mHWData->mGuestProperties.begin();
    3948                  it != mHWData->mGuestProperties.end();
    3949                  ++it)
    3950                 if (it->strName == utf8Name)
     3950        /** @todo r=bird: see efficiency rant in PushGuestProperty. (Yeah, I
     3951         *                know, this is simple and do an OK job atm.) */
     3952        HWData::GuestPropertyList::iterator it;
     3953        for (it = mHWData->mGuestProperties.begin();
     3954             it != mHWData->mGuestProperties.end(); ++it)
     3955            if (it->strName == utf8Name)
     3956            {
     3957                property = *it;
     3958                if (it->mFlags & (RDONLYHOST))
     3959                    rc = setError(E_ACCESSDENIED,
     3960                                  tr("The property '%ls' cannot be changed by the host"),
     3961                                  aName);
     3962                else
    39513963                {
    3952                     property = *it;
    3953                     if (it->mFlags & (RDONLYHOST))
    3954                         rc = setError(E_ACCESSDENIED,
    3955                                       tr("The property '%ls' cannot be changed by the host"),
    3956                                       aName);
    3957                     else
    3958                     {
    3959                         setModified(IsModified_MachineData);
    3960                         mHWData.backup();           // @todo r=dj backup in a loop?!?
    3961 
    3962                         /* The backup() operation invalidates our iterator, so
    3963                         * get a new one. */
    3964                         for (it = mHWData->mGuestProperties.begin();
    3965                              it->strName != utf8Name;
    3966                              ++it)
    3967                             ;
    3968                         mHWData->mGuestProperties.erase(it);
    3969                     }
    3970                     found = true;
    3971                     break;
     3964                    setModified(IsModified_MachineData);
     3965                    mHWData.backup();           // @todo r=dj backup in a loop?!?
     3966
     3967                    /* The backup() operation invalidates our iterator, so
     3968                    * get a new one. */
     3969                    for (it = mHWData->mGuestProperties.begin();
     3970                         it->strName != utf8Name;
     3971                         ++it)
     3972                        ;
     3973                    mHWData->mGuestProperties.erase(it);
    39723974                }
    3973             if (found && SUCCEEDED(rc))
    3974             {
    3975                 if (*aValue)
    3976                 {
    3977                     RTTIMESPEC time;
    3978                     property.strValue = aValue;
    3979                     property.mTimestamp = RTTimeSpecGetNano(RTTimeNow(&time));
    3980                     if (aFlags != NULL)
    3981                         property.mFlags = fFlags;
    3982                     mHWData->mGuestProperties.push_back(property);
    3983                 }
     3975                found = true;
     3976                break;
    39843977            }
    3985             else if (SUCCEEDED(rc) && *aValue)
     3978        if (found && SUCCEEDED(rc))
     3979        {
     3980            if (*aValue)
    39863981            {
    39873982                RTTIMESPEC time;
    3988                 setModified(IsModified_MachineData);
    3989                 mHWData.backup();
    3990                 property.strName = aName;
    39913983                property.strValue = aValue;
    39923984                property.mTimestamp = RTTimeSpecGetNano(RTTimeNow(&time));
    3993                 property.mFlags = fFlags;
     3985                if (aFlags != NULL)
     3986                    property.mFlags = fFlags;
    39943987                mHWData->mGuestProperties.push_back(property);
    39953988            }
    3996             if (   SUCCEEDED(rc)
    3997                 && (   mHWData->mGuestPropertyNotificationPatterns.isEmpty()
    3998                     || RTStrSimplePatternMultiMatch(mHWData->mGuestPropertyNotificationPatterns.raw(), RTSTR_MAX,
    3999                                                     utf8Name.raw(), RTSTR_MAX, NULL) )
    4000                )
    4001             {
    4002                 /** @todo r=bird: Why aren't we leaving the lock here?  The
    4003                  *                same code in PushGuestProperty does... */
    4004                 mParent->onGuestPropertyChange(mData->mUuid, aName, aValue, aFlags);
    4005             }
    4006         }
     3989        }
     3990        else if (SUCCEEDED(rc) && *aValue)
     3991        {
     3992            RTTIMESPEC time;
     3993            setModified(IsModified_MachineData);
     3994            mHWData.backup();
     3995            property.strName = aName;
     3996            property.strValue = aValue;
     3997            property.mTimestamp = RTTimeSpecGetNano(RTTimeNow(&time));
     3998            property.mFlags = fFlags;
     3999            mHWData->mGuestProperties.push_back(property);
     4000        }
     4001        if (   SUCCEEDED(rc)
     4002            && (   mHWData->mGuestPropertyNotificationPatterns.isEmpty()
     4003                || RTStrSimplePatternMultiMatch(mHWData->mGuestPropertyNotificationPatterns.raw(), RTSTR_MAX,
     4004                                                utf8Name.raw(), RTSTR_MAX, NULL) )
     4005           )
     4006        {
     4007            /** @todo r=bird: Why aren't we leaving the lock here?  The
     4008             *                same code in PushGuestProperty does... */
     4009            mParent->onGuestPropertyChange(mData->mUuid, aName, aValue, aFlags);
     4010        }
     4011    }
     4012    catch (std::bad_alloc &)
     4013    {
     4014        rc = E_OUTOFMEMORY;
     4015    }
     4016
     4017    return rc;
     4018}
     4019
     4020/**
     4021 * Set a property on the VM that that property belongs to.
     4022 * @returns E_ACCESSDENIED if the VM process is not available or not
     4023 *          currently handling queries and the setting should then be done in
     4024 *          VBoxSVC.
     4025 */
     4026HRESULT Machine::SetGuestPropertyToVM(IN_BSTR aName, IN_BSTR aValue,
     4027                                      IN_BSTR aFlags)
     4028{
     4029    HRESULT rc;
     4030
     4031    try {
     4032        ComPtr<IInternalSessionControl> directControl =
     4033            mData->mSession.mDirectControl;
     4034
     4035        BSTR dummy = NULL;
     4036        ULONG64 dummy64;
     4037        if (!directControl)
     4038            rc = E_ACCESSDENIED;
    40074039        else
    4008         {
    4009             ComPtr<IInternalSessionControl> directControl =
    4010                 mData->mSession.mDirectControl;
    4011 
    4012             /* just be on the safe side when calling another process */
    4013             alock.leave();
    4014 
    4015             BSTR dummy = NULL;
    4016             ULONG64 dummy64;
    4017             if (!directControl)
    4018                 rc = E_FAIL;
    4019             else
    4020                 rc = directControl->AccessGuestProperty(aName,
    4021                                                         *aValue ? aValue : NULL,  /** @todo Fix when adding DeleteGuestProperty(), see defect. */
    4022                                                         aFlags,
    4023                                                         true /* isSetter */,
    4024                                                         &dummy, &dummy64, &dummy);
    4025         }
     4040            rc = directControl->AccessGuestProperty
     4041                     (aName,
     4042                      /** @todo Fix when adding DeleteGuestProperty(),
     4043                                   see defect. */
     4044                      *aValue ? aValue : NULL, aFlags, true /* isSetter */,
     4045                      &dummy, &dummy64, &dummy);
    40264046    }
    40274047    catch (std::bad_alloc &)
     
    40304050    }
    40314051
     4052    return rc;
     4053}
     4054#endif // VBOX_WITH_GUEST_PROPS
     4055
     4056STDMETHODIMP Machine::SetGuestProperty(IN_BSTR aName, IN_BSTR aValue,
     4057                                       IN_BSTR aFlags)
     4058{
     4059#ifndef VBOX_WITH_GUEST_PROPS
     4060    ReturnComNotImplemented();
     4061#else // VBOX_WITH_GUEST_PROPS
     4062    CheckComArgStrNotEmptyOrNull(aName);
     4063    if ((aFlags != NULL) && !VALID_PTR(aFlags))
     4064        return E_INVALIDARG;
     4065    AutoCaller autoCaller(this);
     4066    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     4067
     4068    HRESULT rc = SetGuestPropertyToVM(aName, aValue, aFlags);
     4069    if (rc == E_ACCESSDENIED)
     4070        /* The VM is not running or the service is not (yet) accessible */
     4071        rc = SetGuestPropertyToService(aName, aValue, aFlags);
    40324072    return rc;
    40334073#endif // VBOX_WITH_GUEST_PROPS
     
    40384078    return SetGuestProperty(aName, aValue, NULL);
    40394079}
     4080
     4081#ifdef VBOX_WITH_GUEST_PROPS
     4082/**
     4083 * Enumerate the guest properties in VBoxSVC's internal structures.
     4084 */
     4085HRESULT Machine::EnumerateGuestPropertiesInService
     4086                (IN_BSTR aPatterns, ComSafeArrayOut(BSTR, aNames),
     4087                 ComSafeArrayOut(BSTR, aValues),
     4088                 ComSafeArrayOut(ULONG64, aTimestamps),
     4089                 ComSafeArrayOut(BSTR, aFlags))
     4090{
     4091    using namespace guestProp;
     4092
     4093    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     4094    Utf8Str strPatterns(aPatterns);
     4095
     4096    /*
     4097     * Look for matching patterns and build up a list.
     4098     */
     4099    HWData::GuestPropertyList propList;
     4100    for (HWData::GuestPropertyList::iterator it = mHWData->mGuestProperties.begin();
     4101         it != mHWData->mGuestProperties.end();
     4102         ++it)
     4103        if (   strPatterns.isEmpty()
     4104            || RTStrSimplePatternMultiMatch(strPatterns.raw(),
     4105                                            RTSTR_MAX,
     4106                                            it->strName.raw(),
     4107                                            RTSTR_MAX, NULL)
     4108           )
     4109            propList.push_back(*it);
     4110
     4111    /*
     4112     * And build up the arrays for returning the property information.
     4113     */
     4114    size_t cEntries = propList.size();
     4115    SafeArray<BSTR> names(cEntries);
     4116    SafeArray<BSTR> values(cEntries);
     4117    SafeArray<ULONG64> timestamps(cEntries);
     4118    SafeArray<BSTR> flags(cEntries);
     4119    size_t iProp = 0;
     4120    for (HWData::GuestPropertyList::iterator it = propList.begin();
     4121         it != propList.end();
     4122         ++it)
     4123    {
     4124         char szFlags[MAX_FLAGS_LEN + 1];
     4125         it->strName.cloneTo(&names[iProp]);
     4126         it->strValue.cloneTo(&values[iProp]);
     4127         timestamps[iProp] = it->mTimestamp;
     4128         writeFlags(it->mFlags, szFlags);
     4129         Bstr(szFlags).cloneTo(&flags[iProp]);
     4130         ++iProp;
     4131    }
     4132    names.detachTo(ComSafeArrayOutArg(aNames));
     4133    values.detachTo(ComSafeArrayOutArg(aValues));
     4134    timestamps.detachTo(ComSafeArrayOutArg(aTimestamps));
     4135    flags.detachTo(ComSafeArrayOutArg(aFlags));
     4136    return S_OK;
     4137}
     4138
     4139/**
     4140 * Enumerate the properties managed by a VM.
     4141 * @returns E_ACCESSDENIED if the VM process is not available or not
     4142 *          currently handling queries and the setting should then be done in
     4143 *          VBoxSVC.
     4144 */
     4145HRESULT Machine::EnumerateGuestPropertiesOnVM
     4146                (IN_BSTR aPatterns, ComSafeArrayOut(BSTR, aNames),
     4147                 ComSafeArrayOut(BSTR, aValues),
     4148                 ComSafeArrayOut(ULONG64, aTimestamps),
     4149                 ComSafeArrayOut(BSTR, aFlags))
     4150{
     4151    HRESULT rc;
     4152    ComPtr<IInternalSessionControl> directControl;
     4153    directControl = mData->mSession.mDirectControl;
     4154
     4155    if (!directControl)
     4156        rc = E_ACCESSDENIED;
     4157    else
     4158        rc = directControl->EnumerateGuestProperties
     4159                     (aPatterns, ComSafeArrayOutArg(aNames),
     4160                      ComSafeArrayOutArg(aValues),
     4161                      ComSafeArrayOutArg(aTimestamps),
     4162                      ComSafeArrayOutArg(aFlags));
     4163    return rc;
     4164}
     4165#endif // VBOX_WITH_GUEST_PROPS
    40404166
    40414167STDMETHODIMP Machine::EnumerateGuestProperties(IN_BSTR aPatterns,
     
    40594185    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    40604186
    4061     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    4062 
    4063     using namespace guestProp;
    4064     HRESULT rc = E_FAIL;
    4065 
    4066     Utf8Str strPatterns(aPatterns);
    4067 
    4068     if (!mHWData->mPropertyServiceActive)
    4069     {
    4070 
    4071         /*
    4072          * Look for matching patterns and build up a list.
    4073          */
    4074         HWData::GuestPropertyList propList;
    4075         for (HWData::GuestPropertyList::iterator it = mHWData->mGuestProperties.begin();
    4076              it != mHWData->mGuestProperties.end();
    4077              ++it)
    4078             if (   strPatterns.isEmpty()
    4079                 || RTStrSimplePatternMultiMatch(strPatterns.raw(),
    4080                                                 RTSTR_MAX,
    4081                                                 it->strName.raw(),
    4082                                                 RTSTR_MAX, NULL)
    4083                )
    4084                 propList.push_back(*it);
    4085 
    4086         /*
    4087          * And build up the arrays for returning the property information.
    4088          */
    4089         size_t cEntries = propList.size();
    4090         SafeArray<BSTR> names(cEntries);
    4091         SafeArray<BSTR> values(cEntries);
    4092         SafeArray<ULONG64> timestamps(cEntries);
    4093         SafeArray<BSTR> flags(cEntries);
    4094         size_t iProp = 0;
    4095         for (HWData::GuestPropertyList::iterator it = propList.begin();
    4096              it != propList.end();
    4097              ++it)
    4098         {
    4099              char szFlags[MAX_FLAGS_LEN + 1];
    4100              it->strName.cloneTo(&names[iProp]);
    4101              it->strValue.cloneTo(&values[iProp]);
    4102              timestamps[iProp] = it->mTimestamp;
    4103              writeFlags(it->mFlags, szFlags);
    4104              Bstr(szFlags).cloneTo(&flags[iProp]);
    4105              ++iProp;
    4106         }
    4107         names.detachTo(ComSafeArrayOutArg(aNames));
    4108         values.detachTo(ComSafeArrayOutArg(aValues));
    4109         timestamps.detachTo(ComSafeArrayOutArg(aTimestamps));
    4110         flags.detachTo(ComSafeArrayOutArg(aFlags));
    4111         rc = S_OK;
    4112     }
    4113     else
    4114     {
    4115         ComPtr<IInternalSessionControl> directControl = mData->mSession.mDirectControl;
    4116 
    4117         /* just be on the safe side when calling another process */
    4118         alock.release();
    4119 
    4120         if (!directControl)
    4121             rc = E_FAIL;
    4122         else
    4123             rc = directControl->EnumerateGuestProperties(aPatterns,
    4124                                                          ComSafeArrayOutArg(aNames),
    4125                                                          ComSafeArrayOutArg(aValues),
    4126                                                          ComSafeArrayOutArg(aTimestamps),
    4127                                                          ComSafeArrayOutArg(aFlags));
    4128     }
     4187    HRESULT rc = EnumerateGuestPropertiesOnVM
     4188                     (aPatterns, ComSafeArrayOutArg(aNames),
     4189                      ComSafeArrayOutArg(aValues),
     4190                      ComSafeArrayOutArg(aTimestamps),
     4191                      ComSafeArrayOutArg(aFlags));
     4192    if (rc == E_ACCESSDENIED)
     4193        /* The VM is not running or the service is not (yet) accessible */
     4194        rc = EnumerateGuestPropertiesInService
     4195                     (aPatterns, ComSafeArrayOutArg(aNames),
     4196                      ComSafeArrayOutArg(aValues),
     4197                      ComSafeArrayOutArg(aTimestamps),
     4198                      ComSafeArrayOutArg(aFlags));
    41294199    return rc;
    41304200#endif // VBOX_WITH_GUEST_PROPS
     
    66396709        }
    66406710
    6641         mHWData->mPropertyServiceActive = false;
    66426711        mHWData->mGuestPropertyNotificationPatterns = data.strNotificationPatterns;
    66436712#endif /* VBOX_WITH_GUEST_PROPS defined */
     
    76957764        data.strNotificationPatterns = mHWData->mGuestPropertyNotificationPatterns;
    76967765        /* I presume this doesn't require a backup(). */
    7697         mHWData->mGuestPropertiesModified = false;
     7766        mData->mGuestPropertiesModified = FALSE;
    76987767#endif /* VBOX_WITH_GUEST_PROPS defined */
    76997768    }
     
    98389907    timestamps.detachTo(ComSafeArrayOutArg(aTimestamps));
    98399908    flags.detachTo(ComSafeArrayOutArg(aFlags));
    9840     mHWData->mPropertyServiceActive = true;
    9841     return S_OK;
    9842 #else
    9843     ReturnComNotImplemented();
    9844 #endif
    9845 }
    9846 
    9847 STDMETHODIMP SessionMachine::PushGuestProperties(ComSafeArrayIn(IN_BSTR, aNames),
    9848                                                  ComSafeArrayIn(IN_BSTR, aValues),
    9849                                                  ComSafeArrayIn(ULONG64, aTimestamps),
    9850                                                  ComSafeArrayIn(IN_BSTR, aFlags))
    9851 {
    9852     LogFlowThisFunc(("\n"));
    9853 
    9854 #ifdef VBOX_WITH_GUEST_PROPS
    9855     using namespace guestProp;
    9856 
    9857     AssertReturn(!ComSafeArrayInIsNull(aNames),      E_POINTER);
    9858     AssertReturn(!ComSafeArrayInIsNull(aValues),     E_POINTER);
    9859     AssertReturn(!ComSafeArrayInIsNull(aTimestamps), E_POINTER);
    9860     AssertReturn(!ComSafeArrayInIsNull(aFlags),      E_POINTER);
    9861 
    9862     AutoCaller autoCaller(this);
    9863     AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
    9864 
    9865     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    9866 
    9867     /*
    9868      * Temporarily reset the registered flag, so that our machine state
    9869      * changes (i.e. mHWData.backup()) succeed.  (isMutable() used in all
    9870      * setters will return FALSE for a Machine instance if mRegistered is TRUE).
    9871      *
    9872      * This is copied from registeredInit(), and may or may not be the right
    9873      * way to handle this.
    9874      *
    9875      * @todo r=dj review this, this gets called during machine power-down when
    9876      * we have already saved the machine settings, there's no need to do this
    9877      * twice.
    9878      */
    9879     Assert(mData->mRegistered);
    9880     mData->mRegistered = FALSE;
    9881 
    9882     HRESULT rc = checkStateDependency(MutableStateDep);
    9883     AssertLogRelMsgReturn(SUCCEEDED(rc), ("%Rhrc\n", rc), rc);
    9884 
    9885     com::SafeArray<IN_BSTR> names(     ComSafeArrayInArg(aNames));
    9886     com::SafeArray<IN_BSTR> values(    ComSafeArrayInArg(aValues));
    9887     com::SafeArray<ULONG64> timestamps(ComSafeArrayInArg(aTimestamps));
    9888     com::SafeArray<IN_BSTR> flags(     ComSafeArrayInArg(aFlags));
    9889 
    9890     DiscardSettings();
    9891     setModified(IsModified_MachineData);
    9892     mHWData.backup();
    9893 
    9894     mHWData->mGuestProperties.erase(mHWData->mGuestProperties.begin(),
    9895                                     mHWData->mGuestProperties.end());
    9896     for (unsigned i = 0; i < names.size(); ++i)
    9897     {
    9898         uint32_t fFlags = NILFLAG;
    9899         validateFlags(Utf8Str(flags[i]).raw(), &fFlags);
    9900         HWData::GuestProperty property = { names[i], values[i], timestamps[i], fFlags };
    9901         mHWData->mGuestProperties.push_back(property);
    9902     }
    9903 
    9904     mHWData->mPropertyServiceActive = false;
    9905 
    9906     alock.release();
    9907     SaveSettings();
    9908 
    9909     /* Restore the mRegistered flag. */
    9910     alock.acquire();
    9911     mData->mRegistered = TRUE;
    9912 
    99139909    return S_OK;
    99149910#else
     
    99539949        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    99549950
    9955         AssertReturn(mHWData->mPropertyServiceActive, VBOX_E_INVALID_OBJECT_STATE);
    99569951        switch (mData->mMachineState)
    99579952        {
     
    99889983            {
    99899984                mHWData->mGuestProperties.erase(iter);
    9990                 mHWData->mGuestPropertiesModified = true;
     9985                mData->mGuestPropertiesModified = TRUE;
    99919986                break;
    99929987            }
     
    99959990            HWData::GuestProperty property = { aName, aValue, aTimestamp, fFlags };
    99969991            mHWData->mGuestProperties.push_back(property);
    9997             mHWData->mGuestPropertiesModified = true;
     9992            mData->mGuestPropertiesModified = TRUE;
    99989993        }
    99999994
     
    1082810823
    1082910824        HWData::GuestPropertyList::iterator it;
    10830         BOOL fNeedsSaving = mHWData->mGuestPropertiesModified;
     10825        BOOL fNeedsSaving = mData->mGuestPropertiesModified;
    1083110826        if (!fNeedsSaving)
    1083210827            for (it = mHWData->mGuestProperties.begin();
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r27805 r27818  
    41284128    </method>
    41294129
    4130     <method name="pushGuestProperties">
    4131       <desc>
    4132         Set the list of the guest properties matching a set of patterns along
    4133         with their values, time stamps and flags and return responsibility for
    4134         managing properties to IMachine.
    4135       </desc>
    4136       <param name="name" type="wstring" dir="in" safearray="yes">
    4137         <desc>
    4138           The names of the properties.
    4139         </desc>
    4140       </param>
    4141       <param name="value" type="wstring" dir="in" safearray="yes">
    4142         <desc>
    4143           The values of the properties.  The array entries match the
    4144           corresponding entries in the @a name array.
    4145         </desc>
    4146       </param>
    4147       <param name="timestamp" type="unsigned long long" dir="in" safearray="yes">
    4148         <desc>
    4149           The time stamps of the properties.  The array entries match
    4150           the corresponding entries in the @a name array.
    4151         </desc>
    4152       </param>
    4153       <param name="flags" type="wstring" dir="in" safearray="yes">
    4154         <desc>
    4155           The flags of the properties.  The array entries match the
    4156           corresponding entries in the @a name array.
    4157         </desc>
    4158       </param>
    4159     </method>
    41604130    <method name="pushGuestProperty">
    41614131      <desc>
  • trunk/src/VBox/Main/include/MachineImpl.h

    r27792 r27818  
    185185
    186186        BOOL mCurrentStateModified;
     187        /** Guest properties have been modified and need saving since the
     188         * machine was started, or there are transient properties which need
     189         * deleting and the machine is being shut down. */
     190        BOOL mGuestPropertiesModified;
    187191
    188192        RTFILE mHandleCfgFile;
     
    299303        typedef std::list<GuestProperty> GuestPropertyList;
    300304        GuestPropertyList    mGuestProperties;
    301         BOOL                 mPropertyServiceActive;
    302         BOOL                 mGuestPropertiesModified;
    303305        Utf8Str              mGuestPropertyNotificationPatterns;
    304306
     
    772774    void copyFrom(Machine *aThat);
    773775
     776#ifdef VBOX_WITH_GUEST_PROPS
     777    HRESULT GetGuestPropertyFromService(IN_BSTR aName, BSTR *aValue,
     778                                        ULONG64 *aTimestamp, BSTR *aFlags);
     779    HRESULT GetGuestPropertyFromVM(IN_BSTR aName, BSTR *aValue,
     780                                   ULONG64 *aTimestamp, BSTR *aFlags);
     781    HRESULT SetGuestPropertyToService(IN_BSTR aName, IN_BSTR aValue,
     782                                      IN_BSTR aFlags);
     783    HRESULT SetGuestPropertyToVM(IN_BSTR aName, IN_BSTR aValue,
     784                                 IN_BSTR aFlags);
     785    HRESULT EnumerateGuestPropertiesInService
     786                (IN_BSTR aPatterns, ComSafeArrayOut(BSTR, aNames),
     787                 ComSafeArrayOut(BSTR, aValues),
     788                 ComSafeArrayOut(ULONG64, aTimestamps),
     789                 ComSafeArrayOut(BSTR, aFlags));
     790    HRESULT EnumerateGuestPropertiesOnVM
     791                (IN_BSTR aPatterns, ComSafeArrayOut(BSTR, aNames),
     792                 ComSafeArrayOut(BSTR, aValues),
     793                 ComSafeArrayOut(ULONG64, aTimestamps),
     794                 ComSafeArrayOut(BSTR, aFlags));
     795#endif /* VBOX_WITH_GUEST_PROPS */
     796
    774797#ifdef VBOX_WITH_RESOURCE_USAGE_API
    775798    void registerMetrics(PerformanceCollector *aCollector, Machine *aMachine, RTPROCESS pid);
     
    880903    STDMETHOD(PullGuestProperties)(ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut(BSTR, aValues),
    881904              ComSafeArrayOut(ULONG64, aTimestamps), ComSafeArrayOut(BSTR, aFlags));
    882     STDMETHOD(PushGuestProperties)(ComSafeArrayIn(IN_BSTR, aNames), ComSafeArrayIn(IN_BSTR, aValues),
    883               ComSafeArrayIn(ULONG64, aTimestamps), ComSafeArrayIn(IN_BSTR, aFlags));
    884905    STDMETHOD(PushGuestProperty)(IN_BSTR aName, IN_BSTR aValue,
    885906                                  ULONG64 aTimestamp, IN_BSTR aFlags);
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