VirtualBox

source: vbox/trunk/src/VBox/Main/include/MediumImpl.h@ 86672

Last change on this file since 86672 was 86501, checked in by vboxsync, 4 years ago

VBoxSVC: Fix Medium leak when encoutering duplicate instances while loading a media registry (from settings) via VirtualBox::initMedia(). The media registration is now moved to before any children are loaded, so that we use the right parent for them. This essentially changes the operation to a merge. An unaddressed issue is that on child load failure, we will leave the parent(s) still registered but non-functioning (uninit was done). (The old code would just leave any successfully loaded children registered with non-working parents only accessible via their parent attribute.) bugref:9841

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.2 KB
Line 
1/* $Id: MediumImpl.h 86501 2020-10-09 12:28:32Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2008-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef MAIN_INCLUDED_MediumImpl_h
19#define MAIN_INCLUDED_MediumImpl_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include <VBox/vd.h>
25#include "MediumWrap.h"
26#include "VirtualBoxBase.h"
27#include "AutoCaller.h"
28#include "SecretKeyStore.h"
29class Progress;
30class MediumFormat;
31class MediumLockList;
32struct MediumCryptoFilterSettings;
33
34namespace settings
35{
36 struct Medium;
37}
38
39////////////////////////////////////////////////////////////////////////////////
40
41/**
42 * Medium component class for all media types.
43 */
44class ATL_NO_VTABLE Medium :
45 public MediumWrap
46{
47public:
48 DECLARE_EMPTY_CTOR_DTOR(Medium)
49
50 HRESULT FinalConstruct();
51 void FinalRelease();
52
53 enum HDDOpenMode { OpenReadWrite, OpenReadOnly };
54 // have to use a special enum for the overloaded init() below;
55 // can't use AccessMode_T from XIDL because that's mapped to an int
56 // and would be ambiguous
57
58 // public initializer/uninitializer for internal purposes only
59
60 // initializer to create empty medium (VirtualBox::CreateMedium())
61 HRESULT init(VirtualBox *aVirtualBox,
62 const Utf8Str &aFormat,
63 const Utf8Str &aLocation,
64 const Guid &uuidMachineRegistry,
65 const DeviceType_T aDeviceType);
66
67 // initializer for opening existing media
68 // (VirtualBox::OpenMedium(); Machine::AttachDevice())
69 HRESULT init(VirtualBox *aVirtualBox,
70 const Utf8Str &aLocation,
71 HDDOpenMode enOpenMode,
72 bool fForceNewUuid,
73 DeviceType_T aDeviceType);
74
75 // initializer used when loading settings
76 HRESULT initOne(Medium *aParent,
77 DeviceType_T aDeviceType,
78 const Guid &uuidMachineRegistry,
79 const settings::Medium &data,
80 const Utf8Str &strMachineFolder);
81 HRESULT initFromSettings(VirtualBox *aVirtualBox,
82 Medium *aParent,
83 DeviceType_T aDeviceType,
84 const Guid &uuidMachineRegistry,
85 const settings::Medium &data,
86 const Utf8Str &strMachineFolder,
87 AutoWriteLock &mediaTreeLock,
88 ComObjPtr<Medium> *ppRegistered);
89
90 // initializer for host floppy/DVD
91 HRESULT init(VirtualBox *aVirtualBox,
92 DeviceType_T aDeviceType,
93 const Utf8Str &aLocation,
94 const Utf8Str &aDescription = Utf8Str::Empty);
95
96 void uninit();
97
98 void i_deparent();
99 void i_setParent(const ComObjPtr<Medium> &pParent);
100
101 // unsafe methods for internal purposes only (ensure there is
102 // a caller and a read lock before calling them!)
103 const ComObjPtr<Medium>& i_getParent() const;
104 const MediaList& i_getChildren() const;
105
106 const Guid& i_getId() const;
107 MediumState_T i_getState() const;
108 MediumVariant_T i_getVariant() const;
109 bool i_isHostDrive() const;
110 const Utf8Str& i_getLocationFull() const;
111 const Utf8Str& i_getFormat() const;
112 const ComObjPtr<MediumFormat> & i_getMediumFormat() const;
113 bool i_isMediumFormatFile() const;
114 uint64_t i_getSize() const;
115 uint64_t i_getLogicalSize() const;
116 DeviceType_T i_getDeviceType() const;
117 MediumType_T i_getType() const;
118 Utf8Str i_getName();
119
120 /* handles caller/locking itself */
121 bool i_addRegistry(const Guid &id);
122 bool i_addRegistryNoCallerCheck(const Guid &id);
123 /* handles caller/locking itself, caller is responsible for tree lock */
124 bool i_addRegistryRecursive(const Guid &id);
125 /* handles caller/locking itself */
126 bool i_removeRegistry(const Guid& id);
127 /* handles caller/locking itself, caller is responsible for tree lock */
128 bool i_removeRegistryRecursive(const Guid& id);
129 bool i_isInRegistry(const Guid& id);
130 bool i_getFirstRegistryMachineId(Guid &uuid) const;
131 void i_markRegistriesModified();
132
133 HRESULT i_setPropertyDirect(const Utf8Str &aName, const Utf8Str &aValue);
134
135 HRESULT i_addBackReference(const Guid &aMachineId,
136 const Guid &aSnapshotId = Guid::Empty);
137 HRESULT i_removeBackReference(const Guid &aMachineId,
138 const Guid &aSnapshotId = Guid::Empty);
139
140
141 const Guid* i_getFirstMachineBackrefId() const;
142 const Guid* i_getAnyMachineBackref() const;
143 const Guid* i_getFirstMachineBackrefSnapshotId() const;
144 size_t i_getMachineBackRefCount() const;
145
146#ifdef DEBUG
147 void i_dumpBackRefs();
148#endif
149
150 HRESULT i_updatePath(const Utf8Str &strOldPath, const Utf8Str &strNewPath);
151
152 /* handles caller/locking itself */
153 ComObjPtr<Medium> i_getBase(uint32_t *aLevel = NULL);
154 /* handles caller/locking itself */
155 uint32_t i_getDepth();
156
157 bool i_isReadOnly();
158 void i_updateId(const Guid &id);
159
160 void i_saveSettingsOne(settings::Medium &data,
161 const Utf8Str &strHardDiskFolder);
162 HRESULT i_saveSettings(settings::Medium &data,
163 const Utf8Str &strHardDiskFolder);
164
165 HRESULT i_createMediumLockList(bool fFailIfInaccessible,
166 Medium *pToLock,
167 bool fMediumLockWriteAll,
168 Medium *pToBeParent,
169 MediumLockList &mediumLockList);
170
171 HRESULT i_createDiffStorage(ComObjPtr<Medium> &aTarget,
172 MediumVariant_T aVariant,
173 MediumLockList *pMediumLockList,
174 ComObjPtr<Progress> *aProgress,
175 bool aWait,
176 bool aNotify);
177 Utf8Str i_getPreferredDiffFormat();
178 MediumVariant_T i_getPreferredDiffVariant();
179
180 HRESULT i_close(AutoCaller &autoCaller);
181 HRESULT i_unlockRead(MediumState_T *aState);
182 HRESULT i_unlockWrite(MediumState_T *aState);
183 HRESULT i_deleteStorage(ComObjPtr<Progress> *aProgress, bool aWait, bool aNotify);
184 HRESULT i_markForDeletion();
185 HRESULT i_unmarkForDeletion();
186 HRESULT i_markLockedForDeletion();
187 HRESULT i_unmarkLockedForDeletion();
188
189 HRESULT i_queryPreferredMergeDirection(const ComObjPtr<Medium> &pOther,
190 bool &fMergeForward);
191
192 HRESULT i_prepareMergeTo(const ComObjPtr<Medium> &pTarget,
193 const Guid *aMachineId,
194 const Guid *aSnapshotId,
195 bool fLockMedia,
196 bool &fMergeForward,
197 ComObjPtr<Medium> &pParentForTarget,
198 MediumLockList * &aChildrenToReparent,
199 MediumLockList * &aMediumLockList);
200 HRESULT i_mergeTo(const ComObjPtr<Medium> &pTarget,
201 bool fMergeForward,
202 const ComObjPtr<Medium> &pParentForTarget,
203 MediumLockList *aChildrenToReparent,
204 MediumLockList *aMediumLockList,
205 ComObjPtr<Progress> *aProgress,
206 bool aWait,
207 bool aNotify);
208 void i_cancelMergeTo(MediumLockList *aChildrenToReparent,
209 MediumLockList *aMediumLockList);
210
211 HRESULT i_resize(uint64_t aLogicalSize,
212 MediumLockList *aMediumLockList,
213 ComObjPtr<Progress> *aProgress,
214 bool aWait,
215 bool aNotify);
216
217 HRESULT i_fixParentUuidOfChildren(MediumLockList *pChildrenToReparent);
218
219 HRESULT i_addRawToFss(const char *aFilename, SecretKeyStore *pKeyStore, RTVFSFSSTREAM hVfsFssDst,
220 const ComObjPtr<Progress> &aProgress, bool fSparse);
221
222 HRESULT i_exportFile(const char *aFilename,
223 const ComObjPtr<MediumFormat> &aFormat,
224 MediumVariant_T aVariant,
225 SecretKeyStore *pKeyStore,
226 RTVFSIOSTREAM hVfsIosDst,
227 const ComObjPtr<Progress> &aProgress);
228 HRESULT i_importFile(const char *aFilename,
229 const ComObjPtr<MediumFormat> &aFormat,
230 MediumVariant_T aVariant,
231 RTVFSIOSTREAM hVfsIosSrc,
232 const ComObjPtr<Medium> &aParent,
233 const ComObjPtr<Progress> &aProgress,
234 bool aNotify);
235
236 HRESULT i_cloneToEx(const ComObjPtr<Medium> &aTarget, MediumVariant_T aVariant,
237 const ComObjPtr<Medium> &aParent, IProgress **aProgress,
238 uint32_t idxSrcImageSame, uint32_t idxDstImageSame, bool aNotify);
239
240 const Utf8Str& i_getKeyId();
241
242 HRESULT i_openForIO(bool fWritable, SecretKeyStore *pKeyStore, PVDISK *ppHdd, MediumLockList *pMediumLockList,
243 struct MediumCryptoFilterSettings *pCryptoSettings);
244
245private:
246
247 // wrapped IMedium properties
248 HRESULT getId(com::Guid &aId);
249 HRESULT getDescription(AutoCaller &autoCaller, com::Utf8Str &aDescription);
250 HRESULT setDescription(AutoCaller &autoCaller, const com::Utf8Str &aDescription);
251 HRESULT getState(MediumState_T *aState);
252 HRESULT getVariant(std::vector<MediumVariant_T> &aVariant);
253 HRESULT getLocation(com::Utf8Str &aLocation);
254 HRESULT setLocation(const com::Utf8Str &aLocation);
255 HRESULT getName(com::Utf8Str &aName);
256 HRESULT getDeviceType(DeviceType_T *aDeviceType);
257 HRESULT getHostDrive(BOOL *aHostDrive);
258 HRESULT getSize(LONG64 *aSize);
259 HRESULT getFormat(com::Utf8Str &aFormat);
260 HRESULT getMediumFormat(ComPtr<IMediumFormat> &aMediumFormat);
261 HRESULT getType(AutoCaller &autoCaller, MediumType_T *aType);
262 HRESULT setType(AutoCaller &autoCaller, MediumType_T aType);
263 HRESULT getAllowedTypes(std::vector<MediumType_T> &aAllowedTypes);
264 HRESULT getParent(AutoCaller &autoCaller, ComPtr<IMedium> &aParent);
265 HRESULT getChildren(AutoCaller &autoCaller, std::vector<ComPtr<IMedium> > &aChildren);
266 HRESULT getBase(AutoCaller &autoCaller, ComPtr<IMedium> &aBase);
267 HRESULT getReadOnly(AutoCaller &autoCaller, BOOL *aReadOnly);
268 HRESULT getLogicalSize(LONG64 *aLogicalSize);
269 HRESULT getAutoReset(BOOL *aAutoReset);
270 HRESULT setAutoReset(BOOL aAutoReset);
271 HRESULT getLastAccessError(com::Utf8Str &aLastAccessError);
272 HRESULT getMachineIds(std::vector<com::Guid> &aMachineIds);
273
274 // wrapped IMedium methods
275 HRESULT setIds(AutoCaller &aAutoCaller,
276 BOOL aSetImageId,
277 const com::Guid &aImageId,
278 BOOL aSetParentId,
279 const com::Guid &aParentId);
280 HRESULT refreshState(AutoCaller &aAutoCaller,
281 MediumState_T *aState);
282 HRESULT getSnapshotIds(const com::Guid &aMachineId,
283 std::vector<com::Guid> &aSnapshotIds);
284 HRESULT lockRead(ComPtr<IToken> &aToken);
285 HRESULT lockWrite(ComPtr<IToken> &aToken);
286 HRESULT close(AutoCaller &aAutoCaller);
287 HRESULT getProperty(const com::Utf8Str &aName,
288 com::Utf8Str &aValue);
289 HRESULT setProperty(const com::Utf8Str &aName,
290 const com::Utf8Str &aValue);
291 HRESULT getProperties(const com::Utf8Str &aNames,
292 std::vector<com::Utf8Str> &aReturnNames,
293 std::vector<com::Utf8Str> &aReturnValues);
294 HRESULT setProperties(const std::vector<com::Utf8Str> &aNames,
295 const std::vector<com::Utf8Str> &aValues);
296 HRESULT createBaseStorage(LONG64 aLogicalSize,
297 const std::vector<MediumVariant_T> &aVariant,
298 ComPtr<IProgress> &aProgress);
299 HRESULT deleteStorage(ComPtr<IProgress> &aProgress);
300 HRESULT createDiffStorage(AutoCaller &autoCaller,
301 const ComPtr<IMedium> &aTarget,
302 const std::vector<MediumVariant_T> &aVariant,
303 ComPtr<IProgress> &aProgress);
304 HRESULT mergeTo(const ComPtr<IMedium> &aTarget,
305 ComPtr<IProgress> &aProgress);
306 HRESULT cloneTo(const ComPtr<IMedium> &aTarget,
307 const std::vector<MediumVariant_T> &aVariant,
308 const ComPtr<IMedium> &aParent,
309 ComPtr<IProgress> &aProgress);
310 HRESULT cloneToBase(const ComPtr<IMedium> &aTarget,
311 const std::vector<MediumVariant_T> &aVariant,
312 ComPtr<IProgress> &aProgress);
313 HRESULT moveTo(AutoCaller &autoCaller,
314 const com::Utf8Str &aLocation,
315 ComPtr<IProgress> &aProgress);
316 HRESULT compact(ComPtr<IProgress> &aProgress);
317 HRESULT resize(LONG64 aLogicalSize,
318 ComPtr<IProgress> &aProgress);
319 HRESULT reset(AutoCaller &autoCaller, ComPtr<IProgress> &aProgress);
320 HRESULT changeEncryption(const com::Utf8Str &aCurrentPassword, const com::Utf8Str &aCipher,
321 const com::Utf8Str &aNewPassword, const com::Utf8Str &aNewPasswordId,
322 ComPtr<IProgress> &aProgress);
323 HRESULT getEncryptionSettings(AutoCaller &autoCaller, com::Utf8Str &aCipher, com::Utf8Str &aPasswordId);
324 HRESULT checkEncryptionPassword(const com::Utf8Str &aPassword);
325 HRESULT openForIO(BOOL aWritable, com::Utf8Str const &aPassword, ComPtr<IMediumIO> &aMediumIO);
326
327 // Private internal nmethods
328 HRESULT i_queryInfo(bool fSetImageId, bool fSetParentId, AutoCaller &autoCaller);
329 HRESULT i_canClose();
330 HRESULT i_unregisterWithVirtualBox();
331 HRESULT i_setStateError();
332 HRESULT i_setLocation(const Utf8Str &aLocation, const Utf8Str &aFormat = Utf8Str::Empty);
333 HRESULT i_setFormat(const Utf8Str &aFormat);
334 VDTYPE i_convertDeviceType();
335 DeviceType_T i_convertToDeviceType(VDTYPE enmType);
336 Utf8Str i_vdError(int aVRC);
337
338 bool i_isPropertyForFilter(const com::Utf8Str &aName);
339
340 HRESULT i_getFilterProperties(std::vector<com::Utf8Str> &aReturnNames,
341 std::vector<com::Utf8Str> &aReturnValues);
342
343 HRESULT i_preparationForMoving(const Utf8Str &aLocation);
344 bool i_isMoveOperation(const ComObjPtr<Medium> &pTarget) const;
345 bool i_resetMoveOperationData();
346 Utf8Str i_getNewLocationForMoving() const;
347
348 static DECLCALLBACK(void) i_vdErrorCall(void *pvUser, int rc, RT_SRC_POS_DECL,
349 const char *pszFormat, va_list va);
350 static DECLCALLBACK(bool) i_vdConfigAreKeysValid(void *pvUser,
351 const char *pszzValid);
352 static DECLCALLBACK(int) i_vdConfigQuerySize(void *pvUser, const char *pszName,
353 size_t *pcbValue);
354 static DECLCALLBACK(int) i_vdConfigUpdate(void *pvUser, bool fCreate,
355 const char *pszName, const char *pszValue);
356
357 static DECLCALLBACK(int) i_vdConfigQuery(void *pvUser, const char *pszName,
358 char *pszValue, size_t cchValue);
359
360 static DECLCALLBACK(bool) i_vdCryptoConfigAreKeysValid(void *pvUser,
361 const char *pszzValid);
362 static DECLCALLBACK(int) i_vdCryptoConfigQuerySize(void *pvUser, const char *pszName,
363 size_t *pcbValue);
364 static DECLCALLBACK(int) i_vdCryptoConfigQuery(void *pvUser, const char *pszName,
365 char *pszValue, size_t cchValue);
366
367 static DECLCALLBACK(int) i_vdCryptoKeyRetain(void *pvUser, const char *pszId,
368 const uint8_t **ppbKey, size_t *pcbKey);
369 static DECLCALLBACK(int) i_vdCryptoKeyRelease(void *pvUser, const char *pszId);
370 static DECLCALLBACK(int) i_vdCryptoKeyStorePasswordRetain(void *pvUser, const char *pszId, const char **ppszPassword);
371 static DECLCALLBACK(int) i_vdCryptoKeyStorePasswordRelease(void *pvUser, const char *pszId);
372 static DECLCALLBACK(int) i_vdCryptoKeyStoreSave(void *pvUser, const void *pvKeyStore, size_t cbKeyStore);
373 static DECLCALLBACK(int) i_vdCryptoKeyStoreReturnParameters(void *pvUser, const char *pszCipher,
374 const uint8_t *pbDek, size_t cbDek);
375
376 class Task;
377 class CreateBaseTask;
378 class CreateDiffTask;
379 class CloneTask;
380 class MoveTask;
381 class CompactTask;
382 class ResizeTask;
383 class ResetTask;
384 class DeleteTask;
385 class MergeTask;
386 class ImportTask;
387 class EncryptTask;
388 friend class Task;
389 friend class CreateBaseTask;
390 friend class CreateDiffTask;
391 friend class CloneTask;
392 friend class MoveTask;
393 friend class CompactTask;
394 friend class ResizeTask;
395 friend class ResetTask;
396 friend class DeleteTask;
397 friend class MergeTask;
398 friend class ImportTask;
399 friend class EncryptTask;
400
401 HRESULT i_taskCreateBaseHandler(Medium::CreateBaseTask &task);
402 HRESULT i_taskCreateDiffHandler(Medium::CreateDiffTask &task);
403 HRESULT i_taskMergeHandler(Medium::MergeTask &task);
404 HRESULT i_taskCloneHandler(Medium::CloneTask &task);
405 HRESULT i_taskMoveHandler(Medium::MoveTask &task);
406 HRESULT i_taskDeleteHandler(Medium::DeleteTask &task);
407 HRESULT i_taskResetHandler(Medium::ResetTask &task);
408 HRESULT i_taskCompactHandler(Medium::CompactTask &task);
409 HRESULT i_taskResizeHandler(Medium::ResizeTask &task);
410 HRESULT i_taskImportHandler(Medium::ImportTask &task);
411 HRESULT i_taskEncryptHandler(Medium::EncryptTask &task);
412
413 void i_taskEncryptSettingsSetup(struct MediumCryptoFilterSettings *pSettings, const char *pszCipher,
414 const char *pszKeyStore, const char *pszPassword,
415 bool fCreateKeyStore);
416
417 struct Data; // opaque data struct, defined in MediumImpl.cpp
418 Data *m;
419};
420
421
422/**
423 * Settings for a crypto filter instance.
424 */
425struct MediumCryptoFilterSettings
426{
427 MediumCryptoFilterSettings()
428 : fCreateKeyStore(false),
429 pszPassword(NULL),
430 pszKeyStore(NULL),
431 pszKeyStoreLoad(NULL),
432 pbDek(NULL),
433 cbDek(0),
434 pszCipher(NULL),
435 pszCipherReturned(NULL)
436 { }
437
438 bool fCreateKeyStore;
439 const char *pszPassword;
440 char *pszKeyStore;
441 const char *pszKeyStoreLoad;
442
443 const uint8_t *pbDek;
444 size_t cbDek;
445 const char *pszCipher;
446
447 /** The cipher returned by the crypto filter. */
448 char *pszCipherReturned;
449
450 PVDINTERFACE vdFilterIfaces;
451
452 VDINTERFACECONFIG vdIfCfg;
453 VDINTERFACECRYPTO vdIfCrypto;
454};
455
456
457
458#endif /* !MAIN_INCLUDED_MediumImpl_h */
459
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette