~ubuntu-branches/ubuntu/quantal/virtualbox/quantal

« back to all changes in this revision

Viewing changes to src/VBox/Additions/common/VBoxService/VBoxServiceControlThread.cpp

  • Committer: Package Import Robot
  • Author(s): Felix Geyer
  • Date: 2012-04-05 12:41:55 UTC
  • mfrom: (3.1.12 sid)
  • Revision ID: package-import@ubuntu.com-20120405124155-i7b39tv5ddwhubbe
Tags: 4.1.12-dfsg-2
* Upstream has replaced the 4.1.12 tarball with a new one that fixes a
  crash when creating host only interfaces. (Closes: #667460)
  - Add 36-tarball-respin.patch which contains the diff between the old
    and the new tarball.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 */
5
5
 
6
6
/*
7
 
 * Copyright (C) 2011 Oracle Corporation
 
7
 * Copyright (C) 2012 Oracle Corporation
8
8
 *
9
9
 * This file is part of VirtualBox Open Source Edition (OSE), as
10
10
 * available from http://www.virtualbox.org. This file is free software;
151
151
{
152
152
    AssertPtrReturn(pThread, VERR_INVALID_POINTER);
153
153
 
154
 
    VBoxServiceVerbose(3, "ControlThread: [PID %u]: Freeing ...\n",
 
154
    VBoxServiceVerbose(3, "[PID %u]: Freeing ...\n",
155
155
                       pThread->uPID);
156
156
 
157
157
    int rc = RTCritSectEnter(&pThread->CritSect);
169
169
        RTStrFree(pThread->pszUser);
170
170
        RTStrFree(pThread->pszPassword);
171
171
 
172
 
        VBoxServiceVerbose(3, "ControlThread: [PID %u]: Setting stopped state\n",
 
172
        VBoxServiceVerbose(3, "[PID %u]: Setting stopped state\n",
173
173
                           pThread->uPID);
174
174
 
175
175
        rc = RTCritSectLeave(&pThread->CritSect);
203
203
{
204
204
    AssertPtrReturn(pThread, VERR_INVALID_POINTER);
205
205
 
206
 
    VBoxServiceVerbose(3, "ControlThread: [PID %u]: Stopping ...\n",
 
206
    VBoxServiceVerbose(3, "[PID %u]: Stopping ...\n",
207
207
                       pThread->uPID);
208
208
 
209
209
    int rc = vboxServiceControlThreadRequestCancel(pThread->pRequest);
210
210
    if (RT_FAILURE(rc))
211
 
        VBoxServiceError("ControlThread: [PID %u]: Signalling request event failed, rc=%Rrc\n",
 
211
        VBoxServiceError("[PID %u]: Signalling request event failed, rc=%Rrc\n",
212
212
                         pThread->uPID, rc);
213
213
 
214
214
    /* Do *not* set pThread->fShutdown or other stuff here!
220
220
    {
221
221
        rc = VBoxServiceControlThreadPerform(pThread->uPID, pRequest);
222
222
        if (RT_FAILURE(rc))
223
 
            VBoxServiceVerbose(3, "ControlThread: [PID %u]: Sending quit request failed with rc=%Rrc\n",
 
223
            VBoxServiceVerbose(3, "[PID %u]: Sending quit request failed with rc=%Rrc\n",
224
224
                               pThread->uPID, rc);
225
225
 
226
226
        VBoxServiceControlThreadRequestFree(pRequest);
235
235
 * @return  IPRT status code.
236
236
 * @param   pThread             Thread to wait shutting down for.
237
237
 * @param   RTMSINTERVAL        Timeout in ms to wait for shutdown.
 
238
 * @param   prc                 Where to store the thread's return code. Optional.
238
239
 */
239
240
int VBoxServiceControlThreadWait(const PVBOXSERVICECTRLTHREAD pThread,
240
 
                                 RTMSINTERVAL msTimeout)
 
241
                                 RTMSINTERVAL msTimeout, int *prc)
