/* $Id $ */ /** @file * * VirtualBox COM class implementation */ /* * Copyright (C) 2008 Sun Microsystems, Inc. * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * General Public License (GPL) as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 USA or visit http://www.sun.com if you need * additional information or have any questions. */ #ifndef ____H_HARDDISK2IMPL #define ____H_HARDDISK2IMPL #include "VirtualBoxBase.h" #include "VirtualBoxImpl.h" #include "MediumImpl.h" #include #include class Progress; //////////////////////////////////////////////////////////////////////////////// /** * The HardDisk2 component class implements the IHardDisk2 interface. */ class ATL_NO_VTABLE HardDisk2 : public com::SupportErrorInfoDerived , public VirtualBoxBaseWithTypedChildrenNEXT , public VirtualBoxSupportTranslation , public IHardDisk2 { public: typedef VirtualBoxBaseWithTypedChildrenNEXT ::DependentChildren List; class MergeChain; VIRTUALBOXSUPPORTTRANSLATION_OVERRIDE (HardDisk2) DECLARE_NOT_AGGREGATABLE (HardDisk2) DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP (HardDisk2) COM_INTERFACE_ENTRY (ISupportErrorInfo) COM_INTERFACE_ENTRY2 (IMedium, MediumBase) COM_INTERFACE_ENTRY (IHardDisk2) END_COM_MAP() NS_DECL_ISUPPORTS DECLARE_EMPTY_CTOR_DTOR (HardDisk2) HRESULT FinalConstruct(); void FinalRelease(); // public initializer/uninitializer for internal purposes only HRESULT init (VirtualBox *aVirtualBox, const BSTR aFormat, const BSTR aLocation); HRESULT init (VirtualBox *aVirtualBox, const BSTR aLocation); HRESULT init (VirtualBox *aVirtualBox, HardDisk2 *aParent, const settings::Key &aNode); void uninit(); // IMedium properties & methods COM_FORWARD_IMedium_TO_BASE (MediumBase) // IHardDisk2 properties STDMETHOD(COMGETTER(Format)) (BSTR *aFormat); STDMETHOD(COMGETTER(Type)) (HardDiskType_T *aType); STDMETHOD(COMSETTER(Type)) (HardDiskType_T aType); STDMETHOD(COMGETTER(Parent)) (IHardDisk2 **aParent); STDMETHOD(COMGETTER(Children)) (ComSafeArrayOut (IHardDisk2 *, aChildren)); STDMETHOD(COMGETTER(Root)) (IHardDisk2 **aRoot); STDMETHOD(COMGETTER(ReadOnly)) (BOOL *aReadOnly); STDMETHOD(COMGETTER(LogicalSize)) (ULONG64 *aLogicalSize); // IHardDisk2 methods STDMETHOD(CreateDynamicStorage) (ULONG64 aLogicalSize, IProgress **aProgress); STDMETHOD(CreateFixedStorage) (ULONG64 aLogicalSize, IProgress **aProgress); STDMETHOD(DeleteStorage) (IProgress **aProgress); STDMETHOD(CreateDiffStorage) (IHardDisk2 *aTarget, IProgress **aProgress); STDMETHOD(MergeTo) (INPTR GUIDPARAM aTargetId, IProgress **aProgress); STDMETHOD(CloneTo) (IHardDisk2 *aTarget, IProgress **aProgress); STDMETHOD(FlattenTo) (IHardDisk2 *aTarget, IProgress **aProgress); // public methods for internal purposes only /** * Shortcut to VirtualBoxBaseWithChildrenNEXT::dependentChildren(). */ const List &children() const { return dependentChildren(); } void updatePaths (const char *aOldPath, const char *aNewPath); ComObjPtr root (uint32_t *aLevel = NULL); bool isReadOnly(); HRESULT saveSettings (settings::Key &aParentNode); HRESULT compareLocationTo (const char *aLocation, int &aResult); /** * Shortcut to #deleteStorage() that doesn't wait for operation completion * and implies the progress object will be used for waiting. */ HRESULT deleteStorageNoWait (ComObjPtr &aProgress) { return deleteStorage (&aProgress, false /* aWait */); } /** * Shortcut to #deleteStorage() that wait for operation completion by * blocking the current thread. */ HRESULT deleteStorageAndWait (ComObjPtr *aProgress = NULL) { return deleteStorage (aProgress, true /* aWait */); } /** * Shortcut to #createDiffStorage() that doesn't wait for operation * completion and implies the progress object will be used for waiting. */ HRESULT createDiffStorageNoWait (ComObjPtr &aTarget, ComObjPtr &aProgress) { return createDiffStorage (aTarget, &aProgress, false /* aWait */); } /** * Shortcut to #createDiffStorage() that wait for operation completion by * blocking the current thread. */ HRESULT createDiffStorageAndWait (ComObjPtr &aTarget, ComObjPtr *aProgress = NULL) { return createDiffStorage (aTarget, aProgress, true /* aWait */); } HRESULT prepareMergeTo (HardDisk2 *aTarget, MergeChain * &aChain, bool aIgnoreAttachments = false); /** * Shortcut to #mergeTo() that doesn't wait for operation completion and * implies the progress object will be used for waiting. */ HRESULT mergeToNoWait (MergeChain *aChain, ComObjPtr &aProgress) { return mergeTo (aChain, &aProgress, false /* aWait */); } /** * Shortcut to #mergeTo() that wait for operation completion by * blocking the current thread. */ HRESULT mergeToAndWait (MergeChain *aChain, ComObjPtr *aProgress = NULL) { return mergeTo (aChain, aProgress, true /* aWait */); } void cancelMergeTo (MergeChain *aChain); Utf8Str name(); static bool isFileLocation (const char *aLocation); HRESULT prepareDiscard (MergeChain * &aChain); HRESULT discard (ComObjPtr &aProgress, MergeChain *aChain); void cancelDiscard (MergeChain *aChain); // unsafe inline public methods for internal purposes only (ensure there is // a caller and a read lock before calling them!) ComObjPtr parent() const { return static_cast (mParent); } HardDiskType_T type() const { return mm.type; } /** For com::SupportErrorInfoImpl. */ static const char *ComponentName() { return "HardDisk2"; } protected: HRESULT deleteStorage (ComObjPtr *aProgress, bool aWait); HRESULT createDiffStorage (ComObjPtr &aTarget, ComObjPtr *aProgress, bool aWait); HRESULT mergeTo (MergeChain *aChain, ComObjPtr *aProgress, bool aWait); LockHandle *treeLock() { return mVirtualBox->hardDiskTreeHandle(); } private: HRESULT setLocation (const BSTR aLocation); HRESULT queryInfo(); HRESULT canClose(); HRESULT canAttach (const Guid &aMachineId, const Guid &aSnapshotId); HRESULT unregisterWithVirtualBox(); Utf8Str vdError (int aVRC); static DECLCALLBACK(void) vdErrorCall (void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va); static DECLCALLBACK(int) vdProgressCall (PVM /* pVM */, unsigned uPercent, void *pvUser); static DECLCALLBACK(int) taskThread (RTTHREAD thread, void *pvUser); /** weak parent */ ComObjPtr mParent; struct Task; friend struct Task; struct Data { Data() : type (HardDiskType_Normal), logicalSize (0) , implicit (false), numCreateDiffTasks (0) , vdProgress (NULL) , vdDiskIfaces (NULL) {} const Bstr format; HardDiskType_T type; uint64_t logicalSize; /*< In MBytes. */ bool implicit : 1; uint32_t numCreateDiffTasks; Utf8Str vdError; /*< Error remembered by the VD error callback. */ Progress *vdProgress; /*< Progress for the VD progress callback. */ VDINTERFACE vdIfError; VDINTERFACEERROR vdIfCallsError; VDINTERFACE vdIfProgress; VDINTERFACEPROGRESS vdIfCallsProgress; PVDINTERFACE vdDiskIfaces; }; Data mm; }; #endif /* ____H_HARDDISK2IMPL */