Changeset 11083 in vbox
- Timestamp:
- Aug 3, 2008 9:14:53 PM (16 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/HostServices/GuestPropertySvc.h
r11082 r11083 39 39 /** 40 40 * 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, 44 44 /** 45 45 * 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, 49 54 /** 50 55 * 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, 54 59 /** 55 60 * Enumerate guest properties. 56 61 * The parameter format matches that of ENUM_PROPS. 57 62 */ 58 ENUM_PROPS_HOST = 563 ENUM_PROPS_HOST = 6 59 64 }; 60 65 -
trunk/src/VBox/HostServices/GuestProperties/service.cpp
r11082 r11083 354 354 uint64_t u64Timestamp = 0; 355 355 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); 359 358 360 359 /* … … 770 769 771 770 /* The host wishes to read a configuration value */ 772 case GET_ CONFIG_KEY_HOST:773 LogFlowFunc(("GET_ CONFIG_KEY_HOST\n"));774 rc = get Key(cParms, paParms);771 case GET_PROP_HOST: 772 LogFlowFunc(("GET_PROP_HOST\n")); 773 rc = getProperty(cParms, paParms); 775 774 break; 776 775 777 776 /* 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")); 780 779 rc = setKey(cParms, paParms); 781 780 break; 782 781 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 783 788 /* The host wishes to remove a configuration value */ 784 case DEL_ CONFIG_KEY_HOST:789 case DEL_PROP_HOST: 785 790 LogFlowFunc(("DEL_CONFIG_KEY_HOST\n")); 786 791 rc = delKey(cParms, paParms); -
trunk/src/VBox/Main/ConsoleImpl.cpp
r11065 r11083 3537 3537 * @note Temporarily locks this object for writing. 3538 3538 */ 3539 HRESULT Console::getGuestProperty (INPTR BSTR aKey, BSTR *aValue) 3539 HRESULT Console::getGuestProperty (INPTR BSTR aName, BSTR *aValue, 3540 ULONG64 *aTimestamp, BSTR *aFlags) 3540 3541 { 3541 3542 #if !defined (VBOX_WITH_GUEST_PROPS) 3542 3543 return E_NOTIMPL; 3543 3544 #else 3544 if (!VALID_PTR (a Key))3545 if (!VALID_PTR (aName)) 3545 3546 return E_INVALIDARG; 3546 3547 if (!VALID_PTR (aValue)) 3547 3548 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; 3548 3553 3549 3554 AutoCaller autoCaller (this); … … 3560 3565 using namespace guestProp; 3561 3566 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]; 3565 3571 3566 3572 parm[0].type = VBOX_HGCM_SVC_PARM_PTR; 3567 3573 /* To save doing a const cast, we use the mutableRaw() member. */ 3568 parm[0].u.pointer.addr = Utf8 Key.mutableRaw();3574 parm[0].u.pointer.addr = Utf8Name.mutableRaw(); 3569 3575 /* The + 1 is the null terminator */ 3570 parm[0].u.pointer.size = Utf8 Key.length() + 1;3576 parm[0].u.pointer.size = Utf8Name.length() + 1; 3571 3577 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]); 3576 3582 /* The returned string should never be able to be greater than our buffer */ 3577 3583 AssertLogRel (vrc != VERR_BUFFER_OVERFLOW); 3584 AssertLogRel (!RT_SUCCESS(vrc) || VBOX_HGCM_SVC_PARM_64BIT == parm[2].type); 3578 3585 if (RT_SUCCESS (vrc) || (VERR_NOT_FOUND == vrc)) 3579 3586 { 3580 3587 rc = S_OK; 3581 3588 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 } 3583 3595 else 3584 3596 aValue = NULL; … … 3594 3606 * @note Temporarily locks this object for writing. 3595 3607 */ 3596 HRESULT Console::setGuestProperty (INPTR BSTR a Key, INPTR BSTR aValue)3608 HRESULT Console::setGuestProperty (INPTR BSTR aName, INPTR BSTR aValue, INPTR BSTR aFlags) 3597 3609 { 3598 3610 #if !defined (VBOX_WITH_GUEST_PROPS) 3599 3611 return E_NOTIMPL; 3600 3612 #else 3601 if (!VALID_PTR (a Key))3613 if (!VALID_PTR (aName)) 3602 3614 return E_INVALIDARG; 3603 3615 if ((aValue != NULL) && !VALID_PTR (aValue)) 3604 3616 return E_INVALIDARG; 3617 if ((aFlags != NULL) && !VALID_PTR (aFlags)) 3618 return E_INVALIDARG; 3605 3619 3606 3620 AutoCaller autoCaller (this); … … 3617 3631 using namespace guestProp; 3618 3632 3619 VBOXHGCMSVCPARM parm[ 2];3620 Utf8Str Utf8 Key = aKey;3633 VBOXHGCMSVCPARM parm[3]; 3634 Utf8Str Utf8Name = aName; 3621 3635 int vrc = VINF_SUCCESS; 3622 3636 3623 3637 parm[0].type = VBOX_HGCM_SVC_PARM_PTR; 3624 3638 /* To save doing a const cast, we use the mutableRaw() member. */ 3625 parm[0].u.pointer.addr = Utf8 Key.mutableRaw();3639 parm[0].u.pointer.addr = Utf8Name.mutableRaw(); 3626 3640 /* 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; 3628 3643 if (aValue != NULL) 3629 3644 { 3630 Utf8Str Utf8Value = aValue;3631 3645 parm[1].type = VBOX_HGCM_SVC_PARM_PTR; 3632 3646 /* To save doing a const cast, we use the mutableRaw() member. */ … … 3634 3648 /* The + 1 is the null terminator */ 3635 3649 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, 3637 3665 2, &parm[0]); 3638 }3639 3666 else 3640 vrc = mVMMDev->hgcmHostCall ("VBoxGuestPropSvc", DEL_ CONFIG_KEY_HOST,3667 vrc = mVMMDev->hgcmHostCall ("VBoxGuestPropSvc", DEL_PROP_HOST, 3641 3668 1, &parm[0]); 3642 3669 if (RT_SUCCESS (vrc)) … … 3746 3773 * arrays supplied by the caller. We start by counting the number of entries. 3747 3774 */ 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 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 } 3760 3787 3761 3788 /* 3762 3789 * And now we create the COM safe arrays and fill them in. 3763 3790 */ 3764 3765 3766 3767 3768 3769 3770 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 { 3772 3799 size_t cchName = strlen(pszBuf + iBuf); 3773 3800 Bstr(pszBuf + iBuf).detachTo(&names[i]); … … 3782 3809 Bstr(pszBuf + iBuf).detachTo(&flags[i]); 3783 3810 iBuf += cchFlags + 1; 3784 3785 3786 3787 3788 3789 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; 3790 3817 #endif /* else !defined (VBOX_WITH_GUEST_PROPS) */ 3791 3818 } … … 4315 4342 } 4316 4343 # 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); 4321 4359 vrc = VINF_SUCCESS; 4360 unsigned iProp = 0; 4322 4361 while (pValue != NULL && RT_SUCCESS(vrc)) 4323 4362 { 4324 4363 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)); 4329 4371 if (RT_SUCCESS(vrc)) 4330 vrc = CFGMR3QueryString (p Registry, szKeyName, szKeyValue, sizeof(szKeyValue));4372 vrc = CFGMR3QueryString (pValues, szPropName, szPropValue, sizeof(szPropValue)); 4331 4373 if (RT_SUCCESS(vrc)) 4332 4374 { 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]); 4341 4381 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)); 4375 4392 # endif /* VBOX_WITH_GUEST_PROPS defined */ 4376 4393 #endif /* VBOX_HGCM */ -
trunk/src/VBox/Main/ConsoleImpl2.cpp
r11076 r11083 47 47 #ifdef VBOX_WITH_GUEST_PROPS 48 48 # include <VBox/HostServices/GuestPropertySvc.h> 49 # include <VBox/com/defs.h> 50 # include <VBox/com/array.h> 49 51 #endif /* VBOX_WITH_GUEST_PROPS */ 50 52 #include <VBox/intnet.h> … … 1721 1723 else 1722 1724 { 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(); 1761 1745 } 1762 1746 -
trunk/src/VBox/Main/MachineImpl.cpp
r11041 r11083 2691 2691 STDMETHODIMP Machine::GetGuestProperty (INPTR BSTR aKey, BSTR *aValue, ULONG64 *aTimestamp, BSTR *aFlags) 2692 2692 { 2693 #if !defined (VBOX_WITH_GUEST_PROPS) 2694 return E_NOTIMPL; 2695 #else 2693 2696 if (!VALID_PTR (aKey)) 2694 2697 return E_INVALIDARG; … … 2699 2702 if (!VALID_PTR (aFlags)) 2700 2703 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 #else2711 if (!VALID_PTR (aKey))2712 return E_INVALIDARG;2713 if (!VALID_PTR (aValue))2714 return E_POINTER;2715 2704 2716 2705 AutoCaller autoCaller (this); … … 2719 2708 AutoReadLock alock (this); 2720 2709 2710 HRESULT rc = checkStateDependency (MutableStateDep); 2711 CheckComRCReturnRC (rc); 2712 2721 2713 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) 2746 2723 { 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; 2751 2728 } 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); 2768 2743 } 2769 2744 return rc; … … 2771 2746 } 2772 2747 2748 STDMETHODIMP Machine::GetGuestPropertyValue (INPTR BSTR aKey, BSTR *aValue) 2749 { 2750 ULONG64 dummyTimestamp; 2751 BSTR dummyFlags; 2752 return GetGuestProperty(aKey, aValue, &dummyTimestamp, &dummyFlags); 2753 } 2754 2773 2755 STDMETHODIMP Machine::GetGuestPropertyTimestamp (INPTR BSTR aKey, ULONG64 *aTimestamp) 2774 2756 { 2775 return E_NOTIMPL; 2757 BSTR dummyValue; 2758 BSTR dummyFlags; 2759 return GetGuestProperty(aKey, &dummyValue, aTimestamp, &dummyFlags); 2776 2760 } 2777 2761 2778 2762 STDMETHODIMP 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)2790 2763 { 2791 2764 #if !defined (VBOX_WITH_GUEST_PROPS) … … 2796 2769 if ((aValue != NULL) && !VALID_PTR (aValue)) 2797 2770 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; 2798 2779 2799 2780 AutoCaller autoCaller (this); 2800 2781 CheckComRCReturnRC (autoCaller.rc()); 2801 2782 2802 /* SetExtraData() needs a write lock */2803 2783 AutoWriteLock alock (this); 2804 2784 2785 HRESULT rc = checkStateDependency (MutableStateDep); 2786 CheckComRCReturnRC (rc); 2787 2805 2788 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) 2830 2798 { 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; 2835 2801 } 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); 2853 2840 } 2854 2841 return rc; 2855 2842 #endif /* else !defined (VBOX_WITH_GUEST_PROPS) */ 2843 } 2844 2845 STDMETHODIMP Machine::SetGuestPropertyValue (INPTR BSTR aName, INPTR BSTR aValue) 2846 { 2847 return SetGuestProperty(aName, aValue, NULL); 2856 2848 } 2857 2849 … … 4836 4828 } 4837 4829 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 4838 4855 AssertComRC (rc); 4839 4856 return rc; … … 6181 6198 guestNode.setValue <ULONG> ("statisticsUpdateInterval", 6182 6199 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 } 6183 6219 } 6184 6220 … … 8731 8767 } 8732 8768 8769 STDMETHODIMP 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 8807 STDMETHODIMP 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 8733 8849 // public methods only for internal purposes 8734 8850 ///////////////////////////////////////////////////////////////////////////// -
trunk/src/VBox/Main/SessionImpl.cpp
r11041 r11083 654 654 } 655 655 656 STDMETHODIMP Session::AccessGuestProperty (INPTR BSTR a Key, INPTR BSTR aValue,657 BOOL aIsSetter, BSTR *aRetValue )656 STDMETHODIMP Session::AccessGuestProperty (INPTR BSTR aName, INPTR BSTR aValue, INPTR BSTR aFlags, 657 BOOL aIsSetter, BSTR *aRetValue, ULONG64 *aRetTimestamp, BSTR *aRetFlags) 658 658 { 659 659 #ifdef VBOX_WITH_GUEST_PROPS … … 666 666 mState); 667 667 AssertReturn (mType == SessionType_Direct, E_UNEXPECTED); 668 if (!VALID_PTR (a Key))668 if (!VALID_PTR (aName)) 669 669 return E_POINTER; 670 670 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)) 671 675 return E_POINTER; 672 676 /* aValue can be NULL for a setter call if the property is to be deleted. */ 673 677 if (aIsSetter && (aValue != NULL) && !VALID_PTR (aValue)) 674 678 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; 675 682 if (!aIsSetter) 676 return mConsole->getGuestProperty (a Key, aRetValue);683 return mConsole->getGuestProperty (aName, aRetValue, aRetTimestamp, aRetFlags); 677 684 else 678 return mConsole->setGuestProperty (a Key, aValue);685 return mConsole->setGuestProperty (aName, aValue, aFlags); 679 686 #else /* VBOX_WITH_GUEST_PROPS not defined */ 680 687 return E_NOTIMPL; -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r11041 r11083 2225 2225 <interface 2226 2226 name="IInternalMachineControl" extends="$unknown" 2227 uuid=" 1063893c-4c38-4304-aee9-73e072c181cc"2227 uuid="de04566a-7125-444b-949e-34e9f3ec3676" 2228 2228 internal="yes" 2229 2229 wsmap="suppress" … … 2462 2462 </method> 2463 2463 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> 2464 2525 </interface> 2465 2526 … … 9780 9841 <interface 9781 9842 name="IInternalSessionControl" extends="$unknown" 9782 uuid=" 0dc8dc04-2d4c-45e7-885c-a0afe7e4dfa7"9843 uuid="2581845a-5a9d-45fb-bc3b-2476552dd970" 9783 9844 internal="yes" 9784 9845 wsmap="suppress" … … 9939 10000 modify guest properties. 9940 10001 </desc> 9941 <param name=" key" type="wstring" dir="in"/>10002 <param name="name" type="wstring" dir="in"/> 9942 10003 <param name="value" type="wstring" dir="in"/> 10004 <param name="flags" type="wstring" dir="in"/> 9943 10005 <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"/> 9945 10009 </method> 9946 10010 -
trunk/src/VBox/Main/include/ConsoleImpl.h
r11041 r11083 182 182 HRESULT onUSBDeviceAttach (IUSBDevice *aDevice, IVirtualBoxErrorInfo *aError, ULONG aMaskedIfs); 183 183 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); 186 186 HRESULT enumerateGuestProperties (INPTR BSTR aPatterns, ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut(BSTR, aValues), ComSafeArrayOut(ULONG64, aTimestamps), ComSafeArrayOut(BSTR, aFlags)); 187 187 VMMDev *getVMMDev() { return mVMMDev; } -
trunk/src/VBox/Main/include/MachineImpl.h
r10868 r11083 229 229 struct HWData 230 230 { 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 231 245 HWData(); 232 246 ~HWData(); … … 248 262 SharedFolderList mSharedFolders; 249 263 ClipboardMode_T mClipboardMode; 264 typedef std::list <GuestProperty> GuestPropertyList; 265 GuestPropertyList mGuestProperties; 266 BOOL mPropertyServiceActive; 250 267 }; 251 268 … … 523 540 STDMETHOD(CanShowConsoleWindow) (BOOL *aCanShow); 524 541 STDMETHOD(ShowConsoleWindow) (ULONG64 *aWinId); 525 STDMETHOD(GetGuestProperty) (INPTR BSTR a Key, BSTR *aValue, ULONG64 *aTimestamp, BSTR *aFlags);526 STDMETHOD(GetGuestPropertyValue) (INPTR BSTR a Key, BSTR *aValue);527 STDMETHOD(GetGuestPropertyTimestamp) (INPTR BSTR a Key, ULONG64 *aTimestamp);528 STDMETHOD(SetGuestProperty) (INPTR BSTR a Key, INPTR BSTR aValue, INPTR BSTR aFlags);529 STDMETHOD(SetGuestPropertyValue) (INPTR BSTR a Key, INPTR BSTR aValue);530 STDMETHOD(EnumerateGuestProperties) (INPTR BSTR aPattern, ComSafeArrayOut(BSTR, a Keys), 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)); 531 548 532 549 // public methods only for internal purposes … … 824 841 STDMETHOD(DiscardCurrentSnapshotAndState) ( 825 842 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)); 826 847 827 848 // public methods only for internal purposes -
trunk/src/VBox/Main/include/SessionImpl.h
r11041 r11083 106 106 STDMETHOD(OnUSBDeviceDetach) (INPTR GUIDPARAM aId, IVirtualBoxErrorInfo *aError); 107 107 STDMETHOD(OnShowWindow) (BOOL aCheck, BOOL *aCanShow, ULONG64 *aWinId); 108 STDMETHOD(AccessGuestProperty) (INPTR BSTR a Key, 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); 110 110 STDMETHOD(EnumerateGuestProperties) (INPTR BSTR aPatterns, 111 111 ComSafeArrayOut(BSTR, aNames), -
trunk/src/VBox/Main/xml/VirtualBox-settings-common.xsd
r10693 r11083 687 687 </xsd:complexType> 688 688 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 689 702 <xsd:complexType name="THardware"> 690 703 <xsd:all> … … 731 744 <xsd:element name="Clipboard" type="TClipboard"/> 732 745 <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> 733 752 </xsd:all> 734 753 </xsd:complexType>
Note:
See TracChangeset
for help on using the changeset viewer.