/* $Id: MediumImpl.h 74353 2018-09-18 21:51:33Z vboxsync $ */ /** @file * VirtualBox COM class implementation */ /* * Copyright (C) 2008-2017 Oracle Corporation * * 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. */ #ifndef ____H_MEDIUMIMPL #define ____H_MEDIUMIMPL #include #include "MediumWrap.h" #include "VirtualBoxBase.h" #include "AutoCaller.h" #include "SecretKeyStore.h" class Progress; class MediumFormat; class MediumLockList; struct MediumCryptoFilterSettings; namespace settings { struct Medium; } //////////////////////////////////////////////////////////////////////////////// /** * Medium component class for all media types. */ class ATL_NO_VTABLE Medium : public MediumWrap { public: DECLARE_EMPTY_CTOR_DTOR(Medium) HRESULT FinalConstruct(); void FinalRelease(); enum HDDOpenMode { OpenReadWrite, OpenReadOnly }; // have to use a special enum for the overloaded init() below; // can't use AccessMode_T from XIDL because that's mapped to an int // and would be ambiguous // public initializer/uninitializer for internal purposes only // initializer to create empty medium (VirtualBox::CreateMedium()) HRESULT init(VirtualBox *aVirtualBox, const Utf8Str &aFormat, const Utf8Str &aLocation, const Guid &uuidMachineRegistry, const DeviceType_T aDeviceType); // initializer for opening existing media // (VirtualBox::OpenMedium(); Machine::AttachDevice()) HRESULT init(VirtualBox *aVirtualBox, const Utf8Str &aLocation, HDDOpenMode enOpenMode, bool fForceNewUuid, DeviceType_T aDeviceType); // initializer used when loading settings HRESULT initOne(Medium *aParent, DeviceType_T aDeviceType, const Guid &uuidMachineRegistry, const settings::Medium &data, const Utf8Str &strMachineFolder); HRESULT init(VirtualBox *aVirtualBox, Medium *aParent, DeviceType_T aDeviceType, const Guid &uuidMachineRegistry, const settings::Medium &data, const Utf8Str &strMachineFolder, AutoWriteLock &mediaTreeLock); // initializer for host floppy/DVD HRESULT init(VirtualBox *aVirtualBox, DeviceType_T aDeviceType, const Utf8Str &aLocation, const Utf8Str &aDescription = Utf8Str::Empty); void uninit(); void i_deparent(); void i_setParent(const ComObjPtr &pParent); // unsafe methods for internal purposes only (ensure there is // a caller and a read lock before calling them!) const ComObjPtr& i_getParent() const; const MediaList& i_getChildren() const; const Guid& i_getId() const; MediumState_T i_getState() const; MediumVariant_T i_getVariant() const; bool i_isHostDrive() const; const Utf8Str& i_getLocationFull() const; const Utf8Str& i_getFormat() const; const ComObjPtr & i_getMediumFormat() const; bool i_isMediumFormatFile() const; uint64_t i_getSize() const; uint64_t i_getLogicalSize() const; DeviceType_T i_getDeviceType() const; MediumType_T i_getType() const; Utf8Str i_getName(); /* handles caller/locking itself */ bool i_addRegistry(const Guid &id); /* handles caller/locking itself, caller is responsible for tree lock */ bool i_addRegistryRecursive(const Guid &id); /* handles caller/locking itself */ bool i_removeRegistry(const Guid& id); /* handles caller/locking itself, caller is responsible for tree lock */ bool i_removeRegistryRecursive(const Guid& id); bool i_isInRegistry(const Guid& id); bool i_getFirstRegistryMachineId(Guid &uuid) const; void i_markRegistriesModified(); HRESULT i_setPropertyDirect(const Utf8Str &aName, const Utf8Str &aValue); HRESULT i_addBackReference(const Guid &aMachineId, const Guid &aSnapshotId = Guid::Empty); HRESULT i_removeBackReference(const Guid &aMachineId, const Guid &aSnapshotId = Guid::Empty); const Guid* i_getFirstMachineBackrefId() const; const Guid* i_getAnyMachineBackref() const; const Guid* i_getFirstMachineBackrefSnapshotId() const; size_t i_getMachineBackRefCount() const; #ifdef DEBUG void i_dumpBackRefs(); #endif HRESULT i_updatePath(const Utf8Str &strOldPath, const Utf8Str &strNewPath); /* handles caller/locking itself */ ComObjPtr i_getBase(uint32_t *aLevel = NULL); /* handles caller/locking itself */ uint32_t i_getDepth(); bool i_isReadOnly(); void i_updateId(const Guid &id); void i_saveSettingsOne(settings::Medium &data, const Utf8Str &strHardDiskFolder); HRESULT i_saveSettings(settings::Medium &data, const Utf8Str &strHardDiskFolder); HRESULT i_createMediumLockList(bool fFailIfInaccessible, Medium *pToLock, bool fMediumLockWriteAll, Medium *pToBeParent, MediumLockList &mediumLockList); HRESULT i_createDiffStorage(ComObjPtr &aTarget, MediumVariant_T aVariant, MediumLockList *pMediumLockList, ComObjPtr *aProgress, bool aWait); Utf8Str i_getPreferredDiffFormat(); MediumVariant_T i_getPreferredDiffVariant(); HRESULT i_close(AutoCaller &autoCaller); HRESULT i_unlockRead(MediumState_T *aState); HRESULT i_unlockWrite(MediumState_T *aState); HRESULT i_deleteStorage(ComObjPtr *aProgress, bool aWait); HRESULT i_markForDeletion(); HRESULT i_unmarkForDeletion(); HRESULT i_markLockedForDeletion(); HRESULT i_unmarkLockedForDeletion(); HRESULT i_queryPreferredMergeDirection(const ComObjPtr &pOther, bool &fMergeForward); HRESULT i_prepareMergeTo(const ComObjPtr &pTarget, const Guid *aMachineId, const Guid *aSnapshotId, bool fLockMedia, bool &fMergeForward, ComObjPtr &pParentForTarget, MediumLockList * &aChildrenToReparent, MediumLockList * &aMediumLockList); HRESULT i_mergeTo(const ComObjPtr &pTarget, bool fMergeForward, const ComObjPtr &pParentForTarget, MediumLockList *aChildrenToReparent, MediumLockList *aMediumLockList, ComObjPtr *aProgress, bool aWait); void i_cancelMergeTo(MediumLockList *aChildrenToReparent, MediumLockList *aMediumLockList); HRESULT i_fixParentUuidOfChildren(MediumLockList *pChildrenToReparent); HRESULT i_addRawToFss(const char *aFilename, SecretKeyStore *pKeyStore, RTVFSFSSTREAM hVfsFssDst, const ComObjPtr &aProgress, bool fSparse); HRESULT i_exportFile(const char *aFilename, const ComObjPtr &aFormat, MediumVariant_T aVariant, SecretKeyStore *pKeyStore, RTVFSIOSTREAM hVfsIosDst, const ComObjPtr &aProgress); HRESULT i_importFile(const char *aFilename, const ComObjPtr &aFormat, MediumVariant_T aVariant, RTVFSIOSTREAM hVfsIosSrc, const ComObjPtr &aParent, const ComObjPtr &aProgress); HRESULT i_cloneToEx(const ComObjPtr &aTarget, MediumVariant_T aVariant, const ComObjPtr &aParent, IProgress **aProgress, uint32_t idxSrcImageSame, uint32_t idxDstImageSame); const Utf8Str& i_getKeyId(); HRESULT i_openForIO(bool fWritable, SecretKeyStore *pKeyStore, PVDISK *ppHdd, MediumLockList *pMediumLockList, struct MediumCryptoFilterSettings *pCryptoSettings); private: // wrapped IMedium properties HRESULT getId(com::Guid &aId); HRESULT getDescription(AutoCaller &autoCaller, com::Utf8Str &aDescription); HRESULT setDescription(AutoCaller &autoCaller, const com::Utf8Str &aDescription); HRESULT getState(MediumState_T *aState); HRESULT getVariant(std::vector &aVariant); HRESULT getLocation(com::Utf8Str &aLocation); HRESULT setLocation(const com::Utf8Str &aLocation); HRESULT getName(com::Utf8Str &aName); HRESULT getDeviceType(DeviceType_T *aDeviceType); HRESULT getHostDrive(BOOL *aHostDrive); HRESULT getSize(LONG64 *aSize); HRESULT getFormat(com::Utf8Str &aFormat); HRESULT getMediumFormat(ComPtr &aMediumFormat); HRESULT getType(AutoCaller &autoCaller, MediumType_T *aType); HRESULT setType(AutoCaller &autoCaller, MediumType_T aType); HRESULT getAllowedTypes(std::vector &aAllowedTypes); HRESULT getParent(AutoCaller &autoCaller, ComPtr &aParent); HRESULT getChildren(AutoCaller &autoCaller, std::vector > &aChildren); HRESULT getBase(AutoCaller &autoCaller, ComPtr &aBase); HRESULT getReadOnly(AutoCaller &autoCaller, BOOL *aReadOnly); HRESULT getLogicalSize(LONG64 *aLogicalSize); HRESULT getAutoReset(BOOL *aAutoReset); HRESULT setAutoReset(BOOL aAutoReset); HRESULT getLastAccessError(com::Utf8Str &aLastAccessError); HRESULT getMachineIds(std::vector &aMachineIds); // wrapped IMedium methods HRESULT setIds(AutoCaller &aAutoCaller, BOOL aSetImageId, const com::Guid &aImageId, BOOL aSetParentId, const com::Guid &aParentId); HRESULT refreshState(AutoCaller &aAutoCaller, MediumState_T *aState); HRESULT getSnapshotIds(const com::Guid &aMachineId, std::vector &aSnapshotIds); HRESULT lockRead(ComPtr &aToken); HRESULT lockWrite(ComPtr &aToken); HRESULT close(AutoCaller &aAutoCaller); HRESULT getProperty(const com::Utf8Str &aName, com::Utf8Str &aValue); HRESULT setProperty(const com::Utf8Str &aName, const com::Utf8Str &aValue); HRESULT getProperties(const com::Utf8Str &aNames, std::vector &aReturnNames, std::vector &aReturnValues); HRESULT setProperties(const std::vector &aNames, const std::vector &aValues); HRESULT createBaseStorage(LONG64 aLogicalSize, const std::vector &aVariant, ComPtr &aProgress); HRESULT deleteStorage(ComPtr &aProgress); HRESULT createDiffStorage(AutoCaller &autoCaller, const ComPtr &aTarget, const std::vector &aVariant, ComPtr &aProgress); HRESULT mergeTo(const ComPtr &aTarget, ComPtr &aProgress); HRESULT cloneTo(const ComPtr &aTarget, const std::vector &aVariant, const ComPtr &aParent, ComPtr &aProgress); HRESULT cloneToBase(const ComPtr &aTarget, const std::vector &aVariant, ComPtr &aProgress); HRESULT moveTo(AutoCaller &autoCaller, const com::Utf8Str &aLocation, ComPtr &aProgress); HRESULT compact(ComPtr &aProgress); HRESULT resize(LONG64 aLogicalSize, ComPtr &aProgress); HRESULT reset(AutoCaller &autoCaller, ComPtr &aProgress); HRESULT changeEncryption(const com::Utf8Str &aCurrentPassword, const com::Utf8Str &aCipher, const com::Utf8Str &aNewPassword, const com::Utf8Str &aNewPasswordId, ComPtr &aProgress); HRESULT getEncryptionSettings(AutoCaller &autoCaller, com::Utf8Str &aCipher, com::Utf8Str &aPasswordId); HRESULT checkEncryptionPassword(const com::Utf8Str &aPassword); HRESULT openForIO(BOOL aWritable, com::Utf8Str const &aPassword, ComPtr &aMediumIO); // Private internal nmethods HRESULT i_queryInfo(bool fSetImageId, bool fSetParentId, AutoCaller &autoCaller); HRESULT i_canClose(); HRESULT i_unregisterWithVirtualBox(); HRESULT i_setStateError(); HRESULT i_setLocation(const Utf8Str &aLocation, const Utf8Str &aFormat = Utf8Str::Empty); HRESULT i_setFormat(const Utf8Str &aFormat); VDTYPE i_convertDeviceType(); DeviceType_T i_convertToDeviceType(VDTYPE enmType); Utf8Str i_vdError(int aVRC); bool i_isPropertyForFilter(const com::Utf8Str &aName); HRESULT i_getFilterProperties(std::vector &aReturnNames, std::vector &aReturnValues); HRESULT i_preparationForMoving(const Utf8Str &aLocation); bool i_isMoveOperation(const ComObjPtr &pTarget) const; bool i_resetMoveOperationData(); Utf8Str i_getNewLocationForMoving() const; static DECLCALLBACK(void) i_vdErrorCall(void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va); static DECLCALLBACK(bool) i_vdConfigAreKeysValid(void *pvUser, const char *pszzValid); static DECLCALLBACK(int) i_vdConfigQuerySize(void *pvUser, const char *pszName, size_t *pcbValue); static DECLCALLBACK(int) i_vdConfigQuery(void *pvUser, const char *pszName, char *pszValue, size_t cchValue); static DECLCALLBACK(int) i_vdTcpSocketCreate(uint32_t fFlags, PVDSOCKET pSock); static DECLCALLBACK(int) i_vdTcpSocketDestroy(VDSOCKET Sock); static DECLCALLBACK(int) i_vdTcpClientConnect(VDSOCKET Sock, const char *pszAddress, uint32_t uPort, RTMSINTERVAL cMillies); static DECLCALLBACK(int) i_vdTcpClientClose(VDSOCKET Sock); static DECLCALLBACK(bool) i_vdTcpIsClientConnected(VDSOCKET Sock); static DECLCALLBACK(int) i_vdTcpSelectOne(VDSOCKET Sock, RTMSINTERVAL cMillies); static DECLCALLBACK(int) i_vdTcpRead(VDSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead); static DECLCALLBACK(int) i_vdTcpWrite(VDSOCKET Sock, const void *pvBuffer, size_t cbBuffer); static DECLCALLBACK(int) i_vdTcpSgWrite(VDSOCKET Sock, PCRTSGBUF pSgBuf); static DECLCALLBACK(int) i_vdTcpFlush(VDSOCKET Sock); static DECLCALLBACK(int) i_vdTcpSetSendCoalescing(VDSOCKET Sock, bool fEnable); static DECLCALLBACK(int) i_vdTcpGetLocalAddress(VDSOCKET Sock, PRTNETADDR pAddr); static DECLCALLBACK(int) i_vdTcpGetPeerAddress(VDSOCKET Sock, PRTNETADDR pAddr); static DECLCALLBACK(bool) i_vdCryptoConfigAreKeysValid(void *pvUser, const char *pszzValid); static DECLCALLBACK(int) i_vdCryptoConfigQuerySize(void *pvUser, const char *pszName, size_t *pcbValue); static DECLCALLBACK(int) i_vdCryptoConfigQuery(void *pvUser, const char *pszName, char *pszValue, size_t cchValue); static DECLCALLBACK(int) i_vdCryptoKeyRetain(void *pvUser, const char *pszId, const uint8_t **ppbKey, size_t *pcbKey); static DECLCALLBACK(int) i_vdCryptoKeyRelease(void *pvUser, const char *pszId); static DECLCALLBACK(int) i_vdCryptoKeyStorePasswordRetain(void *pvUser, const char *pszId, const char **ppszPassword); static DECLCALLBACK(int) i_vdCryptoKeyStorePasswordRelease(void *pvUser, const char *pszId); static DECLCALLBACK(int) i_vdCryptoKeyStoreSave(void *pvUser, const void *pvKeyStore, size_t cbKeyStore); static DECLCALLBACK(int) i_vdCryptoKeyStoreReturnParameters(void *pvUser, const char *pszCipher, const uint8_t *pbDek, size_t cbDek); class Task; class CreateBaseTask; class CreateDiffTask; class CloneTask; class MoveTask; class CompactTask; class ResizeTask; class ResetTask; class DeleteTask; class MergeTask; class ImportTask; class EncryptTask; friend class Task; friend class CreateBaseTask; friend class CreateDiffTask; friend class CloneTask; friend class MoveTask; friend class CompactTask; friend class ResizeTask; friend class ResetTask; friend class DeleteTask; friend class MergeTask; friend class ImportTask; friend class EncryptTask; HRESULT i_taskCreateBaseHandler(Medium::CreateBaseTask &task); HRESULT i_taskCreateDiffHandler(Medium::CreateDiffTask &task); HRESULT i_taskMergeHandler(Medium::MergeTask &task); HRESULT i_taskCloneHandler(Medium::CloneTask &task); HRESULT i_taskMoveHandler(Medium::MoveTask &task); HRESULT i_taskDeleteHandler(Medium::DeleteTask &task); HRESULT i_taskResetHandler(Medium::ResetTask &task); HRESULT i_taskCompactHandler(Medium::CompactTask &task); HRESULT i_taskResizeHandler(Medium::ResizeTask &task); HRESULT i_taskImportHandler(Medium::ImportTask &task); HRESULT i_taskEncryptHandler(Medium::EncryptTask &task); void i_taskEncryptSettingsSetup(struct MediumCryptoFilterSettings *pSettings, const char *pszCipher, const char *pszKeyStore, const char *pszPassword, bool fCreateKeyStore); struct Data; // opaque data struct, defined in MediumImpl.cpp Data *m; }; /** * Settings for a crypto filter instance. */ struct MediumCryptoFilterSettings { MediumCryptoFilterSettings() : fCreateKeyStore(false), pszPassword(NULL), pszKeyStore(NULL), pszKeyStoreLoad(NULL), pbDek(NULL), cbDek(0), pszCipher(NULL), pszCipherReturned(NULL) { } bool fCreateKeyStore; const char *pszPassword; char *pszKeyStore; const char *pszKeyStoreLoad; const uint8_t *pbDek; size_t cbDek; const char *pszCipher; /** The cipher returned by the crypto filter. */ char *pszCipherReturned; PVDINTERFACE vdFilterIfaces; VDINTERFACECONFIG vdIfCfg; VDINTERFACECRYPTO vdIfCrypto; }; #endif /* !____H_MEDIUMIMPL */