VirtualBoxImpl.cpp revision 4fea7a40e3d4c0e903287c0ee728512f3e63df72
6a67d144095c31bbafed93cec1619590157335eajvergara * Implementation of IVirtualBox in VBoxSVC.
6a67d144095c31bbafed93cec1619590157335eajvergara * Copyright (C) 2006-2010 Oracle Corporation
6a67d144095c31bbafed93cec1619590157335eajvergara * This file is part of VirtualBox Open Source Edition (OSE), as
6a67d144095c31bbafed93cec1619590157335eajvergara * available from http://www.virtualbox.org. This file is free software;
6a67d144095c31bbafed93cec1619590157335eajvergara * you can redistribute it and/or modify it under the terms of the GNU
6a67d144095c31bbafed93cec1619590157335eajvergara * General Public License (GPL) as published by the Free Software
6a67d144095c31bbafed93cec1619590157335eajvergara * Foundation, in version 2 as it comes in the "COPYING" file of the
6a67d144095c31bbafed93cec1619590157335eajvergara * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
6a67d144095c31bbafed93cec1619590157335eajvergara * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
6a67d144095c31bbafed93cec1619590157335eajvergara#endif /* VBOX_WITH_RESOURCE_USAGE_API */
6a67d144095c31bbafed93cec1619590157335eajvergara////////////////////////////////////////////////////////////////////////////////
6a67d144095c31bbafed93cec1619590157335eajvergara// Definitions
6a67d144095c31bbafed93cec1619590157335eajvergara////////////////////////////////////////////////////////////////////////////////
6a67d144095c31bbafed93cec1619590157335eajvergara////////////////////////////////////////////////////////////////////////////////
6a67d144095c31bbafed93cec1619590157335eajvergara// Global variables
2401d3c2af505789c7c3b860a43e973f27731243jvergara////////////////////////////////////////////////////////////////////////////////
2401d3c2af505789c7c3b860a43e973f27731243jvergara////////////////////////////////////////////////////////////////////////////////
2401d3c2af505789c7c3b860a43e973f27731243jvergara// VirtualBoxCallbackRegistration
2401d3c2af505789c7c3b860a43e973f27731243jvergara////////////////////////////////////////////////////////////////////////////////
6a67d144095c31bbafed93cec1619590157335eajvergara * Registered IVirtualBoxCallback, used by VirtualBox::CallbackList and
6a67d144095c31bbafed93cec1619590157335eajvergara * VirtualBox::Data::llCallbacks.
6a67d144095c31bbafed93cec1619590157335eajvergara * In addition to keeping the interface pointer this also keeps track of the
6a67d144095c31bbafed93cec1619590157335eajvergara * methods that asked to not be called again. The latter is for reducing
6a67d144095c31bbafed93cec1619590157335eajvergara * unnecessary IPC.
6a67d144095c31bbafed93cec1619590157335eajvergara /** Callback bit indexes (for bmDisabled). */
6a67d144095c31bbafed93cec1619590157335eajvergara typedef enum
ffa279622cea61d6eec13e3df386bd3015388388jvergara /* nothing */
6a67d144095c31bbafed93cec1619590157335eajvergara /* nothing */
6a67d144095c31bbafed93cec1619590157335eajvergara////////////////////////////////////////////////////////////////////////////////
6a67d144095c31bbafed93cec1619590157335eajvergara// CallbackEvent class
6a67d144095c31bbafed93cec1619590157335eajvergara////////////////////////////////////////////////////////////////////////////////
48013e6d1c0677bd7649309e6b0b611b6c364c77jvergara * Abstract callback event class to asynchronously call VirtualBox callbacks
48013e6d1c0677bd7649309e6b0b611b6c364c77jvergara * on a dedicated event thread. Subclasses reimplement #handleCallback()
6a67d144095c31bbafed93cec1619590157335eajvergara * to call appropriate IVirtualBoxCallback methods depending on the event
6a67d144095c31bbafed93cec1619590157335eajvergara * to be dispatched.
6a67d144095c31bbafed93cec1619590157335eajvergara * @note The VirtualBox instance passed to the constructor is strongly
6a67d144095c31bbafed93cec1619590157335eajvergara * referenced, so that the VirtualBox singleton won't be released until the
6a67d144095c31bbafed93cec1619590157335eajvergara * event gets handled by the event thread.
6a67d144095c31bbafed93cec1619590157335eajvergara CallbackEvent(VirtualBox *aVirtualBox, VirtualBoxCallbackRegistration::CallbackBit aWhat)
48013e6d1c0677bd7649309e6b0b611b6c364c77jvergara virtual HRESULT prepareEventDesc(IEventSource* aSource, VBoxEventDesc& aEvDesc) = 0;
48013e6d1c0677bd7649309e6b0b611b6c364c77jvergara * Note that this is a weak ref -- the CallbackEvent handler thread
48013e6d1c0677bd7649309e6b0b611b6c364c77jvergara * is bound to the lifetime of the VirtualBox instance, so it's safe.
6a67d144095c31bbafed93cec1619590157335eajvergara////////////////////////////////////////////////////////////////////////////////
6a67d144095c31bbafed93cec1619590157335eajvergara// VirtualBox private member data definition
2401d3c2af505789c7c3b860a43e973f27731243jvergara////////////////////////////////////////////////////////////////////////////////
0877596da3b90efc5fd39171cef80a2fb8ec395ekenneth_suter#elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
c9d984b0d2c0fda320e79eb3868dd6fbeb1ffa34jvergaratypedef ObjectsList<SharedFolder> SharedFoldersOList;
c9d984b0d2c0fda320e79eb3868dd6fbeb1ffa34jvergaratypedef std::map<Guid, ComPtr<IProgress> > ProgressMap;
c9d984b0d2c0fda320e79eb3868dd6fbeb1ffa34jvergaratypedef std::map<Guid, ComObjPtr<Medium> > HardDiskMap;
6a67d144095c31bbafed93cec1619590157335eajvergara * Main VirtualBox data structure.
6a67d144095c31bbafed93cec1619590157335eajvergara * @note |const| members are persistent during lifetime so can be accessed
6a67d144095c31bbafed93cec1619590157335eajvergara * without locking.
0142bbb7ccb5d0efb942c20f5d27e5ddfb4344fdkenneth_suter lockGuestOSTypes(LOCKCLASS_LISTOFOTHEROBJECTS),
0142bbb7ccb5d0efb942c20f5d27e5ddfb4344fdkenneth_suter lockSharedFolders(LOCKCLASS_LISTOFOTHEROBJECTS),
0142bbb7ccb5d0efb942c20f5d27e5ddfb4344fdkenneth_suter lockDHCPServers(LOCKCLASS_LISTOFOTHEROBJECTS),
0142bbb7ccb5d0efb942c20f5d27e5ddfb4344fdkenneth_suter mtxProgressOperations(LOCKCLASS_PROGRESSLIST),
6a67d144095c31bbafed93cec1619590157335eajvergara // const data members not requiring locking
0142bbb7ccb5d0efb942c20f5d27e5ddfb4344fdkenneth_suter // VirtualBox main settings file
0142bbb7ccb5d0efb942c20f5d27e5ddfb4344fdkenneth_suter // const objects not requiring locking
0142bbb7ccb5d0efb942c20f5d27e5ddfb4344fdkenneth_suter const ComObjPtr<SystemProperties> pSystemProperties;
0142bbb7ccb5d0efb942c20f5d27e5ddfb4344fdkenneth_suter const ComObjPtr<PerformanceCollector> pPerformanceCollector;
6a67d144095c31bbafed93cec1619590157335eajvergara#endif /* VBOX_WITH_RESOURCE_USAGE_API */
6a67d144095c31bbafed93cec1619590157335eajvergara // Each of the following lists use a particular lock handle that protects the
6a67d144095c31bbafed93cec1619590157335eajvergara // list as a whole. As opposed to version 3.1 and earlier, these lists no
6a67d144095c31bbafed93cec1619590157335eajvergara // longer need the main VirtualBox object lock, but only the respective list
0142bbb7ccb5d0efb942c20f5d27e5ddfb4344fdkenneth_suter // lock. In each case, the locking order is defined that the list must be
0142bbb7ccb5d0efb942c20f5d27e5ddfb4344fdkenneth_suter // requested before object locks of members of the lists (see the order definitions
6a67d144095c31bbafed93cec1619590157335eajvergara // in AutoLock.h; e.g. LOCKCLASS_LISTOFMACHINES before LOCKCLASS_MACHINEOBJECT).
48013e6d1c0677bd7649309e6b0b611b6c364c77jvergara // All the media lists are protected by the following locking handle:
48013e6d1c0677bd7649309e6b0b611b6c364c77jvergara // the hard disks map is an additional map sorted by UUID for quick lookup
48013e6d1c0677bd7649309e6b0b611b6c364c77jvergara // and contains ALL hard disks (base and differencing); it is protected by
48013e6d1c0677bd7649309e6b0b611b6c364c77jvergara // the same lock as the other media lists above
48013e6d1c0677bd7649309e6b0b611b6c364c77jvergara // list of pending machine renames (also protected by media tree lock;
48013e6d1c0677bd7649309e6b0b611b6c364c77jvergara // see VirtualBox::rememberMachineNameChangeForMedia())
48013e6d1c0677bd7649309e6b0b611b6c364c77jvergara typedef std::list<PendingMachineRename> PendingMachineRenamesList;
0142bbb7ccb5d0efb942c20f5d27e5ddfb4344fdkenneth_suter // the following are data for the client watcher thread
0142bbb7ccb5d0efb942c20f5d27e5ddfb4344fdkenneth_suter // the following are data for the async event thread
0142bbb7ccb5d0efb942c20f5d27e5ddfb4344fdkenneth_suter// constructor / destructor
0142bbb7ccb5d0efb942c20f5d27e5ddfb4344fdkenneth_suter/////////////////////////////////////////////////////////////////////////////
return init();
uninit();
// public initializer/uninitializer for internal purposes only
m = new Data;
/* compose the VirtualBox.xml file name */
bool fCreate = false;
// load and parse VirtualBox.xml; this will throw on XML or logic errors
fCreate = true;
if (fCreate)
#ifdef VBOX_WITH_RESOURCE_USAGE_API
throw rc;
throw rc;
#ifdef DEBUG
++it)
#if defined(RT_OS_WINDOWS)
return rc;
++it)
&uuid);
return rc;
return S_OK;
++it)
++it)
++it)
return S_OK;
if (m->pHost)
if (m->pSystemProperties)
if (m->pHost)
#ifdef VBOX_WITH_RESOURCE_USAGE_API
if (m->pPerformanceCollector)
if (m->pEventSource)
#if defined(RT_OS_WINDOWS)
VDShutdown();
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return E_POINTER;
return S_OK;
return E_POINTER;
return S_OK;
return E_POINTER;
return S_OK;
return E_POINTER;
return S_OK;
return S_OK;
return S_OK;
#ifndef RT_OS_WINDOWS
#ifdef VBOX_WITH_RESOURCE_USAGE_API
return S_OK;
return E_POINTER;
return S_OK;
return S_OK;
const char* fileName;
const char* url;
} firmwareDesc[] = {
int rc;
if (aFile)
if (aFile)
return S_OK;
LogFlowThisFunc(("aName=\"%ls\",aOsTypeId =\"%ls\",aBaseFolder=\"%ls\"\n", aName, aOsTypeId, aBaseFolder));
aName);
id,
return rc;
id,
return rc;
return rc;
return rc;
&machine);
return rc;
++it)
? S_OK
return rc;
bool fNeedsSaveSettings = false;
if (fNeedsSaveSettings)
saveSettings();
return rc;
if (aSetImageId)
if (aSetParentId)
parentId);
bool fNeedsSaveSettings = false;
if (fNeedsSaveSettings)
saveSettings();
return rc;
return rc;
return rc;
bool fNeedsSaveSettings = false;
if (fNeedsSaveSettings)
saveSettings();
return rc;
return rc;
return rc;
rc = image->init(this, aLocation, Medium::OpenReadWrite, DeviceType_Floppy, true, id, false, Guid());
bool fNeedsSaveSettings = false;
if (fNeedsSaveSettings)
saveSettings();
return rc;
return rc;
return rc;
static const wchar_t *kOldNewIDs[] =
++it)
aId);
using namespace settings;
return E_POINTER;
++it, ++i)
return S_OK;
settings::ExtraDataItemsMap::const_iterator it = m->pMainConfigFile->mapExtraDataItems.find(strKey);
return S_OK;
settings::ExtraDataItemsMap::const_iterator it = m->pMainConfigFile->mapExtraDataItems.find(strKey);
bool fChanged;
aKey,
sep,
err);
if (fChanged)
return S_OK;
#ifdef DEBUG
++mt)
++mt)
return S_OK;
return S_OK;
return E_FAIL;
return S_OK;
return S_OK;
#ifdef RT_OS_WINDOWS
struct StartSVCHelperClientData
bool privileged;
void *user;
d(new StartSVCHelperClientData());
d->that = this;
static_cast <void *>(d.get()),
d.release();
return S_OK;
DECLCALLBACK(int)
bool userFuncCalled = false;
if (!exePath)
if (d->privileged)
userFuncCalled = true;
#if defined(RT_OS_WINDOWS)
#ifndef RT_OS_WINDOWS
switch (mWhat)
return S_OK;
if (fDelivered)
if (!allowChange)
return allowChange;
return aEvDesc.init(aSource, VBoxEventType_OnExtraDataChanged, machineId.raw(), key.raw(), val.raw());
void *handler()
#ifdef VBOX_WITH_RESOURCE_USAGE_API
return NULL;
* already uninitialized, so do a usual AutoCaller/AutoReadLock sequence
if (aControls)
++it)
if (aControls)
bool fPermitInaccessible,
bool aSetError,
++it)
if (!fPermitInaccessible)
if (aMachine)
return rc;
bool aSetError,
if (aId)
if (aHardDisk)
return S_OK;
if (aLocation)
++ it)
if (result == 0)
if (aHardDisk)
if (aId)
return rc;
bool aSetError,
vrc);
bool found = false;
++ it)
if (found)
if (aImage)
if (aId)
return rc;
bool aSetError,
bool found = false;
++ it)
if (found)
if (aImage)
if (aId)
return rc;
return S_OK;
++it)
return S_OK;
return m->pHost;
return m->pSystemProperties;
#ifdef VBOX_WITH_RESOURCE_USAGE_API
return m->pPerformanceCollector;
return m->strHomeDir;
return vrc;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
* Helper function which actually writes out VirtualBox.xml, the main configuration file.
++it)
++it)
++it2)
++it)
++it)
++it)
++it)
return rc;
&pMachine);
return rc;
* @param pfNeedsSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true
* by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed.
* @note Caller must hold the media tree lock for writing; in addition, this locks @a aHardDisk for reading
bool *pfNeedsSaveSettings)
tr("Cannot register the hard disk '%s' with UUID {%RTuuid} because a %s already exists in the media registry ('%s')"),
if (pfNeedsSaveSettings)
*pfNeedsSaveSettings = true;
return rc;
* @param pfNeedsSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true
* by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed.
* @note Caller must hold the media tree lock for writing; in addition, this locks @a aHardDisk for reading
bool *pfNeedsSaveSettings)
if (pfNeedsSaveSettings)
*pfNeedsSaveSettings = true;
return S_OK;
* @param pfNeedsSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true
* by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed.
* @note Caller must hold the media tree lock for writing; in addition, this locks @a argImage for reading
bool *pfNeedsSaveSettings)
tr("Cannot register the image '%s' with UUID {%RTuuid} because a %s already exists in the media registry ('%s')"),
if (pfNeedsSaveSettings)
*pfNeedsSaveSettings = true;
return rc;
* @param pfNeedsSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true
* by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed.
* @note Caller must hold the media tree lock for writing; in addition, this locks @a argImage for reading
bool *pfNeedsSaveSettings)
if (pfNeedsSaveSettings)
*pfNeedsSaveSettings = true;
return rc;
return rc;
vrc));
return S_OK;
AssertFailed();
return E_FAIL;
return m->strSettingsFilePath;
* objects contained in these lists. See AutoLock.h.
return m->lockMedia;
#if defined(RT_OS_WINDOWS)
INFINITE);
bool update = false;
update = true;
update = true;
update = true;
update = true;
if (update)
cnt = 0;
++it)
++cnt;
cntSpawned = 0;
++it)
if (rc == 0)
++cntSpawned;
::CoUninitialize();
bool update = false;
bool updateSpawned = false;
update = true;
updateSpawned = true;
if (cnt > 0)
unsigned long semId = 0;
#ifdef DEBUG
update = true;
unsigned long reqCnt;
if (i >= 0 && i < cnt)
#ifdef DEBUG
update = true;
if (cntSpawned > 0)
if (update)
cnt = 0;
cnt));
++ cnt;
if (cnt > 0)
if (updateSpawned)
bool update = false;
bool updateSpawned = false;
++it)
++it)
update = false;
updateSpawned = false;
++ it;
delete eventQ;
if (!mVirtualBox)
return NULL;
return NULL;
return NULL;
//STDMETHODIMP VirtualBox::CreateDHCPServerForInterface(/*IHostNetworkInterface * aIinterface,*/ IDHCPServer ** aServer)
return rc;
++it)
if (!found)
return E_INVALIDARG;
return rc;
return E_INVALIDARG;
if (aSaveRegistry)
return rc;
if (aSaveRegistry)
return rc;