VirtualBox

Changeset 11041 in vbox


Ignore:
Timestamp:
Jul 31, 2008 6:00:42 PM (17 years ago)
Author:
vboxsync
Message:

Main: added guest property enumeration (currently only works when the machine is running)

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

Legend:

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

    r10901 r11041  
    8484#ifdef VBOX_WITH_GUEST_PROPS
    8585# include <VBox/HostServices/GuestPropertySvc.h>
     86# include <VBox/com/array.h>
    8687#endif
    8788
     
    36453646            tr ("Failed to call the VBoxGuestPropSvc service (%Rrc)"), vrc);
    36463647    return rc;
     3648#endif /* else !defined (VBOX_WITH_GUEST_PROPS) */
     3649}
     3650
     3651
     3652/**
     3653 * @note Temporarily locks this object for writing.
     3654 */
     3655HRESULT 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;
    36473790#endif /* else !defined (VBOX_WITH_GUEST_PROPS) */
    36483791}
  • trunk/src/VBox/Main/MachineImpl.cpp

    r10868 r11041  
    28562856}
    28572857
    2858 STDMETHODIMP Machine::EnumerateGuestProperties (INPTR BSTR aPattern, ComSafeArrayOut(BSTR, aKeys), ComSafeArrayOut(BSTR, aValues), ComSafeArrayOut(ULONG64, aTimestamps), ComSafeArrayOut(BSTR, aFlags))
    2859 {
     2858STDMETHODIMP 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)
    28602861    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) */
    28612919}
    28622920
  • trunk/src/VBox/Main/SessionImpl.cpp

    r10797 r11041  
    677677    else
    678678        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
     684STDMETHODIMP 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));
    679714#else /* VBOX_WITH_GUEST_PROPS not defined */
    680715    return E_NOTIMPL;
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r10896 r11041  
    35223522        Reads an entry from the machine's guest property store.
    35233523      </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.
    35273527        </desc>
    35283528      </param>
    35293529      <param name="value" type="wstring" dir="out">
    35303530        <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
    35323578          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 server
    3538           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 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="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 be
    3561           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.
    35783579        </desc>
    35793580      </param>
     
    35853586        store.
    35863587      </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.
    35903591        </desc>
    35913592      </param>
    35923593      <param name="value" type="wstring" dir="in">
    35933594        <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.
    35973599        </desc>
    35983600      </param>
    35993601      <param name="flags" type="wstring" dir="in">
    36003602        <desc>
    3601           Additional key parameters, passed as a comma-separated list of
     3603          Additional property parameters, passed as a comma-separated list of
    36023604          "name=value" type entries.
    36033605        </desc>
     
    36113613        new property.
    36123614      </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.
    36163618        </desc>
    36173619      </param>
    36183620      <param name="value" type="wstring" dir="in">
    36193621        <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.
    36233626        </desc>
    36243627      </param>
     
    36333636        <desc>
    36343637          The patterns to match the properties against as a comma-separated
    3635           string.  If this is empty, all properties currently set will be
    3636           returned.
    3637         </desc>
    3638       </param>
    3639       <param name="key" type="wstring" dir="out" safearray="yes">
    3640         <desc>
    3641           The key names 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.
    36423645        </desc>
    36433646      </param>
     
    36453648        <desc>
    36463649          The values of the properties returned.  The array entries match the
    3647           corresponding entries in the @a key array.
     3650          corresponding entries in the @a name array.
    36483651        </desc>
    36493652      </param>
     
    36513654        <desc>
    36523655          The timestamps of the properties returned.  The array entries match
    3653           the corresponding entries in the @a key array.
     3656          the corresponding entries in the @a name array.
    36543657        </desc>
    36553658      </param>
     
    36573660        <desc>
    36583661          The flags of the properties returned.  The array entries match the
    3659           corresponding entries in the @a key array.
     3662          corresponding entries in the @a name array.
    36603663        </desc>
    36613664      </param>
     
    97779780  <interface
    97789781     name="IInternalSessionControl" extends="$unknown"
    9779      uuid="ee0bec44-ffec-4994-8f15-c3dea54bbbb6"
     9782     uuid="0dc8dc04-2d4c-45e7-885c-a0afe7e4dfa7"
    97809783     internal="yes"
    97819784     wsmap="suppress"
     
    99409943      <param name="isSetter" type="boolean" dir="in"/>
    99419944      <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>
    99429982    </method>
    99439983
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r10304 r11041  
    184184    HRESULT getGuestProperty (INPTR BSTR aKey, BSTR *aValue);
    185185    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));
    187187    VMMDev *getVMMDev() { return mVMMDev; }
    188188    AudioSniffer *getAudioSniffer () { return mAudioSniffer; }
  • trunk/src/VBox/Main/include/SessionImpl.h

    r10305 r11041  
    108108    STDMETHOD(AccessGuestProperty) (INPTR BSTR aKey, INPTR BSTR aValue,
    109109                                    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));
    110115
    111116    // for VirtualBoxSupportErrorInfoImpl
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