VBoxManageGuestCtrl.cpp revision 22866e6b8e8304e8604724f7509c33253e7eedcf
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * VBoxManage - Implementation of guestcontrol command.
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * Copyright (C) 2010-2011 Oracle Corporation
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * available from http://www.virtualbox.org. This file is free software;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * you can redistribute it and/or modify it under the terms of the GNU
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * General Public License (GPL) as published by the Free Software
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync/*******************************************************************************
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync* Header Files *
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync*******************************************************************************/
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsyncusing namespace com;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * IVirtualBoxCallback implementation for handling the GuestControlCallback in
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * relation to the "guestcontrol * wait" command.
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync/** @todo */
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync/** Set by the signal handler. */
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsyncstatic volatile bool g_fGuestCtrlCanceled = false;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsynctypedef struct COPYCONTEXT
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * An entry for a source element, including an optional DOS-like wildcard (*,?).
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync SOURCEFILEENTRY(const char *pszSource, const char *pszFilter)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync /* No file and no directory -- maybe a filter? */
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync /* Yep, get the actual filter part. */
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync /* Remove the filter from actual sourcec directory name. */
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsynctypedef std::vector<SOURCEFILEENTRY> SOURCEVEC, *PSOURCEVEC;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * An entry for an element which needs to be copied/created to/on the guest.
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync DESTFILEENTRY(Utf8Str strFileName) : mFileName(strFileName) {}
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * Map for holding destination entires, whereas the key is the destination
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * directory and the mapped value is a vector holding all elements for this directoy.
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsynctypedef std::map< Utf8Str, std::vector<DESTFILEENTRY> > DESTDIRMAP, *PDESTDIRMAP;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsynctypedef std::map< Utf8Str, std::vector<DESTFILEENTRY> >::iterator DESTDIRMAPITER, *PDESTDIRMAPITER;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * Special exit codes for returning errors/information of a
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * started guest process to the command line VBoxManage was started from.
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * Useful for e.g. scripting.
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * @note These are frozen as of 4.1.0.
enum EXITCODEEXEC
enum GETOPTDEF_EXEC
enum GETOPTDEF_COPYFROM
enum GETOPTDEF_COPYTO
enum GETOPTDEF_MKDIR
enum GETOPTDEF_STAT
enum OUTPUTTYPE
OUTPUTTYPE_UNDEFINED = 0,
#ifndef VBOX_ONLY_DOCS
static void ctrlSignalHandlerInstall()
#ifdef SIGBREAK
static void ctrlSignalHandlerUninstall()
#ifdef SIGBREAK
switch (enmStatus)
switch (enmStatus)
return rc;
int rc;
&& fCanceled)
return rc;
return VERR_NOT_FOUND;
return VERR_VM_INVALID_VM_STATE;
if (pArg->argc < 2) /* At least the command we want to execute in the guest should be present :-). */
int ch;
bool fOutputBinary = false;
bool fWaitForExit = false;
bool fWaitForStdOut = false;
bool fVerbose = false;
switch (ch)
case GETOPTDEF_EXEC_DOS2UNIX:
char **papszArg;
int cArgs;
for (int j = 0; j < cArgs; j++)
case GETOPTDEF_EXEC_UNIX2DOS:
fVerbose = true;
fWaitForExit = true;
case VINF_GETOPT_NOT_OPTION:
if (fVerbose)
if (cMsTimeout == 0)
&uPID,
if (fVerbose)
if (fWaitForExit)
if (fVerbose)
bool fCanceledAlready = false;
if (fCancelable)
cbOutputData = 0;
if (cbOutputData > 0)
char *pszBufUTF8;
for (char *s = pszBufUTF8, *d = s;
if (cbOutputData <= 0)
if (fCompleted)
g_fGuestCtrlCanceled = false;
&& fCanceled)
if ( cMsTimeout
if (fCancelable)
if (fCanceled)
if (fVerbose)
else if ( fCompleted
RTPrintf("Exit code=%u (Status=%u [%s], Flags=%u)\n", uRetExitCode, retStatus, ctrlExecProcessStatusToText(retStatus), uRetFlags);
if (fVerbose)
return RTEXITCODE_FAILURE;
return rcProc;
bool fHostToGuest,
return VERR_NO_MEMORY;
return VERR_NO_MEMORY;
return VINF_SUCCESS;
if (pContext)
return rc;
#ifdef DEBUG_andy
static int tstTranslatePath()
const char *pszSourceRoot;
const char *pszSource;
const char *pszDest;
const char *pszTranslated;
int iResult;
} aTests[] =
int iTest = 0;
else if ( pszTranslated
if (pszTranslated)
return VINF_SUCCESS;
return rc;
if (bGuest)
return rc;
bool *fExists)
bool *fExists)
if (bOnGuest)
return rc;
bool *fExists)
bool *fExists)
return VINF_SUCCESS;
return vrc;
bool fDirCreated = false;
case RTDIRENTRYTYPE_DIRECTORY:
if (pszSubDir)
if (pszNewSub)
case RTDIRENTRYTYPE_SYMLINK:
case RTDIRENTRYTYPE_FILE:
if ( pszFilter
if (!fDirCreated)
char *pszDestDir;
fDirCreated = true;
if (pszFileSource)
char *pszFileDest;
return rc;
return rc;
bool fDirCreated = false;
&uDirHandle);
switch (enmType)
if (pszSubDir)
if (pszNewSub)
case GuestDirEntryType_File:
if ( pszFilter
if (!fDirCreated)
char *pszDestDir;
fDirCreated = true;
if (pszFileSource)
char *pszFileDest;
return rc;
if ( lenRoot
return VINF_SUCCESS;
bool fHostToGuest)
* what and how to implement the file enumeration/recursive lookup, like VBoxManage
int ch;
bool fVerbose = false;
bool fCopyRecursive = false;
bool fDryRun = false;
switch (ch)
case GETOPTDEF_COPYTO_DRYRUN:
fDryRun = true;
case GETOPTDEF_COPYTO_FOLLOW:
fVerbose = true;
case VINF_GETOPT_NOT_OPTION:
if (fVerbose)
if (fHostToGuest)
if (fDryRun)
&pContext);
return RTEXITCODE_FAILURE;
if ( lenDest
char *pszSourceRoot;
if (fVerbose)
bool fIsFile = false;
bool fExists;
if (fExists)
&& fExists)
fIsFile = true;
&& fExists)
if (fIsFile)
char *pszDestFile;
&& !fExists)
int ch;
bool fVerbose = false;
switch (ch)
fVerbose = true;
case VINF_GETOPT_NOT_OPTION:
if (fVerbose)
it++;
return rcExit;
int ch;
bool fVerbose = false;
switch (ch)
fVerbose = true;
case VINF_GETOPT_NOT_OPTION:
if (fVerbose)
&fExists);
if (!fExists)
it++;
return rcExit;
bool fVerbose = false;
int ch;
switch (ch)
fVerbose = true;
if (fVerbose)
#ifdef DEBUG_andy
if (fVerbose)
&& fVerbose)
#ifdef DEBUG_andy_disabled
return RTEXITCODE_FAILURE;
int rcExit;
return RTEXITCODE_FAILURE;