VirtualBox

Changeset 11090 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Aug 4, 2008 8:38:05 AM (16 years ago)
Author:
vboxsync
Message:

Main: enumerate guest properties when the machine is not running

File:
1 edited

Legend:

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

    r11084 r11090  
    27042704        return E_POINTER;
    27052705
    2706     AutoCaller autoCaller (this);
     2706    AutoLimitedCaller autoCaller (this);
    27072707    CheckComRCReturnRC (autoCaller.rc());
    27082708
    27092709    AutoReadLock alock (this);
    2710 
    2711     HRESULT rc = checkStateDependency (MutableStateDep);
    2712     CheckComRCReturnRC (rc);
    27132710
    27142711    using namespace guestProp;
     
    28472844{
    28482845    return SetGuestProperty(aName, aValue, NULL);
     2846}
     2847
     2848/**
     2849 * Matches a sample name against a pattern.
     2850 *
     2851 * @returns True if matches, false if not.
     2852 * @param   pszPat      Pattern.
     2853 * @param   pszName     Name to match against the pattern.
     2854 * @todo move this into IPRT
     2855 */
     2856static bool matchesSinglePattern(const char *pszPat, const char *pszName)
     2857{
     2858    /* ASSUMES ASCII */
     2859    for (;;)
     2860    {
     2861        char chPat = *pszPat;
     2862        switch (chPat)
     2863        {
     2864            default:
     2865                if (*pszName != chPat)
     2866                    return false;
     2867                break;
     2868
     2869            case '*':
     2870            {
     2871                while ((chPat = *++pszPat) == '*' || chPat == '?')
     2872                    /* nothing */;
     2873
     2874                for (;;)
     2875                {
     2876                    char ch = *pszName++;
     2877                    if (    ch == chPat
     2878                        &&  (   !chPat
     2879                             || matchesSinglePattern(pszPat + 1, pszName)))
     2880                        return true;
     2881                    if (!ch)
     2882                        return false;
     2883                }
     2884                /* won't ever get here */
     2885                break;
     2886            }
     2887
     2888            case '?':
     2889                if (!*pszName)
     2890                    return false;
     2891                break;
     2892
     2893            case '\0':
     2894                return !*pszName;
     2895        }
     2896        pszName++;
     2897        pszPat++;
     2898    }
     2899    return true;
     2900}
     2901
     2902/* Checks to see if the given string matches against one of the patterns in
     2903 * the list. */
     2904static bool matchesPattern(const char *paszPatterns, size_t cchPatterns,
     2905                           const char *pszString)
     2906{
     2907    size_t iOffs = 0;
     2908    /* If the first pattern in the list is empty, treat it as "match all". */
     2909    bool matched = (cchPatterns > 0) && (0 == *paszPatterns) ? true : false;
     2910    while ((iOffs < cchPatterns) && !matched)
     2911    {
     2912        size_t cchCurrent;
     2913        if (   RT_SUCCESS(RTStrNLenEx(paszPatterns + iOffs,
     2914                                      cchPatterns - iOffs, &cchCurrent))
     2915            && (cchCurrent > 0)
     2916           )
     2917        {
     2918            matched = matchesSinglePattern(paszPatterns + iOffs, pszString);
     2919            iOffs += cchCurrent + 1;
     2920        }
     2921        else
     2922            iOffs = cchPatterns;
     2923    }
     2924    return matched;
    28492925}
    28502926
     
    28642940    if (ComSafeArrayOutIsNull (aFlags))
    28652941        return E_POINTER;
    2866     AutoCaller autoCaller (this);
     2942
     2943    AutoLimitedCaller autoCaller (this);
    28672944    CheckComRCReturnRC (autoCaller.rc());
    28682945
     
    28702947
    28712948    using namespace guestProp;
    2872     HRESULT rc = E_FAIL;
    2873 
    2874     switch (mData->mSession.mState)
    2875     {
    2876         case SessionState_Closed:
    2877         {
    2878             rc = setError (E_NOTIMPL,
    2879                      tr ("Not yet implemented for a non-running VM"));
    2880             break;
    2881         }
    2882         case SessionState_Open:
    2883         {
    2884             if (mData->mSession.mState != SessionState_Open)
    2885             {
    2886                 rc = setError (E_FAIL,
    2887                     tr ("Session is not open (session state: %d)"),
    2888                     mData->mSession.mState);
    2889                 break;
    2890             }
    2891 
    2892             ComPtr <IInternalSessionControl> directControl =
    2893                 mData->mSession.mDirectControl;
    2894 
    2895             /* just be on the safe side when calling another process */
    2896             alock.unlock();
    2897 
    2898             rc = directControl->EnumerateGuestProperties(aPatterns,
    2899                                                          ComSafeArrayOutArg(aNames),
    2900                                                          ComSafeArrayOutArg(aValues),
    2901                                                          ComSafeArrayOutArg(aTimestamps),
    2902                                                          ComSafeArrayOutArg(aFlags));
    2903             break;
    2904         }
    2905         default:
    2906             rc = setError (E_FAIL,
    2907                 tr ("Session is currently transitioning (session state: %d)"),
    2908                 mData->mSession.mState);
     2949    rc = E_FAIL;
     2950
     2951    if (!mHWData->mPropertyServiceActive)
     2952    {
     2953
     2954/*
     2955 * Set up the pattern parameter, translating the comma-separated list to a
     2956 * double-terminated zero-separated one.
     2957 */
     2958/** @todo skip this conversion. */
     2959        Utf8Str Utf8PatternsIn = aPatterns;
     2960        if ((aPatterns != NULL) && Utf8PatternsIn.isNull())
     2961            return E_OUTOFMEMORY;
     2962        size_t cchPatterns = Utf8PatternsIn.length();
     2963        Utf8Str Utf8Patterns(cchPatterns + 2);  /* Double terminator */
     2964        if (Utf8Patterns.isNull())
     2965            return E_OUTOFMEMORY;
     2966        char *pszPatterns = Utf8Patterns.mutableRaw();
     2967        unsigned iPatterns = 0;
     2968        for (unsigned i = 0; i < cchPatterns; ++i)
     2969        {
     2970            char cIn = Utf8PatternsIn.raw()[i];
     2971            if ((cIn != ',') && (cIn != ' '))
     2972                pszPatterns[iPatterns] = cIn;
     2973            else if (cIn != ' ')
     2974                pszPatterns[iPatterns] = '\0';
     2975            if (cIn != ' ')
     2976                ++iPatterns;
     2977        }
     2978        pszPatterns[iPatterns] = '\0';
     2979        ++iPatterns;
     2980
     2981/*
     2982 * Look for matching patterns and build up a list.
     2983 */
     2984        HWData::GuestPropertyList propList;
     2985        for (HWData::GuestPropertyList::iterator it = mHWData->mGuestProperties.begin();
     2986             it != mHWData->mGuestProperties.end(); ++it)
     2987            if (matchesPattern(pszPatterns, iPatterns, Utf8Str(it->mName).raw()))
     2988                propList.push_back(*it);
     2989
     2990/*
     2991 * And build up the arrays for returning the property information.
     2992 */
     2993        size_t cEntries = propList.size();
     2994        SafeArray <BSTR> names(cEntries);
     2995        SafeArray <BSTR> values(cEntries);
     2996        SafeArray <ULONG64> timestamps(cEntries);
     2997        SafeArray <BSTR> flags(cEntries);
     2998        size_t iProp = 0;
     2999        for (HWData::GuestPropertyList::iterator it = propList.begin();
     3000             it != propList.end(); ++it)
     3001        {
     3002             it->mName.cloneTo(&names[iProp]);
     3003             it->mValue.cloneTo(&values[iProp]);
     3004             timestamps[iProp] = it->mTimestamp;
     3005             it->mFlags.cloneTo(&flags[iProp]);
     3006             ++iProp;
     3007        }
     3008        names.detachTo(ComSafeArrayOutArg (aNames));
     3009        values.detachTo(ComSafeArrayOutArg (aValues));
     3010        timestamps.detachTo(ComSafeArrayOutArg (aTimestamps));
     3011        flags.detachTo(ComSafeArrayOutArg (aFlags));
     3012        rc = S_OK;
     3013    }
     3014    else
     3015    {
     3016        ComPtr <IInternalSessionControl> directControl =
     3017            mData->mSession.mDirectControl;
     3018
     3019        /* just be on the safe side when calling another process */
     3020        alock.unlock();
     3021
     3022        rc = directControl->EnumerateGuestProperties(aPatterns,
     3023                                                     ComSafeArrayOutArg(aNames),
     3024                                                     ComSafeArrayOutArg(aValues),
     3025                                                     ComSafeArrayOutArg(aTimestamps),
     3026                                                     ComSafeArrayOutArg(aFlags));
    29093027    }
    29103028    return rc;
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