VirtualBox

Changeset 11083 in vbox


Ignore:
Timestamp:
Aug 3, 2008 9:14:53 PM (16 years ago)
Author:
vboxsync
Message:

HostServices/GuestProperties, Main: implemented saving guest properties to machine XML, added support for timestamps and did some renaming

Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/HostServices/GuestPropertySvc.h

    r11082 r11083  
    3939    /**
    4040     * Get the value attached to a configuration property key
    41      * The parameter format matches that of GET_CONFIG_KEY.
    42      */
    43     GET_CONFIG_KEY_HOST = 2,
     41     * The parameter format matches that of GET_PROP.
     42     */
     43    GET_PROP_HOST = 2,
    4444    /**
    4545     * Set the value attached to a configuration property key
    46      * The parameter format matches that of SET_CONFIG_KEY.
    47      */
    48     SET_CONFIG_KEY_HOST = 3,
     46     * The parameter format matches that of SET_PROP.
     47     */
     48    SET_PROP_HOST = 3,
     49    /**
     50     * Set the value attached to a configuration property key
     51     * The parameter format matches that of SET_PROP_VALUE.
     52     */
     53    SET_PROP_VALUE_HOST = 4,
    4954    /**
    5055     * Remove the value attached to a configuration property key
    51      * The parameter format matches that of DEL_CONFIG_KEY.
    52      */
    53     DEL_CONFIG_KEY_HOST = 4,
     56     * The parameter format matches that of DEL_PROP.
     57     */
     58    DEL_PROP_HOST = 5,
    5459    /**
    5560     * Enumerate guest properties.
    5661     * The parameter format matches that of ENUM_PROPS.
    5762     */
    58     ENUM_PROPS_HOST = 5
     63    ENUM_PROPS_HOST = 6
    5964};
    6065
  • trunk/src/VBox/HostServices/GuestProperties/service.cpp

    r11082 r11083  
    354354    uint64_t u64Timestamp = 0;
    355355    if (RT_SUCCESS(rc) && (mpTimestampNode != NULL))
    356         rc = CFGMR3QueryU64(mpFlagsNode, pszName, &u64Timestamp);
    357     if (RT_SUCCESS(rc))
    358         VBoxHGCMParmUInt64Set(&paParms[2], 0);
     356        CFGMR3QueryU64(mpTimestampNode, pszName, &u64Timestamp);
     357    VBoxHGCMParmUInt64Set(&paParms[2], u64Timestamp);
    359358
    360359/*
     
    770769
    771770        /* The host wishes to read a configuration value */
    772         case GET_CONFIG_KEY_HOST:
    773             LogFlowFunc(("GET_CONFIG_KEY_HOST\n"));
    774             rc = getKey(cParms, paParms);
     771        case GET_PROP_HOST:
     772            LogFlowFunc(("GET_PROP_HOST\n"));
     773            rc = getProperty(cParms, paParms);
    775774            break;
    776775
    777776        /* The host wishes to set a configuration value */
    778         case SET_CONFIG_KEY_HOST:
    779             LogFlowFunc(("SET_CONFIG_KEY_HOST\n"));
     777        case SET_PROP_HOST:
     778            LogFlowFunc(("SET_PROP_HOST\n"));
    780779            rc = setKey(cParms, paParms);
    781780            break;
    782781
     782        /* The host wishes to set a configuration value */
     783        case SET_PROP_VALUE_HOST:
     784            LogFlowFunc(("SET_PROP_VALUE_HOST\n"));
     785            rc = setKey(cParms, paParms);
     786            break;
     787
    783788        /* The host wishes to remove a configuration value */
    784         case DEL_CONFIG_KEY_HOST:
     789        case DEL_PROP_HOST:
    785790            LogFlowFunc(("DEL_CONFIG_KEY_HOST\n"));
    786791            rc = delKey(cParms, paParms);
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r11065 r11083  
    35373537 * @note Temporarily locks this object for writing.
    35383538 */
    3539 HRESULT Console::getGuestProperty (INPTR BSTR aKey, BSTR *aValue)
     3539HRESULT Console::getGuestProperty (INPTR BSTR aName, BSTR *aValue,
     3540                                   ULONG64 *aTimestamp, BSTR *aFlags)
    35403541{
    35413542#if !defined (VBOX_WITH_GUEST_PROPS)
    35423543    return E_NOTIMPL;
    35433544#else
    3544     if (!VALID_PTR (aKey))
     3545    if (!VALID_PTR (aName))
    35453546        return E_INVALIDARG;
    35463547    if (!VALID_PTR (aValue))
    35473548        return E_POINTER;
     3549    if ((aTimestamp != NULL) && !VALID_PTR (aTimestamp))
     3550        return E_POINTER;
     3551    if ((aFlags != NULL) && !VALID_PTR (aFlags))
     3552        return E_POINTER;
    35483553
    35493554    AutoCaller autoCaller (this);
     
    35603565    using namespace guestProp;
    35613566
    3562     VBOXHGCMSVCPARM parm[3];
    3563     Utf8Str Utf8Key = aKey;
    3564     Utf8Str Utf8Value (MAX_VALUE_LEN + 1);
     3567    VBOXHGCMSVCPARM parm[4];
     3568    Utf8Str Utf8Name = aName;
     3569    AssertReturn(!Utf8Name.isNull(), E_OUTOFMEMORY);
     3570    char pszBuffer[MAX_VALUE_LEN + MAX_FLAGS_LEN + 2];
    35653571
    35663572    parm[0].type = VBOX_HGCM_SVC_PARM_PTR;
    35673573    /* To save doing a const cast, we use the mutableRaw() member. */
    3568     parm[0].u.pointer.addr = Utf8Key.mutableRaw();
     3574    parm[0].u.pointer.addr = Utf8Name.mutableRaw();
    35693575    /* The + 1 is the null terminator */
    3570     parm[0].u.pointer.size = Utf8Key.length() + 1;
     3576    parm[0].u.pointer.size = Utf8Name.length() + 1;
    35713577    parm[1].type = VBOX_HGCM_SVC_PARM_PTR;
    3572     parm[1].u.pointer.addr = Utf8Value.mutableRaw();
    3573     parm[1].u.pointer.size = MAX_VALUE_LEN + 1;
    3574     int vrc = mVMMDev->hgcmHostCall ("VBoxGuestPropSvc", GET_CONFIG_KEY_HOST,
    3575                                      3, &parm[0]);
     3578    parm[1].u.pointer.addr = pszBuffer;
     3579    parm[1].u.pointer.size = sizeof(pszBuffer);
     3580    int vrc = mVMMDev->hgcmHostCall ("VBoxGuestPropSvc", GET_PROP_HOST,
     3581                                     4, &parm[0]);
    35763582    /* The returned string should never be able to be greater than our buffer */
    35773583    AssertLogRel (vrc != VERR_BUFFER_OVERFLOW);
     3584    AssertLogRel (!RT_SUCCESS(vrc) || VBOX_HGCM_SVC_PARM_64BIT == parm[2].type);
    35783585    if (RT_SUCCESS (vrc) || (VERR_NOT_FOUND == vrc))
    35793586    {
    35803587        rc = S_OK;
    35813588        if (vrc != VERR_NOT_FOUND)
    3582             Utf8Value.cloneTo (aValue);
     3589        {
     3590            size_t iFlags = strlen(pszBuffer) + 1;
     3591            Utf8Str(pszBuffer).cloneTo (aValue);
     3592            *aTimestamp = parm[2].u.uint32;
     3593            Utf8Str(pszBuffer + iFlags).cloneTo (aFlags);
     3594        }
    35833595        else
    35843596            aValue = NULL;
     
    35943606 * @note Temporarily locks this object for writing.
    35953607 */
    3596 HRESULT Console::setGuestProperty (INPTR BSTR aKey, INPTR BSTR aValue)
     3608HRESULT Console::setGuestProperty (INPTR BSTR aName, INPTR BSTR aValue, INPTR BSTR aFlags)
    35973609{
    35983610#if !defined (VBOX_WITH_GUEST_PROPS)
    35993611    return E_NOTIMPL;
    36003612#else
    3601     if (!VALID_PTR (aKey))
     3613    if (!VALID_PTR (aName))
    36023614        return E_INVALIDARG;
    36033615    if ((aValue != NULL) && !VALID_PTR (aValue))
    36043616        return E_INVALIDARG;
     3617    if ((aFlags != NULL) && !VALID_PTR (aFlags))
     3618        return E_INVALIDARG;
    36053619
    36063620    AutoCaller autoCaller (this);
     
    36173631    using namespace guestProp;
    36183632
    3619     VBOXHGCMSVCPARM parm[2];
    3620     Utf8Str Utf8Key = aKey;
     3633    VBOXHGCMSVCPARM parm[3];
     3634    Utf8Str Utf8Name = aName;
    36213635    int vrc = VINF_SUCCESS;
    36223636
    36233637    parm[0].type = VBOX_HGCM_SVC_PARM_PTR;
    36243638    /* To save doing a const cast, we use the mutableRaw() member. */
    3625     parm[0].u.pointer.addr = Utf8Key.mutableRaw();
     3639    parm[0].u.pointer.addr = Utf8Name.mutableRaw();
    36263640    /* The + 1 is the null terminator */
    3627     parm[0].u.pointer.size = Utf8Key.length() + 1;
     3641    parm[0].u.pointer.size = Utf8Name.length() + 1;
     3642    Utf8Str Utf8Value = aValue;
    36283643    if (aValue != NULL)
    36293644    {
    3630         Utf8Str Utf8Value = aValue;
    36313645        parm[1].type = VBOX_HGCM_SVC_PARM_PTR;
    36323646        /* To save doing a const cast, we use the mutableRaw() member. */
     
    36343648        /* The + 1 is the null terminator */
    36353649        parm[1].u.pointer.size = Utf8Value.length() + 1;
    3636         vrc = mVMMDev->hgcmHostCall ("VBoxGuestPropSvc", SET_CONFIG_KEY_HOST,
     3650    }
     3651    Utf8Str Utf8Flags = aFlags;
     3652    if (aFlags != NULL)
     3653    {
     3654        parm[2].type = VBOX_HGCM_SVC_PARM_PTR;
     3655        /* To save doing a const cast, we use the mutableRaw() member. */
     3656        parm[2].u.pointer.addr = Utf8Flags.mutableRaw();
     3657        /* The + 1 is the null terminator */
     3658        parm[2].u.pointer.size = Utf8Flags.length() + 1;
     3659    }
     3660    if ((aValue != NULL) && (aFlags != NULL))
     3661        vrc = mVMMDev->hgcmHostCall ("VBoxGuestPropSvc", SET_PROP_HOST,
     3662                                     3, &parm[0]);
     3663    else if (aValue != NULL)
     3664        vrc = mVMMDev->hgcmHostCall ("VBoxGuestPropSvc", SET_PROP_VALUE_HOST,
    36373665                                     2, &parm[0]);
    3638     }
    36393666    else
    3640         vrc = mVMMDev->hgcmHostCall ("VBoxGuestPropSvc", DEL_CONFIG_KEY_HOST,
     3667        vrc = mVMMDev->hgcmHostCall ("VBoxGuestPropSvc", DEL_PROP_HOST,
    36413668                                     1, &parm[0]);
    36423669    if (RT_SUCCESS (vrc))
     
    37463773 * arrays supplied by the caller.  We start by counting the number of entries.
    37473774 */
    3748      const char *pszBuf
    3749          = reinterpret_cast<const char *>(parm[1].u.pointer.addr);
    3750      unsigned cEntries = 0;
    3751      /* The list is terminated by a zero-length string at the end of a set
    3752       * of four strings. */
    3753      for (size_t i = 0; strlen(pszBuf + i) != 0; )
    3754      {
    3755         /* We are counting sets of four strings. */
    3756         for (unsigned j = 0; j < 4; ++j)
    3757             i += strlen(pszBuf + i) + 1;
    3758         ++cEntries;
    3759      }
     3775    const char *pszBuf
     3776        = reinterpret_cast<const char *>(parm[1].u.pointer.addr);
     3777    unsigned cEntries = 0;
     3778    /* The list is terminated by a zero-length string at the end of a set
     3779     * of four strings. */
     3780    for (size_t i = 0; strlen(pszBuf + i) != 0; )
     3781    {
     3782       /* We are counting sets of four strings. */
     3783       for (unsigned j = 0; j < 4; ++j)
     3784           i += strlen(pszBuf + i) + 1;
     3785       ++cEntries;
     3786    }
    37603787
    37613788/*
    37623789 * And now we create the COM safe arrays and fill them in.
    37633790 */
    3764      com::SafeArray <BSTR> names(cEntries);
    3765      com::SafeArray <BSTR> values(cEntries);
    3766      com::SafeArray <ULONG64> timestamps(cEntries);
    3767      com::SafeArray <BSTR> flags(cEntries);
    3768      size_t iBuf = 0;
    3769      /* Rely on the service to have formated the data correctly. */
    3770      for (unsigned i = 0; i < cEntries; ++i)
    3771      {
     3791    com::SafeArray <BSTR> names(cEntries);
     3792    com::SafeArray <BSTR> values(cEntries);
     3793    com::SafeArray <ULONG64> timestamps(cEntries);
     3794    com::SafeArray <BSTR> flags(cEntries);
     3795    size_t iBuf = 0;
     3796    /* Rely on the service to have formated the data correctly. */
     3797    for (unsigned i = 0; i < cEntries; ++i)
     3798    {
    37723799        size_t cchName = strlen(pszBuf + iBuf);
    37733800        Bstr(pszBuf + iBuf).detachTo(&names[i]);
     
    37823809        Bstr(pszBuf + iBuf).detachTo(&flags[i]);
    37833810        iBuf += cchFlags + 1;
    3784      }
    3785      names.detachTo(ComSafeArrayOutArg (aNames));
    3786      values.detachTo(ComSafeArrayOutArg (aValues));
    3787      timestamps.detachTo(ComSafeArrayOutArg (aTimestamps));
    3788      flags.detachTo(ComSafeArrayOutArg (aFlags));
    3789      return S_OK;
     3811    }
     3812    names.detachTo(ComSafeArrayOutArg (aNames));
     3813    values.detachTo(ComSafeArrayOutArg (aValues));
     3814    timestamps.detachTo(ComSafeArrayOutArg (aTimestamps));
     3815    flags.detachTo(ComSafeArrayOutArg (aFlags));
     3816    return S_OK;
    37903817#endif /* else !defined (VBOX_WITH_GUEST_PROPS) */
    37913818}
     
    43154342    }
    43164343# ifdef VBOX_WITH_GUEST_PROPS
    4317     /* Save all guest/host property store entries to the machine XML
    4318      * file as extra data. */
    4319     PCFGMNODE pRegistry = CFGMR3GetChild (CFGMR3GetRoot (mpVM), "GuestProps/Values/");
    4320     PCFGMLEAF pValue = CFGMR3GetFirstValue (pRegistry);
     4344    /* Save all guest property store entries to the machine XML file */
     4345    PCFGMNODE pValues = CFGMR3GetChild (CFGMR3GetRoot (mpVM), "GuestProps/Values/");
     4346    PCFGMNODE pTimestamps = CFGMR3GetChild (CFGMR3GetRoot (mpVM), "GuestProps/Timestamps/");
     4347    PCFGMNODE pFlags = CFGMR3GetChild (CFGMR3GetRoot (mpVM), "GuestProps/Flags/");
     4348    /* Count the number of entries we have */
     4349    unsigned cValues = 0;
     4350    for (PCFGMLEAF pValue = CFGMR3GetFirstValue (pValues); pValue != NULL;
     4351         pValue = CFGMR3GetNextValue (pValue))
     4352        ++cValues;
     4353    /* And pack them into safe arrays */
     4354    com::SafeArray <BSTR> names(cValues);
     4355    com::SafeArray <BSTR> values(cValues);
     4356    com::SafeArray <ULONG64> timestamps(cValues);
     4357    com::SafeArray <BSTR> flags(cValues);
     4358    PCFGMLEAF pValue = CFGMR3GetFirstValue (pValues);
    43214359    vrc = VINF_SUCCESS;
     4360    unsigned iProp = 0;
    43224361    while (pValue != NULL && RT_SUCCESS(vrc))
    43234362    {
    43244363        using namespace guestProp;
    4325         char szKeyName[MAX_NAME_LEN + 1];
    4326         char szKeyValue[MAX_VALUE_LEN + 1];
    4327         char szExtraDataName[VBOX_SHARED_INFO_PREFIX_LEN + MAX_NAME_LEN + 1];
    4328         vrc = CFGMR3GetValueName (pValue, szKeyName, sizeof(szKeyName));
     4364
     4365        char szPropName[MAX_NAME_LEN + 1];
     4366        char szPropValue[MAX_VALUE_LEN + 1];
     4367        char szPropFlags[MAX_FLAGS_LEN + 1];
     4368        ULONG64 u64Timestamp = 0;  /* default */
     4369        szPropFlags[0] = '\0';  /* default */
     4370        vrc = CFGMR3GetValueName (pValue, szPropName, sizeof(szPropName));
    43294371        if (RT_SUCCESS(vrc))
    4330             vrc = CFGMR3QueryString (pRegistry, szKeyName, szKeyValue, sizeof(szKeyValue));
     4372            vrc = CFGMR3QueryString (pValues, szPropName, szPropValue, sizeof(szPropValue));
    43314373        if (RT_SUCCESS(vrc))
    43324374        {
    4333             strcpy(szExtraDataName, VBOX_SHARED_INFO_KEY_PREFIX);
    4334             strncpy(szExtraDataName + VBOX_SHARED_INFO_PREFIX_LEN, szKeyName, sizeof(szKeyName));
    4335             szExtraDataName[sizeof(szExtraDataName) - 1] = 0;
    4336         }
    4337         if (RT_SUCCESS(vrc))
    4338             if (FAILED(mMachine->SetExtraData(Bstr(szExtraDataName).raw(), Bstr(szKeyValue).raw())))
    4339                 vrc = VERR_UNRESOLVED_ERROR;  /* We only need to know that we have to stop. */
    4340         if (RT_SUCCESS(vrc))
     4375            CFGMR3QueryString (pFlags, szPropName, szPropFlags, sizeof(szPropFlags));
     4376            CFGMR3QueryU64 (pTimestamps, szPropName, &u64Timestamp);
     4377            Bstr(szPropName).cloneTo(&names[iProp]);
     4378            Bstr(szPropValue).cloneTo(&values[iProp]);
     4379            timestamps[iProp] = u64Timestamp;
     4380            Bstr(szPropFlags).cloneTo(&flags[iProp]);
    43414381            pValue = CFGMR3GetNextValue (pValue);
    4342     }
    4343     /* In a second stage, we remove any extra data keys corresponding to
    4344      * properties which aren't in the CFGM node. */
    4345     Bstr strExtraDataKey;
    4346     for (;;)
    4347     {
    4348         using namespace guestProp;
    4349         Bstr strNextExtraDataKey;
    4350         Bstr strExtraDataValue;
    4351 
    4352         /* get the next key */
    4353         int hrc = mMachine->GetNextExtraDataKey(strExtraDataKey, strNextExtraDataKey.asOutParam(),
    4354                                                 strExtraDataValue.asOutParam());
    4355 
    4356         /* stop if for some reason there's nothing more to request */
    4357         if (FAILED(hrc) || !strNextExtraDataKey)
    4358             break;
    4359 
    4360         strExtraDataKey = strNextExtraDataKey;
    4361         Utf8Str strExtraDataKeyUtf8 = Utf8Str(strExtraDataKey);
    4362 
    4363         /* we only care about keys starting with VBOX_SHARED_INFO_KEY_PREFIX */
    4364         if (strncmp(strExtraDataKeyUtf8.raw(), VBOX_SHARED_INFO_KEY_PREFIX, VBOX_SHARED_INFO_PREFIX_LEN) != 0)
    4365             continue;
    4366         char *pszCFGMValueName = (char*)strExtraDataKeyUtf8.raw() + VBOX_SHARED_INFO_PREFIX_LEN;
    4367 
    4368         /* Now see if a lookup of the name in the CFGM node succeeds. */
    4369         char szKeyValue[MAX_VALUE_LEN + 1];
    4370         vrc = CFGMR3QueryString (pRegistry, pszCFGMValueName, szKeyValue, sizeof(szKeyValue));
    4371         /* And delete it from the extra data if it failed. */
    4372         if (VERR_CFGM_VALUE_NOT_FOUND == vrc)
    4373             mMachine->SetExtraData(strExtraDataKey, NULL);
    4374     }
     4382            ++iProp;
     4383            if (iProp >= cValues)
     4384                vrc = VERR_TOO_MUCH_DATA;
     4385        }
     4386    }
     4387    if (RT_SUCCESS(vrc) || (VERR_TOO_MUCH_DATA == vrc))
     4388        mControl->PushGuestProperties(ComSafeArrayAsInParam (names),
     4389                                      ComSafeArrayAsInParam (values),
     4390                                      ComSafeArrayAsInParam (timestamps),
     4391                                      ComSafeArrayAsInParam (flags));
    43754392# endif /* VBOX_WITH_GUEST_PROPS defined */
    43764393#endif /* VBOX_HGCM */
  • trunk/src/VBox/Main/ConsoleImpl2.cpp

    r11076 r11083  
    4747#ifdef VBOX_WITH_GUEST_PROPS
    4848# include <VBox/HostServices/GuestPropertySvc.h>
     49# include <VBox/com/defs.h>
     50# include <VBox/com/array.h>
    4951#endif /* VBOX_WITH_GUEST_PROPS */
    5052#include <VBox/intnet.h>
     
    17211723        else
    17221724        {
    1723             rc = CFGMR3InsertNode(pRoot,       "GuestProps", &pGuestProps);              RC_CHECK();
    1724             rc = CFGMR3InsertNode(pGuestProps, "Values", &pValues);                      RC_CHECK();
    1725             rc = CFGMR3InsertNode(pGuestProps, "Timestamps", &pTimestamps);              RC_CHECK();
    1726             rc = CFGMR3InsertNode(pGuestProps, "Flags", &pFlags);                        RC_CHECK();
    1727             /* Load the saved machine registry.  This is stored as extra data
    1728              * keys in the machine XML file, starting with the prefix
    1729              * VBOX_SHARED_INFO_KEY_PREFIX. */
    1730             Bstr strExtraDataKey;
    1731             for (;;)
    1732             {
    1733                 Bstr strNextExtraDataKey;
    1734                 Bstr strExtraDataValue;
    1735 
    1736                 /* get the next key */
    1737                 hrc = pMachine->GetNextExtraDataKey(strExtraDataKey, strNextExtraDataKey.asOutParam(),
    1738                                                     strExtraDataValue.asOutParam());
    1739 
    1740                 /* stop if for some reason there's nothing more to request */
    1741                 if (FAILED(hrc) || !strNextExtraDataKey)
    1742                     break;
    1743 
    1744                 strExtraDataKey = strNextExtraDataKey;
    1745                 Utf8Str strExtraDataKeyUtf8 = Utf8Str(strExtraDataKey);
    1746 
    1747                 /* we only care about keys starting with VBOX_SHARED_INFO_KEY_PREFIX */
    1748                 if (strncmp(strExtraDataKeyUtf8.raw(), VBOX_SHARED_INFO_KEY_PREFIX, VBOX_SHARED_INFO_PREFIX_LEN) != 0)
    1749                     continue;
    1750                 char *pszCFGMValueName = (char*)strExtraDataKeyUtf8.raw() + VBOX_SHARED_INFO_PREFIX_LEN;
    1751 
    1752                 /* now let's have a look at the value */
    1753                 Utf8Str strCFGMValueUtf8 = Utf8Str(strExtraDataValue);
    1754                 const char *pszCFGMValue = strCFGMValueUtf8.raw();
    1755                 /* empty value means remove value which we've already done */
    1756                 if (pszCFGMValue && *pszCFGMValue)
    1757                 {
    1758                     rc = CFGMR3InsertString(pValues, pszCFGMValueName, pszCFGMValue);
    1759                     AssertMsgRC(rc, ("failed to insert CFGM value '%s' to key '%s'\n", pszCFGMValue, pszCFGMValueName));
    1760                 }
     1725            rc = CFGMR3InsertNode(pRoot,       "GuestProps", &pGuestProps);             RC_CHECK();
     1726            rc = CFGMR3InsertNode(pGuestProps, "Values", &pValues);                     RC_CHECK();
     1727            rc = CFGMR3InsertNode(pGuestProps, "Timestamps", &pTimestamps);             RC_CHECK();
     1728            rc = CFGMR3InsertNode(pGuestProps, "Flags", &pFlags);                       RC_CHECK();
     1729
     1730            /* Pull over the properties from the server. */
     1731            SafeArray <BSTR> names;
     1732            SafeArray <BSTR> values;
     1733            SafeArray <ULONG64> timestamps;
     1734            SafeArray <BSTR> flags;
     1735            hrc = pConsole->mControl->PullGuestProperties(ComSafeArrayAsOutParam(names),
     1736                                                ComSafeArrayAsOutParam(values),
     1737                                                ComSafeArrayAsOutParam(timestamps),
     1738                                                ComSafeArrayAsOutParam(flags));                H();
     1739            size_t cProps = names.size();
     1740            for (size_t i = 0; i < cProps; ++i)
     1741            {
     1742                rc = CFGMR3InsertString(pValues, Utf8Str(names[i]).raw(), Utf8Str(values[i]).raw()); RC_CHECK();
     1743                rc = CFGMR3InsertInteger(pTimestamps, Utf8Str(names[i]).raw(), timestamps[i]);           RC_CHECK();
     1744                rc = CFGMR3InsertString(pFlags, Utf8Str(names[i]).raw(), Utf8Str(flags[i]).raw());   RC_CHECK();
    17611745            }
    17621746
  • trunk/src/VBox/Main/MachineImpl.cpp

    r11041 r11083  
    26912691STDMETHODIMP Machine::GetGuestProperty (INPTR BSTR aKey, BSTR *aValue, ULONG64 *aTimestamp, BSTR *aFlags)
    26922692{
     2693#if !defined (VBOX_WITH_GUEST_PROPS)
     2694    return E_NOTIMPL;
     2695#else
    26932696    if (!VALID_PTR (aKey))
    26942697        return E_INVALIDARG;
     
    26992702    if (!VALID_PTR (aFlags))
    27002703        return E_POINTER;
    2701     *aTimestamp = 0;
    2702     Bstr().cloneTo(aFlags);
    2703     return GetGuestPropertyValue (aKey, aValue);
    2704 }
    2705 
    2706 STDMETHODIMP Machine::GetGuestPropertyValue (INPTR BSTR aKey, BSTR *aValue)
    2707 {
    2708 #if !defined (VBOX_WITH_GUEST_PROPS)
    2709     return E_NOTIMPL;
    2710 #else
    2711     if (!VALID_PTR (aKey))
    2712         return E_INVALIDARG;
    2713     if (!VALID_PTR (aValue))
    2714         return E_POINTER;
    27152704
    27162705    AutoCaller autoCaller (this);
     
    27192708    AutoReadLock alock (this);
    27202709
     2710    HRESULT rc = checkStateDependency (MutableStateDep);
     2711    CheckComRCReturnRC (rc);
     2712
    27212713    using namespace guestProp;
    2722     HRESULT rc = E_FAIL;
    2723 
    2724     switch (mData->mSession.mState)
    2725     {
    2726         case SessionState_Closed:
    2727         {
    2728             /* The "+ 1" in the length is the null terminator. */
    2729             Bstr strKey (Bstr (aKey).length() + VBOX_SHARED_INFO_PREFIX_LEN + 1);
    2730             BSTR strKeyRaw = strKey.mutableRaw();
    2731 
    2732             /* String manipulation in Main is pretty painful, especially given
    2733              * how often it is needed. */
    2734             for (unsigned i = 0; i < VBOX_SHARED_INFO_PREFIX_LEN; ++i)
    2735                 /* I take it this is legal, at least g++ accepts it. */
    2736                 strKeyRaw [i] = VBOX_SHARED_INFO_KEY_PREFIX[i];
    2737             /* The "+ 1" in the length is the null terminator. */
    2738             for (unsigned i = 0, len = Bstr (aKey).length() + 1; i < len; ++i)
    2739                 strKeyRaw [i + VBOX_SHARED_INFO_PREFIX_LEN] = aKey [i];
    2740             rc = GetExtraData (strKey, aValue);
    2741             break;
    2742         }
    2743         case SessionState_Open:
    2744         {
    2745             if (mData->mSession.mState != SessionState_Open)
     2714    rc = E_FAIL;
     2715
     2716    if (!mHWData->mPropertyServiceActive)
     2717    {
     2718        bool found = false;
     2719        for (HWData::GuestPropertyList::const_iterator it = mHWData->mGuestProperties.begin();
     2720             (it != mHWData->mGuestProperties.end()) && !found; ++it)
     2721        {
     2722            if (it->mName == aKey)
    27462723            {
    2747                 rc = setError (E_FAIL,
    2748                     tr ("Session is not open (session state: %d)"),
    2749                     mData->mSession.mState);
    2750                 break;
     2724                it->mValue.cloneTo(aValue);
     2725                *aTimestamp = it->mTimestamp;
     2726                it->mFlags.cloneTo(aFlags);
     2727                found = true;
    27512728            }
    2752 
    2753             ComPtr <IInternalSessionControl> directControl =
    2754                 mData->mSession.mDirectControl;
    2755 
    2756             /* just be on the safe side when calling another process */
    2757             alock.unlock();
    2758 
    2759             rc = directControl->AccessGuestProperty (aKey, NULL,
    2760                                                      false /* isSetter */,
    2761                                                      aValue);
    2762             break;
    2763         }
    2764         default:
    2765             rc = setError (E_FAIL,
    2766                 tr ("Session is currently transitioning (session state: %d)"),
    2767                 mData->mSession.mState);
     2729        }
     2730        rc = S_OK;
     2731    }
     2732    else
     2733    {
     2734        ComPtr <IInternalSessionControl> directControl =
     2735            mData->mSession.mDirectControl;
     2736
     2737        /* just be on the safe side when calling another process */
     2738        alock.unlock();
     2739
     2740        rc = directControl->AccessGuestProperty (aKey, NULL, NULL,
     2741                                                 false /* isSetter */,
     2742                                                 aValue, aTimestamp, aFlags);
    27682743    }
    27692744    return rc;
     
    27712746}
    27722747
     2748STDMETHODIMP Machine::GetGuestPropertyValue (INPTR BSTR aKey, BSTR *aValue)
     2749{
     2750    ULONG64 dummyTimestamp;
     2751    BSTR dummyFlags;
     2752    return GetGuestProperty(aKey, aValue, &dummyTimestamp, &dummyFlags);
     2753}
     2754
    27732755STDMETHODIMP Machine::GetGuestPropertyTimestamp (INPTR BSTR aKey, ULONG64 *aTimestamp)
    27742756{
    2775     return E_NOTIMPL;
     2757    BSTR dummyValue;
     2758    BSTR dummyFlags;
     2759    return GetGuestProperty(aKey, &dummyValue, aTimestamp, &dummyFlags);
    27762760}
    27772761
    27782762STDMETHODIMP Machine::SetGuestProperty (INPTR BSTR aKey, INPTR BSTR aValue, INPTR BSTR aFlags)
    2779 {
    2780     if (!VALID_PTR (aKey))
    2781         return E_INVALIDARG;
    2782     if ((aValue != NULL) && !VALID_PTR (aValue))
    2783         return E_INVALIDARG;
    2784     if ((aFlags != NULL) && !VALID_PTR (aFlags))
    2785         return E_INVALIDARG;
    2786     return SetGuestPropertyValue (aKey, aValue);
    2787 }
    2788 
    2789 STDMETHODIMP Machine::SetGuestPropertyValue (INPTR BSTR aKey, INPTR BSTR aValue)
    27902763{
    27912764#if !defined (VBOX_WITH_GUEST_PROPS)
     
    27962769    if ((aValue != NULL) && !VALID_PTR (aValue))
    27972770        return E_INVALIDARG;
     2771    if ((aFlags != NULL) && !VALID_PTR (aFlags))
     2772        return E_INVALIDARG;
     2773
     2774    /* For now there are no valid flags, so check this. */
     2775    if (aFlags != NULL)
     2776        for (size_t i = 0; aFlags[i] != '\0'; ++i)
     2777            if (aFlags[i] != ' ')
     2778                return E_INVALIDARG;
    27982779
    27992780    AutoCaller autoCaller (this);
    28002781    CheckComRCReturnRC (autoCaller.rc());
    28012782
    2802     /* SetExtraData() needs a write lock */
    28032783    AutoWriteLock alock (this);
    28042784
     2785    HRESULT rc = checkStateDependency (MutableStateDep);
     2786    CheckComRCReturnRC (rc);
     2787
    28052788    using namespace guestProp;
    2806     HRESULT rc = E_FAIL;
    2807 
    2808     switch (mData->mSession.mState)
    2809     {
    2810         case SessionState_Closed:
    2811         {
    2812             /* The "+ 1" in the length is the null terminator. */
    2813             Bstr strKey (Bstr (aKey).length() + VBOX_SHARED_INFO_PREFIX_LEN + 1);
    2814             BSTR strKeyRaw = strKey.mutableRaw();
    2815 
    2816             /* String manipulation in Main is pretty painful, especially given
    2817              * how often it is needed. */
    2818             for (unsigned i = 0; i < VBOX_SHARED_INFO_PREFIX_LEN; ++i)
    2819                 /* I take it this is legal, at least g++ accepts it. */
    2820                 strKeyRaw [i] = VBOX_SHARED_INFO_KEY_PREFIX[i];
    2821             /* The "+ 1" in the length is the null terminator. */
    2822             for (unsigned i = 0, len = Bstr (aKey).length() + 1; i < len; ++i)
    2823                 strKeyRaw [i + VBOX_SHARED_INFO_PREFIX_LEN] = aKey [i];
    2824             rc = SetExtraData (strKey, aValue);
    2825             break;
    2826         }
    2827         case SessionState_Open:
    2828         {
    2829             if (mData->mSession.mState != SessionState_Open)
     2789    rc = E_FAIL;
     2790
     2791    if (!mHWData->mPropertyServiceActive)
     2792    {
     2793        bool found = false;
     2794        HWData::GuestPropertyList::iterator targetIt = mHWData->mGuestProperties.end();
     2795        for (HWData::GuestPropertyList::iterator it = mHWData->mGuestProperties.begin();
     2796             (it != mHWData->mGuestProperties.end()) && !found; ++it)
     2797            if (it->mName == aKey)
    28302798            {
    2831                 rc = setError (E_FAIL,
    2832                     tr ("Session is not open (session state: %d)"),
    2833                     mData->mSession.mState);
    2834                 break;
     2799                targetIt = it;
     2800                found = true;
    28352801            }
    2836 
    2837             ComPtr <IInternalSessionControl> directControl =
    2838                 mData->mSession.mDirectControl;
    2839 
    2840             /* just be on the safe side when calling another process */
    2841             alock.leave();
    2842 
    2843             BSTR dummy = NULL;
    2844             rc = directControl->AccessGuestProperty (aKey, aValue,
    2845                                                      true /* isSetter */,
    2846                                                      &dummy);
    2847             break;
    2848         }
    2849         default:
    2850             rc = setError (E_FAIL,
    2851                 tr ("Session is currently transitioning (session state: %d)"),
    2852                 mData->mSession.mState);
     2802        if (targetIt != mHWData->mGuestProperties.end())
     2803        {
     2804            mHWData.backup();
     2805            if (NULL == aValue)
     2806                mHWData->mGuestProperties.erase(targetIt);
     2807            else
     2808            {
     2809                targetIt->mValue = aValue;
     2810                targetIt->mTimestamp = RTTimeMilliTS();
     2811                if (aFlags != NULL)
     2812                    targetIt->mFlags = aFlags;
     2813            }
     2814        }
     2815        else if (aValue != NULL)
     2816        {
     2817            mHWData.backup();
     2818            HWData::GuestProperty property;
     2819            property.mName = aKey;
     2820            property.mValue = aValue;
     2821            property.mTimestamp = RTTimeMilliTS();
     2822            property.mFlags = (aFlags != NULL ? Bstr(aFlags) : Bstr(""));
     2823            mHWData->mGuestProperties.push_back(property);
     2824        }
     2825        rc = S_OK;
     2826    }
     2827    else
     2828    {
     2829        ComPtr <IInternalSessionControl> directControl =
     2830            mData->mSession.mDirectControl;
     2831
     2832        /* just be on the safe side when calling another process */
     2833        alock.leave();
     2834
     2835        BSTR dummy = NULL;
     2836        ULONG64 dummy64;
     2837        rc = directControl->AccessGuestProperty (aKey, aValue, aFlags,
     2838                                                 true /* isSetter */,
     2839                                                 &dummy, &dummy64, &dummy);
    28532840    }
    28542841    return rc;
    28552842#endif /* else !defined (VBOX_WITH_GUEST_PROPS) */
     2843}
     2844
     2845STDMETHODIMP Machine::SetGuestPropertyValue (INPTR BSTR aName, INPTR BSTR aValue)
     2846{
     2847    return SetGuestProperty(aName, aValue, NULL);
    28562848}
    28572849
     
    48364828    }
    48374829
     4830    /* Guest properties (optional) */
     4831    {
     4832        Key guestPropertiesNode = aNode.findKey ("GuestProperties");
     4833        if (!guestPropertiesNode.isNull())
     4834        {
     4835            Key::List properties = guestPropertiesNode.keys ("GuestProperty");
     4836            for (Key::List::const_iterator it = properties.begin();
     4837                 it != properties.end(); ++ it)
     4838            {
     4839                /* property name (required) */
     4840                Bstr name = (*it).stringValue ("name");
     4841                /* property value (required) */
     4842                Bstr value = (*it).stringValue ("value");
     4843                /* property timestamp (optional, defaults to 0) */
     4844                ULONG64 timestamp = (*it).value<ULONG64> ("timestamp");
     4845                /* property flags (optional, defaults to empty) */
     4846                Bstr flags = (*it).stringValue ("flags");
     4847   
     4848                HWData::GuestProperty property = { name, value, timestamp, flags };
     4849                mHWData->mGuestProperties.push_back(property);
     4850            }
     4851        }
     4852        mHWData->mPropertyServiceActive = false;
     4853    }
     4854
    48384855    AssertComRC (rc);
    48394856    return rc;
     
    61816198        guestNode.setValue <ULONG> ("statisticsUpdateInterval",
    61826199                                    mHWData->mStatisticsUpdateInterval);
     6200    }
     6201
     6202    /* Guest properties */
     6203    {
     6204        Key guestPropertiesNode = aNode.createKey ("GuestProperties");
     6205
     6206        for (HWData::GuestPropertyList::const_iterator it = mHWData->mGuestProperties.begin();
     6207             it != mHWData->mGuestProperties.end();
     6208             ++ it)
     6209        {
     6210            HWData::GuestProperty property = *it;
     6211
     6212            Key propertyNode = guestPropertiesNode.appendKey ("GuestProperty");
     6213
     6214            propertyNode.setValue <Bstr> ("name", property.mName);
     6215            propertyNode.setValue <Bstr> ("value", property.mValue);
     6216            propertyNode.setValue <ULONG64> ("timestamp", property.mTimestamp);
     6217            propertyNode.setValue <Bstr> ("flags", property.mFlags);
     6218        }
    61836219    }
    61846220
     
    87318767}
    87328768
     8769STDMETHODIMP SessionMachine::PullGuestProperties (ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut(BSTR, aValues),
     8770              ComSafeArrayOut(ULONG64, aTimestamps), ComSafeArrayOut(BSTR, aFlags))
     8771{
     8772    LogFlowThisFunc (("\n"));
     8773
     8774    AutoCaller autoCaller (this);
     8775    AssertComRCReturn (autoCaller.rc(), autoCaller.rc());
     8776
     8777    AutoReadLock alock (this);
     8778
     8779    AssertReturn(!ComSafeArrayOutIsNull (aNames), E_POINTER);
     8780    AssertReturn(!ComSafeArrayOutIsNull (aValues), E_POINTER);
     8781    AssertReturn(!ComSafeArrayOutIsNull (aTimestamps), E_POINTER);
     8782    AssertReturn(!ComSafeArrayOutIsNull (aFlags), E_POINTER);
     8783
     8784    unsigned cEntries = mHWData->mGuestProperties.size();
     8785    com::SafeArray <BSTR> names(cEntries);
     8786    com::SafeArray <BSTR> values(cEntries);
     8787    com::SafeArray <ULONG64> timestamps(cEntries);
     8788    com::SafeArray <BSTR> flags(cEntries);
     8789    unsigned i = 0;
     8790    for (HWData::GuestPropertyList::iterator it = mHWData->mGuestProperties.begin();
     8791         it != mHWData->mGuestProperties.end(); ++it)
     8792    {
     8793        it->mName.cloneTo(&names[i]);
     8794        it->mValue.cloneTo(&values[i]);
     8795        timestamps[i] = it->mTimestamp;
     8796        it->mFlags.cloneTo(&flags[i]);
     8797        ++i;
     8798    }
     8799    names.detachTo(ComSafeArrayOutArg (aNames));
     8800    values.detachTo(ComSafeArrayOutArg (aValues));
     8801    timestamps.detachTo(ComSafeArrayOutArg (aTimestamps));
     8802    flags.detachTo(ComSafeArrayOutArg (aFlags));
     8803    mHWData->mPropertyServiceActive = true;
     8804    return S_OK;
     8805}
     8806
     8807STDMETHODIMP SessionMachine::PushGuestProperties (ComSafeArrayIn(INPTR BSTR, aNames),
     8808                                                  ComSafeArrayIn(INPTR BSTR, aValues),
     8809                                                  ComSafeArrayIn(ULONG64, aTimestamps),
     8810                                                  ComSafeArrayIn(INPTR BSTR, aFlags))
     8811{
     8812    LogFlowThisFunc (("\n"));
     8813    AutoCaller autoCaller (this);
     8814    AssertComRCReturn (autoCaller.rc(), autoCaller.rc());
     8815
     8816    AutoWriteLock alock (this);
     8817
     8818    mData->mRegistered = FALSE;
     8819    HRESULT rc = checkStateDependency (MutableStateDep);
     8820    LogRel(("checkStateDependency (MutableStateDep) returned 0x%x\n", rc));
     8821    CheckComRCReturnRC (rc);
     8822
     8823    // ComAssertRet (mData->mMachineState < MachineState_Running, E_FAIL);
     8824
     8825    AssertReturn(!ComSafeArrayInIsNull (aNames), E_POINTER);
     8826    AssertReturn(!ComSafeArrayInIsNull (aValues), E_POINTER);
     8827    AssertReturn(!ComSafeArrayInIsNull (aTimestamps), E_POINTER);
     8828    AssertReturn(!ComSafeArrayInIsNull (aFlags), E_POINTER);
     8829
     8830    com::SafeArray <INPTR BSTR> names(ComSafeArrayInArg(aNames));
     8831    com::SafeArray <INPTR BSTR> values(ComSafeArrayInArg(aValues));
     8832    com::SafeArray <ULONG64> timestamps(ComSafeArrayInArg(aTimestamps));
     8833    com::SafeArray <INPTR BSTR> flags(ComSafeArrayInArg(aFlags));
     8834    mHWData.backup();
     8835    mHWData->mGuestProperties.erase(mHWData->mGuestProperties.begin(),
     8836                                    mHWData->mGuestProperties.end());
     8837    for (unsigned i = 0; i < names.size(); ++i)
     8838    {
     8839        HWData::GuestProperty property = { names[i], values[i], timestamps[i], flags[i] };
     8840        mHWData->mGuestProperties.push_back(property);
     8841    }
     8842    mHWData->mPropertyServiceActive = false;
     8843    alock.unlock();
     8844    SaveSettings();
     8845    mData->mRegistered = TRUE;
     8846    return S_OK;
     8847}
     8848
    87338849// public methods only for internal purposes
    87348850/////////////////////////////////////////////////////////////////////////////
  • trunk/src/VBox/Main/SessionImpl.cpp

    r11041 r11083  
    654654}
    655655
    656 STDMETHODIMP Session::AccessGuestProperty (INPTR BSTR aKey, INPTR BSTR aValue,
    657                                            BOOL aIsSetter, BSTR *aRetValue)
     656STDMETHODIMP Session::AccessGuestProperty (INPTR BSTR aName, INPTR BSTR aValue, INPTR BSTR aFlags,
     657                                           BOOL aIsSetter, BSTR *aRetValue, ULONG64 *aRetTimestamp, BSTR *aRetFlags)
    658658{
    659659#ifdef VBOX_WITH_GUEST_PROPS
     
    666666            mState);
    667667    AssertReturn (mType == SessionType_Direct, E_UNEXPECTED);
    668     if (!VALID_PTR (aKey))
     668    if (!VALID_PTR (aName))
    669669        return E_POINTER;
    670670    if (!aIsSetter && !VALID_PTR (aRetValue))
     671        return E_POINTER;
     672    if (!aIsSetter && !VALID_PTR (aRetTimestamp))
     673        return E_POINTER;
     674    if (!aIsSetter && !VALID_PTR (aRetFlags))
    671675        return E_POINTER;
    672676    /* aValue can be NULL for a setter call if the property is to be deleted. */
    673677    if (aIsSetter && (aValue != NULL) && !VALID_PTR (aValue))
    674678        return E_INVALIDARG;
     679    /* aFlags can be null if it is to be left as is */
     680    if (aIsSetter && (aFlags != NULL) && !VALID_PTR (aFlags))
     681        return E_INVALIDARG;
    675682    if (!aIsSetter)
    676         return mConsole->getGuestProperty (aKey, aRetValue);
     683        return mConsole->getGuestProperty (aName, aRetValue, aRetTimestamp, aRetFlags);
    677684    else
    678         return mConsole->setGuestProperty (aKey, aValue);
     685        return mConsole->setGuestProperty (aName, aValue, aFlags);
    679686#else /* VBOX_WITH_GUEST_PROPS not defined */
    680687    return E_NOTIMPL;
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r11041 r11083  
    22252225  <interface
    22262226     name="IInternalMachineControl" extends="$unknown"
    2227      uuid="1063893c-4c38-4304-aee9-73e072c181cc"
     2227     uuid="de04566a-7125-444b-949e-34e9f3ec3676"
    22282228     internal="yes"
    22292229     wsmap="suppress"
     
    24622462    </method>
    24632463
     2464    <method name="pullGuestProperties">
     2465      <desc>
     2466        Get the list of the guest properties matching a set of patterns along
     2467        with their values, timestamps and flags and give responsibility for
     2468        managing properties to the console.
     2469      </desc>
     2470      <param name="name" type="wstring" dir="out" safearray="yes">
     2471        <desc>
     2472          The names of the properties returned.
     2473        </desc>
     2474      </param>
     2475      <param name="value" type="wstring" dir="out" safearray="yes">
     2476        <desc>
     2477          The values of the properties returned.  The array entries match the
     2478          corresponding entries in the @a name array.
     2479        </desc>
     2480      </param>
     2481      <param name="timestamp" type="unsigned long long" dir="out" safearray="yes">
     2482        <desc>
     2483          The timestamps of the properties returned.  The array entries match
     2484          the corresponding entries in the @a name array.
     2485        </desc>
     2486      </param>
     2487      <param name="flags" type="wstring" dir="out" safearray="yes">
     2488        <desc>
     2489          The flags of the properties returned.  The array entries match the
     2490          corresponding entries in the @a name array.
     2491        </desc>
     2492      </param>
     2493    </method>
     2494
     2495    <method name="pushGuestProperties">
     2496      <desc>
     2497        Set the list of the guest properties matching a set of patterns along
     2498        with their values, timestamps and flags and return responsibility for
     2499        managing properties to IMachine.
     2500      </desc>
     2501      <param name="name" type="wstring" dir="in" safearray="yes">
     2502        <desc>
     2503          The names of the properties returned.
     2504        </desc>
     2505      </param>
     2506      <param name="value" type="wstring" dir="in" safearray="yes">
     2507        <desc>
     2508          The values of the properties returned.  The array entries match the
     2509          corresponding entries in the @a name array.
     2510        </desc>
     2511      </param>
     2512      <param name="timestamp" type="unsigned long long" dir="in" safearray="yes">
     2513        <desc>
     2514          The timestamps of the properties returned.  The array entries match
     2515          the corresponding entries in the @a name array.
     2516        </desc>
     2517      </param>
     2518      <param name="flags" type="wstring" dir="in" safearray="yes">
     2519        <desc>
     2520          The flags of the properties returned.  The array entries match the
     2521          corresponding entries in the @a name array.
     2522        </desc>
     2523      </param>
     2524    </method>
    24642525  </interface>
    24652526
     
    97809841  <interface
    97819842     name="IInternalSessionControl" extends="$unknown"
    9782      uuid="0dc8dc04-2d4c-45e7-885c-a0afe7e4dfa7"
     9843     uuid="2581845a-5a9d-45fb-bc3b-2476552dd970"
    97839844     internal="yes"
    97849845     wsmap="suppress"
     
    993910000        modify guest properties.
    994010001      </desc>
    9941       <param name="key" type="wstring" dir="in"/>
     10002      <param name="name" type="wstring" dir="in"/>
    994210003      <param name="value" type="wstring" dir="in"/>
     10004      <param name="flags" type="wstring" dir="in"/>
    994310005      <param name="isSetter" type="boolean" dir="in"/>
    9944       <param name="retValue" type="wstring" dir="return"/>
     10006      <param name="retValue" type="wstring" dir="out"/>
     10007      <param name="retTimestamp" type="unsigned long long" dir="out"/>
     10008      <param name="retFlags" type="wstring" dir="out"/>
    994510009    </method>
    994610010
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r11041 r11083  
    182182    HRESULT onUSBDeviceAttach (IUSBDevice *aDevice, IVirtualBoxErrorInfo *aError, ULONG aMaskedIfs);
    183183    HRESULT onUSBDeviceDetach (INPTR GUIDPARAM aId, IVirtualBoxErrorInfo *aError);
    184     HRESULT getGuestProperty (INPTR BSTR aKey, BSTR *aValue);
    185     HRESULT setGuestProperty (INPTR BSTR aKey, INPTR BSTR aValue);
     184    HRESULT getGuestProperty (INPTR BSTR aKey, BSTR *aValue, ULONG64 *aTimestamp, BSTR *aFlags);
     185    HRESULT setGuestProperty (INPTR BSTR aKey, INPTR BSTR aValue, INPTR BSTR aFlags);
    186186    HRESULT enumerateGuestProperties (INPTR BSTR aPatterns, ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut(BSTR, aValues), ComSafeArrayOut(ULONG64, aTimestamps), ComSafeArrayOut(BSTR, aFlags));
    187187    VMMDev *getVMMDev() { return mVMMDev; }
  • trunk/src/VBox/Main/include/MachineImpl.h

    r10868 r11083  
    229229    struct HWData
    230230    {
     231        /**
     232         * Data structure to hold information about a guest property.
     233         */
     234        struct GuestProperty {
     235            /** Property name */
     236            Bstr mName;
     237            /** Property value */
     238            Bstr mValue;
     239            /** Property timestamp */
     240            ULONG64 mTimestamp;
     241            /** Property flags */
     242            Bstr mFlags;
     243        };
     244
    231245        HWData();
    232246        ~HWData();
     
    248262        SharedFolderList mSharedFolders;
    249263        ClipboardMode_T mClipboardMode;
     264        typedef std::list <GuestProperty> GuestPropertyList;
     265        GuestPropertyList mGuestProperties;
     266        BOOL           mPropertyServiceActive;
    250267    };
    251268
     
    523540    STDMETHOD(CanShowConsoleWindow) (BOOL *aCanShow);
    524541    STDMETHOD(ShowConsoleWindow) (ULONG64 *aWinId);
    525     STDMETHOD(GetGuestProperty) (INPTR BSTR aKey, BSTR *aValue, ULONG64 *aTimestamp, BSTR *aFlags);
    526     STDMETHOD(GetGuestPropertyValue) (INPTR BSTR aKey, BSTR *aValue);
    527     STDMETHOD(GetGuestPropertyTimestamp) (INPTR BSTR aKey, ULONG64 *aTimestamp);
    528     STDMETHOD(SetGuestProperty) (INPTR BSTR aKey, INPTR BSTR aValue, INPTR BSTR aFlags);
    529     STDMETHOD(SetGuestPropertyValue) (INPTR BSTR aKey, INPTR BSTR aValue);
    530     STDMETHOD(EnumerateGuestProperties) (INPTR BSTR aPattern, ComSafeArrayOut(BSTR, aKeys), ComSafeArrayOut(BSTR, aValues), ComSafeArrayOut(ULONG64, aTimestamps), ComSafeArrayOut(BSTR, aFlags));
     542    STDMETHOD(GetGuestProperty) (INPTR BSTR aName, BSTR *aValue, ULONG64 *aTimestamp, BSTR *aFlags);
     543    STDMETHOD(GetGuestPropertyValue) (INPTR BSTR aName, BSTR *aValue);
     544    STDMETHOD(GetGuestPropertyTimestamp) (INPTR BSTR aName, ULONG64 *aTimestamp);
     545    STDMETHOD(SetGuestProperty) (INPTR BSTR aName, INPTR BSTR aValue, INPTR BSTR aFlags);
     546    STDMETHOD(SetGuestPropertyValue) (INPTR BSTR aName, INPTR BSTR aValue);
     547    STDMETHOD(EnumerateGuestProperties) (INPTR BSTR aPattern, ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut(BSTR, aValues), ComSafeArrayOut(ULONG64, aTimestamps), ComSafeArrayOut(BSTR, aFlags));
    531548
    532549    // public methods only for internal purposes
     
    824841    STDMETHOD(DiscardCurrentSnapshotAndState) (
    825842        IConsole *aInitiator, MachineState_T *aMachineState, IProgress **aProgress);
     843    STDMETHOD(PullGuestProperties) (ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut(BSTR, aValues),
     844              ComSafeArrayOut(ULONG64, aTimestamps), ComSafeArrayOut(BSTR, aFlags));
     845    STDMETHOD(PushGuestProperties) (ComSafeArrayIn(INPTR BSTR, aNames), ComSafeArrayIn(INPTR BSTR, aValues),
     846              ComSafeArrayIn(ULONG64, aTimestamps), ComSafeArrayIn(INPTR BSTR, aFlags));
    826847
    827848    // public methods only for internal purposes
  • trunk/src/VBox/Main/include/SessionImpl.h

    r11041 r11083  
    106106    STDMETHOD(OnUSBDeviceDetach) (INPTR GUIDPARAM aId, IVirtualBoxErrorInfo *aError);
    107107    STDMETHOD(OnShowWindow) (BOOL aCheck, BOOL *aCanShow, ULONG64 *aWinId);
    108     STDMETHOD(AccessGuestProperty) (INPTR BSTR aKey, INPTR BSTR aValue,
    109                                     BOOL aIsSetter, BSTR *aRetValue);
     108    STDMETHOD(AccessGuestProperty) (INPTR BSTR aName, INPTR BSTR aValue, INPTR BSTR aFlags,
     109                                    BOOL aIsSetter, BSTR *aRetValue, ULONG64 *aRetTimestamp, BSTR *aRetFlags);
    110110    STDMETHOD(EnumerateGuestProperties) (INPTR BSTR aPatterns,
    111111                                         ComSafeArrayOut(BSTR, aNames),
  • trunk/src/VBox/Main/xml/VirtualBox-settings-common.xsd

    r10693 r11083  
    687687</xsd:complexType>
    688688
     689<xsd:complexType name="TGuestProperty">
     690  <xsd:attribute name="name"      type="xsd:string"       use="required"/>
     691  <xsd:attribute name="value"     type="xsd:string"       use="required"/>
     692  <xsd:attribute name="timestamp" type="xsd:unsignedLong" default="0"/>
     693  <xsd:attribute name="flags"     type="xsd:string"       default=""/>
     694</xsd:complexType>
     695
     696<xsd:complexType name="TGuestProperties">
     697  <xsd:sequence>
     698    <xsd:element name="GuestProperty" type="TGuestProperty" minOccurs="0" maxOccurs="unbounded"/>
     699  </xsd:sequence>
     700</xsd:complexType>
     701
    689702<xsd:complexType name="THardware">
    690703  <xsd:all>
     
    731744    <xsd:element name="Clipboard" type="TClipboard"/>
    732745    <xsd:element name="Guest" type="TGuest"/>
     746    <xsd:element name="GuestProperties" type="TGuestProperties" minOccurs="0">
     747      <xsd:unique name="THardware-GuestProperties-GuestProperty">
     748        <xsd:selector xpath="vb:GuestProperty"/>
     749        <xsd:field xpath="@name"/>
     750      </xsd:unique>
     751    </xsd:element>
    733752  </xsd:all>
    734753</xsd:complexType>
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