VBoxServiceControlSession.cpp revision 462e60a19d02a99b2b1a5c08dff74bb0808d707c
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/* $Id$ */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/** @file
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * VBoxServiceControlSession - Guest session handling. Also handles
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * the forked session processes.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/*
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Copyright (C) 2013 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*******************************************************************************/
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#include <iprt/assert.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
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/** List of guest control sessions (VBOXSERVICECTRLSESSION). */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncextern RTLISTANCHOR g_lstControlSessions;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncextern int VBoxServiceLogCreate(const char *pszLogFile);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncextern void VBoxServiceLogDestroy(void);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/*******************************************************************************
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync* Internal Functions *
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync*******************************************************************************/
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncint gstcntlSessionFileDestroy(PVBOXSERVICECTRLFILE pFile);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncint gstcntlSessionForkShutdown(uint32_t uClientId, uint32_t cParms);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic PVBOXSERVICECTRLFILE gstcntlSessionGetFile(uint32_t uHandle);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic int gstcntlSessionHandleFileOpen(uint32_t uClientId, uint32_t cParms);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic int gstcntlSessionHandleFileClose(uint32_t uClientId, uint32_t cParms);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic int gstcntlSessionHandleFileRead(uint32_t uClientId, uint32_t cParms);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic int gstcntlSessionHandleFileWrite(uint32_t uClientId, uint32_t cParms, void *pvScratchBuf, size_t cbScratchBuf);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic int gstcntlSessionHandleFileSeek(uint32_t uClientId, uint32_t cParms);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic int gstcntlSessionHandleFileTell(uint32_t uClientId, uint32_t cParms);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/** The session ID of the forked session process. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic uint32_t g_uSessionID = UINT32_MAX;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/** The session HGCM protocol of the forked session process. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic uint32_t g_uSessionProto = 1; /* Use the legacy protocol by default (< VBox 4.3). */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/** List of guest control files (VBOXSERVICECTRLFILE). */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic RTLISTANCHOR g_lstSessionFiles;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/** Generic option indices for session fork arguments. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncenum
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBOXSERVICESESSIONOPT_LOG_FILE = 1000,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBOXSERVICESESSIONOPT_USERNAME,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBOXSERVICESESSIONOPT_SESSION_ID,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBOXSERVICESESSIONOPT_SESSION_PROTO
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
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic PVBOXSERVICECTRLFILE gstcntlSessionGetFile(uint32_t uHandle)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync PVBOXSERVICECTRLFILE pFileCur = NULL;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /** @todo Use a map later! */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTListForEach(&g_lstSessionFiles, pFileCur, VBOXSERVICECTRLFILE, Node)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pFileCur->uHandle == uHandle)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return pFileCur;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return NULL;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic int gstcntlSessionHandleFileOpen(uint32_t uClientId, uint32_t cParms)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync char szFile[RTPATH_MAX];
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync char szOpenMode[64];
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync char szDisposition[64];
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uCreationMode = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint64_t uOffset = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uHandle = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBGLR3GUESTCTRLHOSTCTX ctx = { uClientId, cParms };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc = VbglR3GuestCtrlFileGetOpen(&ctx,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* File to open. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync szFile, sizeof(szFile),
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Open mode. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync szOpenMode, sizeof(szOpenMode),
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Disposition. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync szDisposition, sizeof(szDisposition),
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Creation mode. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &uCreationMode,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Offset. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &uOffset);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync PVBOXSERVICECTRLFILE pFile = (PVBOXSERVICECTRLFILE)RTMemAlloc(sizeof(VBOXSERVICECTRLFILE));
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pFile)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (!RTStrPrintf(pFile->szName, sizeof(pFile->szName), "%s", szFile))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_BUFFER_OVERFLOW;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint64_t fFlags = RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE; /** @todo Modes! */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = RTFileOpen(&pFile->hFile, pFile->szName, fFlags);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if ( RT_SUCCESS(rc)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync && uOffset)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Seeking is optional. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc2 = RTFileSeek(pFile->hFile, (int64_t)uOffset, RTFILE_SEEK_BEGIN, NULL /* Current offset */);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_FAILURE(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(3, "[File %s]: Seeking to offset %RU64 failed; rc=%Rrc\n",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pFile->szName, uOffset, rc);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(3, "[File %s]: Opening failed; rc=%Rrc\n",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pFile->szName, rc);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uHandle = VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(ctx.uContextID);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pFile->uHandle = uHandle;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* rc = */ RTListAppend(&g_lstSessionFiles, &pFile->Node);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(3, "[File %s]: Opened (ID=%RU32)\n",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pFile->szName, pFile->uHandle);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_FAILURE(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTMemFree(pFile);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NO_MEMORY;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Report back in any case. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync CALLBACKPAYLOAD_FILE_NOTFIY_OPEN cplOpen = { rc, uHandle };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc2 = VbglR3GuestCtrlFileNotify(uClientId, ctx.uContextID, GUEST_FILE_NOTIFYTYPE_OPEN,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &cplOpen, sizeof(cplOpen));
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
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic int gstcntlSessionHandleFileClose(uint32_t uClientId, uint32_t cParms)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uHandle;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBGLR3GUESTCTRLHOSTCTX ctx = { uClientId, cParms };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc = VbglR3GuestCtrlFileGetClose(&ctx, &uHandle /* File handle to close */);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync PVBOXSERVICECTRLFILE pFile = gstcntlSessionGetFile(uHandle);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pFile)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = gstcntlSessionFileDestroy(pFile);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NOT_FOUND;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Report back in any case. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync CALLBACKPAYLOAD_FILE_NOTFIY_CLOSE cplClose = { rc };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc2 = VbglR3GuestCtrlFileNotify(uClientId, ctx.uContextID, GUEST_FILE_NOTIFYTYPE_CLOSE,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &cplClose, sizeof(cplClose));
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 }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic int gstcntlSessionHandleFileRead(uint32_t uClientId, uint32_t cParms,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync void *pvScratchBuf, size_t cbScratchBuf)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uHandle;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t cbToRead;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBGLR3GUESTCTRLHOSTCTX ctx = { uClientId, cParms };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc = VbglR3GuestCtrlFileGetRead(&ctx, &uHandle, &cbToRead);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync void *pvDataRead = pvScratchBuf;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync size_t cbRead = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync PVBOXSERVICECTRLFILE pFile = gstcntlSessionGetFile(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. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync CALLBACKPAYLOAD_FILE_NOTFIY_READ cplRead = { rc, cbRead, pvDataRead };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc2 = VbglR3GuestCtrlFileNotify(uClientId, ctx.uContextID, GUEST_FILE_NOTIFYTYPE_READ,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &cplRead, sizeof(cplRead));
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 }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic int gstcntlSessionHandleFileReadAt(uint32_t uClientId, uint32_t cParms,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync void *pvScratchBuf, size_t cbScratchBuf)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uHandle;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t cbToRead; int64_t iOffset;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBGLR3GUESTCTRLHOSTCTX ctx = { uClientId, cParms };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc = VbglR3GuestCtrlFileGetReadAt(&ctx, &uHandle, &cbToRead, (uint64_t*)&iOffset);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync void *pvDataRead = pvScratchBuf;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync size_t cbRead = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync PVBOXSERVICECTRLFILE pFile = gstcntlSessionGetFile(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. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync CALLBACKPAYLOAD_FILE_NOTFIY_READ cplRead = { rc, cbRead, pvDataRead };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc2 = VbglR3GuestCtrlFileNotify(uClientId, ctx.uContextID, GUEST_FILE_NOTIFYTYPE_READ,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &cplRead, sizeof(cplRead));
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 }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic int gstcntlSessionHandleFileWrite(uint32_t uClientId, uint32_t cParms,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync void *pvScratchBuf, size_t cbScratchBuf)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertPtrReturn(pvScratchBuf, VERR_INVALID_POINTER);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertPtrReturn(cbScratchBuf, VERR_INVALID_PARAMETER);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uHandle;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t cbToWrite;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBGLR3GUESTCTRLHOSTCTX ctx = { uClientId, cParms };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc = VbglR3GuestCtrlFileGetWrite(&ctx, &uHandle,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pvScratchBuf, cbScratchBuf,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &cbToWrite);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync size_t cbWritten = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync PVBOXSERVICECTRLFILE pFile = gstcntlSessionGetFile(uHandle);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pFile)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = RTFileWrite(pFile->hFile, pvScratchBuf, cbScratchBuf, &cbWritten);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NOT_FOUND;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Report back in any case. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync CALLBACKPAYLOAD_FILE_NOTFIY_WRITE cplWrite = { rc, (uint32_t)cbWritten };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc2 = VbglR3GuestCtrlFileNotify(uClientId, ctx.uContextID, GUEST_FILE_NOTIFYTYPE_WRITE,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &cplWrite, sizeof(cplWrite));
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 }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic int gstcntlSessionHandleFileWriteAt(uint32_t uClientId, uint32_t cParms,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync void *pvScratchBuf, size_t cbScratchBuf)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertPtrReturn(pvScratchBuf, VERR_INVALID_POINTER);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertPtrReturn(cbScratchBuf, VERR_INVALID_PARAMETER);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uHandle;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t cbToWrite; int64_t iOffset;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBGLR3GUESTCTRLHOSTCTX ctx = { uClientId, cParms };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc = VbglR3GuestCtrlFileGetWriteAt(&ctx, &uHandle,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pvScratchBuf, cbScratchBuf,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &cbToWrite, (uint64_t*)&iOffset);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync size_t cbWritten = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync PVBOXSERVICECTRLFILE pFile = gstcntlSessionGetFile(uHandle);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pFile)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = RTFileWriteAt(pFile->hFile, iOffset,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pvScratchBuf, cbScratchBuf, &cbWritten);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NOT_FOUND;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Report back in any case. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync CALLBACKPAYLOAD_FILE_NOTFIY_WRITE cplWrite = { rc, (uint32_t)cbWritten };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc2 = VbglR3GuestCtrlFileNotify(uClientId, ctx.uContextID, GUEST_FILE_NOTIFYTYPE_WRITE,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &cplWrite, sizeof(cplWrite));
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 }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic int gstcntlSessionHandleFileSeek(uint32_t uClientId, uint32_t cParms)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uHandle;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uSeekMethod;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint64_t uOffset; /* Will be converted to int64_t. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint64_t uOffsetActual = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBGLR3GUESTCTRLHOSTCTX ctx = { uClientId, cParms };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc = VbglR3GuestCtrlFileGetSeek(&ctx, &uHandle,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &uSeekMethod, &uOffset);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync PVBOXSERVICECTRLFILE pFile = gstcntlSessionGetFile(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))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = RTFileSeek(pFile->hFile, (int64_t)uOffset,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uSeekMethodIPRT, &uOffsetActual);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NOT_FOUND;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Report back in any case. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync CALLBACKPAYLOAD_FILE_NOTFIY_SEEK cplSeek = { rc, uOffsetActual };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc2 = VbglR3GuestCtrlFileNotify(uClientId, ctx.uContextID, GUEST_FILE_NOTIFYTYPE_SEEK,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &cplSeek, sizeof(cplSeek));
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 }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic int gstcntlSessionHandleFileTell(uint32_t uClientId, uint32_t cParms)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uHandle;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint64_t uOffsetActual = 0;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBGLR3GUESTCTRLHOSTCTX ctx = { uClientId, cParms };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc = VbglR3GuestCtrlFileGetTell(&ctx, &uHandle);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync PVBOXSERVICECTRLFILE pFile = gstcntlSessionGetFile(uHandle);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pFile)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uOffsetActual = RTFileTell(pFile->hFile);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NOT_FOUND;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Report back in any case. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync CALLBACKPAYLOAD_FILE_NOTFIY_TELL cplTell = { rc, uOffsetActual };
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc2 = VbglR3GuestCtrlFileNotify(uClientId, ctx.uContextID, GUEST_FILE_NOTIFYTYPE_TELL,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &cplTell, sizeof(cplTell));
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 }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncRTEXITCODE gstcntlSessionWorker(void)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync bool fSessionFilter = true;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uClientID;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc = VbglR3GuestCtrlConnect(&uClientID);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Set session filter. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uint32_t uFilterAdd = VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(g_uSessionID);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VbglR3GuestCtrlMsgSetFilter(uClientID, uFilterAdd, 0 /* Filter remove */);
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 }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
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 RTListInit(&g_lstSessionFiles);
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
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 {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(4, "Message requires %RU32 parameters, but only 2 supplied -- retrying request (no error!)...\n", cParms);
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 {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(3, "Msg=%RU32 (%RU32 parms) retrieved\n", uMsg, cParms);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(3, "Msg=%RU32 (%RU32 parms) retrieved\n", uMsg, cParms);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /** @todo Guest session ID change detection? */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync switch (uMsg)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case HOST_CANCEL_PENDING_WAITS:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Fall thru is intentional. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case HOST_SESSION_CLOSE:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Shutdown this fork. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = gstcntlSessionForkShutdown(uClientID, cParms);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync fShutdown = true; /* Shutdown in any case. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case HOST_FILE_OPEN:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = gstcntlSessionHandleFileOpen(uClientID, cParms);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case HOST_FILE_CLOSE:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = gstcntlSessionHandleFileClose(uClientID, cParms);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case HOST_FILE_READ:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = gstcntlSessionHandleFileRead(uClientID, cParms,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pvScratchBuf, cbScratchBuf);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case HOST_FILE_READ_AT:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = gstcntlSessionHandleFileReadAt(uClientID, cParms,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pvScratchBuf, cbScratchBuf);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case HOST_FILE_WRITE:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = gstcntlSessionHandleFileWrite(uClientID, cParms,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pvScratchBuf, cbScratchBuf);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case HOST_FILE_WRITE_AT:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = gstcntlSessionHandleFileWriteAt(uClientID, cParms,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pvScratchBuf, cbScratchBuf);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case HOST_FILE_SEEK:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = gstcntlSessionHandleFileSeek(uClientID, cParms);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case HOST_FILE_TELL:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = gstcntlSessionHandleFileTell(uClientID, cParms);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync default:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(3, "Unsupported message from host, uMsg=%RU32, cParms=%RU32\n",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync uMsg, cParms);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Don't terminate here; just wait for the next message. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (fShutdown)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(0, "Session %RU32 ended\n", g_uSessionID);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pvScratchBuf)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTMemFree(pvScratchBuf);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(3, "Disconnecting client ID=%RU32 ...\n", uClientID);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VbglR3GuestCtrlDisconnect(uClientID);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(3, "Session worker returned with rc=%Rrc\n", rc);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/**
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Creates a guest session. This will spawn a new VBoxService.exe instance under
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * behalf of the given user which then will act as a session host.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync *
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @return IPRT status code.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param pSessionStartupInfo Session startup info.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param pNode Returns newly created session node on success.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Optional.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncint GstCntlSessionOpen(const PVBOXSERVICECTRLSESSIONSTARTUPINFO pSessionStartupInfo,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync PRTLISTNODE pNode)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertPtrReturn(pSessionStartupInfo, VERR_INVALID_POINTER);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* pNode is optional. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#ifdef DEBUG
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync PVBOXSERVICECTRLSESSION pSessionCur;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Check for existing session in debug mode. Should never happen because of
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Main consistency. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTListForEach(&g_lstControlSessions, pSessionCur, VBOXSERVICECTRLSESSION, Node)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pSessionCur->StartupInfo.uSessionID == pSessionStartupInfo->uSessionID)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertMsgFailed(("Guest session %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
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync PVBOXSERVICECTRLSESSION pSession = (PVBOXSERVICECTRLSESSION)RTMemAllocZ(sizeof(VBOXSERVICECTRLSESSION));
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pSession)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Copy over session startup info. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync memcpy(&pSession->StartupInfo, pSessionStartupInfo, sizeof(VBOXSERVICECTRLSESSIONSTARTUPINFO));
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(3, "Forking new guest session szUser=%s, szPassword=%s, szDomain=%s, uFlags=%x, using protocol %RU32\n",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSessionStartupInfo->szUser,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#ifdef DEBUG
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSessionStartupInfo->szPassword,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync "XXX", /* Never show passwords in release mode. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSessionStartupInfo->szDomain,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSessionStartupInfo->uFlags,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSessionStartupInfo->uProtocol);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = RTCritSectInit(&pSession->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];
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (!RTStrPrintf(szParmUserName, sizeof(szParmUserName), "--username=%s", pSession->StartupInfo.szUser))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_BUFFER_OVERFLOW;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync char szParmSessionID[32];
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc) && !RTStrPrintf(szParmSessionID, sizeof(szParmSessionID), "--session-id=%RU32",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSession->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",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSession->StartupInfo.uProtocol))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_BUFFER_OVERFLOW;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int iOptIdx = 0; /* Current index in argument vector. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync char const *papszArgs[8];
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync papszArgs[iOptIdx++] = pszExeName;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync papszArgs[iOptIdx++] = "guestsession";
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync papszArgs[iOptIdx++] = szParmSessionID;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync papszArgs[iOptIdx++] = szParmSessionProto;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync 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 {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync char *pszLogExt = NULL;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RTPathHasExt(pszLogFile))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pszLogExt = RTStrDup(RTPathExt(pszLogFile));
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTPathStripExt(pszLogFile);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync char *pszLogSuffix;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RTStrAPrintf(&pszLogSuffix, "-%RU32-%s",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSessionStartupInfo->uSessionID,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSessionStartupInfo->szUser) < 0)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc2 = VERR_NO_MEMORY;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc2 = RTStrAAppend(&pszLogFile, pszLogSuffix);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc2) && pszLogExt)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc2 = RTStrAAppend(&pszLogFile, pszLogExt);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (!RTStrPrintf(szParmLogFile, sizeof(szParmLogFile),
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync "--logfile %s", pszLogFile))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc2 = VERR_BUFFER_OVERFLOW;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTStrFree(pszLogSuffix);
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);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pszLogExt)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTStrFree(pszLogExt);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTStrFree(pszLogFile);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync papszArgs[iOptIdx++] = szParmLogFile;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync papszArgs[iOptIdx++] = NULL;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync 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
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))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Fork the thing. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /** @todo Do we need a custom environment block? */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = RTProcCreateEx(pszExeName, papszArgs, RTENV_DEFAULT, uProcFlags,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSession->StdIn.phChild, pSession->StdOut.phChild, pSession->StdErr.phChild,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSession->StartupInfo.szUser,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSession->StartupInfo.szPassword,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &pSession->hProcess);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
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
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /** @todo Do we need a custom environment block? */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = RTProcCreateEx(pszExeName, papszArgs, RTENV_DEFAULT, uProcFlags,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync NULL /* StdIn */, NULL /* StdOut */, NULL /* StdErr */,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSession->StartupInfo.szUser,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pSession->StartupInfo.szPassword,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync &pSession->hProcess);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync#endif
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_FILE_NOT_FOUND;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Add session to list. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* rc = */ RTListAppend(&g_lstControlSessions, &pSession->Node);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (pNode) /* Return node if wanted. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pNode = &pSession->Node;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTMemFree(pSession);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync else
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VERR_NO_MEMORY;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(3, "Forking returned returned rc=%Rrc\n", rc);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/**
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Closes a formerly opened guest session.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync *
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @return IPRT status code.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param pSession Guest session to close.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param uFlags Termination flags.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncint GstCntlSessionClose(PVBOXSERVICECTRLSESSION pSession, uint32_t uFlags)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /** @todo Implement session termination. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return VERR_NOT_IMPLEMENTED;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/**
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Close all formerly opened guest sessions.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync *
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @return IPRT status code.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param uFlags Termination flags.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncint GstCntlSessionCloseAll(uint32_t uFlags)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc = VINF_SUCCESS;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(3, "GstCntlSessionCloseAll\n");
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync PVBOXSERVICECTRLSESSION pSessionCur;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTListForEach(&g_lstControlSessions, pSessionCur, VBOXSERVICECTRLSESSION, Node)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc2 = GstCntlSessionClose(pSessionCur, uFlags);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_SUCCESS(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = rc2;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Keep going. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rc;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncRTEXITCODE VBoxServiceControlSessionForkInit(int argc, char **argv)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync static const RTGETOPTDEF s_aOptions[] =
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync { "--logfile", VBOXSERVICESESSIONOPT_LOG_FILE, RTGETOPT_REQ_STRING },
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync { "--username", VBOXSERVICESESSIONOPT_USERNAME, RTGETOPT_REQ_STRING },
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync { "--session-id", VBOXSERVICESESSIONOPT_SESSION_ID, RTGETOPT_REQ_UINT32 },
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync { "--session-proto", VBOXSERVICESESSIONOPT_SESSION_PROTO, RTGETOPT_REQ_UINT32 },
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
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc = VINF_SUCCESS;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
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;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case VBOXSERVICESESSIONOPT_USERNAME:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /** @todo. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case VBOXSERVICESESSIONOPT_SESSION_ID:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync g_uSessionID = ValueUnion.u32;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync case VBOXSERVICESESSIONOPT_SESSION_PROTO:
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync g_uSessionProto = ValueUnion.u32;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
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
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (g_uSessionID == UINT32_MAX)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No session ID specified");
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VBoxServiceLogCreate(strlen(g_szLogFile) ? g_szLogFile : NULL);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_FAILURE(rc))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to create release log (%s, %Rrc)",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync strlen(g_szLogFile) ? g_szLogFile : "<None>", rc);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTEXITCODE rcExit = gstcntlSessionWorker();
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceLogDestroy();
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return rcExit;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncint gstcntlSessionForkShutdown(uint32_t uClientId, uint32_t cParms)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync{
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceVerbose(0, "Session %RU32 is going to shutdown ...\n", g_uSessionID);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Close all left guest files. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync PVBOXSERVICECTRLFILE pFile;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pFile = RTListGetFirst(&g_lstSessionFiles, VBOXSERVICECTRLFILE, Node);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync while (pFile)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync PVBOXSERVICECTRLFILE pNext = RTListNodeGetNext(&pFile->Node, VBOXSERVICECTRLFILE, Node);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync bool fLast = RTListNodeIsLast(&g_lstSessionFiles, &pFile->Node);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int rc2 = gstcntlSessionFileDestroy(pFile);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (RT_FAILURE(rc2))
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync {
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync VBoxServiceError("Unable to close file \"%s\"; rc=%Rrc\n",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pFile->szName, rc2);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Keep going. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync if (fLast)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync break;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pFile = pNext;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync }
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync AssertMsg(RTListIsEmpty(&g_lstSessionFiles),
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync ("Guest file list still contains entries when it should not\n"));
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /** @todo Add guest process termination here. Later. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return VINF_SUCCESS; /** @todo */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync}
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync