summaryrefslogtreecommitdiff
path: root/src/VBox/Additions/common/VBoxService/VBoxServiceControlThread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Additions/common/VBoxService/VBoxServiceControlThread.cpp')
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceControlThread.cpp216
1 files changed, 123 insertions, 93 deletions
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceControlThread.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceControlThread.cpp
index 22a3bf549..62c6e5df0 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceControlThread.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceControlThread.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -151,7 +151,7 @@ int VBoxServiceControlThreadFree(PVBOXSERVICECTRLTHREAD pThread)
{
AssertPtrReturn(pThread, VERR_INVALID_POINTER);
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Freeing ...\n",
+ VBoxServiceVerbose(3, "[PID %u]: Freeing ...\n",
pThread->uPID);
int rc = RTCritSectEnter(&pThread->CritSect);
@@ -169,7 +169,7 @@ int VBoxServiceControlThreadFree(PVBOXSERVICECTRLTHREAD pThread)
RTStrFree(pThread->pszUser);
RTStrFree(pThread->pszPassword);
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Setting stopped state\n",
+ VBoxServiceVerbose(3, "[PID %u]: Setting stopped state\n",
pThread->uPID);
rc = RTCritSectLeave(&pThread->CritSect);
@@ -203,12 +203,12 @@ int VBoxServiceControlThreadStop(const PVBOXSERVICECTRLTHREAD pThread)
{
AssertPtrReturn(pThread, VERR_INVALID_POINTER);
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Stopping ...\n",
+ VBoxServiceVerbose(3, "[PID %u]: Stopping ...\n",
pThread->uPID);
int rc = vboxServiceControlThreadRequestCancel(pThread->pRequest);
if (RT_FAILURE(rc))
- VBoxServiceError("ControlThread: [PID %u]: Signalling request event failed, rc=%Rrc\n",
+ VBoxServiceError("[PID %u]: Signalling request event failed, rc=%Rrc\n",
pThread->uPID, rc);
/* Do *not* set pThread->fShutdown or other stuff here!
@@ -220,7 +220,7 @@ int VBoxServiceControlThreadStop(const PVBOXSERVICECTRLTHREAD pThread)
{
rc = VBoxServiceControlThreadPerform(pThread->uPID, pRequest);
if (RT_FAILURE(rc))
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Sending quit request failed with rc=%Rrc\n",
+ VBoxServiceVerbose(3, "[PID %u]: Sending quit request failed with rc=%Rrc\n",
pThread->uPID, rc);
VBoxServiceControlThreadRequestFree(pRequest);
@@ -235,34 +235,35 @@ int VBoxServiceControlThreadStop(const PVBOXSERVICECTRLTHREAD pThread)
* @return IPRT status code.
* @param pThread Thread to wait shutting down for.
* @param RTMSINTERVAL Timeout in ms to wait for shutdown.
+ * @param prc Where to store the thread's return code. Optional.
*/
int VBoxServiceControlThreadWait(const PVBOXSERVICECTRLTHREAD pThread,
- RTMSINTERVAL msTimeout)
+ RTMSINTERVAL msTimeout, int *prc)
{
AssertPtrReturn(pThread, VERR_INVALID_POINTER);
+ /* prc is optional. */
+
int rc = VINF_SUCCESS;
if ( pThread->Thread != NIL_RTTHREAD
&& ASMAtomicReadBool(&pThread->fStarted))
{
- VBoxServiceVerbose(2, "ControlThread: [PID %u]: Waiting for shutdown ...\n",
- pThread->uPID);
+ VBoxServiceVerbose(2, "[PID %u]: Waiting for shutdown of pThread=0x%p = \"%s\"...\n",
+ pThread->uPID, pThread, pThread->pszCmd);
/* Wait a bit ... */
int rcThread;
rc = RTThreadWait(pThread->Thread, msTimeout, &rcThread);
if (RT_FAILURE(rc))
{
- VBoxServiceError("ControlThread: [PID %u]: Waiting for shutting down thread returned error rc=%Rrc\n",
+ VBoxServiceError("[PID %u]: Waiting for shutting down thread returned error rc=%Rrc\n",
pThread->uPID, rc);
}
else
{
- if (RT_FAILURE(rcThread))
- {
- VBoxServiceError("ControlThread: [PID %u]: Shutdown returned error rc=%Rrc\n",
- pThread->uPID, rcThread);
- rc = rcThread;
- }
+ VBoxServiceVerbose(3, "[PID %u]: Thread reported exit code=%Rrc\n",
+ pThread->uPID, rcThread);
+ if (prc)
+ *prc = rcThread;
}
}
return rc;
@@ -327,7 +328,7 @@ static int VBoxServiceControlThreadHandleOutputError(RTPOLLSET hPollSet, uint32_
AssertPtrReturn(phPipeR, VERR_INVALID_POINTER);
#ifdef DEBUG
- VBoxServiceVerbose(4, "ControlThread: VBoxServiceControlThreadHandleOutputError: fPollEvt=0x%x, idPollHnd=%u\n",
+ VBoxServiceVerbose(4, "VBoxServiceControlThreadHandleOutputError: fPollEvt=0x%x, idPollHnd=%u\n",
fPollEvt, idPollHnd);
#endif
@@ -343,7 +344,7 @@ static int VBoxServiceControlThreadHandleOutputError(RTPOLLSET hPollSet, uint32_
if ( RT_SUCCESS(rc2)
&& cbReadable)
{
- VBoxServiceVerbose(3, "ControlThread: VBoxServiceControlThreadHandleOutputError: idPollHnd=%u has %ld bytes left, vetoing close\n",
+ VBoxServiceVerbose(3, "VBoxServiceControlThreadHandleOutputError: idPollHnd=%u has %ld bytes left, vetoing close\n",
idPollHnd, cbReadable);
/* Veto closing the pipe yet because there's still stuff to read
@@ -352,7 +353,7 @@ static int VBoxServiceControlThreadHandleOutputError(RTPOLLSET hPollSet, uint32_
fClosePipe = false;
}
else
- VBoxServiceVerbose(3, "ControlThread: VBoxServiceControlThreadHandleOutputError: idPollHnd=%u will be closed\n",
+ VBoxServiceVerbose(3, "VBoxServiceControlThreadHandleOutputError: idPollHnd=%u will be closed\n",
idPollHnd);
if ( *phPipeR != NIL_RTPIPE
@@ -381,7 +382,7 @@ static int VBoxServiceControlThreadHandleOutputEvent(RTPOLLSET hPollSet, uint32_
PRTPIPE phPipeR, uint32_t idPollHnd)
{
#if 0
- VBoxServiceVerbose(4, "ControlThread: VBoxServiceControlThreadHandleOutputEvent: fPollEvt=0x%x, idPollHnd=%u\n",
+ VBoxServiceVerbose(4, "VBoxServiceControlThreadHandleOutputEvent: fPollEvt=0x%x, idPollHnd=%u\n",
fPollEvt, idPollHnd);
#endif
@@ -393,7 +394,7 @@ static int VBoxServiceControlThreadHandleOutputEvent(RTPOLLSET hPollSet, uint32_
if ( RT_SUCCESS(rc)
&& cbReadable)
{
- VBoxServiceVerbose(4, "ControlThread: VBoxServiceControlThreadHandleOutputEvent: cbReadable=%ld\n",
+ VBoxServiceVerbose(4, "VBoxServiceControlThreadHandleOutputEvent: cbReadable=%ld\n",
cbReadable);
}
#endif
@@ -405,7 +406,7 @@ static int VBoxServiceControlThreadHandleOutputEvent(RTPOLLSET hPollSet, uint32_
uint8_t byData[_64K];
rc = RTPipeRead(*phPipeR,
byData, sizeof(byData), &cbRead);
- VBoxServiceVerbose(4, "ControlThread: VBoxServiceControlThreadHandleOutputEvent cbRead=%u, rc=%Rrc\n",
+ VBoxServiceVerbose(4, "VBoxServiceControlThreadHandleOutputEvent cbRead=%u, rc=%Rrc\n",
cbRead, rc);
/* Make sure we go another poll round in case there was too much data
@@ -435,14 +436,14 @@ static int VBoxServiceControlThreadHandleRequest(RTPOLLSET hPollSet, uint32_t fP
size_t cbIgnore;
int rc = RTPipeRead(pThread->hNotificationPipeR, abBuf, sizeof(abBuf), &cbIgnore);
if (RT_FAILURE(rc))
- VBoxServiceError("ControlThread: Draining IPC notification pipe failed with rc=%Rrc\n", rc);
+ VBoxServiceError("Draining IPC notification pipe failed with rc=%Rrc\n", rc);
int rcReq = VINF_SUCCESS; /* Actual request result. */
PVBOXSERVICECTRLREQUEST pRequest = pThread->pRequest;
if (!pRequest)
{
- VBoxServiceError("ControlThread: IPC request is invalid\n");
+ VBoxServiceError("IPC request is invalid\n");
return VERR_INVALID_POINTER;
}
@@ -531,7 +532,7 @@ static int VBoxServiceControlThreadHandleRequest(RTPOLLSET hPollSet, uint32_t fP
pRequest->rc = RT_SUCCESS(rc)
? rcReq : rc;
- VBoxServiceVerbose(2, "ControlThread: [PID %u]: Handled req=%u, CID=%u, rc=%Rrc, cbData=%u\n",
+ VBoxServiceVerbose(2, "[PID %u]: Handled req=%u, CID=%u, rc=%Rrc, cbData=%u\n",
pThread->uPID, pRequest->enmType, pRequest->uCID, pRequest->rc, pRequest->cbData);
/* In any case, regardless of the result, we notify
@@ -588,7 +589,7 @@ static int VBoxServiceControlThreadProcLoop(PVBOXSERVICECTRLTHREAD pThread,
rc = VBoxServiceControlAssignPID(pThread, hProcess);
if (RT_FAILURE(rc))
{
- VBoxServiceError("ControlThread: Unable to assign PID=%u, to new thread, rc=%Rrc\n",
+ VBoxServiceError("Unable to assign PID=%u, to new thread, rc=%Rrc\n",
hProcess, rc);
return rc;
}
@@ -597,7 +598,7 @@ static int VBoxServiceControlThreadProcLoop(PVBOXSERVICECTRLTHREAD pThread,
* Before entering the loop, tell the host that we've started the guest
* and that it's now OK to send input to the process.
*/
- VBoxServiceVerbose(2, "ControlThread: [PID %u]: Process \"%s\" started, CID=%u, User=%s\n",
+ VBoxServiceVerbose(2, "[PID %u]: Process \"%s\" started, CID=%u, User=%s\n",
pThread->uPID, pThread->pszCmd, pThread->uContextID, pThread->pszUser);
rc = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID,
pThread->uPID, PROC_STS_STARTED, 0 /* u32Flags */,
@@ -622,7 +623,7 @@ static int VBoxServiceControlThreadProcLoop(PVBOXSERVICECTRLTHREAD pThread,
if (RT_SUCCESS(rc2))
{
- /*VBoxServiceVerbose(4, "ControlThread: [PID %u}: RTPollNoResume idPollHnd=%u\n",
+ /*VBoxServiceVerbose(4, "[PID %u}: RTPollNoResume idPollHnd=%u\n",
pThread->uPID, idPollHnd);*/
switch (idPollHnd)
{
@@ -656,7 +657,7 @@ static int VBoxServiceControlThreadProcLoop(PVBOXSERVICECTRLTHREAD pThread,
}
#if 0
- VBoxServiceVerbose(4, "ControlThread: [PID %u]: Polling done, pollRC=%Rrc, pollCnt=%u, rc=%Rrc, fShutdown=%RTbool\n",
+ VBoxServiceVerbose(4, "[PID %u]: Polling done, pollRC=%Rrc, pollCnt=%u, rc=%Rrc, fShutdown=%RTbool\n",
pThread->uPID, rc2, RTPollSetGetCount(hPollSet), rc, pThread->fShutdown);
#endif
/*
@@ -702,7 +703,7 @@ static int VBoxServiceControlThreadProcLoop(PVBOXSERVICECTRLTHREAD pThread,
uint64_t cMsElapsed = u64Now - MsStart;
if (cMsElapsed >= cMsTimeout)
{
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Timed out (%ums elapsed > %ums timeout), killing ...",
+ VBoxServiceVerbose(3, "[PID %u]: Timed out (%ums elapsed > %ums timeout), killing ...",
pThread->uPID, cMsElapsed, cMsTimeout);
fProcessTimedOut = true;
@@ -751,7 +752,7 @@ static int VBoxServiceControlThreadProcLoop(PVBOXSERVICECTRLTHREAD pThread,
{
if (MsProcessKilled == UINT64_MAX)
{
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Is still alive and not killed yet\n",
+ VBoxServiceVerbose(3, "[PID %u]: Is still alive and not killed yet\n",
pThread->uPID);
MsProcessKilled = RTTimeMilliTS();
@@ -761,19 +762,19 @@ static int VBoxServiceControlThreadProcLoop(PVBOXSERVICECTRLTHREAD pThread,
for (size_t i = 0; i < 10; i++)
{
- VBoxServiceVerbose(4, "ControlThread: [PID %u]: Kill attempt %d/10: Waiting to exit ...\n",
+ VBoxServiceVerbose(4, "[PID %u]: Kill attempt %d/10: Waiting to exit ...\n",
pThread->uPID, i + 1);
rc2 = RTProcWait(hProcess, RTPROCWAIT_FLAGS_NOBLOCK, &ProcessStatus);
if (RT_SUCCESS(rc2))
{
- VBoxServiceVerbose(4, "ControlThread: [PID %u]: Kill attempt %d/10: Exited\n",
+ VBoxServiceVerbose(4, "[PID %u]: Kill attempt %d/10: Exited\n",
pThread->uPID, i + 1);
fProcessAlive = false;
break;
}
if (i >= 5)
{
- VBoxServiceVerbose(4, "ControlThread: [PID %u]: Kill attempt %d/10: Trying to terminate ...\n",
+ VBoxServiceVerbose(4, "[PID %u]: Kill attempt %d/10: Trying to terminate ...\n",
pThread->uPID, i + 1);
RTProcTerminate(hProcess);
}
@@ -781,7 +782,7 @@ static int VBoxServiceControlThreadProcLoop(PVBOXSERVICECTRLTHREAD pThread,
}
if (fProcessAlive)
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Could not be killed\n", pThread->uPID);
+ VBoxServiceVerbose(3, "[PID %u]: Could not be killed\n", pThread->uPID);
}
/*
@@ -795,36 +796,36 @@ static int VBoxServiceControlThreadProcLoop(PVBOXSERVICECTRLTHREAD pThread,
if ( fProcessTimedOut && !fProcessAlive && MsProcessKilled != UINT64_MAX)
{
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Timed out and got killed\n",
+ VBoxServiceVerbose(3, "[PID %u]: Timed out and got killed\n",
pThread->uPID);
uStatus = PROC_STS_TOK;
}
else if (fProcessTimedOut && fProcessAlive && MsProcessKilled != UINT64_MAX)
{
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Timed out and did *not* get killed\n",
+ VBoxServiceVerbose(3, "[PID %u]: Timed out and did *not* get killed\n",
pThread->uPID);
uStatus = PROC_STS_TOA;
}
else if (pThread->fShutdown && (fProcessAlive || MsProcessKilled != UINT64_MAX))
{
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Got terminated because system/service is about to shutdown\n",
+ VBoxServiceVerbose(3, "[PID %u]: Got terminated because system/service is about to shutdown\n",
pThread->uPID);
uStatus = PROC_STS_DWN; /* Service is stopping, process was killed. */
uFlags = pThread->uFlags; /* Return handed-in execution flags back to the host. */
}
else if (fProcessAlive)
{
- VBoxServiceError("ControlThread: [PID %u]: Is alive when it should not!\n",
+ VBoxServiceError("[PID %u]: Is alive when it should not!\n",
pThread->uPID);
}
else if (MsProcessKilled != UINT64_MAX)
{
- VBoxServiceError("ControlThread: [PID %u]: Has been killed when it should not!\n",
+ VBoxServiceError("[PID %u]: Has been killed when it should not!\n",
pThread->uPID);
}
else if (ProcessStatus.enmReason == RTPROCEXITREASON_NORMAL)
{
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Ended with RTPROCEXITREASON_NORMAL (Exit code: %u)\n",
+ VBoxServiceVerbose(3, "[PID %u]: Ended with RTPROCEXITREASON_NORMAL (Exit code: %u)\n",
pThread->uPID, ProcessStatus.iStatus);
uStatus = PROC_STS_TEN;
@@ -832,7 +833,7 @@ static int VBoxServiceControlThreadProcLoop(PVBOXSERVICECTRLTHREAD pThread,
}
else if (ProcessStatus.enmReason == RTPROCEXITREASON_SIGNAL)
{
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Ended with RTPROCEXITREASON_SIGNAL (Signal: %u)\n",
+ VBoxServiceVerbose(3, "[PID %u]: Ended with RTPROCEXITREASON_SIGNAL (Signal: %u)\n",
pThread->uPID, ProcessStatus.iStatus);
uStatus = PROC_STS_TES;
@@ -841,30 +842,30 @@ static int VBoxServiceControlThreadProcLoop(PVBOXSERVICECTRLTHREAD pThread,
else if (ProcessStatus.enmReason == RTPROCEXITREASON_ABEND)
{
/* ProcessStatus.iStatus will be undefined. */
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Ended with RTPROCEXITREASON_ABEND\n",
+ VBoxServiceVerbose(3, "[PID %u]: Ended with RTPROCEXITREASON_ABEND\n",
pThread->uPID);
uStatus = PROC_STS_TEA;
uFlags = ProcessStatus.iStatus;
}
else
- VBoxServiceVerbose(1, "ControlThread: [PID %u]: Handling process status %u not implemented\n",
+ VBoxServiceVerbose(1, "[PID %u]: Handling process status %u not implemented\n",
pThread->uPID, ProcessStatus.enmReason);
- VBoxServiceVerbose(2, "ControlThread: [PID %u]: Ended, ClientID=%u, CID=%u, Status=%u, Flags=0x%x\n",
+ VBoxServiceVerbose(2, "[PID %u]: Ended, ClientID=%u, CID=%u, Status=%u, Flags=0x%x\n",
pThread->uPID, pThread->uClientID, pThread->uContextID, uStatus, uFlags);
rc = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID,
pThread->uPID, uStatus, uFlags,
NULL /* pvData */, 0 /* cbData */);
if (RT_FAILURE(rc))
- VBoxServiceError("ControlThread: [PID %u]: Error reporting final status to host; rc=%Rrc\n",
+ VBoxServiceError("[PID %u]: Error reporting final status to host; rc=%Rrc\n",
pThread->uPID, rc);
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Process loop ended with rc=%Rrc\n",
+ VBoxServiceVerbose(3, "[PID %u]: Process loop ended with rc=%Rrc\n",
pThread->uPID, rc);
}
else
- VBoxServiceError("ControlThread: [PID %u]: Loop failed with rc=%Rrc\n",
+ VBoxServiceError("[PID %u]: Loop failed with rc=%Rrc\n",
pThread->uPID, rc);
return rc;
}
@@ -969,7 +970,7 @@ static int vboxServiceControlThreadRequestCancel(PVBOXSERVICECTRLREQUEST pReq)
if (!pReq) /* Silently skip non-initialized requests. */
return VINF_SUCCESS;
- VBoxServiceVerbose(4, "ControlThread: Cancelling request=0x%p\n", pReq);
+ VBoxServiceVerbose(4, "Cancelling request=0x%p\n", pReq);
return RTSemEventMultiSignal(pReq->Event);
}
@@ -985,7 +986,7 @@ void VBoxServiceControlThreadRequestFree(PVBOXSERVICECTRLREQUEST pReq)
{
AssertPtrReturnVoid(pReq);
- VBoxServiceVerbose(4, "ControlThread: Freeing request=0x%p (event=%RTsem)\n",
+ VBoxServiceVerbose(4, "Freeing request=0x%p (event=%RTsem)\n",
pReq, &pReq->Event);
int rc = RTSemEventMultiDestroy(pReq->Event);
@@ -1010,14 +1011,14 @@ int VBoxServiceControlThreadRequestWait(PVBOXSERVICECTRLREQUEST pReq)
int rc = RTSemEventMultiWait(pReq->Event, RT_INDEFINITE_WAIT);
if (RT_SUCCESS(rc))
{
- VBoxServiceVerbose(4, "ControlThread: Performed request with rc=%Rrc, cbData=%u\n",
+ VBoxServiceVerbose(4, "Performed request with rc=%Rrc, cbData=%u\n",
pReq->rc, pReq->cbData);
/* Give back overall request result. */
rc = pReq->rc;
}
else
- VBoxServiceError("ControlThread: Waiting for request failed, rc=%Rrc\n", rc);
+ VBoxServiceError("Waiting for request failed, rc=%Rrc\n", rc);
return rc;
}
@@ -1117,7 +1118,7 @@ static int VBoxServiceControlThreadMakeFullPath(const char *pszPath, char *pszEx
rc = RTStrCopy(pszExpanded, cbExpanded, pszPath);
#endif
#ifdef DEBUG
- VBoxServiceVerbose(3, "ControlThread: VBoxServiceControlExecMakeFullPath: %s -> %s\n",
+ VBoxServiceVerbose(3, "VBoxServiceControlExecMakeFullPath: %s -> %s\n",
pszPath, pszExpanded);
#endif
return rc;
@@ -1126,40 +1127,48 @@ static int VBoxServiceControlThreadMakeFullPath(const char *pszPath, char *pszEx
/**
* Resolves the full path of a specified executable name. This function also
- * resolves internal VBoxService tools to its appropriate executable path + name.
+ * resolves internal VBoxService tools to its appropriate executable path + name if
+ * VBOXSERVICE_NAME is specified as pszFileName.
*
* @return IPRT status code.
- * @param pszFileName File name to resovle.
+ * @param pszFileName File name to resolve.
* @param pszResolved Pointer to a string where the resolved file name will be stored.
* @param cbResolved Size (in bytes) of resolved file name string.
*/
static int VBoxServiceControlThreadResolveExecutable(const char *pszFileName,
char *pszResolved, size_t cbResolved)
{
+ AssertPtrReturn(pszFileName, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszResolved, VERR_INVALID_POINTER);
+ AssertReturn(cbResolved, VERR_INVALID_PARAMETER);
+
int rc = VINF_SUCCESS;
- /* Search the path of our executable. */
- char szVBoxService[RTPATH_MAX];
- if (RTProcGetExecutablePath(szVBoxService, sizeof(szVBoxService)))
+ char szPathToResolve[RTPATH_MAX];
+ if ( (g_pszProgName && (RTStrICmp(pszFileName, g_pszProgName) == 0))
+ || !RTStrICmp(pszFileName, VBOXSERVICE_NAME))
{
- char *pszExecResolved = NULL;
- if ( (g_pszProgName && RTStrICmp(pszFileName, g_pszProgName) == 0)
- || !RTStrICmp(pszFileName, VBOXSERVICE_NAME))
- {
- /* We just want to execute VBoxService (no toolbox). */
- pszExecResolved = RTStrDup(szVBoxService);
- }
- else /* Nothing to resolve, copy original. */
- pszExecResolved = RTStrDup(pszFileName);
- AssertPtr(pszExecResolved);
+ /* Resolve executable name of this process. */
+ if (!RTProcGetExecutablePath(szPathToResolve, sizeof(szPathToResolve)))
+ rc = VERR_FILE_NOT_FOUND;
+ }
+ else
+ {
+ /* Take the raw argument to resolve. */
+ rc = RTStrCopy(szPathToResolve, sizeof(szPathToResolve), pszFileName);
+ }
- rc = VBoxServiceControlThreadMakeFullPath(pszExecResolved, pszResolved, cbResolved);
-#ifdef DEBUG
- VBoxServiceVerbose(3, "ControlThread: VBoxServiceControlExecResolveExecutable: %s -> %s\n",
- pszFileName, pszResolved);
-#endif
- RTStrFree(pszExecResolved);
+ if (RT_SUCCESS(rc))
+ {
+ rc = VBoxServiceControlThreadMakeFullPath(szPathToResolve, pszResolved, cbResolved);
+ if (RT_SUCCESS(rc))
+ VBoxServiceVerbose(3, "Looked up executable: %s -> %s\n",
+ pszFileName, pszResolved);
}
+
+ if (RT_FAILURE(rc))
+ VBoxServiceError("Failed to lookup executable \"%s\" with rc=%Rrc\n",
+ pszFileName, rc);
return rc;
}
@@ -1169,7 +1178,7 @@ static int VBoxServiceControlThreadResolveExecutable(const char *pszFileName,
* and relative paths.
*
* @return IPRT status code.
- * @param pszArgv0 First argument (argv0), either original or modified version.
+ * @param pszArgv0 First argument (argv0), either original or modified version. Optional.
* @param papszArgs Original argv command line from the host, starting at argv[1].
* @param ppapszArgv Pointer to a pointer with the new argv command line.
* Needs to be freed with RTGetOptArgvFree.
@@ -1208,6 +1217,11 @@ static int VBoxServiceControlThreadPrepareArgv(const char *pszArgv0,
pszNewArgs ? pszNewArgs : "", NULL /* Use standard separators. */);
}
+#ifdef DEBUG
+ VBoxServiceVerbose(3, "Arguments argv0=%s, new arguments=%s\n",
+ pszArgv0 ? pszArgv0 : "<NULL>", pszNewArgs);
+#endif
+
if (pszNewArgs)
RTStrFree(pszNewArgs);
return rc;
@@ -1246,7 +1260,7 @@ static int VBoxServiceControlThreadCreateProcess(const char *pszExec, const char
* (usually, if started by SCM) has administrator rights. Because of that a UI
* won't be shown (doesn't have a desktop).
*/
- if (RTStrICmp(pszExec, "sysprep") == 0)
+ if (!RTStrICmp(pszExec, "sysprep"))
{
/* Use a predefined sysprep path as default. */
char szSysprepCmd[RTPATH_MAX] = "C:\\sysprep\\sysprep.exe";
@@ -1279,6 +1293,10 @@ static int VBoxServiceControlThreadCreateProcess(const char *pszExec, const char
RTGetOptArgvFree(papszArgsExp);
}
}
+
+ if (RT_FAILURE(rc))
+ VBoxServiceVerbose(3, "Starting sysprep returned rc=%Rrc\n", rc);
+
return rc;
}
#endif /* RT_OS_WINDOWS */
@@ -1305,7 +1323,12 @@ static int VBoxServiceControlThreadCreateProcess(const char *pszExec, const char
char **papszArgsExp;
rc = VBoxServiceControlThreadPrepareArgv(pszExec /* Always use the unmodified executable name as argv0. */,
papszArgs /* Append the rest of the argument vector (if any). */, &papszArgsExp);
- if (RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
+ {
+ /* Don't print any arguments -- may contain passwords or other sensible data! */
+ VBoxServiceError("Could not prepare arguments, rc=%Rrc\n", rc);
+ }
+ else
{
uint32_t uProcFlags = 0;
if (fFlags)
@@ -1325,16 +1348,22 @@ static int VBoxServiceControlThreadCreateProcess(const char *pszExec, const char
if (*pszAsUser)
uProcFlags |= RTPROC_FLAGS_SERVICE;
#ifdef DEBUG
- VBoxServiceVerbose(3, "ControlThread: Command: %s\n", szExecExp);
+ VBoxServiceVerbose(3, "Command: %s\n", szExecExp);
for (size_t i = 0; papszArgsExp[i]; i++)
- VBoxServiceVerbose(3, "ControlThread:\targv[%ld]: %s\n", i, papszArgsExp[i]);
+ VBoxServiceVerbose(3, "\targv[%ld]: %s\n", i, papszArgsExp[i]);
#endif
+ VBoxServiceVerbose(3, "Starting process \"%s\" ...\n", szExecExp);
+
/* Do normal execution. */
rc = RTProcCreateEx(szExecExp, papszArgsExp, hEnv, uProcFlags,
phStdIn, phStdOut, phStdErr,
*pszAsUser ? pszAsUser : NULL,
*pszPassword ? pszPassword : NULL,
phProcess);
+
+ VBoxServiceVerbose(3, "Starting process \"%s\" returned rc=%Rrc\n",
+ szExecExp, rc);
+
RTGetOptArgvFree(papszArgsExp);
}
}
@@ -1350,7 +1379,8 @@ static int VBoxServiceControlThreadCreateProcess(const char *pszExec, const char
static int VBoxServiceControlThreadProcessWorker(PVBOXSERVICECTRLTHREAD pThread)
{
AssertPtrReturn(pThread, VERR_INVALID_POINTER);
- VBoxServiceVerbose(3, "ControlThread: Thread of process \"%s\" started\n", pThread->pszCmd);
+ VBoxServiceVerbose(3, "Thread of process pThread=0x%p = \"%s\" started\n",
+ pThread, pThread->pszCmd);
int rc = VBoxServiceControlListSet(VBOXSERVICECTRLTHREADLIST_RUNNING, pThread);
AssertRC(rc);
@@ -1358,11 +1388,11 @@ static int VBoxServiceControlThreadProcessWorker(PVBOXSERVICECTRLTHREAD pThread)
rc = VbglR3GuestCtrlConnect(&pThread->uClientID);
if (RT_FAILURE(rc))
{
- VBoxServiceError("ControlThread: Thread failed to connect to the guest control service, aborted! Error: %Rrc\n", rc);
+ VBoxServiceError("Thread failed to connect to the guest control service, aborted! Error: %Rrc\n", rc);
RTThreadUserSignal(RTThreadSelf());
return rc;
}
- VBoxServiceVerbose(3, "ControlThread: Guest process \"%s\" got client ID=%u, flags=0x%x\n",
+ VBoxServiceVerbose(3, "Guest process \"%s\" got client ID=%u, flags=0x%x\n",
pThread->pszCmd, pThread->uClientID, pThread->uFlags);
bool fSignalled = false; /* Indicator whether we signalled the thread user event already. */
@@ -1447,7 +1477,7 @@ static int VBoxServiceControlThreadProcessWorker(PVBOXSERVICECTRLTHREAD pThread)
pThread->pszUser, pThread->pszPassword,
&hProcess);
if (RT_FAILURE(rc))
- VBoxServiceError("ControlThread: Error starting process, rc=%Rrc\n", rc);
+ VBoxServiceError("Error starting process, rc=%Rrc\n", rc);
/*
* Tell the control thread that it can continue
* spawning services. This needs to be done after the new
@@ -1534,29 +1564,29 @@ static int VBoxServiceControlThreadProcessWorker(PVBOXSERVICECTRLTHREAD pThread)
PROC_STS_ERROR, rc,
NULL /* pvData */, 0 /* cbData */);
if (RT_FAILURE(rc2))
- VBoxServiceError("ControlThread: Could not report process failure error; rc=%Rrc (process error %Rrc)\n",
+ VBoxServiceError("Could not report process failure error; rc=%Rrc (process error %Rrc)\n",
rc2, rc);
}
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Cancelling pending host requests (client ID=%u)\n",
+ VBoxServiceVerbose(3, "[PID %u]: Cancelling pending host requests (client ID=%u)\n",
pThread->uPID, pThread->uClientID);
rc2 = VbglR3GuestCtrlCancelPendingWaits(pThread->uClientID);
if (RT_FAILURE(rc2))
{
- VBoxServiceError("ControlThread: [PID %u]: Cancelling pending host requests failed; rc=%Rrc\n",
+ VBoxServiceError("[PID %u]: Cancelling pending host requests failed; rc=%Rrc\n",
pThread->uPID, rc2);
if (RT_SUCCESS(rc))
rc = rc2;
}
/* Disconnect from guest control service. */
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Disconnecting (client ID=%u) ...\n",
+ VBoxServiceVerbose(3, "[PID %u]: Disconnecting (client ID=%u) ...\n",
pThread->uPID, pThread->uClientID);
VbglR3GuestCtrlDisconnect(pThread->uClientID);
pThread->uClientID = 0;
}
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Thread of process \"%s\" ended with rc=%Rrc\n",
+ VBoxServiceVerbose(3, "[PID %u]: Thread of process \"%s\" ended with rc=%Rrc\n",
pThread->uPID, pThread->pszCmd, rc);
/* Update started/stopped status. */
@@ -1621,12 +1651,12 @@ int VBoxServiceControlThreadStart(uint32_t uContextID,
RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "gctl%u", s_uCtrlExecThread);
if (RT_FAILURE(rc))
{
- VBoxServiceError("ControlThread: RTThreadCreate failed, rc=%Rrc\n, pThread=%p\n",
+ VBoxServiceError("RTThreadCreate failed, rc=%Rrc\n, pThread=%p\n",
rc, pThread);
}
else
{
- VBoxServiceVerbose(4, "ControlThread: Waiting for thread to initialize ...\n");
+ VBoxServiceVerbose(4, "Waiting for thread to initialize ...\n");
/* Wait for the thread to initialize. */
rc = RTThreadUserWait(pThread->Thread, 60 * 1000 /* 60 seconds max. */);
@@ -1634,7 +1664,7 @@ int VBoxServiceControlThreadStart(uint32_t uContextID,
if ( ASMAtomicReadBool(&pThread->fShutdown)
|| RT_FAILURE(rc))
{
- VBoxServiceError("ControlThread: Thread for process \"%s\" failed to start, rc=%Rrc\n",
+ VBoxServiceError("Thread for process \"%s\" failed to start, rc=%Rrc\n",
pProcess->szCmd, rc);
}
else
@@ -1690,7 +1720,7 @@ int VBoxServiceControlThreadPerform(uint32_t uPID, PVBOXSERVICECTRLREQUEST pRequ
if ( RT_SUCCESS(rc)
&& cbWritten)
{
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Waiting for response on enmType=%u, pvData=0x%p, cbData=%u\n",
+ VBoxServiceVerbose(3, "[PID %u]: Waiting for response on enmType=%u, pvData=0x%p, cbData=%u\n",
uPID, pRequest->enmType, pRequest->pvData, pRequest->cbData);
rc = VBoxServiceControlThreadRequestWait(pRequest);
@@ -1702,7 +1732,7 @@ int VBoxServiceControlThreadPerform(uint32_t uPID, PVBOXSERVICECTRLREQUEST pRequ
else /* PID not found! */
rc = VERR_NOT_FOUND;
- VBoxServiceVerbose(3, "ControlThread: [PID %u]: Performed enmType=%u, uCID=%u, pvData=0x%p, cbData=%u, rc=%Rrc\n",
+ VBoxServiceVerbose(3, "[PID %u]: Performed enmType=%u, uCID=%u, pvData=0x%p, cbData=%u, rc=%Rrc\n",
uPID, pRequest->enmType, pRequest->uCID, pRequest->pvData, pRequest->cbData, rc);
return rc;
}