VBoxManageControlVM.cpp revision d01bb88591e2ae070aa233b99c81e58598d557e1
/* $Id$ */
/** @file
* VBoxManage - Implementation of the controlvm command.
*/
/*
* Copyright (C) 2006-2014 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 "VBoxManage.h"
#include <list>
/**
* Parses a number.
*
* @returns Valid number on success.
* @returns 0 if invalid number. All necessary bitching has been done.
* @param psz Pointer to the nic number.
*/
{
char *pszNext;
if ( RT_SUCCESS(rc)
&& *pszNext == '\0'
&& u32 >= 1
return (unsigned)u32;
return 0;
}
{
ULONG NetworkAdapterCount = 0;
do {
return (unsigned int)NetworkAdapterCount;
} while (0);
return 0;
}
int handleControlVM(HandlerArg *a)
{
using namespace com;
if (a->argc < 2)
/* try to find the given machine */
machine.asOutParam()));
return 1;
/* open a session for the VM */
do
{
/* get the associated console */
/* ... and session machine */
/* which command? */
{
}
{
}
{
}
{
{
break;
}
}
{
{
break;
}
}
{
{
break;
}
}
{
{
break;
}
else
{
}
{
}
}
{
{
break;
}
else
{
}
{
}
}
{
}
{
bool fPaused = false;
{
bool fError = true;
if (rc == VBOX_E_INVALID_VM_STATE)
{
/* check if we are already paused */
/* the error code was lost by the previous instruction */
if (machineState != MachineState_Paused)
{
RTMsgError("Machine in invalid state %d -- %s\n",
}
else
{
fError = false;
fPaused = true;
}
}
if (fError)
break;
}
{
if (!fPaused)
break;
}
{
if (!fPaused)
}
}
{
}
{
}
{
if (!pKeyboard)
{
RTMsgError("Guest not running");
break;
}
{
errorArgument("Missing argument to '%s'. Expected IBM PC AT set 2 keyboard scancode(s) as hex byte(s).", a->argv[1]);
break;
}
/* Process the command line. */
int i;
{
if ( RT_C_IS_XDIGIT (a->argv[i][0])
&& a->argv[i][2] == 0)
{
if (RT_FAILURE (irc))
{
break;
}
}
else
{
break;
}
}
break;
/* Send scancodes to the VM. */
ULONG codesStored = 0;
&codesStored));
{
break;
}
}
{
/* Get the number of network adapters */
if (!n)
{
break;
}
{
break;
}
/* get the corresponding network adapter */
if (adapter)
{
{
}
{
}
else
{
break;
}
}
}
/* here the order in which strncmp is called is important
* cause nictracefile can be very well compared with
* nictrace and nic and thus everything will always fail
* if the order is changed
*/
{
/* Get the number of network adapters */
if (!n)
{
break;
}
if (a->argc <= 2)
{
break;
}
/* get the corresponding network adapter */
if (adapter)
{
if (fEnabled)
{
if (a->argv[2])
{
}
else
{
errorArgument("Invalid filename or filename not specified for NIC %lu", n);
break;
}
}
else
RTMsgError("The NIC %d is currently disabled and thus its tracefile can't be changed", n);
}
}
{
/* Get the number of network adapters */
if (!n)
{
break;
}
if (a->argc <= 2)
{
break;
}
/* get the corresponding network adapter */
if (adapter)
{
if (fEnabled)
{
{
}
{
}
else
{
break;
}
}
else
RTMsgError("The NIC %d is currently disabled and thus its trace flag can't be changed", n);
}
}
else if( a->argc > 2
{
/* Get the number of network adapters */
if (!n)
{
break;
}
if (a->argc <= 2)
{
break;
}
/* get the corresponding network adapter */
if (!adapter)
{
break;
}
if (!engine)
{
break;
}
{
if (a->argc >= 3)
}
else
{
#define ITERATE_TO_NEXT_TERM(ch) \
do { \
while (*ch != ',') \
{ \
if (*ch == 0) \
{ \
return errorSyntax(USAGE_CONTROLVM, \
"Missing or invalid argument to '%s'", \
a->argv[1]); \
} \
ch++; \
} \
*ch = '\0'; \
ch++; \
} while(0)
char *strName;
char *strProto;
char *strHostIp;
char *strHostPort;
char *strGuestIp;
char *strGuestPort;
else
{
return errorSyntax(USAGE_CONTROLVM,
"Wrong rule proto '%s' specified -- only 'udp' and 'tcp' are allowed.",
strProto);
}
}
/* commit changes */
}
{
/* Get the number of network adapters */
if (!n)
{
break;
}
if (a->argc <= 2)
{
break;
}
/* get the corresponding network adapter */
if (adapter)
{
if (fEnabled)
{
/* Parse 'name=value' */
if (pszProperty)
{
if (pDelimiter)
{
*pDelimiter = '\0';
}
else
{
}
}
else
{
RTStrmPrintf(g_pStdErr, "Error: Failed to allocate memory for nicproperty%d '%s'\n", n, a->argv[2]);
}
break;
}
else
RTMsgError("The NIC %d is currently disabled and thus its properties can't be changed", n);
}
}
{
/* Get the number of network adapters */
if (!n)
{
break;
}
if (a->argc <= 2)
{
break;
}
/* get the corresponding network adapter */
if (adapter)
{
if (fEnabled)
{
else
{
rc = E_INVALIDARG;
break;
}
}
else
RTMsgError("The NIC %d is currently disabled and thus its promiscuous mode can't be changed", n);
}
}
{
/* Get the number of network adapters */
if (!n)
{
break;
}
if (a->argc <= 2)
{
break;
}
/* get the corresponding network adapter */
if (adapter)
{
if (fEnabled)
{
{
}
{
if (a->argc == 4)
}
{
if (a->argc <= 3)
{
break;
}
}
{
if (a->argc <= 3)
{
break;
}
}
#if defined(VBOX_WITH_NETFLT)
{
if (a->argc <= 3)
{
break;
}
}
#endif
{
if (a->argc <= 3)
{
break;
}
}
{
if (a->argc <= 3)
{
break;
}
}
/** @todo obsolete, remove eventually */
{
if (a->argc <= 3)
{
break;
}
}
else
{
break;
}
}
else
RTMsgError("The NIC %d is currently disabled and thus its attachment type can't be changed", n);
}
}
{
{
break;
}
if (vrdeServer)
{
{
}
{
}
else
{
break;
}
}
}
{
{
break;
}
if (vrdeServer)
{
ports = "0";
else
}
}
{
RTStrmPrintf(g_pStdErr, "Warning: 'vrdpvideochannelquality' is deprecated. Use 'vrdevideochannelquality'.\n");
{
break;
}
if (vrdeServer)
{
}
}
{
{
break;
}
if (vrdeServer)
{
/* Parse 'name=value' */
if (pszProperty)
{
if (pDelimiter)
{
*pDelimiter = '\0';
}
else
{
}
}
else
{
}
}
{
break;
}
}
{
if (a->argc < 3)
{
break;
}
{
// assume address
if (attach)
{
dev.asOutParam()));
}
else
{
dev.asOutParam()));
}
}
{
break;
}
if (attach)
else
{
dev.asOutParam()));
}
}
{
{
break;
}
bool fEnabled = true;
uint32_t uDisplayIdx = 0;
bool fChangeOrigin = false;
if (a->argc >= 6)
if (a->argc >= 7)
{
if (RT_FAILURE(vrc))
{
break;
}
}
if (a->argc == 9)
{
fChangeOrigin = true;
}
if (!pDisplay)
{
RTMsgError("Guest not running");
break;
}
}
{
bool fAllowLocalLogon = true;
if ( a->argc == 7
|| ( a->argc == 8
{
{
break;
}
fAllowLocalLogon = false;
}
else if ( a->argc != 5
&& ( a->argc != 6
{
break;
}
{
}
else
{
if (rcExit != RTEXITCODE_SUCCESS)
{
break;
}
}
if (!pGuest)
{
RTMsgError("Guest not running");
break;
}
}
#if 0 /* TODO: review & remove */
{
if (a->argc != 3)
{
break;
}
/* unmount? */
{
/* nothing to do, NULL object will cause unmount */
}
/* host drive? */
{
if (!dvdMedium)
{
errorArgument("Invalid host DVD drive name \"%s\"",
break;
}
}
else
{
/* first assume it's a UUID */
{
/* must be a filename, check if it's in the collection */
/* not registered, do that on the fly */
if (!dvdMedium)
{
}
}
if (!dvdMedium)
{
break;
}
}
/** @todo generalize this, allow arbitrary number of DVD drives
* and as a consequence multiple attachments and different
* storage controllers. */
if (dvdMedium)
else
}
{
if (a->argc != 3)
{
break;
}
/* unmount? */
{
/* nothing to do, NULL object will cause unmount */
}
/* host drive? */
{
if (!floppyMedium)
{
errorArgument("Invalid host floppy drive name \"%s\"",
break;
}
}
else
{
/* first assume it's a UUID */
{
/* must be a filename, check if it's in the collection */
/* not registered, do that on the fly */
if (!floppyMedium)
{
CHECK_ERROR(a->virtualBox, OpenFloppyImage(Bstr(a->argv[2]), emptyUUID, floppyMedium.asOutParam()));
}
}
if (!floppyMedium)
{
break;
}
}
}
#endif /* obsolete dvdattach/floppyattach */
{
if (a->argc != 3)
{
break;
}
int vrc;
if (vrc != VINF_SUCCESS)
{
break;
}
/* guest is running; update IGuest */
{
if (!pGuest)
{
RTMsgError("Guest not running");
break;
}
}
}
{
uint32_t cMsTimeout = 0;
static const RTGETOPTDEF s_aTeleportOptions[] =
{
};
RTGetOptInit(&GetOptState, a->argc, a->argv, s_aTeleportOptions, RT_ELEMENTS(s_aTeleportOptions), 2, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
int ch;
{
switch (ch)
{
case 'D': g_fDetailedProgress = true; break;
case 'p':
{
if (rcExit != RTEXITCODE_SUCCESS)
break;
}
default:
break;
}
}
break;
progress.asOutParam()));
if (cMsTimeout)
{
}
}
{
{
break;
}
int vrc;
if (a->argc == 4)
{
if (vrc != VINF_SUCCESS)
{
break;
}
}
if (!pDisplay)
{
RTMsgError("Guest not running");
break;
}
CHECK_ERROR_BREAK(pDisplay, GetScreenResolution(iScreen, &width, &height, &bpp, &xOrigin, &yOrigin));
CHECK_ERROR_BREAK(pDisplay, TakeScreenShotToArray(iScreen, width, height, BitmapFormat_PNG, ComSafeArrayAsOutParam(saScreenshot)));
vrc = RTFileOpen(&pngFile, a->argv[2], RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_TRUNCATE | RTFILE_O_DENY_ALL);
if (RT_FAILURE(vrc))
{
break;
}
if (RT_FAILURE(vrc))
{
}
}
{
if (a->argc != 3)
{
break;
}
{
}
{
}
else
{
break;
}
}
{
if ( a->argc == 3
{
/* enable all screens */
for (unsigned i = 0; i < cMonitors; i++)
saScreens[i] = true;
}
else if ( a->argc == 3
{
/* disable all screens */
for (unsigned i = 0; i < cMonitors; i++)
saScreens[i] = false;
}
else
{
/* enable selected screens */
for (unsigned i = 0; i < cMonitors; i++)
saScreens[i] = false;
{
if (vrc != VINF_SUCCESS)
{
break;
}
{
break;
}
}
}
CHECK_ERROR_BREAK(sessionMachine, COMSETTER(VideoCaptureScreens)(ComSafeArrayAsInParam(saScreens)));
}
{
if (a->argc < 3)
{
break;
}
if (!pEmulatedUSB)
{
RTMsgError("Guest not running");
break;
}
{
if (a->argc >= 4)
if (a->argc >= 5)
}
{
if (a->argc >= 4)
}
{
{
}
}
else
{
break;
}
}
else
{
}
} while (0);
a->session->UnlockMachine();
}