VBoxHeadless.cpp revision 1620d0ba94cdb023e9436603164aa6ca2745b2ed
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync * VBoxHeadless - The VirtualBox Headless frontend for running VMs on servers.
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync * Copyright (C) 2006-2012 Oracle Corporation
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync * available from http://www.virtualbox.org. This file is free software;
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync * you can redistribute it and/or modify it under the terms of the GNU
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync * General Public License (GPL) as published by the Free Software
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsyncusing namespace com;
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync//#define VBOX_WITH_SAVESTATE_ON_SIGNAL
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync////////////////////////////////////////////////////////////////////////////////
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync Log(("VBoxHeadless: ERROR: " m " [rc=0x%08X]\n", rc)); \
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync } while (0)
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync////////////////////////////////////////////////////////////////////////////////
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync/* global weak references (for event handlers) */
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync/* flag whether frontend should terminate */
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsyncstatic volatile bool g_fTerminateFE = false;
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync////////////////////////////////////////////////////////////////////////////////
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync * Handler for VirtualBoxClient events.
7d7c3dba7ea44027b3adf273ef13b638271a4f58vboxsync STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent)
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync ComPtr<IVBoxSVCAvailabilityChangedEvent> pVSACEv = aEvent;
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync LogRel(("VBoxHeadless: VBoxSVC became unavailable, exiting.\n"));
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync RTPrintf("VBoxSVC became unavailable, exiting.\n");
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync /* Terminate the VM as cleanly as possible given that VBoxSVC
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync * is no longer present. */
094bd1aaada16d47495d62f7c3324f9df84c999avboxsync * Handler for global events.
094bd1aaada16d47495d62f7c3324f9df84c999avboxsync STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent)
094bd1aaada16d47495d62f7c3324f9df84c999avboxsync if (aKey == Bstr("/VirtualBox/GuestInfo/OS/NoLoggedInUsers"))
094bd1aaada16d47495d62f7c3324f9df84c999avboxsync /* Check if this is our machine and the "disconnect on logout feature" is enabled. */
094bd1aaada16d47495d62f7c3324f9df84c999avboxsync hrc = gConsole->COMGETTER(Machine)(machine.asOutParam());
094bd1aaada16d47495d62f7c3324f9df84c999avboxsync gpcev->COMGETTER(MachineId)(machineId.asOutParam());
094bd1aaada16d47495d62f7c3324f9df84c999avboxsync hrc = machine->GetExtraData(Bstr("VRDP/DisconnectOnGuestLogout").raw(),
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync if (!mfNoLoggedInUsers) /* Only if the property really changes. */
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync /* Guest property got deleted due to reset,
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync * so it has no value anymore. */
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync /* Guest property got deleted due to reset,
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync * take the shortcut without touching the mfNoLoggedInUsers
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync * state. */
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync /* If there is a connection, drop it. */
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync hrc = gConsole->COMGETTER(VRDEServerInfo)(info.asOutParam());
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync hrc = machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync LogRel(("VRDE: the guest user has logged out, disconnecting remote clients.\n"));
decf6daa697ed0e43daab9dc84769165b23f5abavboxsync * Handler for machine events.
094bd1aaada16d47495d62f7c3324f9df84c999avboxsync STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent)
094bd1aaada16d47495d62f7c3324f9df84c999avboxsync ComPtr<IMouseCapabilityChangedEvent> mccev = aEvent;
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync mccev->COMGETTER(SupportsAbsolute)(&fSupportsAbsolute);
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync /* Emit absolute mouse event to actually enable the host mouse cursor. */
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync mouse->PutMouseEventAbsolute(-1, -1, 0, 0 /* Horizontal wheel */, 0);
decf6daa697ed0e43daab9dc84769165b23f5abavboxsync /* Terminate any event wait operation if the machine has been
1d42c7799e7c35c5b36a2494cde9a47e5651ceadvboxsync if (machineState < MachineState_Running && !m_fIgnorePowerOffEvents)
g_fTerminateFE = true;
if (gConsole)
if (info)
else if (port == 0)
AssertFailed();
return S_OK;
long mLastVRDEPort;
bool m_fIgnorePowerOffEvents;
lrc = ~0;
if (!lrc)
static void show_usage()
#ifdef VBOX_WITH_VIDEO_REC
#ifdef VBOX_WITH_VIDEO_REC
const char *pszEnvTemp;
errno = 0;
if (errno != 0)
errno = 0;
if (errno != 0)
errno = 0;
if (errno != 0)
if (!fStdIn)
if (!fStdIn)
return rcExit;
int rc;
return rcExit;
#ifdef RT_OS_WINDOWS
unsigned cVRDEProperties = 0;
unsigned fRawR0 = ~0U;
unsigned fRawR3 = ~0U;
unsigned fPATM = ~0U;
unsigned fCSAM = ~0U;
#ifdef VBOX_WITH_VIDEO_REC
unsigned fFFMPEG = 0;
#ifdef VBOX_WITH_VIDEO_REC
enum eHeadlessOptions
#ifdef VBOX_WITH_VIDEO_REC
int ch;
switch(ch)
RTPrintf("Warning: '-p' or '-vrdpport' are deprecated. Use '-e \"TCP/Ports=%s\"'\n", ValueUnion.psz);
RTPrintf("Warning: '-a' or '-vrdpaddress' are deprecated. Use '-e \"TCP/Address=%s\"'\n", ValueUnion.psz);
case OPT_RAW_R0:
fRawR0 = true;
case OPT_NO_RAW_R0:
fRawR0 = false;
case OPT_RAW_R3:
fRawR3 = true;
case OPT_NO_RAW_R3:
fRawR3 = false;
case OPT_PATM:
fPATM = true;
case OPT_NO_PATM:
fPATM = false;
case OPT_CSAM:
fCSAM = true;
case OPT_NO_CSAM:
fCSAM = false;
case OPT_SETTINGSPW:
case OPT_SETTINGSPW_FILE:
#ifdef VBOX_WITH_VIDEO_REC
fFFMPEG = true;
#ifdef VBOX_WITH_VIDEO_REC
show_usage();
case OPT_COMMENT:
show_usage();
return ch;
#ifdef VBOX_WITH_VIDEO_REC
if (!pcszNameOrUUID)
show_usage();
#ifdef VBOX_WITH_XPCOM
RTPrintf("Failed to initialize COM because the global settings directory '%s' is not accessible!", szHome);
bool fSessionOpened = false;
if (pcszSettingsPw)
else if (pcszSettingsPwFile)
fSessionOpened = true;
#ifdef VBOX_WITH_VIDEO_REC
if (fFFMPEG)
rrc = SUPR3HardenedLdrLoadAppPriv("VBoxFFmpegFB", &hLdrFFmpegFB, RTLDRLOAD_FLAGS_LOCAL, &ErrInfo.Core);
reinterpret_cast<void **>(&pfnRegisterFFmpegFB));
LogError("Failed to load the video capture extension\n", rrc); /** @todo stupid function, no formatting options. */
unsigned uScreenId;
# ifdef VBOX_WITH_VIDEO_REC
if (!pVRDPFramebuffer)
if (machineDebugger)
if (fRawR0 != ~0U)
if (!machineDebugger)
if (fRawR3 != ~0U)
if (!machineDebugger)
if (fPATM != ~0U)
if (!machineDebugger)
if (fCSAM != ~0U)
if (!machineDebugger)
fVRDEEnable = false;
if (!fVRDEEnabled)
fVRDEEnable = false;
if (fVRDEEnable)
if (cVRDEProperties > 0)
for (unsigned i = 0; i < cVRDEProperties; i++)
if (pszProperty)
if (pDelimiter)
if (!fVRDEEnabled)
if (fVRDEEnabled)
if (!g_fTerminateFE)
while ( !g_fTerminateFE
#ifdef VBOX_WITH_VIDEO_REC
if (pFramebuffer)
if ( gConsole
if (vboxListener)
if (consoleListener)
if (vboxClientListener)
/* No more access to the 'console' object, which will be uninitialized by the next session->Close call. */
if (fSessionOpened)
#ifndef VBOX_WITH_HARDENING
switch (rc)
#ifdef VBOX_WITH_XPCOM