VirtualBox

Ignore:
Timestamp:
Apr 21, 2010 11:18:32 AM (15 years ago)
Author:
vboxsync
Message:

Guest Control: Update (first stuff for piping output).

Location:
trunk/src/VBox/Additions/common/VBoxService
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp

    r28446 r28557  
    100100
    101101
    102 static int VBoxServiceControlHandleCmdExec(uint32_t u32ClientId, uint32_t uNumParms)
     102static int VBoxServiceControlHandleCmdStartProcess(uint32_t u32ClientId, uint32_t uNumParms)
    103103{
    104104    uint32_t uContextID;
     
    142142    if (RT_FAILURE(rc))
    143143    {
    144         VBoxServiceError("Control: Failed to retrieve execution command! Error: %Rrc\n", rc);
     144        VBoxServiceError("Control: Failed to retrieve exec start command! Error: %Rrc\n", rc);
    145145    }
    146146    else
     
    150150                                           szStdIn, szStdOut, szStdErr,
    151151                                           szUser, szPassword, uTimeLimitMS);
     152    }
     153    return rc;
     154}
     155
     156
     157static int VBoxServiceControlHandleCmdGetOutput(uint32_t u32ClientId, uint32_t uNumParms)
     158{
     159    uint32_t uContextID;
     160    uint32_t uPID;
     161    uint32_t uHandleID;
     162    uint32_t uFlags;
     163
     164    int rc = VbglR3GuestCtrlExecGetHostCmdOutput(u32ClientId, uNumParms,
     165                                                 &uContextID, &uPID, &uHandleID, &uFlags);
     166    if (RT_FAILURE(rc))
     167    {
     168        VBoxServiceError("Control: Failed to retrieve exec output command! Error: %Rrc\n", rc);
     169    }
     170    else
     171    {
     172        /* Let's have a look if we have a running process with PID = uPID ... */
     173        PVBOXSERVICECTRLTHREAD pNode;
     174        bool bFound = false;
     175        RTListForEach(&g_GuestControlExecThreads, pNode, VBOXSERVICECTRLTHREAD, Node)
     176        {
     177            if (   pNode->fStarted
     178                && pNode->enmType == VBoxServiceCtrlThreadDataExec)
     179            {
     180                PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData;
     181                if (pData && pData->uPID == uPID)
     182                {
     183                    bFound = true;
     184                    break;
     185                }
     186            }
     187        }
     188
     189        if (bFound)
     190        {
     191            PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData;
     192            AssertPtr(pData);
     193
     194            uint32_t cbRead = _4K; /* Try reading 4k. */
     195            BYTE *pBuf = (BYTE*)RTMemAlloc(cbRead);
     196            if (pBuf)
     197            {
     198                rc = VBoxServiceControlExecReadPipeBufferContent(&pData->stdOut, pBuf, cbRead, &cbRead);
     199                if (RT_SUCCESS(rc))
     200                {   
     201                    AssertPtr(pBuf);
     202                    /* cbRead now contains actual size. */
     203                    rc = VbglR3GuestCtrlExecSendOut(u32ClientId, uContextID, uPID, 0 /* handle ID */, 0 /* flags */,
     204                                                    pBuf, cbRead);
     205                }
     206                RTMemFree(pBuf);
     207            }
     208            else
     209                rc = VERR_NO_MEMORY;
     210        }
     211        else
     212            rc = VERR_NOT_FOUND; /* PID not found! */
    152213    }
    153214    return rc;
     
    176237        uint32_t uMsg;
    177238        uint32_t uNumParms;
    178         VBoxServiceVerbose(3, "Control: Waiting for host msg ...\n");
     239        VBoxServiceVerbose(4, "Control: Waiting for host msg ...\n");
    179240        rc = VbglR3GuestCtrlGetHostMsg(g_GuestControlSvcClientID, &uMsg, &uNumParms, 1000 /* 1s timeout */);
    180241        if (rc == VERR_TOO_MUCH_DATA)
     
    190251        if (RT_SUCCESS(rc))
    191252        {
     253            VBoxServiceVerbose(3, "Control: Msg=%u (%u parms) retrieved\n", uMsg, uNumParms);
    192254            switch(uMsg)
    193255            {
    194                 case GETHOSTMSG_EXEC_CMD:
    195                     rc = VBoxServiceControlHandleCmdExec(g_GuestControlSvcClientID, uNumParms);
     256                case GETHOSTMSG_EXEC_START_PROCESS:
     257                    rc = VBoxServiceControlHandleCmdStartProcess(g_GuestControlSvcClientID, uNumParms);
    196258                    break;
    197259
     260                case GETHOSTMSG_EXEC_GET_OUTPUT:
     261                    rc = VBoxServiceControlHandleCmdGetOutput(g_GuestControlSvcClientID, uNumParms);
     262                    break;
     263
    198264                default:
    199                     VBoxServiceVerbose(3, "Control: Unsupported message from host! Msg=%ld\n", uMsg);
     265                    VBoxServiceVerbose(3, "Control: Unsupported message from host! Msg=%u\n", uMsg);
    200266                    /* Don't terminate here; just wait for the next message. */
    201267                    break;
    202268            }
     269
     270            if (RT_FAILURE(rc))
     271                VBoxServiceVerbose(3, "Control: Message was processed with rc=%Rrc\n", rc);
    203272        }
    204273
     
    252321            int rc2 = RTThreadWait(pNode->Thread, 30 * 1000 /* Wait 30 seconds max. */, NULL);
    253322            if (RT_FAILURE(rc2))
    254                 VBoxServiceError("Control: Thread (PID: %u) failed to stop; rc2=%Rrc\n", pNode->uPID, rc2);
    255         }
    256         VBoxServiceControlExecDestroyThreadData(pNode);
     323                VBoxServiceError("Control: Thread failed to stop; rc2=%Rrc\n", rc2);
     324        }
     325
     326        /* Destroy thread specific data. */
     327        switch (pNode->enmType)
     328        {
     329            case VBoxServiceCtrlThreadDataExec:
     330                VBoxServiceControlExecDestroyThreadData((PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData);
     331                break;
     332
     333            default:
     334                break;
     335        }
    257336    }
    258337
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp

    r28463 r28557  
    145145 *
    146146 * @returns IPRT status code from client send.
     147 * @param   pThread             The thread specific data.
    147148 * @param   hPollSet            The polling set.
    148149 * @param   fPollEvt            The event mask returned by RTPollNoResume.
     
    154155 * @todo    Put the last 4 parameters into a struct!
    155156 */
    156 static int VBoxServiceControlExecProcHandleOutputEvent(RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phPipeR,
     157static int VBoxServiceControlExecProcHandleOutputEvent(PVBOXSERVICECTRLTHREAD pThread,
     158                                                       RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phPipeR,
    157159                                                       uint32_t *puCrc32 , uint32_t uHandleId)
    158160{
     
    163165     */
    164166    int rc = VINF_SUCCESS;
    165 
    166     char    abBuf[_64K];
    167167    size_t  cbRead;
    168     int     rc2 = RTPipeRead(*phPipeR, abBuf, sizeof(abBuf), &cbRead);
     168    BYTE    abBuf[_64K];
     169
     170    AssertPtr(pThread);
     171    PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData;
     172    AssertPtr(pData);
     173
     174    int rc2 = RTPipeRead(*phPipeR, abBuf, sizeof(abBuf), &cbRead);
    169175    if (RT_SUCCESS(rc2) && cbRead)
    170176    {
    171         Log(("Crc32=%#x ", *puCrc32));
    172 
    173 #if 1
    174             abBuf[cbRead] = '\0';
    175             RTPrintf("%s: %s\n", uHandleId == 1 ? "StdOut: " : "StdErr: ", abBuf);
     177#if 0
     178        /* Only used for "real-time" stdout/stderr data; gets sent immediately (later)! */
     179        rc = VbglR3GuestCtrlExecSendOut(pThread->uClientID, pThread->uContextID,
     180                                        pData->uPID, uHandleId, 0 /* u32Flags */,
     181                                        abBuf, cbRead);
    176182#endif
    177 
    178         /**puCrc32 = RTCrc32Process(*puCrc32, abBuf, cbRead);
    179         Log(("cbRead=%#x Crc32=%#x \n", cbRead, *puCrc32));
    180         Pkt.uCrc32 = RTCrc32Finish(*puCrc32);*/
    181        /* if (g_fDisplayOutput)
    182         {
    183             if (enmHndId == TXSEXECHNDID_STDOUT)
    184                 RTStrmPrintf(g_pStdErr, "%.*s", cbRead, Pkt.abBuf);
    185             else if (enmHndId == TXSEXECHNDID_STDERR)
    186                 RTStrmPrintf(g_pStdErr, "%.*s", cbRead, Pkt.abBuf);
    187         }
    188 
    189         rc = txsReplyInternal(&Pkt.Hdr, pszOpcode, cbRead + sizeof(uint32_t));*/
    190 
    191         /* Make sure we go another poll round in case there was too much data
    192            for the buffer to hold. */
    193         fPollEvt &= RTPOLL_EVT_ERROR;
     183        rc = VBoxServiceControlExecWritePipeBuffer(&pData->stdOut, abBuf, cbRead);
     184        if (RT_SUCCESS(rc))
     185        {
     186            /* Make sure we go another poll round in case there was too much data
     187               for the buffer to hold. */
     188            fPollEvt &= RTPOLL_EVT_ERROR;
     189        }
    194190    }
    195191    else if (RT_FAILURE(rc2))
     
    254250                                                      || hStdOutR   != NIL_RTPIPE
    255251                                                      || hStdErrR   != NIL_RTPIPE;
    256     RTMSINTERVAL const  cMsPollBase                 = hStdInW != NIL_RTPIPE
     252    RTMSINTERVAL const          cMsPollBase         = hStdInW != NIL_RTPIPE
    257253                                                      ? 100   /* need to poll for input */
    258254                                                      : 1000; /* need only poll for process exit and aborts */
    259     RTMSINTERVAL        cMsPollCur                  = 0;
     255    RTMSINTERVAL                cMsPollCur          = 0;
     256
     257    AssertPtr(pThread);
     258
     259    AssertPtr(pThread);
     260    PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData;
     261    AssertPtr(pData);
    260262
    261263    /* Assign PID to thread data. */
    262     pThread->uPID = hProcess;
     264    pData->uPID = hProcess;
    263265
    264266    /*
     
    266268     * and that it's now OK to send input to the process.
    267269     */
    268     AssertPtr(pThread);
    269270    VBoxServiceVerbose(3, "Control: Process started: PID=%u, CID=%u\n",
    270                        pThread->uPID, pThread->uContextID);
     271                       pData->uPID, pThread->uContextID);
    271272    rc = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID,
    272                                          pThread->uPID, PROC_STS_STARTED, 0 /* u32Flags */,
     273                                         pData->uPID, PROC_STS_STARTED, 0 /* u32Flags */,
    273274                                         NULL /* pvData */, 0 /* cbData */);
    274275
     
    299300
    300301                case 1 /* TXSEXECHNDID_STDOUT */:
    301                     rc = VBoxServiceControlExecProcHandleOutputEvent(hPollSet, fPollEvt, &hStdOutR, &uStdOutCrc32, 1 /* TXSEXECHNDID_STDOUT */);
     302                    rc = VBoxServiceControlExecProcHandleOutputEvent(pThread, hPollSet, fPollEvt, &hStdOutR, &uStdOutCrc32, 1 /* TXSEXECHNDID_STDOUT */);
    302303                    break;
    303304
    304305                case 2 /*TXSEXECHNDID_STDERR */:
    305                     rc = VBoxServiceControlExecProcHandleOutputEvent(hPollSet, fPollEvt, &hStdErrR, &uStdErrCrc32, 2 /*TXSEXECHNDID_STDERR */);
     306                    rc = VBoxServiceControlExecProcHandleOutputEvent(pThread, hPollSet, fPollEvt, &hStdErrR, &uStdErrCrc32, 2 /*TXSEXECHNDID_STDERR */);
    306307                    break;
    307308
     
    467468
    468469        VBoxServiceVerbose(3, "Control: Process ended: PID=%u, CID=%u, Status=%u, Flags=%u\n",
    469                            pThread->uPID, pThread->uContextID, uStatus, uFlags);
     470                           pData->uPID, pThread->uContextID, uStatus, uFlags);
    470471        rc = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID,
    471                                              pThread->uPID, uStatus, uFlags,
     472                                             pData->uPID, uStatus, uFlags,
    472473                                             NULL /* pvData */, 0 /* cbData */);
    473474    }
    474475    RTMemFree(StdInBuf.pch);
    475 
    476476    VBoxServiceVerbose(3, "Control: Process loop ended with rc=%Rrc\n", rc);
    477477    return rc;
     
    529529}
    530530
     531int VBoxServiceControlExecReadPipeBufferContent(PVBOXSERVICECTRLEXECPIPEBUF pBuf,
     532                                                BYTE *pbBuffer, uint32_t cbBuffer, uint32_t *pcbToRead)
     533{
     534    AssertPtr(pcbToRead);
     535
     536// LOCKING
     537
     538    Assert(pBuf->cbOffset >= pBuf->cbRead);
     539    if (*pcbToRead > pBuf->cbOffset - pBuf->cbRead)
     540        *pcbToRead = pBuf->cbOffset - pBuf->cbRead;
     541
     542    if (*pcbToRead > cbBuffer)
     543        *pcbToRead = cbBuffer;
     544
     545    if (*pcbToRead > 0)
     546    {
     547        memcpy(pbBuffer, pBuf->pbData + pBuf->cbRead, *pcbToRead);
     548        pBuf->cbRead += *pcbToRead;
     549    }
     550    else
     551        pbBuffer = NULL;
     552    return VINF_SUCCESS;
     553}
     554
     555int VBoxServiceControlExecWritePipeBuffer(PVBOXSERVICECTRLEXECPIPEBUF pBuf,
     556                                          BYTE *pbData, uint32_t cbData)
     557{
     558    AssertPtr(pBuf);
     559
     560// LOCKING
     561
     562    /** @todo Use RTMemCache or RTMemObj here? */
     563    BYTE *pNewBuf;
     564    while (pBuf->cbSize - pBuf->cbOffset < cbData)
     565    {
     566        pNewBuf = (BYTE*)RTMemRealloc(pBuf->pbData, pBuf->cbSize + _4K);
     567        if (pNewBuf == NULL)
     568            break;
     569        pBuf->cbSize += _4K;
     570        pBuf->pbData = pNewBuf;
     571    }
     572
     573    int rc = VINF_SUCCESS;
     574    if (pBuf->pbData)
     575    {
     576        memcpy(pBuf->pbData + pBuf->cbOffset, pbData, cbData);
     577        pBuf->cbOffset += cbData;
     578        /** @todo Add offset clamping! */
     579    }
     580    else
     581        rc = VERR_NO_MEMORY;
     582    return rc;
     583}
     584
    531585/** Allocates and gives back a thread data struct which then can be used by the worker thread. */
    532586int VBoxServiceControlExecAllocateThreadData(PVBOXSERVICECTRLTHREAD pThread,
     
    540594    AssertPtr(pThread);
    541595
     596    /* General stuff. */   
    542597    pThread->Node.pPrev = NULL;
    543598    pThread->Node.pNext = NULL;
     
    547602    pThread->fStopped = false;
    548603
     604    pThread->uContextID = u32ContextID;
    549605    /* ClientID will be assigned when thread is started! */
    550     pThread->uContextID = u32ContextID;
    551     pThread->uPID = 0; /* Don't have a PID yet. */
    552     pThread->pszCmd = RTStrDup(pszCmd);
    553     pThread->uFlags = uFlags;
    554     pThread->uNumEnvVars = 0;
    555     pThread->uNumArgs = 0; /* Initialize in case of RTGetOptArgvFromString() is failing ... */
     606
     607    /* Specific stuff. */
     608    PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)RTMemAlloc(sizeof(VBOXSERVICECTRLTHREADDATAEXEC));
     609    if (pData == NULL)
     610        return VERR_NO_MEMORY;
     611
     612    pData->uPID = 0; /* Don't have a PID yet. */
     613    pData->pszCmd = RTStrDup(pszCmd);
     614    pData->uFlags = uFlags;
     615    pData->uNumEnvVars = 0;
     616    pData->uNumArgs = 0; /* Initialize in case of RTGetOptArgvFromString() is failing ... */
    556617
    557618    /* Prepare argument list. */
    558     int rc = RTGetOptArgvFromString(&pThread->papszArgs, (int*)&pThread->uNumArgs,
     619    int rc = RTGetOptArgvFromString(&pData->papszArgs, (int*)&pData->uNumArgs,
    559620                                    (uNumArgs > 0) ? pszArgs : "", NULL);
    560621    /* Did we get the same result? */
    561     Assert(uNumArgs == pThread->uNumArgs);
     622    Assert(uNumArgs == pData->uNumArgs);
    562623
    563624    if (RT_SUCCESS(rc))
     
    566627        if (uNumEnvVars)
    567628        {
    568             pThread->papszEnv = (char**)RTMemAlloc(uNumEnvVars * sizeof(char*));
    569             AssertPtr(pThread->papszEnv);
    570             pThread->uNumEnvVars = uNumEnvVars;
     629            pData->papszEnv = (char**)RTMemAlloc(uNumEnvVars * sizeof(char*));
     630            AssertPtr(pData->papszEnv);
     631            pData->uNumEnvVars = uNumEnvVars;
    571632
    572633            const char *pcCur = pszEnv;
     
    575636            while (cbLen < cbEnv)
    576637            {
    577                 if (RTStrAPrintf(& pThread->papszEnv[i++], "%s", pcCur) < 0)
     638                if (RTStrAPrintf(&pData->papszEnv[i++], "%s", pcCur) < 0)
    578639                {
    579640                    rc = VERR_NO_MEMORY;
     
    585646        }
    586647
    587         pThread->pszStdIn = RTStrDup(pszStdIn);
    588         pThread->pszStdOut = RTStrDup(pszStdOut);
    589         pThread->pszStdErr = RTStrDup(pszStdErr);
    590         pThread->pszUser = RTStrDup(pszUser);
    591         pThread->pszPassword = RTStrDup(pszPassword);
    592         pThread->uTimeLimitMS = uTimeLimitMS;
    593     }
    594 
    595     /* Adjust time limit value. */
    596     pThread->uTimeLimitMS = (   (uTimeLimitMS == UINT32_MAX)
    597                              || (uTimeLimitMS == 0)) ?
    598                              RT_INDEFINITE_WAIT : uTimeLimitMS;
     648        pData->pszStdIn = RTStrDup(pszStdIn);
     649        pData->pszStdOut = RTStrDup(pszStdOut);
     650        pData->pszStdErr = RTStrDup(pszStdErr);
     651        pData->pszUser = RTStrDup(pszUser);
     652        pData->pszPassword = RTStrDup(pszPassword);
     653        pData->uTimeLimitMS = uTimeLimitMS;
     654
     655        /* Adjust time limit value. */
     656        pData->uTimeLimitMS = (   (uTimeLimitMS == UINT32_MAX)
     657                               || (uTimeLimitMS == 0)) ?
     658                               RT_INDEFINITE_WAIT : uTimeLimitMS;
     659
     660        /* Init buffers. */
     661        pData->stdOut.pbData = NULL;
     662        pData->stdOut.cbSize = 0;
     663        pData->stdOut.cbOffset = 0;
     664        pData->stdOut.cbRead = 0;
     665
     666        pData->stdErr.pbData = NULL;
     667        pData->stdErr.cbSize = 0;
     668        pData->stdErr.cbOffset = 0;
     669        pData->stdErr.cbRead = 0;
     670    }
     671
     672    if (RT_FAILURE(rc))
     673    {
     674        VBoxServiceControlExecDestroyThreadData(pData);
     675    }
     676    else
     677    {
     678        pThread->enmType = VBoxServiceCtrlThreadDataExec;
     679        pThread->pvData = pData;
     680    }
    599681    return rc;
    600682}
    601683
     684void VBoxServiceControlExecDestroyPipeBuffer(PVBOXSERVICECTRLEXECPIPEBUF pBuf)
     685{
     686    if (pBuf)
     687    {
     688        if (pBuf->pbData)
     689            RTMemFree(pBuf->pbData);
     690        pBuf->pbData = NULL;
     691        pBuf->cbSize = 0;
     692        pBuf->cbOffset = 0;
     693        pBuf->cbRead = 0;
     694    }
     695}
     696
    602697/** Frees an allocated thread data structure along with all its allocated parameters. */
    603 void VBoxServiceControlExecDestroyThreadData(PVBOXSERVICECTRLTHREAD pThread)
     698void VBoxServiceControlExecDestroyThreadData(PVBOXSERVICECTRLTHREADDATAEXEC pData)
     699{
     700    if (pData)
     701    {   
     702        RTStrFree(pData->pszCmd);
     703        if (pData->uNumEnvVars)
     704        {
     705            for (uint32_t i = 0; i < pData->uNumEnvVars; i++)
     706                RTStrFree(pData->papszEnv[i]);
     707            RTMemFree(pData->papszEnv);
     708        }
     709        RTGetOptArgvFree(pData->papszArgs);
     710        RTStrFree(pData->pszStdIn);
     711        RTStrFree(pData->pszStdOut);
     712        RTStrFree(pData->pszStdErr);
     713        RTStrFree(pData->pszUser);
     714        RTStrFree(pData->pszPassword);
     715   
     716        VBoxServiceControlExecDestroyPipeBuffer(&pData->stdOut);
     717        VBoxServiceControlExecDestroyPipeBuffer(&pData->stdErr);
     718
     719        RTMemFree(pData);
     720        pData = NULL;
     721    }
     722}
     723
     724DECLCALLBACK(int) VBoxServiceControlExecProcessWorker(PVBOXSERVICECTRLTHREAD pThread)
    604725{
    605726    AssertPtr(pThread);
    606     RTStrFree(pThread->pszCmd);
    607     if (pThread->uNumEnvVars)
    608     {
    609         for (uint32_t i = 0; i < pThread->uNumEnvVars; i++)
    610             RTStrFree(pThread->papszEnv[i]);
    611         RTMemFree(pThread->papszEnv);
    612     }
    613     RTGetOptArgvFree(pThread->papszArgs);
    614     RTStrFree(pThread->pszStdIn);
    615     RTStrFree(pThread->pszStdOut);
    616     RTStrFree(pThread->pszStdErr);
    617     RTStrFree(pThread->pszUser);
    618     RTStrFree(pThread->pszPassword);
    619 }
    620 
    621 DECLCALLBACK(int) VBoxServiceControlExecProcessWorker(PVBOXSERVICECTRLTHREAD pThread)
    622 {
    623     AssertPtr(pThread);
    624 
    625     AssertPtr(pThread);
    626     AssertPtr(pThread->papszArgs);
    627     AssertPtr(pThread->papszEnv);
     727    PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData;
     728    AssertPtr(pData);
    628729
    629730    /*
     
    632733     */
    633734    RTThreadUserSignal(RTThreadSelf());
    634     VBoxServiceVerbose(3, "Control: Thread of process \"%s\" started\n", pThread->pszCmd);
     735    VBoxServiceVerbose(3, "Control: Thread of process \"%s\" started\n", pData->pszCmd);
    635736
    636737    int rc = VbglR3GuestCtrlConnect(&pThread->uClientID);
     
    649750    {
    650751        size_t i;
    651         for (i = 0; i < pThread->uNumEnvVars; i++)
    652         {
    653             rc = RTEnvPutEx(hEnv, pThread->papszEnv[i]);
     752        for (i = 0; i < pData->uNumEnvVars && pData->papszEnv; i++)
     753        {
     754            rc = RTEnvPutEx(hEnv, pData->papszEnv[i]);
    654755            if (RT_FAILURE(rc))
    655756                break;
     
    695796                            {
    696797                                RTPROCESS hProcess;
    697                                 rc = RTProcCreateEx(pThread->pszCmd, pThread->papszArgs, hEnv, pThread->uFlags,
     798                                rc = RTProcCreateEx(pData->pszCmd, pData->papszArgs, hEnv, pData->uFlags,
    698799                                                    phStdIn, phStdOut, phStdErr,
    699                                                     strlen(pThread->pszUser) ? pThread->pszUser : NULL,
    700                                                     strlen(pThread->pszUser) && strlen(pThread->pszPassword) ? pThread->pszPassword : NULL,
     800                                                    strlen(pData->pszUser) ? pData->pszUser : NULL,
     801                                                    strlen(pData->pszUser) && strlen(pData->pszPassword) ? pData->pszPassword : NULL,
    701802                                                    &hProcess);
    702803                                if (RT_SUCCESS(rc))
     
    714815                                    /* Enter the process loop. */
    715816                                    rc = VBoxServiceControlExecProcLoop(pThread,
    716                                                                         hProcess, pThread->uTimeLimitMS, hPollSet,
     817                                                                        hProcess, pData->uTimeLimitMS, hPollSet,
    717818                                                                        hStdInW, hStdOutR, hStdErrR);
    718819
     
    732833                                else /* Something went wrong; report error! */
    733834                                {
    734                                     int rc2 = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID, pThread->uPID,
     835                                    int rc2 = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID, pData->uPID,
    735836                                                                              PROC_STS_ERROR, rc,
    736837                                                                              NULL /* pvData */, 0 /* cbData */);
     
    756857    VbglR3GuestCtrlDisconnect(pThread->uClientID);
    757858    VBoxServiceVerbose(3, "Control: Thread of process \"%s\" (PID: %u) ended with rc=%Rrc\n",
    758                        pThread->pszCmd, pThread->uPID, rc);
     859                       pData->pszCmd, pData->uPID, rc);
    759860    return rc;
    760861}
     
    807908                else
    808909                {
     910                    pThread->fStarted = true;
    809911                    /*rc =*/ RTListAppend(&g_GuestControlExecThreads, &pThread->Node);
    810912                }
     
    812914
    813915            if (RT_FAILURE(rc))
    814                 VBoxServiceControlExecDestroyThreadData(pThread);
     916                VBoxServiceControlExecDestroyThreadData((PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData);
    815917        }
    816918        if (RT_FAILURE(rc))
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h

    r28434 r28557  
    130130
    131131#ifdef VBOX_WITH_GUEST_CONTROL
    132 /* Structure for holding thread relevant data. */
    133 typedef struct
    134 {
    135     /** Node. */
    136     RTLISTNODE                 Node;
    137     /** The worker thread. */
    138     RTTHREAD                   Thread;
    139     /** Shutdown indicator. */
    140     bool volatile              fShutdown;
    141     /** Indicator set by the service thread exiting. */
    142     bool volatile              fStopped;
    143     /** Whether the service was started or not. */
    144     bool                       fStarted;
    145     /** @todo */
    146     uint32_t  uClientID;
    147     uint32_t  uContextID;
     132enum VBOXSERVICECTRLTHREADDATATYPE
     133{
     134    VBoxServiceCtrlThreadDataUnknown = 0,
     135    VBoxServiceCtrlThreadDataExec = 1
     136};
     137
     138typedef struct
     139{
     140    BYTE     *pbData;
     141    uint32_t  cbSize;
     142    uint32_t  cbOffset;
     143    uint32_t  cbRead;
     144} VBOXSERVICECTRLEXECPIPEBUF;
     145/** Pointer to thread data. */
     146typedef VBOXSERVICECTRLEXECPIPEBUF *PVBOXSERVICECTRLEXECPIPEBUF;
     147
     148/* Structure for holding guest exection relevant data. */
     149typedef struct
     150{
    148151    uint32_t  uPID;
    149152    char     *pszCmd;
     
    159162    char     *pszPassword;
    160163    uint32_t  uTimeLimitMS;
     164
     165    VBOXSERVICECTRLEXECPIPEBUF stdOut;
     166    VBOXSERVICECTRLEXECPIPEBUF stdErr;
     167
     168} VBOXSERVICECTRLTHREADDATAEXEC;
     169/** Pointer to thread data. */
     170typedef VBOXSERVICECTRLTHREADDATAEXEC *PVBOXSERVICECTRLTHREADDATAEXEC;
     171
     172/* Structure for holding thread relevant data. */
     173typedef struct
     174{
     175    /** Node. */
     176    RTLISTNODE                      Node;
     177    /** The worker thread. */
     178    RTTHREAD                        Thread;
     179    /** Shutdown indicator. */
     180    bool volatile                   fShutdown;
     181    /** Indicator set by the service thread exiting. */
     182    bool volatile                   fStopped;
     183    /** Whether the service was started or not. */
     184    bool                            fStarted;
     185    /** Client ID. */
     186    uint32_t                        uClientID;
     187    /** Context ID. */
     188    uint32_t                        uContextID;
     189    /** Type of thread.  See VBOXSERVICECTRLTHREADDATATYPE for more info. */
     190    VBOXSERVICECTRLTHREADDATATYPE   enmType;
     191    /** Pointer to actual thread data, depending on enmType. */
     192    void                           *pvData;
    161193} VBOXSERVICECTRLTHREAD;
    162194/** Pointer to thread data. */
     
    236268                                         const char *pszStdIn, const char *pszStdOut, const char *pszStdErr,
    237269                                         const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS);
    238 extern void VBoxServiceControlExecDestroyThreadData(PVBOXSERVICECTRLTHREAD pThread);
     270extern void VBoxServiceControlExecDestroyThreadData(PVBOXSERVICECTRLTHREADDATAEXEC pThread);
     271extern int VBoxServiceControlExecReadPipeBufferContent(PVBOXSERVICECTRLEXECPIPEBUF pBuf,
     272                                                       BYTE *pbBuffer, uint32_t cbBuffer, uint32_t *pcbToRead);
     273extern int VBoxServiceControlExecWritePipeBuffer(PVBOXSERVICECTRLEXECPIPEBUF pBuf,
     274                                                 BYTE *pbData, uint32_t cbData);
    239275#endif
    240276
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