VirtualBox

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

Last change on this file since 95085 was 94598, checked in by vboxsync, 3 years ago

Main/Machine+Medium+Snapshot+VirtualBox: Recursion elimination to save stack space. Caused trouble with the current settings limits already in ASAN builds, now much higher limits would be possible, but that's not urgent. Also fix the behavior of forgetting medium objects when unregistering VMs (was previously not doing what the API documentation said in the CleanupMode_UnregisterOnly case). bugref:7717

Settings.cpp: Recursion elimination and make the handling of settings reading and writing more similar.

ValidationKit/tests/api/tdTreeDepth1.py: Improve testcase. Make sure that VM unregistering does the right thing with the associated medium objects.

  • 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 94598 2022-04-13 21:50:00Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2008-2022 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_COMMON_CLASS_METHODS(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 Utf8Str &strMachineFolder,
80 const settings::Medium &data);
81 static HRESULT initFromSettings(VirtualBox *aVirtualBox,
82 DeviceType_T aDeviceType,
83 const Guid &uuidMachineRegistry,
84 const Utf8Str &strMachineFolder,
85 const settings::Medium &data,
86 AutoWriteLock &mediaTreeLock,
87 std::list<std::pair<Guid, DeviceType_T> > &uIdsForNotify);
88
89 // initializer for host floppy/DVD
90 HRESULT init(VirtualBox *aVirtualBox,
91 DeviceType_T aDeviceType,
92 const Utf8Str &aLocation,
93 const Utf8Str &aDescription = Utf8Str::Empty);
94
95 void uninit();
96
97 void i_deparent();
98 void i_setParent(const ComObjPtr<Medium> &pParent);
99
100 // unsafe methods for internal purposes only (ensure there is
101 // a caller and a read lock before calling them!)
102 const ComObjPtr<Medium>& i_getParent() const;
103 const MediaList& i_getChildren() const;
104
105 const Guid& i_getId() const;
106 MediumState_T i_getState() const;
107 MediumVariant_T i_getVariant() const;
108 bool i_isHostDrive() const;
109 const Utf8Str& i_getLocationFull() const;
110 const Utf8Str& i_getFormat() const;
111 const ComObjPtr<MediumFormat> & i_getMediumFormat() const;
112 bool i_isMediumFormatFile() const;
113 uint64_t i_getSize() const;
114 uint64_t i_getLogicalSize() const;
115 DeviceType_T i_getDeviceType() const;
116 MediumType_T i_getType() const;
117 Utf8Str i_getName();
118
119 /* handles caller/locking itself */
120 bool i_addRegistry(const Guid &id);
121 bool i_addRegistryNoCallerCheck(const Guid &id);
122 /* handles caller/locking itself, caller is responsible for tree lock */
123 bool i_addRegistryAll(const Guid &id);
124 /* handles caller/locking itself */
125 bool i_removeRegistry(const Guid& id);
126 /* handles caller/locking itself, caller is responsible for tree lock */
127 bool i_removeRegistryAll(const Guid& id);
128 bool i_isInRegistry(const Guid& id);
129 bool i_getFirstRegistryMachineId(Guid &uuid) const;
130 void i_markRegistriesModified();
131
132 HRESULT i_setPropertyDirect(const Utf8Str &aName, const Utf8Str &aValue);
133
134 HRESULT i_addBackReference(const Guid &aMachineId,
135 const Guid &aSnapshotId = Guid::Empty);
136 HRESULT i_removeBackReference(const Guid &aMachineId,
137 const Guid &aSnapshotId = Guid::Empty);
138
139
140 const Guid* i_getFirstMachineBackrefId() const;
141 const Guid* i_getAnyMachineBackref(const Guid &aId) const;
142 const Guid* i_getFirstMachineBackrefSnapshotId() const;
143 size_t i_getMachineBackRefCount() const;
144
145#ifdef DEBUG
146 void i_dumpBackRefs();
147#endif
148
149 HRESULT i_updatePath(const Utf8Str &strOldPath, const Utf8Str &strNewPath);
150
151 /* handles caller/locking itself */
152 ComObjPtr<Medium> i_getBase(uint32_t *aLevel = NULL);
153 /* handles caller/locking itself */
154 uint32_t i_getDepth();
155
156 bool i_isReadOnly();
157 void i_updateId(const Guid &id);
158
159 void i_saveSettingsOne(settings::Medium &data,
160 const Utf8Str &strHardDiskFolder);
161 HRESULT i_saveSettings(settings::Medium &data,
162 const Utf8Str &strHardDiskFolder);
163
164 HRESULT i_createMediumLockList(bool fFailIfInaccessible,
165 Medium *pToLock,
166 bool fMediumLockWriteAll,
167 Medium *pToBeParent,
168 MediumLockList &mediumLockList);
169
170 HRESULT i_createDiffStorage(ComObjPtr<Medium> &aTarget,
171 MediumVariant_T aVariant,
172 MediumLockList *pMediumLockList,
173 ComObjPtr<Progress> *aProgress,
174 bool aWait,
175 bool aNotify);
176 Utf8Str i_getPreferredDiffFormat();
177 MediumVariant_T i_getPreferredDiffVariant();
178
179 HRESULT i_close(AutoCaller &autoCaller);
180 HRESULT i_unlockRead(MediumState_T *aState);
181 HRESULT i_unlockWrite(MediumState_T *aState);
182 HRESULT i_deleteStorage(ComObjPtr<Progress> *aProgress, bool aWait, bool aNotify);
183 HRESULT i_markForDeletion();
184 HRESULT i_unmarkForDeletion();
185 HRESULT i_markLockedForDeletion();
186 HRESULT i_unmarkLockedForDeletion();
187
188 HRESULT i_queryPreferredMergeDirection(const ComObjPtr<Medium> &pOther,
189 bool &fMergeForward);
190
191 HRESULT i_prepareMergeTo(const ComObjPtr<Medium> &pTarget,
192 const Guid *aMachineId,
193 const Guid *aSnapshotId,
194 bool fLockMedia,
195 bool &fMergeForward,
196 ComObjPtr<Medium> &pParentForTarget,
197 MediumLockList * &aChildrenToReparent,
198 MediumLockList * &aMediumLockList);
199 HRESULT i_mergeTo(const ComObjPtr<Medium> &pTarget,
200 bool fMergeForward,
201 const ComObjPtr<Medium> &pParentForTarget,
202 MediumLockList *aChildrenToReparent,
203 MediumLockList *aMediumLockList,
204 ComObjPtr<Progress> *aProgress,
205 bool aWait,
206 bool aNotify);
207 void i_cancelMergeTo(MediumLockList *aChildrenToReparent,
208 MediumLockList *aMediumLockList);
209
210 HRESULT i_resize(uint64_t aLogicalSize,
211 MediumLockList *aMediumLockList,
212 ComObjPtr<Progress> *aProgress,
213 bool aWait,
214 bool aNotify);
215
216 HRESULT i_fixParentUuidOfChildren(MediumLockList *pChildrenToReparent);
217
218 HRESULT i_addRawToFss(const char *aFilename, SecretKeyStore *pKeyStore, RTVFSFSSTREAM hVfsFssDst,
219 const ComObjPtr<Progress> &aProgress, bool fSparse);
220
221 HRESULT i_exportFile(const char *aFilename,
222 const ComObjPtr<MediumFormat> &aFormat,
223 MediumVariant_T aVariant,
224 SecretKeyStore *pKeyStore,
225 RTVFSIOSTREAM hVfsIosDst,
226 const ComObjPtr<Progress> &aProgress);
227 HRESULT i_importFile(const char *aFilename,
228 const ComObjPtr<MediumFormat> &aFormat,
229 MediumVariant_T aVariant,
230 RTVFSIOSTREAM hVfsIosSrc,
231 const ComObjPtr<Medium> &aParent,
232 const ComObjPtr<Progress> &aProgress,
233 bool aNotify);
234
235 HRESULT i_cloneToEx(const ComObjPtr<Medium> &aTarget, MediumVariant_T aVariant,
236 const ComObjPtr<Medium> &aParent, IProgress **aProgress,
237 uint32_t idxSrcImageSame, uint32_t idxDstImageSame, bool aNotify);
238
239 const Utf8Str& i_getKeyId();
240
241 HRESULT i_openForIO(bool fWritable, SecretKeyStore *pKeyStore, PVDISK *ppHdd, MediumLockList *pMediumLockList,
242 struct MediumCryptoFilterSettings *pCryptoSettings);
243
244private:
245
246 // wrapped IMedium properties
247 HRESULT getId(com::Guid &aId);
248 HRESULT getDescription(AutoCaller &autoCaller, com::Utf8Str &aDescription);
249 HRESULT setDescription(AutoCaller &autoCaller, const com::Utf8Str &aDescription);
250 HRESULT getState(MediumState_T *aState);
251 HRESULT getVariant(std::vector<MediumVariant_T> &aVariant);
252 HRESULT getLocation(com::Utf8Str &aLocation);
253 HRESULT setLocation(const com::Utf8Str &aLocation);
254 HRESULT getName(com::Utf8Str &aName);
255 HRESULT getDeviceType(DeviceType_T *aDeviceType);
256 HRESULT getHostDrive(BOOL *aHostDrive);
257 HRESULT getSize(LONG64 *aSize);
258 HRESULT getFormat(com::Utf8Str &aFormat);
259 HRESULT getMediumFormat(ComPtr<IMediumFormat> &aMediumFormat);
260 HRESULT getType(AutoCaller &autoCaller, MediumType_T *aType);
261 HRESULT setType(AutoCaller &autoCaller, MediumType_T aType);
262 HRESULT getAllowedTypes(std::vector<MediumType_T> &aAllowedTypes);
263 HRESULT getParent(AutoCaller &autoCaller, ComPtr<IMedium> &aParent);
264 HRESULT getChildren(AutoCaller &autoCaller, std::vector<ComPtr<IMedium> > &aChildren);
265 HRESULT getBase(AutoCaller &autoCaller, ComPtr<IMedium> &aBase);
266 HRESULT getReadOnly(AutoCaller &autoCaller, BOOL *aReadOnly);
267 HRESULT getLogicalSize(LONG64 *aLogicalSize);
268 HRESULT getAutoReset(BOOL *aAutoReset);
269 HRESULT setAutoReset(BOOL aAutoReset);
270 HRESULT getLastAccessError(com::Utf8Str &aLastAccessError);
271 HRESULT getMachineIds(std::vector<com::Guid> &aMachineIds);
272
273 // wrapped IMedium methods
274 HRESULT setIds(AutoCaller &aAutoCaller,
275 BOOL aSetImageId,
276 const com::Guid &aImageId,
277 BOOL aSetParentId,
278 const com::Guid &aParentId);
279 HRESULT refreshState(AutoCaller &aAutoCaller,
280 MediumState_T *aState);
281 HRESULT getSnapshotIds(const com::Guid &aMachineId,
282 std::vector<com::Guid> &aSnapshotIds);
283 HRESULT lockRead(ComPtr<IToken> &aToken);
284 HRESULT lockWrite(ComPtr<IToken> &aToken);
285 HRESULT close(AutoCaller &aAutoCaller);
286 HRESULT getProperty(const com::Utf8Str &aName,
287 com::Utf8Str &aValue);
288 HRESULT setProperty(const com::Utf8Str &aName,
289 const com::Utf8Str &aValue);
290 HRESULT getProperties(const com::Utf8Str &aNames,
291 std::vector<com::Utf8Str> &aReturnNames,
292 std::vector<com::Utf8Str> &aReturnValues);
293 HRESULT setProperties(const std::vector<com::Utf8Str> &aNames,
294 const std::vector<com::Utf8Str> &aValues);
295 HRESULT createBaseStorage(LONG64 aLogicalSize,
296 const std::vector<MediumVariant_T> &aVariant,
297 ComPtr<IProgress> &aProgress);
298 HRESULT deleteStorage(ComPtr<IProgress> &aProgress);
299 HRESULT createDiffStorage(AutoCaller &autoCaller,
300 const ComPtr<IMedium> &aTarget,
301 const std::vector<MediumVariant_T> &aVariant,
302 ComPtr<IProgress> &aProgress);
303 HRESULT mergeTo(const ComPtr<IMedium> &aTarget,
304 ComPtr<IProgress> &aProgress);
305 HRESULT cloneTo(const ComPtr<IMedium> &aTarget,
306 const std::vector<MediumVariant_T> &aVariant,
307 const ComPtr<IMedium> &aParent,
308 ComPtr<IProgress> &aProgress);
309 HRESULT cloneToBase(const ComPtr<IMedium> &aTarget,
310 const std::vector<MediumVariant_T> &aVariant,
311 ComPtr<IProgress> &aProgress);
312 HRESULT moveTo(AutoCaller &autoCaller,
313 const com::Utf8Str &aLocation,
314 ComPtr<IProgress> &aProgress);
315 HRESULT compact(ComPtr<IProgress> &aProgress);
316 HRESULT resize(LONG64 aLogicalSize,
317 ComPtr<IProgress> &aProgress);
318 HRESULT reset(AutoCaller &autoCaller, ComPtr<IProgress> &aProgress);
319 HRESULT changeEncryption(const com::Utf8Str &aCurrentPassword, const com::Utf8Str &aCipher,
320 const com::Utf8Str &aNewPassword, const com::Utf8Str &aNewPasswordId,
321 ComPtr<IProgress> &aProgress);
322 HRESULT getEncryptionSettings(AutoCaller &autoCaller, com::Utf8Str &aCipher, com::Utf8Str &aPasswordId);
323 HRESULT checkEncryptionPassword(const com::Utf8Str &aPassword);
324 HRESULT openForIO(BOOL aWritable, com::Utf8Str const &aPassword, ComPtr<IMediumIO> &aMediumIO);
325
326 // Private internal nmethods
327 HRESULT i_queryInfo(bool fSetImageId, bool fSetParentId, AutoCaller &autoCaller);
328 HRESULT i_canClose();
329 HRESULT i_unregisterWithVirtualBox();
330 HRESULT i_setStateError();
331 HRESULT i_setLocation(const Utf8Str &aLocation, const Utf8Str &aFormat = Utf8Str::Empty);
332 HRESULT i_setFormat(const Utf8Str &aFormat);
333 VDTYPE i_convertDeviceType();
334 DeviceType_T i_convertToDeviceType(VDTYPE enmType);
335 Utf8Str i_vdError(int aVRC);
336
337 bool i_isPropertyForFilter(const com::Utf8Str &aName);
338
339 HRESULT i_getFilterProperties(std::vector<com::Utf8Str> &aReturnNames,
340 std::vector<com::Utf8Str> &aReturnValues);
341
342 HRESULT i_preparationForMoving(const Utf8Str &aLocation);
343 bool i_isMoveOperation(const ComObjPtr<Medium> &pTarget) const;
344 bool i_resetMoveOperationData();
345 Utf8Str i_getNewLocationForMoving() const;
346
347 static DECLCALLBACK(void) i_vdErrorCall(void *pvUser, int rc, RT_SRC_POS_DECL,
348 const char *pszFormat, va_list va);
349 static DECLCALLBACK(bool) i_vdConfigAreKeysValid(void *pvUser,
350 const char *pszzValid);
351 static DECLCALLBACK(int) i_vdConfigQuerySize(void *pvUser, const char *pszName,
352 size_t *pcbValue);
353 static DECLCALLBACK(int) i_vdConfigUpdate(void *pvUser, bool fCreate,
354 const char *pszName, const char *pszValue);
355
356 static DECLCALLBACK(int) i_vdConfigQuery(void *pvUser, const char *pszName,
357 char *pszValue, size_t cchValue);
358
359 static DECLCALLBACK(bool) i_vdCryptoConfigAreKeysValid(void *pvUser,
360 const char *pszzValid);
361 static DECLCALLBACK(int) i_vdCryptoConfigQuerySize(void *pvUser, const char *pszName,
362 size_t *pcbValue);
363 static DECLCALLBACK(int) i_vdCryptoConfigQuery(void *pvUser, const char *pszName,
364 char *pszValue, size_t cchValue);
365
366 static DECLCALLBACK(int) i_vdCryptoKeyRetain(void *pvUser, const char *pszId,
367 const uint8_t **ppbKey, size_t *pcbKey);
368 static DECLCALLBACK(int) i_vdCryptoKeyRelease(void *pvUser, const char *pszId);
369 static DECLCALLBACK(int) i_vdCryptoKeyStorePasswordRetain(void *pvUser, const char *pszId, const char **ppszPassword);
370 static DECLCALLBACK(int) i_vdCryptoKeyStorePasswordRelease(void *pvUser, const char *pszId);
371 static DECLCALLBACK(int) i_vdCryptoKeyStoreSave(void *pvUser, const void *pvKeyStore, size_t cbKeyStore);
372 static DECLCALLBACK(int) i_vdCryptoKeyStoreReturnParameters(void *pvUser, const char *pszCipher,
373 const uint8_t *pbDek, size_t cbDek);
374
375 class Task;
376 class CreateBaseTask;
377 class CreateDiffTask;
378 class CloneTask;
379 class MoveTask;
380 class CompactTask;
381 class ResizeTask;
382 class ResetTask;
383 class DeleteTask;
384 class MergeTask;
385 class ImportTask;
386 class EncryptTask;
387 friend class Task;
388 friend class CreateBaseTask;
389 friend class CreateDiffTask;
390 friend class CloneTask;
391 friend class MoveTask;
392 friend class CompactTask;
393 friend class ResizeTask;
394 friend class ResetTask;
395 friend class DeleteTask;
396 friend class MergeTask;
397 friend class ImportTask;
398 friend class EncryptTask;
399
400 HRESULT i_taskCreateBaseHandler(Medium::CreateBaseTask &task);
401 HRESULT i_taskCreateDiffHandler(Medium::CreateDiffTask &task);
402 HRESULT i_taskMergeHandler(Medium::MergeTask &task);
403 HRESULT i_taskCloneHandler(Medium::CloneTask &task);
404 HRESULT i_taskMoveHandler(Medium::MoveTask &task);
405 HRESULT i_taskDeleteHandler(Medium::DeleteTask &task);
406 HRESULT i_taskResetHandler(Medium::ResetTask &task);
407 HRESULT i_taskCompactHandler(Medium::CompactTask &task);
408 HRESULT i_taskResizeHandler(Medium::ResizeTask &task);
409 HRESULT i_taskImportHandler(Medium::ImportTask &task);
410 HRESULT i_taskEncryptHandler(Medium::EncryptTask &task);
411
412 void i_taskEncryptSettingsSetup(struct MediumCryptoFilterSettings *pSettings, const char *pszCipher,
413 const char *pszKeyStore, const char *pszPassword,
414 bool fCreateKeyStore);
415
416 struct Data; // opaque data struct, defined in MediumImpl.cpp
417 Data *m;
418};
419
420
421/**
422 * Settings for a crypto filter instance.
423 */
424struct MediumCryptoFilterSettings
425{
426 MediumCryptoFilterSettings()
427 : fCreateKeyStore(false),
428 pszPassword(NULL),
429 pszKeyStore(NULL),
430 pszKeyStoreLoad(NULL),
431 pbDek(NULL),
432 cbDek(0),
433 pszCipher(NULL),
434 pszCipherReturned(NULL)
435 { }
436
437 bool fCreateKeyStore;
438 const char *pszPassword;
439 char *pszKeyStore;
440 const char *pszKeyStoreLoad;
441
442 const uint8_t *pbDek;
443 size_t cbDek;
444 const char *pszCipher;
445
446 /** The cipher returned by the crypto filter. */
447 char *pszCipherReturned;
448
449 PVDINTERFACE vdFilterIfaces;
450
451 VDINTERFACECONFIG vdIfCfg;
452 VDINTERFACECRYPTO vdIfCrypto;
453};
454
455
456
457#endif /* !MAIN_INCLUDED_MediumImpl_h */
458
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