VirtualBox

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


Ignore:
Timestamp:
Jul 16, 2012 8:28:47 PM (13 years ago)
Author:
vboxsync
Message:

Guest Control 2.0: Update.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h

    r42160 r42171  
    4848typedef std::vector <LONG> ProcessAffinity;
    4949typedef std::vector <Utf8Str> ProcessArguments;
    50 typedef std::map <Utf8Str, Utf8Str> ProcessEnvironmentMap;
    5150
    5251
     
    108107};
    109108
     109typedef std::vector <Utf8Str> GuestEnvironmentArray;
     110class GuestEnvironment
     111{
     112public:
     113
     114    int BuildEnvironmentBlock(void **ppvEnv, uint32_t *pcbEnv, uint32_t *pcEnvVars);
     115
     116    void Clear(void);
     117
     118    int CopyFrom(const GuestEnvironmentArray &environment);
     119
     120    int CopyTo(GuestEnvironmentArray &environment);
     121
     122    static void FreeEnvironmentBlock(void *pvEnv);
     123
     124    Utf8Str Get(size_t nPos);
     125
     126    bool Has(const Utf8Str &strKey);
     127
     128    int Set(const Utf8Str &strKey, const Utf8Str &strValue);
     129
     130    int Set(const Utf8Str &strPair);
     131
     132    size_t Size(void);
     133
     134    int Unset(const Utf8Str &strKey);
     135
     136public:
     137
     138    GuestEnvironment& operator=(const GuestEnvironmentArray &that);
     139
     140    GuestEnvironment& operator=(const GuestEnvironment &that);
     141
     142protected:
     143
     144    int appendToEnvBlock(const char *pszEnv, void **ppvList, uint32_t *pcbList, uint32_t *pcEnvVars);
     145
     146protected:
     147
     148    std::map <Utf8Str, Utf8Str> mEnvironment;
     149};
     150
     151
    110152/**
    111153 * Structure for keeping all the relevant process
     
    116158    Utf8Str                     mCommand;
    117159    ProcessArguments            mArguments;
    118     ProcessEnvironmentMap       mEnvironment;
     160    GuestEnvironment            mEnvironment;
    119161    uint32_t                    mFlags;
    120162    ULONG                       mTimeoutMS;
  • trunk/src/VBox/Main/include/GuestSessionImpl.h

    r42160 r42171  
    108108    /** @}  */
    109109
     110private:
     111
     112    typedef std::vector <ComObjPtr<GuestDirectory> > SessionDirectories;
     113    typedef std::vector <ComObjPtr<GuestFile> > SessionFiles;
     114    typedef std::map <uint32_t, ComObjPtr<GuestProcess> > SessionProcesses;
     115
    110116public:
    111117    /** @name Public internal methods.
     
    114120    int                     fileClose(ComObjPtr<GuestFile> pFile);
    115121    const GuestCredentials &getCredentials(void);
     122    const GuestEnvironment &getEnvironment(void);
    116123    int                     processClose(ComObjPtr<GuestProcess> pProcess);
    117124    int                     processCreateExInteral(GuestProcessInfo &aProcInfo, IGuestProcess **aProcess);
     
    120127
    121128private:
    122 
    123     typedef std::map <Utf8Str, Utf8Str> SessionEnvironment;
    124 
    125     typedef std::vector <ComObjPtr<GuestDirectory> > SessionDirectories;
    126     typedef std::vector <ComObjPtr<GuestFile> > SessionFiles;
    127     typedef std::map <uint32_t, ComObjPtr<GuestProcess> > SessionProcesses;
    128129
    129130    struct Data
     
    142143        /** The session timeout. Default is 30s. */
    143144        ULONG                mTimeout;
    144         SessionEnvironment   mEnvironment;
     145        GuestEnvironment     mEnvironment;
    145146        SessionDirectories   mDirectories;
    146147        SessionFiles         mFiles;
  • trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp

    r42160 r42171  
    27602760    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    27612761
    2762 
     2762    int rc = sessionCreate(aUser, aPassword, aDomain, aSessionName, aGuestSession);
     2763    return RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR;
    27632764#endif /* VBOX_WITH_GUEST_CONTROL */
    27642765}
  • trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp

    r42160 r42171  
    125125    Assert(mEventSem != NIL_RTSEMEVENT);
    126126    return RTSemEventWait(mEventSem, timeoutMS);
     127}
     128
     129///////////////////////////////////////////////////////////////////////////////
     130
     131int GuestEnvironment::BuildEnvironmentBlock(void **ppvEnv, uint32_t *pcbEnv, uint32_t *pcEnvVars)
     132{
     133    AssertPtrReturn(ppvEnv, VERR_INVALID_POINTER);
     134    /* Rest is optional. */
     135
     136    uint32_t cbEnv = 0;
     137    uint32_t cEnvVars = 0;
     138
     139    int rc = VINF_SUCCESS;
     140
     141    size_t cEnv = mEnvironment.size();
     142    if (cEnv)
     143    {
     144        std::map<Utf8Str, Utf8Str>::const_iterator itEnv = mEnvironment.begin();
     145        for (; itEnv != mEnvironment.end() && RT_SUCCESS(rc); itEnv++)
     146        {
     147            char *pszEnv;
     148            if (!RTStrAPrintf(&pszEnv, "%s=%s", itEnv->first.c_str(), itEnv->second.c_str()))
     149            {
     150                rc = VERR_NO_MEMORY;
     151                break;
     152            }
     153            AssertPtr(pszEnv);
     154            rc = appendToEnvBlock(pszEnv, ppvEnv, &cbEnv, &cEnvVars);
     155            RTStrFree(pszEnv);
     156        }
     157        Assert(cEnv == cEnvVars);
     158    }
     159
     160    if (pcbEnv)
     161        *pcbEnv = cbEnv;
     162    if (pcEnvVars)
     163        *pcEnvVars = cEnvVars;
     164
     165    return rc;
     166}
     167
     168void GuestEnvironment::Clear(void)
     169{
     170    mEnvironment.clear();
     171}
     172
     173int GuestEnvironment::CopyFrom(const GuestEnvironmentArray &environment)
     174{
     175    int rc = VINF_SUCCESS;
     176
     177    for (GuestEnvironmentArray::const_iterator it = environment.begin();
     178         it != environment.end() && RT_SUCCESS(rc);
     179         ++it)
     180    {
     181        rc = Set((*it));
     182    }
     183
     184    return rc;
     185}
     186
     187int GuestEnvironment::CopyTo(GuestEnvironmentArray &environment)
     188{
     189    size_t s = 0;
     190    for (std::map<Utf8Str, Utf8Str>::const_iterator it = mEnvironment.begin();
     191         it != mEnvironment.end();
     192         ++it, ++s)
     193    {
     194        environment[s] = Bstr(it->first + "=" + it->second).raw();
     195    }
     196
     197    return VINF_SUCCESS;
     198}
     199
     200/* static */
     201void GuestEnvironment::FreeEnvironmentBlock(void *pvEnv)
     202{
     203    if (pvEnv)
     204        RTMemFree(pvEnv);
     205}
     206
     207Utf8Str GuestEnvironment::Get(size_t nPos)
     208{
     209    size_t curPos = 0;
     210    std::map<Utf8Str, Utf8Str>::const_iterator it = mEnvironment.begin();
     211    for (; it != mEnvironment.end() && curPos < nPos;
     212         ++it) { }
     213
     214    if (it != mEnvironment.end())
     215        return Utf8Str(it->first + "=" + it->second);
     216
     217    return Utf8Str("");
     218}
     219
     220bool GuestEnvironment::Has(const Utf8Str &strKey)
     221{
     222    std::map <Utf8Str, Utf8Str>::const_iterator itEnv = mEnvironment.find(strKey);
     223    return (itEnv != mEnvironment.end());
     224}
     225
     226int GuestEnvironment::Set(const Utf8Str &strKey, const Utf8Str &strValue)
     227{
     228    mEnvironment[strValue] = strValue;
     229    return VINF_SUCCESS;
     230}
     231
     232int GuestEnvironment::Set(const Utf8Str &strPair)
     233{
     234    RTCList<RTCString> listPair = strPair.split("=", RTCString::KeepEmptyParts);
     235    size_t p = 0;
     236    while(p < listPair.size())
     237    {
     238        Utf8Str strKey = listPair.at(p++);
     239        if (strKey.isEmpty()) /* Skip pairs with empty keys (e.g. "=FOO"). */
     240        {
     241            p++;
     242            continue;
     243        }
     244        Utf8Str strValue;
     245        if (p < listPair.size())
     246            strValue = listPair.at(p++);
     247       mEnvironment[strKey] = strValue;
     248    }
     249
     250    return VINF_SUCCESS;
     251}
     252
     253size_t GuestEnvironment::Size(void)
     254{
     255    return mEnvironment.size();
     256}
     257
     258int GuestEnvironment::Unset(const Utf8Str &strKey)
     259{
     260    std::map <Utf8Str, Utf8Str>::iterator itEnv = mEnvironment.find(strKey);
     261    if (itEnv != mEnvironment.end())
     262    {
     263        mEnvironment.erase(itEnv);
     264        return VINF_SUCCESS;
     265    }
     266
     267    return VERR_NOT_FOUND;
     268}
     269
     270GuestEnvironment& GuestEnvironment::operator=(const GuestEnvironmentArray &that)
     271{
     272    CopyFrom(that);
     273    return *this;
     274}
     275
     276GuestEnvironment& GuestEnvironment::operator=(const GuestEnvironment &that)
     277{
     278    for (std::map<Utf8Str, Utf8Str>::const_iterator it = that.mEnvironment.begin();
     279         it != that.mEnvironment.end();
     280         ++it)
     281    {
     282        mEnvironment[it->first] = it->second;
     283    }
     284
     285    return *this;
     286}
     287
     288/**
     289 * Appends environment variables to the environment block.
     290 *
     291 * Each var=value pair is separated by the null character ('\\0').  The whole
     292 * block will be stored in one blob and disassembled on the guest side later to
     293 * fit into the HGCM param structure.
     294 *
     295 * @returns VBox status code.
     296 *
     297 * @param   pszEnvVar       The environment variable=value to append to the
     298 *                          environment block.
     299 * @param   ppvList         This is actually a pointer to a char pointer
     300 *                          variable which keeps track of the environment block
     301 *                          that we're constructing.
     302 * @param   pcbList         Pointer to the variable holding the current size of
     303 *                          the environment block.  (List is a misnomer, go
     304 *                          ahead a be confused.)
     305 * @param   pcEnvVars       Pointer to the variable holding count of variables
     306 *                          stored in the environment block.
     307 */
     308int GuestEnvironment::appendToEnvBlock(const char *pszEnv, void **ppvList, uint32_t *pcbList, uint32_t *pcEnvVars)
     309{
     310    int rc = VINF_SUCCESS;
     311    uint32_t cchEnv = strlen(pszEnv); Assert(cchEnv >= 2);
     312    if (*ppvList)
     313    {
     314        uint32_t cbNewLen = *pcbList + cchEnv + 1; /* Include zero termination. */
     315        char *pvTmp = (char *)RTMemRealloc(*ppvList, cbNewLen);
     316        if (pvTmp == NULL)
     317            rc = VERR_NO_MEMORY;
     318        else
     319        {
     320            memcpy(pvTmp + *pcbList, pszEnv, cchEnv);
     321            pvTmp[cbNewLen - 1] = '\0'; /* Add zero termination. */
     322            *ppvList = (void **)pvTmp;
     323        }
     324    }
     325    else
     326    {
     327        char *pszTmp;
     328        if (RTStrAPrintf(&pszTmp, "%s", pszEnv) >= 0)
     329        {
     330            *ppvList = (void **)pszTmp;
     331            /* Reset counters. */
     332            *pcEnvVars = 0;
     333            *pcbList = 0;
     334        }
     335    }
     336    if (RT_SUCCESS(rc))
     337    {
     338        *pcbList += cchEnv + 1; /* Include zero termination. */
     339        *pcEnvVars += 1;        /* Increase env variable count. */
     340    }
     341    return rc;
    127342}
    128343
  • trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp

    r42162 r42171  
    184184    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    185185
    186     com::SafeArray<BSTR> collection(mData.mProcess.mEnvironment.size());
    187     size_t s = 0;
    188     for (ProcessEnvironmentMap::const_iterator it = mData.mProcess.mEnvironment.begin();
    189          it != mData.mProcess.mEnvironment.end();
    190          it++, s++)
    191     {
    192         Bstr strEnv = it->first + Utf8Str("=") + it->second;
    193         collection[s] = strEnv.raw();
    194     }
    195 
    196     collection.detachTo(ComSafeArrayOutArg(aEnvironment));
     186    com::SafeArray<BSTR> arguments(mData.mProcess.mEnvironment.Size());
     187    for (size_t i = 0; i < arguments.size(); i++)
     188        arguments[i] = Bstr(mData.mProcess.mEnvironment.Get(i)).raw();
     189    arguments.detachTo(ComSafeArrayOutArg(aEnvironment));
    197190
    198191    return S_OK;
     
    347340}
    348341
    349 /**
    350  * Appends environment variables to the environment block.
    351  *
    352  * Each var=value pair is separated by the null character ('\\0').  The whole
    353  * block will be stored in one blob and disassembled on the guest side later to
    354  * fit into the HGCM param structure.
    355  *
    356  * @returns VBox status code.
    357  *
    358  * @param   pszEnvVar       The environment variable=value to append to the
    359  *                          environment block.
    360  * @param   ppvList         This is actually a pointer to a char pointer
    361  *                          variable which keeps track of the environment block
    362  *                          that we're constructing.
    363  * @param   pcbList         Pointer to the variable holding the current size of
    364  *                          the environment block.  (List is a misnomer, go
    365  *                          ahead a be confused.)
    366  * @param   pcEnvVars       Pointer to the variable holding count of variables
    367  *                          stored in the environment block.
    368  */
    369 int GuestProcess::prepareExecuteEnv(const char *pszEnv, void **ppvList, uint32_t *pcbList, uint32_t *pcEnvVars)
    370 {
    371     int rc = VINF_SUCCESS;
    372     uint32_t cchEnv = strlen(pszEnv); Assert(cchEnv >= 2);
    373     if (*ppvList)
    374     {
    375         uint32_t cbNewLen = *pcbList + cchEnv + 1; /* Include zero termination. */
    376         char *pvTmp = (char *)RTMemRealloc(*ppvList, cbNewLen);
    377         if (pvTmp == NULL)
    378             rc = VERR_NO_MEMORY;
    379         else
    380         {
    381             memcpy(pvTmp + *pcbList, pszEnv, cchEnv);
    382             pvTmp[cbNewLen - 1] = '\0'; /* Add zero termination. */
    383             *ppvList = (void **)pvTmp;
    384         }
    385     }
    386     else
    387     {
    388         char *pszTmp;
    389         if (RTStrAPrintf(&pszTmp, "%s", pszEnv) >= 0)
    390         {
    391             *ppvList = (void **)pszTmp;
    392             /* Reset counters. */
    393             *pcEnvVars = 0;
    394             *pcbList = 0;
    395         }
    396     }
    397     if (RT_SUCCESS(rc))
    398     {
    399         *pcbList += cchEnv + 1; /* Include zero termination. */
    400         *pcEnvVars += 1;        /* Increase env variable count. */
    401     }
    402     return rc;
    403 }
    404 
    405342int GuestProcess::readData(ULONG aHandle, ULONG aSize, ULONG aTimeoutMS, ComSafeArrayOut(BYTE, aData))
    406343{
     
    460397        /* Prepare environment. */
    461398        void *pvEnv = NULL;
    462         size_t cEnv = mData.mProcess.mEnvironment.size();
    463399        uint32_t cbEnv = 0;
    464         if (   RT_SUCCESS(rc)
    465             && cEnv)
    466         {
    467             uint32_t cEnvBuild = 0;
    468             ProcessEnvironmentMap::const_iterator itEnv = mData.mProcess.mEnvironment.begin();
    469             for (; itEnv != mData.mProcess.mEnvironment.end() && RT_SUCCESS(rc); itEnv++)
    470             {
    471                 char *pszEnv;
    472                 if (!RTStrAPrintf(&pszEnv, "%s=%s", itEnv->first.c_str(), itEnv->second.c_str()))
    473                 {
    474                     rc = VERR_NO_MEMORY;
    475                     break;
    476                 }
    477                 AssertPtr(pszEnv);
    478                 rc = prepareExecuteEnv(pszEnv, &pvEnv, &cbEnv, &cEnvBuild);
    479                 RTStrFree(pszEnv);
    480             }
    481             Assert(cEnv == cEnvBuild);
    482         }
     400        rc = mData.mProcess.mEnvironment.BuildEnvironmentBlock(&pvEnv, &cbEnv, NULL /* cEnv */);
    483401
    484402        if (RT_SUCCESS(rc))
     
    493411            paParms[i++].setUInt32(mData.mProcess.mArguments.size());
    494412            paParms[i++].setPointer((void*)pszArgs, cbArgs);
    495             paParms[i++].setUInt32(mData.mProcess.mEnvironment.size());
     413            paParms[i++].setUInt32(mData.mProcess.mEnvironment.Size());
    496414            paParms[i++].setUInt32(cbEnv);
    497415            paParms[i++].setPointer((void*)pvEnv, cbEnv);
     
    529447        }
    530448
    531         if (pvEnv)
    532             RTMemFree(pvEnv);
     449        GuestEnvironment::FreeEnvironmentBlock(pvEnv);
    533450        if (pszArgs)
    534451            RTStrFree(pszArgs);
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r42160 r42171  
    2828#include "Logging.h"
    2929
     30#include <iprt/env.h>
     31
    3032#include <VBox/com/array.h>
    3133
     
    223225    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    224226
    225     com::SafeArray<BSTR> collection(mData.mEnvironment.size());
    226     size_t s = 0;
    227     for (SessionEnvironment::const_iterator it = mData.mEnvironment.begin();
    228          it != mData.mEnvironment.end();
    229          ++it, ++s)
    230     {
    231         collection[s] = Bstr(it->first + "=" + it->second).raw();
    232     }
    233 
    234     collection.detachTo(ComSafeArrayOutArg(aEnvironment));
     227    com::SafeArray<BSTR> arguments(mData.mEnvironment.Size());
     228    for (size_t i = 0; i < arguments.size(); i++)
     229        arguments[i] = Bstr(mData.mEnvironment.Get(i)).raw();
     230    arguments.detachTo(ComSafeArrayOutArg(aEnvironment));
    235231
    236232    return S_OK;
     
    335331{
    336332    return mData.mCredentials;
     333}
     334
     335const GuestEnvironment& GuestSession::getEnvironment(void)
     336{
     337    return mData.mEnvironment;
    337338}
    338339
     
    589590    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    590591
    591     ReturnComNotImplemented();
     592    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     593
     594    mData.mEnvironment.Clear();
     595
     596    return S_OK;
    592597#endif /* VBOX_WITH_GUEST_CONTROL */
    593598}
     
    601606    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    602607
    603     ReturnComNotImplemented();
     608    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     609
     610    mData.mEnvironment.Set(Utf8Str(aName), Utf8Str(aValue));
     611
     612    return S_OK;
    604613#endif /* VBOX_WITH_GUEST_CONTROL */
    605614}
     
    613622    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    614623
    615     ReturnComNotImplemented();
     624    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     625
     626    com::SafeArray<IN_BSTR> environment(ComSafeArrayInArg(aValues));
     627
     628    int rc = VINF_SUCCESS;
     629    for (size_t i = 0; i < environment.size() && RT_SUCCESS(rc); i++)
     630        rc = mData.mEnvironment.Set(Utf8Str(environment[i]));
     631
     632    return RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR;
    616633#endif /* VBOX_WITH_GUEST_CONTROL */
    617634}
     
    625642    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    626643
    627     ReturnComNotImplemented();
     644    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     645
     646    mData.mEnvironment.Unset(Utf8Str(aName));
     647
     648    return S_OK;
    628649#endif /* VBOX_WITH_GUEST_CONTROL */
    629650}
     
    761782        procInfo.mArguments[i] = Utf8Str(Bstr(arguments[i]));
    762783
     784    int rc = VINF_SUCCESS;
     785
     786    /* Create the process environment:
     787     * - Apply the session environment in a first step, and
     788     * - Apply environment variables specified by this call to
     789     *   have the chance of overwriting/deleting session entries.
     790     */
     791    procInfo.mEnvironment = mData.mEnvironment;
    763792    com::SafeArray<IN_BSTR> environment(ComSafeArrayInArg(aEnvironment));
    764     for (size_t i = 0; i < environment.size(); i++)
    765     {
    766         Utf8Str strEnv = Bstr(environment[i]);
    767         RTCList<RTCString> listPair = strEnv.split("=", RTCString::KeepEmptyParts);
    768         size_t p = 0;
    769         while(p < listPair.size())
    770         {
    771             Utf8Str strKey = listPair.at(p++);
    772             if (strKey.isEmpty()) /* Skip pairs with empty keys (e.g. "=FOO"). */
    773             {
    774                 p++;
    775                 continue;
    776             }
    777             Utf8Str strValue;
    778             if (p < listPair.size())
    779                 strValue = listPair.at(p++);
    780             procInfo.mEnvironment[strKey] = strValue;
    781         }
    782     }
    783 
    784     com::SafeArray<ProcessCreateFlag_T> flags(ComSafeArrayInArg(aFlags));
    785     for (size_t i = 0; i < flags.size(); i++)
    786         procInfo.mFlags |= flags[i];
    787 
    788     procInfo.mTimeoutMS = aTimeoutMS;
    789 
    790     com::SafeArray<LONG> affinity(ComSafeArrayInArg(aAffinity));
    791     procInfo.mAffinity.reserve(affinity.size());
    792     for (size_t i = 0; i < affinity.size(); i++)
    793         procInfo.mAffinity[i] = affinity[i]; /** @todo Really necessary? Later. */
    794 
    795     procInfo.mPriority = aPriority;
    796 
    797     int rc = processCreateExInteral(procInfo, aProcess);
     793    for (size_t i = 0; i < environment.size() && RT_SUCCESS(rc); i++)
     794        rc = mData.mEnvironment.Set(Utf8Str(environment[i]));
     795
     796    if (RT_SUCCESS(rc))
     797    {
     798
     799        com::SafeArray<ProcessCreateFlag_T> flags(ComSafeArrayInArg(aFlags));
     800        for (size_t i = 0; i < flags.size(); i++)
     801            procInfo.mFlags |= flags[i];
     802
     803        procInfo.mTimeoutMS = aTimeoutMS;
     804
     805        com::SafeArray<LONG> affinity(ComSafeArrayInArg(aAffinity));
     806        procInfo.mAffinity.reserve(affinity.size());
     807        for (size_t i = 0; i < affinity.size(); i++)
     808            procInfo.mAffinity[i] = affinity[i]; /** @todo Really necessary? Later. */
     809
     810        procInfo.mPriority = aPriority;
     811
     812        rc = processCreateExInteral(procInfo, aProcess);
     813    }
    798814    return RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR;
    799815#endif /* VBOX_WITH_GUEST_CONTROL */
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