VirtualBox

source: vbox/trunk/src/VBox/Main/include/HardDisk2Impl.h@ 15468

Last change on this file since 15468 was 15318, checked in by vboxsync, 16 years ago

Main: Fixed a deadlock in VBoxSVC when attaching a hard disk indirectly, through creating a new diff for it.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 10.5 KB
Line 
1/* $Id: HardDisk2Impl.h 15318 2008-12-11 17:27:02Z vboxsync $ */
2
3/** @file
4 *
5 * VirtualBox COM class implementation
6 */
7
8/*
9 * Copyright (C) 2008 Sun Microsystems, Inc.
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
20 * Clara, CA 95054 USA or visit http://www.sun.com if you need
21 * additional information or have any questions.
22 */
23
24#ifndef ____H_HARDDISK2IMPL
25#define ____H_HARDDISK2IMPL
26
27#include "VirtualBoxBase.h"
28
29#include "VirtualBoxImpl.h"
30#include "HardDiskFormatImpl.h"
31#include "MediumImpl.h"
32
33#include <VBox/com/SupportErrorInfo.h>
34
35#include <VBox/VBoxHDD-new.h>
36
37#include <map>
38
39class Progress;
40
41////////////////////////////////////////////////////////////////////////////////
42
43/**
44 * The HardDisk2 component class implements the IHardDisk2 interface.
45 */
46class ATL_NO_VTABLE HardDisk2
47 : public com::SupportErrorInfoDerived <MediumBase, HardDisk2, IHardDisk2>
48 , public VirtualBoxBaseWithTypedChildrenNEXT <HardDisk2>
49 , public VirtualBoxSupportTranslation <HardDisk2>
50 , public IHardDisk2
51{
52public:
53
54 typedef VirtualBoxBaseWithTypedChildrenNEXT <HardDisk2>::DependentChildren
55 List;
56
57 class MergeChain;
58
59 VIRTUALBOXSUPPORTTRANSLATION_OVERRIDE (HardDisk2)
60
61 DECLARE_NOT_AGGREGATABLE (HardDisk2)
62
63 DECLARE_PROTECT_FINAL_CONSTRUCT()
64
65 BEGIN_COM_MAP (HardDisk2)
66 COM_INTERFACE_ENTRY (ISupportErrorInfo)
67 COM_INTERFACE_ENTRY2 (IMedium, MediumBase)
68 COM_INTERFACE_ENTRY (IHardDisk2)
69 END_COM_MAP()
70
71 NS_DECL_ISUPPORTS
72
73 DECLARE_EMPTY_CTOR_DTOR (HardDisk2)
74
75 HRESULT FinalConstruct();
76 void FinalRelease();
77
78 // public initializer/uninitializer for internal purposes only
79 HRESULT init (VirtualBox *aVirtualBox, CBSTR aFormat,
80 CBSTR aLocation);
81 HRESULT init (VirtualBox *aVirtualBox,
82 CBSTR aLocation);
83 HRESULT init (VirtualBox *aVirtualBox, HardDisk2 *aParent,
84 const settings::Key &aNode);
85 void uninit();
86
87 // IMedium properties & methods
88 COM_FORWARD_IMedium_TO_BASE (MediumBase)
89
90 // IHardDisk2 properties
91 STDMETHOD(COMGETTER(Format)) (BSTR *aFormat);
92 STDMETHOD(COMGETTER(Type)) (HardDiskType_T *aType);
93 STDMETHOD(COMSETTER(Type)) (HardDiskType_T aType);
94 STDMETHOD(COMGETTER(Parent)) (IHardDisk2 **aParent);
95 STDMETHOD(COMGETTER(Children)) (ComSafeArrayOut (IHardDisk2 *, aChildren));
96 STDMETHOD(COMGETTER(Root)) (IHardDisk2 **aRoot);
97 STDMETHOD(COMGETTER(ReadOnly)) (BOOL *aReadOnly);
98 STDMETHOD(COMGETTER(LogicalSize)) (ULONG64 *aLogicalSize);
99
100 // IHardDisk2 methods
101 STDMETHOD(GetProperty) (IN_BSTR aName, BSTR *aValue);
102 STDMETHOD(SetProperty) (IN_BSTR aName, IN_BSTR aValue);
103 STDMETHOD(GetProperties) (IN_BSTR aNames,
104 ComSafeArrayOut (BSTR, aReturnNames),
105 ComSafeArrayOut (BSTR, aReturnValues));
106 STDMETHOD(SetProperties) (ComSafeArrayIn (IN_BSTR, aNames),
107 ComSafeArrayIn (IN_BSTR, aValues));
108 STDMETHOD(CreateDynamicStorage) (ULONG64 aLogicalSize, IProgress **aProgress);
109 STDMETHOD(CreateFixedStorage) (ULONG64 aLogicalSize, IProgress **aProgress);
110 STDMETHOD(DeleteStorage) (IProgress **aProgress);
111 STDMETHOD(CreateDiffStorage) (IHardDisk2 *aTarget, IProgress **aProgress);
112 STDMETHOD(MergeTo) (IN_GUID aTargetId, IProgress **aProgress);
113 STDMETHOD(CloneTo) (IHardDisk2 *aTarget, IProgress **aProgress);
114 STDMETHOD(FlattenTo) (IHardDisk2 *aTarget, IProgress **aProgress);
115
116 // public methods for internal purposes only
117
118 /**
119 * Shortcut to VirtualBoxBaseWithTypedChildrenNEXT::dependentChildren().
120 */
121 const List &children() const { return dependentChildren(); }
122
123 void updatePaths (const char *aOldPath, const char *aNewPath);
124
125 ComObjPtr <HardDisk2> root (uint32_t *aLevel = NULL);
126
127 bool isReadOnly();
128
129 HRESULT saveSettings (settings::Key &aParentNode);
130
131 HRESULT compareLocationTo (const char *aLocation, int &aResult);
132
133 /**
134 * Shortcut to #deleteStorage() that doesn't wait for operation completion
135 * and implies the progress object will be used for waiting.
136 */
137 HRESULT deleteStorageNoWait (ComObjPtr <Progress> &aProgress)
138 { return deleteStorage (&aProgress, false /* aWait */); }
139
140 /**
141 * Shortcut to #deleteStorage() that wait for operation completion by
142 * blocking the current thread.
143 */
144 HRESULT deleteStorageAndWait (ComObjPtr <Progress> *aProgress = NULL)
145 { return deleteStorage (aProgress, true /* aWait */); }
146
147 /**
148 * Shortcut to #createDiffStorage() that doesn't wait for operation
149 * completion and implies the progress object will be used for waiting.
150 */
151 HRESULT createDiffStorageNoWait (ComObjPtr <HardDisk2> &aTarget,
152 ComObjPtr <Progress> &aProgress)
153 { return createDiffStorage (aTarget, &aProgress, false /* aWait */); }
154
155 /**
156 * Shortcut to #createDiffStorage() that wait for operation completion by
157 * blocking the current thread.
158 */
159 HRESULT createDiffStorageAndWait (ComObjPtr <HardDisk2> &aTarget,
160 ComObjPtr <Progress> *aProgress = NULL)
161 { return createDiffStorage (aTarget, aProgress, true /* aWait */); }
162
163 HRESULT prepareMergeTo (HardDisk2 *aTarget, MergeChain * &aChain,
164 bool aIgnoreAttachments = false);
165
166 /**
167 * Shortcut to #mergeTo() that doesn't wait for operation completion and
168 * implies the progress object will be used for waiting.
169 */
170 HRESULT mergeToNoWait (MergeChain *aChain,
171 ComObjPtr <Progress> &aProgress)
172 { return mergeTo (aChain, &aProgress, false /* aWait */); }
173
174 /**
175 * Shortcut to #mergeTo() that wait for operation completion by
176 * blocking the current thread.
177 */
178 HRESULT mergeToAndWait (MergeChain *aChain,
179 ComObjPtr <Progress> *aProgress = NULL)
180 { return mergeTo (aChain, aProgress, true /* aWait */); }
181
182 void cancelMergeTo (MergeChain *aChain);
183
184 Utf8Str name();
185
186 HRESULT prepareDiscard (MergeChain * &aChain);
187 HRESULT discard (ComObjPtr <Progress> &aProgress, MergeChain *aChain);
188 void cancelDiscard (MergeChain *aChain);
189
190 /** Returns a preferred format for a differencing hard disk. */
191 Bstr preferredDiffFormat();
192
193 // unsafe inline public methods for internal purposes only (ensure there is
194 // a caller and a read lock before calling them!)
195
196 ComObjPtr <HardDisk2> parent() const { return static_cast <HardDisk2 *> (mParent); }
197 HardDiskType_T type() const { return mm.type; }
198
199 /** For com::SupportErrorInfoImpl. */
200 static const char *ComponentName() { return "HardDisk2"; }
201
202protected:
203
204 HRESULT deleteStorage (ComObjPtr <Progress> *aProgress, bool aWait);
205
206 HRESULT createDiffStorage (ComObjPtr <HardDisk2> &aTarget,
207 ComObjPtr <Progress> *aProgress,
208 bool aWait);
209
210 HRESULT mergeTo (MergeChain *aChain,
211 ComObjPtr <Progress> *aProgress,
212 bool aWait);
213
214 /**
215 * Returns VirtualBox::hardDiskTreeHandle(), for convenience. Don't forget
216 * to follow these locking rules:
217 *
218 * 1. The write lock on this handle must be either held alone on the thread
219 * or requested *after* the VirtualBox object lock. Mixing with other
220 * locks is prohibited.
221 *
222 * 2. The read lock on this handle may be intermixed with any other lock
223 * with the exception that it must be requested *after* the VirtualBox
224 * object lock.
225 */
226 RWLockHandle *treeLock() { return mVirtualBox->hardDiskTreeLockHandle(); }
227
228 /** Reimplements VirtualBoxWithTypedChildren::childrenLock() to return
229 * treeLock(). */
230 RWLockHandle *childrenLock() { return treeLock(); }
231
232private:
233
234 HRESULT setLocation (CBSTR aLocation);
235 HRESULT setFormat (CBSTR aFormat);
236
237 HRESULT queryInfo();
238
239 HRESULT canClose();
240 HRESULT canAttach (const Guid &aMachineId,
241 const Guid &aSnapshotId);
242
243 HRESULT unregisterWithVirtualBox();
244
245 Utf8Str vdError (int aVRC);
246
247 static DECLCALLBACK(void) vdErrorCall (void *pvUser, int rc, RT_SRC_POS_DECL,
248 const char *pszFormat, va_list va);
249
250 static DECLCALLBACK(int) vdProgressCall (PVM /* pVM */, unsigned uPercent,
251 void *pvUser);
252
253 static DECLCALLBACK(bool) vdConfigAreKeysValid (void *pvUser,
254 const char *pszzValid);
255 static DECLCALLBACK(int) vdConfigQuerySize (void *pvUser, const char *pszName,
256 size_t *pcbValue);
257 static DECLCALLBACK(int) vdConfigQuery (void *pvUser, const char *pszName,
258 char *pszValue, size_t cchValue);
259
260 static DECLCALLBACK(int) taskThread (RTTHREAD thread, void *pvUser);
261
262 /** weak parent */
263 ComObjPtr <HardDisk2, ComWeakRef> mParent;
264
265 struct Task;
266 friend struct Task;
267
268 struct Data
269 {
270 Data() : type (HardDiskType_Normal), logicalSize (0)
271 , implicit (false), numCreateDiffTasks (0)
272 , vdProgress (NULL) , vdDiskIfaces (NULL) {}
273
274 const Bstr format;
275 ComObjPtr <HardDiskFormat> formatObj;
276
277 HardDiskType_T type;
278 uint64_t logicalSize; /*< In MBytes. */
279
280 typedef std::map <Bstr, Bstr> PropertyMap;
281 PropertyMap properties;
282
283 bool implicit : 1;
284
285 uint32_t numCreateDiffTasks;
286
287 Utf8Str vdError; /*< Error remembered by the VD error callback. */
288 Progress *vdProgress; /*< Progress for the VD progress callback. */
289
290 VDINTERFACE vdIfError;
291 VDINTERFACEERROR vdIfCallsError;
292
293 VDINTERFACE vdIfProgress;
294 VDINTERFACEPROGRESS vdIfCallsProgress;
295
296 VDINTERFACE vdIfConfig;
297 VDINTERFACECONFIG vdIfCallsConfig;
298
299 VDINTERFACE vdIfTcpNet;
300 VDINTERFACETCPNET vdIfCallsTcpNet;
301
302 PVDINTERFACE vdDiskIfaces;
303 };
304
305 Data mm;
306};
307
308#endif /* ____H_HARDDISK2IMPL */
309
310/* vi: set tabstop=4 shiftwidth=4 expandtab: */
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