DVDImageImpl.cpp revision 2c75187df4bc65eae9117019c2190800bd1a7aa1
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * VirtualBox COM class implementation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Copyright (C) 2006-2007 innotek GmbH
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * available from http://www.virtualbox.org. This file is free software;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * you can redistribute it and/or modify it under the terms of the GNU
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * General Public License as published by the Free Software Foundation,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * If you received this file as part of a commercial VirtualBox
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * distribution, then only the terms of your commercial VirtualBox
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * license agreement apply instead of the previous paragraph.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "DVDImageImpl.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "VirtualBoxImpl.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "Logging.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <iprt/file.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <iprt/path.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <iprt/cpputils.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <VBox/err.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <VBox/param.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// constructor / destructor
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/////////////////////////////////////////////////////////////////////////////
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncDEFINE_EMPTY_CTOR_DTOR (DVDImage)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncHRESULT DVDImage::FinalConstruct()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mAccessible = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return S_OK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncvoid DVDImage::FinalRelease()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync uninit();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// public initializer/uninitializer for internal purposes only
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/////////////////////////////////////////////////////////////////////////////
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Initializes the DVD image object.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * @param aParent
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * parent object
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * @param aFilePath
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * local file system path to the image file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * (can be relative to the VirtualBox config dir)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * @param aRegistered
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * whether this object is being initialized by the VirtualBox init code
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * because it is present in the registry
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * @param aId
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * ID of the DVD image to assign
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * @return COM result indicator
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncHRESULT DVDImage::init (VirtualBox *aParent, const BSTR aFilePath,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOL aRegistered, const Guid &aId)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LogFlowThisFunc (("aFilePath={%ls}, aId={%s}\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync aFilePath, aId.toString().raw()));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ComAssertRet (aParent && aFilePath && !!aId, E_INVALIDARG);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* Enclose the state transition NotReady->InInit->Ready */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AutoInitSpan autoInitSpan (this);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AssertReturn (autoInitSpan.isOk(), E_UNEXPECTED);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync HRESULT rc = S_OK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* share the parent weakly */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync unconst (mParent) = aParent;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* register with parent early, since uninit() will unconditionally
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * unregister on failure */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mParent->addDependentChild (this);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync unconst (mImageFile) = aFilePath;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync unconst (mUuid) = aId;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* get the full file name */
char filePathFull [RTPATH_MAX];
int vrc = RTPathAbsEx (mParent->homeDir(), Utf8Str (aFilePath),
filePathFull, sizeof (filePathFull));
if (VBOX_FAILURE (vrc))
return setError (E_FAIL,
tr ("Invalid image file path: '%ls' (%Vrc)"),
aFilePath, vrc);
unconst (mImageFileFull) = filePathFull;
LogFlowThisFunc (("...filePathFull={%ls}\n", mImageFileFull.raw()));
if (!aRegistered)
{
/* check whether the given file exists or not */
RTFILE file;
vrc = RTFileOpen (&file, filePathFull,
RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
if (VBOX_FAILURE (vrc))
{
/* here we come when the image was just opened by
* IVirtualBox::OpenDVDImage(). fail in this case */
rc = setError (E_FAIL,
tr ("Could not open the CD/DVD image '%ls' (%Vrc)"),
mImageFileFull.raw(), vrc);
}
else
RTFileClose (file);
}
/* Confirm a successful initialization when it's the case */
if (SUCCEEDED (rc))
autoInitSpan.setSucceeded();
return rc;
}
/**
* Uninitializes the instance and sets the ready flag to FALSE.
* Called either from FinalRelease() or by the parent when it gets destroyed.
*/
void DVDImage::uninit()
{
LogFlowThisFunc (("\n"));
/* Enclose the state transition Ready->InUninit->NotReady */
AutoUninitSpan autoUninitSpan (this);
if (autoUninitSpan.uninitDone())
return;
LogFlowThisFunc (("initFailed()=%RTbool\n", autoUninitSpan.initFailed()));
mParent->removeDependentChild (this);
unconst (mParent).setNull();
}
// IDVDImage properties
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP DVDImage::COMGETTER(Id) (GUIDPARAMOUT aId)
{
if (!aId)
return E_POINTER;
AutoCaller autoCaller (this);
CheckComRCReturnRC (autoCaller.rc());
/* mUuid is constant during life time, no need to lock */
mUuid.cloneTo (aId);
return S_OK;
}
STDMETHODIMP DVDImage::COMGETTER(FilePath) (BSTR *aFilePath)
{
if (!aFilePath)
return E_POINTER;
AutoCaller autoCaller (this);
CheckComRCReturnRC (autoCaller.rc());
AutoReaderLock alock (this);
mImageFileFull.cloneTo (aFilePath);
return S_OK;
}
STDMETHODIMP DVDImage::COMGETTER(Accessible) (BOOL *aAccessible)
{
if (!aAccessible)
return E_POINTER;
AutoCaller autoCaller (this);
CheckComRCReturnRC (autoCaller.rc());
AutoLock alock (this);
HRESULT rc = S_OK;
/* check whether the given image file exists or not */
RTFILE file;
int vrc = RTFileOpen (&file, Utf8Str (mImageFileFull),
RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
if (VBOX_FAILURE (vrc))
{
Log (("DVDImage::COMGETTER(Accessible): WARNING: '%ls' "
"is not accessible (%Vrc)\n", mImageFileFull.raw(), vrc));
mAccessible = FALSE;
}
else
{
mAccessible = TRUE;
RTFileClose (file);
}
*aAccessible = mAccessible;
return rc;
}
STDMETHODIMP DVDImage::COMGETTER(Size) (ULONG64 *aSize)
{
if (!aSize)
return E_POINTER;
HRESULT rc = S_OK;
AutoCaller autoCaller (this);
CheckComRCReturnRC (autoCaller.rc());
AutoReaderLock alock (this);
RTFILE file;
int vrc = RTFileOpen (&file, Utf8Str (mImageFileFull),
RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
if (VBOX_FAILURE (vrc))
rc = setError (E_FAIL, tr("Failed to open ISO image '%ls' (%Vrc)\n"),
mImageFileFull.raw(), vrc);
else
{
AssertCompile (sizeof (uint64_t) == sizeof (ULONG64));
uint64_t u64Size = 0;
vrc = RTFileGetSize (file, &u64Size);
if (VBOX_SUCCESS (vrc))
*aSize = u64Size;
else
rc = setError (E_FAIL,
tr ("Failed to determine size of ISO image '%ls' (%Vrc)\n"),
mImageFileFull.raw(), vrc);
RTFileClose (file);
}
return rc;
}
// public methods for internal purposes only
////////////////////////////////////////////////////////////////////////////////
/**
* Changes the stored path values of this image to reflect the new location.
* Intended to be called only by VirtualBox::updateSettings() if a machine's
* name change causes directory renaming that affects this image.
*
* @param aNewFullPath new full path to this image file
* @param aNewPath new path to this image file relative to the VirtualBox
* settings directory (when possible)
*
* @note Locks this object for writing.
*/
void DVDImage::updatePath (const char *aNewFullPath, const char *aNewPath)
{
AssertReturnVoid (aNewFullPath);
AssertReturnVoid (aNewPath);
AutoCaller autoCaller (this);
AssertComRCReturnVoid (autoCaller.rc());
AutoLock alock (this);
unconst (mImageFileFull) = aNewFullPath;
unconst (mImageFile) = aNewPath;
}