241
242
{
242
243
    AssertPtrReturn(pThread, VERR_INVALID_POINTER);
 
244
    /* prc is optional. */
 
245
 
243
246
    int rc = VINF_SUCCESS;
244
247
    if (   pThread->Thread != NIL_RTTHREAD
245
248
        && ASMAtomicReadBool(&pThread->fStarted))
246
249
    {
247
 
        VBoxServiceVerbose(2, "ControlThread: [PID %u]: Waiting for shutdown ...\n",
248
 
                           pThread->uPID);
 
250
        VBoxServiceVerbose(2, "[PID %u]: Waiting for shutdown of pThread=0x%p = \"%s\"...\n",
 
251
                           pThread->uPID, pThread, pThread->pszCmd);
249
252
 
250
253
        /* Wait a bit ... */
251
254
        int rcThread;
252
255
        rc = RTThreadWait(pThread->Thread, msTimeout, &rcThread);
253
256
        if (RT_FAILURE(rc))
254
257
        {
255
 
            VBoxServiceError("ControlThread: [PID %u]: Waiting for shutting down thread returned error rc=%Rrc\n",
 
258
            VBoxServiceError("[PID %u]: Waiting for shutting down thread returned error rc=%Rrc\n",
256
259
                             pThread->uPID, rc);
257
260
        }
258
261
        else
259
262
        {
260
 
            if (RT_FAILURE(rcThread))
261
 
            {
262
 
                VBoxServiceError("ControlThread: [PID %u]: Shutdown returned error rc=%Rrc\n",
263
 
                                 pThread->uPID, rcThread);
264
 
                rc = rcThread;
265
 
            }
 
263
            VBoxServiceVerbose(3, "[PID %u]: Thread reported exit code=%Rrc\n",
 
264
                               pThread->uPID, rcThread);
 
265
            if (prc)
 
266
                *prc = rcThread;
266
267
        }
267
268
    }
268
269
    return rc;
327
328
    AssertPtrReturn(phPipeR, VERR_INVALID_POINTER);
328
329
 
329
330
#ifdef DEBUG
330
 
    VBoxServiceVerbose(4, "ControlThread: VBoxServiceControlThreadHandleOutputError: fPollEvt=0x%x, idPollHnd=%u\n",
 
331
    VBoxServiceVerbose(4, "VBoxServiceControlThreadHandleOutputError: fPollEvt=0x%x, idPollHnd=%u\n",
331
332
                       fPollEvt, idPollHnd);
332
333
#endif
333
334
 
343
344
    if (   RT_SUCCESS(rc2)
344
345
        && cbReadable)
345
346
    {
346
 
        VBoxServiceVerbose(3, "ControlThread: VBoxServiceControlThreadHandleOutputError: idPollHnd=%u has %ld bytes left, vetoing close\n",
 
347
        VBoxServiceVerbose(3, "VBoxServiceControlThreadHandleOutputError: idPollHnd=%u has %ld bytes left, vetoing close\n",
347
348
                           idPollHnd, cbReadable);
348
349
 
349
350
        /* Veto closing the pipe yet because there's still stuff to read
352
353
        fClosePipe = false;
353
354
    }
354
355
    else
355
 
        VBoxServiceVerbose(3, "ControlThread: VBoxServiceControlThreadHandleOutputError: idPollHnd=%u will be closed\n",
 
356
        VBoxServiceVerbose(3, "VBoxServiceControlThreadHandleOutputError: idPollHnd=%u will be closed\n",
356
357
                           idPollHnd);
357
358
 
358
359
    if (   *phPipeR != NIL_RTPIPE
381
382
                                                     PRTPIPE phPipeR, uint32_t idPollHnd)
382
383
{
383
384
#if 0
384
 
    VBoxServiceVerbose(4, "ControlThread: VBoxServiceControlThreadHandleOutputEvent: fPollEvt=0x%x, idPollHnd=%u\n",
 
385
    VBoxServiceVerbose(4, "VBoxServiceControlThreadHandleOutputEvent: fPollEvt=0x%x, idPollHnd=%u\n",
385
386
                       fPollEvt, idPollHnd);
386
387
#endif
387
388
 
393
394
    if (   RT_SUCCESS(rc)
394
395
        && cbReadable)
395
396
    {
396
 
        VBoxServiceVerbose(4, "ControlThread: VBoxServiceControlThreadHandleOutputEvent: cbReadable=%ld\n",
 
397
        VBoxServiceVerbose(4, "VBoxServiceControlThreadHandleOutputEvent: cbReadable=%ld\n",
397
398
                           cbReadable);
398
399
    }
399
400
#endif
405
406
        uint8_t byData[_64K];
406
407
        rc = RTPipeRead(*phPipeR,
407
408
                        byData, sizeof(byData), &cbRead);
408
 
        VBoxServiceVerbose(4, "ControlThread: VBoxServiceControlThreadHandleOutputEvent cbRead=%u, rc=%Rrc\n",
 
409
        VBoxServiceVerbose(4, "VBoxServiceControlThreadHandleOutputEvent cbRead=%u, rc=%Rrc\n",
409
410
                           cbRead, rc);
410
411
 
411
412
        /* Make sure we go another poll round in case there was too much data
435
436
    size_t cbIgnore;
436
437
    int rc = RTPipeRead(pThread->hNotificationPipeR, abBuf, sizeof(abBuf), &cbIgnore);
437
438
    if (RT_FAILURE(rc))
438
 
        VBoxServiceError("ControlThread: Draining IPC notification pipe failed with rc=%Rrc\n", rc);
 
439
        VBoxServiceError("Draining IPC notification pipe failed with rc=%Rrc\n", rc);
439
440
 
440
441
    int rcReq = VINF_SUCCESS; /* Actual request result. */
441
442
 
442
443
    PVBOXSERVICECTRLREQUEST pRequest = pThread->pRequest;
443
444
    if (!pRequest)
444
445
    {
445
 
        VBoxServiceError("ControlThread: IPC request is invalid\n");
 
446
        VBoxServiceError("IPC request is invalid\n");
446
447
        return VERR_INVALID_POINTER;
447
448
    }
448
449
 
531
532
    pRequest->rc = RT_SUCCESS(rc)
532
533
                 ? rcReq : rc;
533
534
 
534
 
    VBoxServiceVerbose(2, "ControlThread: [PID %u]: Handled req=%u, CID=%u, rc=%Rrc, cbData=%u\n",
 
535
    VBoxServiceVerbose(2, "[PID %u]: Handled req=%u, CID=%u, rc=%Rrc, cbData=%u\n",
535
536
                       pThread->uPID, pRequest->enmType, pRequest->uCID, pRequest->rc, pRequest->cbData);
536
537
 
537
538
    /* In any case, regardless of the result, we notify
588
589
    rc = VBoxServiceControlAssignPID(pThread, hProcess);
589
590
    if (RT_FAILURE(rc))
590
591
    {
591
 
        VBoxServiceError("ControlThread: Unable to assign PID=%u, to new thread, rc=%Rrc\n",
 
592
        VBoxServiceError("Unable to assign PID=%u, to new thread, rc=%Rrc\n",
592
593
                         hProcess, rc);
593
594
        return rc;
594
595
    }
597
598
     * Before entering the loop, tell the host that we've started the guest
598
599
     * and that it's now OK to send input to the process.
599
600
     */
600
 
    VBoxServiceVerbose(2, "ControlThread: [PID %u]: Process \"%s\" started, CID=%u, User=%s\n",
 
601
    VBoxServiceVerbose(2, "[PID %u]: Process \"%s\" started, CID=%u, User=%s\n",
601
602
                       pThread->uPID, pThread->pszCmd, pThread->uContextID, pThread->pszUser);
602
603
    rc = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID,
603
604
                                         pThread->uPID, PROC_STS_STARTED, 0 /* u32Flags */,
622
623
 
623
624
        if (RT_SUCCESS(rc2))
624
625
        {
625
 
            /*VBoxServiceVerbose(4, "ControlThread: [PID %u}: RTPollNoResume idPollHnd=%u\n",
 
626
            /*VBoxServiceVerbose(4, "[PID %u}: RTPollNoResume idPollHnd=%u\n",
626
627
                                 pThread->uPID, idPollHnd);*/
627
628
            switch (idPollHnd)
628
629
            {
656
657
        }
657
658
 
658
659
#if 0
659
 
        VBoxServiceVerbose(4, "ControlThread: [PID %u]: Polling done, pollRC=%Rrc, pollCnt=%u, rc=%Rrc, fShutdown=%RTbool\n",
 
660
        VBoxServiceVerbose(4, "[PID %u]: Polling done, pollRC=%Rrc, pollCnt=%u, rc=%Rrc, fShutdown=%RTbool\n",
660
661
                           pThread->uPID, rc2, RTPollSetGetCount(hPollSet), rc, pThread->fShutdown);
661
662
#endif
662
663
        /*
702
703
            uint64_t cMsElapsed = u64Now - MsStart;
703
704
            if (cMsElapsed >= cMsTimeout)
704
705
            {
705
 
                VBoxServiceVerbose(3, "ControlThread: [PID %u]: Timed out (%ums elapsed > %ums timeout), killing ...",
 
706
                VBoxServiceVerbose(3, "[PID %u]: Timed out (%ums elapsed > %ums timeout), killing ...",
706
707
                                   pThread->uPID, cMsElapsed, cMsTimeout);
707
708
 
708
709
                fProcessTimedOut = true;
751
752
    {
752
753
        if (MsProcessKilled == UINT64_MAX)
753
754
        {
754
 
            VBoxServiceVerbose(3, "ControlThread: [PID %u]: Is still alive and not killed yet\n",
 
755
            VBoxServiceVerbose(3, "[PID %u]: Is still alive and not killed yet\n",
755
756
                               pThread->uPID);
756
757
 
757
758
            MsProcessKilled = RTTimeMilliTS();
761
762
 
762
763
        for (size_t i = 0; i < 10; i++)
763
764
        {
764
 
            VBoxServiceVerbose(4, "ControlThread: [PID %u]: Kill attempt %d/10: Waiting to exit ...\n",
 
765
            VBoxServiceVerbose(4, "[PID %u]: Kill attempt %d/10: Waiting to exit ...\n",
765
766
                               pThread->uPID, i + 1);
766
767
            rc2 = RTProcWait(hProcess, RTPROCWAIT_FLAGS_NOBLOCK, &ProcessStatus);
767
768
            if (RT_SUCCESS(rc2))
768
769
            {
769
 
                VBoxServiceVerbose(4, "ControlThread: [PID %u]: Kill attempt %d/10: Exited\n",
 
770
                VBoxServiceVerbose(4, "[PID %u]: Kill attempt %d/10: Exited\n",
770
771
                                   pThread->uPID, i + 1);
771
772
                fProcessAlive = false;
772
773
                break;
773
774
            }
774
775
            if (i >= 5)
775
776
            {
776
 
                VBoxServiceVerbose(4, "ControlThread: [PID %u]: Kill attempt %d/10: Trying to terminate ...\n",
 
777
                VBoxServiceVerbose(4, "[PID %u]: Kill attempt %d/10: Trying to terminate ...\n",
777
778
                                   pThread->uPID, i + 1);
778
779
                RTProcTerminate(hProcess);
779
780
            }
781
782
        }
782
783
 
783
784
        if (fProcessAlive)
784
 
            VBoxServiceVerbose(3, "ControlThread: [PID %u]: Could not be killed\n", pThread->uPID);
 
785
            VBoxServiceVerbose(3, "[PID %u]: Could not be killed\n", pThread->uPID);
785
786
    }
786
787
 
787
788
    /*
795
796
 
796
797
        if (     fProcessTimedOut  && !fProcessAlive && MsProcessKilled != UINT64_MAX)
797
798
        {
798
 
            VBoxServiceVerbose(3, "ControlThread: [PID %u]: Timed out and got killed\n",
 
799
            VBoxServiceVerbose(3, "[PID %u]: Timed out and got killed\n",
799
800
                               pThread->uPID);
800
801
            uStatus = PROC_STS_TOK;
801
802
        }
802
803
        else if (fProcessTimedOut  &&  fProcessAlive && MsProcessKilled != UINT64_MAX)
803
804
        {
804
 
            VBoxServiceVerbose(3, "ControlThread: [PID %u]: Timed out and did *not* get killed\n",
 
805
            VBoxServiceVerbose(3, "[PID %u]: Timed out and did *not* get killed\n",
805
806
                               pThread->uPID);
806
807
            uStatus = PROC_STS_TOA;
807
808
        }
808
809
        else if (pThread->fShutdown && (fProcessAlive || MsProcessKilled != UINT64_MAX))
809
810
        {
810
 
            VBoxServiceVerbose(3, "ControlThread: [PID %u]: Got terminated because system/service is about to shutdown\n",
 
811
            VBoxServiceVerbose(3, "[PID %u]: Got terminated because system/service is about to shutdown\n",
811
812
                               pThread->uPID);
812
813
            uStatus = PROC_STS_DWN; /* Service is stopping, process was killed. */
813
814
            uFlags = pThread->uFlags; /* Return handed-in execution flags back to the host. */
814
815
        }
815
816
        else if (fProcessAlive)
816
817
        {
817
 
            VBoxServiceError("ControlThread: [PID %u]: Is alive when it should not!\n",
 
818
            VBoxServiceError("[PID %u]: Is alive when it should not!\n",
818
819
                             pThread->uPID);
819
820
        }
820
821
        else if (MsProcessKilled != UINT64_MAX)
821
822
        {
822
 
            VBoxServiceError("ControlThread: [PID %u]: Has been killed when it should not!\n",
 
823
            VBoxServiceError("[PID %u]: Has been killed when it should not!\n",
823
824
                             pThread->uPID);
824
825
        }
825
826
        else if (ProcessStatus.enmReason == RTPROCEXITREASON_NORMAL)
826
827
        {
827
 
            VBoxServiceVerbose(3, "ControlThread: [PID %u]: Ended with RTPROCEXITREASON_NORMAL (Exit code: %u)\n",
 
828
            VBoxServiceVerbose(3, "[PID %u]: Ended with RTPROCEXITREASON_NORMAL (Exit code: %u)\n",
828
829
                               pThread->uPID, ProcessStatus.iStatus);
829
830
 
830
831
            uStatus = PROC_STS_TEN;
832
833
        }
833
834
        else if (ProcessStatus.enmReason == RTPROCEXITREASON_SIGNAL)
834
835
        {
835
 
            VBoxServiceVerbose(3, "ControlThread: [PID %u]: Ended with RTPROCEXITREASON_SIGNAL (Signal: %u)\n",
 
836
            VBoxServiceVerbose(3, "[PID %u]: Ended with RTPROCEXITREASON_SIGNAL (Signal: %u)\n",
836
837
                               pThread->uPID, ProcessStatus.iStatus);
837
838
 
838
839
            uStatus = PROC_STS_TES;
841
842
        else if (ProcessStatus.enmReason == RTPROCEXITREASON_ABEND)
842
843
        {
843
844
            /* ProcessStatus.iStatus will be undefined. */
844
 
            VBoxServiceVerbose(3, "ControlThread: [PID %u]: Ended with RTPROCEXITREASON_ABEND\n",
 
845
            VBoxServiceVerbose(3, "[PID %u]: Ended with RTPROCEXITREASON_ABEND\n",
845
846
                               pThread->uPID);
846
847
 
847
848
            uStatus = PROC_STS_TEA;
848
849
            uFlags = ProcessStatus.iStatus;
849
850
        }
850
851
        else
851
 
            VBoxServiceVerbose(1, "ControlThread: [PID %u]: Handling process status %u not implemented\n",
 
852
            VBoxServiceVerbose(1, "[PID %u]: Handling process status %u not implemented\n",
852
853
                               pThread->uPID, ProcessStatus.enmReason);
853
854
 
854
 
        VBoxServiceVerbose(2, "ControlThread: [PID %u]: Ended, ClientID=%u, CID=%u, Status=%u, Flags=0x%x\n",
 
855
        VBoxServiceVerbose(2, "[PID %u]: Ended, ClientID=%u, CID=%u, Status=%u, Flags=0x%x\n",
855
856
                           pThread->uPID, pThread->uClientID, pThread->uContextID, uStatus, uFlags);
856
857
        rc = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID,
857
858
                                             pThread->uPID, uStatus, uFlags,
858
859
                                             NULL /* pvData */, 0 /* cbData */);
859
860
        if (RT_FAILURE(rc))
860
 
            VBoxServiceError("ControlThread: [PID %u]: Error reporting final status to host; rc=%Rrc\n",
 
861
            VBoxServiceError("[PID %u]: Error reporting final status to host; rc=%Rrc\n",
861
862
                             pThread->uPID, rc);
862
863
 
863
 
        VBoxServiceVerbose(3, "ControlThread: [PID %u]: Process loop ended with rc=%Rrc\n",
 
864
        VBoxServiceVerbose(3, "[PID %u]: Process loop ended with rc=%Rrc\n",
864
865
                           pThread->uPID, rc);
865
866
    }
866
867
    else
867
 
        VBoxServiceError("ControlThread: [PID %u]: Loop failed with rc=%Rrc\n",
 
868
        VBoxServiceError("[PID %u]: Loop failed with rc=%Rrc\n",
868
869
                         pThread->uPID, rc);
869
870
    return rc;
870
871
}
969
970
    if (!pReq) /* Silently skip non-initialized requests. */
970
971
        return VINF_SUCCESS;
971
972
 
972
 
    VBoxServiceVerbose(4, "ControlThread: Cancelling request=0x%p\n", pReq);
 
973
    VBoxServiceVerbose(4, "Cancelling request=0x%p\n", pReq);
973
974
 
974
975
    return RTSemEventMultiSignal(pReq->Event);
975
976
}
985
986
{
986
987
    AssertPtrReturnVoid(pReq);
987
988
 
988
 
    VBoxServiceVerbose(4, "ControlThread: Freeing request=0x%p (event=%RTsem)\n",
 
989
    VBoxServiceVerbose(4, "Freeing request=0x%p (event=%RTsem)\n",
989
990
                       pReq, &pReq->Event);
990
991
 
991
992
    int rc = RTSemEventMultiDestroy(pReq->Event);
1010
1011
    int rc = RTSemEventMultiWait(pReq->Event, RT_INDEFINITE_WAIT);
1011
1012
    if (RT_SUCCESS(rc))
1012
1013
    {
1013
 
        VBoxServiceVerbose(4, "ControlThread: Performed request with rc=%Rrc, cbData=%u\n",
 
1014
        VBoxServiceVerbose(4, "Performed request with rc=%Rrc, cbData=%u\n",
1014
1015
                           pReq->rc, pReq->cbData);
1015
1016
 
1016
1017
        /* Give back overall request result. */
1017
1018
        rc = pReq->rc;
1018
1019
    }
1019
1020
    else
1020
 
        VBoxServiceError("ControlThread: Waiting for request failed, rc=%Rrc\n", rc);
 
1021
        VBoxServiceError("Waiting for request failed, rc=%Rrc\n", rc);
1021
1022
 
1022
1023
    return rc;
1023
1024
}
1117
1118
    rc = RTStrCopy(pszExpanded, cbExpanded, pszPath);
1118
1119
#endif
1119
1120
#ifdef DEBUG
1120
 
    VBoxServiceVerbose(3, "ControlThread: VBoxServiceControlExecMakeFullPath: %s -> %s\n",
 
1121
    VBoxServiceVerbose(3, "VBoxServiceControlExecMakeFullPath: %s -> %s\n",
1121
1122
                       pszPath, pszExpanded);
1122
1123
#endif
1123
1124
    return rc;
1126
1127
 
1127
1128
/**
1128
1129
 * Resolves the full path of a specified executable name. This function also
1129
 
 * resolves internal VBoxService tools to its appropriate executable path + name.
 
1130
 * resolves internal VBoxService tools to its appropriate executable path + name if
 
1131
 * VBOXSERVICE_NAME is specified as pszFileName.
1130
1132
 *
1131
1133
 * @return  IPRT status code.
1132
 
 * @param   pszFileName                 File name to resovle.
 
1134
 * @param   pszFileName                 File name to resolve.
1133
1135
 * @param   pszResolved                 Pointer to a string where the resolved file name will be stored.
1134
1136
 * @param   cbResolved                  Size (in bytes) of resolved file name string.
1135
1137
 */
1136
1138
static int VBoxServiceControlThreadResolveExecutable(const char *pszFileName,
1137
1139
                                                     char *pszResolved, size_t cbResolved)
1138
1140
{
 
1141
    AssertPtrReturn(pszFileName, VERR_INVALID_POINTER);
 
1142
    AssertPtrReturn(pszResolved, VERR_INVALID_POINTER);
 
1143
    AssertReturn(cbResolved, VERR_INVALID_PARAMETER);
 
1144
 
1139
1145
    int rc = VINF_SUCCESS;
1140
1146
 
1141
 
    /* Search the path of our executable. */
1142
 
    char szVBoxService[RTPATH_MAX];
1143
 
    if (RTProcGetExecutablePath(szVBoxService, sizeof(szVBoxService)))
1144
 
    {
1145
 
        char *pszExecResolved = NULL;
1146
 
        if (   (g_pszProgName && RTStrICmp(pszFileName, g_pszProgName) == 0)
1147
 
            || !RTStrICmp(pszFileName, VBOXSERVICE_NAME))
1148
 
        {
1149
 
            /* We just want to execute VBoxService (no toolbox). */
1150
 
            pszExecResolved = RTStrDup(szVBoxService);
1151
 
        }
1152
 
        else /* Nothing to resolve, copy original. */
1153
 
            pszExecResolved = RTStrDup(pszFileName);
1154
 
        AssertPtr(pszExecResolved);
1155
 
 
1156
 
        rc = VBoxServiceControlThreadMakeFullPath(pszExecResolved, pszResolved, cbResolved);
1157
 
#ifdef DEBUG
1158
 
        VBoxServiceVerbose(3, "ControlThread: VBoxServiceControlExecResolveExecutable: %s -> %s\n",
1159
 
                           pszFileName, pszResolved);
1160
 
#endif
1161
 
        RTStrFree(pszExecResolved);
1162
 
    }
 
1147
    char szPathToResolve[RTPATH_MAX];
 
1148
    if (    (g_pszProgName && (RTStrICmp(pszFileName, g_pszProgName) == 0))
 
1149
        || !RTStrICmp(pszFileName, VBOXSERVICE_NAME))
 
1150
    {
 
1151
        /* Resolve executable name of this process. */
 
1152
        if (!RTProcGetExecutablePath(szPathToResolve, sizeof(szPathToResolve)))
 
1153
            rc = VERR_FILE_NOT_FOUND;
 
1154
    }
 
1155
    else
 
1156
    {
 
1157
        /* Take the raw argument to resolve. */
 
1158
        rc = RTStrCopy(szPathToResolve, sizeof(szPathToResolve), pszFileName);
 
1159
    }
 
1160
 
 
1161
    if (RT_SUCCESS(rc))
 
1162
    {
 
1163
        rc = VBoxServiceControlThreadMakeFullPath(szPathToResolve, pszResolved, cbResolved);
 
1164
        if (RT_SUCCESS(rc))
 
1165
            VBoxServiceVerbose(3, "Looked up executable: %s -> %s\n",
 
1166
                               pszFileName, pszResolved);
 
1167
    }
 
1168
 
 
1169
    if (RT_FAILURE(rc))
 
1170
        VBoxServiceError("Failed to lookup executable \"%s\" with rc=%Rrc\n",
 
1171
                         pszFileName, rc);
1163
1172
    return rc;
1164
1173
}
1165
1174
 
1169
1178
 * and relative paths.
1170
1179
 *
1171
1180
 * @return IPRT status code.
1172
 
 * @param  pszArgv0         First argument (argv0), either original or modified version.
 
1181
 * @param  pszArgv0         First argument (argv0), either original or modified version.  Optional.
1173
1182
 * @param  papszArgs        Original argv command line from the host, starting at argv[1].
1174
1183
 * @param  ppapszArgv       Pointer to a pointer with the new argv command line.
1175
1184
 *                          Needs to be freed with RTGetOptArgvFree.
1208
1217
                                    pszNewArgs ? pszNewArgs : "", NULL /* Use standard separators. */);
1209
1218
    }
1210
1219
 
 
1220
#ifdef DEBUG
 
1221
    VBoxServiceVerbose(3, "Arguments argv0=%s, new arguments=%s\n",
 
1222
                       pszArgv0 ? pszArgv0 : "<NULL>", pszNewArgs);
 
1223
#endif
 
1224
 
1211
1225
    if (pszNewArgs)
1212
1226
        RTStrFree(pszNewArgs);
1213
1227
    return rc;
1246
1260
     * (usually, if started by SCM) has administrator rights. Because of that a UI
1247
1261
     * won't be shown (doesn't have a desktop).
1248
1262
     */
1249
 
    if (RTStrICmp(pszExec, "sysprep") == 0)
 
1263
    if (!RTStrICmp(pszExec, "sysprep"))
1250
1264
    {
1251
1265
        /* Use a predefined sysprep path as default. */
1252
1266
        char szSysprepCmd[RTPATH_MAX] = "C:\\sysprep\\sysprep.exe";
1279
1293
                RTGetOptArgvFree(papszArgsExp);
1280
1294
            }
1281
1295
        }
 
1296
 
 
1297
        if (RT_FAILURE(rc))
 
1298
            VBoxServiceVerbose(3, "Starting sysprep returned rc=%Rrc\n", rc);
 
1299
 
1282
1300
        return rc;
1283
1301
    }
1284
1302
#endif /* RT_OS_WINDOWS */
1305
1323
        char **papszArgsExp;
1306
1324
        rc = VBoxServiceControlThreadPrepareArgv(pszExec /* Always use the unmodified executable name as argv0. */,
1307
1325
                                                 papszArgs /* Append the rest of the argument vector (if any). */, &papszArgsExp);
1308
 
        if (RT_SUCCESS(rc))
 
1326
        if (RT_FAILURE(rc))
 
1327
        {
 
1328
            /* Don't print any arguments -- may contain passwords or other sensible data! */
 
1329
            VBoxServiceError("Could not prepare arguments, rc=%Rrc\n", rc);
 
1330
        }
 
1331
        else
1309
1332
        {
1310
1333
            uint32_t uProcFlags = 0;
1311
1334
            if (fFlags)
1325
1348
            if (*pszAsUser)
1326
1349
                uProcFlags |= RTPROC_FLAGS_SERVICE;
1327
1350
#ifdef DEBUG
1328
 
            VBoxServiceVerbose(3, "ControlThread: Command: %s\n", szExecExp);
 
1351
            VBoxServiceVerbose(3, "Command: %s\n", szExecExp);
1329
1352
            for (size_t i = 0; papszArgsExp[i]; i++)
1330
 
                VBoxServiceVerbose(3, "ControlThread:\targv[%ld]: %s\n", i, papszArgsExp[i]);
 
1353
                VBoxServiceVerbose(3, "\targv[%ld]: %s\n", i, papszArgsExp[i]);
1331
1354
#endif
 
1355
            VBoxServiceVerbose(3, "Starting process \"%s\" ...\n", szExecExp);
 
1356
 
1332
1357
            /* Do normal execution. */
1333
1358
            rc = RTProcCreateEx(szExecExp, papszArgsExp, hEnv, uProcFlags,
1334
1359
                                phStdIn, phStdOut, phStdErr,
1335
1360
                                *pszAsUser   ? pszAsUser   : NULL,
1336
1361
                                *pszPassword ? pszPassword : NULL,
1337
1362
                                phProcess);
 
1363
 
 
1364
            VBoxServiceVerbose(3, "Starting process \"%s\" returned rc=%Rrc\n",
 
1365
                               szExecExp, rc);
 
1366
 
1338
1367
            RTGetOptArgvFree(papszArgsExp);
1339
1368
        }
1340
1369
    }
1350
1379
static int VBoxServiceControlThreadProcessWorker(PVBOXSERVICECTRLTHREAD pThread)
1351
1380
{
1352
1381
    AssertPtrReturn(pThread, VERR_INVALID_POINTER);
1353
 
    VBoxServiceVerbose(3, "ControlThread: Thread of process \"%s\" started\n", pThread->pszCmd);
 
1382
    VBoxServiceVerbose(3, "Thread of process pThread=0x%p = \"%s\" started\n",
 
1383
                       pThread, pThread->pszCmd);
1354
1384
 
1355
1385
    int rc = VBoxServiceControlListSet(VBOXSERVICECTRLTHREADLIST_RUNNING, pThread);
1356
1386
    AssertRC(rc);
1358
1388
    rc = VbglR3GuestCtrlConnect(&pThread->uClientID);
1359
1389
    if (RT_FAILURE(rc))
1360
1390
    {
1361
 
        VBoxServiceError("ControlThread: Thread failed to connect to the guest control service, aborted! Error: %Rrc\n", rc);
 
1391
        VBoxServiceError("Thread failed to connect to the guest control service, aborted! Error: %Rrc\n", rc);
1362
1392
        RTThreadUserSignal(RTThreadSelf());
1363
1393
        return rc;
1364
1394
    }
1365
 
    VBoxServiceVerbose(3, "ControlThread: Guest process \"%s\" got client ID=%u, flags=0x%x\n",
 
1395
    VBoxServiceVerbose(3, "Guest process \"%s\" got client ID=%u, flags=0x%x\n",
1366
1396
                       pThread->pszCmd, pThread->uClientID, pThread->uFlags);
1367
1397
 
1368
1398
    bool fSignalled = false; /* Indicator whether we signalled the thread user event already. */
1447
1477
                                                                           pThread->pszUser, pThread->pszPassword,
1448
1478
                                                                           &hProcess);
1449
1479
                                if (RT_FAILURE(rc))
1450
 
                                    VBoxServiceError("ControlThread: Error starting process, rc=%Rrc\n", rc);
 
1480
                                    VBoxServiceError("Error starting process, rc=%Rrc\n", rc);
1451
1481
                                /*
1452
1482
                                 * Tell the control thread that it can continue
1453
1483
                                 * spawning services. This needs to be done after the new
1534
1564
                                                  PROC_STS_ERROR, rc,
1535
1565
                                                  NULL /* pvData */, 0 /* cbData */);
1536
1566
            if (RT_FAILURE(rc2))
1537
 
                VBoxServiceError("ControlThread: Could not report process failure error; rc=%Rrc (process error %Rrc)\n",
 
1567
                VBoxServiceError("Could not report process failure error; rc=%Rrc (process error %Rrc)\n",
1538
1568
                                 rc2, rc);
1539
1569
        }
1540
1570
 
1541
 
        VBoxServiceVerbose(3, "ControlThread: [PID %u]: Cancelling pending host requests (client ID=%u)\n",
 
1571
        VBoxServiceVerbose(3, "[PID %u]: Cancelling pending host requests (client ID=%u)\n",
1542
1572
                           pThread->uPID, pThread->uClientID);
1543
1573
        rc2 = VbglR3GuestCtrlCancelPendingWaits(pThread->uClientID);
1544
1574
        if (RT_FAILURE(rc2))
1545
1575
        {
1546
 
            VBoxServiceError("ControlThread: [PID %u]: Cancelling pending host requests failed; rc=%Rrc\n",
 
1576
            VBoxServiceError("[PID %u]: Cancelling pending host requests failed; rc=%Rrc\n",
1547
1577
                             pThread->uPID, rc2);
1548
1578
            if (RT_SUCCESS(rc))
1549
1579
                rc = rc2;
1550
1580
        }
1551
1581
 
1552
1582
        /* Disconnect from guest control service. */
1553
 
        VBoxServiceVerbose(3, "ControlThread: [PID %u]: Disconnecting (client ID=%u) ...\n",
 
1583
        VBoxServiceVerbose(3, "[PID %u]: Disconnecting (client ID=%u) ...\n",
1554
1584
                           pThread->uPID, pThread->uClientID);
1555
1585
        VbglR3GuestCtrlDisconnect(pThread->uClientID);
1556
1586
        pThread->uClientID = 0;
1557
1587
    }
1558
1588
 
1559
 
    VBoxServiceVerbose(3, "ControlThread: [PID %u]: Thread of process \"%s\" ended with rc=%Rrc\n",
 
1589
    VBoxServiceVerbose(3, "[PID %u]: Thread of process \"%s\" ended with rc=%Rrc\n",
1560
1590
                       pThread->uPID, pThread->pszCmd, rc);
1561
1591
 
1562
1592
    /* Update started/stopped status. */
1621
1651
                             RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "gctl%u", s_uCtrlExecThread);
1622
1652
        if (RT_FAILURE(rc))
1623
1653
        {
1624
 
            VBoxServiceError("ControlThread: RTThreadCreate failed, rc=%Rrc\n, pThread=%p\n",
 
1654
            VBoxServiceError("RTThreadCreate failed, rc=%Rrc\n, pThread=%p\n",
1625
1655
                             rc, pThread);
1626
1656
        }
1627
1657
        else
1628
1658
        {
1629
 
            VBoxServiceVerbose(4, "ControlThread: Waiting for thread to initialize ...\n");
 
1659
            VBoxServiceVerbose(4, "Waiting for thread to initialize ...\n");
1630
1660
 
1631
1661
            /* Wait for the thread to initialize. */
1632
1662
            rc = RTThreadUserWait(pThread->Thread, 60 * 1000 /* 60 seconds max. */);
1634
1664
            if (   ASMAtomicReadBool(&pThread->fShutdown)
1635
1665
                || RT_FAILURE(rc))
1636
1666
            {
1637
 
                VBoxServiceError("ControlThread: Thread for process \"%s\" failed to start, rc=%Rrc\n",
 
1667
                VBoxServiceError("Thread for process \"%s\" failed to start, rc=%Rrc\n",
1638
1668
                                 pProcess->szCmd, rc);
1639
1669
            }
1640
1670
            else
1690
1720
            if (   RT_SUCCESS(rc)
1691
1721
                && cbWritten)
1692
1722
            {
1693
 
                VBoxServiceVerbose(3, "ControlThread: [PID %u]: Waiting for response on enmType=%u, pvData=0x%p, cbData=%u\n",
 
1723
                VBoxServiceVerbose(3, "[PID %u]: Waiting for response on enmType=%u, pvData=0x%p, cbData=%u\n",
1694
1724
                                   uPID, pRequest->enmType, pRequest->pvData, pRequest->cbData);
1695
1725
 
1696
1726
                rc = VBoxServiceControlThreadRequestWait(pRequest);
1702
1732
    else /* PID not found! */
1703
1733
        rc = VERR_NOT_FOUND;
1704
1734
 
1705
 
    VBoxServiceVerbose(3, "ControlThread: [PID %u]: Performed enmType=%u, uCID=%u, pvData=0x%p, cbData=%u, rc=%Rrc\n",
 
1735
    VBoxServiceVerbose(3, "[PID %u]: Performed enmType=%u, uCID=%u, pvData=0x%p, cbData=%u, rc=%Rrc\n",
1706
1736
                       uPID, pRequest->enmType, pRequest->uCID, pRequest->pvData, pRequest->cbData, rc);
1707
1737
    return rc;
1708
1738
}