VBoxHeadless.cpp revision c054ef480e3ba61ca85a0fe720e85c44f94a57d2
5b281ba489ca18f0380d7efc7a5108b606cce449vboxsync * VBoxHeadless - The VirtualBox Headless frontend for running VMs on servers.
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * Copyright (C) 2006-2010 Oracle Corporation
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * available from http://www.virtualbox.org. This file is free software;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * you can redistribute it and/or modify it under the terms of the GNU
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * General Public License (GPL) as published by the Free Software
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsyncusing namespace com;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync//#define VBOX_WITH_SAVESTATE_ON_SIGNAL
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync////////////////////////////////////////////////////////////////////////////////
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync Log(("VBoxHeadless: ERROR: " m " [rc=0x%08X]\n", rc)); \
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync } while (0)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync////////////////////////////////////////////////////////////////////////////////
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync/* global weak references (for event handlers) */
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync/* flag whether frontend should terminate */
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsyncstatic volatile bool g_fTerminateFE = false;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync////////////////////////////////////////////////////////////////////////////////
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * Handler for VirtualBoxClient events.
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent * aEvent)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync ComPtr<IVBoxSVCAvailabilityChangedEvent> pVSACEv = aEvent;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync LogRel(("VBoxHeadless: VBoxSVC became unavailable, exiting.\n"));
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync RTPrintf("VBoxSVC became unavailable, exiting.\n");
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync /* Terminate the VM as cleanly as possible given that VBoxSVC
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * is no longer present. */
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * Handler for global events.
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent * aEvent)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync if (aKey == Bstr("/VirtualBox/GuestInfo/OS/NoLoggedInUsers"))
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync /* Check if this is our machine and the "disconnect on logout feature" is enabled. */
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync hrc = gConsole->COMGETTER(Machine)(machine.asOutParam());
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync gpcev->COMGETTER(MachineId)(machineId.asOutParam());
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync hrc = machine->GetExtraData(Bstr("VRDP/DisconnectOnGuestLogout").raw(),
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync if (!mfNoLoggedInUsers) /* Only if the property really changes. */
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync /* If there is a connection, drop it. */
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync hrc = gConsole->COMGETTER(VRDEServerInfo)(info.asOutParam());
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync hrc = machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
004d34f82d0e8a4d58a65cc50eacf298bc6eb956vboxsync LogRel(("VRDE: the guest user has logged out, disconnecting remote clients.\n"));
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * Handler for machine events.
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent * aEvent)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync ComPtr<IMouseCapabilityChangedEvent> mccev = aEvent;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync mccev->COMGETTER(SupportsAbsolute)(&fSupportsAbsolute);
if (mouse)
#ifdef VBOX_WITH_VNC
if (g_pFramebufferVNC)
* PoweredDown/Saved/Aborted. */
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_VNC
#ifdef VBOX_FFMPEG
#ifdef VBOX_FFMPEG
const char *pszEnvTemp;
errno = 0;
if (errno != 0)
errno = 0;
if (errno != 0)
errno = 0;
if (errno != 0)
unsigned cVRDEProperties = 0;
#ifdef VBOX_WITH_VNC
bool fVNCEnable = false;
unsigned fRawR0 = ~0U;
unsigned fRawR3 = ~0U;
unsigned fPATM = ~0U;
unsigned fCSAM = ~0U;
#ifdef VBOX_FFMPEG
unsigned fFFMPEG = 0;
#ifdef VBOX_FFMPEG
enum eHeadlessOptions
#ifdef VBOX_WITH_VNC
#ifdef VBOX_FFMPEG
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);
#ifdef VBOX_WITH_VNC
fVNCEnable = true;
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;
#ifdef VBOX_FFMPEG
fFFMPEG = true;
#ifdef VBOX_FFMPEG
show_usage();
case OPT_COMMENT:
show_usage();
return ch;
#ifdef VBOX_FFMPEG
if (!pcszNameOrUUID)
show_usage();
bool fSessionOpened = false;
fSessionOpened = true;
#ifdef VBOX_FFMPEG
if (fFFMPEG)
rrc = SUPR3HardenedLdrLoadAppPriv("VBoxFFmpegFB", &hLdrFFmpegFB, 0 /*=fFlags*/, szErr, sizeof(szErr));
reinterpret_cast<void **>(&pfnRegisterFFmpegFB));
LogError("Failed to load the video capture extension\n", rrc); /** @todo stupid function, no formatting options. */
#ifdef VBOX_WITH_VNC
if (fVNCEnable)
delete g_pFramebufferVNC;
unsigned uScreenId;
# ifdef VBOX_FFMPEG
# ifdef VBOX_WITH_VNC
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_FFMPEG
if (pFramebuffer)
if ( gConsole
if (vboxListener)
if (consoleListener)
if (consoleListener)
/* 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