VirtualBox

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

Last change on this file since 72703 was 72703, checked in by vboxsync, 6 years ago

Main/Medium: Fix a number of potential deadlocks due to lock order violation. Several are still present and need to be fixed later.

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