MachineImpl.cpp revision b4370115582400e9dd1b8576c4f752c7f5938163
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * Implementation of IMachine in VBoxSVC.
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync * Copyright (C) 2006-2010 Oracle Corporation
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * available from http://www.virtualbox.org. This file is free software;
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * you can redistribute it and/or modify it under the terms of the GNU
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * General Public License (GPL) as published by the Free Software
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync/* Make sure all the stdint.h macros are included - must come first! */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync#include <iprt/cpp/xml.h> /* xml::XmlFileWriter::s_psz*Suff. */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync#else /* !RT_OS_WINDOWS */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync#endif /* !RT_OS_WINDOWS */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync// defines / prototypes
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync/////////////////////////////////////////////////////////////////////////////
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync/////////////////////////////////////////////////////////////////////////////
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync// Machine::Data structure
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync/////////////////////////////////////////////////////////////////////////////
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync /* mUuid is initialized in Machine::init() */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync/////////////////////////////////////////////////////////////////////////////
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync// Machine::UserData structure
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync/////////////////////////////////////////////////////////////////////////////
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync /* default values for a newly created machine */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync /* mName, mOSTypeId, mSnapshotFolder, mSnapshotFolderFull are initialized in
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * Machine::init() */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync/////////////////////////////////////////////////////////////////////////////
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync// Machine::HWData structure
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync/////////////////////////////////////////////////////////////////////////////
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync /* default values for a newly created machine */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync mHWVersion = "2"; /** @todo get the default from the schema if that is possible. */
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync /* Default value decision pending. */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync /* Not supported on 32 bits hosts. */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync#if HC_ARCH_BITS == 64 || defined(RT_OS_WINDOWS) || defined(RT_OS_DARWIN)
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync /* default boot order: floppy - DVD - HDD */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync for (size_t i = 3; i < RT_ELEMENTS(mBootOrder); ++i)
9edbe160de7266b3b5d54ccf2f07ed95f9f40c6bvboxsync for (size_t i = 0; i < RT_ELEMENTS(mCPUAttached); i++)
9edbe160de7266b3b5d54ccf2f07ed95f9f40c6bvboxsync/////////////////////////////////////////////////////////////////////////////
9edbe160de7266b3b5d54ccf2f07ed95f9f40c6bvboxsync// Machine::HDData structure
9edbe160de7266b3b5d54ccf2f07ed95f9f40c6bvboxsync/////////////////////////////////////////////////////////////////////////////
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync/////////////////////////////////////////////////////////////////////////////
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync// Machine class
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync/////////////////////////////////////////////////////////////////////////////
9edbe160de7266b3b5d54ccf2f07ed95f9f40c6bvboxsync// constructor / destructor
951d1da36c2120dd8bf59a3b57800f8429dcd387vboxsync/////////////////////////////////////////////////////////////////////////////
9edbe160de7266b3b5d54ccf2f07ed95f9f40c6bvboxsync * Initializes a new machine instance; this init() variant creates a new, empty machine.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * This gets called from VirtualBox::CreateMachine() or VirtualBox::CreateLegacyMachine().
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @param aParent Associated parent object
9edbe160de7266b3b5d54ccf2f07ed95f9f40c6bvboxsync * @param strConfigFile Local file system path to the VM settings file (can
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * be relative to the VirtualBox config directory).
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @param strName name for the machine
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @param aId UUID for the new machine.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @param aOsType Optional OS Type of this machine.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @param aOverride |TRUE| to override VM config file existence checks.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * |FALSE| refuses to overwrite existing VM configs.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @param aNameSync |TRUE| to automatically sync settings dir and file
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * name with the machine name. |FALSE| is used for legacy
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * machines where the file name is specified by the
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * user and should never change.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @return Success indicator. if not S_OK, the machine object is invalid
4aafb1203580a5c145a7bdae57ebf69a36fa4f01vboxsync LogFlowThisFunc(("(Init_New) aConfigFile='%s'\n", strConfigFile.raw()));
4aafb1203580a5c145a7bdae57ebf69a36fa4f01vboxsync /* Enclose the state transition NotReady->InInit->Ready */
4aafb1203580a5c145a7bdae57ebf69a36fa4f01vboxsync // create an empty machine config
4aafb1203580a5c145a7bdae57ebf69a36fa4f01vboxsync mData->pMachineConfigFile = new settings::MachineConfigFile(NULL);
0f77dc54d7ec617480988ccdfcd080f480e79698vboxsync // set to true now to cause uninit() to call uninitDataAndChildObjects() on failure
619824b60d668e6e43f385ef78cf06e13d43aab6vboxsync /* initialize the default snapshots folder
0f77dc54d7ec617480988ccdfcd080f480e79698vboxsync * (note: depends on the name value set above!) */
0f77dc54d7ec617480988ccdfcd080f480e79698vboxsync /* Store OS type */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync /* Apply BIOS defaults */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync /* Apply network adapters defaults */
76cb9831bbeaff3bb30068363e35660a776736c4vboxsync for (ULONG slot = 0; slot < RT_ELEMENTS(mNetworkAdapters); ++slot)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* Apply serial port defaults */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync for (ULONG slot = 0; slot < RT_ELEMENTS(mSerialPorts); ++slot)
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync /* commit all changes made during the initialization */
5422fa26c16d9d065b5879feb3852da231be5c55vboxsync /* Confirm a successful initialization when it's the case */
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync LogFlowThisFunc(("mName='%ls', mRegistered=%RTbool, mAccessible=%RTbool, rc=%08X\n",
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * Initializes a new instance with data from machine XML (formerly Init_Registered).
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * Gets called in two modes:
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * -- from VirtualBox::initMachines() during VirtualBox startup; in that case, the
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * UUID is specified and we mark the machine as "registered";
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * -- from the public VirtualBox::OpenMachine() API, in which case the UUID is NULL
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * and the machine remains unregistered until RegisterMachine() is called.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @param aParent Associated parent object
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @param aConfigFile Local file system path to the VM settings file (can
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * be relative to the VirtualBox config directory).
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @param aId UUID of the machine or NULL (see above).
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @return Success indicator. if not S_OK, the machine object is invalid
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync LogFlowThisFunc(("(Init_Registered) aConfigFile='%s\n", strConfigFile.raw()));
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync /* Enclose the state transition NotReady->InInit->Ready */
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync // loading a registered VM:
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync // now load the settings from XML:
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync // this calls initDataAndChildObjects() and loadSettings()
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync // opening an unregistered VM (VirtualBox::OpenMachine()):
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync // set to true now to cause uninit() to call uninitDataAndChildObjects() on failure
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync // load and parse machine XML; this will throw on XML or logic errors
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync mData->pMachineConfigFile = new settings::MachineConfigFile(&mData->m_strConfigFileFull);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync // use UUID from machine config
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync unconst(mData->mUuid) = mData->pMachineConfigFile->uuid;
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync rc = loadMachineDataFromSettings(*mData->pMachineConfigFile);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* we assume that error info is set by the thrower */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync catch (...)
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync rc = VirtualBox::handleUnexpectedExceptions(RT_SRC_POS);
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync /* Confirm a successful initialization when it's the case */
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync LogFlowThisFunc(("mName='%ls', mRegistered=%RTbool, mAccessible=%RTbool "
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync "rc=%08X\n",
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * Initializes a new instance from a machine config that is already in memory
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * (import OVF case). Since we are importing, the UUID in the machine
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * config is ignored and we always generate a fresh one.
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync * @param strName Name for the new machine; this overrides what is specified in config and is used
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync * for the settings file as well.
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync * @param config Machine configuration loaded and parsed from XML.
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync * @return Success indicator. if not S_OK, the machine object is invalid
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* Enclose the state transition NotReady->InInit->Ready */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync Utf8Str strConfigFile(aParent->getDefaultMachineFolder());
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync rc = tryCreateMachineConfigFile(FALSE /* aOverride */);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync // set to true now to cause uninit() to call uninitDataAndChildObjects() on failure
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync // create empty machine config for instance data
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync mData->pMachineConfigFile = new settings::MachineConfigFile(NULL);
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync // generate fresh UUID, ignore machine config
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync // override VM name as well, it may be different
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync /* commit all changes made during the initialization */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* Confirm a successful initialization when it's the case */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync LogFlowThisFunc(("mName='%ls', mRegistered=%RTbool, mAccessible=%RTbool "
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync "rc=%08X\n",
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * Shared code between the various init() implementations.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @param aParent
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync AssertReturn(!strConfigFile.isEmpty(), E_INVALIDARG);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* share the parent weakly */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* allocate the essential machine data structure (the rest will be
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync * allocated later by initDataAndChildObjects() */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* memorize the config file name (as provided) */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* get the full file name */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync int vrc1 = mParent->calculateFullPath(strConfigFile, mData->m_strConfigFileFull);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync tr("Invalid machine settings file name '%s' (%Rrc)"),
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * Tries to create a machine settings file in the path stored in the machine
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * instance data. Used when a new machine is created to fail gracefully if
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * the settings file could not be written (e.g. because machine dir is read-only).
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncHRESULT Machine::tryCreateMachineConfigFile(BOOL aOverride)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync // when we create a new machine, we must be able to create the settings file
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync int vrc = RTFileOpen(&f, mData->m_strConfigFileFull.c_str(), RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* try to delete the config file, as otherwise the creation
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * of a new settings file will fail. */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync int vrc2 = RTFileDelete(mData->m_strConfigFileFull.c_str());
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync tr("Could not delete the existing settings file '%s' (%Rrc)"),
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync tr("Invalid machine settings file name '%s' (%Rrc)"),
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * Initializes the registered machine by loading the settings file.
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * This method is separated from #init() in order to make it possible to
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * retry the operation after VirtualBox startup instead of refusing to
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * startup the whole VirtualBox server in case if the settings file of some
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * registered VM is invalid or inaccessible.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @note Must be always called from this object's write lock
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * (unless called from #init() that doesn't need any locking).
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * @note Locks the mUSBController method for writing.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @note Subclasses must not call this method.
951d1da36c2120dd8bf59a3b57800f8429dcd387vboxsync /* Temporarily reset the registered flag in order to let setters
951d1da36c2120dd8bf59a3b57800f8429dcd387vboxsync * potentially called from loadSettings() succeed (isMutable() used in
951d1da36c2120dd8bf59a3b57800f8429dcd387vboxsync * all setters will return FALSE for a Machine instance if mRegistered
951d1da36c2120dd8bf59a3b57800f8429dcd387vboxsync * is TRUE). */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync // load and parse machine XML; this will throw on XML or logic errors
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync mData->pMachineConfigFile = new settings::MachineConfigFile(&mData->m_strConfigFileFull);
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync if (mData->mUuid != mData->pMachineConfigFile->uuid)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync tr("Machine UUID {%RTuuid} in '%s' doesn't match its UUID {%s} in the registry file '%s'"),
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync rc = loadMachineDataFromSettings(*mData->pMachineConfigFile);
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync /* we assume that error info is set by the thrower */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync catch (...)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync rc = VirtualBox::handleUnexpectedExceptions(RT_SRC_POS);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* Restore the registered flag (even on failure) */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* Set mAccessible to TRUE only if we successfully locked and loaded
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * the settings file */
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync /* commit all changes made during loading the settings file */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync commit(); // @todo r=dj why do we need a commit during init?!? this is very expensive
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* If the machine is registered, then, instead of returning a
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * failure, we mark it as inaccessible and set the result to
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * success to give it a try later */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* fetch the current error info */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync LogWarning(("Machine {%RTuuid} is inaccessible! [%ls]\n",
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* rollback all changes */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* uninitialize the common part to make sure all data is reset to
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * default (null) values */
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * Uninitializes the instance.
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * Called either from FinalRelease() or by the parent when it gets destroyed.
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * @note The caller of this method must make sure that this object
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * a) doesn't have active callers on the current thread and b) is not locked
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * by the current thread; otherwise uninit() will hang either a) due to
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * AutoUninitSpan waiting for a number of calls to drop to zero or b) due to
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * a dead-lock caused by this thread waiting for all callers on the other
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * threads are done but preventing them from doing so by holding a lock.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* Enclose the state transition Ready->InUninit->NotReady */
951d1da36c2120dd8bf59a3b57800f8429dcd387vboxsync LogFlowThisFunc(("initFailed()=%d\n", autoUninitSpan.initFailed()));
951d1da36c2120dd8bf59a3b57800f8429dcd387vboxsync LogFlowThisFunc(("mRegistered=%d\n", mData->mRegistered));
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync /* Theoretically, this can only happen if the VirtualBox server has been
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * terminated while there were clients running that owned open direct
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync * sessions. Since in this case we are definitely called by
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * VirtualBox::uninit(), we may be sure that SessionMachine::uninit()
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync * won't happen on the client watcher thread (because it does
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * VirtualBox::addCaller() for the duration of the
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * SessionMachine::checkForDeath() call, so that VirtualBox::uninit()
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync * cannot happen until the VirtualBox caller is released). This is
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync * important, because SessionMachine::uninit() cannot correctly operate
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync * after we return from this method (it expects the Machine instance is
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync * still valid). We'll call it ourselves below.
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync LogWarningThisFunc(("Session machine is not NULL (%p), the direct session is still open!\n",
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync if (Global::IsOnlineOrTransient(mData->mMachineState))
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync LogWarningThisFunc(("Setting state to Aborted!\n"));
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync /* set machine state using SessionMachine reimplementation */
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync static_cast<Machine*>(mData->mSession.mMachine)->setMachineState(MachineState_Aborted);
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * Uninitialize SessionMachine using public uninit() to indicate
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync * an unexpected uninitialization.
3a2aedd9e337c0cc515ce501a066359ba2f9505cvboxsync /* SessionMachine::uninit() must set mSession.mMachine to null */
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync /* the lock is no more necessary (SessionMachine is uninitialized) */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync // has machine been modified?
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync LogWarningThisFunc(("Discarding unsaved settings changes!\n"));
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync /* free the essential data structure last */
0f77dc54d7ec617480988ccdfcd080f480e79698vboxsync// IMachine properties
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync/////////////////////////////////////////////////////////////////////////////
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsyncSTDMETHODIMP Machine::COMGETTER(Parent)(IVirtualBox **aParent)
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync /* mParent is constant during life time, no need to lock */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncSTDMETHODIMP Machine::COMGETTER(Accessible)(BOOL *aAccessible)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* try to initialize the VM once more if not accessible */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync LogFlowThisFunc(("Dumping media backreferences\n"));
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync // reset the XML file to force loadSettings() (called from registeredInit())
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync // to parse it again; the file might have changed
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync /* make sure interesting parties will notice the accessibility
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync * state change */
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync mParent->onMachineStateChange(mData->mUuid, mData->mMachineState);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncSTDMETHODIMP Machine::COMGETTER(AccessError)(IVirtualBoxErrorInfo **aAccessError)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync if (mData->mAccessible || !mData->mAccessError.isBasicAvailable())
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync /* return shortly */
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync errorInfo->init(mData->mAccessError.getResultCode(),
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync Utf8Str(mData->mAccessError.getComponent()).c_str(),
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsyncSTDMETHODIMP Machine::COMSETTER(Name)(IN_BSTR aName)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync HRESULT rc = checkStateDependency(MutableStateDep);
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsyncSTDMETHODIMP Machine::COMGETTER(Description)(BSTR *aDescription)
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsyncSTDMETHODIMP Machine::COMSETTER(Description)(IN_BSTR aDescription)
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
affcf9ad9ceb4b20938f02dd7cd284b4aaf6b5bbvboxsync HRESULT rc = checkStateDependency(MutableStateDep);
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsyncSTDMETHODIMP Machine::COMGETTER(OSTypeId)(BSTR *aOSTypeId)
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsyncSTDMETHODIMP Machine::COMSETTER(OSTypeId)(IN_BSTR aOSTypeId)
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* look up the object by Id to check it is valid */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync HRESULT rc = mParent->GetGuestOSType(aOSTypeId, guestOSType.asOutParam());
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* when setting, always use the "etalon" value for consistency -- lookup
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * by ID is case-insensitive and the input value may have different case */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync rc = guestOSType->COMGETTER(Id)(osTypeId.asOutParam());
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsyncSTDMETHODIMP Machine::COMGETTER(FirmwareType)(FirmwareType_T *aFirmwareType)
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsyncSTDMETHODIMP Machine::COMSETTER(FirmwareType)(FirmwareType_T aFirmwareType)
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
0f77dc54d7ec617480988ccdfcd080f480e79698vboxsyncSTDMETHODIMP Machine::COMGETTER(KeyboardHidType)(KeyboardHidType_T *aKeyboardHidType)
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsyncSTDMETHODIMP Machine::COMSETTER(KeyboardHidType)(KeyboardHidType_T aKeyboardHidType)
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsyncSTDMETHODIMP Machine::COMGETTER(PointingHidType)(PointingHidType_T *aPointingHidType)
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsyncSTDMETHODIMP Machine::COMSETTER(PointingHidType)(PointingHidType_T aPointingHidType)
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsyncSTDMETHODIMP Machine::COMGETTER(HardwareVersion)(BSTR *aHWVersion)
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsyncSTDMETHODIMP Machine::COMSETTER(HardwareVersion)(IN_BSTR aHWVersion)
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync /* check known version */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync tr("Invalid hardware version: %ls\n"), aHWVersion);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync HRESULT rc = checkStateDependency(MutableStateDep);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncSTDMETHODIMP Machine::COMGETTER(HardwareUUID)(BSTR *aUUID)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsyncSTDMETHODIMP Machine::COMSETTER(HardwareUUID)(IN_BSTR aUUID)
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync HRESULT rc = checkStateDependency(MutableStateDep);
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsyncSTDMETHODIMP Machine::COMGETTER(MemorySize)(ULONG *memorySize)
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncSTDMETHODIMP Machine::COMSETTER(MemorySize)(ULONG memorySize)
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync /* check RAM limits */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync tr("Invalid RAM size: %lu MB (must be in range [%lu, %lu] MB)"),
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync HRESULT rc = checkStateDependency(MutableStateDep);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncSTDMETHODIMP Machine::COMGETTER(CPUCount)(ULONG *CPUCount)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncSTDMETHODIMP Machine::COMSETTER(CPUCount)(ULONG CPUCount)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* check CPU limits */
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync tr("Invalid virtual CPU count: %lu (must be in range [%lu, %lu])"),
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync CPUCount, SchemaDefs::MinCPUCount, SchemaDefs::MaxCPUCount);
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* We cant go below the current number of CPUs if hotplug is enabled*/
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync for (unsigned idx = CPUCount; idx < SchemaDefs::MaxCPUCount; idx++)
0f77dc54d7ec617480988ccdfcd080f480e79698vboxsync HRESULT rc = checkStateDependency(MutableStateDep);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncSTDMETHODIMP Machine::COMGETTER(CPUHotPlugEnabled)(BOOL *enabled)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncSTDMETHODIMP Machine::COMSETTER(CPUHotPlugEnabled)(BOOL enabled)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync /* Add the amount of CPUs currently attached */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * We can disable hotplug only if the amount of maximum CPUs is equal
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * to the amount of attached CPUs
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync unsigned iHighestId = 0;
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync for (unsigned i = 0; i < SchemaDefs::MaxCPUCount; i++)
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync tr("CPU hotplugging can't be disabled because the maximum number of CPUs is not equal to the amount of CPUs attached\n"));
951d1da36c2120dd8bf59a3b57800f8429dcd387vboxsyncSTDMETHODIMP Machine::COMGETTER(HpetEnabled)(BOOL *enabled)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsyncSTDMETHODIMP Machine::COMSETTER(HpetEnabled)(BOOL enabled)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsyncSTDMETHODIMP Machine::COMGETTER(VRAMSize)(ULONG *memorySize)
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
7202d537edf6d2c5fc2c26bade6855541c675fa0vboxsyncSTDMETHODIMP Machine::COMSETTER(VRAMSize)(ULONG memorySize)
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync /* check VRAM limits */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync tr("Invalid VRAM size: %lu MB (must be in range [%lu, %lu] MB)"),
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync memorySize, SchemaDefs::MinGuestVRAM, SchemaDefs::MaxGuestVRAM);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync HRESULT rc = checkStateDependency(MutableStateDep);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync/** @todo this method should not be public */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncSTDMETHODIMP Machine::COMGETTER(MemoryBalloonSize)(ULONG *memoryBalloonSize)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync * Set the memory balloon size.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * This method is also called from IGuest::COMSETTER(MemoryBalloonSize) so
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * we have to make sure that we never call IGuest from here.
7202d537edf6d2c5fc2c26bade6855541c675fa0vboxsyncSTDMETHODIMP Machine::COMSETTER(MemoryBalloonSize)(ULONG memoryBalloonSize)
e9e12792a48d30217ce62abc9051b4fdd55e7fa1vboxsync /* This must match GMMR0Init; currently we only support memory ballooning on all 64-bit hosts except Mac OS X */
7202d537edf6d2c5fc2c26bade6855541c675fa0vboxsync#if HC_ARCH_BITS == 64 && (defined(RT_OS_WINDOWS) || defined(RT_OS_SOLARIS) || defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD))
e9e12792a48d30217ce62abc9051b4fdd55e7fa1vboxsync /* check limits */
e9e12792a48d30217ce62abc9051b4fdd55e7fa1vboxsync if (memoryBalloonSize >= VMMDEV_MAX_MEMORY_BALLOON(mHWData->mMemorySize))
7202d537edf6d2c5fc2c26bade6855541c675fa0vboxsync tr("Invalid memory balloon size: %lu MB (must be in range [%lu, %lu] MB)"),
7202d537edf6d2c5fc2c26bade6855541c675fa0vboxsync memoryBalloonSize, 0, VMMDEV_MAX_MEMORY_BALLOON(mHWData->mMemorySize));
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
25c97a3e3ce2710f95faa6d181486df26b518e74vboxsync return setError(E_NOTIMPL, tr("Memory ballooning is only supported on 64-bit hosts"));
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsyncSTDMETHODIMP Machine::COMGETTER(PageFusionEnabled) (BOOL *enabled)
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsyncSTDMETHODIMP Machine::COMSETTER(PageFusionEnabled) (BOOL enabled)
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync return setError(E_NOTIMPL, tr("Page fusion is only supported on 64-bit hosts"));
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncSTDMETHODIMP Machine::COMGETTER(Accelerate3DEnabled)(BOOL *enabled)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncSTDMETHODIMP Machine::COMSETTER(Accelerate3DEnabled)(BOOL enable)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync HRESULT rc = checkStateDependency(MutableStateDep);
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync /** @todo check validity! */
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncSTDMETHODIMP Machine::COMGETTER(Accelerate2DVideoEnabled)(BOOL *enabled)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsyncSTDMETHODIMP Machine::COMSETTER(Accelerate2DVideoEnabled)(BOOL enable)
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync HRESULT rc = checkStateDependency(MutableStateDep);
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync /** @todo check validity! */
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsyncSTDMETHODIMP Machine::COMGETTER(MonitorCount)(ULONG *monitorCount)
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
4aafb1203580a5c145a7bdae57ebf69a36fa4f01vboxsyncSTDMETHODIMP Machine::COMSETTER(MonitorCount)(ULONG monitorCount)
ffbd405f3093b70e19fe9f173cf7d783a304e3e3vboxsync /* make sure monitor count is a sensible number */
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync if (monitorCount < 1 || monitorCount > SchemaDefs::MaxGuestMonitors)
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync tr("Invalid monitor count: %lu (must be in range [%lu, %lu])"),
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync HRESULT rc = checkStateDependency(MutableStateDep);
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsyncSTDMETHODIMP Machine::COMGETTER(BIOSSettings)(IBIOSSettings **biosSettings)
0dfc79e0666da4c8853deda18a14ebf5819d0d78vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
return S_OK;
if (!aVal)
return E_POINTER;
switch(property)
case CPUPropertyType_PAE:
return E_INVALIDARG;
return S_OK;
switch(property)
case CPUPropertyType_PAE:
return E_INVALIDARG;
return S_OK;
STDMETHODIMP Machine::GetCPUIDLeaf(ULONG aId, ULONG *aValEax, ULONG *aValEbx, ULONG *aValEcx, ULONG *aValEdx)
switch(aId)
return S_OK;
STDMETHODIMP Machine::SetCPUIDLeaf(ULONG aId, ULONG aValEax, ULONG aValEbx, ULONG aValEcx, ULONG aValEdx)
switch(aId)
return S_OK;
switch(aId)
return S_OK;
return S_OK;
if (!aVal)
return E_POINTER;
switch(property)
return E_INVALIDARG;
return S_OK;
switch(property)
return E_INVALIDARG;
return S_OK;
return S_OK;
tr("The snapshot folder of a machine with snapshots cannot be changed (please delete all snapshots first)"));
if (isInOwnDir())
return S_OK;
STDMETHODIMP Machine::COMGETTER(MediumAttachments)(ComSafeArrayOut(IMediumAttachment*, aAttachments))
return E_POINTER;
return S_OK;
#ifdef VBOX_WITH_VRDP
if (!vrdpServer)
return E_POINTER;
return S_OK;
if (!audioAdapter)
return E_POINTER;
return S_OK;
#ifdef VBOX_WITH_VUSB
# ifdef VBOX_WITH_USB
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
if (!machineState)
return E_POINTER;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
? FALSE
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return rc;
return S_OK;
return S_OK;
if ( aEnabled
&& ( !isSessionMachine()
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
if ( aEnabled
&& ( !isSessionMachine()
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
LogFlowThisFunc(("after waiting: mSession.mState=%s\n", Global::stringifySessionState(mData->mSession.mState)));
if ( (mData->mSession.mState == SessionState_Locked) // machine is write-locked already (i.e. session machine exists)
&& (lockType == LockType_Shared) // caller wants a shared link to the existing session that holds the write lock:
// 3) process W: the process which already holds the write lock on the machine (write-locking session)
if (fLaunchingVMProcess)
* Machine/SessionMachine methods. Leaving the lock here is quite safe
if (fLaunchingVMProcess)
return rc;
return rc;
static_cast<IMachine*>(this),
return rc;
return S_OK;
return S_OK;
bool fNeedsSaveSettings = false;
if ( (aControllerPort < 0)
|| (aDevice < 0)
aDevice)))
if (pMedium)
tr("Medium '%s' is already attached to port %d, device %d of controller '%ls' of this virtual machine"),
switch (aType)
case DeviceType_HardDisk:
(int)aType);
bool indirect = false;
bool associate = true;
return S_OK;
associate = false;
if (!indirect)
++it)
pMedium))
return S_OK;
indirect = false;
associate = false;
while (snap)
++it)
delete pMediumLockList;
if (fNeedsSaveSettings)
return rc;
bool fNeedsSaveSettings = false;
aDevice);
if (!pAttach)
if (fNeedsSaveSettings)
bool fNeedsGlobalSaveSettings = false;
return S_OK;
aDevice);
if (!pAttach)
tr("Setting passthrough rejected as the device attached to device slot %d on port %d of controller '%ls' is not a DVD"),
return S_OK;
aDevice);
switch (mediumType)
case DeviceType_DVD:
++it)
medium = p;
case DeviceType_Floppy:
++it)
medium = p;
aDevice);
aDevice);
return rc;
return rc;
aDevice);
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return E_POINTER;
for (settings::ExtraDataItemsMap::const_iterator it = mData->pMachineConfigFile->mapExtraDataItems.begin();
++it, ++i)
return S_OK;
settings::ExtraDataItemsMap::const_iterator it = mData->pMachineConfigFile->mapExtraDataItems.find(Utf8Str(aKey));
return S_OK;
settings::ExtraDataItemsMap::const_iterator it = mData->pMachineConfigFile->mapExtraDataItems.find(strKey);
bool fChanged;
aKey,
sep,
err);
if (isSnapshotMachine())
bool fNeedsGlobalSaveSettings = false;
if (fChanged)
return S_OK;
bool fNeedsGlobalSaveSettings = false;
return rc;
return S_OK;
if (snapshotCount)
if (fAutoCleanup)
++it)
commitMedia();
if (fAutoCleanup)
size_t u = 0;
++it)
size_t i = 0;
++it)
return S_OK;
vrc);
Utf8Str otherXml = Utf8StrFmt("%s%s", mData->m_strConfigFileFull.c_str(), xml::XmlFileWriter::s_pszTmpSuff);
otherXml = Utf8StrFmt("%s%s", mData->m_strConfigFileFull.c_str(), xml::XmlFileWriter::s_pszPrevSuff);
for (int i = uLogHistoryCount; i > 0; i--)
return S_OK;
if ( (aId)
/* Either it's a null UUID or the conversion failed. (null uuid has a special meaning in findSnapshot) */
aId);
return rc;
return rc;
STDMETHODIMP Machine::CreateSharedFolder(IN_BSTR aName, IN_BSTR aHostPath, BOOL aWritable, BOOL aAutoMount)
aName);
return S_OK;
return S_OK;
if (!directControl)
return S_OK;
if (!directControl)
return S_OK;
#ifdef VBOX_WITH_GUEST_PROPS
using namespace guestProp;
return S_OK;
if (!directControl)
return rc;
#ifndef VBOX_WITH_GUEST_PROPS
return rc;
#ifdef VBOX_WITH_GUEST_PROPS
using namespace guestProp;
bool found = false;
aFlags);
aName);
++it)
found = true;
if (*aValue)
return rc;
if (!directControl)
(aName,
return rc;
#ifndef VBOX_WITH_GUEST_PROPS
return E_INVALIDARG;
return rc;
#ifdef VBOX_WITH_GUEST_PROPS
using namespace guestProp;
++it)
++it)
++iProp;
return S_OK;
if (!directControl)
return rc;
#ifndef VBOX_WITH_GUEST_PROPS
return E_POINTER;
return rc;
return S_OK;
aDevice);
return S_OK;
aName);
++it)
return S_OK;
return rc;
++it)
return S_OK;
++it)
aName);
return S_OK;
static int readSavedDisplayScreenshot(Utf8Str *pStateFilePath, uint32_t u32Type, uint8_t **ppu8Data, uint32_t *pcbData, uint32_t *pu32Width, uint32_t *pu32Height)
return VERR_NOT_SUPPORTED;
return vrc;
STDMETHODIMP Machine::QuerySavedThumbnailSize(ULONG aScreenId, ULONG *aSize, ULONG *aWidth, ULONG *aHeight)
if (aScreenId != 0)
return E_NOTIMPL;
int vrc = readSavedDisplayScreenshot(&mSSData->mStateFilePath, 0 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
vrc);
return S_OK;
STDMETHODIMP Machine::ReadSavedThumbnailToArray(ULONG aScreenId, BOOL aBGR, ULONG *aWidth, ULONG *aHeight, ComSafeArrayOut(BYTE, aData))
if (aScreenId != 0)
return E_NOTIMPL;
int vrc = readSavedDisplayScreenshot(&mSSData->mStateFilePath, 0 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
vrc);
if (aBGR)
return S_OK;
STDMETHODIMP Machine::QuerySavedScreenshotPNGSize(ULONG aScreenId, ULONG *aSize, ULONG *aWidth, ULONG *aHeight)
if (aScreenId != 0)
return E_NOTIMPL;
int vrc = readSavedDisplayScreenshot(&mSSData->mStateFilePath, 1 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
vrc);
return S_OK;
STDMETHODIMP Machine::ReadSavedScreenshotPNGToArray(ULONG aScreenId, ULONG *aWidth, ULONG *aHeight, ComSafeArrayOut(BYTE, aData))
if (aScreenId != 0)
return E_NOTIMPL;
int vrc = readSavedDisplayScreenshot(&mSSData->mStateFilePath, 1 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
vrc);
for (unsigned i = 0; i < cbData; i++)
return S_OK;
return setError(E_INVALIDARG, tr("CPU id exceeds number of possible CPUs [0:%lu]"), mHWData->mCPUCount-1);
return S_OK;
if (aCpu == 0)
return S_OK;
*aCpuAttached = false;
*aCpuAttached = true;
return S_OK;
return S_OK;
STDMETHODIMP Machine::ReadLog(ULONG aIdx, ULONG64 aOffset, ULONG64 aSize, ComSafeArrayOut(BYTE, aData))
return rc;
return S_OK;
return vrc;
if (idx == 0)
return log;
for (char *p = newEnvStr; *p; ++p)
if (*var)
if (val)
#ifdef VBOX_WITH_QTGUI
# ifdef RT_OS_DARWIN /* Avoid Launch Services confusing this with the selector by using a helper app. */
const char * args[] = {szPath, "--comment", strName.c_str(), "--startvm", idStr.c_str(), "--no-startvm-errormsgbox", 0 };
#ifdef VBOX_WITH_VBOXSDL
#ifdef VBOX_WITH_HEADLESS
#ifdef VBOX_WITH_VRDP
#ifdef VBOX_WITH_VRDP
return S_OK;
#if defined(RT_OS_WINDOWS)
&status);
// no need to check whether VirtualBox.xml needs saving too since
commit();
return rc;
AssertFailed();
if (aState)
if (aRegistered)
return S_OK;
switch (aDepType)
case AnyStateDep:
case MutableStateDep:
&& ( !isSessionMachine() /** @todo This was just convered raw; Check if Running and Paused should actually be included here... (Live Migration) */
case MutableOrSavedStateDep:
&& ( !isSessionMachine() /** @todo This was just convered raw; Check if Running and Paused should actually be included here... (Live Migration) */
return S_OK;
#ifdef VBOX_WITH_VRDP
return S_OK;
if (mUSBController)
if (mAudioAdapter)
#ifdef VBOX_WITH_VRDP
if (mVRDPServer)
if (mBIOSSettings)
if ( !!mMediaData
&& (!isSessionMachine())
++it)
if (isSessionMachine())
return S_OK;
bool found = false;
++it)
if (found)
return rc;
vrc);
return S_OK;
vrc);
++it)
return rc;
++it)
++it)
for (size_t i = 0;
#ifdef VBOX_WITH_VRDP
++it)
++it)
++it)
++it)
#ifdef VBOX_WITH_GUEST_PROPS
++it)
return E_OUTOFMEMORY;
return rc;
++it)
return rc;
return S_OK;
++it)
++it2)
tr("Duplicate attachments for storage controller '%s', port %d, device %d of the virtual machine '%ls'"),
++it)
case DeviceType_Floppy:
case DeviceType_DVD:
case DeviceType_HardDisk:
if (isSnapshotMachine())
return rc;
if (isSnapshotMachine())
tr("Immutable hard disk '%s' with UUID {%RTuuid} cannot be directly attached to snapshot with UUID {%RTuuid} "
tr("Immutable hard disk '%s' with UUID {%RTuuid} cannot be directly attached to the virtual machine '%ls' ('%s')"),
if ( !isSnapshotMachine()
tr("Hard disk '%s' with UUID {%RTuuid} cannot be directly attached to the virtual machine '%ls' ('%s') "
medium))
if (isSnapshotMachine())
return rc;
if (aSetError)
return E_FAIL;
if (!aSnapshot)
if (aSetError)
return E_FAIL;
return S_OK;
if (aSetError)
return VBOX_E_OBJECT_NOT_FOUND;
if (!aSnapshot)
if (aSetError)
return VBOX_E_OBJECT_NOT_FOUND;
return S_OK;
++it)
return S_OK;
if (aSetError)
return VBOX_E_OBJECT_NOT_FOUND;
++it)
return S_OK;
bool dirRenamed = false;
bool fileRenamed = false;
if (!fSettingsFileIsNew)
vrc);
dirRenamed = true;
if (!fSettingsFileIsNew)
vrc);
fileRenamed = true;
*pfNeedsGlobalSaveSettings = true;
if (fileRenamed)
if (dirRenamed)
if (fSettingsFileIsNew)
vrc);
vrc);
RTFileClose(f);
return rc;
E_FAIL);
bool fNeedsWrite = false;
fNeedsWrite = true;
if (fNeedsWrite)
delete pOldConfig;
commit();
delete pNewConfig;
if (isSessionMachine())
return rc;
return rc;
mHWData->mHWVersion = "2"; /** @todo Is this safe, to update mHWVersion here? If not some other point needs to be found where this can be done. */
for (size_t i = 0;
#ifdef VBOX_WITH_VRDP
++slot)
++slot)
++slot)
++it)
#ifdef VBOX_WITH_GUEST_PROPS
++it)
return E_OUTOFMEMORY;
return rc;
++it)
return S_OK;
++it)
if (pMedium)
return rc;
if (fHostDrive)
return S_OK;
if (aFlags == 0)
return S_OK;
//@todo live migration mData->pMachineConfigFile->fTeleported = (mData->mMachineState == MachineState_Teleported);
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.
bool aOnline,
bool *pfNeedsSaveSettings)
, E_FAIL);
if (aOnline)
if (!aOnline)
++it)
NULL,
delete pMediumLockList;
throw rc;
++it)
if (aOnline)
diff,
if (!aOnline)
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.
++it)
++it)
AssertMsg(SUCCEEDED(rc), ("rc=%Rhrc it=%s hd=%s\n", rc, (*it)->getLogName(), hd->getLocationFull().c_str() ));
return mrc;
++it)
return pAttach;
return NULL;
++it)
return pAttach;
return NULL;
++it)
return pAttach;
return NULL;
* @param writeLock Machine write lock which the caller must have locked once. This may be released temporarily in here.
* @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.
bool *pfNeedsSaveSettings)
return S_OK;
bool fMediaNeedsLocking = false;
++it)
fImplicit));
if (fImplicit)
if ( aOnline
&& pMedium
if (pMediumLockList)
if (!fMediaNeedsLocking)
fMediaNeedsLocking = true;
if (pMedium)
++oldIt)
LogFlowThisFunc(("--> medium '%s' was attached before, will not remove\n", pMedium->getName().raw()));
++it)
if (aOnline)
if (pMediumLockList)
if (fMediaNeedsLocking)
if (isSessionMachine())
* @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.
++it)
if (pMedium)
if (pMedium)
if (aSettingsDir)
++it;
++it;
if (mBIOSSettings)
#ifdef VBOX_WITH_VRDP
if (mAudioAdapter)
if (aNotify)
commitMedia();
#ifdef VBOX_WITH_VRDP
bool commitStorageControllers = false;
if (mPeer)
if (!peer)
++it;
++it;
commitStorageControllers = true;
commitStorageControllers = true;
++it;
if (isSessionMachine())
++it)
#ifdef VBOX_WITH_VRDP
++it)
#ifdef VBOX_WITH_RESOURCE_USAGE_API
/* The total amount of physical ram is fixed now, but we'll support dynamic guest ram configurations in the future. */
pm::SubMetric *guestMemTotal = new pm::SubMetric("Guest/RAM/Usage/Total", "Total amount of physical guest RAM.");
pm::SubMetric *guestMemFree = new pm::SubMetric("Guest/RAM/Usage/Free", "Free amount of physical guest RAM.");
pm::SubMetric *guestMemBalloon = new pm::SubMetric("Guest/RAM/Usage/Balloon", "Amount of ballooned physical guest RAM.");
pm::SubMetric *guestMemShared = new pm::SubMetric("Guest/RAM/Usage/Shared", "Amount of shared physical guest RAM.");
pm::SubMetric *guestMemCache = new pm::SubMetric("Guest/RAM/Usage/Cache", "Total amount of guest (disk) cache memory.");
pm::SubMetric *guestPagedTotal = new pm::SubMetric("Guest/Pagefile/Usage/Total", "Total amount of space in the page file.");
pm::BaseMetric *guestCpuLoad = new pm::GuestCpuLoad(mGuestHAL, aMachine, guestLoadUser, guestLoadKernel, guestLoadIdle);
pm::BaseMetric *guestCpuMem = new pm::GuestRamUsage(mGuestHAL, aMachine, guestMemTotal, guestMemFree, guestMemBalloon, guestMemShared,
if (aCollector)
if (mGuestHAL)
delete mGuestHAL;
#if defined(RT_OS_WINDOWS)
return S_OK;
#if defined(RT_OS_WINDOWS)
E_FAIL);
E_FAIL);
# ifdef VBOX_WITH_NEW_SYS_V_KEYGEN
if (sem >= 0)
return E_FAIL;
#ifdef RT_OS_LINUX
return E_FAIL;
E_FAIL);
E_FAIL);
++it)
#ifdef VBOX_WITH_VRDP
return S_OK;
* mData->mSession.mMachine.setNull() below (which can release the last
#if defined(RT_OS_WINDOWS)
if (mIPCSem)
if (mIPCSem >= 0)
# ifdef VBOX_WITH_NEW_SYS_V_KEYGEN
#ifdef VBOX_WITH_USB
if (service)
++it;
#if defined(RT_OS_WINDOWS)
if (mIPCSem)
if (mIPCSem >= 0)
# ifdef VBOX_WITH_NEW_SYS_V_KEYGEN
return S_OK;
# ifdef VBOX_WITH_NEW_SYS_V_KEYGEN
return S_OK;
return VBOX_E_INVALID_OBJECT_STATE;
return S_OK;
return VBOX_E_INVALID_OBJECT_STATE;
#ifdef VBOX_WITH_RESOURCE_USAGE_API
return S_OK;
#ifdef VBOX_WITH_USB
return S_OK;
#ifdef VBOX_WITH_USB
return E_NOTIMPL;
#ifdef VBOX_WITH_USB
return E_NOTIMPL;
#ifdef VBOX_WITH_USB
return S_OK;
* Machine/SessionMachine lock).
#ifdef VBOX_WITH_USB
return S_OK;
++it;
return S_OK;
E_FAIL);
return S_OK;
E_FAIL);
if (aSuccess)
vrc);
#ifdef VBOX_WITH_GUEST_PROPS
using namespace guestProp;
++it)
return S_OK;
#ifdef VBOX_WITH_GUEST_PROPS
using namespace guestProp;
if (aFlags)
case MachineState_Paused:
case MachineState_Running:
case MachineState_Teleporting:
case MachineState_Saving:
++iter)
aFlags);
return S_OK;
bool terminated = false;
#if defined(RT_OS_WINDOWS)
terminated = true;
terminated = true;
if (val > 0)
terminated = true;
if (terminated)
return terminated;
if (!directControl)
return S_OK;
if (!directControl)
return S_OK;
if (!directControl)
return S_OK;
if (!directControl)
return S_OK;
if (!directControl)
return S_OK;
if (!directControl)
return S_OK;
if (!directControl)
return S_OK;
if (!directControl)
return S_OK;
if (!directControl)
return S_OK;
bool SessionMachine::hasMatchingUSBFilter(const ComObjPtr<HostUSBDevice> &aDevice, ULONG *aMaskedIfs)
#ifdef VBOX_WITH_USB
case MachineState_Starting:
case MachineState_Restoring:
case MachineState_Paused:
case MachineState_Running:
if (!directControl)
return E_FAIL;
AssertMsg(RTLockValidatorWriteLockGetCount(RTThreadSelf()) == 0, ("%d\n", RTLockValidatorWriteLockGetCount(RTThreadSelf())));
AssertMsg(RTLockValidatorReadLockGetCount(RTThreadSelf()) == 0, ("%d\n", RTLockValidatorReadLockGetCount(RTThreadSelf())));
if (!directControl)
return E_FAIL;
AssertMsg(RTLockValidatorWriteLockGetCount(RTThreadSelf()) == 0, ("%d\n", RTLockValidatorWriteLockGetCount(RTThreadSelf())));
AssertMsg(RTLockValidatorReadLockGetCount(RTThreadSelf()) == 0, ("%d\n", RTLockValidatorReadLockGetCount(RTThreadSelf())));
if (aSuccess)
// no need to check whether VirtualBox.xml needs saving also since
return rc;
++it)
NULL,
delete pMediumLockList;
return mrc;
E_FAIL);
int stsFlags = 0;
bool deleteSavedState = false;
|| mSnapshotData.mLastState >= MachineState_Running /** @todo Live Migration: clean up (lazy bird) */
unlockMedia();
deleteSavedState = true;
deleteSavedState = true;
if (deleteSavedState)
if (!fNeedsSaving)
fNeedsSaving = true;
if (fNeedsSaving)
SaveSettings(); // @todo r=dj why the public method? why first SaveSettings and then saveStateSettings?
return rc;
return S_OK;