VRDEServerImpl.cpp revision 436af3fae467c3876aa5004db9fb92a01714039f
/** @file
*
* VirtualBox COM class implementation
*/
/*
* Copyright (C) 2006-2013 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.
*/
#include "VRDEServerImpl.h"
#include "MachineImpl.h"
#include "VirtualBoxImpl.h"
#ifdef VBOX_WITH_EXTPACK
# include "ExtPackManagerImpl.h"
#endif
#include "AutoStateDep.h"
#include "AutoCaller.h"
#include "Global.h"
#include "Logging.h"
// defines
/////////////////////////////////////////////////////////////////////////////
#define VRDP_DEFAULT_PORT_STR "3389"
// constructor / destructor
/////////////////////////////////////////////////////////////////////////////
{
}
VRDEServer::~VRDEServer()
{
}
{
return BaseFinalConstruct();
}
void VRDEServer::FinalRelease()
{
uninit();
}
// public initializer/uninitializer for internal purposes only
/////////////////////////////////////////////////////////////////////////////
/**
* Initializes the VRDP server object.
*
* @param aParent Handle of the parent object.
*/
{
/* Enclose the state transition NotReady->InInit->Ready */
AutoInitSpan autoInitSpan(this);
/* mPeer is left null */
mData->mAuthTimeout = 0;
/* Confirm a successful initialization */
return S_OK;
}
/**
* Initializes the object given another object
* (a kind of copy constructor). This object shares data with
* the object passed as an argument.
*
* @note This object must be destroyed before the original object
* it shares data with is destroyed.
*
* @note Locks @a aThat object for reading.
*/
{
/* Enclose the state transition NotReady->InInit->Ready */
AutoInitSpan autoInitSpan(this);
/* Confirm a successful initialization */
return S_OK;
}
/**
* Initializes the guest object given another guest object
* (a kind of copy constructor). This object makes a private copy of data
* of the original object passed as an argument.
*
* @note Locks @a aThat object for reading.
*/
{
/* Enclose the state transition NotReady->InInit->Ready */
AutoInitSpan autoInitSpan(this);
/* mPeer is left null */
/* Confirm a successful initialization */
return S_OK;
}
/**
* Uninitializes the instance and sets the ready flag to FALSE.
* Called either from FinalRelease() or by the parent when it gets destroyed.
*/
void VRDEServer::uninit()
{
LogFlowThisFunc(("\n"));
/* Enclose the state transition Ready->InUninit->NotReady */
AutoUninitSpan autoUninitSpan(this);
if (autoUninitSpan.uninitDone())
return;
}
/**
* Loads settings from the given machine node.
* May be called once right after this object creation.
*
* @param aMachineNode <Machine> node.
*
* @note Locks this object for writing.
*/
{
using namespace settings;
AutoCaller autoCaller(this);
return S_OK;
}
/**
* Saves settings to the given machine node.
*
* @param aMachineNode <Machine> node.
*
* @note Locks this object for reading.
*/
{
AutoCaller autoCaller(this);
return S_OK;
}
// IVRDEServer properties
/////////////////////////////////////////////////////////////////////////////
{
AutoCaller autoCaller(this);
return S_OK;
}
{
AutoCaller autoCaller(this);
/* the machine can also be in saved state for this property to change */
{
/* leave the lock before informing callbacks */
/* Avoid deadlock when onVRDEServerChange eventually calls SetExtraData. */
}
return rc;
}
{
/* Gets a string of digits, converts to 16 bit port number.
* Note: pszStart <= pszEnd is expected, the string contains
* only digits and pszEnd points to the char after last
* digit.
*/
{
unsigned uPort = 0;
{
pszStart++;
}
{
if (pu16Port)
return VINF_SUCCESS;
}
}
return VERR_INVALID_PARAMETER;
}
{
return VERR_INVALID_PARAMETER;
/* The string should be like "1000-1010,1020,2000-2003" */
while (*pszPortRange)
{
const char *pszStart = pszPortRange;
{
if (*pszEnd == '-')
{
return VERR_INVALID_PARAMETER; /* More than one '-'. */
}
else if (!RT_C_IS_DIGIT(*pszEnd))
return VERR_INVALID_PARAMETER;
pszEnd++;
}
/* Update the next range pointer. */
if (*pszPortRange == ',')
{
pszPortRange++;
}
/* A probably valid range. Verify and parse it. */
int rc;
if (pszDash)
{
if (RT_SUCCESS(rc))
}
else
if (RT_FAILURE(rc))
return rc;
}
return VINF_SUCCESS;
}
{
LogFlowThisFunc(("\n"));
AutoCaller autoCaller(this);
/* the machine can also be in saved state for this property to change */
/* Special processing for some "standard" properties. */
{
/* Verify the string. */
if (RT_FAILURE(vrc))
return E_INVALIDARG;
{
/* Port value is not verified here because it is up to VRDP transport to
* use it. Specifying a wrong port number will cause a running server to
* stop. There is no fool proof here.
*/
else
/* leave the lock before informing callbacks */
/* Avoid deadlock when onVRDEServerChange eventually calls SetExtraData. */
}
}
else
{
/* Generic properties processing.
* Look up the old value first; if nothing's changed then do nothing.
*/
if (strOldValue != strValue)
{
else
/* leave the lock before informing callbacks */
/* Avoid deadlock when onVRDEServerChange eventually calls SetExtraData. */
}
}
return S_OK;
}
{
AutoCaller autoCaller(this);
return S_OK;
}
static int loadVRDELibrary(const char *pszLibraryName, RTLDRMOD *phmod, PFNVRDESUPPORTEDPROPERTIES *ppfn)
{
int rc = VINF_SUCCESS;
if (RTPathHavePath(pszLibraryName))
else
if (RT_SUCCESS(rc))
{
}
else
{
LogRel(("VRDE: Error loading the library '%s': %s (%Rrc)\n", pszLibraryName, ErrInfo.Core.pszMsg, rc));
else
hmod = NIL_RTLDRMOD;
}
if (RT_SUCCESS(rc))
{
}
else
{
if (hmod != NIL_RTLDRMOD)
{
hmod = NIL_RTLDRMOD;
}
}
return rc;
}
{
return E_POINTER;
AutoCaller autoCaller(this);
size_t cProperties = 0;
{
return S_OK;
}
/*
* Check that a VRDE extension pack name is set and resolve it into a
* library path.
*/
return hrc;
if (bstrExtPack.isEmpty())
return E_FAIL;
int vrc = VINF_SUCCESS;
strVrdeLibrary = "VBoxVRDP";
else
{
#ifdef VBOX_WITH_EXTPACK
#else
#endif
}
if (RT_SUCCESS(vrc))
{
/*
* Load the VRDE library and start the server, if it is enabled.
*/
if (RT_SUCCESS(vrc))
{
const char * const *papszNames = pfn();
if (papszNames)
{
size_t i;
for (i = 0; papszNames[i] != NULL; ++i)
{
cProperties++;
}
}
if (cProperties > 0)
{
size_t i;
{
}
}
/* Do not forget to unload the library. */
hmod = NIL_RTLDRMOD;
}
}
if (RT_FAILURE(vrc))
{
return E_FAIL;
}
return S_OK;
}
{
AutoCaller autoCaller(this);
return S_OK;
}
{
AutoCaller autoCaller(this);
/* the machine can also be in saved state for this property to change */
{
/* leave the lock before informing callbacks */
}
return S_OK;
}
{
AutoCaller autoCaller(this);
return S_OK;
}
{
AutoCaller autoCaller(this);
/* the machine can also be in saved state for this property to change */
{
/* leave the lock before informing callbacks */
/* sunlover 20060131: This setter does not require the notification
* really */
#if 0
#endif
}
return S_OK;
}
{
AutoCaller autoCaller(this);
if (bstrLibrary.isEmpty())
{
/* Get the global setting. */
}
return S_OK;
}
{
AutoCaller autoCaller(this);
/* the machine can also be in saved state for this property to change */
{
/* leave the lock before informing callbacks */
}
return S_OK;
}
{
AutoCaller autoCaller(this);
return S_OK;
}
{
AutoCaller autoCaller(this);
/* the machine can also be in saved state for this property to change */
{
/* leave the lock before informing callbacks */
}
return S_OK;
}
{
AutoCaller autoCaller(this);
return S_OK;
}
{
AutoCaller autoCaller(this);
/* the machine can also be in saved state for this property to change */
{
/* leave the lock before informing callbacks */
}
return S_OK;
}
{
AutoCaller autoCaller(this);
{
if (strExtPack.isNotEmpty())
{
else
{
#ifdef VBOX_WITH_EXTPACK
#else
#endif
}
}
else
{
/* Get the global setting. */
}
}
return hrc;
}
{
AutoCaller autoCaller(this);
{
/* the machine can also be in saved state for this property to change */
{
/*
* If not empty, check the specific extension pack.
*/
if (!strExtPack.isEmpty())
{
else
{
#ifdef VBOX_WITH_EXTPACK
#else
#endif
}
}
{
/*
* Update the setting if there is an actual change, post an
* change event to trigger a VRDE server restart.
*/
{
/* leave the lock before informing callbacks */
}
}
}
}
return hrc;
}
// public methods only for internal purposes
/////////////////////////////////////////////////////////////////////////////
/**
* @note Locks this object for writing.
*/
void VRDEServer::rollback()
{
/* sanity */
AutoCaller autoCaller(this);
}
/**
* @note Locks this object for writing, together with the peer object (also
* for writing) if there is one.
*/
void VRDEServer::commit()
{
/* sanity */
AutoCaller autoCaller(this);
/* sanity too */
/* lock both for writing since we modify both (mPeer is "master" so locked
* first) */
if (mData.isBackedUp())
{
if (mPeer)
{
/* attach new data to the peer and reshare it */
}
}
}
/**
* @note Locks this object for writing, together with the peer object
* represented by @a aThat (locked for reading).
*/
{
/* sanity */
AutoCaller autoCaller(this);
/* sanity too */
/* peer is not modified, lock it for reading (aThat is "master" so locked
* first) */
/* this will back up current data */
}
/* vi: set tabstop=4 shiftwidth=4 expandtab: */