VirtualBoxImpl.cpp revision 234e4395eef540230f4ffdea9781e8c923bc4d4a
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Implementation of IVirtualBox in VBoxSVC.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Copyright (C) 2006-2013 Oracle Corporation
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * This file is part of VirtualBox Open Source Edition (OSE), as
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * available from http://www.virtualbox.org. This file is free software;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * you can redistribute it and/or modify it under the terms of the GNU
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * General Public License (GPL) as published by the Free Software
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Foundation, in version 2 as it comes in the "COPYING" file of the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan#endif /* VBOX_WITH_RESOURCE_USAGE_API */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo////////////////////////////////////////////////////////////////////////////////
34683adecebe88ca2c857e28be4749f3a083f9fcsg// Definitions
c1c61f44e88f4c8c155272ee56d868043146096asb////////////////////////////////////////////////////////////////////////////////
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#define VBOX_GLOBAL_SETTINGS_FILE "VirtualBox.xml"
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG////////////////////////////////////////////////////////////////////////////////
c1c61f44e88f4c8c155272ee56d868043146096asb// Global variables
f0ca1d9a12d54d304791bc74525e2010ca924726sb////////////////////////////////////////////////////////////////////////////////
06db247c678f0e3956535e8a6dec31d6c2108827raghuramstd::map<Bstr, int> VirtualBox::sNatNetworkNameToRefCount;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram// static leaked (todo: find better place to free it.)
06db247c678f0e3956535e8a6dec31d6c2108827raghuramRWLockHandle *VirtualBox::spMtxNatNetworkNameToRefCountLock;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram////////////////////////////////////////////////////////////////////////////////
d8a518c84b0b033745c344594c3478e1294f3a9aSriharsha Basavapatna// CallbackEvent class
f0ca1d9a12d54d304791bc74525e2010ca924726sb////////////////////////////////////////////////////////////////////////////////
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Abstract callback event class to asynchronously call VirtualBox callbacks
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * on a dedicated event thread. Subclasses reimplement #handleCallback()
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * to call appropriate IVirtualBoxCallback methods depending on the event
808f26a819b6259a3340d8d53074a2f1635315cbSriharsha Basavapatna * to be dispatched.
808f26a819b6259a3340d8d53074a2f1635315cbSriharsha Basavapatna * @note The VirtualBox instance passed to the constructor is strongly
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * referenced, so that the VirtualBox singleton won't be released until the
7a327842c3ad1ec3b602c454b218df4ebbc716fbwentaoy * event gets handled by the event thread.
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG CallbackEvent(VirtualBox *aVirtualBox, VBoxEventType_T aWhat)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram virtual HRESULT prepareEventDesc(IEventSource* aSource, VBoxEventDesc& aEvDesc) = 0;
c1c61f44e88f4c8c155272ee56d868043146096asb * Note that this is a weak ref -- the CallbackEvent handler thread
c1c61f44e88f4c8c155272ee56d868043146096asb * is bound to the lifetime of the VirtualBox instance, so it's safe.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng////////////////////////////////////////////////////////////////////////////////
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng// VirtualBox private member data definition
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng////////////////////////////////////////////////////////////////////////////////
da14cebe459d3275048785f25bd869cb09b5307fEric Chengtypedef ObjectsList<GuestOSType> GuestOSTypesOList;
da14cebe459d3275048785f25bd869cb09b5307fEric Chengtypedef ObjectsList<SharedFolder> SharedFoldersOList;
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatnatypedef ObjectsList<NATNetwork> NATNetworksOList;
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatnatypedef std::map<Guid, ComPtr<IProgress> > ProgressMap;
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANGtypedef std::map<Guid, ComObjPtr<Medium> > HardDiskMap;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Main VirtualBox data structure.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * @note |const| members are persistent during lifetime so can be accessed
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * without locking.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram uuidMediaRegistry("48024e5c-fdd9-470f-93af-ec29f7ea518c"),
f0ca1d9a12d54d304791bc74525e2010ca924726sb // const data members not requiring locking
f0ca1d9a12d54d304791bc74525e2010ca924726sb // VirtualBox main settings file
f0ca1d9a12d54d304791bc74525e2010ca924726sb // constant pseudo-machine ID for global media registry
f0ca1d9a12d54d304791bc74525e2010ca924726sb // counter if global media registry needs saving, updated using atomic
f0ca1d9a12d54d304791bc74525e2010ca924726sb // operations, without requiring any locks
06db247c678f0e3956535e8a6dec31d6c2108827raghuram // const objects not requiring locking
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb const ComObjPtr<PerformanceCollector> pPerformanceCollector;
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb#endif /* VBOX_WITH_RESOURCE_USAGE_API */
51aa9d07dcd9c8ed955768d19058f8c15460fd7csb // Each of the following lists use a particular lock handle that protects the
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna // list as a whole. As opposed to version 3.1 and earlier, these lists no
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna // longer need the main VirtualBox object lock, but only the respective list
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna // lock. In each case, the locking order is defined that the list must be
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna // requested before object locks of members of the lists (see the order definitions
678453a8ed49104d8adad58f3ba591bdc39883e8speer // in AutoLock.h; e.g. LOCKCLASS_LISTOFMACHINES before LOCKCLASS_MACHINEOBJECT).
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna // All the media lists are protected by the following locking handle:
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna MediaOList allHardDisks, // base images only!
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna // the hard disks map is an additional map sorted by UUID for quick lookup
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna // and contains ALL hard disks (base and differencing); it is protected by
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna // the same lock as the other media lists above
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna // list of pending machine renames (also protected by media tree lock;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna // see VirtualBox::rememberMachineNameChangeForMedia())
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna typedef std::list<PendingMachineRename> PendingMachineRenamesList;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna PendingMachineRenamesList llPendingMachineRenames;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna // the following are data for the async event thread
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /** The extension pack manager object lives here. */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna const ComObjPtr<ExtPackManager> ptrExtPackManager;
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /** The global autostart database for the user. */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna /** Settings secret */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna uint8_t SettingsCipherKey[RTSHA512_HASH_SIZE];
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna// constructor / destructor
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna/////////////////////////////////////////////////////////////////////////////
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna// public initializer/uninitializer for internal purposes only
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/////////////////////////////////////////////////////////////////////////////
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna * Initializes the VirtualBox object.
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna * @return COM result code
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna /* Enclose the state transition NotReady->InInit->Ready */
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna AssertReturn(autoInitSpan.isOk(), E_FAIL);
f0ca1d9a12d54d304791bc74525e2010ca924726sb /* Locking this object for writing during init sounds a bit paradoxical,
f0ca1d9a12d54d304791bc74525e2010ca924726sb * but in the current locking mess this avoids that some code gets a
f0ca1d9a12d54d304791bc74525e2010ca924726sb * read lock and later calls code which wants the same write lock. */
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna // allocate our instance data
06db247c678f0e3956535e8a6dec31d6c2108827raghuram LogFlow(("===========================================================\n"));
ba2e4443695ee6a6f420a35cd4fc3d3346d22932seb tmp = tmp.substr(0, tmp.length() - strlen(VBOX_BUILD_PUBLISHER));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo spMtxNatNetworkNameToRefCountLock = new RWLockHandle(LOCKCLASS_VIRTUALBOXOBJECT);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo LogFlowThisFunc(("Version: %ls, Package: %ls, API Version: %ls\n", sVersion.raw(), sPackageType.raw(), sAPIVersion.raw()));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* Get the VirtualBox home directory. */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int vrc = com::GetVBoxUserHomeDirectory(szHomeDir, sizeof(szHomeDir));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo tr("Could not create the VirtualBox home directory '%s' (%Rrc)"),
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* compose the VirtualBox.xml file name */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo unconst(m->strSettingsFilePath) = Utf8StrFmt("%s%c%s",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo bool fCreate = false;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo // load and parse VirtualBox.xml; this will throw on XML or logic errors
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo m->pMainConfigFile = new settings::MainConfigFile(&m->strSettingsFilePath);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo // this is thrown by the XML backend if the RTOpen() call fails;
205eeb1ae627fcf67b5705c443a2b56a8263406blm // only if the main settings file does not exist, create it,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo // if there's something more serious, then do fail!
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo m->pMainConfigFile = new settings::MainConfigFile(NULL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* create the performance collector object BEFORE host */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#endif /* VBOX_WITH_RESOURCE_USAGE_API */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* create the host object early, machines will need it */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rc = m->pHost->loadSettings(m->pMainConfigFile->host);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Create autostart database object early, because the system properties
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * might need it.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* create the system properties object, someone may need it too */
c1c61f44e88f4c8c155272ee56d868043146096asb rc = m->pSystemProperties->loadSettings(m->pMainConfigFile->systemProperties);
c1c61f44e88f4c8c155272ee56d868043146096asb /* guest OS type objects, needed by machines */
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna ComObjPtr<GuestOSType> guestOSTypeObj;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* all registered media, needed by machines */
34683adecebe88ca2c857e28be4749f3a083f9fcsg /* machines */
34683adecebe88ca2c857e28be4749f3a083f9fcsg /* net services - dhcp services */
34683adecebe88ca2c857e28be4749f3a083f9fcsg for (settings::DHCPServersList::const_iterator it = m->pMainConfigFile->llDhcpServers.begin();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rc = registerDHCPServer(pDhcpServer, false /* aSaveRegistry */);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* net services - nat networks */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (settings::NATNetworksList::const_iterator it = m->pMainConfigFile->llNATNetworks.begin();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rc = registerNATNetwork(pNATNetwork, false /* aSaveRegistry */);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* events */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (SUCCEEDED(rc = unconst(m->pEventSource).createObject()))
06db247c678f0e3956535e8a6dec31d6c2108827raghuram rc = m->pEventSource->init(static_cast<IVirtualBox*>(this));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* extension manager */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rc = m->ptrExtPackManager->initExtPackManager(this, VBOXEXTPACKCTX_PER_USER_DAEMON);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* we assume that error info is set by the thrower */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo catch (...)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo rc = VirtualBoxBase::handleUnexpectedExceptions(this, RT_SRC_POS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* set up client monitoring */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* start the async event handler thread */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo int vrc = RTThreadCreate(&unconst(m->threadAsyncEvent),
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo "EventHandler");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* wait until the thread sets m->pAsyncEventQ */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo RTThreadUserWait(m->threadAsyncEvent, RT_INDEFINITE_WAIT);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* Confirm a successful initialization when it's the case */
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG /* Let the extension packs have a go at things. */
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG m->ptrExtPackManager->callAllVirtualBoxReadyHooks();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo LogFlow(("===========================================================\n"));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (settings::MachinesRegistry::const_iterator it = m->pMainConfigFile->llMachines.begin();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo const settings::MachineRegistryEntry &xmlMachine = *it;
19b65a69adc64b3289ccb2fc32b805782e3f4540sb * Loads a media registry from XML and adds the media contained therein to
19b65a69adc64b3289ccb2fc32b805782e3f4540sb * the global lists of known media.
19b65a69adc64b3289ccb2fc32b805782e3f4540sb * This now (4.0) gets called from two locations:
19b65a69adc64b3289ccb2fc32b805782e3f4540sb * -- VirtualBox::init(), to load the global media registry from VirtualBox.xml;
19b65a69adc64b3289ccb2fc32b805782e3f4540sb * -- Machine::loadMachineDataFromSettings(), to load the per-machine registry
19b65a69adc64b3289ccb2fc32b805782e3f4540sb * from machine XML, for machines created with VirtualBox 4.0 or later.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * In both cases, the media found are added to the global lists so the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * global arrays of media (including the GUI's virtual media manager)
205eeb1ae627fcf67b5705c443a2b56a8263406blm * continue to work as before.
c1c61f44e88f4c8c155272ee56d868043146096asb * @param uuidMachineRegistry The UUID of the media registry. This is either the
c1c61f44e88f4c8c155272ee56d868043146096asb * transient UUID created at VirtualBox startup for the global registry or
205eeb1ae627fcf67b5705c443a2b56a8263406blm * a machine ID.
c1c61f44e88f4c8c155272ee56d868043146096asb * @param mediaRegistry The XML settings structure to load, either from VirtualBox.xml
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * or a machine XML.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoHRESULT VirtualBox::initMedia(const Guid &uuidRegistry,
205eeb1ae627fcf67b5705c443a2b56a8263406blm LogFlow(("VirtualBox::initMedia ENTERING, uuidRegistry=%s, strMachineFolder=%s\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo AutoWriteLock treeLock(getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
7bd3a2e26cc8569257b88c1691d559138e1d32d0Sriharsha Basavapatna for (it = mediaRegistry.llHardDisks.begin();
34b64c01c6a2242177691e1420a386e2789f79dcWENTAO YANG xmlHD, // XML data; this recurses to processes the children
34b64c01c6a2242177691e1420a386e2789f79dcWENTAO YANG rc = registerMedium(pHardDisk, &pHardDisk, DeviceType_HardDisk);
808f26a819b6259a3340d8d53074a2f1635315cbSriharsha Basavapatna rc = registerMedium(pImage, &pImage, DeviceType_DVD);
808f26a819b6259a3340d8d53074a2f1635315cbSriharsha Basavapatna for (it = mediaRegistry.llFloppyImages.begin();
808f26a819b6259a3340d8d53074a2f1635315cbSriharsha Basavapatna it != mediaRegistry.llFloppyImages.end();
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG /* Enclose the state transition Ready->InUninit->NotReady */
19b65a69adc64b3289ccb2fc32b805782e3f4540sb LogFlow(("===========================================================\n"));
19b65a69adc64b3289ccb2fc32b805782e3f4540sb LogFlowThisFunc(("initFailed()=%d\n", autoUninitSpan.initFailed()));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* tell all our child objects we've been uninitialized */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo LogFlowThisFunc(("Uninitializing machines (%d)...\n", m->allMachines.size()));
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG /* It is necessary to hold the VirtualBox and Host locks here because
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo we may have to uninitialize SessionMachines. */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo AutoMultiWriteLock2 multilock(this, m->pHost COMMA_LOCKVAL_SRC_POS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* Note that we release singleton children after we've all other children.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * In some cases this is important because these other children may use
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * some resources of the singletons which would prevent them from
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * uninitializing (as for example, mSystemProperties which owns
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * MediumFormat objects which Medium objects refer to) */
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG#endif /* VBOX_WITH_RESOURCE_USAGE_API */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo LogFlowThisFunc(("Terminating the async event handler...\n"));
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG /* signal to exit the event loop */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (RT_SUCCESS(m->pAsyncEventQ->interruptEventQueueProcessing()))
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Wait for thread termination (only after we've successfully
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG * interrupted the event queue processing!)
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG int vrc = RTThreadWait(m->threadAsyncEvent, 60000, NULL);
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG LogWarningFunc(("RTThreadWait(%RTthrd) -> %Rrc\n",
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG AssertMsgFailed(("interruptEventQueueProcessing() failed\n"));
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG // we don't perform uninit() as it's possible that some pending event refers to this source
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG LogFlowThisFunc(("Terminating the client watcher...\n"));
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG // clean up our instance data
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG /* Unload hard disk plugin backends. */
d10e4ef2fabf16c3237c6d6592496df3eac6a1efnarayan LogFlow(("===========================================================\n"));
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG// IVirtualBox properties
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG/////////////////////////////////////////////////////////////////////////////
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANGSTDMETHODIMP VirtualBox::COMGETTER(Version)(BSTR *aVersion)
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG if (FAILED(autoCaller.rc())) return autoCaller.rc();
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANGSTDMETHODIMP VirtualBox::COMGETTER(VersionNormalized)(BSTR *aVersionNormalized)
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG if (FAILED(autoCaller.rc())) return autoCaller.rc();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoSTDMETHODIMP VirtualBox::COMGETTER(Revision)(ULONG *aRevision)
34b64c01c6a2242177691e1420a386e2789f79dcWENTAO YANG if (FAILED(autoCaller.rc())) return autoCaller.rc();
34b64c01c6a2242177691e1420a386e2789f79dcWENTAO YANGSTDMETHODIMP VirtualBox::COMGETTER(PackageType)(BSTR *aPackageType)
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANGSTDMETHODIMP VirtualBox::COMGETTER(APIVersion)(BSTR *aAPIVersion)
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANGSTDMETHODIMP VirtualBox::COMGETTER(HomeFolder)(BSTR *aHomeFolder)
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG if (FAILED(autoCaller.rc())) return autoCaller.rc();
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG /* mHomeDir is const and doesn't need a lock */
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANGSTDMETHODIMP VirtualBox::COMGETTER(SettingsFilePath)(BSTR *aSettingsFilePath)
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG if (FAILED(autoCaller.rc())) return autoCaller.rc();
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG /* mCfgFile.mName is const and doesn't need a lock */
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANG m->strSettingsFilePath.cloneTo(aSettingsFilePath);
6f09f0fef8e4582cfa771d87fe2a1f777bfb5cf0WENTAO YANGSTDMETHODIMP VirtualBox::COMGETTER(Host)(IHost **aHost)
34b64c01c6a2242177691e1420a386e2789f79dcWENTAO YANG if (FAILED(autoCaller.rc())) return autoCaller.rc();
34b64c01c6a2242177691e1420a386e2789f79dcWENTAO YANG /* mHost is const, no need to lock */
a862df29af145cac620492c4ebe1f42c1906c66eSriharsha BasavapatnaVirtualBox::COMGETTER(SystemProperties)(ISystemProperties **aSystemProperties)
34683adecebe88ca2c857e28be4749f3a083f9fcsg /* mSystemProperties is const, no need to lock */
34683adecebe88ca2c857e28be4749f3a083f9fcsg m->pSystemProperties.queryInterfaceTo(aSystemProperties);
34683adecebe88ca2c857e28be4749f3a083f9fcsgVirtualBox::COMGETTER(Machines)(ComSafeArrayOut(IMachine *, aMachines))
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo AutoReadLock al(m->allMachines.getLockHandle() COMMA_LOCKVAL_SRC_POS);
f2b610cf6e03184d9538e3aaec99bcaf65124714wentaoy SafeIfaceArray<IMachine> machines(m->allMachines.getList());
f2b610cf6e03184d9538e3aaec99bcaf65124714wentaoyVirtualBox::COMGETTER(MachineGroups)(ComSafeArrayOut(BSTR, aMachineGroups))
f2b610cf6e03184d9538e3aaec99bcaf65124714wentaoy CheckComArgOutSafeArrayPointerValid(aMachineGroups);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* get copy of all machine references, to avoid holding the list lock */
34683adecebe88ca2c857e28be4749f3a083f9fcsg AutoReadLock al(m->allMachines.getLockHandle() COMMA_LOCKVAL_SRC_POS);
f2b610cf6e03184d9538e3aaec99bcaf65124714wentaoy for (MachinesOList::MyList::const_iterator it = allMachines.begin();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo const StringsList &thisGroups = pMachine->getGroups();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (StringsList::const_iterator it2 = thisGroups.begin();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* throw out any duplicates */
34683adecebe88ca2c857e28be4749f3a083f9fcsg for (std::list<Bstr>::const_iterator it = allGroups.begin();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo machineGroups.detachTo(ComSafeArrayOutArg(aMachineGroups));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoSTDMETHODIMP VirtualBox::COMGETTER(HardDisks)(ComSafeArrayOut(IMedium *, aHardDisks))
34683adecebe88ca2c857e28be4749f3a083f9fcsg AutoReadLock al(m->allHardDisks.getLockHandle() COMMA_LOCKVAL_SRC_POS);
34683adecebe88ca2c857e28be4749f3a083f9fcsg SafeIfaceArray<IMedium> hardDisks(m->allHardDisks.getList());
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng hardDisks.detachTo(ComSafeArrayOutArg(aHardDisks));
34683adecebe88ca2c857e28be4749f3a083f9fcsgSTDMETHODIMP VirtualBox::COMGETTER(DVDImages)(ComSafeArrayOut(IMedium *, aDVDImages))
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo AutoReadLock al(m->allDVDImages.getLockHandle() COMMA_LOCKVAL_SRC_POS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo SafeIfaceArray<IMedium> images(m->allDVDImages.getList());
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoSTDMETHODIMP VirtualBox::COMGETTER(FloppyImages)(ComSafeArrayOut(IMedium *, aFloppyImages))
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lm AutoReadLock al(m->allFloppyImages.getLockHandle() COMMA_LOCKVAL_SRC_POS);
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lm SafeIfaceArray<IMedium> images(m->allFloppyImages.getList());
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lmSTDMETHODIMP VirtualBox::COMGETTER(ProgressOperations)(ComSafeArrayOut(IProgress *, aOperations))
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (FAILED(autoCaller.rc())) return autoCaller.rc();
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lm /* protect mProgressOperations */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng AutoReadLock safeLock(m->mtxProgressOperations COMMA_LOCKVAL_SRC_POS);
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lm SafeIfaceArray<IProgress> progress(m->mapProgressOperations);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng progress.detachTo(ComSafeArrayOutArg(aOperations));
da14cebe459d3275048785f25bd869cb09b5307fEric ChengSTDMETHODIMP VirtualBox::COMGETTER(GuestOSTypes)(ComSafeArrayOut(IGuestOSType *, aGuestOSTypes))
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng CheckComArgOutSafeArrayPointerValid(aGuestOSTypes);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng AutoReadLock al(m->allGuestOSTypes.getLockHandle() COMMA_LOCKVAL_SRC_POS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo SafeIfaceArray<IGuestOSType> ostypes(m->allGuestOSTypes.getList());
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lmSTDMETHODIMP VirtualBox::COMGETTER(SharedFolders)(ComSafeArrayOut(ISharedFolder *, aSharedFolders))
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#endif /* RT_OS_WINDOWS */
06db247c678f0e3956535e8a6dec31d6c2108827raghuramVirtualBox::COMGETTER(PerformanceCollector)(IPerformanceCollector **aPerformanceCollector)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* mPerformanceCollector is const, no need to lock */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram m->pPerformanceCollector.queryInterfaceTo(aPerformanceCollector);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#else /* !VBOX_WITH_RESOURCE_USAGE_API */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram#endif /* !VBOX_WITH_RESOURCE_USAGE_API */
06db247c678f0e3956535e8a6dec31d6c2108827raghuramVirtualBox::COMGETTER(DHCPServers)(ComSafeArrayOut(IDHCPServer *, aDHCPServers))
06db247c678f0e3956535e8a6dec31d6c2108827raghuram AutoReadLock al(m->allDHCPServers.getLockHandle() COMMA_LOCKVAL_SRC_POS);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram SafeIfaceArray<IDHCPServer> svrs(m->allDHCPServers.getList());
06db247c678f0e3956535e8a6dec31d6c2108827raghuramVirtualBox::COMGETTER(NATNetworks)(ComSafeArrayOut(INATNetwork *, aNATNetworks))
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (FAILED(autoCaller.rc())) return autoCaller.rc();
06db247c678f0e3956535e8a6dec31d6c2108827raghuram AutoReadLock al(m->allNATNetworks.getLockHandle() COMMA_LOCKVAL_SRC_POS);
19b65a69adc64b3289ccb2fc32b805782e3f4540sb SafeIfaceArray<INATNetwork> nets(m->allNATNetworks.getList());
06db247c678f0e3956535e8a6dec31d6c2108827raghuramVirtualBox::COMGETTER(EventSource)(IEventSource ** aEventSource)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (FAILED(autoCaller.rc())) return autoCaller.rc();
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* event source is const, no need to lock */
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lmVirtualBox::COMGETTER(ExtensionPackManager)(IExtPackManager **aExtPackManager)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* The extension pack manager is const, no need to lock. */
19b65a69adc64b3289ccb2fc32b805782e3f4540sb hrc = m->ptrExtPackManager.queryInterfaceTo(aExtPackManager);
19b65a69adc64b3289ccb2fc32b805782e3f4540sbSTDMETHODIMP VirtualBox::COMGETTER(InternalNetworks)(ComSafeArrayOut(BSTR, aInternalNetworks))
06db247c678f0e3956535e8a6dec31d6c2108827raghuram CheckComArgOutSafeArrayPointerValid(aInternalNetworks);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (FAILED(autoCaller.rc())) return autoCaller.rc();
19b65a69adc64b3289ccb2fc32b805782e3f4540sb /* get copy of all machine references, to avoid holding the list lock */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram AutoReadLock al(m->allMachines.getLockHandle() COMMA_LOCKVAL_SRC_POS);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram for (MachinesOList::MyList::const_iterator it = allMachines.begin();
06db247c678f0e3956535e8a6dec31d6c2108827raghuram AutoReadLock mlock(pMachine COMMA_LOCKVAL_SRC_POS);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng uint32_t cNetworkAdapters = Global::getMaxNetworkAdapters(pMachine->getChipsetType());
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng HRESULT rc = pMachine->GetNetworkAdapter(i, pNet.asOutParam());
19b65a69adc64b3289ccb2fc32b805782e3f4540sb rc = pNet->COMGETTER(InternalNetwork)(strInternalNetwork.asOutParam());
34683adecebe88ca2c857e28be4749f3a083f9fcsg /* throw out any duplicates */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram com::SafeArray<BSTR> internalNetworks(allInternalNetworks.size());
34683adecebe88ca2c857e28be4749f3a083f9fcsg for (std::list<Bstr>::const_iterator it = allInternalNetworks.begin();
34683adecebe88ca2c857e28be4749f3a083f9fcsg internalNetworks.detachTo(ComSafeArrayOutArg(aInternalNetworks));
06db247c678f0e3956535e8a6dec31d6c2108827raghuramSTDMETHODIMP VirtualBox::COMGETTER(GenericNetworkDrivers)(ComSafeArrayOut(BSTR, aGenericNetworkDrivers))
06db247c678f0e3956535e8a6dec31d6c2108827raghuram CheckComArgOutSafeArrayPointerValid(aGenericNetworkDrivers);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* get copy of all machine references, to avoid holding the list lock */
19b65a69adc64b3289ccb2fc32b805782e3f4540sb AutoReadLock al(m->allMachines.getLockHandle() COMMA_LOCKVAL_SRC_POS);
19b65a69adc64b3289ccb2fc32b805782e3f4540sb for (MachinesOList::MyList::const_iterator it = allMachines.begin();
06db247c678f0e3956535e8a6dec31d6c2108827raghuram AutoReadLock mlock(pMachine COMMA_LOCKVAL_SRC_POS);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram uint32_t cNetworkAdapters = Global::getMaxNetworkAdapters(pMachine->getChipsetType());
06db247c678f0e3956535e8a6dec31d6c2108827raghuram HRESULT rc = pMachine->GetNetworkAdapter(i, pNet.asOutParam());
06db247c678f0e3956535e8a6dec31d6c2108827raghuram rc = pNet->COMGETTER(GenericDriver)(strGenericNetworkDriver.asOutParam());
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (FAILED(rc) || strGenericNetworkDriver.isEmpty())
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng allGenericNetworkDrivers.push_back(strGenericNetworkDriver);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* throw out any duplicates */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram com::SafeArray<BSTR> genericNetworks(allGenericNetworkDrivers.size());
06db247c678f0e3956535e8a6dec31d6c2108827raghuram for (std::list<Bstr>::const_iterator it = allGenericNetworkDrivers.begin();
19b65a69adc64b3289ccb2fc32b805782e3f4540sb genericNetworks.detachTo(ComSafeArrayOutArg(aGenericNetworkDrivers));
06db247c678f0e3956535e8a6dec31d6c2108827raghuramVirtualBox::CheckFirmwarePresent(FirmwareType_T aFirmwareType,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (FAILED(autoCaller.rc())) return autoCaller.rc();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo static const struct
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo const char* fileName;
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo const char* url;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* compiled-in firmware */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram FirmwareType_EFI32, "VBoxEFI32.fd", "http://virtualbox.org/firmware/VBoxEFI32.fd"
06db247c678f0e3956535e8a6dec31d6c2108827raghuram FirmwareType_EFI64, "VBoxEFI64.fd", "http://virtualbox.org/firmware/VBoxEFI64.fd"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo FirmwareType_EFIDUAL, "VBoxEFIDual.fd", "http://virtualbox.org/firmware/VBoxEFIDual.fd"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (size_t i = 0; i < sizeof(firmwareDesc) / sizeof(firmwareDesc[0]); i++)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* compiled-in firmware */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /** @todo: account for version in the URL */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* Assume single record per firmware type */
19b65a69adc64b3289ccb2fc32b805782e3f4540sb// IVirtualBox methods
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/////////////////////////////////////////////////////////////////////////////
19b65a69adc64b3289ccb2fc32b805782e3f4540sb/* Helper for VirtualBox::ComposeMachineFilename */
06db247c678f0e3956535e8a6dec31d6c2108827raghuramstatic void sanitiseMachineFilename(Utf8Str &aName);
06db247c678f0e3956535e8a6dec31d6c2108827raghuramSTDMETHODIMP VirtualBox::ComposeMachineFilename(IN_BSTR aName,
06db247c678f0e3956535e8a6dec31d6c2108827raghuram LogFlowThisFunc(("aName=\"%ls\",aBaseFolder=\"%ls\"\n", aName, aBaseFolder));
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (FAILED(autoCaller.rc())) return autoCaller.rc();
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* skip over everything which doesn't contain '=' */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram Utf8Str strKey(strFlag.c_str(), pcszEqual - strFlag.c_str());
19b65a69adc64b3289ccb2fc32b805782e3f4540sb Utf8Str strValue(strFlag.c_str() + (pcszEqual - strFlag.c_str() + 1));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* do something else */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* Compose the settings file name using the following scheme:
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * <base_folder><group>/<machine_name>/<machine_name>.xml
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * If a non-null and non-empty base folder is specified, the default
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * machine folder will be used as a base folder.
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lm * We sanitise the machine name to a safe white list of characters before
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * using it.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* we use the non-full folder value below to keep the path relative */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* eliminate toplevel group to avoid // in the result */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram Bstr bstrSettingsFile = BstrFmt("%s%s%c%s%c%s.vbox",
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Remove characters from a machine file name which can be problematic on
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lm * particular systems.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * @param strName The file name to sanitise.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /** Set of characters which should be safe for use in filenames: some basic
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * ASCII, Unicode from Latin-1 alphabetic to the end of Hangul. We try to
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * skip anything that could count as a control character in Windows or
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * *nix, or be otherwise difficult for shells to handle (I would have
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * preferred to remove the space and brackets too). We also remove all
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * characters which need UTF-16 surrogate pairs for Windows's benefit. */
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lm { ' ', ' ', '(', ')', '-', '.', '0', '9', 'A', 'Z', 'a', 'z', '_', '_',
19b65a69adc64b3289ccb2fc32b805782e3f4540sb int cReplacements = RTStrPurgeComplementSet(pszName, aCpSet, '_');
5f94e909a253b6d0625c7c7425f59848f0cfb850sg /* No leading dot or dash. */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* No trailing dot. */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* Mangle leading and trailing spaces. */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram for (size_t i = strName.length() - 1; i && pszName[i] == ' '; --i)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/** Simple unit test/operation examples for sanitiseMachineFilename(). */
06db247c678f0e3956535e8a6dec31d6c2108827raghuramstatic unsigned testSanitiseMachineFilename(void (*pfnPrintf)(const char *, ...))
06db247c678f0e3956535e8a6dec31d6c2108827raghuram unsigned cErrors = 0;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /** Expected results of sanitising given file names. */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram static struct
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /** The test file name to be sanitised (Utf-8). */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram const char *pcszIn;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /** The expected sanitised output (Utf-8). */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram/** @todo Proper testcase. */
5f94e909a253b6d0625c7c7425f59848f0cfb850sg/** @todo Do we have a better method of doing init functions? */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram Assert(!testSanitiseMachineFilename(RTAssertMsg2));
06db247c678f0e3956535e8a6dec31d6c2108827raghuram TestSanitiseMachineFilename s_TestSanitiseMachineFilename;
1ef0bbb5af03e2721bb767e58ada1c58265e9fdenarayan/** @note Locks mSystemProperties object for reading. */
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lmSTDMETHODIMP VirtualBox::CreateMachine(IN_BSTR aSettingsFile,
06db247c678f0e3956535e8a6dec31d6c2108827raghuram LogFlowThisFunc(("aSettingsFile=\"%ls\", aName=\"%ls\", aOsTypeId =\"%ls\", aCreateFlags=\"%ls\"\n", aSettingsFile, aName, aOsTypeId, aCreateFlags));
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /** @todo tighten checks on aId? */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram HRESULT rc = convertMachineGroups(ComSafeArrayInArg(aGroups), &llGroups);
c1c61f44e88f4c8c155272ee56d868043146096asb bool fForceOverwrite = false;
5f94e909a253b6d0625c7c7425f59848f0cfb850sg /* skip over everything which doesn't contain '=' */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram Utf8Str strKey(strFlag.c_str(), pcszEqual - strFlag.c_str());
06db247c678f0e3956535e8a6dec31d6c2108827raghuram Utf8Str strValue(strFlag.c_str() + (pcszEqual - strFlag.c_str() + 1));
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* Create UUID if none was specified. */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* do something else */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* NULL settings file means compose automatically */
5f94e909a253b6d0625c7c7425f59848f0cfb850sg Utf8Str strNewCreateFlags(Utf8StrFmt("UUID=%RTuuid", id.raw()));
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* create a new object */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* initialize the machine object */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* set the return value */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* call the extension pack hooks */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram m->ptrExtPackManager->callAllVmCreatedHooks(machine);
06db247c678f0e3956535e8a6dec31d6c2108827raghuramSTDMETHODIMP VirtualBox::OpenMachine(IN_BSTR aSettingsFile,
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (FAILED(autoCaller.rc())) return autoCaller.rc();
5f94e909a253b6d0625c7c7425f59848f0cfb850sg /* create a new object */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* initialize the machine object */
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lm /* set the return value */
34683adecebe88ca2c857e28be4749f3a083f9fcsg/** @note Locks objects! */
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lmSTDMETHODIMP VirtualBox::RegisterMachine(IMachine *aMachine)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng rc = aMachine->COMGETTER(Name)(name.asOutParam());
1ef0bbb5af03e2721bb767e58ada1c58265e9fdenarayan /* We can safely cast child to Machine * here because only Machine
5f94e909a253b6d0625c7c7425f59848f0cfb850sg * implementations of IMachine can be among our children. */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng Machine *pMachine = static_cast<Machine*>(aMachine);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna /* fire an event */
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna onMachineRegistered(pMachine->getId(), TRUE);
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna/** @note Locks this object for reading, then some machine objects for reading. */
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha BasavapatnaSTDMETHODIMP VirtualBox::FindMachine(IN_BSTR aNameOrId, IMachine **aMachine)
c1c61f44e88f4c8c155272ee56d868043146096asb LogFlowThisFunc(("aName=\"%ls\", aMachine={%p}\n", aNameOrId, aMachine));
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG /* start with not found */
c1c61f44e88f4c8c155272ee56d868043146096asb true /* fPermitInaccessible */,
c1c61f44e88f4c8c155272ee56d868043146096asb true /* setError */,
c1c61f44e88f4c8c155272ee56d868043146096asb // returns VBOX_E_OBJECT_NOT_FOUND if not found and sets error
c1c61f44e88f4c8c155272ee56d868043146096asb true /* setError */,
c1c61f44e88f4c8c155272ee56d868043146096asb // returns VBOX_E_OBJECT_NOT_FOUND if not found and sets error
c1c61f44e88f4c8c155272ee56d868043146096asb /* this will set (*machine) to NULL if machineObj is null */
c1c61f44e88f4c8c155272ee56d868043146096asb LogFlowThisFunc(("aName=\"%ls\", aMachine=%p, rc=%08X\n", aNameOrId, *aMachine, rc));
c1c61f44e88f4c8c155272ee56d868043146096asbSTDMETHODIMP VirtualBox::GetMachinesByGroups(ComSafeArrayIn(IN_BSTR, aGroups), ComSafeArrayOut(IMachine *, aMachines))
c1c61f44e88f4c8c155272ee56d868043146096asb HRESULT rc = convertMachineGroups(ComSafeArrayInArg(aGroups), &llGroups);
c1c61f44e88f4c8c155272ee56d868043146096asb /* we want to rely on sorted groups during compare, to save time */
c1c61f44e88f4c8c155272ee56d868043146096asb /* get copy of all machine references, to avoid holding the list lock */
c1c61f44e88f4c8c155272ee56d868043146096asb AutoReadLock al(m->allMachines.getLockHandle() COMMA_LOCKVAL_SRC_POS);
c1c61f44e88f4c8c155272ee56d868043146096asb for (MachinesOList::MyList::const_iterator it = allMachines.begin();
c1c61f44e88f4c8c155272ee56d868043146096asb for (StringsList::const_iterator it2 = thisGroups.begin();
c1c61f44e88f4c8c155272ee56d868043146096asb bool fAppended = false;
c1c61f44e88f4c8c155272ee56d868043146096asb else if (order > 0)
c1c61f44e88f4c8c155272ee56d868043146096asb /* avoid duplicates and save time */
c1c61f44e88f4c8c155272ee56d868043146096asbSTDMETHODIMP VirtualBox::GetMachineStates(ComSafeArrayIn(IMachine *, aMachines), ComSafeArrayOut(MachineState_T, aStates))
c1c61f44e88f4c8c155272ee56d868043146096asb com::SafeIfaceArray<IMachine> saMachines(ComSafeArrayInArg(aMachines));
c1c61f44e88f4c8c155272ee56d868043146096asb com::SafeArray<MachineState_T> saStates(saMachines.size());
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG HRESULT rc = pMachine->COMGETTER(State)(&state);
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANGSTDMETHODIMP VirtualBox::CreateHardDisk(IN_BSTR aFormat,
f0ca1d9a12d54d304791bc74525e2010ca924726sb /* we don't access non-const data members so no need to lock */
f0ca1d9a12d54d304791bc74525e2010ca924726sb // have to get write lock as the whole find/update sequence must be done
f0ca1d9a12d54d304791bc74525e2010ca924726sb // in one critical section, otherwise there are races which can lead to
f0ca1d9a12d54d304791bc74525e2010ca924726sb // multiple Medium objects with the same content
f0ca1d9a12d54d304791bc74525e2010ca924726sb AutoWriteLock treeLock(getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
f0ca1d9a12d54d304791bc74525e2010ca924726sb // check if the device type is correct, and see if a medium for the
f0ca1d9a12d54d304791bc74525e2010ca924726sb // given path has already initialized; if so, return that
f0ca1d9a12d54d304791bc74525e2010ca924726sb rc = findHardDiskById(id, false /* setError */, &pMedium);
f0ca1d9a12d54d304791bc74525e2010ca924726sb false, /* aSetError */
f0ca1d9a12d54d304791bc74525e2010ca924726sb rc = findDVDOrFloppyImage(deviceType, &id, Utf8Str::Empty,
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna rc = findDVDOrFloppyImage(deviceType, NULL, aLocation,
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna // enforce read-only for DVDs even if caller specified ReadWrite
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna return setError(E_INVALIDARG, "Device type must be HardDisk, DVD or Floppy %d", deviceType);
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna (accessMode == AccessMode_ReadWrite) ? Medium::OpenReadWrite : Medium::OpenReadOnly,
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna rc = registerMedium(pMedium, &pMedium, deviceType);
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna /* Note that it's important to call uninit() on failure to register
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna * because the differencing hard disk would have been already associated
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna * with the parent and this association needs to be broken. */
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna/** @note Locks this object for reading. */
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha BasavapatnaSTDMETHODIMP VirtualBox::GetGuestOSType(IN_BSTR aId, IGuestOSType **aType)
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna if (FAILED(autoCaller.rc())) return autoCaller.rc();
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna AutoReadLock alock(m->allGuestOSTypes.getLockHandle() COMMA_LOCKVAL_SRC_POS);
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna for (GuestOSTypesOList::iterator it = m->allGuestOSTypes.begin();
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna AssertMsg(!typeId.isEmpty(), ("ID must not be NULL"));
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna if (typeId.compare(aId, Bstr::CaseInsensitive) == 0)
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna tr("'%ls' is not a valid Guest OS type"),
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha BasavapatnaSTDMETHODIMP VirtualBox::CreateSharedFolder(IN_BSTR aName, IN_BSTR aHostPath,
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna BOOL /* aWritable */, BOOL /* aAutoMount */)
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna CheckComArgStrNotEmptyOrNull(aHostPath);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna if (FAILED(autoCaller.rc())) return autoCaller.rc();
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna return setError(E_NOTIMPL, "Not yet implemented");
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha BasavapatnaSTDMETHODIMP VirtualBox::RemoveSharedFolder(IN_BSTR aName)
d8a518c84b0b033745c344594c3478e1294f3a9aSriharsha Basavapatna if (FAILED(autoCaller.rc())) return autoCaller.rc();
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna return setError(E_NOTIMPL, "Not yet implemented");
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna * @note Locks this object for reading.
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha BasavapatnaSTDMETHODIMP VirtualBox::GetExtraDataKeys(ComSafeArrayOut(BSTR, aKeys))
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna using namespace settings;
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna CheckComArgOutSafeArrayPointerValid(aKeys);
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG if (FAILED(autoCaller.rc())) return autoCaller.rc();
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG com::SafeArray<BSTR> saKeys(m->pMainConfigFile->mapExtraDataItems.size());
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG for (StringsMap::const_iterator it = m->pMainConfigFile->mapExtraDataItems.begin();
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG it != m->pMainConfigFile->mapExtraDataItems.end();
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lm * @note Locks this object for reading.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (FAILED(autoCaller.rc())) return autoCaller.rc();
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lm /* start with nothing found */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram settings::StringsMap::const_iterator it = m->pMainConfigFile->mapExtraDataItems.find(strKey);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (it != m->pMainConfigFile->mapExtraDataItems.end())
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* return the result to caller (may be empty) */
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG * @note Locks this object for writing.
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG if (FAILED(autoCaller.rc())) return autoCaller.rc();
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lm // locking note: we only hold the read lock briefly to look up the old value,
06db247c678f0e3956535e8a6dec31d6c2108827raghuram // then release it and call the onExtraCanChange callbacks. There is a small
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lm // chance of a race insofar as the callback might be called twice if two callers
06db247c678f0e3956535e8a6dec31d6c2108827raghuram // change the same key at the same time, but that's a much better solution
06db247c678f0e3956535e8a6dec31d6c2108827raghuram // than the deadlock we had here before. The actual changing of the extradata
06db247c678f0e3956535e8a6dec31d6c2108827raghuram // is then performed under the write lock and race-free.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram // look up the old value first; if nothing has changed then we need not do anything
06db247c678f0e3956535e8a6dec31d6c2108827raghuram AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); // hold read lock only while looking up
06db247c678f0e3956535e8a6dec31d6c2108827raghuram settings::StringsMap::const_iterator it = m->pMainConfigFile->mapExtraDataItems.find(strKey);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (it != m->pMainConfigFile->mapExtraDataItems.end())
e1ebb9ec908bc2d0a8810f137ebd6566cc8a8061lm // ask for permission from all listeners outside the locks;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram // onExtraDataCanChange() only briefly requests the VirtualBox
06db247c678f0e3956535e8a6dec31d6c2108827raghuram // lock to copy the list of callbacks to invoke
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (!onExtraDataCanChange(Guid::Empty, aKey, bstrValue.raw(), error))
06db247c678f0e3956535e8a6dec31d6c2108827raghuram LogWarningFunc(("Someone vetoed! Change refused%s%ls\n",
06db247c678f0e3956535e8a6dec31d6c2108827raghuram tr("Could not set extra data because someone refused the requested change of '%ls' to '%ls'%s%ls"),
06db247c678f0e3956535e8a6dec31d6c2108827raghuram // data is changing and change not vetoed: then write it out under the lock
06db247c678f0e3956535e8a6dec31d6c2108827raghuram m->pMainConfigFile->mapExtraDataItems.erase(strKey);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram m->pMainConfigFile->mapExtraDataItems[strKey] = strValue;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram // creates a new key if needed
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* save settings on success */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram // fire notification outside the lock
5f94e909a253b6d0625c7c7425f59848f0cfb850sgSTDMETHODIMP VirtualBox::SetSettingsSecret(IN_BSTR aValue)
06db247c678f0e3956535e8a6dec31d6c2108827raghuramint VirtualBox::decryptMediumSettings(Medium *pMedium)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng HRESULT hrc = pMedium->GetProperty(Bstr("InitiatorSecretEncrypted").raw(),
c1c61f44e88f4c8c155272ee56d868043146096asb pMedium->setPropertyDirect("InitiatorSecret", strPlaintext);
c1c61f44e88f4c8c155272ee56d868043146096asb * Decrypt all encrypted settings.
c1c61f44e88f4c8c155272ee56d868043146096asb * So far we only have encrypted iSCSI initiator secrets so we just go through
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna * all hard disk mediums and determine the plain 'InitiatorSecret' from
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna * 'InitiatorSecretEncrypted. The latter is stored as Base64 because medium
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna * properties need to be null-terminated strings.
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna AutoReadLock al(m->allHardDisks.getLockHandle() COMMA_LOCKVAL_SRC_POS);
7b1f684a14f99a2b9b1b2561f484ff648eff6d9bSriharsha Basavapatna for (MediaList::const_iterator mt = m->allHardDisks.begin();
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna AutoWriteLock mlock(pMedium COMMA_LOCKVAL_SRC_POS);
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna int vrc = decryptMediumSettings(pMedium);
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG return fFailure ? VERR_INVALID_PARAMETER : VINF_SUCCESS;
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG * @param aPlaintext plaintext to be encrypted
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG * @param aCiphertext resulting ciphertext (base64-encoded)
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANGint VirtualBox::encryptSetting(const Utf8Str &aPlaintext, Utf8Str *aCiphertext)
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna int rc = encryptSettingBytes((uint8_t*)aPlaintext.c_str(), abCiphertext,
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna aPlaintext.length()+1, sizeof(abCiphertext));
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna rc = RTBase64Encode(abCiphertext, sizeof(abCiphertext),
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna szCipherBase64, sizeof(szCipherBase64),
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna * @param aPlaintext resulting plaintext
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna * @param aCiphertext ciphertext (base64-encoded) to decrypt
d8a518c84b0b033745c344594c3478e1294f3a9aSriharsha Basavapatnaint VirtualBox::decryptSetting(Utf8Str *aPlaintext, const Utf8Str &aCiphertext)
1107ea9346159bcc8ea154084897667347c4e6d5Sriharsha Basavapatna int rc = RTBase64Decode(aCiphertext.c_str(),
06db247c678f0e3956535e8a6dec31d6c2108827raghuram rc = decryptSettingBytes(abPlaintext, abCiphertext, cbCiphertext);
808f26a819b6259a3340d8d53074a2f1635315cbSriharsha Basavapatna for (unsigned i = 0; i < cbCiphertext; i++)
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* sanity check: null-terminated string? */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* sanity check: valid UTF8 string? */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (RTStrIsValidEncoding((const char*)abPlaintext))
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Encrypt secret bytes. Use the m->SettingsCipherKey as key.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * @param aPlaintext clear text to be encrypted
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * @param aCiphertext resulting encrypted text
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * @param aPlaintextSize size of the plaintext
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * @param aCiphertextSize size of the ciphertext
5f94e909a253b6d0625c7c7425f59848f0cfb850sgint VirtualBox::encryptSettingBytes(const uint8_t *aPlaintext, uint8_t *aCiphertext,
06db247c678f0e3956535e8a6dec31d6c2108827raghuram unsigned i, j;
7636cb21f250f0485ca6052ffadc80ace93e6358lm /* store the first 8 bytes of the cipherkey for verification */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram for (i = 0, j = 0; i < 8; i++, j++)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram for (unsigned k = 0; k < aPlaintextSize && i < aCiphertextSize; i++, k++)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram aCiphertext[i] = (aPlaintext[k] ^ m->SettingsCipherKey[j]);
808f26a819b6259a3340d8d53074a2f1635315cbSriharsha Basavapatna if (++j >= sizeof(m->SettingsCipherKey))
7636cb21f250f0485ca6052ffadc80ace93e6358lm /* fill with random data to have a minimal length (salt) */
808f26a819b6259a3340d8d53074a2f1635315cbSriharsha Basavapatna RTRandBytes(aBytes, aCiphertextSize - i);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram for (int k = 0; i < aCiphertextSize; i++, k++)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram aCiphertext[i] = aBytes[k] ^ m->SettingsCipherKey[j];
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (++j >= sizeof(m->SettingsCipherKey))
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Decrypt secret bytes. Use the m->SettingsCipherKey as key.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * @param aPlaintext resulting plaintext
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * @param aCiphertext ciphertext to be decrypted
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * @param aCiphertextSize size of the ciphertext == size of the plaintext
06db247c678f0e3956535e8a6dec31d6c2108827raghuramint VirtualBox::decryptSettingBytes(uint8_t *aPlaintext,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const uint8_t *aCiphertext, size_t aCiphertextSize) const
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo unsigned i, j;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* key verification */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (i = 0, j = 0; i < 8; i++, j++)
c1c61f44e88f4c8c155272ee56d868043146096asb /* poison */
c1c61f44e88f4c8c155272ee56d868043146096asb for (int k = 0; i < aCiphertextSize; i++, k++)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng aPlaintext[k] = aCiphertext[i] ^ m->SettingsCipherKey[j];
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (++j >= sizeof(m->SettingsCipherKey))
c1c61f44e88f4c8c155272ee56d868043146096asb * Store a settings key.
c1c61f44e88f4c8c155272ee56d868043146096asb * @param aKey the key to store
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng RTSha512(aKey.c_str(), aKey.length(), m->SettingsCipherKey);
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG// public methods only for internal purposes
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG/////////////////////////////////////////////////////////////////////////////
06db247c678f0e3956535e8a6dec31d6c2108827raghuram AutoReadLock al(m->allHardDisks.getLockHandle() COMMA_LOCKVAL_SRC_POS);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram for (MediaList::const_iterator mt = m->allHardDisks.begin();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo AutoReadLock al(m->allDVDImages.getLockHandle() COMMA_LOCKVAL_SRC_POS);
c1c61f44e88f4c8c155272ee56d868043146096asb for (MediaList::const_iterator mt = m->allDVDImages.begin();
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Posts an event to the event queue that is processed asynchronously
678453a8ed49104d8adad58f3ba591bdc39883e8speer * on a dedicated thread.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Posting events to the dedicated event queue is useful to perform secondary
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * actions outside any object locks -- for example, to iterate over a list
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * of callbacks and inform them about some change caused by some object's
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * method call.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * @param event event to post; must have been allocated using |new|, will
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * be deleted automatically by the event thread after processing
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * @note Doesn't lock any object.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram LogWarningFunc(("VirtualBox has been uninitialized (state=%d), the event is discarded!\n",
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo // return S_OK
06db247c678f0e3956535e8a6dec31d6c2108827raghuram else if ( (m->pAsyncEventQ)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo // in any event of failure, we must clean up here, or we'll leak;
06db247c678f0e3956535e8a6dec31d6c2108827raghuram // the caller has allocated the object using new()
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Adds a progress to the global collection of pending operations.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Usually gets called upon progress object initialization.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * @param aProgress Operation to add to the collection.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * @note Doesn't lock objects.
06db247c678f0e3956535e8a6dec31d6c2108827raghuramHRESULT VirtualBox::addProgress(IProgress *aProgress)
06db247c678f0e3956535e8a6dec31d6c2108827raghuram if (FAILED(autoCaller.rc())) return autoCaller.rc();
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo HRESULT rc = aProgress->COMGETTER(Id)(id.asOutParam());
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* protect mProgressOperations */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo AutoWriteLock safeLock(m->mtxProgressOperations COMMA_LOCKVAL_SRC_POS);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo m->mapProgressOperations.insert(ProgressMap::value_type(Guid(id), aProgress));
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Removes the progress from the global collection of pending operations.
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * Usually gets called upon progress completion.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * @param aId UUID of the progress operation to remove
c1c61f44e88f4c8c155272ee56d868043146096asb * @note Doesn't lock objects.
c1c61f44e88f4c8c155272ee56d868043146096asb /* protect mProgressOperations */
c1c61f44e88f4c8c155272ee56d868043146096asb AutoWriteLock safeLock(m->mtxProgressOperations COMMA_LOCKVAL_SRC_POS);
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG * Helper method that starts a worker thread that:
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG * - creates a pipe communication channel using SVCHlpClient;
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG * - starts an SVC Helper process that will inherit this channel;
c1c61f44e88f4c8c155272ee56d868043146096asb * - executes the supplied function by passing it the created SVCHlpClient
c1c61f44e88f4c8c155272ee56d868043146096asb * and opened instance to communicate to the Helper process and the given
c1c61f44e88f4c8c155272ee56d868043146096asb * Progress object.
c1c61f44e88f4c8c155272ee56d868043146096asb * The user function is supposed to communicate to the helper process
c1c61f44e88f4c8c155272ee56d868043146096asb * using the \a aClient argument to do the requested job and optionally expose
c1c61f44e88f4c8c155272ee56d868043146096asb * the progress through the \a aProgress object. The user function should never
c1c61f44e88f4c8c155272ee56d868043146096asb * call notifyComplete() on it: this will be done automatically using the
c1c61f44e88f4c8c155272ee56d868043146096asb * result code returned by the function.
c1c61f44e88f4c8c155272ee56d868043146096asb * Before the user function is started, the communication channel passed to
c1c61f44e88f4c8c155272ee56d868043146096asb * the \a aClient argument is fully set up, the function should start using
c1c61f44e88f4c8c155272ee56d868043146096asb * its write() and read() methods directly.
c1c61f44e88f4c8c155272ee56d868043146096asb * The \a aVrc parameter of the user function may be used to return an error
c1c61f44e88f4c8c155272ee56d868043146096asb * code if it is related to communication errors (for example, returned by
c1c61f44e88f4c8c155272ee56d868043146096asb * the SVCHlpClient members when they fail). In this case, the correct error
c1c61f44e88f4c8c155272ee56d868043146096asb * message using this value will be reported to the caller. Note that the
c1c61f44e88f4c8c155272ee56d868043146096asb * value of \a aVrc is inspected only if the user function itself returns
c1c61f44e88f4c8c155272ee56d868043146096asb * success.
c1c61f44e88f4c8c155272ee56d868043146096asb * If a failure happens anywhere before the user function would be normally
c1c61f44e88f4c8c155272ee56d868043146096asb * called, it will be called anyway in special "cleanup only" mode indicated
c1c61f44e88f4c8c155272ee56d868043146096asb * by \a aClient, \a aProgress and \aVrc arguments set to NULL. In this mode,
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * all the function is supposed to do is to cleanup its aUser argument if
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * necessary (it's assumed that the ownership of this argument is passed to
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * the user function once #startSVCHelperClient() returns a success, thus
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * making it responsible for the cleanup).
c1c61f44e88f4c8c155272ee56d868043146096asb * After the user function returns, the thread will send the SVCHlpMsg::Null
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * message to indicate a process termination.
c1c61f44e88f4c8c155272ee56d868043146096asb * @param aPrivileged |true| to start the SVC Helper process as a privileged
c1c61f44e88f4c8c155272ee56d868043146096asb * user that can perform administrative tasks
c1c61f44e88f4c8c155272ee56d868043146096asb * @param aFunc user function to run
c1c61f44e88f4c8c155272ee56d868043146096asb * @param aUser argument to the user function
c1c61f44e88f4c8c155272ee56d868043146096asb * @param aProgress progress object that will track operation completion
c1c61f44e88f4c8c155272ee56d868043146096asb * @note aPrivileged is currently ignored (due to some unsolved problems in
c1c61f44e88f4c8c155272ee56d868043146096asb * Vista) and the process will be started as a normal (unprivileged)
678453a8ed49104d8adad58f3ba591bdc39883e8speer * @note Doesn't lock anything.
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANGHRESULT VirtualBox::startSVCHelperClient(bool aPrivileged,
c1c61f44e88f4c8c155272ee56d868043146096asb /* create the SVCHelperClientThread() argument */
c1c61f44e88f4c8c155272ee56d868043146096asb d->that = this;
c1c61f44e88f4c8c155272ee56d868043146096asb static_cast <void *>(d.get()),
c1c61f44e88f4c8c155272ee56d868043146096asb return setError(E_FAIL, "Could not create SVCHelper thread (%Rrc)", vrc);
c1c61f44e88f4c8c155272ee56d868043146096asb /* d is now owned by SVCHelperClientThread(), so release it */
c1c61f44e88f4c8c155272ee56d868043146096asb * Worker thread for startSVCHelperClient().
c1c61f44e88f4c8c155272ee56d868043146096asb/* static */
da14cebe459d3275048785f25bd869cb09b5307fEric ChengVirtualBox::SVCHelperClientThread(RTTHREAD aThread, void *aUser)
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG d(static_cast<StartSVCHelperClientData*>(aUser));
c1c61f44e88f4c8c155272ee56d868043146096asb bool userFuncCalled = false;
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG /* protect VirtualBox from uninitialization */
bce0a86e5d4d65341c5aca6da2595c848297b2aaWENTAO YANG /* it's too late */
678453a8ed49104d8adad58f3ba591bdc39883e8speer vrc = client.create(Utf8StrFmt("VirtualBox\\SVCHelper\\{%RTuuid}",
678453a8ed49104d8adad58f3ba591bdc39883e8speer tr("Could not create the communication channel (%Rrc)"), vrc);
678453a8ed49104d8adad58f3ba591bdc39883e8speer /* get the path to the executable */
c1c61f44e88f4c8c155272ee56d868043146096asb char *exePath = RTProcGetExecutablePath(exePathBuf, RTPATH_MAX);
678453a8ed49104d8adad58f3ba591bdc39883e8speer rc = d->that->setError(E_FAIL, tr("Cannot get executable name"));
678453a8ed49104d8adad58f3ba591bdc39883e8speer Utf8Str argsStr = Utf8StrFmt("/Helper %s", client.name().c_str());
c1c61f44e88f4c8c155272ee56d868043146096asb LogFlowFunc(("Starting '\"%s\" %s'...\n", exePath, argsStr.c_str()));
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* Attempt to start a privileged process using the Run As dialog */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* hide excessive details in case of a frequent error
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * (pressing the Cancel button to close the Run As dialog) */
06db247c678f0e3956535e8a6dec31d6c2108827raghuram tr("Could not launch a privileged process '%s' (%Rrc)"),
06db247c678f0e3956535e8a6dec31d6c2108827raghuram const char *args[] = { exePath, "/Helper", client.name().c_str(), 0 };
06db247c678f0e3956535e8a6dec31d6c2108827raghuram vrc = RTProcCreate(exePath, args, RTENV_DEFAULT, 0, &pid);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo tr("Could not launch a process '%s' (%Rrc)"), exePath, vrc);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* wait for the client to connect */
f0ca1d9a12d54d304791bc74525e2010ca924726sb /* start the user supplied function */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* send the termination signal to the process anyway */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo tr("Could not operate the communication channel (%Rrc)"), vrc);
06db247c678f0e3956535e8a6dec31d6c2108827raghuram /* call the user function in the "cleanup only" mode
06db247c678f0e3956535e8a6dec31d6c2108827raghuram * to let it free resources passed to in aUser */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#endif /* RT_OS_WINDOWS */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * Sends a signal to the client watcher to rescan the set of machines
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * that have open sessions.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * @note Doesn't lock anything.
switch (mWhat)
return S_OK;
if (fDelivered)
if (!allowChange)
return allowChange;
return aEvDesc.init(aSource, VBoxEventType_OnExtraDataChanged, machineId.raw(), key.raw(), val.raw());
void VirtualBox::onNatRedirectChange(const Guid &aMachineId, ULONG ulSlot, bool fRemove, IN_BSTR aName,
fireNATRedirectEvent(m->pEventSource, aMachineId.toUtf16().raw(), ulSlot, fRemove, aName, aProto, aHostIp,
if (m->pEventSource)
* already uninitialized, so do a usual AutoCaller/AutoReadLock sequence
if (aControls)
++it)
if (aControls)
return m->allMachines;
bool fPermitInaccessible,
bool aSetError,
++it)
if (!fPermitInaccessible)
if (aMachine)
return rc;
++it)
if (aMachine)
if (aMachine)
return rc;
static HRESULT validateMachineGroupHelper(const Utf8Str &aGroup, bool fPrimary, VirtualBox *pVirtualBox)
return E_INVALIDARG;
return S_OK;
return E_INVALIDARG;
return E_INVALIDARG;
return E_INVALIDARG;
while (pStr)
if (pSlash)
return E_INVALIDARG;
return E_INVALIDARG;
if (fPrimary)
return VBOX_E_VM_ERROR;
return E_INVALIDARG;
return S_OK;
return rc;
HRESULT VirtualBox::convertMachineGroups(ComSafeArrayIn(IN_BSTR, aMachineGroups), StringsList *pllMachineGroups)
if (aMachineGroups)
return rc;
return S_OK;
bool aSetError,
if (aHardDisk)
return S_OK;
if (aSetError)
return VBOX_E_OBJECT_NOT_FOUND;
bool aSetError,
++it)
if (aHardDisk)
return S_OK;
if (aSetError)
return VBOX_E_OBJECT_NOT_FOUND;
bool aSetError,
vrc);
switch (mediumType)
case DeviceType_DVD:
case DeviceType_Floppy:
return E_INVALIDARG;
bool found = false;
++it)
if (found)
if (aImage)
if (aId)
return rc;
bool fRefresh,
bool aSetError,
return S_OK;
uuid,
pMedium);
return rc;
return S_OK;
++it)
return S_OK;
return m->uuidMediaRegistry;
return m->pHost;
return m->pSystemProperties;
#ifdef VBOX_WITH_EXTPACK
return m->ptrExtPackManager;
return m->pAutostartDb;
#ifdef VBOX_WITH_RESOURCE_USAGE_API
return m->pPerformanceCollector;
return m->strHomeDir;
sizeof(folder));
return vrc;
if (!pcszType)
if (!pcszType)
rc = findDVDOrFloppyImage(DeviceType_Floppy, &aId, aLocation, false /* aSetError */, &pMediumFound);
return S_OK;
bool fInUse = false;
switch (deviceType)
case DeviceType_HardDisk:
case DeviceType_DVD:
rc = findDVDOrFloppyImage(DeviceType_DVD, &aId, Utf8Str::Empty, false /* aSetError */, &pMediumFound);
case DeviceType_Floppy:
rc = findDVDOrFloppyImage(DeviceType_Floppy, &aId, Utf8Str::Empty, false /* aSetError */, &pMediumFound);
fInUse = true;
return fInUse;
struct SaveMediaRegistriesDesc
if (!pDesc)
return VERR_INVALID_PARAMETER;
++it)
delete pDesc;
return VINF_SUCCESS;
* @param uuidRegistry The UUID of the media registry; either a machine UUID (if machine registry) or the UUID of the global registry.
* @param strMachineFolder The machine folder for relative paths, if machine registry, or an empty string otherwise.
++it)
++it2)
(void *)pDesc,
delete pDesc;
delete pDesc;
++it)
* Helper function which actually writes out VirtualBox.xml, the main configuration file.
++it)
++it)
#ifdef VBOX_WITH_NAT_SERVICE
++it)
return rc;
&pMachine);
return rc;
switch (argType)
case DeviceType_HardDisk:
case DeviceType_DVD:
case DeviceType_Floppy:
&pDupMedium);
return rc;
* @note Caller must hold the media tree lock for writing; in addition, this locks @a pMedium for reading
switch (devType)
case DeviceType_HardDisk:
case DeviceType_DVD:
case DeviceType_Floppy:
return S_OK;
++it)
++it)
++it)
return S_OK;
++it)
if (puuidBetter)
return rc;
&pMachine);
bool fNeedsGlobalSettings = false;
++it)
if (!uOld)
ASMNopPause();
if (uOld)
if (!uOld)
ASMNopPause();
return sVersionNormalized;
if (fCreate)
vrc));
return S_OK;
return m->strSettingsFilePath;
* before the locks of any machine object. See AutoLock.h.
return m->lockMachines;
* objects contained in these lists. See AutoLock.h.
return m->lockMedia;
return VERR_COM_UNEXPECTED;
delete pEventQueue;
return rc;
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 (aSaveSettings)
return rc;
if (aSaveSettings)
return rc;
#ifdef VBOX_WITH_NAT_SERVICE
return rc;
return E_NOTIMPL;
#ifdef VBOX_WITH_NAT_SERVICE
++it)
if (!found)
return E_INVALIDARG;
return E_NOTIMPL;
#ifdef VBOX_WITH_NAT_SERVICE
return rc;
return E_NOTIMPL;
#ifdef VBOX_WITH_NAT_SERVICE
&& aSaveSettings)
if (aSaveSettings)
return rc;
return S_OK;
#ifdef VBOX_WITH_NAT_SERVICE
if (aSaveSettings)
return rc;
return E_NOTIMPL;