VirtualBox

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


Ignore:
Timestamp:
Apr 12, 2010 1:48:49 PM (15 years ago)
Author:
vboxsync
Message:

Guest Control: Update (first code for low level HGCM callback).

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

Legend:

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

    r28132 r28206  
    3636# include <VBox/HostServices/GuestControlSvc.h>
    3737# include <VBox/com/array.h>
     38# include <hgcm/HGCM.h>
    3839#endif
    3940#include <iprt/cpp/utils.h>
     
    435436    return rc;
    436437}
     438
     439// static
     440DECLCALLBACK(int) Guest::doGuestCtrlNotification(void *pvExtension,
     441                                                 uint32_t u32Function,
     442                                                 void *pvParms,
     443                                                 uint32_t cbParms)
     444{
     445    using namespace guestControl;
     446
     447    /*
     448     * No locking, as this is purely a notification which does not make any
     449     * changes to the object state.
     450     */
     451    PHOSTCALLBACKDATA pCBData = reinterpret_cast<PHOSTCALLBACKDATA>(pvParms);
     452    AssertReturn(sizeof(HOSTCALLBACKDATA) == cbParms, VERR_INVALID_PARAMETER);
     453    AssertReturn(HOSTCALLBACKMAGIC == pCBData->u32Magic, VERR_INVALID_PARAMETER);
     454    LogFlowFunc(("pvExtension = %p, u32Function = %d, pvParms = %p, cbParms = %d\n",
     455                 pvExtension, u32Function, pvParms, cbParms));
     456
     457    int rc = VINF_SUCCESS;
     458    Guest *pGuest = static_cast <Guest *>(pvExtension);
     459
     460    switch (u32Function)
     461    {       
     462        default:
     463            rc = VERR_NOT_SUPPORTED;
     464            break;
     465    }
     466
     467    ASMAtomicWriteBool(&pGuest->mSignalled, true);
     468    return rc;
     469}
    437470#endif /* VBOX_WITH_GUEST_CONTROL */
    438471
     
    477510
    478511        /*
    479          * Prepare process execution.
     512         * Register the host notification callback
    480513         */
    481         int vrc = VINF_SUCCESS;
    482         Utf8Str Utf8Command(aCommand);
    483 
    484         /* Prepare arguments. */       
    485         com::SafeArray<IN_BSTR> args(ComSafeArrayInArg(aArguments));
    486         uint32_t uNumArgs = args.size();
    487         char **papszArgv = NULL;
    488         if(uNumArgs > 0)
    489         {
    490             papszArgv = (char**)RTMemAlloc(sizeof(char*) * (uNumArgs + 1));
    491             AssertPtr(papszArgv);
    492             for (unsigned i = 0; RT_SUCCESS(vrc) && i < uNumArgs; i++)
    493                 vrc = RTStrAPrintf(&papszArgv[i], "%s", Utf8Str(args[i]).raw());
    494             papszArgv[uNumArgs] = NULL;
    495         }
    496 
     514        HGCMSVCEXTHANDLE hExt;
     515        int vrc = HGCMHostRegisterServiceExtension(&hExt, "VBoxGuestCtrlSvc",
     516                                                   &Guest::doGuestCtrlNotification,
     517                                                   this);
    497518        if (RT_SUCCESS(vrc))
    498519        {
    499             char *pszArgs = NULL;
    500             if (uNumArgs > 0)
    501                 vrc = RTGetOptArgvToString(&pszArgs, papszArgv, 0);         
     520            /*
     521             * Prepare process execution.
     522             */
     523            Utf8Str Utf8Command(aCommand);
     524   
     525            /* Prepare arguments. */       
     526            com::SafeArray<IN_BSTR> args(ComSafeArrayInArg(aArguments));
     527            uint32_t uNumArgs = args.size();
     528            char **papszArgv = NULL;
     529            if(uNumArgs > 0)
     530            {
     531                papszArgv = (char**)RTMemAlloc(sizeof(char*) * (uNumArgs + 1));
     532                AssertPtr(papszArgv);
     533                for (unsigned i = 0; RT_SUCCESS(vrc) && i < uNumArgs; i++)
     534                    vrc = RTStrAPrintf(&papszArgv[i], "%s", Utf8Str(args[i]).raw());
     535                papszArgv[uNumArgs] = NULL;
     536            }
     537   
    502538            if (RT_SUCCESS(vrc))
    503539            {
    504                 uint32_t cbArgs = pszArgs ? strlen(pszArgs) + 1 : 0; /* Include terminating zero. */
    505 
    506                 /* Prepare environment. */
    507                 com::SafeArray<IN_BSTR> env(ComSafeArrayInArg(aEnvironment));
    508    
    509                 void *pvEnv = NULL;
    510                 uint32_t uNumEnv = 0;
    511                 uint32_t cbEnv = 0;
    512    
    513                 for (unsigned i = 0; i < env.size(); i++)
    514                 {
    515                     vrc = prepareExecuteEnv(Utf8Str(env[i]).raw(), &pvEnv, &cbEnv, &uNumEnv);
    516                     if (RT_FAILURE(vrc))
    517                         break;
    518                 }
    519    
     540                char *pszArgs = NULL;
     541                if (uNumArgs > 0)
     542                    vrc = RTGetOptArgvToString(&pszArgs, papszArgv, 0);         
    520543                if (RT_SUCCESS(vrc))
    521544                {
    522                     Utf8Str Utf8StdIn(aStdIn);
    523                     Utf8Str Utf8StdOut(aStdOut);
    524                     Utf8Str Utf8StdErr(aStdErr);
    525                     Utf8Str Utf8UserName(aUserName);
    526                     Utf8Str Utf8Password(aPassword);
    527                
    528                     VBOXHGCMSVCPARM paParms[14];
    529                     int i = 0;
    530                     paParms[i++].setPointer((void*)Utf8Command.raw(), (uint32_t)strlen(Utf8Command.raw()) + 1);
    531                     paParms[i++].setUInt32(aFlags);
    532                     paParms[i++].setUInt32(uNumArgs);
    533                     paParms[i++].setPointer((void*)pszArgs, cbArgs);
    534                     paParms[i++].setUInt32(uNumEnv);
    535                     paParms[i++].setUInt32(cbEnv);
    536                     paParms[i++].setPointer((void*)pvEnv, cbEnv);
    537                     paParms[i++].setPointer((void*)Utf8StdIn.raw(), (uint32_t)strlen(Utf8StdIn.raw()) + 1);
    538                     paParms[i++].setPointer((void*)Utf8StdOut.raw(), (uint32_t)strlen(Utf8StdOut.raw()) + 1);
    539                     paParms[i++].setPointer((void*)Utf8StdErr.raw(), (uint32_t)strlen(Utf8StdErr.raw()) + 1);
    540                     paParms[i++].setPointer((void*)Utf8UserName.raw(), (uint32_t)strlen(Utf8UserName.raw()) + 1);
    541                     paParms[i++].setPointer((void*)Utf8Password.raw(), (uint32_t)strlen(Utf8Password.raw()) + 1);
    542                     paParms[i++].setUInt32(aTimeoutMS);
     545                    uint32_t cbArgs = pszArgs ? strlen(pszArgs) + 1 : 0; /* Include terminating zero. */
    543546   
    544                     /* Forward the information to the VMM device. */
    545                     AssertPtr(mParent);
    546                     VMMDev *vmmDev = mParent->getVMMDev();
    547                     if (vmmDev)
     547                    /* Prepare environment. */
     548                    com::SafeArray<IN_BSTR> env(ComSafeArrayInArg(aEnvironment));
     549       
     550                    void *pvEnv = NULL;
     551                    uint32_t uNumEnv = 0;
     552                    uint32_t cbEnv = 0;
     553       
     554                    for (unsigned i = 0; i < env.size(); i++)
    548555                    {
    549                         LogFlow(("Guest::ExecuteProgram: numParms=%d\n", i));
    550                         vrc = vmmDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_CMD,
    551                                                    i, paParms);
    552                         /** @todo Get the PID. */
     556                        vrc = prepareExecuteEnv(Utf8Str(env[i]).raw(), &pvEnv, &cbEnv, &uNumEnv);
     557                        if (RT_FAILURE(vrc))
     558                            break;
    553559                    }
    554                     RTMemFree(pvEnv);
     560       
     561                    if (RT_SUCCESS(vrc))
     562                    {
     563                        Utf8Str Utf8StdIn(aStdIn);
     564                        Utf8Str Utf8StdOut(aStdOut);
     565                        Utf8Str Utf8StdErr(aStdErr);
     566                        Utf8Str Utf8UserName(aUserName);
     567                        Utf8Str Utf8Password(aPassword);
     568                   
     569                        VBOXHGCMSVCPARM paParms[14];
     570                        int i = 0;
     571                        paParms[i++].setPointer((void*)Utf8Command.raw(), (uint32_t)strlen(Utf8Command.raw()) + 1);
     572                        paParms[i++].setUInt32(aFlags);
     573                        paParms[i++].setUInt32(uNumArgs);
     574                        paParms[i++].setPointer((void*)pszArgs, cbArgs);
     575                        paParms[i++].setUInt32(uNumEnv);
     576                        paParms[i++].setUInt32(cbEnv);
     577                        paParms[i++].setPointer((void*)pvEnv, cbEnv);
     578                        paParms[i++].setPointer((void*)Utf8StdIn.raw(), (uint32_t)strlen(Utf8StdIn.raw()) + 1);
     579                        paParms[i++].setPointer((void*)Utf8StdOut.raw(), (uint32_t)strlen(Utf8StdOut.raw()) + 1);
     580                        paParms[i++].setPointer((void*)Utf8StdErr.raw(), (uint32_t)strlen(Utf8StdErr.raw()) + 1);
     581                        paParms[i++].setPointer((void*)Utf8UserName.raw(), (uint32_t)strlen(Utf8UserName.raw()) + 1);
     582                        paParms[i++].setPointer((void*)Utf8Password.raw(), (uint32_t)strlen(Utf8Password.raw()) + 1);
     583                        paParms[i++].setUInt32(aTimeoutMS);
     584       
     585                        /* Forward the information to the VMM device. */
     586                        AssertPtr(mParent);
     587                        VMMDev *vmmDev = mParent->getVMMDev();
     588                        if (vmmDev)
     589                        {
     590                            LogFlow(("Guest::ExecuteProgram: numParms=%d\n", i));
     591                            vrc = vmmDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_CMD,
     592                                                       i, paParms);
     593                            /** @todo Get the PID. */
     594                        }
     595                        RTMemFree(pvEnv);
     596                    }
     597                    RTStrFree(pszArgs);
    555598                }
    556                 RTStrFree(pszArgs);
     599                if (RT_SUCCESS(vrc))
     600                {
     601                    /* Wait for the HGCM low level callback */
     602                    mSignalled = false;
     603                    uint64_t u64Started = RTTimeMilliTS();
     604                    do
     605                    {
     606                        unsigned cMsWait;
     607                        if (aTimeoutMS == RT_INDEFINITE_WAIT)
     608                            cMsWait = 1000;
     609                        else
     610                        {
     611                            uint64_t cMsElapsed = RTTimeMilliTS() - u64Started;
     612                            if (cMsElapsed >= aTimeoutMS)
     613                                break; /* timed out */
     614                            cMsWait = RT_MIN(1000, aTimeoutMS - (uint32_t)cMsElapsed);
     615                        }
     616                    } while (!mSignalled);
     617#if 0
     618                    progress.queryInterfaceTo(aProgress);
     619#endif
     620                }
     621                else
     622                    rc = setError(E_UNEXPECTED,
     623                                  tr("The service call failed with the error %Rrc"),
     624                                  vrc);
     625   
     626                for (unsigned i = 0; i < uNumArgs; i++)
     627                    RTMemFree(papszArgv[i]);
     628                RTMemFree(papszArgv);
    557629            }
    558             if (RT_SUCCESS(vrc))
    559             {
    560 #if 0
    561                 progress.queryInterfaceTo(aProgress);
    562 #endif
    563                 rc = S_OK;
    564             }
    565             else
    566                 rc = setError(E_UNEXPECTED,
    567                               tr("The service call failed with the error %Rrc"),
    568                               vrc);
    569 
    570             for (unsigned i = 0; i < uNumArgs; i++)
    571                 RTMemFree(papszArgv[i]);
    572             RTMemFree(papszArgv);
     630            /* Unregister HGCM extension */
     631            HGCMHostUnregisterServiceExtension(hExt);
    573632        }
    574633    }
     
    576635    {
    577636        rc = E_OUTOFMEMORY;
    578     };
    579 
     637    }
    580638    return rc;
    581639#endif /* VBOX_WITH_GUEST_CONTROL */
  • trunk/src/VBox/Main/include/GuestImpl.h

    r28036 r28206  
    107107
    108108# ifdef VBOX_WITH_GUEST_CONTROL
    109     int prepareExecuteArgs(const char *pszArgs, void **ppvList,
    110                            uint32_t *pcbList, uint32_t *pcArgs);
    111 
    112     int prepareExecuteEnv(const char *pszEnv, void **ppvList,
    113                           uint32_t *pcbList, uint32_t *pcEnv);
     109    int prepareExecuteArgs(const char *pszArgs, void **ppvList, uint32_t *pcbList, uint32_t *pcArgs);
     110    int prepareExecuteEnv(const char *pszEnv, void **ppvList, uint32_t *pcbList, uint32_t *pcEnv);
     111    /** Static callback for handling guest notifications. */
     112    static DECLCALLBACK(int) doGuestCtrlNotification(void *pvExtension, uint32_t u32Function, void *pvParms, uint32_t cbParms);
    114113# endif
    115114
     
    132131    Console *mParent;
    133132    Data mData;
     133    bool mSignalled;
    134134};
    135135
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