VirtualBox

source: vbox/trunk/src/VBox/Main/include/HardDiskImpl.h@ 3330

Last change on this file since 3330 was 3317, checked in by vboxsync, 17 years ago

Main: Improved error handling when opening hard disks using the generic IVirtualBox::openHardDisk() call (#2017).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.6 KB
Line 
1/** @file
2 *
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
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 as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
20 */
21
22#ifndef ____H_HARDDISKIMPL
23#define ____H_HARDDISKIMPL
24
25#include "VirtualBoxBase.h"
26#include "Collection.h"
27
28#include <VBox/cfgldr.h>
29#include <VBox/VBoxHDD-new.h>
30
31#include <iprt/semaphore.h>
32
33#include <list>
34
35class VirtualBox;
36class Progress;
37class HVirtualDiskImage;
38
39////////////////////////////////////////////////////////////////////////////////
40
41class ATL_NO_VTABLE HardDisk :
42 public VirtualBoxSupportErrorInfoImpl <HardDisk, IHardDisk>,
43 public VirtualBoxSupportTranslation <HardDisk>,
44 public VirtualBoxBaseWithTypedChildren <HardDisk>,
45 public IHardDisk
46{
47
48public:
49
50 typedef VirtualBoxBaseWithTypedChildren <HardDisk>::DependentChildren
51 HardDiskList;
52
53 DECLARE_NOT_AGGREGATABLE(HardDisk)
54
55 DECLARE_PROTECT_FINAL_CONSTRUCT()
56
57 BEGIN_COM_MAP(HardDisk)
58 COM_INTERFACE_ENTRY(ISupportErrorInfo)
59 COM_INTERFACE_ENTRY(IHardDisk)
60 END_COM_MAP()
61
62 NS_DECL_ISUPPORTS
63
64 HRESULT FinalConstruct();
65 void FinalRelease();
66
67protected:
68
69 // protected initializer/uninitializer for internal purposes only
70 HRESULT protectedInit (VirtualBox *aVirtualBox, HardDisk *aParent);
71 void protectedUninit (AutoLock &alock);
72
73public:
74
75 // IHardDisk properties
76 STDMETHOD(COMGETTER(Id)) (GUIDPARAMOUT aId);
77 STDMETHOD(COMGETTER(StorageType)) (HardDiskStorageType_T *aStorageType);
78 STDMETHOD(COMGETTER(Location)) (BSTR *aLocation);
79 STDMETHOD(COMGETTER(Type)) (HardDiskType_T *aType);
80 STDMETHOD(COMSETTER(Type)) (HardDiskType_T aType);
81 STDMETHOD(COMGETTER(Parent)) (IHardDisk **aParent);
82 STDMETHOD(COMGETTER(Children)) (IHardDiskCollection **aChildren);
83 STDMETHOD(COMGETTER(Root)) (IHardDisk **aRoot);
84 STDMETHOD(COMGETTER(Accessible)) (BOOL *aAccessible);
85 STDMETHOD(COMGETTER(AllAccessible)) (BOOL *aAllAccessible);
86 STDMETHOD(COMGETTER(LastAccessError)) (BSTR *aLastAccessError);
87 STDMETHOD(COMGETTER(MachineId)) (GUIDPARAMOUT aMachineId);
88 STDMETHOD(COMGETTER(SnapshotId)) (GUIDPARAMOUT aSnapshotId);
89
90 // IHardDisk methods
91 STDMETHOD(CloneToImage) (INPTR BSTR aFilePath, IVirtualDiskImage **aImage,
92 IProgress **aProgress);
93
94 // public methods for internal purposes only
95
96 const Guid &id() const { return mId; }
97 HardDiskStorageType_T storageType() const { return mStorageType; }
98 HardDiskType_T type() const { return mType; }
99 const Guid &machineId() const { return mMachineId; }
100 const Guid &snapshotId() const { return mSnapshotId; }
101
102 void setMachineId (const Guid &aId) { mMachineId = aId; }
103 void setSnapshotId (const Guid &aId) { mSnapshotId = aId; }
104
105 bool isDifferencing() const
106 {
107 return mType == HardDiskType_NormalHardDisk &&
108 mStorageType == HardDiskStorageType_VirtualDiskImage &&
109 !mParent.isNull();
110 }
111 bool isParentImmutable() const
112 {
113 AutoLock parentLock (mParent);
114 return !mParent.isNull() && mParent->type() == HardDiskType_ImmutableHardDisk;
115 }
116
117 inline HVirtualDiskImage *asVDI();
118
119 ComObjPtr <HardDisk> parent() const { return static_cast <HardDisk *> (mParent); }
120
121 /** Shortcut to #dependentChildrenLock() */
122 AutoLock::Handle &childrenLock() const { return dependentChildrenLock(); }
123
124 /**
125 * Shortcut to #dependentChildren().
126 * Do |AutoLock alock (childrenLock());| before acceessing the returned list!
127 */
128 const HardDiskList &children() const { return dependentChildren(); }
129
130 ComObjPtr <HardDisk> root() const;
131
132 HRESULT getBaseAccessible (Bstr &aAccessError, bool aCheckBusy = false,
133 bool aCheckReaders = false);
134
135 // virtual methods that need to be [re]implemented by every subclass
136
137 virtual HRESULT trySetRegistered (BOOL aRegistered);
138 virtual HRESULT getAccessible (Bstr &aAccessError) = 0;
139
140 virtual HRESULT saveSettings (CFGNODE aHDNode, CFGNODE aStorageNode) = 0;
141
142 virtual void updatePath (const char *aOldPath, const char *aNewPath) {}
143
144 virtual Bstr toString (bool aShort = false) = 0;
145 virtual bool sameAs (HardDisk *that);
146
147 virtual HRESULT cloneToImage (const Guid &aId, const Utf8Str &aTargetPath,
148 Progress *aProgress) = 0;
149 virtual HRESULT createDiffImage (const Guid &aId, const Utf8Str &aTargetPath,
150 Progress *aProgress) = 0;
151public:
152
153 void setBusy();
154 void clearBusy();
155 void addReader();
156 void releaseReader();
157 void addReaderOnAncestors();
158 void releaseReaderOnAncestors();
159 bool hasForeignChildren();
160
161 HRESULT setBusyWithChildren();
162 void clearBusyWithChildren();
163 HRESULT getAccessibleWithChildren (Bstr &aAccessError);
164
165 HRESULT checkConsistency();
166
167 HRESULT createDiffHardDisk (const Bstr &aFolder, const Guid &aMachineId,
168 ComObjPtr <HVirtualDiskImage> &aHardDisk,
169 Progress *aProgress);
170
171 void updatePaths (const char *aOldPath, const char *aNewPath);
172
173 /* the following must be called from under the lock */
174 bool isBusy() { isLockedOnCurrentThread(); return mBusy; }
175 unsigned readers() { isLockedOnCurrentThread(); return mReaders; }
176 const Bstr &lastAccessError() const { return mLastAccessError; }
177
178 static HRESULT openHardDisk (VirtualBox *aVirtualBox, INPTR BSTR aLocation,
179 ComObjPtr <HardDisk> &hardDisk);
180
181 // for VirtualBoxSupportErrorInfoImpl
182 static const wchar_t *getComponentName() { return L"HardDisk"; }
183
184protected:
185
186 HRESULT loadSettings (CFGNODE aHDNode);
187 HRESULT saveSettings (CFGNODE aHDNode);
188
189 /** weak VirualBox parent */
190 ComObjPtr <VirtualBox, ComWeakRef> mVirtualBox;
191
192 BOOL mRegistered;
193
194 ComObjPtr <HardDisk, ComWeakRef> mParent;
195
196 Guid mId;
197 HardDiskStorageType_T mStorageType;
198 HardDiskType_T mType;
199 Guid mMachineId;
200 Guid mSnapshotId;
201
202private:
203
204 Bstr mLastAccessError;
205
206 bool mBusy;
207 unsigned mReaders;
208};
209
210////////////////////////////////////////////////////////////////////////////////
211
212class ATL_NO_VTABLE HVirtualDiskImage :
213 public HardDisk,
214 public VirtualBoxSupportTranslation <HVirtualDiskImage>,
215 public IVirtualDiskImage
216{
217
218public:
219
220 VIRTUALBOXSUPPORTTRANSLATION_OVERRIDE(HVirtualDiskImage)
221
222 DECLARE_NOT_AGGREGATABLE(HVirtualDiskImage)
223
224 DECLARE_PROTECT_FINAL_CONSTRUCT()
225
226 BEGIN_COM_MAP(HVirtualDiskImage)
227 COM_INTERFACE_ENTRY(ISupportErrorInfo)
228 COM_INTERFACE_ENTRY(IHardDisk)
229 COM_INTERFACE_ENTRY(IVirtualDiskImage)
230 END_COM_MAP()
231
232 NS_DECL_ISUPPORTS
233
234 HRESULT FinalConstruct();
235 void FinalRelease();
236
237 // public initializer/uninitializer for internal purposes only
238
239 HRESULT init (VirtualBox *aVirtualBox, HardDisk *aParent,
240 CFGNODE aHDNode, CFGNODE aVDINode);
241 HRESULT init (VirtualBox *aVirtualBox, HardDisk *aParent,
242 const BSTR aFilePath, BOOL aRegistered = FALSE);
243 void uninit();
244
245 // IHardDisk properties
246 STDMETHOD(COMGETTER(Description)) (BSTR *aDescription);
247 STDMETHOD(COMSETTER(Description)) (INPTR BSTR aDescription);
248 STDMETHOD(COMGETTER(Size)) (ULONG64 *aSize);
249 STDMETHOD(COMGETTER(ActualSize)) (ULONG64 *aActualSize);
250
251 // IVirtualDiskImage properties
252 STDMETHOD(COMGETTER(FilePath)) (BSTR *aFilePath);
253 STDMETHOD(COMSETTER(FilePath)) (INPTR BSTR aFilePath);
254 STDMETHOD(COMGETTER(Created)) (BOOL *aCreated);
255
256 // IVirtualDiskImage methods
257 STDMETHOD(CreateDynamicImage) (ULONG64 aSize, IProgress **aProgress);
258 STDMETHOD(CreateFixedImage) (ULONG64 aSize, IProgress **aProgress);
259 STDMETHOD(DeleteImage)();
260
261 // public methods for internal purposes only
262
263 const Bstr &filePath() const { return mFilePath; }
264 const Bstr &filePathFull() const { return mFilePathFull; }
265
266 HRESULT trySetRegistered (BOOL aRegistered);
267 HRESULT getAccessible (Bstr &aAccessError);
268
269 HRESULT saveSettings (CFGNODE aHDNode, CFGNODE aStorageNode);
270
271 void updatePath (const char *aOldPath, const char *aNewPath);
272
273 Bstr toString (bool aShort = false);
274
275 HRESULT cloneToImage (const Guid &aId, const Utf8Str &aTargetPath,
276 Progress *aProgress);
277 HRESULT createDiffImage (const Guid &aId, const Utf8Str &aTargetPath,
278 Progress *aProgress);
279
280 HRESULT cloneDiffImage (const Bstr &aFolder, const Guid &aMachineId,
281 ComObjPtr <HVirtualDiskImage> &aHardDisk,
282 Progress *aProgress);
283
284 HRESULT mergeImageToParent (Progress *aProgress);
285 HRESULT mergeImageToChildren (Progress *aProgress);
286
287 HRESULT wipeOutImage();
288
289 // for VirtualBoxSupportErrorInfoImpl
290 static const wchar_t *getComponentName() { return L"VirtualDiskImage"; }
291
292private:
293
294 HRESULT setFilePath (const BSTR aFilePath);
295 HRESULT queryInformation (Bstr *aAccessError);
296 HRESULT createImage (ULONG64 aSize, BOOL aDynamic, IProgress **aProgress);
297
298 /** VDI asynchronous operation thread function */
299 static DECLCALLBACK(int) VDITaskThread (RTTHREAD thread, void *pvUser);
300
301 enum State
302 {
303 NotCreated,
304 Created,
305 /* the following must be greater than Created */
306 Accessible,
307 };
308
309 State mState;
310
311 RTSEMEVENTMULTI mStateCheckSem;
312 ULONG mStateCheckWaiters;
313
314 Bstr mDescription;
315
316 ULONG64 mSize;
317 ULONG64 mActualSize;
318
319 Bstr mFilePath;
320 Bstr mFilePathFull;
321
322 friend class HardDisk;
323};
324
325// dependent inline members
326////////////////////////////////////////////////////////////////////////////////
327
328inline HVirtualDiskImage *HardDisk::asVDI()
329{
330 AssertReturn (mStorageType == HardDiskStorageType_VirtualDiskImage, 0);
331 return static_cast <HVirtualDiskImage *> (this);
332}
333
334////////////////////////////////////////////////////////////////////////////////
335
336class ATL_NO_VTABLE HISCSIHardDisk :
337 public HardDisk,
338 public VirtualBoxSupportTranslation <HISCSIHardDisk>,
339 public IISCSIHardDisk
340{
341
342public:
343
344 VIRTUALBOXSUPPORTTRANSLATION_OVERRIDE(HISCSIHardDisk)
345
346 DECLARE_NOT_AGGREGATABLE(HISCSIHardDisk)
347
348 DECLARE_PROTECT_FINAL_CONSTRUCT()
349
350 BEGIN_COM_MAP(HISCSIHardDisk)
351 COM_INTERFACE_ENTRY(ISupportErrorInfo)
352 COM_INTERFACE_ENTRY(IHardDisk)
353 COM_INTERFACE_ENTRY(IISCSIHardDisk)
354 END_COM_MAP()
355
356 NS_DECL_ISUPPORTS
357
358 HRESULT FinalConstruct();
359 void FinalRelease();
360
361 // public initializer/uninitializer for internal purposes only
362
363 HRESULT init (VirtualBox *aVirtualBox,
364 CFGNODE aHDNode, CFGNODE aISCSINode);
365 HRESULT init (VirtualBox *aVirtualBox);
366 void uninit();
367
368 // IHardDisk properties
369 STDMETHOD(COMGETTER(Description)) (BSTR *aDescription);
370 STDMETHOD(COMSETTER(Description)) (INPTR BSTR aDescription);
371 STDMETHOD(COMGETTER(Size)) (ULONG64 *aSize);
372 STDMETHOD(COMGETTER(ActualSize)) (ULONG64 *aActualSize);
373
374 // IISCSIHardDisk properties
375 STDMETHOD(COMGETTER(Server)) (BSTR *aServer);
376 STDMETHOD(COMSETTER(Server)) (INPTR BSTR aServer);
377 STDMETHOD(COMGETTER(Port)) (USHORT *aPort);
378 STDMETHOD(COMSETTER(Port)) (USHORT aPort);
379 STDMETHOD(COMGETTER(Target)) (BSTR *aTarget);
380 STDMETHOD(COMSETTER(Target)) (INPTR BSTR aTarget);
381 STDMETHOD(COMGETTER(Lun)) (ULONG64 *aLun);
382 STDMETHOD(COMSETTER(Lun)) (ULONG64 aLun);
383 STDMETHOD(COMGETTER(UserName)) (BSTR *aUserName);
384 STDMETHOD(COMSETTER(UserName)) (INPTR BSTR aUserName);
385 STDMETHOD(COMGETTER(Password)) (BSTR *aPassword);
386 STDMETHOD(COMSETTER(Password)) (INPTR BSTR aPassword);
387
388 // public methods for internal purposes only
389
390 const Bstr &server() const { return mServer; }
391 USHORT port() const { return mPort; }
392 const Bstr &target() const { return mTarget; }
393 ULONG64 lun() const { return mLun; }
394 const Bstr &userName() const { return mUserName; }
395 const Bstr &password() const { return mPassword; }
396
397 HRESULT trySetRegistered (BOOL aRegistered);
398 HRESULT getAccessible (Bstr &aAccessError);
399
400 HRESULT saveSettings (CFGNODE aHDNode, CFGNODE aStorageNode);
401
402 Bstr toString (bool aShort = false);
403
404 HRESULT cloneToImage (const Guid &aId, const Utf8Str &aTargetPath,
405 Progress *aProgress);
406 HRESULT createDiffImage (const Guid &aId, const Utf8Str &aTargetPath,
407 Progress *aProgress);
408
409public:
410
411 // for VirtualBoxSupportErrorInfoImpl
412 static const wchar_t *getComponentName() { return L"ISCSIHardDisk"; }
413
414private:
415
416 HRESULT queryInformation (Bstr &aAccessError);
417
418 Bstr mDescription;
419
420 ULONG64 mSize;
421 ULONG64 mActualSize;
422
423 Bstr mServer;
424 USHORT mPort;
425 Bstr mTarget;
426 ULONG64 mLun;
427 Bstr mUserName;
428 Bstr mPassword;
429};
430
431////////////////////////////////////////////////////////////////////////////////
432
433class ATL_NO_VTABLE HVMDKImage :
434 public HardDisk,
435 public VirtualBoxSupportTranslation <HVMDKImage>,
436 public IVMDKImage
437{
438
439public:
440
441 VIRTUALBOXSUPPORTTRANSLATION_OVERRIDE(HVMDKImage)
442
443 DECLARE_NOT_AGGREGATABLE(HVMDKImage)
444
445 DECLARE_PROTECT_FINAL_CONSTRUCT()
446
447 BEGIN_COM_MAP(HVMDKImage)
448 COM_INTERFACE_ENTRY(ISupportErrorInfo)
449 COM_INTERFACE_ENTRY(IHardDisk)
450 COM_INTERFACE_ENTRY(IVMDKImage)
451 END_COM_MAP()
452
453 NS_DECL_ISUPPORTS
454
455 HRESULT FinalConstruct();
456 void FinalRelease();
457
458 // public initializer/uninitializer for internal purposes only
459
460 HRESULT init (VirtualBox *aVirtualBox, HardDisk *aParent,
461 CFGNODE aHDNode, CFGNODE aVMDKNode);
462 HRESULT init (VirtualBox *aVirtualBox, HardDisk *aParent,
463 INPTR BSTR aFilePath, BOOL aRegistered = FALSE);
464 void uninit();
465
466 // IHardDisk properties
467 STDMETHOD(COMGETTER(Description)) (BSTR *aDescription);
468 STDMETHOD(COMSETTER(Description)) (INPTR BSTR aDescription);
469 STDMETHOD(COMGETTER(Size)) (ULONG64 *aSize);
470 STDMETHOD(COMGETTER(ActualSize)) (ULONG64 *aActualSize);
471
472 // IVirtualDiskImage properties
473 STDMETHOD(COMGETTER(FilePath)) (BSTR *aFilePath);
474 STDMETHOD(COMSETTER(FilePath)) (INPTR BSTR aFilePath);
475 STDMETHOD(COMGETTER(Created)) (BOOL *aCreated);
476
477 // IVirtualDiskImage methods
478 STDMETHOD(CreateDynamicImage) (ULONG64 aSize, IProgress **aProgress);
479 STDMETHOD(CreateFixedImage) (ULONG64 aSize, IProgress **aProgress);
480 STDMETHOD(DeleteImage)();
481
482 // public methods for internal purposes only
483
484 const Bstr &filePath() const { return mFilePath; }
485 const Bstr &filePathFull() const { return mFilePathFull; }
486
487 HRESULT trySetRegistered (BOOL aRegistered);
488 HRESULT getAccessible (Bstr &aAccessError);
489
490 HRESULT saveSettings (CFGNODE aHDNode, CFGNODE aStorageNode);
491
492 void updatePath (const char *aOldPath, const char *aNewPath);
493
494 Bstr toString (bool aShort = false);
495
496 HRESULT cloneToImage (const Guid &aId, const Utf8Str &aTargetPath,
497 Progress *aProgress);
498 HRESULT createDiffImage (const Guid &aId, const Utf8Str &aTargetPath,
499 Progress *aProgress);
500
501 // for VirtualBoxSupportErrorInfoImpl
502 static const wchar_t *getComponentName() { return L"VMDKImage"; }
503
504private:
505
506 HRESULT setFilePath (const BSTR aFilePath);
507 HRESULT queryInformation (Bstr *aAccessError);
508 HRESULT createImage (ULONG64 aSize, BOOL aDynamic, IProgress **aProgress);
509
510 /** VDI asynchronous operation thread function */
511 static DECLCALLBACK(int) VDITaskThread (RTTHREAD thread, void *pvUser);
512
513 static DECLCALLBACK(void) VDError (void *pvUser, int rc, RT_SRC_POS_DECL,
514 const char *pszFormat, va_list va);
515
516 enum State
517 {
518 NotCreated,
519 Created,
520 /* the following must be greater than Created */
521 Accessible,
522 };
523
524 State mState;
525
526 RTSEMEVENTMULTI mStateCheckSem;
527 ULONG mStateCheckWaiters;
528
529 Bstr mDescription;
530
531 ULONG64 mSize;
532 ULONG64 mActualSize;
533
534 Bstr mFilePath;
535 Bstr mFilePathFull;
536
537 PVBOXHDD mContainer;
538
539 Utf8Str mLastVDError;
540
541 friend class HardDisk;
542};
543
544
545COM_DECL_READONLY_ENUM_AND_COLLECTION (HardDisk)
546
547#endif // ____H_HARDDISKIMPL
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