Changeset 11041 in vbox
- Timestamp:
- Jul 31, 2008 6:00:42 PM (17 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/ConsoleImpl.cpp
r10901 r11041 84 84 #ifdef VBOX_WITH_GUEST_PROPS 85 85 # include <VBox/HostServices/GuestPropertySvc.h> 86 # include <VBox/com/array.h> 86 87 #endif 87 88 … … 3645 3646 tr ("Failed to call the VBoxGuestPropSvc service (%Rrc)"), vrc); 3646 3647 return rc; 3648 #endif /* else !defined (VBOX_WITH_GUEST_PROPS) */ 3649 } 3650 3651 3652 /** 3653 * @note Temporarily locks this object for writing. 3654 */ 3655 HRESULT Console::enumerateGuestProperties (INPTR BSTR aPatterns, 3656 ComSafeArrayOut(BSTR, aNames), 3657 ComSafeArrayOut(BSTR, aValues), 3658 ComSafeArrayOut(ULONG64, aTimestamps), 3659 ComSafeArrayOut(BSTR, aFlags)) 3660 { 3661 #if !defined (VBOX_WITH_GUEST_PROPS) 3662 return E_NOTIMPL; 3663 #else 3664 if (!VALID_PTR (aPatterns) && (aPatterns != NULL)) 3665 return E_POINTER; 3666 if (ComSafeArrayOutIsNull (aNames)) 3667 return E_POINTER; 3668 if (ComSafeArrayOutIsNull (aValues)) 3669 return E_POINTER; 3670 if (ComSafeArrayOutIsNull (aTimestamps)) 3671 return E_POINTER; 3672 if (ComSafeArrayOutIsNull (aFlags)) 3673 return E_POINTER; 3674 3675 AutoCaller autoCaller (this); 3676 AssertComRCReturnRC (autoCaller.rc()); 3677 3678 /* protect mpVM (if not NULL) */ 3679 AutoVMCallerWeak autoVMCaller (this); 3680 CheckComRCReturnRC (autoVMCaller.rc()); 3681 3682 /* Note: validity of mVMMDev which is bound to uninit() is guaranteed by 3683 * autoVMCaller, so there is no need to hold a lock of this */ 3684 3685 using namespace guestProp; 3686 3687 VBOXHGCMSVCPARM parm[3]; 3688 3689 /* 3690 * Set up the pattern parameter, translating the comma-separated list to a 3691 * double-terminated zero-separated one. 3692 */ 3693 Utf8Str Utf8PatternsIn = aPatterns; 3694 if ((aPatterns != NULL) && Utf8PatternsIn.isNull()) 3695 return E_OUTOFMEMORY; 3696 size_t cchPatterns = Utf8PatternsIn.length(); 3697 Utf8Str Utf8Patterns(cchPatterns + 2); /* Double terminator */ 3698 if (Utf8Patterns.isNull()) 3699 return E_OUTOFMEMORY; 3700 char *pszPatterns = Utf8Patterns.mutableRaw(); 3701 unsigned iPatterns = 0; 3702 for (unsigned i = 0; i < cchPatterns; ++i) 3703 { 3704 char cIn = Utf8PatternsIn.raw()[i]; 3705 if ((cIn != ',') && (cIn != ' ')) 3706 pszPatterns[iPatterns] = cIn; 3707 else if (cIn != ' ') 3708 pszPatterns[iPatterns] = '\0'; 3709 if (cIn != ' ') 3710 ++iPatterns; 3711 } 3712 pszPatterns[iPatterns] = '\0'; 3713 parm[0].type = VBOX_HGCM_SVC_PARM_PTR; 3714 parm[0].u.pointer.addr = pszPatterns; 3715 parm[0].u.pointer.size = cchPatterns + 1; 3716 3717 /* 3718 * Now things get slightly complicated. Due to a race with the guest adding 3719 * properties, there is no good way to know how much large a buffer to provide 3720 * the service to enumerate into. We choose a decent starting size and loop a 3721 * few times, each time retrying with the size suggested by the service plus 3722 * one Kb. 3723 */ 3724 size_t cchBuf = 4096; 3725 Utf8Str Utf8Buf; 3726 int vrc = VERR_BUFFER_OVERFLOW; 3727 for (unsigned i = 0; i < 10 && (VERR_BUFFER_OVERFLOW == vrc); ++i) 3728 { 3729 Utf8Buf.alloc(cchBuf + 1024); 3730 if (Utf8Buf.isNull()) 3731 return E_OUTOFMEMORY; 3732 parm[1].type = VBOX_HGCM_SVC_PARM_PTR; 3733 parm[1].u.pointer.addr = Utf8Buf.mutableRaw(); 3734 parm[1].u.pointer.size = cchBuf + 1024; 3735 vrc = mVMMDev->hgcmHostCall ("VBoxGuestPropSvc", ENUM_PROPS_HOST, 3, 3736 &parm[0]); 3737 if (parm[2].type != VBOX_HGCM_SVC_PARM_32BIT) 3738 return setError (E_FAIL, tr ("Internal application error")); 3739 cchBuf = parm[2].u.uint32; 3740 } 3741 if (VERR_BUFFER_OVERFLOW == vrc) 3742 return setError (E_UNEXPECTED, tr ("Temporary failure due to guest activity, please retry")); 3743 3744 /* 3745 * Finally we have to unpack the data returned by the service into the safe 3746 * arrays supplied by the caller. We start by counting the number of entries. 3747 */ 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 } 3760 3761 /* 3762 * And now we create the COM safe arrays and fill them in. 3763 */ 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 { 3772 size_t cchName = strlen(pszBuf + iBuf); 3773 Bstr(pszBuf + iBuf).detachTo(&names[i]); 3774 iBuf += cchName + 1; 3775 size_t cchValue = strlen(pszBuf + iBuf); 3776 Bstr(pszBuf + iBuf).detachTo(&values[i]); 3777 iBuf += cchValue + 1; 3778 size_t cchTimestamp = strlen(pszBuf + iBuf); 3779 timestamps[i] = RTStrToUInt64(pszBuf + iBuf); 3780 iBuf += cchTimestamp + 1; 3781 size_t cchFlags = strlen(pszBuf + iBuf); 3782 Bstr(pszBuf + iBuf).detachTo(&flags[i]); 3783 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; 3647 3790 #endif /* else !defined (VBOX_WITH_GUEST_PROPS) */ 3648 3791 } -
trunk/src/VBox/Main/MachineImpl.cpp
r10868 r11041 2856 2856 } 2857 2857 2858 STDMETHODIMP Machine::EnumerateGuestProperties (INPTR BSTR aPattern, ComSafeArrayOut(BSTR, aKeys), ComSafeArrayOut(BSTR, aValues), ComSafeArrayOut(ULONG64, aTimestamps), ComSafeArrayOut(BSTR, aFlags)) 2859 { 2858 STDMETHODIMP Machine::EnumerateGuestProperties (INPTR BSTR aPatterns, ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut(BSTR, aValues), ComSafeArrayOut(ULONG64, aTimestamps), ComSafeArrayOut(BSTR, aFlags)) 2859 { 2860 #if !defined (VBOX_WITH_GUEST_PROPS) 2860 2861 return E_NOTIMPL; 2862 #else 2863 if (!VALID_PTR (aPatterns) && (aPatterns != NULL)) 2864 return E_POINTER; 2865 if (ComSafeArrayOutIsNull (aNames)) 2866 return E_POINTER; 2867 if (ComSafeArrayOutIsNull (aValues)) 2868 return E_POINTER; 2869 if (ComSafeArrayOutIsNull (aTimestamps)) 2870 return E_POINTER; 2871 if (ComSafeArrayOutIsNull (aFlags)) 2872 return E_POINTER; 2873 AutoCaller autoCaller (this); 2874 CheckComRCReturnRC (autoCaller.rc()); 2875 2876 AutoReadLock alock (this); 2877 2878 using namespace guestProp; 2879 HRESULT rc = E_FAIL; 2880 2881 switch (mData->mSession.mState) 2882 { 2883 case SessionState_Closed: 2884 { 2885 rc = setError (E_NOTIMPL, 2886 tr ("Not yet implemented for a non-running VM")); 2887 break; 2888 } 2889 case SessionState_Open: 2890 { 2891 if (mData->mSession.mState != SessionState_Open) 2892 { 2893 rc = setError (E_FAIL, 2894 tr ("Session is not open (session state: %d)"), 2895 mData->mSession.mState); 2896 break; 2897 } 2898 2899 ComPtr <IInternalSessionControl> directControl = 2900 mData->mSession.mDirectControl; 2901 2902 /* just be on the safe side when calling another process */ 2903 alock.unlock(); 2904 2905 rc = directControl->EnumerateGuestProperties(aPatterns, 2906 ComSafeArrayOutArg(aNames), 2907 ComSafeArrayOutArg(aValues), 2908 ComSafeArrayOutArg(aTimestamps), 2909 ComSafeArrayOutArg(aFlags)); 2910 break; 2911 } 2912 default: 2913 rc = setError (E_FAIL, 2914 tr ("Session is currently transitioning (session state: %d)"), 2915 mData->mSession.mState); 2916 } 2917 return rc; 2918 #endif /* else !defined (VBOX_WITH_GUEST_PROPS) */ 2861 2919 } 2862 2920 -
trunk/src/VBox/Main/SessionImpl.cpp
r10797 r11041 677 677 else 678 678 return mConsole->setGuestProperty (aKey, aValue); 679 #else /* VBOX_WITH_GUEST_PROPS not defined */ 680 return E_NOTIMPL; 681 #endif /* VBOX_WITH_GUEST_PROPS not defined */ 682 } 683 684 STDMETHODIMP Session::EnumerateGuestProperties (INPTR BSTR aPatterns, 685 ComSafeArrayOut(BSTR, aNames), 686 ComSafeArrayOut(BSTR, aValues), 687 ComSafeArrayOut(ULONG64, aTimestamps), 688 ComSafeArrayOut(BSTR, aFlags)) 689 { 690 #ifdef VBOX_WITH_GUEST_PROPS 691 AutoCaller autoCaller (this); 692 AssertComRCReturn (autoCaller.rc(), autoCaller.rc()); 693 694 if (mState != SessionState_Open) 695 return setError (E_FAIL, 696 tr ("Machine session is not open (session state: %d)."), 697 mState); 698 AssertReturn (mType == SessionType_Direct, E_UNEXPECTED); 699 if (!VALID_PTR (aPatterns) && (aPatterns != NULL)) 700 return E_POINTER; 701 if (ComSafeArrayOutIsNull (aNames)) 702 return E_POINTER; 703 if (ComSafeArrayOutIsNull (aValues)) 704 return E_POINTER; 705 if (ComSafeArrayOutIsNull (aTimestamps)) 706 return E_POINTER; 707 if (ComSafeArrayOutIsNull (aFlags)) 708 return E_POINTER; 709 return mConsole->enumerateGuestProperties(aPatterns, 710 ComSafeArrayOutArg(aNames), 711 ComSafeArrayOutArg(aValues), 712 ComSafeArrayOutArg(aTimestamps), 713 ComSafeArrayOutArg(aFlags)); 679 714 #else /* VBOX_WITH_GUEST_PROPS not defined */ 680 715 return E_NOTIMPL; -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r10896 r11041 3522 3522 Reads an entry from the machine's guest property store. 3523 3523 </desc> 3524 <param name=" key" type="wstring" dir="in">3525 <desc> 3526 The name of the key to read.3524 <param name="name" type="wstring" dir="in"> 3525 <desc> 3526 The name of the property to read. 3527 3527 </desc> 3528 3528 </param> 3529 3529 <param name="value" type="wstring" dir="out"> 3530 3530 <desc> 3531 The value of the key. If the key does not exist then this will be 3531 The value of the property. If the property does not exist then this 3532 will be empty. 3533 </desc> 3534 </param> 3535 <param name="timestamp" type="unsigned long long" dir="out"> 3536 <desc> 3537 The time at which the property was last modified, as seen by the 3538 server process. 3539 </desc> 3540 </param> 3541 <param name="flags" type="wstring" dir="out"> 3542 <desc> 3543 Additional property parameters, passed as a comma-separated list of 3544 "name=value" type entries. 3545 </desc> 3546 </param> 3547 </method> 3548 3549 <method name="getGuestPropertyValue"> 3550 <desc> 3551 Reads a value from the machine's guest property store. 3552 </desc> 3553 <param name="property" type="wstring" dir="in"> 3554 <desc> 3555 The name of the property to read. 3556 </desc> 3557 </param> 3558 <param name="value" type="wstring" dir="return"> 3559 <desc> 3560 The value of the property. If the property does not exist then this 3561 will be empty. 3562 </desc> 3563 </param> 3564 </method> 3565 3566 <method name="getGuestPropertyTimestamp"> 3567 <desc> 3568 Reads a property timestamp from the machine's guest property store. 3569 </desc> 3570 <param name="property" type="wstring" dir="in"> 3571 <desc> 3572 The name of the property to read. 3573 </desc> 3574 </param> 3575 <param name="value" type="unsigned long long" dir="return"> 3576 <desc> 3577 The timestamp. If the property does not exist then this will be 3532 3578 empty. 3533 </desc>3534 </param>3535 <param name="timestamp" type="unsigned long long" dir="out">3536 <desc>3537 The time at which the key was last modified, as seen by the server3538 process.3539 </desc>3540 </param>3541 <param name="flags" type="wstring" dir="out">3542 <desc>3543 Additional key parameters, passed as a comma-separated list of3544 "name=value" type entries.3545 </desc>3546 </param>3547 </method>3548 3549 <method name="getGuestPropertyValue">3550 <desc>3551 Reads a value from the machine's guest property store.3552 </desc>3553 <param name="key" type="wstring" dir="in">3554 <desc>3555 The name of the key to read.3556 </desc>3557 </param>3558 <param name="value" type="wstring" dir="return">3559 <desc>3560 The value of the key. If the key does not exist then this will be3561 empty.3562 </desc>3563 </param>3564 </method>3565 3566 <method name="getGuestPropertyTimestamp">3567 <desc>3568 Reads a key timestamp from the machine's guest property store.3569 </desc>3570 <param name="key" type="wstring" dir="in">3571 <desc>3572 The name of the key to read.3573 </desc>3574 </param>3575 <param name="value" type="unsigned long long" dir="return">3576 <desc>3577 The timestamp. If the key does not exist then this will be empty.3578 3579 </desc> 3579 3580 </param> … … 3585 3586 store. 3586 3587 </desc> 3587 <param name=" key" type="wstring" dir="in">3588 <desc> 3589 The name of the key to set, change or delete.3588 <param name="property" type="wstring" dir="in"> 3589 <desc> 3590 The name of the property to set, change or delete. 3590 3591 </desc> 3591 3592 </param> 3592 3593 <param name="value" type="wstring" dir="in"> 3593 3594 <desc> 3594 The new value of the key to set, change or delete. If the key does 3595 not yet exist and value is non-empty, it will be created. If value 3596 is empty, the key will be deleted if it exists. 3595 The new value of the property to set, change or delete. If the 3596 property does not yet exist and value is non-empty, it will be 3597 created. If the value is empty, the key will be deleted if it 3598 exists. 3597 3599 </desc> 3598 3600 </param> 3599 3601 <param name="flags" type="wstring" dir="in"> 3600 3602 <desc> 3601 Additional key parameters, passed as a comma-separated list of3603 Additional property parameters, passed as a comma-separated list of 3602 3604 "name=value" type entries. 3603 3605 </desc> … … 3611 3613 new property. 3612 3614 </desc> 3613 <param name=" key" type="wstring" dir="in">3614 <desc> 3615 The name of the key to set, change or delete.3615 <param name="property" type="wstring" dir="in"> 3616 <desc> 3617 The name of the property to set, change or delete. 3616 3618 </desc> 3617 3619 </param> 3618 3620 <param name="value" type="wstring" dir="in"> 3619 3621 <desc> 3620 The new value of the key to set, change or delete. If the key does 3621 not yet exist and value is non-empty, it will be created. If value 3622 is empty, the key will be deleted if it exists. 3622 The new value of the property to set, change or delete. If the 3623 property does not yet exist and value is non-empty, it will be 3624 created. If value is empty, the property will be deleted if it 3625 exists. 3623 3626 </desc> 3624 3627 </param> … … 3633 3636 <desc> 3634 3637 The patterns to match the properties against as a comma-separated 3635 string . If this is empty, all properties currently set will be3636 returned.3637 </desc> 3638 </param> 3639 <param name=" key" type="wstring" dir="out" safearray="yes">3640 <desc> 3641 The keynames of the properties returned.3638 string with no spaces. If this is empty, all properties currently 3639 set will be returned. 3640 </desc> 3641 </param> 3642 <param name="name" type="wstring" dir="out" safearray="yes"> 3643 <desc> 3644 The names of the properties returned. 3642 3645 </desc> 3643 3646 </param> … … 3645 3648 <desc> 3646 3649 The values of the properties returned. The array entries match the 3647 corresponding entries in the @a keyarray.3650 corresponding entries in the @a name array. 3648 3651 </desc> 3649 3652 </param> … … 3651 3654 <desc> 3652 3655 The timestamps of the properties returned. The array entries match 3653 the corresponding entries in the @a keyarray.3656 the corresponding entries in the @a name array. 3654 3657 </desc> 3655 3658 </param> … … 3657 3660 <desc> 3658 3661 The flags of the properties returned. The array entries match the 3659 corresponding entries in the @a keyarray.3662 corresponding entries in the @a name array. 3660 3663 </desc> 3661 3664 </param> … … 9777 9780 <interface 9778 9781 name="IInternalSessionControl" extends="$unknown" 9779 uuid=" ee0bec44-ffec-4994-8f15-c3dea54bbbb6"9782 uuid="0dc8dc04-2d4c-45e7-885c-a0afe7e4dfa7" 9780 9783 internal="yes" 9781 9784 wsmap="suppress" … … 9940 9943 <param name="isSetter" type="boolean" dir="in"/> 9941 9944 <param name="retValue" type="wstring" dir="return"/> 9945 </method> 9946 9947 <method name="enumerateGuestProperties"> 9948 <desc> 9949 Return a list of the guest properties matching a set of patterns along 9950 with their values, timestamps and flags. 9951 </desc> 9952 <param name="patterns" type="wstring" dir="in"> 9953 <desc> 9954 The patterns to match the properties against as a comma-separated 9955 string. If this is empty, all properties currently set will be 9956 returned. 9957 </desc> 9958 </param> 9959 <param name="key" type="wstring" dir="out" safearray="yes"> 9960 <desc> 9961 The key names of the properties returned. 9962 </desc> 9963 </param> 9964 <param name="value" type="wstring" dir="out" safearray="yes"> 9965 <desc> 9966 The values of the properties returned. The array entries match the 9967 corresponding entries in the @a key array. 9968 </desc> 9969 </param> 9970 <param name="timestamp" type="unsigned long long" dir="out" safearray="yes"> 9971 <desc> 9972 The timestamps of the properties returned. The array entries match 9973 the corresponding entries in the @a key array. 9974 </desc> 9975 </param> 9976 <param name="flags" type="wstring" dir="out" safearray="yes"> 9977 <desc> 9978 The flags of the properties returned. The array entries match the 9979 corresponding entries in the @a key array. 9980 </desc> 9981 </param> 9942 9982 </method> 9943 9983 -
trunk/src/VBox/Main/include/ConsoleImpl.h
r10304 r11041 184 184 HRESULT getGuestProperty (INPTR BSTR aKey, BSTR *aValue); 185 185 HRESULT setGuestProperty (INPTR BSTR aKey, INPTR BSTR aValue); 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; } 188 188 AudioSniffer *getAudioSniffer () { return mAudioSniffer; } -
trunk/src/VBox/Main/include/SessionImpl.h
r10305 r11041 108 108 STDMETHOD(AccessGuestProperty) (INPTR BSTR aKey, INPTR BSTR aValue, 109 109 BOOL aIsSetter, BSTR *aRetValue); 110 STDMETHOD(EnumerateGuestProperties) (INPTR BSTR aPatterns, 111 ComSafeArrayOut(BSTR, aNames), 112 ComSafeArrayOut(BSTR, aValues), 113 ComSafeArrayOut(ULONG64, aTimestamps), 114 ComSafeArrayOut(BSTR, aFlags)); 110 115 111 116 // for VirtualBoxSupportErrorInfoImpl
Note:
See TracChangeset
for help on using the changeset viewer.