462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/* $Id$ */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/** @file
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * VBoxServiceControlSession - Guest session handling. Also handles
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * the forked session processes.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/*
026b1e278173a87acfffc3dd69c71766b7259b5evboxsync * Copyright (C) 2013-2014 Oracle Corporation
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync *
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * available from http://www.virtualbox.org. This file is free software;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * you can redistribute it and/or modify it under the terms of the GNU
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * General Public License (GPL) as published by the Free Software
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/*******************************************************************************
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync* Header Files *
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync*******************************************************************************/
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync#include <iprt/asm.h>
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#include <iprt/assert.h>
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync#include <iprt/dir.h>
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#include <iprt/env.h>
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#include <iprt/file.h>
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#include <iprt/getopt.h>
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#include <iprt/handle.h>
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#include <iprt/mem.h>
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#include <iprt/message.h>
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#include <iprt/path.h>
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#include <iprt/pipe.h>
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#include <iprt/poll.h>
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#include <iprt/process.h>
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#include "VBoxServiceInternal.h"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#include "VBoxServiceUtils.h"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#include "VBoxServiceControl.h"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncusing namespace guestControl;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync/*******************************************************************************
4260648b018894247c6a73e244050be76c28f857vboxsync* Externals *
4260648b018894247c6a73e244050be76c28f857vboxsync*******************************************************************************/
4260648b018894247c6a73e244050be76c28f857vboxsyncextern RTLISTANCHOR g_lstControlSessionThreads;
4260648b018894247c6a73e244050be76c28f857vboxsyncextern VBOXSERVICECTRLSESSION g_Session;
4260648b018894247c6a73e244050be76c28f857vboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncextern int VBoxServiceLogCreate(const char *pszLogFile);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncextern void VBoxServiceLogDestroy(void);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/*******************************************************************************
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync* Internal Functions *
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync*******************************************************************************/
248c89033c87fed7229aa29bbbc4f4698fb13687vboxsyncstatic int gstcntlSessionFileDestroy(PVBOXSERVICECTRLFILE pFile);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsyncstatic int gstcntlSessionFileAdd(PVBOXSERVICECTRLSESSION pSession, PVBOXSERVICECTRLFILE pFile);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsyncstatic PVBOXSERVICECTRLFILE gstcntlSessionFileGetLocked(const PVBOXSERVICECTRLSESSION pSession, uint32_t uHandle);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsyncstatic DECLCALLBACK(int) gstcntlSessionThread(RTTHREAD ThreadSelf, void *pvUser);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync/* Host -> Guest handlers. */
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsyncstatic int gstcntlSessionHandleDirRemove(PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsyncstatic int gstcntlSessionHandleFileOpen(PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsyncstatic int gstcntlSessionHandleFileClose(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsyncstatic int gstcntlSessionHandleFileRead(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsyncstatic int gstcntlSessionHandleFileWrite(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx, void *pvScratchBuf, size_t cbScratchBuf);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsyncstatic int gstcntlSessionHandleFileSeek(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsyncstatic int gstcntlSessionHandleFileTell(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsyncstatic int gstcntlSessionHandlePathRename(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsyncstatic int gstcntlSessionHandleProcExec(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsyncstatic int gstcntlSessionHandleProcInput(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx, void *pvScratchBuf, size_t cbScratchBuf);
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsyncstatic int gstcntlSessionHandleProcOutput(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsyncstatic int gstcntlSessionHandleProcTerminate(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsyncstatic int gstcntlSessionHandleProcWaitFor(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/** Generic option indices for session fork arguments. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncenum
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
27d188eaec68419914903b118f1428ad597584d8vboxsync VBOXSERVICESESSIONOPT_FIRST = 1000, /* For initialization. */
27d188eaec68419914903b118f1428ad597584d8vboxsync#ifdef DEBUG
27d188eaec68419914903b118f1428ad597584d8vboxsync VBOXSERVICESESSIONOPT_DUMP_STDOUT,
27d188eaec68419914903b118f1428ad597584d8vboxsync VBOXSERVICESESSIONOPT_DUMP_STDERR,
27d188eaec68419914903b118f1428ad597584d8vboxsync#endif
27d188eaec68419914903b118f1428ad597584d8vboxsync VBOXSERVICESESSIONOPT_LOG_FILE,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBOXSERVICESESSIONOPT_USERNAME,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBOXSERVICESESSIONOPT_SESSION_ID,
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync VBOXSERVICESESSIONOPT_SESSION_PROTO,
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync VBOXSERVICESESSIONOPT_THREAD_ID
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync};
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic int gstcntlSessionFileDestroy(PVBOXSERVICECTRLFILE pFile)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertPtrReturn(pFile, VERR_INVALID_POINTER);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc = RTFileClose(pFile->hFile);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Remove file entry in any case. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTListNodeRemove(&pFile->Node);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Destroy this object. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTMemFree(pFile);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync/** @todo No locking done yet! */
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsyncstatic PVBOXSERVICECTRLFILE gstcntlSessionFileGetLocked(const PVBOXSERVICECTRLSESSION pSession,
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync uint32_t uHandle)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, NULL);
4260648b018894247c6a73e244050be76c28f857vboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync PVBOXSERVICECTRLFILE pFileCur = NULL;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /** @todo Use a map later! */
4260648b018894247c6a73e244050be76c28f857vboxsync RTListForEach(&pSession->lstFiles, pFileCur, VBOXSERVICECTRLFILE, Node)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pFileCur->uHandle == uHandle)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return pFileCur;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return NULL;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsyncstatic int gstcntlSessionHandleDirRemove(PVBOXSERVICECTRLSESSION pSession,
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync PVBGLR3GUESTCTRLCMDCTX pHostCtx)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync{
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync char szDir[RTPATH_MAX];
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync uint32_t uFlags = 0;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync int rc = VbglR3GuestCtrlDirGetRemove(pHostCtx,
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /* Directory to remove. */
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync szDir, sizeof(szDir),
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /* Flags of type DIRREMOVE_FLAG_. */
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync &uFlags);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (RT_SUCCESS(rc))
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync uint32_t uFlagsRemRec = 0;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync bool fRecursive = false;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (!(uFlags & ~DIRREMOVE_FLAG_VALID_MASK))
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (uFlags & DIRREMOVE_FLAG_RECURSIVE)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /* Note: DIRREMOVE_FLAG_RECURSIVE must be set explicitly.
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync * Play safe here. */
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync fRecursive = true;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (uFlags & DIRREMOVE_FLAG_CONTENT_AND_DIR)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /* Setting direct value is intentional. */
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync uFlagsRemRec = RTDIRRMREC_F_CONTENT_AND_DIR;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (uFlags & DIRREMOVE_FLAG_CONTENT_ONLY)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /* Setting direct value is intentional. */
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync uFlagsRemRec |= RTDIRRMREC_F_CONTENT_ONLY;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync else
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = VERR_NOT_SUPPORTED;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync VBoxServiceVerbose(4, "[Dir %s]: Removing with uFlags=0x%x, fRecursive=%RTbool\n",
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync szDir, uFlags, fRecursive);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (RT_SUCCESS(rc))
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /** @todo Add own recursive function (or a new IPRT function w/ callback?) to
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync * provide guest-to-host progress reporting. */
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (fRecursive)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = RTDirRemoveRecursive(szDir, uFlagsRemRec);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync else
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = RTDirRemove(szDir);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /* Report back in any case. */
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync int rc2 = VbglR3GuestCtrlMsgReply(pHostCtx, rc);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (RT_FAILURE(rc2))
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync VBoxServiceError("[Dir %s]: Failed to report removing status, rc=%Rrc\n",
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync szDir, rc2);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (RT_SUCCESS(rc))
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = rc2;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync#ifdef DEBUG
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync VBoxServiceVerbose(4, "Removing directory \"%s\" returned rc=%Rrc\n",
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync szDir, rc);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync#endif
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync return rc;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync}
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsyncstatic int gstcntlSessionHandleFileOpen(PVBOXSERVICECTRLSESSION pSession,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync PVBGLR3GUESTCTRLCMDCTX pHostCtx)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync char szFile[RTPATH_MAX];
81096b0da0061583a511da27088643aa949a1ec9vboxsync char szAccess[64];
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync char szDisposition[64];
81096b0da0061583a511da27088643aa949a1ec9vboxsync char szSharing[64];
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uCreationMode = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint64_t uOffset = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uHandle = 0;
81096b0da0061583a511da27088643aa949a1ec9vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync int rc = VbglR3GuestCtrlFileGetOpen(pHostCtx,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* File to open. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync szFile, sizeof(szFile),
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Open mode. */
81096b0da0061583a511da27088643aa949a1ec9vboxsync szAccess, sizeof(szAccess),
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Disposition. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync szDisposition, sizeof(szDisposition),
81096b0da0061583a511da27088643aa949a1ec9vboxsync /* Sharing. */
81096b0da0061583a511da27088643aa949a1ec9vboxsync szSharing, sizeof(szSharing),
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Creation mode. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &uCreationMode,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Offset. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &uOffset);
754b106b329bcd196e73b286a98eba2fd9d6b46avboxsync VBoxServiceVerbose(4, "[File %s]: szAccess=%s, szDisposition=%s, szSharing=%s, uOffset=%RU64, rc=%Rrc\n",
754b106b329bcd196e73b286a98eba2fd9d6b46avboxsync szFile, szAccess, szDisposition, szSharing, uOffset, rc);
754b106b329bcd196e73b286a98eba2fd9d6b46avboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
c5d30148e5df55335757c5ce5ea4b08085312ee0vboxsync PVBOXSERVICECTRLFILE pFile = (PVBOXSERVICECTRLFILE)RTMemAllocZ(sizeof(VBOXSERVICECTRLFILE));
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pFile)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
81096b0da0061583a511da27088643aa949a1ec9vboxsync if (!strlen(szFile))
81096b0da0061583a511da27088643aa949a1ec9vboxsync rc = VERR_INVALID_PARAMETER;
81096b0da0061583a511da27088643aa949a1ec9vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync if ( RT_SUCCESS(rc)
81096b0da0061583a511da27088643aa949a1ec9vboxsync && !RTStrPrintf(pFile->szName, sizeof(pFile->szName), "%s", szFile))
81096b0da0061583a511da27088643aa949a1ec9vboxsync rc = VERR_NO_MEMORY;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
81096b0da0061583a511da27088643aa949a1ec9vboxsync uint64_t fFlags;
81096b0da0061583a511da27088643aa949a1ec9vboxsync rc = RTFileModeToFlagsEx(szAccess, szDisposition,
81096b0da0061583a511da27088643aa949a1ec9vboxsync NULL /* pszSharing, not used yet */, &fFlags);
754b106b329bcd196e73b286a98eba2fd9d6b46avboxsync VBoxServiceVerbose(4, "[File %s]: Opening flags=0x%x, rc=%Rrc\n",
754b106b329bcd196e73b286a98eba2fd9d6b46avboxsync pFile->szName, fFlags, rc);
81096b0da0061583a511da27088643aa949a1ec9vboxsync if (RT_SUCCESS(rc))
81096b0da0061583a511da27088643aa949a1ec9vboxsync rc = RTFileOpen(&pFile->hFile, pFile->szName, fFlags);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if ( RT_SUCCESS(rc)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync && uOffset)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
5278d702cbff6f1a044009365d745d19eb005e26vboxsync /* Seeking is optional. However, the whole operation
5278d702cbff6f1a044009365d745d19eb005e26vboxsync * will fail if we don't succeed seeking to the wanted position. */
5278d702cbff6f1a044009365d745d19eb005e26vboxsync rc = RTFileSeek(pFile->hFile, (int64_t)uOffset, RTFILE_SEEK_BEGIN, NULL /* Current offset */);
5278d702cbff6f1a044009365d745d19eb005e26vboxsync if (RT_FAILURE(rc))
754b106b329bcd196e73b286a98eba2fd9d6b46avboxsync VBoxServiceError("[File %s]: Seeking to offset %RU64 failed; rc=%Rrc\n",
754b106b329bcd196e73b286a98eba2fd9d6b46avboxsync pFile->szName, uOffset, rc);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
81096b0da0061583a511da27088643aa949a1ec9vboxsync else if (RT_FAILURE(rc))
754b106b329bcd196e73b286a98eba2fd9d6b46avboxsync VBoxServiceError("[File %s]: Opening failed; rc=%Rrc\n",
754b106b329bcd196e73b286a98eba2fd9d6b46avboxsync pFile->szName, rc);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
4260648b018894247c6a73e244050be76c28f857vboxsync uHandle = VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pHostCtx->uContextID);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pFile->uHandle = uHandle;
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync /* rc = */ RTListAppend(&pSession->lstFiles, &pFile->Node);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(3, "[File %s]: Opened (ID=%RU32)\n",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pFile->szName, pFile->uHandle);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_FAILURE(rc))
c5d30148e5df55335757c5ce5ea4b08085312ee0vboxsync {
c5d30148e5df55335757c5ce5ea4b08085312ee0vboxsync if (pFile->hFile)
c5d30148e5df55335757c5ce5ea4b08085312ee0vboxsync RTFileClose(pFile->hFile);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTMemFree(pFile);
c5d30148e5df55335757c5ce5ea4b08085312ee0vboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NO_MEMORY;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Report back in any case. */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync int rc2 = VbglR3GuestCtrlFileCbOpen(pHostCtx, rc, uHandle);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_FAILURE(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceError("[File %s]: Failed to report file open status, rc=%Rrc\n",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync szFile, rc2);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = rc2;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync#ifdef DEBUG
81096b0da0061583a511da27088643aa949a1ec9vboxsync VBoxServiceVerbose(4, "Opening file \"%s\" (open mode=\"%s\", disposition=\"%s\", creation mode=0x%x returned rc=%Rrc\n",
81096b0da0061583a511da27088643aa949a1ec9vboxsync szFile, szAccess, szDisposition, uCreationMode, rc);
81096b0da0061583a511da27088643aa949a1ec9vboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsyncstatic int gstcntlSessionHandleFileClose(const PVBOXSERVICECTRLSESSION pSession,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync PVBGLR3GUESTCTRLCMDCTX pHostCtx)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync PVBOXSERVICECTRLFILE pFile = NULL;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync uint32_t uHandle = 0;
4260648b018894247c6a73e244050be76c28f857vboxsync int rc = VbglR3GuestCtrlFileGetClose(pHostCtx, &uHandle /* File handle to close */);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
81096b0da0061583a511da27088643aa949a1ec9vboxsync pFile = gstcntlSessionFileGetLocked(pSession, uHandle);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pFile)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = gstcntlSessionFileDestroy(pFile);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NOT_FOUND;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Report back in any case. */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync int rc2 = VbglR3GuestCtrlFileCbClose(pHostCtx, rc);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_FAILURE(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceError("Failed to report file close status, rc=%Rrc\n", rc2);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = rc2;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync#ifdef DEBUG
81096b0da0061583a511da27088643aa949a1ec9vboxsync VBoxServiceVerbose(4, "Closing file \"%s\" (handle=%RU32) returned rc=%Rrc\n",
81096b0da0061583a511da27088643aa949a1ec9vboxsync pFile ? pFile->szName : "<Not found>", uHandle, rc);
81096b0da0061583a511da27088643aa949a1ec9vboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsyncstatic int gstcntlSessionHandleFileRead(const PVBOXSERVICECTRLSESSION pSession,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync PVBGLR3GUESTCTRLCMDCTX pHostCtx,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync void *pvScratchBuf, size_t cbScratchBuf)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync PVBOXSERVICECTRLFILE pFile = NULL;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync uint32_t uHandle = 0;
81096b0da0061583a511da27088643aa949a1ec9vboxsync uint32_t cbToRead;
4260648b018894247c6a73e244050be76c28f857vboxsync int rc = VbglR3GuestCtrlFileGetRead(pHostCtx, &uHandle, &cbToRead);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync void *pvDataRead = pvScratchBuf;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync size_t cbRead = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
ac1c6ded98668924a40c2bf4acaf9a7b137954f7vboxsync pFile = gstcntlSessionFileGetLocked(pSession, uHandle);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pFile)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (cbToRead)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (cbToRead > cbScratchBuf)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pvDataRead = RTMemAlloc(cbToRead);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (!pvDataRead)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NO_MEMORY;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_LIKELY(RT_SUCCESS(rc)))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = RTFileRead(pFile->hFile, pvDataRead, cbToRead, &cbRead);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_BUFFER_UNDERFLOW;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NOT_FOUND;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Report back in any case. */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync int rc2 = VbglR3GuestCtrlFileCbRead(pHostCtx, rc, pvDataRead, (uint32_t)cbRead);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if ( cbToRead > cbScratchBuf
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync && pvDataRead)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTMemFree(pvDataRead);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_FAILURE(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceError("Failed to report file read status, rc=%Rrc\n", rc2);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = rc2;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
81096b0da0061583a511da27088643aa949a1ec9vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync#ifdef DEBUG
81096b0da0061583a511da27088643aa949a1ec9vboxsync VBoxServiceVerbose(4, "Reading file \"%s\" (handle=%RU32) returned rc=%Rrc\n",
81096b0da0061583a511da27088643aa949a1ec9vboxsync pFile ? pFile->szName : "<Not found>", uHandle, rc);
81096b0da0061583a511da27088643aa949a1ec9vboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsyncstatic int gstcntlSessionHandleFileReadAt(const PVBOXSERVICECTRLSESSION pSession,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync PVBGLR3GUESTCTRLCMDCTX pHostCtx,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync void *pvScratchBuf, size_t cbScratchBuf)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync PVBOXSERVICECTRLFILE pFile = NULL;
81096b0da0061583a511da27088643aa949a1ec9vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync uint32_t uHandle = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t cbToRead; int64_t iOffset;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync int rc = VbglR3GuestCtrlFileGetReadAt(pHostCtx,
81096b0da0061583a511da27088643aa949a1ec9vboxsync &uHandle, &cbToRead, (uint64_t *)&iOffset);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync void *pvDataRead = pvScratchBuf;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync size_t cbRead = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync pFile = gstcntlSessionFileGetLocked(pSession, uHandle);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pFile)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (cbToRead)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (cbToRead > cbScratchBuf)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pvDataRead = RTMemAlloc(cbToRead);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (!pvDataRead)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NO_MEMORY;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_LIKELY(RT_SUCCESS(rc)))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = RTFileReadAt(pFile->hFile, iOffset, pvDataRead, cbToRead, &cbRead);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_BUFFER_UNDERFLOW;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NOT_FOUND;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Report back in any case. */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync int rc2 = VbglR3GuestCtrlFileCbRead(pHostCtx, rc, pvDataRead, (uint32_t)cbRead);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if ( cbToRead > cbScratchBuf
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync && pvDataRead)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTMemFree(pvDataRead);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_FAILURE(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceError("Failed to report file read status, rc=%Rrc\n", rc2);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = rc2;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
81096b0da0061583a511da27088643aa949a1ec9vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync#ifdef DEBUG
81096b0da0061583a511da27088643aa949a1ec9vboxsync VBoxServiceVerbose(4, "Reading file \"%s\" at offset (handle=%RU32) returned rc=%Rrc\n",
81096b0da0061583a511da27088643aa949a1ec9vboxsync pFile ? pFile->szName : "<Not found>", uHandle, rc);
81096b0da0061583a511da27088643aa949a1ec9vboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsyncstatic int gstcntlSessionHandleFileWrite(const PVBOXSERVICECTRLSESSION pSession,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync PVBGLR3GUESTCTRLCMDCTX pHostCtx,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync void *pvScratchBuf, size_t cbScratchBuf)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertPtrReturn(pvScratchBuf, VERR_INVALID_POINTER);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertPtrReturn(cbScratchBuf, VERR_INVALID_PARAMETER);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync PVBOXSERVICECTRLFILE pFile = NULL;
81096b0da0061583a511da27088643aa949a1ec9vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync uint32_t uHandle = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t cbToWrite;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync int rc = VbglR3GuestCtrlFileGetWrite(pHostCtx, &uHandle,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pvScratchBuf, cbScratchBuf,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &cbToWrite);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync size_t cbWritten = 0;
81096b0da0061583a511da27088643aa949a1ec9vboxsync pFile = gstcntlSessionFileGetLocked(pSession, uHandle);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pFile)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync rc = RTFileWrite(pFile->hFile, pvScratchBuf, cbToWrite, &cbWritten);
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync#ifdef DEBUG
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync VBoxServiceVerbose(4, "[File %s]: Writing pvScratchBuf=%p, cbToWrite=%RU32, cbWritten=%zu, rc=%Rrc\n",
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync pFile->szName, pvScratchBuf, cbToWrite, cbWritten, rc);
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NOT_FOUND;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Report back in any case. */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync int rc2 = VbglR3GuestCtrlFileCbWrite(pHostCtx, rc, (uint32_t)cbWritten);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_FAILURE(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceError("Failed to report file write status, rc=%Rrc\n", rc2);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = rc2;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
81096b0da0061583a511da27088643aa949a1ec9vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync#ifdef DEBUG
81096b0da0061583a511da27088643aa949a1ec9vboxsync VBoxServiceVerbose(4, "Writing file \"%s\" (handle=%RU32) returned rc=%Rrc\n",
81096b0da0061583a511da27088643aa949a1ec9vboxsync pFile ? pFile->szName : "<Not found>", uHandle, rc);
81096b0da0061583a511da27088643aa949a1ec9vboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsyncstatic int gstcntlSessionHandleFileWriteAt(const PVBOXSERVICECTRLSESSION pSession,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync PVBGLR3GUESTCTRLCMDCTX pHostCtx,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync void *pvScratchBuf, size_t cbScratchBuf)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertPtrReturn(pvScratchBuf, VERR_INVALID_POINTER);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertPtrReturn(cbScratchBuf, VERR_INVALID_PARAMETER);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync PVBOXSERVICECTRLFILE pFile = NULL;
81096b0da0061583a511da27088643aa949a1ec9vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync uint32_t uHandle = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t cbToWrite; int64_t iOffset;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync int rc = VbglR3GuestCtrlFileGetWriteAt(pHostCtx, &uHandle,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pvScratchBuf, cbScratchBuf,
81096b0da0061583a511da27088643aa949a1ec9vboxsync &cbToWrite, (uint64_t *)&iOffset);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync size_t cbWritten = 0;
ac1c6ded98668924a40c2bf4acaf9a7b137954f7vboxsync pFile = gstcntlSessionFileGetLocked(pSession, uHandle);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pFile)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = RTFileWriteAt(pFile->hFile, iOffset,
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync pvScratchBuf, cbToWrite, &cbWritten);
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync#ifdef DEBUG
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync VBoxServiceVerbose(4, "[File %s]: Writing iOffset=%RI64, pvScratchBuf=%p, cbToWrite=%RU32, cbWritten=%zu, rc=%Rrc\n",
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync pFile->szName, iOffset, pvScratchBuf, cbToWrite, cbWritten, rc);
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NOT_FOUND;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Report back in any case. */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync int rc2 = VbglR3GuestCtrlFileCbWrite(pHostCtx, rc, (uint32_t)cbWritten);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_FAILURE(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceError("Failed to report file write status, rc=%Rrc\n", rc2);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = rc2;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
81096b0da0061583a511da27088643aa949a1ec9vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync#ifdef DEBUG
81096b0da0061583a511da27088643aa949a1ec9vboxsync VBoxServiceVerbose(4, "Writing file \"%s\" at offset (handle=%RU32) returned rc=%Rrc\n",
81096b0da0061583a511da27088643aa949a1ec9vboxsync pFile ? pFile->szName : "<Not found>", uHandle, rc);
81096b0da0061583a511da27088643aa949a1ec9vboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsyncstatic int gstcntlSessionHandleFileSeek(const PVBOXSERVICECTRLSESSION pSession,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync PVBGLR3GUESTCTRLCMDCTX pHostCtx)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync PVBOXSERVICECTRLFILE pFile = NULL;
81096b0da0061583a511da27088643aa949a1ec9vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync uint32_t uHandle = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uSeekMethod;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint64_t uOffset; /* Will be converted to int64_t. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint64_t uOffsetActual = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync int rc = VbglR3GuestCtrlFileGetSeek(pHostCtx, &uHandle,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &uSeekMethod, &uOffset);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
81096b0da0061583a511da27088643aa949a1ec9vboxsync pFile = gstcntlSessionFileGetLocked(pSession, uHandle);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pFile)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync unsigned uSeekMethodIPRT;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync switch (uSeekMethod)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case GUEST_FILE_SEEKTYPE_BEGIN:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uSeekMethodIPRT = RTFILE_SEEK_BEGIN;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case GUEST_FILE_SEEKTYPE_CURRENT:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uSeekMethodIPRT = RTFILE_SEEK_CURRENT;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case GUEST_FILE_SEEKTYPE_END:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uSeekMethodIPRT = RTFILE_SEEK_END;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync default:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NOT_SUPPORTED;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = RTFileSeek(pFile->hFile, (int64_t)uOffset,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uSeekMethodIPRT, &uOffsetActual);
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync#ifdef DEBUG
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync VBoxServiceVerbose(4, "[File %s]: Seeking to iOffset=%RI64, uSeekMethodIPRT=%RU16, rc=%Rrc\n",
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync pFile->szName, (int64_t)uOffset, uSeekMethodIPRT, rc);
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync#endif
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NOT_FOUND;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Report back in any case. */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync int rc2 = VbglR3GuestCtrlFileCbSeek(pHostCtx, rc, uOffsetActual);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_FAILURE(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceError("Failed to report file seek status, rc=%Rrc\n", rc2);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = rc2;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
81096b0da0061583a511da27088643aa949a1ec9vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync#ifdef DEBUG
81096b0da0061583a511da27088643aa949a1ec9vboxsync VBoxServiceVerbose(4, "Seeking file \"%s\" (handle=%RU32) returned rc=%Rrc\n",
81096b0da0061583a511da27088643aa949a1ec9vboxsync pFile ? pFile->szName : "<Not found>", uHandle, rc);
81096b0da0061583a511da27088643aa949a1ec9vboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsyncstatic int gstcntlSessionHandleFileTell(const PVBOXSERVICECTRLSESSION pSession,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync PVBGLR3GUESTCTRLCMDCTX pHostCtx)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync PVBOXSERVICECTRLFILE pFile = NULL;
81096b0da0061583a511da27088643aa949a1ec9vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync uint32_t uHandle = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint64_t uOffsetActual = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync int rc = VbglR3GuestCtrlFileGetTell(pHostCtx, &uHandle);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
81096b0da0061583a511da27088643aa949a1ec9vboxsync pFile = gstcntlSessionFileGetLocked(pSession, uHandle);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pFile)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uOffsetActual = RTFileTell(pFile->hFile);
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync#ifdef DEBUG
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync VBoxServiceVerbose(4, "[File %s]: Telling uOffsetActual=%RU64\n",
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync pFile->szName, uOffsetActual);
a8044a7c40f40fd70348f06ffa49bbb4497444f9vboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NOT_FOUND;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Report back in any case. */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync int rc2 = VbglR3GuestCtrlFileCbTell(pHostCtx, rc, uOffsetActual);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_FAILURE(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceError("Failed to report file tell status, rc=%Rrc\n", rc2);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = rc2;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
81096b0da0061583a511da27088643aa949a1ec9vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync#ifdef DEBUG
81096b0da0061583a511da27088643aa949a1ec9vboxsync VBoxServiceVerbose(4, "Telling file \"%s\" (handle=%RU32) returned rc=%Rrc\n",
81096b0da0061583a511da27088643aa949a1ec9vboxsync pFile ? pFile->szName : "<Not found>", uHandle, rc);
81096b0da0061583a511da27088643aa949a1ec9vboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsyncstatic int gstcntlSessionHandlePathRename(PVBOXSERVICECTRLSESSION pSession,
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync PVBGLR3GUESTCTRLCMDCTX pHostCtx)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync{
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync char szSource[RTPATH_MAX];
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync char szDest[RTPATH_MAX];
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync uint32_t uFlags = 0;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync int rc = VbglR3GuestCtrlPathGetRename(pHostCtx,
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync szSource, sizeof(szSource),
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync szDest, sizeof(szDest),
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /* Flags of type PATHRENAME_FLAG_. */
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync &uFlags);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (RT_SUCCESS(rc))
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (uFlags & ~PATHRENAME_FLAG_VALID_MASK)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = VERR_NOT_SUPPORTED;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync VBoxServiceVerbose(4, "Renaming \"%s\" to \"%s\", uFlags=0x%x, rc=%Rrc\n",
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync szSource, szDest, uFlags, rc);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (RT_SUCCESS(rc))
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (uFlags & PATHRENAME_FLAG_NO_REPLACE)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync uFlags |= RTPATHRENAME_FLAGS_NO_REPLACE;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (uFlags & PATHRENAME_FLAG_REPLACE)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync uFlags |= RTPATHRENAME_FLAGS_REPLACE;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (uFlags & PATHRENAME_FLAG_NO_SYMLINKS)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync uFlags |= RTPATHRENAME_FLAGS_NO_SYMLINKS;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = RTPathRename(szSource, szDest, uFlags);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /* Report back in any case. */
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync int rc2 = VbglR3GuestCtrlMsgReply(pHostCtx, rc);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (RT_FAILURE(rc2))
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync VBoxServiceError("Failed to report renaming status, rc=%Rrc\n", rc2);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (RT_SUCCESS(rc))
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = rc2;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync#ifdef DEBUG
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync VBoxServiceVerbose(4, "Renaming \"%s\" to \"%s\" returned rc=%Rrc\n",
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync szSource, szDest, rc);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync#endif
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync return rc;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync}
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync/**
4260648b018894247c6a73e244050be76c28f857vboxsync * Handles starting a guest processes.
4260648b018894247c6a73e244050be76c28f857vboxsync *
4260648b018894247c6a73e244050be76c28f857vboxsync * @returns IPRT status code.
4260648b018894247c6a73e244050be76c28f857vboxsync * @param pSession Guest session.
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync * @param pHostCtx Host context.
4260648b018894247c6a73e244050be76c28f857vboxsync */
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsyncint gstcntlSessionHandleProcExec(PVBOXSERVICECTRLSESSION pSession,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync PVBGLR3GUESTCTRLCMDCTX pHostCtx)
4260648b018894247c6a73e244050be76c28f857vboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync int rc = VINF_SUCCESS;
4260648b018894247c6a73e244050be76c28f857vboxsync bool fStartAllowed = false; /* Flag indicating whether starting a process is allowed or not. */
4260648b018894247c6a73e244050be76c28f857vboxsync
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync switch (pHostCtx->uProtocol)
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync {
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync case 1: /* Guest Additions < 4.3. */
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync if (pHostCtx->uNumParms != 11)
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync rc = VERR_NOT_SUPPORTED;
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync break;
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync case 2: /* Guest Additions >= 4.3. */
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync if (pHostCtx->uNumParms != 12)
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync rc = VERR_NOT_SUPPORTED;
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync break;
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync default:
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync rc = VERR_NOT_SUPPORTED;
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync break;
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync }
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync if (RT_SUCCESS(rc))
4260648b018894247c6a73e244050be76c28f857vboxsync {
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync VBOXSERVICECTRLPROCSTARTUPINFO startupInfo;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync RT_ZERO(startupInfo);
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync /* Initialize maximum environment block size -- needed as input
4260648b018894247c6a73e244050be76c28f857vboxsync * parameter to retrieve the stuff from the host. On output this then
4260648b018894247c6a73e244050be76c28f857vboxsync * will contain the actual block size. */
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync startupInfo.cbEnv = sizeof(startupInfo.szEnv);
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync rc = VbglR3GuestCtrlProcGetStart(pHostCtx,
4260648b018894247c6a73e244050be76c28f857vboxsync /* Command */
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync startupInfo.szCmd, sizeof(startupInfo.szCmd),
4260648b018894247c6a73e244050be76c28f857vboxsync /* Flags */
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync &startupInfo.uFlags,
4260648b018894247c6a73e244050be76c28f857vboxsync /* Arguments */
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync startupInfo.szArgs, sizeof(startupInfo.szArgs), &startupInfo.uNumArgs,
4260648b018894247c6a73e244050be76c28f857vboxsync /* Environment */
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync startupInfo.szEnv, &startupInfo.cbEnv, &startupInfo.uNumEnvVars,
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync /* Credentials; for hosts with VBox < 4.3 (protocol version 1).
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync * For protocl v2 and up the credentials are part of the session
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync * opening call. */
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync startupInfo.szUser, sizeof(startupInfo.szUser),
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync startupInfo.szPassword, sizeof(startupInfo.szPassword),
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync /* Timeout (in ms) */
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync &startupInfo.uTimeLimitMS,
4260648b018894247c6a73e244050be76c28f857vboxsync /* Process priority */
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync &startupInfo.uPriority,
4260648b018894247c6a73e244050be76c28f857vboxsync /* Process affinity */
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync startupInfo.uAffinity, sizeof(startupInfo.uAffinity), &startupInfo.uNumAffinity);
4260648b018894247c6a73e244050be76c28f857vboxsync if (RT_SUCCESS(rc))
4260648b018894247c6a73e244050be76c28f857vboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync VBoxServiceVerbose(3, "Request to start process szCmd=%s, uFlags=0x%x, szArgs=%s, szEnv=%s, uTimeout=%RU32\n",
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync startupInfo.szCmd, startupInfo.uFlags,
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync startupInfo.uNumArgs ? startupInfo.szArgs : "<None>",
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync startupInfo.uNumEnvVars ? startupInfo.szEnv : "<None>",
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync startupInfo.uTimeLimitMS);
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync rc = GstCntlSessionProcessStartAllowed(pSession, &fStartAllowed);
4260648b018894247c6a73e244050be76c28f857vboxsync if (RT_SUCCESS(rc))
4260648b018894247c6a73e244050be76c28f857vboxsync {
4260648b018894247c6a73e244050be76c28f857vboxsync if (fStartAllowed)
4260648b018894247c6a73e244050be76c28f857vboxsync {
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync rc = GstCntlProcessStart(pSession, &startupInfo, pHostCtx->uContextID);
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync else
4260648b018894247c6a73e244050be76c28f857vboxsync rc = VERR_MAX_PROCS_REACHED; /* Maximum number of processes reached. */
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync /* In case of an error we need to notify the host to not wait forever for our response. */
4260648b018894247c6a73e244050be76c28f857vboxsync if (RT_FAILURE(rc))
4260648b018894247c6a73e244050be76c28f857vboxsync {
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync VBoxServiceError("Starting process failed with rc=%Rrc, protocol=%RU32, parameters=%RU32\n",
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync rc, pHostCtx->uProtocol, pHostCtx->uNumParms);
4260648b018894247c6a73e244050be76c28f857vboxsync
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync /* Don't report back if we didn't supply sufficient buffer for getting
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync * the actual command -- we don't have the matching context ID. */
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync if (rc != VERR_TOO_MUCH_DATA)
4260648b018894247c6a73e244050be76c28f857vboxsync {
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync /*
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync * Note: The context ID can be 0 because we mabye weren't able to fetch the command
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync * from the host. The host in case has to deal with that!
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync */
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync int rc2 = VbglR3GuestCtrlProcCbStatus(pHostCtx, 0 /* PID, invalid */,
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync PROC_STS_ERROR, rc,
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync NULL /* pvData */, 0 /* cbData */);
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync if (RT_FAILURE(rc2))
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync VBoxServiceError("Error sending start process status to host, rc=%Rrc\n", rc2);
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync return rc;
4260648b018894247c6a73e244050be76c28f857vboxsync}
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync/**
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * Sends stdin input to a specific guest process.
4260648b018894247c6a73e244050be76c28f857vboxsync *
4260648b018894247c6a73e244050be76c28f857vboxsync * @returns IPRT status code.
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * @param pSession The session which is in charge.
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * @param pHostCtx The host context to use.
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * @param pvScratchBuf The scratch buffer.
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * @param cbScratchBuf The scratch buffer size for retrieving the input data.
4260648b018894247c6a73e244050be76c28f857vboxsync */
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsyncint gstcntlSessionHandleProcInput(PVBOXSERVICECTRLSESSION pSession,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync PVBGLR3GUESTCTRLCMDCTX pHostCtx,
4260648b018894247c6a73e244050be76c28f857vboxsync void *pvScratchBuf, size_t cbScratchBuf)
4260648b018894247c6a73e244050be76c28f857vboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(cbScratchBuf, VERR_INVALID_PARAMETER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pvScratchBuf, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync uint32_t uPID;
4260648b018894247c6a73e244050be76c28f857vboxsync uint32_t uFlags;
4260648b018894247c6a73e244050be76c28f857vboxsync uint32_t cbSize;
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync uint32_t uStatus = INPUT_STS_UNDEFINED; /* Status sent back to the host. */
4260648b018894247c6a73e244050be76c28f857vboxsync uint32_t cbWritten = 0; /* Number of bytes written to the guest. */
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync /*
4260648b018894247c6a73e244050be76c28f857vboxsync * Ask the host for the input data.
4260648b018894247c6a73e244050be76c28f857vboxsync */
4260648b018894247c6a73e244050be76c28f857vboxsync int rc = VbglR3GuestCtrlProcGetInput(pHostCtx, &uPID, &uFlags,
4260648b018894247c6a73e244050be76c28f857vboxsync pvScratchBuf, cbScratchBuf, &cbSize);
4260648b018894247c6a73e244050be76c28f857vboxsync if (RT_FAILURE(rc))
4260648b018894247c6a73e244050be76c28f857vboxsync {
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync VBoxServiceError("Failed to retrieve process input command for PID=%RU32, rc=%Rrc\n",
4260648b018894247c6a73e244050be76c28f857vboxsync uPID, rc);
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync else if (cbSize > cbScratchBuf)
4260648b018894247c6a73e244050be76c28f857vboxsync {
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync VBoxServiceError("Too much process input received, rejecting: uPID=%RU32, cbSize=%RU32, cbScratchBuf=%RU32\n",
4260648b018894247c6a73e244050be76c28f857vboxsync uPID, cbSize, cbScratchBuf);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync rc = VERR_TOO_MUCH_DATA;
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync else
4260648b018894247c6a73e244050be76c28f857vboxsync {
4260648b018894247c6a73e244050be76c28f857vboxsync /*
4260648b018894247c6a73e244050be76c28f857vboxsync * Is this the last input block we need to deliver? Then let the pipe know ...
4260648b018894247c6a73e244050be76c28f857vboxsync */
4260648b018894247c6a73e244050be76c28f857vboxsync bool fPendingClose = false;
4260648b018894247c6a73e244050be76c28f857vboxsync if (uFlags & INPUT_FLAG_EOF)
4260648b018894247c6a73e244050be76c28f857vboxsync {
4260648b018894247c6a73e244050be76c28f857vboxsync fPendingClose = true;
81096b0da0061583a511da27088643aa949a1ec9vboxsync#ifdef DEBUG
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync VBoxServiceVerbose(4, "Got last process input block for PID=%RU32 (%RU32 bytes) ...\n",
4260648b018894247c6a73e244050be76c28f857vboxsync uPID, cbSize);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync#endif
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync PVBOXSERVICECTRLPROCESS pProcess = GstCntlSessionRetainProcess(pSession, uPID);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync if (pProcess)
4260648b018894247c6a73e244050be76c28f857vboxsync {
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync rc = GstCntlProcessHandleInput(pProcess, pHostCtx, fPendingClose,
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync pvScratchBuf, cbSize);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync if (RT_FAILURE(rc))
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync VBoxServiceError("Error handling input command for PID=%RU32, rc=%Rrc\n",
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync uPID, rc);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync GstCntlProcessRelease(pProcess);
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync else
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync rc = VERR_NOT_FOUND;
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync#ifdef DEBUG
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync VBoxServiceVerbose(4, "Setting input for PID=%RU32 resulted in rc=%Rrc\n",
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync uPID, rc);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync#endif
4260648b018894247c6a73e244050be76c28f857vboxsync return rc;
4260648b018894247c6a73e244050be76c28f857vboxsync}
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync/**
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * Gets stdout/stderr output of a specific guest process.
4260648b018894247c6a73e244050be76c28f857vboxsync *
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * @return IPRT status code.
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * @param pSession The session which is in charge.
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * @param pHostCtx The host context to use.
4260648b018894247c6a73e244050be76c28f857vboxsync */
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsyncint gstcntlSessionHandleProcOutput(PVBOXSERVICECTRLSESSION pSession,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync PVBGLR3GUESTCTRLCMDCTX pHostCtx)
4260648b018894247c6a73e244050be76c28f857vboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync uint32_t uPID;
4260648b018894247c6a73e244050be76c28f857vboxsync uint32_t uHandleID;
4260648b018894247c6a73e244050be76c28f857vboxsync uint32_t uFlags;
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync int rc = VbglR3GuestCtrlProcGetOutput(pHostCtx, &uPID, &uHandleID, &uFlags);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync#ifdef DEBUG_andy
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync VBoxServiceVerbose(4, "Getting output for PID=%RU32, CID=%RU32, uHandleID=%RU32, uFlags=%RU32\n",
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync uPID, pHostCtx->uContextID, uHandleID, uFlags);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync#endif
4260648b018894247c6a73e244050be76c28f857vboxsync if (RT_SUCCESS(rc))
4260648b018894247c6a73e244050be76c28f857vboxsync {
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync PVBOXSERVICECTRLPROCESS pProcess = GstCntlSessionRetainProcess(pSession, uPID);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync if (pProcess)
4260648b018894247c6a73e244050be76c28f857vboxsync {
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync rc = GstCntlProcessHandleOutput(pProcess, pHostCtx,
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync uHandleID, _64K /* cbToRead */, uFlags);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync if (RT_FAILURE(rc))
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync VBoxServiceError("Error getting output for PID=%RU32, rc=%Rrc\n",
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync uPID, rc);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync GstCntlProcessRelease(pProcess);
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync else
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync rc = VERR_NOT_FOUND;
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync#ifdef DEBUG_andy
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync VBoxServiceVerbose(4, "Getting output for PID=%RU32 resulted in rc=%Rrc\n",
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync uPID, rc);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync#endif
4260648b018894247c6a73e244050be76c28f857vboxsync return rc;
4260648b018894247c6a73e244050be76c28f857vboxsync}
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync/**
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * Tells a guest process to terminate.
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync *
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * @return IPRT status code.
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * @param pSession The session which is in charge.
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * @param pHostCtx The host context to use.
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync */
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsyncint gstcntlSessionHandleProcTerminate(const PVBOXSERVICECTRLSESSION pSession,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync PVBGLR3GUESTCTRLCMDCTX pHostCtx)
4260648b018894247c6a73e244050be76c28f857vboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync uint32_t uPID;
4260648b018894247c6a73e244050be76c28f857vboxsync int rc = VbglR3GuestCtrlProcGetTerminate(pHostCtx, &uPID);
4260648b018894247c6a73e244050be76c28f857vboxsync if (RT_SUCCESS(rc))
4260648b018894247c6a73e244050be76c28f857vboxsync {
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync PVBOXSERVICECTRLPROCESS pProcess = GstCntlSessionRetainProcess(pSession, uPID);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync if (pProcess)
4260648b018894247c6a73e244050be76c28f857vboxsync {
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync rc = GstCntlProcessHandleTerm(pProcess);
4260648b018894247c6a73e244050be76c28f857vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync GstCntlProcessRelease(pProcess);
4260648b018894247c6a73e244050be76c28f857vboxsync }
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync else
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync rc = VERR_NOT_FOUND;
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync#ifdef DEBUG_andy
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync VBoxServiceVerbose(4, "Terminating PID=%RU32 resulted in rc=%Rrc\n",
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync uPID, rc);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync#endif
4260648b018894247c6a73e244050be76c28f857vboxsync return rc;
4260648b018894247c6a73e244050be76c28f857vboxsync}
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsyncint gstcntlSessionHandleProcWaitFor(const PVBOXSERVICECTRLSESSION pSession,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync PVBGLR3GUESTCTRLCMDCTX pHostCtx)
4260648b018894247c6a73e244050be76c28f857vboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync uint32_t uPID;
4260648b018894247c6a73e244050be76c28f857vboxsync uint32_t uWaitFlags; uint32_t uTimeoutMS;
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync int rc = VbglR3GuestCtrlProcGetWaitFor(pHostCtx, &uPID, &uWaitFlags, &uTimeoutMS);
4260648b018894247c6a73e244050be76c28f857vboxsync if (RT_SUCCESS(rc))
4260648b018894247c6a73e244050be76c28f857vboxsync {
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync PVBOXSERVICECTRLPROCESS pProcess = GstCntlSessionRetainProcess(pSession, uPID);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync if (pProcess)
4260648b018894247c6a73e244050be76c28f857vboxsync {
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync rc = VERR_NOT_IMPLEMENTED; /** @todo */
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync GstCntlProcessRelease(pProcess);
4260648b018894247c6a73e244050be76c28f857vboxsync }
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync else
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync rc = VERR_NOT_FOUND;
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync return rc;
4260648b018894247c6a73e244050be76c28f857vboxsync}
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsyncint GstCntlSessionHandler(PVBOXSERVICECTRLSESSION pSession,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync uint32_t uMsg, PVBGLR3GUESTCTRLCMDCTX pHostCtx,
4260648b018894247c6a73e244050be76c28f857vboxsync void *pvScratchBuf, size_t cbScratchBuf,
4260648b018894247c6a73e244050be76c28f857vboxsync volatile bool *pfShutdown)
4260648b018894247c6a73e244050be76c28f857vboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pvScratchBuf, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pfShutdown, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync int rc = VINF_SUCCESS;
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync /**
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync * Only anonymous sessions (that is, sessions which run with local
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync * service privileges) or forked session processes can do certain
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync * operations.
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync */
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync bool fImpersonated = ( pSession->uFlags & VBOXSERVICECTRLSESSION_FLAG_FORK
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync || pSession->uFlags & VBOXSERVICECTRLSESSION_FLAG_ANONYMOUS);
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync switch (uMsg)
4260648b018894247c6a73e244050be76c28f857vboxsync {
4260648b018894247c6a73e244050be76c28f857vboxsync case HOST_SESSION_CLOSE:
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /* Shutdown (this fork). */
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync rc = GstCntlSessionClose(pSession);
4260648b018894247c6a73e244050be76c28f857vboxsync *pfShutdown = true; /* Shutdown in any case. */
4260648b018894247c6a73e244050be76c28f857vboxsync break;
4260648b018894247c6a73e244050be76c28f857vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync case HOST_DIR_REMOVE:
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = fImpersonated
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync ? gstcntlSessionHandleDirRemove(pSession, pHostCtx)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync : VERR_NOT_SUPPORTED;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync break;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync case HOST_EXEC_CMD:
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync rc = gstcntlSessionHandleProcExec(pSession, pHostCtx);
4260648b018894247c6a73e244050be76c28f857vboxsync break;
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync case HOST_EXEC_SET_INPUT:
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync rc = gstcntlSessionHandleProcInput(pSession, pHostCtx,
4260648b018894247c6a73e244050be76c28f857vboxsync pvScratchBuf, cbScratchBuf);
4260648b018894247c6a73e244050be76c28f857vboxsync break;
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync case HOST_EXEC_GET_OUTPUT:
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync rc = gstcntlSessionHandleProcOutput(pSession, pHostCtx);
4260648b018894247c6a73e244050be76c28f857vboxsync break;
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync case HOST_EXEC_TERMINATE:
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync rc = gstcntlSessionHandleProcTerminate(pSession, pHostCtx);
4260648b018894247c6a73e244050be76c28f857vboxsync break;
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync case HOST_EXEC_WAIT_FOR:
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync rc = gstcntlSessionHandleProcWaitFor(pSession, pHostCtx);
4260648b018894247c6a73e244050be76c28f857vboxsync break;
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync case HOST_FILE_OPEN:
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync rc = fImpersonated
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync ? gstcntlSessionHandleFileOpen(pSession, pHostCtx)
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync : VERR_NOT_SUPPORTED;
4260648b018894247c6a73e244050be76c28f857vboxsync break;
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync case HOST_FILE_CLOSE:
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync rc = fImpersonated
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync ? gstcntlSessionHandleFileClose(pSession, pHostCtx)
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync : VERR_NOT_SUPPORTED;
4260648b018894247c6a73e244050be76c28f857vboxsync break;
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync case HOST_FILE_READ:
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync rc = fImpersonated
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync ? gstcntlSessionHandleFileRead(pSession, pHostCtx,
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync pvScratchBuf, cbScratchBuf)
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync : VERR_NOT_SUPPORTED;
4260648b018894247c6a73e244050be76c28f857vboxsync break;
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync case HOST_FILE_READ_AT:
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync rc = fImpersonated
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync ? gstcntlSessionHandleFileReadAt(pSession, pHostCtx,
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync pvScratchBuf, cbScratchBuf)
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync : VERR_NOT_SUPPORTED;
4260648b018894247c6a73e244050be76c28f857vboxsync break;
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync case HOST_FILE_WRITE:
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync rc = fImpersonated
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync ? gstcntlSessionHandleFileWrite(pSession, pHostCtx,
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync pvScratchBuf, cbScratchBuf)
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync : VERR_NOT_SUPPORTED;
4260648b018894247c6a73e244050be76c28f857vboxsync break;
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync case HOST_FILE_WRITE_AT:
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync rc = fImpersonated
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync ? gstcntlSessionHandleFileWriteAt(pSession, pHostCtx,
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync pvScratchBuf, cbScratchBuf)
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync : VERR_NOT_SUPPORTED;
4260648b018894247c6a73e244050be76c28f857vboxsync break;
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync case HOST_FILE_SEEK:
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync rc = fImpersonated
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync ? gstcntlSessionHandleFileSeek(pSession, pHostCtx)
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync : VERR_NOT_SUPPORTED;
4260648b018894247c6a73e244050be76c28f857vboxsync break;
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync case HOST_FILE_TELL:
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync rc = fImpersonated
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync ? gstcntlSessionHandleFileTell(pSession, pHostCtx)
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync : VERR_NOT_SUPPORTED;
4260648b018894247c6a73e244050be76c28f857vboxsync break;
4260648b018894247c6a73e244050be76c28f857vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync case HOST_PATH_RENAME:
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = fImpersonated
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync ? gstcntlSessionHandlePathRename(pSession, pHostCtx)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync : VERR_NOT_SUPPORTED;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync break;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync default:
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync rc = VbglR3GuestCtrlMsgSkip(pHostCtx->uClientID);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync VBoxServiceVerbose(3, "Unsupported message (uMsg=%RU32, cParms=%RU32) from host, skipping\n",
4260648b018894247c6a73e244050be76c28f857vboxsync uMsg, pHostCtx->uNumParms);
4260648b018894247c6a73e244050be76c28f857vboxsync break;
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync
81096b0da0061583a511da27088643aa949a1ec9vboxsync if (RT_FAILURE(rc))
81096b0da0061583a511da27088643aa949a1ec9vboxsync VBoxServiceError("Error while handling message (uMsg=%RU32, cParms=%RU32), rc=%Rrc\n",
81096b0da0061583a511da27088643aa949a1ec9vboxsync uMsg, pHostCtx->uNumParms, rc);
81096b0da0061583a511da27088643aa949a1ec9vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync return rc;
4260648b018894247c6a73e244050be76c28f857vboxsync}
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync/**
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync * Thread main routine for a forked guest session process.
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync * This thread runs in the main executable to control the forked
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * session process.
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync *
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * @return IPRT status code.
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * @param RTTHREAD Pointer to the thread's data.
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * @param void* User-supplied argument pointer.
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync *
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync */
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsyncstatic DECLCALLBACK(int) gstcntlSessionThread(RTTHREAD ThreadSelf, void *pvUser)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync{
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync PVBOXSERVICECTRLSESSIONTHREAD pThread = (PVBOXSERVICECTRLSESSIONTHREAD)pvUser;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync AssertPtrReturn(pThread, VERR_INVALID_POINTER);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync uint32_t uSessionID = pThread->StartupInfo.uSessionID;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync uint32_t uClientID;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync int rc = VbglR3GuestCtrlConnect(&uClientID);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync if (RT_SUCCESS(rc))
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync {
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync VBoxServiceVerbose(3, "Session ID=%RU32 thread running, client ID=%RU32\n",
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync uSessionID, uClientID);
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync /* The session thread is not interested in receiving any commands;
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync * tell the host service. */
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync rc = VbglR3GuestCtrlMsgFilterSet(uClientID, 0 /* Skip all */,
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync 0 /* Filter mask to add */, 0 /* Filter mask to remove */);
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync if (RT_FAILURE(rc))
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync {
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync VBoxServiceError("Unable to set message filter, rc=%Rrc\n", rc);
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync /* Non-critical. */
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync rc = VINF_SUCCESS;
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync }
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync }
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync else
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync VBoxServiceError("Error connecting to guest control service, rc=%Rrc\n", rc);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync if (RT_FAILURE(rc))
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync pThread->fShutdown = true;
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync /* Let caller know that we're done initializing, regardless of the result. */
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync int rc2 = RTThreadUserSignal(RTThreadSelf());
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync AssertRC(rc2);
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync if (RT_FAILURE(rc))
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync return rc;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync bool fProcessAlive = true;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync RTPROCSTATUS ProcessStatus;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync RT_ZERO(ProcessStatus);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync int rcWait;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync if (RT_SUCCESS(rc))
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync uint32_t uTimeoutsMS = 30 * 1000; /** @todo Make this configurable. Later. */
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync uint64_t u64TimeoutStart = 0;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync for (;;)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync {
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync rcWait = RTProcWaitNoResume(pThread->hProcess, RTPROCWAIT_FLAGS_NOBLOCK,
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync &ProcessStatus);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync if (RT_UNLIKELY(rcWait == VERR_INTERRUPTED))
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync continue;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync else if ( rcWait == VINF_SUCCESS
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync || rcWait == VERR_PROCESS_NOT_FOUND)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync {
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync fProcessAlive = false;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync break;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync }
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync else
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync AssertMsgBreak(rcWait == VERR_PROCESS_RUNNING,
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync ("Got unexpected rc=%Rrc while waiting for session process termination\n", rcWait));
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync if (ASMAtomicReadBool(&pThread->fShutdown))
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync {
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync if (!u64TimeoutStart)
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync VBoxServiceVerbose(3, "Notifying guest session process (PID=%RU32, session ID=%RU32) ...\n",
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync pThread->hProcess, uSessionID);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync VBGLR3GUESTCTRLCMDCTX hostCtx = { uClientID,
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(uSessionID),
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync pThread->StartupInfo.uProtocol, 2 /* uNumParms */ };
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = VbglR3GuestCtrlSessionClose(&hostCtx, 0 /* uFlags */);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (RT_FAILURE(rc))
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync VBoxServiceError("Unable to notify guest session process (PID=%RU32, session ID=%RU32), rc=%Rrc\n",
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync pThread->hProcess, uSessionID, rc);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (rc == VERR_NOT_SUPPORTED)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /* Terminate guest session process in case it's not supported by a too old host. */
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = RTProcTerminate(pThread->hProcess);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync VBoxServiceVerbose(3, "Terminating guest session process (PID=%RU32) ended with rc=%Rrc\n",
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync pThread->hProcess, rc);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync break;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync VBoxServiceVerbose(3, "Guest session ID=%RU32 thread was asked to terminate, waiting for session process to exit (%RU32ms timeout) ...\n",
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync uSessionID, uTimeoutsMS);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync u64TimeoutStart = RTTimeMilliTS();
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync continue; /* Don't waste time on waiting. */
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync }
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync if (RTTimeMilliTS() - u64TimeoutStart > uTimeoutsMS)
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync {
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync VBoxServiceVerbose(3, "Guest session ID=%RU32 process did not shut down within time\n",
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync uSessionID);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync break;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync }
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync }
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync RTThreadSleep(100); /* Wait a bit. */
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync }
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync if (!fProcessAlive)
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync {
026b1e278173a87acfffc3dd69c71766b7259b5evboxsync VBoxServiceVerbose(2, "Guest session process (ID=%RU32) terminated with rc=%Rrc, reason=%ld, status=%d\n",
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync uSessionID, rcWait,
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync ProcessStatus.enmReason, ProcessStatus.iStatus);
026b1e278173a87acfffc3dd69c71766b7259b5evboxsync if (ProcessStatus.iStatus == RTEXITCODE_INIT)
026b1e278173a87acfffc3dd69c71766b7259b5evboxsync {
026b1e278173a87acfffc3dd69c71766b7259b5evboxsync VBoxServiceError("Guest session process (ID=%RU32) failed to initialize. Here some hints:\n",
026b1e278173a87acfffc3dd69c71766b7259b5evboxsync uSessionID);
026b1e278173a87acfffc3dd69c71766b7259b5evboxsync VBoxServiceError("- Is logging enabled and the output directory is read-only by the guest session user?\n");
026b1e278173a87acfffc3dd69c71766b7259b5evboxsync /** @todo Add more here. */
026b1e278173a87acfffc3dd69c71766b7259b5evboxsync }
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync }
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync }
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync uint32_t uSessionStatus = GUEST_SESSION_NOTIFYTYPE_UNDEFINED;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync uint32_t uSessionRc = VINF_SUCCESS; /** uint32_t vs. int. */
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync if (fProcessAlive)
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync {
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync for (int i = 0; i < 3; i++)
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync {
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync VBoxServiceVerbose(2, "Guest session ID=%RU32 process still alive, killing attempt %d/3\n",
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync uSessionID, i + 1);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync rc = RTProcTerminate(pThread->hProcess);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync if (RT_SUCCESS(rc))
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync break;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync RTThreadSleep(3000);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync }
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync VBoxServiceVerbose(2, "Guest session ID=%RU32 process termination resulted in rc=%Rrc\n",
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync uSessionID, rc);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync uSessionStatus = RT_SUCCESS(rc)
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync ? GUEST_SESSION_NOTIFYTYPE_TOK : GUEST_SESSION_NOTIFYTYPE_TOA;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync }
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync else
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync if (RT_SUCCESS(rcWait))
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync switch (ProcessStatus.enmReason)
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync case RTPROCEXITREASON_NORMAL:
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync uSessionStatus = GUEST_SESSION_NOTIFYTYPE_TEN;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync break;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync case RTPROCEXITREASON_ABEND:
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync uSessionStatus = GUEST_SESSION_NOTIFYTYPE_TEA;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync break;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync case RTPROCEXITREASON_SIGNAL:
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync uSessionStatus = GUEST_SESSION_NOTIFYTYPE_TES;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync break;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync default:
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync AssertMsgFailed(("Unhandled process termination reason (%ld)\n",
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync ProcessStatus.enmReason));
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync uSessionStatus = GUEST_SESSION_NOTIFYTYPE_TEA;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync break;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync }
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync }
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync else
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync /* If we didn't find the guest process anymore, just assume it
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync * terminated normally. */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync uSessionStatus = GUEST_SESSION_NOTIFYTYPE_TEN;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync }
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync }
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync VBoxServiceVerbose(3, "Guest session ID=%RU32 thread ended with sessionStatus=%RU32, sessionRc=%Rrc\n",
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync uSessionID, uSessionStatus, uSessionRc);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync /* Report final status. */
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync Assert(uSessionStatus != GUEST_SESSION_NOTIFYTYPE_UNDEFINED);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync VBGLR3GUESTCTRLCMDCTX ctx = { uClientID, VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(uSessionID) };
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync rc2 = VbglR3GuestCtrlSessionNotify(&ctx,
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync uSessionStatus, uSessionRc);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync if (RT_FAILURE(rc2))
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync VBoxServiceError("Reporting session ID=%RU32 final status failed with rc=%Rrc\n",
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync uSessionID, rc2);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync VbglR3GuestCtrlDisconnect(uClientID);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync VBoxServiceVerbose(3, "Session ID=%RU32 thread ended with rc=%Rrc\n",
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync uSessionID, rc);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync return rc;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync}
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsyncRTEXITCODE gstcntlSessionForkWorker(PVBOXSERVICECTRLSESSION pSession)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync AssertPtrReturn(pSession, RTEXITCODE_FAILURE);
4260648b018894247c6a73e244050be76c28f857vboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync bool fSessionFilter = true;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync VBoxServiceVerbose(0, "Hi, this is guest session ID=%RU32\n",
4260648b018894247c6a73e244050be76c28f857vboxsync pSession->StartupInfo.uSessionID);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uClientID;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc = VbglR3GuestCtrlConnect(&uClientID);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
d528a04fa09ef242ac61f49472a5f1027b6b33e5vboxsync /* Set session filter. This prevents the guest control
d528a04fa09ef242ac61f49472a5f1027b6b33e5vboxsync * host service to send messages which belong to another
d528a04fa09ef242ac61f49472a5f1027b6b33e5vboxsync * session we don't want to handle. */
4260648b018894247c6a73e244050be76c28f857vboxsync uint32_t uFilterAdd =
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync VBOX_GUESTCTRL_FILTER_BY_SESSION(pSession->StartupInfo.uSessionID);
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync rc = VbglR3GuestCtrlMsgFilterSet(uClientID,
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(pSession->StartupInfo.uSessionID),
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync uFilterAdd, 0 /* Filter remove */);
d528a04fa09ef242ac61f49472a5f1027b6b33e5vboxsync VBoxServiceVerbose(3, "Setting message filterAdd=0x%x returned %Rrc\n",
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync uFilterAdd, rc);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if ( RT_FAILURE(rc)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync && rc == VERR_NOT_SUPPORTED)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* No session filter available. Skip. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync fSessionFilter = false;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VINF_SUCCESS;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync VBoxServiceVerbose(1, "Using client ID=%RU32\n", uClientID);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync else
4260648b018894247c6a73e244050be76c28f857vboxsync VBoxServiceError("Error connecting to guest control service, rc=%Rrc\n", rc);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync /* Report started status. */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync VBGLR3GUESTCTRLCMDCTX ctx = { uClientID, VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(pSession->StartupInfo.uSessionID) };
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync int rc2 = VbglR3GuestCtrlSessionNotify(&ctx,
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync GUEST_SESSION_NOTIFYTYPE_STARTED, VINF_SUCCESS);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync if (RT_FAILURE(rc2))
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync VBoxServiceError("Reporting session ID=%RU32 started status failed with rc=%Rrc\n",
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync pSession->StartupInfo.uSessionID, rc2);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /*
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync * If session status cannot be posted to the host for
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync * some reason, bail out.
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync */
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (RT_SUCCESS(rc))
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync rc = rc2;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Allocate a scratch buffer for commands which also send
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * payload data with them. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t cbScratchBuf = _64K; /** @todo Make buffer size configurable via guest properties/argv! */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertReturn(RT_IS_POWER_OF_TWO(cbScratchBuf), RTEXITCODE_FAILURE);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint8_t *pvScratchBuf = NULL;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pvScratchBuf = (uint8_t*)RTMemAlloc(cbScratchBuf);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (!pvScratchBuf)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NO_MEMORY;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync bool fShutdown = false;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync VBGLR3GUESTCTRLCMDCTX ctxHost = { uClientID, 0 /* Context ID, zeroed */,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync pSession->StartupInfo.uProtocol };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync for (;;)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(3, "Waiting for host msg ...\n");
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uMsg = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t cParms = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VbglR3GuestCtrlMsgWaitFor(uClientID, &uMsg, &cParms);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (rc == VERR_TOO_MUCH_DATA)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync#ifdef DEBUG
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(4, "Message requires %RU32 parameters, but only 2 supplied -- retrying request (no error!)...\n", cParms);
14dd3a4fb403e2c27503be7dc22b85e5a3732e9dvboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VINF_SUCCESS; /* Try to get "real" message in next block below. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else if (RT_FAILURE(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(3, "Getting host message failed with %Rrc\n", rc); /* VERR_GEN_IO_FAILURE seems to be normal if ran into timeout. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
81096b0da0061583a511da27088643aa949a1ec9vboxsync VBoxServiceVerbose(4, "Msg=%RU32 (%RU32 parms) retrieved\n", uMsg, cParms);
81096b0da0061583a511da27088643aa949a1ec9vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync /* Set number of parameters for current host context. */
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync ctxHost.uNumParms = cParms;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync /* ... and pass it on to the session handler. */
4260648b018894247c6a73e244050be76c28f857vboxsync rc = GstCntlSessionHandler(pSession, uMsg, &ctxHost,
4260648b018894247c6a73e244050be76c28f857vboxsync pvScratchBuf, cbScratchBuf, &fShutdown);
4260648b018894247c6a73e244050be76c28f857vboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync if (fShutdown)
4260648b018894247c6a73e244050be76c28f857vboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync /* Let's sleep for a bit and let others run ... */
4260648b018894247c6a73e244050be76c28f857vboxsync RTThreadYield();
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync VBoxServiceVerbose(0, "Session %RU32 ended\n", pSession->StartupInfo.uSessionID);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync if (pvScratchBuf)
4260648b018894247c6a73e244050be76c28f857vboxsync RTMemFree(pvScratchBuf);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (uClientID)
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync {
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync VBoxServiceVerbose(3, "Disconnecting client ID=%RU32 ...\n", uClientID);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync VbglR3GuestCtrlDisconnect(uClientID);
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync VBoxServiceVerbose(3, "Session worker returned with rc=%Rrc\n", rc);
4260648b018894247c6a73e244050be76c28f857vboxsync return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
4260648b018894247c6a73e244050be76c28f857vboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync/**
81c1b367548a9be74982fcbc058cbb0c243f5217vboxsync * Finds a (formerly) started guest process given by its PID and increases
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync * its reference count. Must be decreased by the caller with GstCntlProcessRelease().
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * Note: This does *not lock the process!
4260648b018894247c6a73e244050be76c28f857vboxsync *
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * @return PVBOXSERVICECTRLTHREAD Guest process if found, otherwise NULL.
4260648b018894247c6a73e244050be76c28f857vboxsync * @param PVBOXSERVICECTRLSESSION Pointer to guest session where to search process in.
4260648b018894247c6a73e244050be76c28f857vboxsync * @param uPID PID to search for.
4260648b018894247c6a73e244050be76c28f857vboxsync */
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsyncPVBOXSERVICECTRLPROCESS GstCntlSessionRetainProcess(PVBOXSERVICECTRLSESSION pSession, uint32_t uPID)
4260648b018894247c6a73e244050be76c28f857vboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, NULL);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync PVBOXSERVICECTRLPROCESS pProcess = NULL;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync int rc = RTCritSectEnter(&pSession->CritSect);
4260648b018894247c6a73e244050be76c28f857vboxsync if (RT_SUCCESS(rc))
4260648b018894247c6a73e244050be76c28f857vboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync PVBOXSERVICECTRLPROCESS pCurProcess;
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync RTListForEach(&pSession->lstProcesses, pCurProcess, VBOXSERVICECTRLPROCESS, Node)
4260648b018894247c6a73e244050be76c28f857vboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync if (pCurProcess->uPID == uPID)
4260648b018894247c6a73e244050be76c28f857vboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync rc = RTCritSectEnter(&pCurProcess->CritSect);
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync if (RT_SUCCESS(rc))
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync {
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync pCurProcess->cRefs++;
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync rc = RTCritSectLeave(&pCurProcess->CritSect);
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync AssertRC(rc);
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync }
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync if (RT_SUCCESS(rc))
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync pProcess = pCurProcess;
4260648b018894247c6a73e244050be76c28f857vboxsync break;
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync rc = RTCritSectLeave(&pSession->CritSect);
a8eb7fc5c25340796ead9a42000b9c9f1695dc4bvboxsync AssertRC(rc);
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync return pProcess;
4260648b018894247c6a73e244050be76c28f857vboxsync}
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsyncint GstCntlSessionClose(PVBOXSERVICECTRLSESSION pSession)
4260648b018894247c6a73e244050be76c28f857vboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync VBoxServiceVerbose(0, "Session %RU32 is about to close ...\n",
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync pSession->StartupInfo.uSessionID);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync int rc = RTCritSectEnter(&pSession->CritSect);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync if (RT_SUCCESS(rc))
4260648b018894247c6a73e244050be76c28f857vboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync /*
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync * Close all guest processes.
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync */
9759711377ef1968c1a907f90d431df4b01d6dddvboxsync VBoxServiceVerbose(0, "Stopping all guest processes ...\n");
4260648b018894247c6a73e244050be76c28f857vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync /* Signal all guest processes in the active list that we want to shutdown. */
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync size_t cProcesses = 0;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync PVBOXSERVICECTRLPROCESS pProcess;
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync RTListForEach(&pSession->lstProcesses, pProcess, VBOXSERVICECTRLPROCESS, Node)
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync GstCntlProcessStop(pProcess);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync cProcesses++;
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync }
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync VBoxServiceVerbose(1, "%zu guest processes were signalled to stop\n", cProcesses);
9759711377ef1968c1a907f90d431df4b01d6dddvboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync /* Wait for all active threads to shutdown and destroy the active thread list. */
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync pProcess = RTListGetFirst(&pSession->lstProcesses, VBOXSERVICECTRLPROCESS, Node);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync while (pProcess)
4260648b018894247c6a73e244050be76c28f857vboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync PVBOXSERVICECTRLPROCESS pNext = RTListNodeGetNext(&pProcess->Node, VBOXSERVICECTRLPROCESS, Node);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync bool fLast = RTListNodeIsLast(&pSession->lstProcesses, &pProcess->Node);
4260648b018894247c6a73e244050be76c28f857vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync int rc2 = RTCritSectLeave(&pSession->CritSect);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync AssertRC(rc2);
4260648b018894247c6a73e244050be76c28f857vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync rc2 = GstCntlProcessWait(pProcess,
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync 30 * 1000 /* Wait 30 seconds max. */,
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync NULL /* rc */);
9759711377ef1968c1a907f90d431df4b01d6dddvboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync int rc3 = RTCritSectEnter(&pSession->CritSect);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync AssertRC(rc3);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync if (RT_SUCCESS(rc2))
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync GstCntlProcessFree(pProcess);
4260648b018894247c6a73e244050be76c28f857vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync if (fLast)
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync break;
4260648b018894247c6a73e244050be76c28f857vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync pProcess = pNext;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync }
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync#ifdef DEBUG
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync pProcess = RTListGetFirst(&pSession->lstProcesses, VBOXSERVICECTRLPROCESS, Node);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync while (pProcess)
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync {
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync PVBOXSERVICECTRLPROCESS pNext = RTListNodeGetNext(&pProcess->Node, VBOXSERVICECTRLPROCESS, Node);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync bool fLast = RTListNodeIsLast(&pSession->lstProcesses, &pProcess->Node);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync VBoxServiceVerbose(1, "Process %p (PID %RU32) still in list\n",
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync pProcess, pProcess->uPID);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync if (fLast)
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync break;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync pProcess = pNext;
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync }
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync#endif
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync AssertMsg(RTListIsEmpty(&pSession->lstProcesses),
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync ("Guest process list still contains entries when it should not\n"));
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync /*
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync * Close all left guest files.
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync */
9759711377ef1968c1a907f90d431df4b01d6dddvboxsync VBoxServiceVerbose(0, "Closing all guest files ...\n");
9759711377ef1968c1a907f90d431df4b01d6dddvboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync PVBOXSERVICECTRLFILE pFile;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync pFile = RTListGetFirst(&pSession->lstFiles, VBOXSERVICECTRLFILE, Node);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync while (pFile)
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync PVBOXSERVICECTRLFILE pNext = RTListNodeGetNext(&pFile->Node, VBOXSERVICECTRLFILE, Node);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync bool fLast = RTListNodeIsLast(&pSession->lstFiles, &pFile->Node);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync int rc2 = gstcntlSessionFileDestroy(pFile);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync if (RT_FAILURE(rc2))
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync VBoxServiceError("Unable to close file \"%s\"; rc=%Rrc\n",
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync pFile->szName, rc2);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync if (RT_SUCCESS(rc))
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync rc = rc2;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync /* Keep going. */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync }
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync if (fLast)
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync break;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync pFile = pNext;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync }
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync AssertMsg(RTListIsEmpty(&pSession->lstFiles),
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync ("Guest file list still contains entries when it should not\n"));
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync int rc2 = RTCritSectLeave(&pSession->CritSect);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync if (RT_SUCCESS(rc))
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync rc = rc2;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync }
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync return rc;
4260648b018894247c6a73e244050be76c28f857vboxsync}
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsyncint GstCntlSessionDestroy(PVBOXSERVICECTRLSESSION pSession)
4260648b018894247c6a73e244050be76c28f857vboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync int rc = GstCntlSessionClose(pSession);
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync /* Destroy critical section. */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync RTCritSectDelete(&pSession->CritSect);
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync return rc;
4260648b018894247c6a73e244050be76c28f857vboxsync}
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsyncint GstCntlSessionInit(PVBOXSERVICECTRLSESSION pSession, uint32_t uFlags)
4260648b018894247c6a73e244050be76c28f857vboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync RTListInit(&pSession->lstProcesses);
4260648b018894247c6a73e244050be76c28f857vboxsync RTListInit(&pSession->lstFiles);
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync pSession->uFlags = uFlags;
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync /* Init critical section for protecting the thread lists. */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync int rc = RTCritSectInit(&pSession->CritSect);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertRC(rc);
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync return rc;
4260648b018894247c6a73e244050be76c28f857vboxsync}
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync/**
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * Adds a guest process to a session's process list.
4260648b018894247c6a73e244050be76c28f857vboxsync *
4260648b018894247c6a73e244050be76c28f857vboxsync * @return IPRT status code.
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * @param pSession Guest session to add process to.
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * @param pProcess Guest process to add.
4260648b018894247c6a73e244050be76c28f857vboxsync */
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsyncint GstCntlSessionProcessAdd(PVBOXSERVICECTRLSESSION pSession,
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync PVBOXSERVICECTRLPROCESS pProcess)
4260648b018894247c6a73e244050be76c28f857vboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync AssertPtrReturn(pProcess, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync int rc = RTCritSectEnter(&pSession->CritSect);
4260648b018894247c6a73e244050be76c28f857vboxsync if (RT_SUCCESS(rc))
4260648b018894247c6a73e244050be76c28f857vboxsync {
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync VBoxServiceVerbose(3, "Adding process (PID %RU32) to session ID=%RU32\n",
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync pProcess->uPID, pSession->StartupInfo.uSessionID);
4260648b018894247c6a73e244050be76c28f857vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync /* Add process to session list. */
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync /* rc = */ RTListAppend(&pSession->lstProcesses, &pProcess->Node);
4260648b018894247c6a73e244050be76c28f857vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync int rc2 = RTCritSectLeave(&pSession->CritSect);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync if (RT_SUCCESS(rc))
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync rc = rc2;
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync return VINF_SUCCESS;
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync}
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync/**
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * Removes a guest process from a session's process list.
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync *
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * @return IPRT status code.
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * @param pSession Guest session to remove process from.
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * @param pProcess Guest process to remove.
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync */
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsyncint GstCntlSessionProcessRemove(PVBOXSERVICECTRLSESSION pSession,
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync PVBOXSERVICECTRLPROCESS pProcess)
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync{
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync AssertPtrReturn(pProcess, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync int rc = RTCritSectEnter(&pSession->CritSect);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync if (RT_SUCCESS(rc))
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync {
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync VBoxServiceVerbose(3, "Removing process (PID %RU32) from session ID=%RU32\n",
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync pProcess->uPID, pSession->StartupInfo.uSessionID);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync Assert(pProcess->cRefs == 0);
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync RTListNodeRemove(&pProcess->Node);
4260648b018894247c6a73e244050be76c28f857vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync int rc2 = RTCritSectLeave(&pSession->CritSect);
4260648b018894247c6a73e244050be76c28f857vboxsync if (RT_SUCCESS(rc))
4260648b018894247c6a73e244050be76c28f857vboxsync rc = rc2;
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync return VINF_SUCCESS;
4260648b018894247c6a73e244050be76c28f857vboxsync}
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync/**
4260648b018894247c6a73e244050be76c28f857vboxsync * Determines whether starting a new guest process according to the
4260648b018894247c6a73e244050be76c28f857vboxsync * maximum number of concurrent guest processes defined is allowed or not.
4260648b018894247c6a73e244050be76c28f857vboxsync *
4260648b018894247c6a73e244050be76c28f857vboxsync * @return IPRT status code.
4260648b018894247c6a73e244050be76c28f857vboxsync * @param pbAllowed True if starting (another) guest process
4260648b018894247c6a73e244050be76c28f857vboxsync * is allowed, false if not.
4260648b018894247c6a73e244050be76c28f857vboxsync */
4260648b018894247c6a73e244050be76c28f857vboxsyncint GstCntlSessionProcessStartAllowed(const PVBOXSERVICECTRLSESSION pSession,
4260648b018894247c6a73e244050be76c28f857vboxsync bool *pbAllowed)
4260648b018894247c6a73e244050be76c28f857vboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pbAllowed, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync int rc = RTCritSectEnter(&pSession->CritSect);
4260648b018894247c6a73e244050be76c28f857vboxsync if (RT_SUCCESS(rc))
4260648b018894247c6a73e244050be76c28f857vboxsync {
4260648b018894247c6a73e244050be76c28f857vboxsync /*
4260648b018894247c6a73e244050be76c28f857vboxsync * Check if we're respecting our memory policy by checking
4260648b018894247c6a73e244050be76c28f857vboxsync * how many guest processes are started and served already.
4260648b018894247c6a73e244050be76c28f857vboxsync */
4260648b018894247c6a73e244050be76c28f857vboxsync bool fLimitReached = false;
4260648b018894247c6a73e244050be76c28f857vboxsync if (pSession->uProcsMaxKept) /* If we allow unlimited processes (=0), take a shortcut. */
4260648b018894247c6a73e244050be76c28f857vboxsync {
4260648b018894247c6a73e244050be76c28f857vboxsync uint32_t uProcsRunning = 0;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync PVBOXSERVICECTRLPROCESS pProcess;
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync RTListForEach(&pSession->lstProcesses, pProcess, VBOXSERVICECTRLPROCESS, Node)
4260648b018894247c6a73e244050be76c28f857vboxsync uProcsRunning++;
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync VBoxServiceVerbose(3, "Maximum served guest processes set to %u, running=%u\n",
4260648b018894247c6a73e244050be76c28f857vboxsync pSession->uProcsMaxKept, uProcsRunning);
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync int32_t iProcsLeft = (pSession->uProcsMaxKept - uProcsRunning - 1);
4260648b018894247c6a73e244050be76c28f857vboxsync if (iProcsLeft < 0)
4260648b018894247c6a73e244050be76c28f857vboxsync {
4260648b018894247c6a73e244050be76c28f857vboxsync VBoxServiceVerbose(3, "Maximum running guest processes reached (%u)\n",
4260648b018894247c6a73e244050be76c28f857vboxsync pSession->uProcsMaxKept);
4260648b018894247c6a73e244050be76c28f857vboxsync fLimitReached = true;
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync *pbAllowed = !fLimitReached;
4260648b018894247c6a73e244050be76c28f857vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync int rc2 = RTCritSectLeave(&pSession->CritSect);
4260648b018894247c6a73e244050be76c28f857vboxsync if (RT_SUCCESS(rc))
4260648b018894247c6a73e244050be76c28f857vboxsync rc = rc2;
4260648b018894247c6a73e244050be76c28f857vboxsync }
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync return rc;
4260648b018894247c6a73e244050be76c28f857vboxsync}
4260648b018894247c6a73e244050be76c28f857vboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/**
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Creates a guest session. This will spawn a new VBoxService.exe instance under
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * behalf of the given user which then will act as a session host. On successful
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync * open, the session will be added to the given session thread list.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync *
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @return IPRT status code.
4260648b018894247c6a73e244050be76c28f857vboxsync * @param pList Which list to use to store the session thread in.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param pSessionStartupInfo Session startup info.
4260648b018894247c6a73e244050be76c28f857vboxsync * @param ppSessionThread Returns newly created session thread on success.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Optional.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsyncint GstCntlSessionThreadCreate(PRTLISTANCHOR pList,
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync const PVBOXSERVICECTRLSESSIONSTARTUPINFO pSessionStartupInfo,
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync PVBOXSERVICECTRLSESSIONTHREAD *ppSessionThread)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pList, VERR_INVALID_POINTER);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertPtrReturn(pSessionStartupInfo, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync /* ppSessionThread is optional. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#ifdef DEBUG
4260648b018894247c6a73e244050be76c28f857vboxsync PVBOXSERVICECTRLSESSIONTHREAD pSessionCur;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Check for existing session in debug mode. Should never happen because of
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Main consistency. */
4260648b018894247c6a73e244050be76c28f857vboxsync RTListForEach(pList, pSessionCur, VBOXSERVICECTRLSESSIONTHREAD, Node)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pSessionCur->StartupInfo.uSessionID == pSessionStartupInfo->uSessionID)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync AssertMsgFailed(("Guest session thread ID=%RU32 (%p) already exists when it should not\n",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSessionCur->StartupInfo.uSessionID, pSessionCur));
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return VERR_ALREADY_EXISTS;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc = VINF_SUCCESS;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync /* Static counter to help tracking session thread <-> process relations. */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync static uint32_t s_uCtrlSessionThread = 0;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync if (s_uCtrlSessionThread++ == UINT32_MAX)
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync s_uCtrlSessionThread = 0; /* Wrap around to not let IPRT freak out. */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync PVBOXSERVICECTRLSESSIONTHREAD pSessionThread =
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync (PVBOXSERVICECTRLSESSIONTHREAD)RTMemAllocZ(sizeof(VBOXSERVICECTRLSESSIONTHREAD));
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync if (pSessionThread)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Copy over session startup info. */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync memcpy(&pSessionThread->StartupInfo, pSessionStartupInfo,
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync sizeof(VBOXSERVICECTRLSESSIONSTARTUPINFO));
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync pSessionThread->fShutdown = false;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync pSessionThread->fStarted = false;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync pSessionThread->fStopped = false;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync /* Is this an anonymous session? */
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync /* Anonymous sessions run with the same privileges as the main VBoxService executable. */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync bool fAnonymous = !RT_BOOL(strlen(pSessionThread->StartupInfo.szUser));
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync if (fAnonymous)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync Assert(!strlen(pSessionThread->StartupInfo.szPassword));
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync Assert(!strlen(pSessionThread->StartupInfo.szDomain));
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync VBoxServiceVerbose(3, "New anonymous guest session ID=%RU32 created, uFlags=%x, using protocol %RU32\n",
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync pSessionStartupInfo->uSessionID,
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync pSessionStartupInfo->uFlags,
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync pSessionStartupInfo->uProtocol);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync }
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync else
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync {
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync VBoxServiceVerbose(3, "Forking new guest session ID=%RU32, szUser=%s, szPassword=%s, szDomain=%s, uFlags=%x, using protocol %RU32\n",
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync pSessionStartupInfo->uSessionID,
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync pSessionStartupInfo->szUser,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#ifdef DEBUG
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync pSessionStartupInfo->szPassword,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#else
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync "XXX", /* Never show passwords in release mode. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#endif
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync pSessionStartupInfo->szDomain,
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync pSessionStartupInfo->uFlags,
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync pSessionStartupInfo->uProtocol);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync rc = RTCritSectInit(&pSessionThread->CritSect);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertRC(rc);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Fork child doing the actual session handling. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync char szExeName[RTPATH_MAX];
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync char *pszExeName = RTProcGetExecutablePath(szExeName, sizeof(szExeName));
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pszExeName)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync char szParmUserName[GUESTPROCESS_MAX_USER_LEN + 32];
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync if (!fAnonymous)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync if (!RTStrPrintf(szParmUserName, sizeof(szParmUserName), "--user=%s", pSessionThread->StartupInfo.szUser))
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync rc = VERR_BUFFER_OVERFLOW;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync char szParmSessionID[32];
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc) && !RTStrPrintf(szParmSessionID, sizeof(szParmSessionID), "--session-id=%RU32",
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync pSessionThread->StartupInfo.uSessionID))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_BUFFER_OVERFLOW;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync char szParmSessionProto[32];
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc) && !RTStrPrintf(szParmSessionProto, sizeof(szParmSessionProto), "--session-proto=%RU32",
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync pSessionThread->StartupInfo.uProtocol))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_BUFFER_OVERFLOW;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync#ifdef DEBUG
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync char szParmThreadId[32];
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync if (RT_SUCCESS(rc) && !RTStrPrintf(szParmThreadId, sizeof(szParmThreadId), "--thread-id=%RU32",
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync s_uCtrlSessionThread))
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync rc = VERR_BUFFER_OVERFLOW;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync }
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync#endif /* DEBUG */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int iOptIdx = 0; /* Current index in argument vector. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync char const *papszArgs[16];
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync papszArgs[iOptIdx++] = pszExeName;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync papszArgs[iOptIdx++] = "guestsession";
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync papszArgs[iOptIdx++] = szParmSessionID;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync papszArgs[iOptIdx++] = szParmSessionProto;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync#ifdef DEBUG
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync papszArgs[iOptIdx++] = szParmThreadId;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync#endif /* DEBUG */
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync if (!fAnonymous)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync papszArgs[iOptIdx++] = szParmUserName;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Add same verbose flags as parent process. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc2 = VINF_SUCCESS;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync char szParmVerbose[32] = { 0 };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync for (int i = 0; i < g_cVerbosity && RT_SUCCESS(rc2); i++)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (i == 0)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc2 = RTStrCat(szParmVerbose, sizeof(szParmVerbose), "-");
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_FAILURE(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc2 = RTStrCat(szParmVerbose, sizeof(szParmVerbose), "v");
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync papszArgs[iOptIdx++] = szParmVerbose;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Add log file handling. Each session will have an own
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * log file, naming based on the parent log file. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync char szParmLogFile[RTPATH_MAX];
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if ( RT_SUCCESS(rc2)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync && strlen(g_szLogFile))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync char *pszLogFile = RTStrDup(g_szLogFile);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pszLogFile)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
d1bb48754376874c3cc6b1091a6abec549663c0cvboxsync char *pszLogSuff = NULL;
d1bb48754376874c3cc6b1091a6abec549663c0cvboxsync if (RTPathHasSuffix(pszLogFile))
d1bb48754376874c3cc6b1091a6abec549663c0cvboxsync pszLogSuff = RTStrDup(RTPathSuffix(pszLogFile));
d1bb48754376874c3cc6b1091a6abec549663c0cvboxsync RTPathStripSuffix(pszLogFile);
d1bb48754376874c3cc6b1091a6abec549663c0cvboxsync char *pszLogNewSuffix;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync#ifndef DEBUG
d1bb48754376874c3cc6b1091a6abec549663c0cvboxsync if (RTStrAPrintf(&pszLogNewSuffix, "-%RU32-%s",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSessionStartupInfo->uSessionID,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSessionStartupInfo->szUser) < 0)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc2 = VERR_NO_MEMORY;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync#else
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /* Include the session thread ID in the log file name. */
d1bb48754376874c3cc6b1091a6abec549663c0cvboxsync if (RTStrAPrintf(&pszLogNewSuffix, "-%RU32-%RU32-%s",
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync pSessionStartupInfo->uSessionID,
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync s_uCtrlSessionThread,
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync pSessionStartupInfo->szUser) < 0)
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync rc2 = VERR_NO_MEMORY;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync }
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync#endif /* DEBUG */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
d1bb48754376874c3cc6b1091a6abec549663c0cvboxsync rc2 = RTStrAAppend(&pszLogFile, pszLogNewSuffix);
d1bb48754376874c3cc6b1091a6abec549663c0cvboxsync if (RT_SUCCESS(rc2) && pszLogSuff)
d1bb48754376874c3cc6b1091a6abec549663c0cvboxsync rc2 = RTStrAAppend(&pszLogFile, pszLogSuff);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (!RTStrPrintf(szParmLogFile, sizeof(szParmLogFile),
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync "--logfile=%s", pszLogFile))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc2 = VERR_BUFFER_OVERFLOW;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
d1bb48754376874c3cc6b1091a6abec549663c0cvboxsync RTStrFree(pszLogNewSuffix);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_FAILURE(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceError("Error building session logfile string for session %RU32 (user %s), rc=%Rrc\n",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSessionStartupInfo->uSessionID, pSessionStartupInfo->szUser, rc2);
d1bb48754376874c3cc6b1091a6abec549663c0cvboxsync if (pszLogSuff)
d1bb48754376874c3cc6b1091a6abec549663c0cvboxsync RTStrFree(pszLogSuff);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTStrFree(pszLogFile);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync papszArgs[iOptIdx++] = szParmLogFile;
27d188eaec68419914903b118f1428ad597584d8vboxsync
27d188eaec68419914903b118f1428ad597584d8vboxsync rc = rc2;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
27d188eaec68419914903b118f1428ad597584d8vboxsync else if (RT_FAILURE(rc2))
27d188eaec68419914903b118f1428ad597584d8vboxsync rc = rc2;
27d188eaec68419914903b118f1428ad597584d8vboxsync#ifdef DEBUG
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync VBoxServiceVerbose(4, "Argv building rc=%Rrc, session flags=%x\n",
27d188eaec68419914903b118f1428ad597584d8vboxsync rc, g_Session.uFlags);
27d188eaec68419914903b118f1428ad597584d8vboxsync char szParmDumpStdOut[32];
27d188eaec68419914903b118f1428ad597584d8vboxsync if ( RT_SUCCESS(rc)
27d188eaec68419914903b118f1428ad597584d8vboxsync && g_Session.uFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDOUT)
27d188eaec68419914903b118f1428ad597584d8vboxsync {
27d188eaec68419914903b118f1428ad597584d8vboxsync if (!RTStrPrintf(szParmDumpStdOut, sizeof(szParmDumpStdOut), "--dump-stdout"))
27d188eaec68419914903b118f1428ad597584d8vboxsync rc = VERR_BUFFER_OVERFLOW;
27d188eaec68419914903b118f1428ad597584d8vboxsync if (RT_SUCCESS(rc))
27d188eaec68419914903b118f1428ad597584d8vboxsync papszArgs[iOptIdx++] = szParmDumpStdOut;
27d188eaec68419914903b118f1428ad597584d8vboxsync }
27d188eaec68419914903b118f1428ad597584d8vboxsync char szParmDumpStdErr[32];
27d188eaec68419914903b118f1428ad597584d8vboxsync if ( RT_SUCCESS(rc)
27d188eaec68419914903b118f1428ad597584d8vboxsync && g_Session.uFlags & VBOXSERVICECTRLSESSION_FLAG_DUMPSTDERR)
27d188eaec68419914903b118f1428ad597584d8vboxsync {
27d188eaec68419914903b118f1428ad597584d8vboxsync if (!RTStrPrintf(szParmDumpStdErr, sizeof(szParmDumpStdErr), "--dump-stderr"))
27d188eaec68419914903b118f1428ad597584d8vboxsync rc = VERR_BUFFER_OVERFLOW;
27d188eaec68419914903b118f1428ad597584d8vboxsync if (RT_SUCCESS(rc))
27d188eaec68419914903b118f1428ad597584d8vboxsync papszArgs[iOptIdx++] = szParmDumpStdErr;
27d188eaec68419914903b118f1428ad597584d8vboxsync }
27d188eaec68419914903b118f1428ad597584d8vboxsync#endif
27d188eaec68419914903b118f1428ad597584d8vboxsync papszArgs[iOptIdx++] = NULL;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (g_cVerbosity > 3)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(4, "Forking parameters:\n");
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync iOptIdx = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync while (papszArgs[iOptIdx])
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(4, "\t%s\n", papszArgs[iOptIdx++]);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uProcFlags = RTPROC_FLAGS_SERVICE
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync | RTPROC_FLAGS_HIDDEN; /** @todo More flags from startup info? */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
bbdd3a289839096f1a15979598e686f25fcacfc1vboxsync /*
bbdd3a289839096f1a15979598e686f25fcacfc1vboxsync * Create the session process' environment block.
bbdd3a289839096f1a15979598e686f25fcacfc1vboxsync */
bbdd3a289839096f1a15979598e686f25fcacfc1vboxsync RTENV hEnv = NIL_RTENV;
bbdd3a289839096f1a15979598e686f25fcacfc1vboxsync if (RT_SUCCESS(rc))
bbdd3a289839096f1a15979598e686f25fcacfc1vboxsync {
bbdd3a289839096f1a15979598e686f25fcacfc1vboxsync /** @todo At the moment a session process does not have the ability to use the
bbdd3a289839096f1a15979598e686f25fcacfc1vboxsync * per-session environment variables itself, only the session's guest
bbdd3a289839096f1a15979598e686f25fcacfc1vboxsync * processes do so. Implement that later, also needs tweaking of
bbdd3a289839096f1a15979598e686f25fcacfc1vboxsync * VbglR3GuestCtrlSessionGetOpen(). */
bbdd3a289839096f1a15979598e686f25fcacfc1vboxsync rc = RTEnvClone(&hEnv, RTENV_DEFAULT);
bbdd3a289839096f1a15979598e686f25fcacfc1vboxsync }
bbdd3a289839096f1a15979598e686f25fcacfc1vboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#if 0 /* Pipe handling not needed (yet). */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Setup pipes. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = GstcntlProcessSetupPipe("|", 0 /*STDIN_FILENO*/,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &pSession->StdIn.hChild, &pSession->StdIn.phChild, &pSession->hStdInW);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = GstcntlProcessSetupPipe("|", 1 /*STDOUT_FILENO*/,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &pSession->StdOut.hChild, &pSession->StdOut.phChild, &pSession->hStdOutR);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = GstcntlProcessSetupPipe("|", 2 /*STDERR_FILENO*/,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &pSession->StdErr.hChild, &pSession->StdErr.phChild, &pSession->hStdErrR);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = RTPollSetCreate(&pSession->hPollSet);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = RTPollSetAddPipe(pSession->hPollSet, pSession->hStdInW, RTPOLL_EVT_ERROR,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBOXSERVICECTRLPIPEID_STDIN);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = RTPollSetAddPipe(pSession->hPollSet, pSession->hStdOutR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBOXSERVICECTRLPIPEID_STDOUT);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = RTPollSetAddPipe(pSession->hPollSet, pSession->hStdErrR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBOXSERVICECTRLPIPEID_STDERR);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
bbdd3a289839096f1a15979598e686f25fcacfc1vboxsync rc = RTProcCreateEx(pszExeName, papszArgs, hEnv, uProcFlags,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSession->StdIn.phChild, pSession->StdOut.phChild, pSession->StdErr.phChild,
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync !fAnonymous ? pSession->StartupInfo.szUser : NULL,
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync !fAnonymous ? pSession->StartupInfo.szPassword : NULL,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &pSession->hProcess);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /*
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Close the child ends of any pipes and redirected files.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc2 = RTHandleClose(pSession->StdIn.phChild); AssertRC(rc2);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSession->StdIn.phChild = NULL;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc2 = RTHandleClose(pSession->StdOut.phChild); AssertRC(rc2);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSession->StdOut.phChild = NULL;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc2 = RTHandleClose(pSession->StdErr.phChild); AssertRC(rc2);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSession->StdErr.phChild = NULL;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#else
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync RTHANDLE hStdIn;
27d188eaec68419914903b118f1428ad597584d8vboxsync if (RT_SUCCESS(rc))
27d188eaec68419914903b118f1428ad597584d8vboxsync rc = RTFileOpenBitBucket(&hStdIn.u.hFile, RTFILE_O_READ);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync if (RT_SUCCESS(rc))
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync {
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync hStdIn.enmType = RTHANDLETYPE_FILE;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync RTHANDLE hStdOutAndErr;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync rc = RTFileOpenBitBucket(&hStdOutAndErr.u.hFile, RTFILE_O_WRITE);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync if (RT_SUCCESS(rc))
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync {
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync hStdOutAndErr.enmType = RTHANDLETYPE_FILE;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
bbdd3a289839096f1a15979598e686f25fcacfc1vboxsync rc = RTProcCreateEx(pszExeName, papszArgs, hEnv, uProcFlags,
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync &hStdIn, &hStdOutAndErr, &hStdOutAndErr,
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync !fAnonymous ? pSessionThread->StartupInfo.szUser : NULL,
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync !fAnonymous ? pSessionThread->StartupInfo.szPassword : NULL,
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync &pSessionThread->hProcess);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync RTFileClose(hStdOutAndErr.u.hFile);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync }
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync RTFileClose(hStdIn.u.hFile);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#endif
bbdd3a289839096f1a15979598e686f25fcacfc1vboxsync if (hEnv != NIL_RTENV)
bbdd3a289839096f1a15979598e686f25fcacfc1vboxsync RTEnvDestroy(hEnv);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_FILE_NOT_FOUND;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync /* Start session thread. */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync rc = RTThreadCreateF(&pSessionThread->Thread, gstcntlSessionThread,
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync pSessionThread /*pvUser*/, 0 /*cbStack*/,
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "sess%u", s_uCtrlSessionThread);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync if (RT_FAILURE(rc))
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync {
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync VBoxServiceError("Creating session thread failed, rc=%Rrc\n", rc);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync }
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync else
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync {
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync /* Wait for the thread to initialize. */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync rc = RTThreadUserWait(pSessionThread->Thread, 60 * 1000 /* 60s timeout */);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync if ( ASMAtomicReadBool(&pSessionThread->fShutdown)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync || RT_FAILURE(rc))
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync {
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync VBoxServiceError("Thread for session ID=%RU32 failed to start, rc=%Rrc\n",
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync pSessionThread->StartupInfo.uSessionID, rc);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync if (RT_SUCCESS(rc))
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync rc = VERR_CANT_CREATE; /** @todo Find a better rc. */
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync }
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync else
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync VBoxServiceVerbose(2, "Thread for session ID=%RU32 started\n",
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync pSessionThread->StartupInfo.uSessionID);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync ASMAtomicXchgBool(&pSessionThread->fStarted, true);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync /* Add session to list. */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync /* rc = */ RTListAppend(pList, &pSessionThread->Node);
4260648b018894247c6a73e244050be76c28f857vboxsync if (ppSessionThread) /* Return session if wanted. */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync *ppSessionThread = pSessionThread;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync }
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync if (RT_FAILURE(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync RTMemFree(pSessionThread);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NO_MEMORY;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync VBoxServiceVerbose(3, "Forking session thread returned returned rc=%Rrc\n", rc);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/**
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync * Waits for a formerly opened guest session process to close.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync *
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @return IPRT status code.
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync * @param pThread Guest session thread to wait for.
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync * @param uTimeoutMS Waiting timeout (in ms).
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * @param uFlags Closing flags.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsyncint GstCntlSessionThreadWait(PVBOXSERVICECTRLSESSIONTHREAD pThread,
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync uint32_t uTimeoutMS, uint32_t uFlags)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync AssertPtrReturn(pThread, VERR_INVALID_POINTER);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync /** @todo Validate closing flags. */
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync if (pThread->Thread == NIL_RTTHREAD)
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync AssertMsgFailed(("Guest session thread of session %p does not exist when it should\n",
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync pThread));
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync return VERR_NOT_FOUND;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync int rc = VINF_SUCCESS;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync /*
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync * The fork should have received the same closing request,
9759711377ef1968c1a907f90d431df4b01d6dddvboxsync * so just wait for the process to close.
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync */
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync if (ASMAtomicReadBool(&pThread->fStarted))
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync {
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync /* Ask the thread to shutdown. */
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync ASMAtomicXchgBool(&pThread->fShutdown, true);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync VBoxServiceVerbose(3, "Waiting for session thread ID=%RU32 to close (%RU32ms) ...\n",
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync pThread->StartupInfo.uSessionID, uTimeoutMS);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync int rcThread;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync rc = RTThreadWait(pThread->Thread, uTimeoutMS, &rcThread);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync if (RT_FAILURE(rc))
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync {
4260648b018894247c6a73e244050be76c28f857vboxsync VBoxServiceError("Waiting for session thread ID=%RU32 to close failed with rc=%Rrc\n",
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync pThread->StartupInfo.uSessionID, rc);
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync }
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync else
4260648b018894247c6a73e244050be76c28f857vboxsync VBoxServiceVerbose(3, "Session thread ID=%RU32 ended with rc=%Rrc\n",
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync pThread->StartupInfo.uSessionID, rcThread);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync }
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync return rc;
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync}
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync/**
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync * Waits for the specified session thread to end and remove
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync * it from the session thread list.
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync *
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync * @return IPRT status code.
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync * @param pThread Session thread to destroy.
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync * @param uFlags Closing flags.
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsyncint GstCntlSessionThreadDestroy(PVBOXSERVICECTRLSESSIONTHREAD pThread, uint32_t uFlags)
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync{
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync AssertPtrReturn(pThread, VERR_INVALID_POINTER);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync int rc = GstCntlSessionThreadWait(pThread,
9759711377ef1968c1a907f90d431df4b01d6dddvboxsync 5 * 60 * 1000 /* 5 minutes timeout */, uFlags);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync /* Remove session from list and destroy object. */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync RTListNodeRemove(&pThread->Node);
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync RTMemFree(pThread);
16db1eeb97dd76f4d94b4808171fb14461b135d2vboxsync pThread = NULL;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/**
4260648b018894247c6a73e244050be76c28f857vboxsync * Close all formerly opened guest session threads.
880dee6db77afb69b9a9a442bbf6e2981efce3f7vboxsync * Note: Caller is responsible for locking!
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync *
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @return IPRT status code.
4260648b018894247c6a73e244050be76c28f857vboxsync * @param pList Which list to close the session threads for.
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync * @param uFlags Closing flags.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsyncint GstCntlSessionThreadDestroyAll(PRTLISTANCHOR pList, uint32_t uFlags)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
4260648b018894247c6a73e244050be76c28f857vboxsync AssertPtrReturn(pList, VERR_INVALID_POINTER);
4260648b018894247c6a73e244050be76c28f857vboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc = VINF_SUCCESS;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync /*int rc = VbglR3GuestCtrlClose
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync if (RT_FAILURE(rc))
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync VBoxServiceError("Cancelling pending waits failed; rc=%Rrc\n", rc);*/
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync PVBOXSERVICECTRLSESSIONTHREAD pSessionThread
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync = RTListGetFirst(pList, VBOXSERVICECTRLSESSIONTHREAD, Node);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync while (pSessionThread)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync PVBOXSERVICECTRLSESSIONTHREAD pSessionThreadNext =
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync RTListGetNext(pList, pSessionThread, VBOXSERVICECTRLSESSIONTHREAD, Node);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync bool fLast = RTListNodeIsLast(pList, &pSessionThread->Node);
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync int rc2 = GstCntlSessionThreadDestroy(pSessionThread, uFlags);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync if (RT_FAILURE(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync VBoxServiceError("Closing session thread failed with rc=%Rrc\n", rc2);
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync if (RT_SUCCESS(rc))
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync rc = rc2;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Keep going. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync if (fLast)
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync break;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync pSessionThread = pSessionThreadNext;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync }
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync return rc;
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync}
3fb3de312d1ff675e0f7cc62a7d46cbb1d5d9353vboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncRTEXITCODE VBoxServiceControlSessionForkInit(int argc, char **argv)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync static const RTGETOPTDEF s_aOptions[] =
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
27d188eaec68419914903b118f1428ad597584d8vboxsync#ifdef DEBUG
27d188eaec68419914903b118f1428ad597584d8vboxsync { "--dump-stdout", VBOXSERVICESESSIONOPT_DUMP_STDOUT, RTGETOPT_REQ_NOTHING },
27d188eaec68419914903b118f1428ad597584d8vboxsync { "--dump-stderr", VBOXSERVICESESSIONOPT_DUMP_STDERR, RTGETOPT_REQ_NOTHING },
27d188eaec68419914903b118f1428ad597584d8vboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync { "--logfile", VBOXSERVICESESSIONOPT_LOG_FILE, RTGETOPT_REQ_STRING },
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync { "--user", VBOXSERVICESESSIONOPT_USERNAME, RTGETOPT_REQ_STRING },
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync { "--session-id", VBOXSERVICESESSIONOPT_SESSION_ID, RTGETOPT_REQ_UINT32 },
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync { "--session-proto", VBOXSERVICESESSIONOPT_SESSION_PROTO, RTGETOPT_REQ_UINT32 },
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync#ifdef DEBUG
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync { "--thread-id", VBOXSERVICESESSIONOPT_THREAD_ID, RTGETOPT_REQ_UINT32 },
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync#endif /* DEBUG */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync { "--verbose", 'v', RTGETOPT_REQ_NOTHING }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int ch;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTGETOPTUNION ValueUnion;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTGETOPTSTATE GetState;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTGetOptInit(&GetState, argc, argv,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync s_aOptions, RT_ELEMENTS(s_aOptions),
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync 1 /*iFirst*/, RTGETOPTINIT_FLAGS_OPTS_FIRST);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync uint32_t uSessionFlags = VBOXSERVICECTRLSESSION_FLAG_FORK;
4260648b018894247c6a73e244050be76c28f857vboxsync
27d188eaec68419914903b118f1428ad597584d8vboxsync /* Protocol and session ID must be specified explicitly. */
27d188eaec68419914903b118f1428ad597584d8vboxsync g_Session.StartupInfo.uProtocol = UINT32_MAX;
27d188eaec68419914903b118f1428ad597584d8vboxsync g_Session.StartupInfo.uSessionID = UINT32_MAX;
27d188eaec68419914903b118f1428ad597584d8vboxsync
27d188eaec68419914903b118f1428ad597584d8vboxsync int rc = VINF_SUCCESS;
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync while ( (ch = RTGetOpt(&GetState, &ValueUnion))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync && RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* For options that require an argument, ValueUnion has received the value. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync switch (ch)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case VBOXSERVICESESSIONOPT_LOG_FILE:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (!RTStrPrintf(g_szLogFile, sizeof(g_szLogFile), "%s", ValueUnion.psz))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Unable to set logfile name to '%s'",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync ValueUnion.psz);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
27d188eaec68419914903b118f1428ad597584d8vboxsync#ifdef DEBUG
27d188eaec68419914903b118f1428ad597584d8vboxsync case VBOXSERVICESESSIONOPT_DUMP_STDOUT:
27d188eaec68419914903b118f1428ad597584d8vboxsync uSessionFlags |= VBOXSERVICECTRLSESSION_FLAG_DUMPSTDOUT;
27d188eaec68419914903b118f1428ad597584d8vboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
27d188eaec68419914903b118f1428ad597584d8vboxsync case VBOXSERVICESESSIONOPT_DUMP_STDERR:
27d188eaec68419914903b118f1428ad597584d8vboxsync uSessionFlags |= VBOXSERVICECTRLSESSION_FLAG_DUMPSTDERR;
27d188eaec68419914903b118f1428ad597584d8vboxsync break;
27d188eaec68419914903b118f1428ad597584d8vboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case VBOXSERVICESESSIONOPT_USERNAME:
27d188eaec68419914903b118f1428ad597584d8vboxsync /** @todo Information not needed right now, skip. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case VBOXSERVICESESSIONOPT_SESSION_ID:
4260648b018894247c6a73e244050be76c28f857vboxsync g_Session.StartupInfo.uSessionID = ValueUnion.u32;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case VBOXSERVICESESSIONOPT_SESSION_PROTO:
4260648b018894247c6a73e244050be76c28f857vboxsync g_Session.StartupInfo.uProtocol = ValueUnion.u32;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync#ifdef DEBUG
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync case VBOXSERVICESESSIONOPT_THREAD_ID:
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync /* Not handled. */
c55bf74b54ecdfb5ebc4e5d90b620d0fee31737evboxsync break;
4171ffb38eb8720b2ae9a8d13e95103ab26cfd12vboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /** @todo Implement help? */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case 'v':
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync g_cVerbosity++;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case VINF_GETOPT_NOT_OPTION:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Ignore; might be "guestsession" main command. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync default:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown command '%s'", ValueUnion.psz);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break; /* Never reached. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_FAILURE(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Initialization failed with rc=%Rrc", rc);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync if (g_Session.StartupInfo.uProtocol == UINT32_MAX)
4260648b018894247c6a73e244050be76c28f857vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No protocol version specified");
4260648b018894247c6a73e244050be76c28f857vboxsync
4260648b018894247c6a73e244050be76c28f857vboxsync if (g_Session.StartupInfo.uSessionID == UINT32_MAX)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No session ID specified");
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
27d188eaec68419914903b118f1428ad597584d8vboxsync /* Init the session object. */
27d188eaec68419914903b118f1428ad597584d8vboxsync rc = GstCntlSessionInit(&g_Session, uSessionFlags);
27d188eaec68419914903b118f1428ad597584d8vboxsync if (RT_FAILURE(rc))
026b1e278173a87acfffc3dd69c71766b7259b5evboxsync return RTMsgErrorExit(RTEXITCODE_INIT, "Failed to initialize session object, rc=%Rrc\n", rc);
27d188eaec68419914903b118f1428ad597584d8vboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VBoxServiceLogCreate(strlen(g_szLogFile) ? g_szLogFile : NULL);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_FAILURE(rc))
026b1e278173a87acfffc3dd69c71766b7259b5evboxsync return RTMsgErrorExit(RTEXITCODE_INIT, "Failed to create log file \"%s\", rc=%Rrc\n",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync strlen(g_szLogFile) ? g_szLogFile : "<None>", rc);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
9bff17fe6983cfda2ddd98f1979841bcb48e78e7vboxsync RTEXITCODE rcExit = gstcntlSessionForkWorker(&g_Session);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceLogDestroy();
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rcExit;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync