MediumImpl.cpp revision 8dbf70ba2345e69b0b6d45c38cf1add0ef10591c
77b1a2d8b5dbe2c0b5200794914239fee3c8ee5dvboxsync * VirtualBox COM class implementation
d1aab951b0bd1de1a8a51daca46fce06daaed8d7vboxsync * Copyright (C) 2008-2010 Oracle Corporation
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * available from http://www.virtualbox.org. This file is free software;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
efff36b306e370346025647a158689021df2e1d1vboxsync////////////////////////////////////////////////////////////////////////////////
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync// Medium data definition
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync////////////////////////////////////////////////////////////////////////////////
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync/** Describes how a machine refers to this image. */
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync /** Equality predicate for stdc++. */
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync struct EqualsTo : public std::unary_function <BackRef, bool>
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync explicit EqualsTo(const Guid &aMachineId) : machineId(aMachineId) {}
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /** weak VirtualBox parent */
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync // pParent and llChildren are protected by VirtualBox::getMediaTreeLockHandle()
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync MediaList llChildren; // to add a child, just call push_back; to remove a child, call child->deparent() which does a lookup
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync /** the following members are invalid after changing UUID on open */
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync Utf8Str vdError; /*< Error remembered by the VD error callback. */
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync////////////////////////////////////////////////////////////////////////////////
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync////////////////////////////////////////////////////////////////////////////////
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync * Medium::Task class for asynchronous operations.
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync * @note Instances of this class must be created using new() because the
b5ad839a3757b305d4e98d7264da2b53c9cd27f0vboxsync * task thread function will delete them when the task is complete.
61b5982fad4660d0fe3dd6ceba9eda85eb32f7e8vboxsync * @note The constructor of this class adds a caller on the managed Medium
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync * object which is automatically released upon destruction.
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync /* Set up a per-operation progress interface, can be used freely (for
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync * binary operations you can use it either on the source or target). */
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync mVDIfCallsProgress.cbSize = sizeof(VDINTERFACEPROGRESS);
eeebcc1f7aedfdbcaf7c4dae90ad932d5d9c03c8vboxsync mVDIfCallsProgress.enmInterface = VDINTERFACETYPE_PROGRESS;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync "Medium::Task::vdInterfaceProgress",
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync // Make all destructors virtual. Just in case.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync static int fntMediumTask(RTTHREAD aThread, void *pvUser);
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync // Whether the caller needs to call VirtualBox::saveSettings() after
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync // the task function returns. Only used in synchronous (wait) mode;
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync // otherwise the task will save the settings itself.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync friend HRESULT Medium::runNow(Medium::Task*, bool*);
16a9adc14900ca18e6909679a579f6833425e030vboxsync static DECLCALLBACK(int) vdProgressCall(void *pvUser, unsigned uPercent);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync AssertReturnVoidStmt(aTarget != NULL, mRC = E_FAIL);
a0a5ab4e085a7ee5b95bdfae04cec7de95792c3cvboxsync mfKeepSourceMediumLockList(fKeepSourceMediumLockList),
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync mfKeepTargetMediumLockList(fKeepTargetMediumLockList)
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync AssertReturnVoidStmt(aTarget != NULL, mRC = E_FAIL);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* aParent may be NULL */
d5ea45cc92d7f1d3ade8189944531f665bfe8ed5vboxsync AssertReturnVoidStmt(aSourceMediumLockList != NULL, mRC = E_FAIL);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync AssertReturnVoidStmt(aTargetMediumLockList != NULL, mRC = E_FAIL);
468c2bcb36eb9a032f5dd0fcb34db10bd58e9996vboxsync if (!mfKeepSourceMediumLockList && mpSourceMediumLockList)
9496f2d398b49813176939d7a339ae513d5175efvboxsync if (!mfKeepTargetMediumLockList && mpTargetMediumLockList)
61d064a54f03596920c3918f58ecc7764074a5d8vboxsync AssertReturnVoidStmt(aMediumLockList != NULL, mRC = E_FAIL);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync AssertReturnVoidStmt(aMediumLockList != NULL, mRC = E_FAIL);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync for (MediaList::const_iterator it = mChildrenToReparent.begin();
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync for (MediaList::const_iterator it2 = mChildrenToReparent.begin();
a0a5ab4e085a7ee5b95bdfae04cec7de95792c3cvboxsync for (MediaList::const_iterator it = mChildrenToReparent.begin();
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync /* When mChildrenToReparent is empty then mParentForTarget is non-null.
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync * In other words: they are used in different cases. */
a0a5ab4e085a7ee5b95bdfae04cec7de95792c3cvboxsync * Thread function for time-consuming medium tasks.
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync * @param pvUser Pointer to the Medium::Task instance.
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync/* static */
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsyncDECLCALLBACK(int) Medium::Task::fntMediumTask(RTTHREAD aThread, void *pvUser)
a9f41cb889f53e8407561a6155052c441eb0fc5fvboxsync Medium::Task *pTask = static_cast<Medium::Task *>(pvUser);
9496f2d398b49813176939d7a339ae513d5175efvboxsync /* complete the progress if run asynchronously */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /* pTask is no longer needed, delete it. */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync return (int)rc;
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync * PFNVDPROGRESS callback handler for Task operations.
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync * @param pvUser Pointer to the Progress instance.
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync * @param uPercent Completetion precentage (0-100).
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsyncDECLCALLBACK(int) Medium::Task::vdProgressCall(void *pvUser, unsigned uPercent)
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync /* update the progress object, capping it at 99% as the final percent
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync * is used for additional operations like setting the UUIDs and similar. */
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync HRESULT rc = that->SetCurrentOperationProgress(uPercent * 99 / 100);
16a9adc14900ca18e6909679a579f6833425e030vboxsync * Implementation code for the "create base" task.
16a9adc14900ca18e6909679a579f6833425e030vboxsync * Implementation code for the "create diff" task.
16a9adc14900ca18e6909679a579f6833425e030vboxsync * Implementation code for the "clone" task.
16a9adc14900ca18e6909679a579f6833425e030vboxsync * Implementation code for the "compact" task.
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync * Implementation code for the "reset" task.
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync * Implementation code for the "delete" task.
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync * Implementation code for the "merge" task.
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync////////////////////////////////////////////////////////////////////////////////
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync// Medium constructor / destructor
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync////////////////////////////////////////////////////////////////////////////////
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync /* Initialize the callbacks of the VD error interface */
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync m->vdIfCallsError.cbSize = sizeof(VDINTERFACEERROR);
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync m->vdIfCallsError.enmInterface = VDINTERFACETYPE_ERROR;
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync /* Initialize the callbacks of the VD config interface */
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync m->vdIfCallsConfig.cbSize = sizeof(VDINTERFACECONFIG);
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync m->vdIfCallsConfig.enmInterface = VDINTERFACETYPE_CONFIG;
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync m->vdIfCallsConfig.pfnAreKeysValid = vdConfigAreKeysValid;
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync m->vdIfCallsConfig.pfnQuerySize = vdConfigQuerySize;
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync /* Initialize the callbacks of the VD TCP interface (we always use the host
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync * IP stack for now) */
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync m->vdIfCallsTcpNet.cbSize = sizeof(VDINTERFACETCPNET);
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync m->vdIfCallsTcpNet.enmInterface = VDINTERFACETYPE_TCPNET;
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync m->vdIfCallsTcpNet.pfnClientConnect = RTTcpClientConnect;
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync m->vdIfCallsTcpNet.pfnClientClose = RTTcpClientClose;
d1aab951b0bd1de1a8a51daca46fce06daaed8d7vboxsync m->vdIfCallsTcpNet.pfnSetSendCoalescing = RTTcpSetSendCoalescing;
d1aab951b0bd1de1a8a51daca46fce06daaed8d7vboxsync m->vdIfCallsTcpNet.pfnGetLocalAddress = RTTcpGetLocalAddress;
d1aab951b0bd1de1a8a51daca46fce06daaed8d7vboxsync m->vdIfCallsTcpNet.pfnGetPeerAddress = RTTcpGetPeerAddress;
d1aab951b0bd1de1a8a51daca46fce06daaed8d7vboxsync /* Initialize the per-disk interface chain */
d1aab951b0bd1de1a8a51daca46fce06daaed8d7vboxsync "Medium::vdInterfaceError",
d1aab951b0bd1de1a8a51daca46fce06daaed8d7vboxsync "Medium::vdInterfaceConfig",
d1aab951b0bd1de1a8a51daca46fce06daaed8d7vboxsync "Medium::vdInterfaceTcpNet",
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync * Initializes the hard disk object without creating or opening an associated
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * storage unit.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * For hard disks that don't have the VD_CAP_CREATE_FIXED or
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * VD_CAP_CREATE_DYNAMIC capability (and therefore cannot be created or deleted
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * with the means of VirtualBox) the associated storage unit is assumed to be
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * ready for use so the state of the hard disk object will be set to Created.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * @param aVirtualBox VirtualBox object.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * @param aLocation Storage unit location.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * @param pfNeedsSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync AssertReturn(aFormat != NULL && *aFormat != '\0', E_FAIL);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* Enclose the state transition NotReady->InInit->Ready */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* share VirtualBox weakly (parent remains NULL so far) */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* no storage yet */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* cannot be a host drive */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* No storage unit is created yet, no need to queryInfo() */
d8c1ea9ddf56bd31af2c314604613d9d695f6e89vboxsync if (m->formatObj->capabilities() & MediumFormatCapabilities_File)
d8c1ea9ddf56bd31af2c314604613d9d695f6e89vboxsync if (!(m->formatObj->capabilities() & ( MediumFormatCapabilities_CreateFixed
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* storage for hard disks of this format can neither be explicitly
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * created by VirtualBox nor deleted, so we place the hard disk to
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Created state here and also add it to the registry */
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync AutoWriteLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync rc = m->pVirtualBox->registerHardDisk(this, pfNeedsSaveSettings);
1e9e76e4273dcc2e3d560a0f3605c46f0013eb7bvboxsync /* Confirm a successful initialization when it's the case */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * Initializes the medium object by opening the storage unit at the specified
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * location. The enOpenMode parameter defines whether the image will be opened
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync * read/write or read-only.
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync * Note that the UUID, format and the parent of this medium will be
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync * determined when reading the medium storage unit, unless new values are
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync * specified by the parameters. If the detected or set parent is
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync * not known to VirtualBox, then this method will fail.
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync * @param aVirtualBox VirtualBox object.
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync * @param aLocation Storage unit location.
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync * @param enOpenMode Whether to open the image read/write or read-only.
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync * @param aDeviceType Device type of medium.
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync * @param aSetImageId Whether to set the image UUID or not.
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync * @param aImageId New image UUID if @aSetId is true. Empty string means
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync * create a new UUID, and a zero UUID is invalid.
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync * @param aSetParentId Whether to set the parent UUID or not.
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync * @param aParentId New parent UUID if @aSetParentId is true. Empty string
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync * means create a new UUID, and a zero UUID is valid.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* Enclose the state transition NotReady->InInit->Ready */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* share VirtualBox weakly (parent remains NULL so far) */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* there must be a storage unit */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* remember device type for correct unregistering later */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* cannot be a host drive */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* remember the open mode (defaults to ReadWrite) */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* save the new uuid values, will be used by queryInfo() */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* get all the information about the medium from the storage unit */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* if the storage unit is not accessible, it's not acceptable for the
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * newly opened media so convert this into an error */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync rc = setError(E_FAIL, m->strLastAccessError.c_str());
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* storage format must be detected by queryInfo() if the medium is accessible */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* Confirm a successful initialization when it's the case */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Initializes the medium object by loading its data from the given settings
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * node. In this mode, the image will always be opened read/write.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @param aVirtualBox VirtualBox object.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @param aParent Parent medium disk or NULL for a root (base) medium.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @param aDeviceType Device type of the medium.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @param aNode Configuration settings.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @note Locks VirtualBox for writing, the medium tree for writing.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync using namespace settings;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* Enclose the state transition NotReady->InInit->Ready */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* share VirtualBox and parent weakly */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* register with VirtualBox/parent early, since uninit() will
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * unconditionally unregister on failure */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync // differencing image: add to parent
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync AutoWriteLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* see below why we don't call queryInfo() (and therefore treat the medium
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * as inaccessible for now */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync m->strLastAccessError = tr("Accessibility check was not yet performed");
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* required */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* assume not a host drive */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* optional */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* required */
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync /// @todo handle host drive settings here as well?
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync /* optional, only for diffs, default is false;
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync * we can only auto-reset diff images, so they
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync * must not have a parent */
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync /* properties (after setting the format as it populates the map). Note that
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync * if some properties are not supported but preseint in the settings file,
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * they will still be read and accessible (for possible backward
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * compatibility; we can also clean them up from the XML upon next
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * XML format version change if we wish) */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync for (settings::PropertiesMap::const_iterator it = data.properties.begin();
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync /* required */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* type is only for base hard disks */
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync /* remember device type for correct unregistering later */
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync LogFlowThisFunc(("m->strLocationFull='%s', m->strFormat=%s, m->id={%RTuuid}\n",
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync m->strLocationFull.raw(), m->strFormat.raw(), m->id.raw()));
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync /* Don't call queryInfo() for registered media to prevent the calling
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync * thread (i.e. the VirtualBox server startup thread) from an unexpected
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * freeze but mark it as initially inaccessible instead. The vital UUID,
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync * location and format properties are read from the registry file above; to
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync * get the actual state and the rest of the data, the user will have to call
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync * COMGETTER(State). */
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync AutoWriteLock treeLock(aVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync /* load all children */
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync for (settings::MediaList::const_iterator it = data.llChildren.begin();
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync this, // parent
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync rc = m->pVirtualBox->registerHardDisk(pHD, NULL /*pfNeedsSaveSettings*/);
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync /* Confirm a successful initialization when it's the case */
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync * Initializes the medium object by providing the host drive information.
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync * Not used for anything but the host floppy/host DVD case.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * @todo optimize all callers to avoid reconstructing objects with the same
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync * information over and over again - in the typical case each VM referring to
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync * a particular host drive has its own instance.
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync * @param aVirtualBox VirtualBox object.
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync * @param aDeviceType Device type of the medium.
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync * @param aLocation Location of the host drive.
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync * @param aDescription Comment for this host drive.
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync * @note Locks VirtualBox lock for writing.
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync ComAssertRet(aDeviceType == DeviceType_DVD || aDeviceType == DeviceType_Floppy, E_INVALIDARG);
30c39307775310ba50de9d9b74f1ea9e12524102vboxsync /* Enclose the state transition NotReady->InInit->Ready */
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync /* share VirtualBox weakly (parent remains NULL so far) */
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync /* fake up a UUID which is unique, but also reproducible */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* use device name, adjusted to the end of uuid, shortened if necessary */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync memcpy(&uuid.au8[4], loc.raw() + (cbLocation - 12), 12);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync memcpy(&uuid.au8[4 + 12 - cbLocation], loc.raw(), cbLocation);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync/// @todo generate uuid (similarly to host network interface uuid) from location and device type
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * Uninitializes the instance.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * Called either from FinalRelease() or by the parent when it gets destroyed.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * @note All children of this hard disk get uninitialized by calling their
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * uninit() methods.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * @note Caller must hold the tree lock of the medium tree this medium is on.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* Enclose the state transition Ready->InUninit->NotReady */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* remove the caller reference we added in setFormat() */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* we are being uninitialized after've been deleted by merge.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * Reparenting has already been done so don't touch it here (we are
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * now orphans and removeDependentChild() will assert) */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync m->llChildren.clear(); // this unsets all the ComPtrs and probably calls delete
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync // this is a differencing disk: then remove it from the parent's children list
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * Internal helper that removes "this" from the list of children of its
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * parent. Used in uninit() and other places when reparenting is necessary.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * The caller must hold the hard disk tree lock!
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * Internal helper that removes "this" from the list of children of its
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * parent. Used in uninit() and other places when reparenting is necessary.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * The caller must hold the hard disk tree lock!
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncvoid Medium::setParent(const ComObjPtr<Medium> &pParent)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync////////////////////////////////////////////////////////////////////////////////
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync// IMedium public methods
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync////////////////////////////////////////////////////////////////////////////////
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
d8c1ea9ddf56bd31af2c314604613d9d695f6e89vboxsyncSTDMETHODIMP Medium::COMGETTER(Description)(BSTR *aDescription)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
b0b15690f00527424b2d5fb88456d747252322f7vboxsyncSTDMETHODIMP Medium::COMSETTER(Description)(IN_BSTR aDescription)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync// AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /// @todo update m->description and save the global registry (and local
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /// registries of portable VMs referring to this medium), this will also
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /// require to add the mRegistered flag to data
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncSTDMETHODIMP Medium::COMGETTER(State)(MediumState_T *aState)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncSTDMETHODIMP Medium::COMGETTER(Location)(BSTR *aLocation)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncSTDMETHODIMP Medium::COMSETTER(Location)(IN_BSTR aLocation)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /// @todo NEWMEDIA for file names, add the default extension if no extension
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /// is present (using the information from the VD backend which also implies
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /// that one more parameter should be passed to setLocation() requesting
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /// that functionality since it is only allwed when called from this method
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /// @todo NEWMEDIA rename the file and set m->location on success, then save
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /// the global registry (and local registries of portable VMs referring to
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /// this medium), this will also require to add the mRegistered flag to data
51a01524909c95ee04b636218b6a89b29fb81825vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
51a01524909c95ee04b636218b6a89b29fb81825vboxsyncSTDMETHODIMP Medium::COMGETTER(DeviceType)(DeviceType_T *aDeviceType)
51a01524909c95ee04b636218b6a89b29fb81825vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncSTDMETHODIMP Medium::COMGETTER(HostDrive)(BOOL *aHostDrive)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncSTDMETHODIMP Medium::COMGETTER(Size)(ULONG64 *aSize)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
b0b15690f00527424b2d5fb88456d747252322f7vboxsyncSTDMETHODIMP Medium::COMGETTER(Format)(BSTR *aFormat)
51a01524909c95ee04b636218b6a89b29fb81825vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* no need to lock, m->strFormat is const */
51a01524909c95ee04b636218b6a89b29fb81825vboxsyncSTDMETHODIMP Medium::COMGETTER(MediumFormat)(IMediumFormat **aMediumFormat)
51a01524909c95ee04b636218b6a89b29fb81825vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
51a01524909c95ee04b636218b6a89b29fb81825vboxsync /* no need to lock, m->formatObj is const */
51a01524909c95ee04b636218b6a89b29fb81825vboxsyncSTDMETHODIMP Medium::COMGETTER(Type)(MediumType_T *aType)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncSTDMETHODIMP Medium::COMSETTER(Type)(MediumType_T aType)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
51a01524909c95ee04b636218b6a89b29fb81825vboxsync // we access mParent and members
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync AutoMultiWriteLock2 mlock(&m->pVirtualBox->getMediaTreeLockHandle(), this->lockHandle() COMMA_LOCKVAL_SRC_POS);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /** @todo implement this case later */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync CheckComArgExpr(aType, aType != MediumType_Shareable);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* Nothing to do */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* cannot change the type of a differencing hard disk */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync tr("Cannot change the type of hard disk '%s' because it is a differencing hard disk"),
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* cannot change the type of a hard disk being in use by more than one VM */
b0b15690f00527424b2d5fb88456d747252322f7vboxsync tr("Cannot change the type of hard disk '%s' because it is attached to %d virtual machines"),
b0b15690f00527424b2d5fb88456d747252322f7vboxsync /* normal can be easily converted to immutable and vice versa even
b0b15690f00527424b2d5fb88456d747252322f7vboxsync * if they have children as long as they are not attached to any
b0b15690f00527424b2d5fb88456d747252322f7vboxsync * machine themselves */
b0b15690f00527424b2d5fb88456d747252322f7vboxsync /* cannot change to writethrough or shareable if there are children */
b0b15690f00527424b2d5fb88456d747252322f7vboxsync tr("Cannot change type for hard disk '%s' since it has %d child hard disk(s)"),
b0b15690f00527424b2d5fb88456d747252322f7vboxsync // saveSettings needs vbox lock
b0b15690f00527424b2d5fb88456d747252322f7vboxsync AutoWriteLock alock(m->pVirtualBox COMMA_LOCKVAL_SRC_POS);
b0b15690f00527424b2d5fb88456d747252322f7vboxsyncSTDMETHODIMP Medium::COMGETTER(Parent)(IMedium **aParent)
b0b15690f00527424b2d5fb88456d747252322f7vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
b0b15690f00527424b2d5fb88456d747252322f7vboxsync /* we access mParent */
b0b15690f00527424b2d5fb88456d747252322f7vboxsync AutoReadLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
b0b15690f00527424b2d5fb88456d747252322f7vboxsyncSTDMETHODIMP Medium::COMGETTER(Children)(ComSafeArrayOut(IMedium *, aChildren))
b0b15690f00527424b2d5fb88456d747252322f7vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
b0b15690f00527424b2d5fb88456d747252322f7vboxsync /* we access children */
b0b15690f00527424b2d5fb88456d747252322f7vboxsync AutoReadLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
b0b15690f00527424b2d5fb88456d747252322f7vboxsync SafeIfaceArray<IMedium> children(this->getChildren());
b0b15690f00527424b2d5fb88456d747252322f7vboxsyncSTDMETHODIMP Medium::COMGETTER(Base)(IMedium **aBase)
b0b15690f00527424b2d5fb88456d747252322f7vboxsync /* base() will do callers/locking */
b0b15690f00527424b2d5fb88456d747252322f7vboxsyncSTDMETHODIMP Medium::COMGETTER(ReadOnly)(BOOL *aReadOnly)
b0b15690f00527424b2d5fb88456d747252322f7vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
b0b15690f00527424b2d5fb88456d747252322f7vboxsync /* isRadOnly() will do locking */
b0b15690f00527424b2d5fb88456d747252322f7vboxsyncSTDMETHODIMP Medium::COMGETTER(LogicalSize)(ULONG64 *aLogicalSize)
b0b15690f00527424b2d5fb88456d747252322f7vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
b0b15690f00527424b2d5fb88456d747252322f7vboxsync /* we access mParent */
b0b15690f00527424b2d5fb88456d747252322f7vboxsync AutoReadLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
b0b15690f00527424b2d5fb88456d747252322f7vboxsync /* We assume that some backend may decide to return a meaningless value in
b0b15690f00527424b2d5fb88456d747252322f7vboxsync * response to VDGetSize() for differencing hard disks and therefore
b0b15690f00527424b2d5fb88456d747252322f7vboxsync * always ask the base hard disk ourselves. */
b0b15690f00527424b2d5fb88456d747252322f7vboxsync /* base() will do callers/locking */
b0b15690f00527424b2d5fb88456d747252322f7vboxsync return getBase()->COMGETTER(LogicalSize)(aLogicalSize);
b0b15690f00527424b2d5fb88456d747252322f7vboxsyncSTDMETHODIMP Medium::COMGETTER(AutoReset)(BOOL *aAutoReset)
b0b15690f00527424b2d5fb88456d747252322f7vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncSTDMETHODIMP Medium::COMSETTER(AutoReset)(BOOL aAutoReset)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
eeebcc1f7aedfdbcaf7c4dae90ad932d5d9c03c8vboxsync // saveSettings needs vbox lock
eeebcc1f7aedfdbcaf7c4dae90ad932d5d9c03c8vboxsync AutoWriteLock alock(m->pVirtualBox COMMA_LOCKVAL_SRC_POS);
eeebcc1f7aedfdbcaf7c4dae90ad932d5d9c03c8vboxsyncSTDMETHODIMP Medium::COMGETTER(LastAccessError)(BSTR *aLastAccessError)
eeebcc1f7aedfdbcaf7c4dae90ad932d5d9c03c8vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncSTDMETHODIMP Medium::COMGETTER(MachineIds)(ComSafeArrayOut(BSTR,aMachineIds))
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync for (BackRefList::const_iterator it = m->backRefs.begin();
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync machineIds.detachTo(ComSafeArrayOutArg(aMachineIds));
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsyncSTDMETHODIMP Medium::RefreshState(MediumState_T *aState)
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync /* queryInfo() locks this for writing. */
1fdf058ef3f645ee13c9957807e401ac3c9bc65bvboxsyncSTDMETHODIMP Medium::GetSnapshotIds(IN_BSTR aMachineId,
1fdf058ef3f645ee13c9957807e401ac3c9bc65bvboxsync CheckComArgExpr(aMachineId, Guid(aMachineId).isEmpty() == false);
1fdf058ef3f645ee13c9957807e401ac3c9bc65bvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1fdf058ef3f645ee13c9957807e401ac3c9bc65bvboxsync for (BackRefList::const_iterator it = m->backRefs.begin();
1fdf058ef3f645ee13c9957807e401ac3c9bc65bvboxsync /* if the medium is attached to the machine in the current state, we
1fdf058ef3f645ee13c9957807e401ac3c9bc65bvboxsync * return its ID as the first element of the array */
1fdf058ef3f645ee13c9957807e401ac3c9bc65bvboxsync it->machineId.toUtf16().detachTo(&snapshotIds[j++]);
1fdf058ef3f645ee13c9957807e401ac3c9bc65bvboxsync for (BackRef::GuidList::const_iterator jt = it->llSnapshotIds.begin();
1fdf058ef3f645ee13c9957807e401ac3c9bc65bvboxsync snapshotIds.detachTo(ComSafeArrayOutArg(aSnapshotIds));
1fdf058ef3f645ee13c9957807e401ac3c9bc65bvboxsync * @note @a aState may be NULL if the state value is not needed (only for
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * in-process calls).
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsyncSTDMETHODIMP Medium::LockRead(MediumState_T *aState)
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync /* Wait for a concurrently running queryInfo() to complete */
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync RTSemEventMultiWait(m->queryInfoSem, RT_INDEFINITE_WAIT);
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync /* return the current state before */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync ComAssertMsgBreak(m->readers != 0, ("Counter overflow"), rc = E_FAIL);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* Remember pre-lock state */
16a9adc14900ca18e6909679a579f6833425e030vboxsync LogFlowThisFunc(("Okay - prev state=%d readers=%d\n", m->state, m->readers));
16a9adc14900ca18e6909679a579f6833425e030vboxsync LogFlowThisFunc(("Failing - state=%d\n", m->state));
16a9adc14900ca18e6909679a579f6833425e030vboxsync * @note @a aState may be NULL if the state value is not needed (only for
16a9adc14900ca18e6909679a579f6833425e030vboxsync * in-process calls).
e4f367251aede667a6de69baa54ef9eb5f150871vboxsyncSTDMETHODIMP Medium::UnlockRead(MediumState_T *aState)
16a9adc14900ca18e6909679a579f6833425e030vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync /* Reset the state after the last reader */
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync if (m->readers == 0)
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync /* There are cases where we inject the deleting state into
203cad92999b4792bf61b4b65e1e2abfe08f5664vboxsync * a medium locked for reading. Make sure #unmarkForDeletion()
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync * gets the right state afterwards. */
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync LogFlowThisFunc(("Failing - state=%d\n", m->state));
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync /* return the current state after */
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync * @note @a aState may be NULL if the state value is not needed (only for
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync * in-process calls).
f4fd9b62ec1cb6bb79fc7432a2d1a4c5f7c63bfcvboxsyncSTDMETHODIMP Medium::LockWrite(MediumState_T *aState)
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync /* Wait for a concurrently running queryInfo() to complete */
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync RTSemEventMultiWait(m->queryInfoSem, RT_INDEFINITE_WAIT);
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync /* return the current state before */
e18d16f31765f000e2a4a111a3df6d211cd825f1vboxsync LogFlowThisFunc(("Okay - prev state=%d locationFull=%s\n", m->state, getLocationFull().c_str()));
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync LogFlowThisFunc(("Failing - state=%d locationFull=%s\n", m->state, getLocationFull().c_str()));
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * @note @a aState may be NULL if the state value is not needed (only for
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * in-process calls).
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsyncSTDMETHODIMP Medium::UnlockWrite(MediumState_T *aState)
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync /* There are cases where we inject the deleting state into
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync * a medium locked for writing. Make sure #unmarkForDeletion()
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * gets the right state afterwards. */
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync LogFlowThisFunc(("new state=%d locationFull=%s\n", m->state, getLocationFull().c_str()));
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync LogFlowThisFunc(("Failing - state=%d locationFull=%s\n", m->state, getLocationFull().c_str()));
e04eeee1b306d610b0441cee9bf1c750100254d5vboxsync /* return the current state after */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync // we're accessing parent/child and backrefs, so lock the tree first, then ourselves
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync AutoMultiWriteLock2 multilock(&m->pVirtualBox->getMediaTreeLockHandle(),
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync tr("Medium '%s' is attached to %d virtual machines"),
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync /* perform extra media-dependent close checks */
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync /* remove from the list of known media before performing actual
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * uninitialization (to keep the media registry consistent on
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * failure to do so) */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync rc = unregisterWithVirtualBox(&fNeedsSaveSettings);
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync // make a copy of VirtualBox pointer which gets nulled by uninit()
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync // leave the AutoCaller, as otherwise uninit() will simply hang
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* Keep the locks held until after uninit, as otherwise the consistency
f4aad55f8addd816ef005845842a2418bbdc3ea2vboxsync * of the medium tree cannot be guaranteed. */
e2ebb3d022edb845fd1158d6338e3def1d0e2159vboxsync AutoWriteLock vboxlock(pVirtualBox COMMA_LOCKVAL_SRC_POS);
1bf320fa7c84120347a65cdbbf4d673f50abdbaevboxsyncSTDMETHODIMP Medium::GetProperty(IN_BSTR aName, BSTR *aValue)
47579c4cc64e7dff9b4de48841a2c4df3b96ab38vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
60a713666695ab3f2f6a0e43288c38e72f697d41vboxsync Data::PropertyMap::const_iterator it = m->properties.find(Bstr(aName));
47579c4cc64e7dff9b4de48841a2c4df3b96ab38vboxsyncSTDMETHODIMP Medium::SetProperty(IN_BSTR aName, IN_BSTR aValue)
47579c4cc64e7dff9b4de48841a2c4df3b96ab38vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
47579c4cc64e7dff9b4de48841a2c4df3b96ab38vboxsync Data::PropertyMap::iterator it = m->properties.find(Bstr(aName));
009d45aa55691312278d41edb20154dc208d9cd8vboxsync // saveSettings needs vbox lock
009d45aa55691312278d41edb20154dc208d9cd8vboxsync AutoWriteLock alock(m->pVirtualBox COMMA_LOCKVAL_SRC_POS);
9496f2d398b49813176939d7a339ae513d5175efvboxsync CheckComArgOutSafeArrayPointerValid(aReturnValues);
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
eeebcc1f7aedfdbcaf7c4dae90ad932d5d9c03c8vboxsync /// @todo make use of aNames according to the documentation
19badc2a6bdaeb1208f71b7de06feec1aa7c59c9vboxsync for (Data::PropertyMap::const_iterator it = m->properties.begin();
009d45aa55691312278d41edb20154dc208d9cd8vboxsync values.detachTo(ComSafeArrayOutArg(aReturnValues));
9496f2d398b49813176939d7a339ae513d5175efvboxsyncSTDMETHODIMP Medium::SetProperties(ComSafeArrayIn(IN_BSTR, aNames),
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
eeebcc1f7aedfdbcaf7c4dae90ad932d5d9c03c8vboxsync com::SafeArray<IN_BSTR> names(ComSafeArrayInArg(aNames));
eeebcc1f7aedfdbcaf7c4dae90ad932d5d9c03c8vboxsync com::SafeArray<IN_BSTR> values(ComSafeArrayInArg(aValues));
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync /* first pass: validate names */
009d45aa55691312278d41edb20154dc208d9cd8vboxsync if (m->properties.find(Bstr(names[i])) == m->properties.end())
009d45aa55691312278d41edb20154dc208d9cd8vboxsync /* second pass: assign */
009d45aa55691312278d41edb20154dc208d9cd8vboxsync Data::PropertyMap::iterator it = m->properties.find(Bstr(names[i]));
fc78e01f665145ab3641c5f8095e9ae984ddcb84vboxsync // saveSettings needs vbox lock
009d45aa55691312278d41edb20154dc208d9cd8vboxsync AutoWriteLock alock(m->pVirtualBox COMMA_LOCKVAL_SRC_POS);
bdaae7f756db4f5cf2d62f495a2a80acaf581a0cvboxsyncSTDMETHODIMP Medium::CreateBaseStorage(ULONG64 aLogicalSize,
fc78e01f665145ab3641c5f8095e9ae984ddcb84vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
f4aad55f8addd816ef005845842a2418bbdc3ea2vboxsync aVariant = (MediumVariant_T)((unsigned)aVariant & (unsigned)~MediumVariant_Diff);
f4aad55f8addd816ef005845842a2418bbdc3ea2vboxsync && !(m->formatObj->capabilities() & MediumFormatCapabilities_CreateDynamic))
f4aad55f8addd816ef005845842a2418bbdc3ea2vboxsync tr("Hard disk format '%s' does not support dynamic storage creation"),
f4aad55f8addd816ef005845842a2418bbdc3ea2vboxsync && !(m->formatObj->capabilities() & MediumFormatCapabilities_CreateDynamic))
f4aad55f8addd816ef005845842a2418bbdc3ea2vboxsync tr("Hard disk format '%s' does not support fixed storage creation"),
009d45aa55691312278d41edb20154dc208d9cd8vboxsync static_cast<IMedium*>(this),
009d45aa55691312278d41edb20154dc208d9cd8vboxsync ? BstrFmt(tr("Creating fixed hard disk storage unit '%s'"), m->strLocationFull.raw())
009d45aa55691312278d41edb20154dc208d9cd8vboxsync : BstrFmt(tr("Creating dynamic hard disk storage unit '%s'"), m->strLocationFull.raw()),
009d45aa55691312278d41edb20154dc208d9cd8vboxsync /* setup task object to carry out the operation asynchronously */
009d45aa55691312278d41edb20154dc208d9cd8vboxsync pTask = new Medium::CreateBaseTask(this, pProgress, aLogicalSize,
009d45aa55691312278d41edb20154dc208d9cd8vboxsyncSTDMETHODIMP Medium::DeleteStorage(IProgress **aProgress)
009d45aa55691312278d41edb20154dc208d9cd8vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
009d45aa55691312278d41edb20154dc208d9cd8vboxsync false /* aWait */,
f4aad55f8addd816ef005845842a2418bbdc3ea2vboxsync AutoWriteLock vboxlock(m->pVirtualBox COMMA_LOCKVAL_SRC_POS);
f4aad55f8addd816ef005845842a2418bbdc3ea2vboxsyncSTDMETHODIMP Medium::CreateDiffStorage(IMedium *aTarget,
10e818af327731667e40ed25ee3e70ab5ea2cc4cvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
10e818af327731667e40ed25ee3e70ab5ea2cc4cvboxsync ComObjPtr<Medium> diff = static_cast<Medium*>(aTarget);
10e818af327731667e40ed25ee3e70ab5ea2cc4cvboxsync /* Apply the normal locking logic to the entire chain. */
10e818af327731667e40ed25ee3e70ab5ea2cc4cvboxsync MediumLockList *pMediumLockList(new MediumLockList());
10e818af327731667e40ed25ee3e70ab5ea2cc4cvboxsync HRESULT rc = diff->createMediumLockList(true /* fFailIfInaccessible */,
10e818af327731667e40ed25ee3e70ab5ea2cc4cvboxsync true /* fMediumLockWrite */,
10e818af327731667e40ed25ee3e70ab5ea2cc4cvboxsync rc = createDiffStorage(diff, aVariant, pMediumLockList, &pProgress,
baacecc94a2d23b6f5086739c08cf06d6b357d0avboxsyncSTDMETHODIMP Medium::MergeTo(IMedium *aTarget, IProgress **aProgress)
baacecc94a2d23b6f5086739c08cf06d6b357d0avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
baacecc94a2d23b6f5086739c08cf06d6b357d0avboxsync ComObjPtr<Medium> pTarget = static_cast<Medium*>(aTarget);
baacecc94a2d23b6f5086739c08cf06d6b357d0avboxsync rc = prepareMergeTo(pTarget, NULL, NULL, true, fMergeForward,
baacecc94a2d23b6f5086739c08cf06d6b357d0avboxsync pParentForTarget, childrenToReparent, pMediumLockList);
f4fd9b62ec1cb6bb79fc7432a2d1a4c5f7c63bfcvboxsync rc = mergeTo(pTarget, fMergeForward, pParentForTarget, childrenToReparent,
baacecc94a2d23b6f5086739c08cf06d6b357d0avboxsync cancelMergeTo(childrenToReparent, pMediumLockList);
a39ea3668b7019c23a68936259545f9b71bce1aavboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
da3503c04ce76e653401396fe2795a9bc2427a1dvboxsync ComObjPtr<Medium> pTarget = static_cast<Medium*>(aTarget);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync // locking: we need the tree lock first because we access parent pointers
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync AutoReadLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync // and we need to write-lock the images involved
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync AutoMultiWriteLock3 alock(this, pTarget, pParent COMMA_LOCKVAL_SRC_POS);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /* Build the source lock list. */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync MediumLockList *pSourceMediumLockList(new MediumLockList());
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync rc = createMediumLockList(true /* fFailIfInaccessible */,
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync false /* fMediumLockWrite */,
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /* Build the target lock list (including the to-be parent chain). */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync MediumLockList *pTargetMediumLockList(new MediumLockList());
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync rc = pTarget->createMediumLockList(true /* fFailIfInaccessible */,
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync true /* fMediumLockWrite */,
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync static_cast <IMedium *>(this),
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync BstrFmt(tr("Creating clone hard disk '%s'"), pTarget->m->strLocationFull.raw()),
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /* setup task object to carry out the operation asynchronously */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync pTask = new Medium::CloneTask(this, pProgress, pTarget, aVariant,
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync /* We need to lock both the current object, and the tree lock (would
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync * cause a lock order violation otherwise) for createMediumLockList. */
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync AutoMultiWriteLock2 multilock(&m->pVirtualBox->getMediaTreeLockHandle(),
ff5f52502d5dff6a8f353c85702ef49cc25c2f6bvboxsync /* Build the medium lock list. */
ff5f52502d5dff6a8f353c85702ef49cc25c2f6bvboxsync MediumLockList *pMediumLockList(new MediumLockList());
ff5f52502d5dff6a8f353c85702ef49cc25c2f6bvboxsync rc = createMediumLockList(true /* fFailIfInaccessible */ ,
ff5f52502d5dff6a8f353c85702ef49cc25c2f6bvboxsync true /* fMediumLockWrite */,
c7ff622115966b69b482bd2896662e40d823b22fvboxsync static_cast <IMedium *>(this),
c7ff622115966b69b482bd2896662e40d823b22fvboxsync BstrFmt(tr("Compacting hard disk '%s'"), m->strLocationFull.raw()),
16a9adc14900ca18e6909679a579f6833425e030vboxsync /* setup task object to carry out the operation asynchronously */
16a9adc14900ca18e6909679a579f6833425e030vboxsync pTask = new Medium::CompactTask(this, pProgress, pMediumLockList);
76364cddabfeb143dad91862d41a5638d8860b25vboxsyncSTDMETHODIMP Medium::Resize(ULONG64 aLogicalSize, IProgress **aProgress)
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* canClose() needs the tree lock */
681fd85cc7cd49e9cf66a917d6ae9ff36eb7d9e9vboxsync AutoMultiWriteLock2 multilock(&m->pVirtualBox->getMediaTreeLockHandle(),
681fd85cc7cd49e9cf66a917d6ae9ff36eb7d9e9vboxsync LogFlowThisFunc(("ENTER for medium %s\n", m->strLocationFull.c_str()));
090d729e786b999dc285f8ea267f9effd1319544vboxsync /* Build the medium lock list. */
61d064a54f03596920c3918f58ecc7764074a5d8vboxsync MediumLockList *pMediumLockList(new MediumLockList());
16a9adc14900ca18e6909679a579f6833425e030vboxsync rc = createMediumLockList(true /* fFailIfInaccessible */,
16a9adc14900ca18e6909679a579f6833425e030vboxsync true /* fMediumLockWrite */,
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync static_cast<IMedium*>(this),
e2ebb3d022edb845fd1158d6338e3def1d0e2159vboxsync BstrFmt(tr("Resetting differencing hard disk '%s'"), m->strLocationFull.raw()),
9496f2d398b49813176939d7a339ae513d5175efvboxsync /* setup task object to carry out the operation asynchronously */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync pTask = new Medium::ResetTask(this, pProgress, pMediumLockList);
cab115cfa31c584def7069312a1e23c3fc88533bvboxsync /* Note: on success, the task will unlock this */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync////////////////////////////////////////////////////////////////////////////////
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync// Medium internal methods
009d45aa55691312278d41edb20154dc208d9cd8vboxsync////////////////////////////////////////////////////////////////////////////////
6437cb19ad6d607a74ccf8d8f25c7e7af761b316vboxsync * Internal method to return the medium's parent medium. Must have caller + locking!
c28fa006ba669ad8f26ae31d00a338379c04ea1bvboxsync * Internal method to return the medium's list of child media. Must have caller + locking!
6437cb19ad6d607a74ccf8d8f25c7e7af761b316vboxsync * Internal method to return the medium's GUID. Must have caller + locking!
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Internal method to return the medium's GUID. Must have caller + locking!
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync * Internal method to return the medium's location. Must have caller + locking!
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync * Internal method to return the medium's full location. Must have caller + locking!
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync * Internal method to return the medium's format string. Must have caller + locking!
24a0cc1776a88752cc25446a98e2a3881e623216vboxsync * Internal method to return the medium's format object. Must have caller + locking!
24a0cc1776a88752cc25446a98e2a3881e623216vboxsyncconst ComObjPtr<MediumFormat> & Medium::getMediumFormat() const
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync * Internal method to return the medium's size. Must have caller + locking!
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync * Adds the given machine and optionally the snapshot to the list of the objects
61d064a54f03596920c3918f58ecc7764074a5d8vboxsync * this image is attached to.
61d064a54f03596920c3918f58ecc7764074a5d8vboxsync * @param aMachineId Machine ID.
61d064a54f03596920c3918f58ecc7764074a5d8vboxsync * @param aSnapshotId Snapshot ID; when non-empty, adds a snapshot attachment.
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync LogFlowThisFunc(("ENTER, aMachineId: {%RTuuid}, aSnapshotId: {%RTuuid}\n", aMachineId.raw(), aSnapshotId.raw()));
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync tr("Cannot attach hard disk '%s' {%RTuuid}: %u differencing child hard disk(s) are being created"),
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync BackRefList::iterator it = std::find_if(m->backRefs.begin(),
009d45aa55691312278d41edb20154dc208d9cd8vboxsync // if the caller has not supplied a snapshot ID, then we're attaching
009d45aa55691312278d41edb20154dc208d9cd8vboxsync // to a machine a medium which represents the machine's current state,
009d45aa55691312278d41edb20154dc208d9cd8vboxsync // so set the flag
b5ad839a3757b305d4e98d7264da2b53c9cd27f0vboxsync /* sanity: no duplicate attachments */
e2ebb3d022edb845fd1158d6338e3def1d0e2159vboxsync // otherwise: a snapshot medium is being attached
e2ebb3d022edb845fd1158d6338e3def1d0e2159vboxsync /* sanity: no duplicate attachments */
e2ebb3d022edb845fd1158d6338e3def1d0e2159vboxsync for (BackRef::GuidList::const_iterator jt = it->llSnapshotIds.begin();
c13422b6c2690d4243041112362ef95e0ac23e79vboxsync tr("Cannot attach medium '%s' {%RTuuid} from snapshot '%RTuuid': medium is already in use by this snapshot!"),
ee00a0b29854e7f513198772bccb6650f6dd2184vboxsync * Removes the given machine and optionally the snapshot from the list of the
ee00a0b29854e7f513198772bccb6650f6dd2184vboxsync * objects this image is attached to.
ee00a0b29854e7f513198772bccb6650f6dd2184vboxsync * @param aMachineId Machine ID.
ee00a0b29854e7f513198772bccb6650f6dd2184vboxsync * @param aSnapshotId Snapshot ID; when non-empty, removes the snapshot
ee00a0b29854e7f513198772bccb6650f6dd2184vboxsync * attachment.
681fd85cc7cd49e9cf66a917d6ae9ff36eb7d9e9vboxsync std::find_if(m->backRefs.begin(), m->backRefs.end(),
681fd85cc7cd49e9cf66a917d6ae9ff36eb7d9e9vboxsync /* remove the current state attachment */
681fd85cc7cd49e9cf66a917d6ae9ff36eb7d9e9vboxsync /* remove the snapshot attachment */
681fd85cc7cd49e9cf66a917d6ae9ff36eb7d9e9vboxsync std::find(it->llSnapshotIds.begin(), it->llSnapshotIds.end(), aSnapshotId);
681fd85cc7cd49e9cf66a917d6ae9ff36eb7d9e9vboxsync AssertReturn(jt != it->llSnapshotIds.end(), E_FAIL);
681fd85cc7cd49e9cf66a917d6ae9ff36eb7d9e9vboxsync /* if the backref becomes empty, remove it */
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync if (it->fInCurState == false && it->llSnapshotIds.size() == 0)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Internal method to return the medium's list of backrefs. Must have caller + locking!
16a9adc14900ca18e6909679a579f6833425e030vboxsyncconst Guid* Medium::getFirstMachineBackrefId() const
61b5982fad4660d0fe3dd6ceba9eda85eb32f7e8vboxsyncconst Guid* Medium::getFirstMachineBackrefSnapshotId() const
16a9adc14900ca18e6909679a579f6833425e030vboxsync * Debugging helper that gets called after VirtualBox initialization that writes all
16a9adc14900ca18e6909679a579f6833425e030vboxsync * machine backreferences to the debug log.
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync LogFlowThisFunc(("Dumping backrefs for medium '%s':\n", m->strLocationFull.raw()));
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync for (BackRefList::iterator it2 = m->backRefs.begin();
16a9adc14900ca18e6909679a579f6833425e030vboxsync LogFlowThisFunc((" Backref from machine {%RTuuid} (fInCurState: %d)\n", ref.machineId.raw(), ref.fInCurState));
16a9adc14900ca18e6909679a579f6833425e030vboxsync for (BackRef::GuidList::const_iterator jt2 = it2->llSnapshotIds.begin();
ee00a0b29854e7f513198772bccb6650f6dd2184vboxsync LogFlowThisFunc((" Backref from snapshot {%RTuuid}\n", id.raw()));
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync * Checks if the given change of \a aOldPath to \a aNewPath affects the location
6437cb19ad6d607a74ccf8d8f25c7e7af761b316vboxsync * of this media and updates it if necessary to reflect the new location.
16a9adc14900ca18e6909679a579f6833425e030vboxsync * @param aOldPath Old path (full).
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsync * @param aNewPath New path (full).
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * @note Locks this object for writing.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsyncHRESULT Medium::updatePath(const char *aOldPath, const char *aNewPath)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsync LogFlowThisFunc(("locationFull.before='%s'\n", m->strLocationFull.raw()));
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync const char *pcszMediumPath = m->strLocationFull.c_str();
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync LogFlowThisFunc(("locationFull.after='%s'\n", m->strLocationFull.raw()));
16a9adc14900ca18e6909679a579f6833425e030vboxsync * Checks if the given change of \a aOldPath to \a aNewPath affects the location
16a9adc14900ca18e6909679a579f6833425e030vboxsync * of this hard disk or any its child and updates the paths if necessary to
16a9adc14900ca18e6909679a579f6833425e030vboxsync * reflect the new location.
16a9adc14900ca18e6909679a579f6833425e030vboxsync * @param aOldPath Old path (full).
16a9adc14900ca18e6909679a579f6833425e030vboxsync * @param aNewPath New path (full).
16a9adc14900ca18e6909679a579f6833425e030vboxsync * @note Locks the medium tree for reading, this object and all children for writing.
16a9adc14900ca18e6909679a579f6833425e030vboxsyncvoid Medium::updatePaths(const char *aOldPath, const char *aNewPath)
16a9adc14900ca18e6909679a579f6833425e030vboxsync /* we access children() */
16a9adc14900ca18e6909679a579f6833425e030vboxsync AutoReadLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
16a9adc14900ca18e6909679a579f6833425e030vboxsync /* update paths of all children */
16a9adc14900ca18e6909679a579f6833425e030vboxsync for (MediaList::const_iterator it = getChildren().begin();
670b83d458bceb92123155b5b47a39b9d24e3266vboxsync * Returns the base hard disk of the hard disk chain this hard disk is part of.
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync * The base hard disk is found by walking up the parent-child relationship axis.
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync * If the hard disk doesn't have a parent (i.e. it's a base hard disk), it
baacecc94a2d23b6f5086739c08cf06d6b357d0avboxsync * returns itself in response to this method.
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync * @param aLevel Where to store the number of ancestors of this hard disk
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * (zero for the base), may be @c NULL.
1741b757f7a570a7e6d48db46c3f4cd50f2ee296vboxsync * @note Locks medium tree for reading.
203cad92999b4792bf61b4b65e1e2abfe08f5664vboxsyncComObjPtr<Medium> Medium::getBase(uint32_t *aLevel /*= NULL*/)
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync /* we access mParent */
c5abe3ea9c7ac6dec34f42af30612534bea951ffvboxsync AutoReadLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync * Returns @c true if this hard disk cannot be modified because it has
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync * dependants (children) or is part of the snapshot. Related to the hard disk
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync * type and posterity, not to the current media state.
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync * @note Locks this object and medium tree for reading.
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync /* we access children */
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync AutoReadLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync switch (m->type)
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync return true;
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync for (BackRefList::const_iterator it = m->backRefs.begin();
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync return true;
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync return false;
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync return true;
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync return false;
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync * Saves hard disk data by appending a new <HardDisk> child node to the given
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync * parent node which can be either <HardDisks> or <HardDisk>.
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync * @param data Settings struct to be updated.
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync * @note Locks this object, medium tree and children for reading.
e4f367251aede667a6de69baa54ef9eb5f150871vboxsyncHRESULT Medium::saveSettings(settings::Medium &data)
c0a370e600bb60153a269fb32b5f709347c35768vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
c0a370e600bb60153a269fb32b5f709347c35768vboxsync /* we access mParent */
c0a370e600bb60153a269fb32b5f709347c35768vboxsync AutoReadLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync /* optional, only for diffs, default is false */
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync /* optional */
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync /* optional properties */
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync for (Data::PropertyMap::const_iterator it = m->properties.begin();
c0a370e600bb60153a269fb32b5f709347c35768vboxsync /* only save properties that have non-default values */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* only for base hard disks */
9496f2d398b49813176939d7a339ae513d5175efvboxsync /* save all children */
61d064a54f03596920c3918f58ecc7764074a5d8vboxsync for (MediaList::const_iterator it = getChildren().begin();
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync * Compares the location of this hard disk to the given location.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * The comparison takes the location details into account. For example, if the
9496f2d398b49813176939d7a339ae513d5175efvboxsync * location is a file in the host's filesystem, a case insensitive comparison
9496f2d398b49813176939d7a339ae513d5175efvboxsync * will be performed for case insensitive filesystems.
e2ebb3d022edb845fd1158d6338e3def1d0e2159vboxsync * @param aLocation Location to compare to (as is).
e2ebb3d022edb845fd1158d6338e3def1d0e2159vboxsync * @param aResult Where to store the result of comparison: 0 if locations
e2ebb3d022edb845fd1158d6338e3def1d0e2159vboxsync * are equal, 1 if this object's location is greater than
e2ebb3d022edb845fd1158d6338e3def1d0e2159vboxsync * the specified location, and -1 otherwise.
e2ebb3d022edb845fd1158d6338e3def1d0e2159vboxsyncHRESULT Medium::compareLocationTo(const char *aLocation, int &aResult)
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync /// @todo NEWMEDIA delegate the comparison to the backend?
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync if (m->formatObj->capabilities() & MediumFormatCapabilities_File)
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync /* For locations represented by files, append the default path if
d1bffa158f98ff3c18f7d085e7372c9ea00e9a43vboxsync * only the name is given, and then get the full path. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync int vrc = m->pVirtualBox->calculateFullPath(location, location);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync tr("Invalid hard disk storage file location '%s' (%Rrc)"),
9496f2d398b49813176939d7a339ae513d5175efvboxsync aResult = RTPathCompare(locationFull.c_str(), location.c_str());
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Constructs a medium lock list for this medium. The lock is not taken.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @note Locks the medium tree for reading.
6437cb19ad6d607a74ccf8d8f25c7e7af761b316vboxsync * @param fFailIfInaccessible If true, this fails with an error if a medium is inaccessible. If false,
681fd85cc7cd49e9cf66a917d6ae9ff36eb7d9e9vboxsync * inaccessible media are silently skipped and not locked (i.e. their state remains "Inaccessible");
681fd85cc7cd49e9cf66a917d6ae9ff36eb7d9e9vboxsync * this is necessary for a VM's removable images on VM startup for which we do not want to fail.
1e1273b11e17928ec3c3a8fff45121aa7a169413vboxsync * @param fMediumLockWrite Whether to associate a write lock with this medium.
681fd85cc7cd49e9cf66a917d6ae9ff36eb7d9e9vboxsync * @param pToBeParent Medium which will become the parent of this medium.
681fd85cc7cd49e9cf66a917d6ae9ff36eb7d9e9vboxsync * @param mediumLockList Where to store the resulting list.
681fd85cc7cd49e9cf66a917d6ae9ff36eb7d9e9vboxsyncHRESULT Medium::createMediumLockList(bool fFailIfInaccessible,
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync /* we access parent medium objects */
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync AutoReadLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
e4f367251aede667a6de69baa54ef9eb5f150871vboxsync /* paranoid sanity checking if the medium has a to-be parent medium */
681fd85cc7cd49e9cf66a917d6ae9ff36eb7d9e9vboxsync // need write lock for RefreshState if medium is inaccessible
681fd85cc7cd49e9cf66a917d6ae9ff36eb7d9e9vboxsync AutoWriteLock alock(pMedium COMMA_LOCKVAL_SRC_POS);
681fd85cc7cd49e9cf66a917d6ae9ff36eb7d9e9vboxsync /* Accessibility check must be first, otherwise locking interferes
1e1273b11e17928ec3c3a8fff45121aa7a169413vboxsync * with getting the medium state. Lock lists are not created for
681fd85cc7cd49e9cf66a917d6ae9ff36eb7d9e9vboxsync * fun, and thus getting the image status is no luxury. */
16a9adc14900ca18e6909679a579f6833425e030vboxsync // ignore inaccessible ISO images and silently return S_OK,
16a9adc14900ca18e6909679a579f6833425e030vboxsync // otherwise VM startup (esp. restore) may fail without good reason
f4aad55f8addd816ef005845842a2418bbdc3ea2vboxsync // otherwise report an error
009d45aa55691312278d41edb20154dc208d9cd8vboxsync rc = pMedium->COMGETTER(LastAccessError)(error.asOutParam());
cab115cfa31c584def7069312a1e23c3fc88533bvboxsync /* collect multiple errors */
cab115cfa31c584def7069312a1e23c3fc88533bvboxsync // error message will be something like
cab115cfa31c584def7069312a1e23c3fc88533bvboxsync // "Could not open the medium ... VD: error VERR_FILE_NOT_FOUND opening image file ... (VERR_FILE_NOT_FOUND).
cab115cfa31c584def7069312a1e23c3fc88533bvboxsync if (pMedium == this)
cab115cfa31c584def7069312a1e23c3fc88533bvboxsync * Returns a preferred format for differencing hard disks.
cab115cfa31c584def7069312a1e23c3fc88533bvboxsync /* m->strFormat is const, no need to lock */
009d45aa55691312278d41edb20154dc208d9cd8vboxsync /* check that our own format supports diffs */
009d45aa55691312278d41edb20154dc208d9cd8vboxsync if (!(m->formatObj->capabilities() & MediumFormatCapabilities_Differencing))
baacecc94a2d23b6f5086739c08cf06d6b357d0avboxsync /* use the default format if not */
baacecc94a2d23b6f5086739c08cf06d6b357d0avboxsync AutoReadLock propsLock(m->pVirtualBox->systemProperties() COMMA_LOCKVAL_SRC_POS);
baacecc94a2d23b6f5086739c08cf06d6b357d0avboxsync strFormat = m->pVirtualBox->getDefaultHardDiskFormat();
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * Returns the medium type. Must have caller + locking!
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync// private methods
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync////////////////////////////////////////////////////////////////////////////////
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync * Returns a short version of the location attribute.
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync * @note Must be called from under this object's read or write lock.
63c12491acc2b8b95c8ac454f1c48b98eec8f7d8vboxsync Utf8Str name = RTPathFilename(m->strLocationFull.c_str());
1e1273b11e17928ec3c3a8fff45121aa7a169413vboxsync * Sets the value of m->strLocation and calculates the value of m->strLocationFull.
1e1273b11e17928ec3c3a8fff45121aa7a169413vboxsync * Treats non-FS-path locations specially, and prepends the default hard disk
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync * folder if the given location string does not contain any path information
4a23807f02e9920d92c8449bd93d84501add460avboxsync * Also, if the specified location is a file path that ends with '/' then the
1189c7dde5d7f6c26f338ced3d40fc830b822e68vboxsync * file name part will be generated by this method automatically in the format
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * '{<uuid>}.<ext>' where <uuid> is a fresh UUID that this method will generate
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * and assign to this medium, and <ext> is the default extension for this
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * medium's storage format. Note that this procedure requires the media state to
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * be NotCreated and will return a failure otherwise.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param aLocation Location of the storage unit. If the location is a FS-path,
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * then it can be relative to the VirtualBox home directory.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @param aFormat Optional fallback format if it is an import and the format
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * cannot be determined.
5b465a7c1237993faf8bb50120d247f3f0319adavboxsync * @note Must be called from under this object's write lock.
ad77e3ec3cde24263bc7537575f5cae442bee3b1vboxsyncHRESULT Medium::setLocation(const Utf8Str &aLocation, const Utf8Str &aFormat)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* formatObj may be null only when initializing from an existing path and
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * no format is known yet */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync AssertReturn( (!m->strFormat.isEmpty() && !m->formatObj.isNull())
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync /* are we dealing with a new medium constructed using the existing
ad77e3ec3cde24263bc7537575f5cae442bee3b1vboxsync * location? */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync || ( (m->formatObj->capabilities() & MediumFormatCapabilities_File)
cba6719bd64ec749967bbe931230452664109857vboxsync /* must be a file (formatObj must be already known) */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync Assert(m->formatObj->capabilities() & MediumFormatCapabilities_File);
cba6719bd64ec749967bbe931230452664109857vboxsync /* no file name is given (either an empty string or ends with a
cba6719bd64ec749967bbe931230452664109857vboxsync * slash), generate a new UUID + file name if the state allows
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync ComAssertMsgRet(!m->formatObj->fileExtensions().empty(),
cba6719bd64ec749967bbe931230452664109857vboxsync ("Must be at least one extension if it is MediumFormatCapabilities_File\n"),
E_FAIL);
E_FAIL);
if (isImport)
* VDCreateBase/VDCreateDiff as a wanted UUID). Note that we
return S_OK;
return E_FAIL;
if (m->queryInfoRunning)
return S_OK;
bool success = false;
|| !isImport
m->queryInfoRunning = true;
if (m->hostDrive)
success = true;
throw S_OK;
m->vdDiskIfaces);
throw S_OK;
if (m->setImageId)
if (m->setParentId)
m->setImageId = false;
m->setParentId = false;
if (isImport)
tr("UUID {%RTuuid} of the medium '%s' does not match the value {%RTuuid} stored in the media registry ('%s')"),
&uuid,
throw S_OK;
if (isImport)
if (m->setImageId)
unsigned uImageFlags;
if (isImport)
&pParent);
tr("Parent hard disk with UUID {%RTuuid} of the hard disk '%s' is not found in the media registry ('%s')"),
throw S_OK;
tr("Hard disk '%s' is differencing but it is not associated with any parent hard disk in the media registry ('%s')"),
throw S_OK;
tr("Parent UUID {%RTuuid} of the hard disk '%s' does not match UUID {%RTuuid} of its parent hard disk stored in the media registry ('%s')"),
throw S_OK;
success = true;
if (isImport)
if (success)
m->queryInfoRunning = false;
if (success)
return rc;
switch (m->state)
case MediumState_NotCreated:
case MediumState_Created:
case MediumState_LockedRead:
case MediumState_LockedWrite:
case MediumState_Inaccessible:
case MediumState_Creating:
case MediumState_Deleting:
AssertFailed();
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.
* This only works in "wait" mode; otherwise saveSettings gets called automatically by the thread that was created,
bool aWait,
bool *pfNeedsSaveSettings)
this->lockHandle()
switch (m->state)
case MediumState_Created:
case MediumState_Deleting:
case MediumState_Inaccessible:
throw setStateError();
++it)
#ifdef DEBUG
dumpBackRefs();
tr("Cannot delete storage: hard disk '%s' is still attached to the following %d virtual machine(s): %s"),
throw rc;
throw rc;
NULL,
delete pMediumLockList;
throw rc;
delete pMediumLockList;
throw rc;
static_cast<IMedium*>(this),
throw rc;
throw rc;
if (aWait)
if (pTask)
delete pTask;
return rc;
switch (m->state)
case MediumState_Created:
case MediumState_Inaccessible:
return S_OK;
return setStateError();
switch (m->state)
case MediumState_Deleting:
return S_OK;
return setStateError();
return S_OK;
return setStateError();
return S_OK;
return setStateError();
bool aWait,
bool *pfNeedsSaveSettings)
++it)
tr("Hard disk '%s' is attached to a virtual machine with UUID {%RTuuid}. No differencing hard disks based on it may be created until it is detached"),
static_cast<IMedium*>(this),
BstrFmt(tr("Creating differencing hard disk storage unit '%s'"), aTarget->m->strLocationFull.raw()),
throw rc;
throw rc;
++m->numCreateDiffTasks;
if (aWait)
delete pTask;
return rc;
bool fLockMedia,
bool &fMergeForward,
fMergeForward = false;
fMergeForward = false;
if (pMedium == this)
fMergeForward = true;
if (fMergeForward)
NULL,
NULL,
throw rc;
if (fLockMedia)
throw setStateError();
if (fMergeForward)
&& ( !aMachineId
throw rc;
if (fLockMedia)
throw setStateError();
throw setStateError();
throw setStateError();
if (fMergeForward)
++it)
if (fLockMedia)
throw rc;
throw rc;
if (!fMergeForward)
lockListEnd--;
++it)
if (fLockMedia)
delete aMediumLockList;
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.
* This only works in "wait" mode; otherwise saveSettings gets called automatically by the thread that was created,
bool fMergeForward,
bool aWait,
bool *pfNeedsSaveSettings)
static_cast<IMedium*>(this),
throw rc;
throw rc;
if (aWait)
delete pTask;
return rc;
++it)
delete aMediumLockList;
++it)
aFormat);
++it)
return S_OK;
return S_OK;
* @param pfNeedsSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true
* by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed.
if (m->pParent)
deparent();
switch (m->devType)
case DeviceType_DVD:
case DeviceType_Floppy:
case DeviceType_HardDisk:
if (pParentBackup)
return rc;
return error;
return VERR_CFGM_VALUE_NOT_FOUND;
return VERR_CFGM_VALUE_NOT_FOUND;
return VINF_SUCCESS;
return VERR_CFGM_VALUE_NOT_FOUND;
return VERR_CFGM_NOT_ENOUGH_SPACE;
return VERR_CFGM_VALUE_NOT_FOUND;
return VINF_SUCCESS;
delete pTask;
vrc),
E_FAIL);
return S_OK;
++it)
throw vrc;
++it)
throw vrc;
throw vrc;
throw vrc;
catch (int aVRC)
return rc;
bool *pfNeedsSaveSettings)
* asynchronously. As a result, we always save the VirtualBox.xml file when
bool fGenerateUuid = false;
if (fGenerateUuid)
throw rc;
NULL,
&geo,
&geo,
NULL,
bool fNeedsSaveSettings = false;
if (fNeedsSaveSettings)
if (fGenerateUuid)
return rc;
bool fNeedsSaveSettings = false;
bool fGenerateUuid = false;
if (fGenerateUuid)
++it)
throw rc;
NULL,
deparent();
if (fGenerateUuid)
if (fNeedsSaveSettings)
--m->numCreateDiffTasks;
return rc;
++it)
if (pMedium == this)
uSourceIdx = i;
uTargetIdx = i;
unsigned uOpenFlags = 0;
throw vrc;
throw vrc;
++it)
throw vrc;
throw vrc;
throw vrc;
catch (int aVRC)
deparent();
it++)
++it;
if (pMedium == this)
return rc;
* As a result, we always save the VirtualBox.xml file when we're done here.
bool fCreatingTarget = false;
bool fGenerateUuid = false;
if (fGenerateUuid)
++it)
throw rc;
++it)
NULL,
if (pParent)
if (fCreatingTarget)
if (fGenerateUuid)
return rc;
m->vdDiskIfaces);
return rc;
++it)
if (pMedium == this)
m->vdDiskIfaces);
NULL,
m->vdDiskIfaces,
return rc;
++it)
return rc;