GuestSessionImpl.cpp revision a160e6af8f766b85db20b6caecb65284c9a385f9
/* $Id$ */
/** @file
* VirtualBox Main - XXX.
*/
/*
* Copyright (C) 2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include "GuestImpl.h"
#include "GuestSessionImpl.h"
#include "GuestCtrlImplPrivate.h"
#include "Global.h"
#include "AutoCaller.h"
#include "ProgressImpl.h"
#include <memory> /* For auto_ptr. */
// constructor / destructor
/////////////////////////////////////////////////////////////////////////////
{
LogFlowThisFunc(("\n"));
return BaseFinalConstruct();
}
void GuestSession::FinalRelease(void)
{
uninit();
}
// session task classes
/////////////////////////////////////////////////////////////////////////////
{
}
GuestSessionTask::~GuestSessionTask(void)
{
}
{
return VINF_SUCCESS;
&& fCanceled)
return VERR_CANCELLED;
&& !fCompleted)
return VINF_SUCCESS;
return VERR_COM_UNEXPECTED;
return VINF_SUCCESS;
}
int GuestSessionTask::setProgressSuccess(void)
{
return VINF_SUCCESS;
&& !fCanceled
&& !fCompleted)
{
return VERR_COM_UNEXPECTED; /** @todo Find a better rc. */
}
return VINF_SUCCESS;
}
{
return hr; /* Return original rc. */
&& !fCanceled
&& !fCompleted)
{
return hr2;
}
return hr; /* Return original rc. */
}
: mSourceFile(NULL),
mSourceOffset(0),
mSourceSize(0),
{
}
{
}
SessionTaskCopyTo::~SessionTaskCopyTo(void)
{
}
int SessionTaskCopyTo::Run(void)
{
if (mCopyFileFlags)
{
return VERR_INVALID_PARAMETER;
}
int rc;
if (!mSourceFile)
{
/* Does our source file exist? */
{
}
else
{
if (RT_FAILURE(rc))
{
}
else
{
if (RT_FAILURE(rc))
{
}
}
}
}
else
{
pFile = mSourceFile;
/* Size + offset are optional. */
}
procInfo.mName = Utf8StrFmt(GuestSession::tr("Copying file \"%s\" to the guest to \"%s\" (%RU64 bytes)"),
/* Set arguments.*/
procInfo.mArguments.push_back(Utf8StrFmt("--output=%s", mDest.c_str())); /** @todo Do we need path conversion? */
/* Startup process. */
if (RT_SUCCESS(rc))
if (RT_FAILURE(rc))
{
}
else
{
uint64_t cbWrittenTotal = 0;
for (;;)
{
if ( RT_FAILURE(rc)
{
break;
}
if (mSourceSize) /* If we have nothing to write, take a shortcut. */
{
/** @todo Not very efficient, but works for now. */
if (RT_SUCCESS(rc))
{
/*
* Some other error occured? There might be a chance that RTFileRead
* print a generic error.
*/
if (RT_FAILURE(rc))
{
break;
}
}
else
{
break;
}
}
/* Did we reach the end of the content we want to transfer (last chunk)? */
/* Did we reach the last block which is exactly _64K? */
/* ... or does the user want to cancel? */
&& fCanceled)
)
{
}
if (RT_FAILURE(rc))
{
break;
}
#ifdef DEBUG
LogFlowThisFunc(("cbWritten=%RU32, cbToRead=%RU64, cbWrittenTotal=%RU64, cbFileSize=%RU64\n",
#endif
/* Only subtract bytes reported written by the guest. */
/* Update total bytes written to the guest. */
/* Did the user cancel the operation above? */
if (fCanceled)
break;
/* Update the progress.
* Watch out for division by zero. */
mSourceSize > 0
if (RT_FAILURE(rc))
break;
/* End of file reached? */
if (!cbToRead)
break;
} /* for */
if ( !fCanceled
|| RT_SUCCESS(rc))
{
/*
* Even if we succeeded until here make sure to check whether we really transfered
* everything.
*/
if ( mSourceSize > 0
&& cbWrittenTotal == 0)
{
/* If nothing was transfered but the file size was > 0 then "vbox_cat" wasn't able to write
* to the destination -> access denied. */
}
else if (cbWrittenTotal < mSourceSize)
{
/* If we did not copy all let the user know. */
}
else
{
if ( RT_FAILURE(rc)
{
if (RT_FAILURE(rc))
else
Utf8StrFmt(GuestSession::tr("Waiting on termination for copying file \"%s\" failed with wait result %ld"),
}
if (RT_SUCCESS(rc))
{
&& exitCode != 0)
)
{
}
}
if (RT_SUCCESS(rc))
rc = setProgressSuccess();
}
}
} /* processCreateExInteral */
if (!mSourceFile) /* Only close locally opened files. */
RTFileClose(*pFile);
return rc;
}
{
LogFlowThisFunc(("strDesc=%s, strSource=%s, strDest=%s, mCopyFileFlags=%x\n",
"gctlCpyTo");
return rc;
}
/* static */
{
}
{
}
{
}
int SessionTaskCopyFrom::Run(void)
{
/*
* Note: There will be races between querying file size + reading the guest file's
* content because we currently *do not* lock down the guest file when doing the
* actual operations.
** @todo Implement guest file locking!
*/
if (RT_FAILURE(rc))
{
}
{
}
if (RT_SUCCESS(rc))
{
RTFILE_O_WRITE | RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_WRITE); /** @todo Use the correct open modes! */
if (RT_FAILURE(rc))
{
}
else
{
procInfo.mName = Utf8StrFmt(GuestSession::tr("Copying file \"%s\" from guest to the host to \"%s\" (%RI64 bytes)"),
/* Set arguments.*/
/* Startup process. */
if (RT_SUCCESS(rc))
if (RT_FAILURE(rc))
{
}
else
{
uint64_t cbWrittenTotal = 0;
for (;;)
{
if ( RT_FAILURE(rc)
{
break;
}
&cbRead);
if (RT_FAILURE(rc))
{
break;
}
if (cbRead)
{
if (RT_FAILURE(rc))
{
break;
}
/* Only subtract bytes reported written by the guest. */
/* Update total bytes written to the guest. */
cbWrittenTotal += cbRead;
/* Did the user cancel the operation above? */
&& fCanceled)
break;
if (RT_FAILURE(rc))
break;
/* End of file reached? */
if (cbToRead == 0)
break;
}
} /* for */
if ( !fCanceled
|| RT_SUCCESS(rc))
{
/*
* Even if we succeeded until here make sure to check whether we really transfered
* everything.
*/
if ( objData.mObjectSize > 0
&& cbWrittenTotal == 0)
{
/* If nothing was transfered but the file size was > 0 then "vbox_cat" wasn't able to write
* to the destination -> access denied. */
}
{
/* If we did not copy all let the user know. */
}
else
{
&& exitCode != 0)
)
{
}
else /* Yay, success! */
rc = setProgressSuccess();
}
}
}
}
}
return rc;
}
{
LogFlowThisFunc(("strDesc=%s, strSource=%s, strDest=%s, uFlags=%x\n",
"gctlCpyFrom");
return rc;
}
/* static */
{
}
{
}
{
}
int SessionTaskUpdateAdditions::Run(void)
{
if (RT_FAILURE(rc))
return rc;
/*
* Determine guest OS type and the required installer image.
* At the moment only Windows guests are supported.
*/
{
{
strInstallerImage = "VBOXWINDOWSADDITIONS_AMD64.EXE";
else
strInstallerImage = "VBOXWINDOWSADDITIONS_X86.EXE";
/* Since the installers are located in the root directory,
* no further path processing needs to be done (yet). */
}
else /* Everything else is not supported (yet). */
{
Utf8StrFmt(GuestSession::tr("Detected guest OS (%s) does not support automatic Guest Additions updating, please update manually"),
osTypeIdUtf8.c_str()));
}
}
else
{
}
if (RT_SUCCESS(rc))
{
/*
* Try to open the .ISO file and locate the specified installer.
*/
if (RT_FAILURE(rc))
{
}
else
{
if ( RT_SUCCESS(rc)
&& cbOffset
&& cbSize)
{
if (RT_FAILURE(rc))
}
else
{
switch (rc)
{
case VERR_FILE_NOT_FOUND:
break;
default:
Utf8StrFmt(GuestSession::tr("An unknown error (%Rrc) occured while retrieving information of setup file on installation medium \"%s\""),
break;
}
}
/* Specify the ouput path on the guest side. */
/** @todo Add support for non-Windows as well! */
/* Copy over the Guest Additions installer to the guest. */
if (RT_SUCCESS(rc))
{
LogRel(("Copying Guest Additions installer \"%s\" to \"%s\" on guest ...\n",
if (RT_SUCCESS(rc))
{
rc = pSession->startTaskAsync(Utf8StrFmt(GuestSession::tr("Copying Guest Additions installer from \"%s\" to \"%s\" on the guest"),
if (RT_FAILURE(rc))
{
Utf8StrFmt(GuestSession::tr("Unable to start copying Guest Additions installer \"%s\" to \"%s\": %Rrc"),
}
else
{
{
}
&& fCanceled)
{
}
else
{
Utf8StrFmt(GuestSession::tr("Error while copying Guest Additions installer \"%s\" to \"%s\": %Rhrc"),
}
}
}
}
if (RT_SUCCESS(rc))
{
/* Install needed certificates for the WHQL crap. */
/** @todo Copy over VBoxCertUtil? */
}
if (RT_SUCCESS(rc))
{
/*
* Installer was transferred successfully, so let's start it
* (with system rights).
*/
LogRel(("Starting Guest Additions installer ...\n"));
}
if (RT_SUCCESS(rc))
{
/* If the caller does not want to wait for out guest update process to end,
* complete the progress object now so that the caller can do other work. */
/* Construct arguments. */
/* Don't quit VBoxService during upgrade because it still is used for this
* piece of code we're in right now (that is, here!) ... */
/* Tell the installer to report its current installation status
* using a running VBoxTray instance via balloon messages in the
* Windows taskbar. */
if (RT_SUCCESS(rc))
if (RT_SUCCESS(rc))
if (RT_SUCCESS(rc))
{
LogRel(("Updating Guest Additions in progress ...\n"));
{
&& exitCode != 0)
)
{
}
else /* Yay, success! */
hr = setProgressSuccess();
}
else
{
if (RT_FAILURE(rc))
else
}
}
}
RTIsoFsClose(&iso);
}
}
return rc;
}
{
LogFlowThisFunc(("strDesc=%s, strSource=%s, uFlags=%x\n",
"gctlUpGA");
return rc;
}
/* static */
{
}
// public initializer/uninitializer for internal purposes only
/////////////////////////////////////////////////////////////////////////////
{
/* Enclose the state transition NotReady->InInit->Ready. */
AutoInitSpan autoInitSpan(this);
/* Confirm a successful initialization when it's the case. */
return VINF_SUCCESS;
}
/**
* Uninitializes the instance.
* Called from FinalRelease().
*/
void GuestSession::uninit(void)
{
/* Enclose the state transition Ready->InUninit->NotReady. */
AutoUninitSpan autoUninitSpan(this);
if (autoUninitSpan.uninitDone())
return;
#ifdef VBOX_WITH_GUEST_CONTROL
{
}
{
}
{
}
{
}
#endif
}
/////////////////////////////////////////////////////////////////////////////
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
return S_OK;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
return S_OK;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
return S_OK;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
return S_OK;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
return S_OK;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
return S_OK;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
{
}
return S_OK;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
int rc = VINF_SUCCESS;
{
}
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
return S_OK;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
return S_OK;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
return S_OK;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
// private methods
/////////////////////////////////////////////////////////////////////////////
{
{
if (pDirectory == (*itDirs))
{
return VINF_SUCCESS;
}
}
return VERR_NOT_FOUND;
}
int GuestSession::directoryCreateInternal(const Utf8Str &strPath, uint32_t uMode, uint32_t uFlags, ComObjPtr<GuestDirectory> &pDirectory)
{
LogFlowThisFunc(("strPath=%s, uMode=%x, uFlags=%x\n",
int rc = VINF_SUCCESS;
/* Construct arguments. */
procInfo.mArguments.push_back(Utf8Str("--parents")); /* We also want to create the parent directories. */
if (uMode)
{
char szMode[16];
{
}
else
}
if (RT_SUCCESS(rc))
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
{
{
if (lExitCode != 0)
return VERR_CANT_CREATE;
}
else
}
}
if (RT_FAILURE(rc))
return rc;
/* Create the directory object. */
return VERR_COM_UNEXPECTED;
object here. */
if (RT_FAILURE(rc))
return rc;
/* Add the created directory to our vector. */
LogFlowFunc(("Added new directory \"%s\" (Session: %RU32)\n",
return rc;
}
{
LogFlowThisFunc(("strPath=%s, strPath=%s, uFlags=%x\n",
/* Create the directory object. */
return VERR_COM_UNEXPECTED;
if (RT_FAILURE(rc))
return rc;
/* Add the created directory to our vector. */
LogFlowFunc(("Added new directory \"%s\" (Session: %RU32)\n",
return rc;
}
int GuestSession::dispatchToProcess(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData)
{
#ifdef DEBUG
LogFlowFunc(("uProcessID=%RU32 (%RU32 total)\n",
#endif
int rc;
{
}
else
rc = VERR_NOT_FOUND;
return rc;
}
{
{
{
return VINF_SUCCESS;
}
}
return VERR_NOT_FOUND;
}
/**
* Implementation of FileRemove(). Can throw an exception due to the use of
* Utf8Str, Utf8StrFmt and std::vector near the beginning (and others?). The
* caller should catch this. On success, *prc will be set to the return code
* of the delete operation to distinguish between API and command failure.
*/
{
int rc = VINF_SUCCESS;
/* Construct arguments. */
if (RT_SUCCESS(rc))
if (RT_SUCCESS(rc))
{
for (;;)
{
if ( RT_FAILURE(rc)
{
break;
}
&cbRead);
if (RT_FAILURE(rc))
break;
if (cbRead)
{
if (RT_FAILURE(rc))
break;
}
}
LogFlowThisFunc(("rc=%Rrc, cbRead=%RU32, cbStreamOut=%RU32\n",
}
else
if (RT_FAILURE(rc))
{
LogThisFunc(("No return code after deleting file"));
rc = VERR_NO_DATA;
}
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
}
else
return rc;
}
int GuestSession::fileOpenInternal(const Utf8Str &strPath, const Utf8Str &strOpenMode, const Utf8Str &strDisposition,
{
LogFlowThisFunc(("strPath=%s, strOpenMode=%s, strDisposition=%s, uCreationMode=%x, iOffset=%RI64\n",
/* Create the directory object. */
return VERR_COM_UNEXPECTED;
object here. */
if (RT_FAILURE(rc))
return rc;
/* Add the created directory to our vector. */
LogFlowFunc(("Added new file \"%s\" (Session: %RU32\n",
return rc;
}
/* Note: Will work on directories and others, too. */
{
/* Construct arguments. */
if (RT_SUCCESS(rc))
if (RT_SUCCESS(rc))
{
/** @todo Merge with GuestDirectory::read. */
for (;;)
{
if ( RT_FAILURE(rc)
{
break;
}
&cbRead);
if (RT_FAILURE(rc))
break;
if (cbRead)
{
if (RT_FAILURE(rc))
break;
}
}
LogFlowThisFunc(("rc=%Rrc, cbRead=%RU64, cbStreamOut=%RU32\n",
}
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
{
}
else
}
return rc;
}
{
if (RT_SUCCESS(rc))
{
else
}
return rc;
}
{
return mData.mCredentials;
}
{
return mData.mEnvironment;
}
{
}
{
{
{
LogFlowFunc(("Removing process (Session: %RU32) with process ID=%RU32, guest PID=%RU32 (now total %ld processes)\n",
mData.mId, itProcs->second->getProcessID(), itProcs->second->getPID(), mData.mProcesses.size() - 1));
return VINF_SUCCESS;
}
}
return VERR_NOT_FOUND;
}
/**
* Creates but does *not* start the process yet. See GuestProcess::startProcess() or
* GuestProcess::startProcessAsync() for that.
*
* @return IPRT status code.
* @param procInfo
* @param pProcess
*/
int GuestSession::processCreateExInteral(GuestProcessStartupInfo &procInfo, ComObjPtr<GuestProcess> &pProcess)
{
LogFlowFunc(("mCmd=%s, mFlags=%x, mTimeoutMS=%RU32\n",
#ifdef DEBUG
{
LogFlowFunc(("Arguments:"));
{
it++;
}
LogFlow(("\n"));
}
#endif
/* Validate flags. */
{
{
return VERR_INVALID_PARAMETER;
}
}
/* Adjust timeout. If set to 0, we define
* an infinite timeout. */
if (procInfo.mTimeoutMS == 0)
/** @tood Implement process priority + affinity. */
int rc = VERR_MAX_PROCS_REACHED;
return rc;
/* Create a new (host-based) process ID and assign it. */
uint32_t uNewProcessID = 0;
for (;;)
{
/* Is the context ID already used? */
{
/* Callback with context ID was not found. This means
* we can use this context ID for our new callback we want
* to add below. */
rc = VINF_SUCCESS;
break;
}
uNewProcessID = 0;
if (++uTries == UINT32_MAX)
break; /* Don't try too hard. */
}
if (RT_FAILURE(rc))
return rc;
/* Create the process object. */
return VERR_COM_UNEXPECTED;
if (RT_FAILURE(rc))
return rc;
/* Add the created process to our map. */
LogFlowFunc(("Added new process (Session: %RU32) with process ID=%RU32 (now total %ld processes)\n",
return rc;
}
{
{
if (pProcess)
return true;
}
return false;
}
{
AssertReturn(uPID, false);
/* pProcess is optional. */
{
if (procCaller.rc())
return VERR_COM_INVALID_OBJECT_STATE;
{
if (pProcess)
return VINF_SUCCESS;
}
}
return VERR_NOT_FOUND;
}
{
/* Create the progress object. */
return VERR_COM_UNEXPECTED;
TRUE /* aCancelable */);
return VERR_COM_UNEXPECTED;
/* Initialize our worker task. */
if (RT_FAILURE(rc))
return rc;
/* Don't destruct on success. */
return rc;
}
/**
* This is necessary to know which guest control protocol version to use,
* among other things (later).
*
* @return IPRT status code.
*/
int GuestSession::queryInfo(void)
{
#if 1
/* Since the new functions were not implemented yet, force Main to use protocol ver 1. */
#else
/*
* Try querying the guest control protocol version running on the guest.
* This is done using the Guest Additions version
*/
? 2 /* Guest control 2.0. */
: 1; /* Legacy guest control (VBox < 4.2). */
/* Build revision is ignored. */
/* Tell the user but don't bitch too often. */
static short s_gctrlLegacyWarning = 0;
LogRel((tr("Warning: Guest Additions are older (%ld.%ld) than host capabilities for guest control, please upgrade them. Using protocol version %ld now\n"),
VBOX_FULL_VERSION_GET_MAJOR(uVerAdditions), VBOX_FULL_VERSION_GET_MINOR(uVerAdditions), mData.mProtocolVersion));
#endif
return VINF_SUCCESS;
}
// implementation of public methods
/////////////////////////////////////////////////////////////////////////////
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
uninit();
return S_OK;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestSession::CopyFrom(IN_BSTR aSource, IN_BSTR aDest, ComSafeArrayIn(CopyFileFlag_T, aFlags), IProgress **aProgress)
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
if (aFlags)
{
}
int rc = startTaskAsync(Utf8StrFmt(tr("Copying \"%ls\" from guest to \"%ls\" on the host"), aSource, aDest),
if (RT_SUCCESS(rc))
{
/* Return progress to the caller. */
}
else
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestSession::CopyTo(IN_BSTR aSource, IN_BSTR aDest, ComSafeArrayIn(CopyFileFlag_T, aFlags), IProgress **aProgress)
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
if (aFlags)
{
}
int rc = startTaskAsync(Utf8StrFmt(tr("Copying \"%ls\" from host to \"%ls\" on the guest"), aSource, aDest),
if (RT_SUCCESS(rc))
{
/* Return progress to the caller. */
}
else
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
/* aDirectory is optional. */
AutoCaller autoCaller(this);
if (aFlags)
{
if (fFlags)
{
if (!(fFlags & DirectoryCreateFlag_Parents))
}
}
if (RT_SUCCESS(rc))
{
if (aDirectory)
{
/* Return directory object to the caller. */
}
else
{
if (RT_FAILURE(rc))
}
}
else
{
switch (rc)
{
case VERR_INVALID_PARAMETER:
break;
case VERR_BROKEN_PIPE:
break;
case VERR_CANT_CREATE:
break;
default:
break;
}
}
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestSession::DirectoryCreateTemp(IN_BSTR aTemplate, ULONG aMode, IN_BSTR aName, IGuestDirectory **aDirectory)
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
int rc = VINF_SUCCESS;
try /* Can this be done without exceptions? */
{
strTemplate.c_str()));
/* Construct arguments. */
}
catch (...)
{
return E_OUTOFMEMORY;
}
if (RT_SUCCESS(rc))
{
for (;;)
{
if ( RT_FAILURE(rc)
{
break;
}
&cbRead);
if (RT_FAILURE(rc))
break;
if (cbRead)
{
if (RT_FAILURE(rc))
break;
}
}
LogFlowThisFunc(("rc=%Rrc, cbRead=%RU32, cbStreamOut=%RU32\n",
}
else
return setError(E_FAIL, tr("Error while starting temporary directory creation tool on guest: %Rrc"), rc);
if (RT_FAILURE(rc))
if (RT_SUCCESS(rc))
{
if (RT_FAILURE((int)i64rc))
}
else
return setError(E_FAIL, tr("Error while getting return code from creating temporary directory: %Rrc"), rc);
return S_OK;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
if (RT_SUCCESS(rc))
{
}
else
{
switch (rc)
{
/** @todo Add more errors here! */
default:
break;
}
}
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestSession::DirectoryOpen(IN_BSTR aPath, IN_BSTR aFilter, ComSafeArrayIn(DirectoryOpenFlag_T, aFlags), IGuestDirectory **aDirectory)
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
if (aFlags)
{
if (fFlags)
}
if (RT_SUCCESS(rc))
{
if (aDirectory)
{
/* Return directory object to the caller. */
}
else
{
if (RT_FAILURE(rc))
}
}
else
{
switch (rc)
{
case VERR_INVALID_PARAMETER:
break;
case VERR_BROKEN_PIPE:
break;
default:
break;
}
}
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestSession::DirectoryRemoveRecursive(IN_BSTR aPath, ComSafeArrayIn(DirectoryRemoveRecFlag_T, aFlags), IProgress **aProgress)
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestSession::DirectoryRename(IN_BSTR aSource, IN_BSTR aDest, ComSafeArrayIn(PathRenameFlag_T, aFlags))
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
return S_OK;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
return S_OK;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
return S_OK;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestSession::FileCreateTemp(IN_BSTR aTemplate, ULONG aMode, IN_BSTR aName, IGuestFile **aFile)
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
if (RT_SUCCESS(rc))
{
}
else
{
switch (rc)
{
/** @todo Add more errors here! */
default:
break;
}
}
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
try /* Can this be done without exceptions? */
{
int rc2;
if (RT_FAILURE((rc)))
else if (RT_FAILURE((rc2)))
return setError(VBOX_E_IPRT_ERROR,
}
catch (...)
{
return E_OUTOFMEMORY;
}
return S_OK;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestSession::FileOpen(IN_BSTR aPath, IN_BSTR aOpenMode, IN_BSTR aDisposition, ULONG aCreationMode, LONG64 aOffset, IGuestFile **aFile)
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
/** @todo Validate open mode. */
/** @todo Validate disposition mode. */
/** @todo Validate creation mode. */
uint32_t uCreationMode = 0;
if (RT_SUCCESS(rc))
{
/* Return directory object to the caller. */
}
else
{
switch (rc)
{
/** @todo Add more error info! */
default:
break;
}
}
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
if (RT_SUCCESS(rc))
{
}
else
{
switch (rc)
{
/** @todo Add more errors here! */
default:
break;
}
}
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestSession::FileRename(IN_BSTR aSource, IN_BSTR aDest, ComSafeArrayIn(PathRenameFlag_T, aFlags))
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestSession::ProcessCreate(IN_BSTR aCommand, ComSafeArrayIn(IN_BSTR, aArguments), ComSafeArrayIn(IN_BSTR, aEnvironment),
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
HRESULT hr = ProcessCreateEx(aCommand, ComSafeArrayInArg(aArguments), ComSafeArrayInArg(aEnvironment),
ComSafeArrayInArg(aFlags), aTimeoutMS, ProcessPriority_Default, ComSafeArrayAsInParam(affinity), aProcess);
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestSession::ProcessCreateEx(IN_BSTR aCommand, ComSafeArrayIn(IN_BSTR, aArguments), ComSafeArrayIn(IN_BSTR, aEnvironment),
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
if (aArguments)
{
}
int rc = VINF_SUCCESS;
/*
* Create the process environment:
* - Apply the session environment in a first step, and
* - Apply environment variables specified by this call to
* have the chance of overwriting/deleting session entries.
*/
if (aEnvironment)
{
}
if (RT_SUCCESS(rc))
{
if (aFlags)
{
}
if (aAffinity)
{
}
if (RT_SUCCESS(rc))
{
/* Return guest session to the caller. */
if (RT_SUCCESS(rc))
}
}
if (RT_FAILURE(rc))
{
switch (rc)
{
case VERR_MAX_PROCS_REACHED:
break;
/** @todo Add more errors here. */
default:
break;
}
}
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
if (aPID == 0)
AutoCaller autoCaller(this);
if (RT_FAILURE(rc))
/* This will set (*aProcess) to NULL if pProgress is NULL. */
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestSession::SymlinkRead(IN_BSTR aSymlink, ComSafeArrayIn(SymlinkReadFlag_T, aFlags), BSTR *aTarget)
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
#endif /* VBOX_WITH_GUEST_CONTROL */
}
{
#ifndef VBOX_WITH_GUEST_CONTROL
#else
AutoCaller autoCaller(this);
#endif /* VBOX_WITH_GUEST_CONTROL */
}