VirtualBox

Changeset 27767 in vbox


Ignore:
Timestamp:
Mar 29, 2010 9:12:24 AM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
59413
Message:

Guest Control: Update (Main).

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

Legend:

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

    r27742 r27767  
    3737#endif
    3838#include <iprt/cpp/utils.h>
     39#include <iprt/getopt.h>
    3940
    4041// defines
     
    313314
    314315#ifdef VBOX_WITH_GUEST_CONTROL
    315 HRESULT Guest::prepareExecuteArgs(ComSafeArrayIn(IN_BSTR, aArguments),
    316                                   char **ppszArgv, uint32_t *pcbList, uint32_t *pcArgs)
    317 {
    318     com::SafeArray<IN_BSTR> args(ComSafeArrayInArg(aArguments));
    319     char *pszArgs;
    320     const char *pszCurArg;
    321 
    322     HRESULT rc = S_OK;
    323     int vrc = VINF_SUCCESS;
    324 
    325     for (unsigned i = 0; i < args.size(); ++i)
    326     {
    327         if (i > 0) /* Insert space as delimiter. */
    328             vrc = RTStrAAppendN(&pszArgs, " ", 1);
    329         if (RT_SUCCESS(vrc))
     316/**
     317 * Creates the argument list as an array used for executing a program.
     318 *
     319 * @returns VBox status code.
     320 *
     321 * @todo
     322 *
     323 * @todo Respect spaces when quoting for arguments, e.g. "c:\\program files\\".
     324 * @todo Handle empty ("") argguments.
     325 */
     326int Guest::prepareExecuteArgs(const char *pszArgs, void **ppvList, uint32_t *pcbList, uint32_t *pcArgs)
     327{
     328    char **ppaArg;
     329    int iArgs;
     330    int rc = RTGetOptArgvFromString(&ppaArg, &iArgs, pszArgs, NULL);
     331    if (RT_SUCCESS(rc))
     332    {
     333        char *pszTemp = NULL;
     334        *pcbList = 0;
     335        for (int i=0; i<iArgs; i++)
    330336        {
    331             pszCurArg = Utf8Str(args[i]).raw();
    332             vrc = RTStrAAppendN(&pszArgs, pszCurArg, strlen(pszCurArg));
     337            if (i > 0) /* Insert space as delimiter. */
     338                rc = RTStrAAppendN(&pszTemp, " ", 1);
     339
     340            if (RT_FAILURE(rc))
     341                break;
     342            else
     343            {
     344                rc = RTStrAAppendN(&pszTemp, ppaArg[i], strlen(ppaArg[i]));
     345                if (RT_FAILURE(rc))
     346                    break;
     347            }
    333348        }
    334         if (RT_FAILURE(vrc))
    335             break;
    336     }
    337 
     349        RTGetOptArgvFree(ppaArg);
     350        if (RT_SUCCESS(rc))
     351        {
     352            *ppvList = pszTemp;
     353            *pcArgs = iArgs;
     354            *pcbList = strlen(pszTemp) + 1; /* Include zero termination. */
     355        }
     356        else
     357            RTStrFree(pszTemp);
     358    }
     359    return rc;
     360}
     361
     362/**
     363 * Appends environment variables to the environment block. Each var=value pair is separated
     364 * by NULL (\0) sequence. The whole block will be stored in one blob and disassembled on the
     365 * guest side later to fit into the HGCM param structure.
     366 *
     367 * @returns VBox status code.
     368 *
     369 * @todo
     370 *
     371 */
     372int Guest::prepareExecuteEnv(const char *pszEnv, void **ppvList, uint32_t *pcbList, uint32_t *pcEnv)
     373{
     374    int rc = VINF_SUCCESS;
     375    uint32_t cbLen = strlen(pszEnv);
     376    if (*ppvList)
     377    {
     378        uint32_t cbNewLen = *pcbList + cbLen + 1; /* Include zero termination. */
     379        char *pvTmp = (char*)RTMemRealloc(*ppvList, cbNewLen);       
     380        if (NULL == pvTmp)
     381        {
     382            rc = VERR_NO_MEMORY;
     383        }
     384        else
     385        {
     386            memcpy(pvTmp + *pcbList, pszEnv, cbLen);
     387            pvTmp[cbNewLen - 1] = '\0'; /* Add zero termination. */
     388            *ppvList = (void**)pvTmp;
     389        }
     390    }
     391    else
     392    {
     393        char *pcTmp;
     394        if (RTStrAPrintf(&pcTmp, "%s", pszEnv) > 0)
     395        {
     396            *ppvList = (void**)pcTmp;
     397            /* Reset counters. */
     398            *pcEnv = 0;
     399            *pcbList = 0;
     400        }
     401    }
    338402    if (RT_SUCCESS(rc))
    339403    {
    340         *ppszArgv = pszArgs;
    341         *pcArgs = args.size();
    342         *pcbList = strlen(pszArgs) + 1; /* Include zero termination. */
    343     }
    344     else
    345     {
    346         rc = setError(E_UNEXPECTED,
    347                               tr("The service call failed with the error %Rrc"),
    348                               vrc);
     404        *pcbList += cbLen + 1; /* Include zero termination. */
     405        *pcEnv += 1;           /* Increase env pairs count. */
    349406    }
    350407    return rc;
    351408}
    352 
    353 HRESULT Guest::prepareExecuteEnv(ComSafeArrayIn(IN_BSTR, aEnvironment),
    354                                  void **ppvList, uint32_t *pcbList, uint32_t *pcEnv)
    355 {
    356     com::SafeArray<IN_BSTR> env(ComSafeArrayInArg(aEnvironment));
    357     const char *pszCurEnv;
    358     for (unsigned i = 0; i < env.size(); ++i)
    359     {
    360     }
    361 
    362     return S_OK;
    363 }
    364409#endif /* VBOX_WITH_GUEST_CONTROL */
    365410
    366 STDMETHODIMP Guest::ExecuteProgram(IN_BSTR aExecName, ULONG aFlags,
    367                                    ComSafeArrayIn(IN_BSTR, aArguments), ComSafeArrayIn(IN_BSTR, aEnvironment),
     411STDMETHODIMP Guest::ExecuteProgram(IN_BSTR aCommand, ULONG aFlags,
     412                                   IN_BSTR aArguments, ComSafeArrayIn(IN_BSTR, aEnvironment),
    368413                                   IN_BSTR aStdIn, IN_BSTR aStdOut, IN_BSTR aStdErr,
    369414                                   IN_BSTR aUserName, IN_BSTR aPassword,
     
    375420    using namespace guestControl;
    376421
    377     CheckComArgStrNotEmptyOrNull(aExecName);
     422    CheckComArgStrNotEmptyOrNull(aCommand);
    378423    CheckComArgOutPointerValid(aPID);
    379424    /* Flags are not supported at the moment. */
     
    397442   
    398443        int vrc = VINF_SUCCESS;
    399         Utf8Str Utf8ExecName(aExecName);
    400 
    401         /* Prepare arguments. */
    402         char *pszArgs;
    403         uint32_t cNumArgs;
     444        Utf8Str Utf8Command(aCommand);
     445
     446        /* Prepare arguments. */       
     447        void *pvArgs;
     448        uint32_t uNumArgs;
    404449        uint32_t cbArgs;
    405         rc = prepareExecuteArgs(aArguments,
    406                                 &pszArgs, &cbArgs, &cNumArgs);
    407         if (SUCCEEDED(rc))
     450
     451        const char *pszCurArg = Utf8Str(aArguments).raw();
     452        vrc = prepareExecuteArgs(pszCurArg,
     453                                 &pvArgs, &cbArgs, &uNumArgs);
     454        if (RT_SUCCESS(vrc))
    408455        {
    409456            /* Prepare environment. */
    410             /** @todo */
    411             if (SUCCEEDED(rc))
     457            void *pvEnv = NULL;
     458            uint32_t uNumEnv;
     459            uint32_t cbEnv;
     460
     461            com::SafeArray<IN_BSTR> env(ComSafeArrayInArg(aEnvironment));
     462            for (unsigned i = 0; i < env.size(); ++i)
     463            {
     464                const char *pszCurEnv = Utf8Str(env[i]).raw();
     465                vrc = prepareExecuteEnv(pszCurEnv, &pvEnv, &cbEnv, &uNumEnv);
     466                if (RT_FAILURE(vrc))
     467                    break;
     468            }
     469
     470            if (RT_SUCCESS(vrc))
    412471            {
    413472                Utf8Str Utf8StdIn(aStdIn);
     
    417476                Utf8Str Utf8Password(aPassword);
    418477           
    419                 /* Call the stub which does the actual work. */
    420                 if (RT_SUCCESS(vrc))
     478                VBOXHGCMSVCPARM paParms[13];
     479                paParms[0].setUInt32(HOST_EXEC_CMD);
     480                paParms[1].setUInt32(aFlags);
     481                paParms[2].setPointer((void*)Utf8Command.raw(), (uint32_t)strlen(Utf8Command.raw()) + 1);
     482                paParms[3].setUInt32(uNumArgs);
     483                paParms[4].setPointer((void*)pvArgs, cbArgs);
     484                paParms[5].setUInt32(uNumEnv);
     485                paParms[6].setPointer((void*)pvEnv, cbEnv);
     486                paParms[7].setPointer((void*)Utf8StdIn.raw(), (uint32_t)strlen(Utf8StdIn.raw()) + 1);
     487                paParms[8].setPointer((void*)Utf8StdOut.raw(), (uint32_t)strlen(Utf8StdOut.raw()) + 1);
     488                paParms[9].setPointer((void*)Utf8StdErr.raw(), (uint32_t)strlen(Utf8StdErr.raw()) + 1);
     489                paParms[10].setPointer((void*)Utf8UserName.raw(), (uint32_t)strlen(Utf8UserName.raw()) + 1);
     490                paParms[11].setPointer((void*)Utf8Password.raw(), (uint32_t)strlen(Utf8Password.raw()) + 1);
     491                paParms[12].setUInt32(aTimeoutMS);
     492
     493                /* Forward the information to the VMM device. */
     494                AssertPtr(mParent);
     495                VMMDev *vmmDev = mParent->getVMMDev();
     496                if (vmmDev)
    421497                {
    422                     VBOXHGCMSVCPARM paParms[13];
    423                     uint32_t cParms = 13;
    424 
    425                     /* Forward the information to the VMM device. */
    426                     AssertPtr(mParent);
    427                     VMMDev *vmmDev = mParent->getVMMDev();
    428                     if (vmmDev)
    429                     {
    430                         vrc = vmmDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_CMD,
    431                                                    cParms, &paParms[0]);
    432                     }
     498                    vrc = vmmDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_CMD,
     499                                               13, &paParms[0]);
     500                    /** @todo Get the PID. */
    433501                }
    434                 //RTMemFree(pszEnv);
     502                RTMemFree(pvEnv);
    435503            }
    436             RTStrFree(pszArgs);
     504            RTMemFree(pvArgs);
    437505        }
    438506        if (RT_SUCCESS(vrc))
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r27730 r27767  
    84548454  <interface
    84558455     name="IGuest" extends="$unknown"
    8456      uuid="9576d333-deb9-4c65-0f06-6a1eb6a833e7"
     8456     uuid="a910034a-f95e-bc2c-6bae-eabc3ccd9c73"
    84578457     wsmap="managed"
    84588458     >
     
    85848584        <desc>Foobar</desc>
    85858585      </param>
    8586       <param name="arguments" type="wstring" safearray="yes" dir="in">
     8586      <param name="arguments" type="wstring" dir="in">
    85878587        <desc>Foobar</desc>
    85888588      </param>
  • trunk/src/VBox/Main/include/GuestImpl.h

    r27742 r27767  
    7272                              IN_BSTR aDomain, BOOL aAllowInteractiveLogon);
    7373    STDMETHOD(GetStatistic)(ULONG aCpuId, GuestStatisticType_T aStatistic, ULONG *aStatVal);
    74     STDMETHOD(ExecuteProgram)(IN_BSTR aExecName, ULONG aFlags,
    75                               ComSafeArrayIn(IN_BSTR, aArguments), ComSafeArrayIn(IN_BSTR, aEnvironment),
     74    STDMETHOD(ExecuteProgram)(IN_BSTR aCommand, ULONG aFlags,
     75                              IN_BSTR aArguments, ComSafeArrayIn(IN_BSTR, aEnvironment),
    7676                              IN_BSTR aStdIn, IN_BSTR aStdOut, IN_BSTR aStdErr,
    7777                              IN_BSTR aUserName, IN_BSTR aPassword,
     
    9393
    9494# ifdef VBOX_WITH_GUEST_CONTROL
    95     HRESULT prepareExecuteArgs(ComSafeArrayIn(IN_BSTR, aArguments),
    96                                char **ppszArgv, uint32_t *pcbList, uint32_t *pcArgs);
     95    int prepareExecuteArgs(const char *pszArgs, void **ppvList,
     96                           uint32_t *pcbList, uint32_t *pcArgs);
    9797
    98     HRESULT prepareExecuteEnv(ComSafeArrayIn(IN_BSTR, aEnvironment),
    99                               void **ppvList, uint32_t *pcbList, uint32_t *pcEnv);
     98    int prepareExecuteEnv(const char *pszEnv, void **ppvList,
     99                          uint32_t *pcbList, uint32_t *pcEnv);
    100100# endif
    101101
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette