DVDDriveImpl.cpp revision 70bb61ea2f96e80150e807529ce5df435607706b
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * VirtualBox COM class implementation
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * Copyright (C) 2006-2009 Sun Microsystems, Inc.
10cdf5733351fdcd857d439ca32189e812f18682vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
10cdf5733351fdcd857d439ca32189e812f18682vboxsync * available from http://www.virtualbox.org. This file is free software;
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * you can redistribute it and/or modify it under the terms of the GNU
438870735e3606c923d51fce19d9fc3b6ebffde1vboxsync * General Public License (GPL) as published by the Free Software
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a74782eac5771b0de57834e8c8c0247c55e8dd57vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a74782eac5771b0de57834e8c8c0247c55e8dd57vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a74782eac5771b0de57834e8c8c0247c55e8dd57vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
a74782eac5771b0de57834e8c8c0247c55e8dd57vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
a74782eac5771b0de57834e8c8c0247c55e8dd57vboxsync * additional information or have any questions.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync// constructor / destructor
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync////////////////////////////////////////////////////////////////////////////////
0270d1440bcecad2d4d12bd37c82252b6ee5afdbvboxsync// public initializer/uninitializer for internal purposes only
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync////////////////////////////////////////////////////////////////////////////////
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * Initializes the DVD drive object.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * @param aParent Handle of the parent object.
c9dbeac49601b9e10f0941b1c8e4f97853d4fab5vboxsync /* Enclose the state transition NotReady->InInit->Ready */
23179f1443b03947d85eccc81cbc6b5153a4abf3vboxsync /* mPeer is left null */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* Confirm a successful initialization */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * Initializes the DVD drive object given another DVD drive object
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * (a kind of copy constructor). This object shares data with
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * the object passed as an argument.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * @note This object must be destroyed before the original object
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * it shares data with is destroyed.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * @note Locks @a aThat object for reading.
583008eb7eb336e25724785bc04833bd33271fd6vboxsyncHRESULT DVDDrive::init (Machine *aParent, DVDDrive *aThat)
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync LogFlowThisFunc (("aParent=%p, aThat=%p\n", aParent, aThat));
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* Enclose the state transition NotReady->InInit->Ready */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* Confirm a successful initialization */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * Initializes the DVD drive object given another DVD drive object
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * (a kind of copy constructor). This object makes a private copy of data
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * of the original object passed as an argument.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * @note Locks @a aThat object for reading.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncHRESULT DVDDrive::initCopy (Machine *aParent, DVDDrive *aThat)
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync LogFlowThisFunc (("aParent=%p, aThat=%p\n", aParent, aThat));
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* Enclose the state transition NotReady->InInit->Ready */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* mPeer is left null */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* at present, this must be a snapshot machine */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* associate the DVD image media with the snapshot */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* Confirm a successful initialization */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * Uninitializes the instance and sets the ready flag to FALSE.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * Called either from FinalRelease() or by the parent when it gets destroyed.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* Enclose the state transition Ready->InUninit->NotReady */
fadf3b452e8a0c58afb43fd56f445fa8583d9d0cvboxsync /* Deassociate the DVD image (only when mParent is a real Machine or a
fadf3b452e8a0c58afb43fd56f445fa8583d9d0cvboxsync * SnapshotMachine instance; SessionMachine instances
fadf3b452e8a0c58afb43fd56f445fa8583d9d0cvboxsync * refer to real Machine hard disks). This is necessary for a clean
fadf3b452e8a0c58afb43fd56f445fa8583d9d0cvboxsync * re-initialization of the VM after successfully re-checking the
fadf3b452e8a0c58afb43fd56f445fa8583d9d0cvboxsync * accessibility state. */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync// IDVDDrive properties
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync////////////////////////////////////////////////////////////////////////////////
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncSTDMETHODIMP DVDDrive::COMGETTER(State) (DriveState_T *aState)
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncSTDMETHODIMP DVDDrive::COMGETTER(Passthrough) (BOOL *aPassthrough)
fadf3b452e8a0c58afb43fd56f445fa8583d9d0cvboxsyncSTDMETHODIMP DVDDrive::COMSETTER(Passthrough) (BOOL aPassthrough)
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* the machine needs to be mutable */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Machine::AutoMutableStateDependency adep (mParent);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync// IDVDDrive methods
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync////////////////////////////////////////////////////////////////////////////////
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncSTDMETHODIMP DVDDrive::MountImage (IN_GUID aImageId)
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* the machine needs to be mutable */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Machine::AutoMutableStateDependency adep (mParent);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* Our lifetime is bound to mParent's lifetime, so we don't add caller.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * We also don't lock mParent since its mParent field is const. */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync rc = mParent->virtualBox()->findDVDImage(&imageId, NULL,
bde2993862d2d76510aca28c77db01c889301ccavboxsync rc = image->attachTo (mParent->id(), mParent->snapshotId());
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* umount() will backup data */
ebb33f3aef3b410579a2865109426b798b9d4a9dvboxsync /* lock the image for reading if the VM is online. It will
ebb33f3aef3b410579a2865109426b798b9d4a9dvboxsync * be unlocked either when unmounted from this drive or by
ebb33f3aef3b410579a2865109426b798b9d4a9dvboxsync * SessionMachine::setMachineState() when the VM is
ebb33f3aef3b410579a2865109426b798b9d4a9dvboxsync * terminated */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* leave the lock before informing callbacks */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncSTDMETHODIMP DVDDrive::CaptureHostDrive (IHostDVDDrive *aHostDVDDrive)
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* the machine needs to be mutable */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Machine::AutoMutableStateDependency adep (mParent);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* umount() will backup data */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* leave the lock before informing callbacks */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* the machine needs to be mutable */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Machine::AutoMutableStateDependency adep (mParent);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* umount() will backup data */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* leave the lock before informing callbacks */
28a02a9abdb21adbaaeeae87339534ca0346f97avboxsyncSTDMETHODIMP DVDDrive::GetImage (IDVDImage **aDVDImage)
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncSTDMETHODIMP DVDDrive::GetHostDrive(IHostDVDDrive **aHostDrive)
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync// public methods only for internal purposes
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync////////////////////////////////////////////////////////////////////////////////
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * Loads settings from the given machine node. May be called once right after
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * this object creation.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * @param aMachineNode <Machine> node.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * @note Locks this object for writing.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncHRESULT DVDDrive::loadSettings (const settings::Key &aMachineNode)
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync using namespace settings;
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* Note: we assume that the default values for attributes of optional
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * nodes are assigned in the Data::Data() constructor and don't do it
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * here. It implies that this method may only be called after constructing
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * a new BIOSSettings object while all its data fields are in the default
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * values. Exceptions are fields whose creation time defaults don't match
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * values that should be applied when these fields are not explicitly set
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * in the settings file (for backwards compatibility reasons). This takes
28a02a9abdb21adbaaeeae87339534ca0346f97avboxsync * place when a setting of a newly created object must default to A while
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * the same setting of an object loaded from the old settings file must
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * default to B. */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* DVD drive (required, contains either Image or HostDrive or nothing) */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* optional, defaults to false */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync m->passthrough = dvdDriveNode.value <bool> ("passthrough");
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync if (!(typeNode = dvdDriveNode.findKey ("Image")).isNull())
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync else if (!(typeNode = dvdDriveNode.findKey ("HostDrive")).isNull())
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* find the corresponding object */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ComObjPtr <Host> host = mParent->virtualBox()->host();
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync rc = host->COMGETTER(DVDDrives) (ComSafeArrayAsOutParam(coll));
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync rc = host->FindHostDVDDrive (src, drive.asOutParam());
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* the host DVD drive is not currently available. we
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * assume it will be available later and create an
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * extra object now */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * Saves settings to the given machine node.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * @param aMachineNode <Machine> node.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * @note Locks this object for reading.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncHRESULT DVDDrive::saveSettings (settings::Key &aMachineNode)
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync using namespace settings;
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync node.setValue <bool> ("passthrough", !!m->passthrough);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync HRESULT rc = m->image->COMGETTER(Id) (id.asOutParam());
6bace994141628622511ae44b06facc8e31f24fdvboxsync HRESULT rc = m->hostDrive->COMGETTER(Name) (name.asOutParam());
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* do nothing, i.e.leave the drive node empty */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ComAssertMsgFailedRet (("Invalid drive state: %d", m->state),
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * @note Locks this object for writing.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* sanity */
01cfd051d439d6d1d5f7e5aa3f64d34014254065vboxsync /* we need adep for the state check */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync bool changed = false;
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* we need to check all data to see whether anything will be changed
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * after rollback */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* detach the current image that will go away after rollback */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync m->image->detachFrom (mParent->id(), mParent->snapshotId());
6bace994141628622511ae44b06facc8e31f24fdvboxsync /* unlock the image for reading if the VM is online */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * @note Locks this object for writing, together with the peer object (also for
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * writing) if there is one.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* sanity */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* sanity too */
a12c113a863b1f7a3132da4c008b786218516e2fvboxsync /* we need adep for the state check */
c2ce5189c8cbdecf46df173d22e4cb7a6e2f6c83vboxsync /* lock both for writing since we modify both (mPeer is "master" so locked
c2ce5189c8cbdecf46df173d22e4cb7a6e2f6c83vboxsync * first) */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* detach the old image that will go away after commit */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync oldData->image->detachFrom (mParent->id(), mParent->snapshotId());
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* unlock the image for reading if the VM is online */
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync /* attach new data to the peer and reshare it */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * @note Locks this object for writing, together with the peer object
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * represented by @a aThat (locked for reading).
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* sanity */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* sanity too */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* peer is not modified, lock it for reading (aThat is "master" so locked
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * first) */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync AutoMultiLock2 alock (aThat->rlock(), this->wlock());
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync /* this will back up current data */
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * Helper to unmount a drive.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync * @note Must be called from under this object's write lock.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync AssertReturn (isWriteLockOnCurrentThread(), E_FAIL);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync// private methods
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync////////////////////////////////////////////////////////////////////////////////
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync/* vi: set tabstop=4 shiftwidth=4 expandtab: */