VirtualBox

source: vbox/trunk/src/VBox/Main/MediumAttachmentImpl.cpp@ 25275

Last change on this file since 25275 was 25200, checked in by vboxsync, 14 years ago

Main: make MediumAttachment instance data private

File size: 9.8 KB
Line 
1/** @file
2 *
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2009 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#include "MediumAttachmentImpl.h"
23#include "MachineImpl.h"
24#include "MediumImpl.h"
25#include "Global.h"
26
27#include "Logging.h"
28
29////////////////////////////////////////////////////////////////////////////////
30//
31// private member data definition
32//
33////////////////////////////////////////////////////////////////////////////////
34
35struct BackupableMediumAttachmentData
36{
37 BackupableMediumAttachmentData()
38 : lPort(0),
39 lDevice(0),
40 type(DeviceType_Null),
41 fPassthrough(false),
42 fImplicit(false)
43 { }
44
45 bool operator==(const BackupableMediumAttachmentData &that) const
46 {
47 return this == &that
48 || (fPassthrough == that.fPassthrough);
49 }
50
51 ComObjPtr<Medium> pMedium;
52 /* Since MediumAttachment is not a first class citizen when it
53 * comes to managing settings, having a reference to the storage
54 * controller will not work - when settings are changed it will point
55 * to the old, uninitialized instance. Changing this requires
56 * substantial changes to MediumImpl.cpp. */
57 const Bstr bstrControllerName;
58 const LONG lPort;
59 const LONG lDevice;
60 const DeviceType_T type;
61 bool fPassthrough : 1;
62 bool fImplicit : 1;
63};
64
65struct MediumAttachment::Data
66{
67 Data()
68 { }
69
70 /** Reference to Machine object, for checking mutable state. */
71 const ComObjPtr<Machine, ComWeakRef> pMachine;
72 /* later: const ComObjPtr<MediumAttachment> mPeer; */
73
74 Backupable<BackupableMediumAttachmentData> bd;
75};
76
77// constructor / destructor
78/////////////////////////////////////////////////////////////////////////////
79
80HRESULT MediumAttachment::FinalConstruct()
81{
82 LogFlowThisFunc(("\n"));
83 return S_OK;
84}
85
86void MediumAttachment::FinalRelease()
87{
88 LogFlowThisFuncEnter();
89 uninit();
90 LogFlowThisFuncLeave();
91}
92
93// public initializer/uninitializer for internal purposes only
94/////////////////////////////////////////////////////////////////////////////
95
96/**
97 * Initializes the medium attachment object.
98 *
99 * @param aParent Machine object.
100 * @param aMedium Medium object.
101 * @param aController Controller the hard disk is attached to.
102 * @param aPort Port number.
103 * @param aDevice Device number on the port.
104 * @param aImplicit Wether the attachment contains an implicitly created diff.
105 */
106HRESULT MediumAttachment::init(Machine *aParent,
107 Medium *aMedium,
108 const Bstr &aControllerName,
109 LONG aPort,
110 LONG aDevice,
111 DeviceType_T aType,
112 bool aImplicit /*= false*/)
113{
114 LogFlowThisFuncEnter();
115 LogFlowThisFunc(("aParent=%p aMedium=%p aControllerName=%ls aPort=%d aDevice=%d aType=%d aImplicit=%d\n", aParent, aMedium, aControllerName.raw(), aPort, aDevice, aType, aImplicit));
116
117 if (aType == DeviceType_HardDisk)
118 AssertReturn(aMedium, E_INVALIDARG);
119
120 /* Enclose the state transition NotReady->InInit->Ready */
121 AutoInitSpan autoInitSpan(this);
122 AssertReturn(autoInitSpan.isOk(), E_FAIL);
123
124 m = new Data();
125
126 unconst(m->pMachine) = aParent;
127
128 m->bd.allocate();
129 m->bd->pMedium = aMedium;
130 unconst(m->bd->bstrControllerName) = aControllerName;
131 unconst(m->bd->lPort) = aPort;
132 unconst(m->bd->lDevice) = aDevice;
133 unconst(m->bd->type) = aType;
134
135 m->bd->fPassthrough = false;
136 m->bd->fImplicit = aImplicit;
137
138 /* Confirm a successful initialization when it's the case */
139 autoInitSpan.setSucceeded();
140
141 /* Construct a short log name for this attachment. */
142 Utf8Str ctlName(aControllerName);
143 const char *psz = strpbrk(ctlName.c_str(), " \t:-");
144 mLogName = Utf8StrFmt("MA%p[%.*s:%u:%u:%s%s]",
145 this,
146 psz ? psz - ctlName.c_str() : 4, ctlName.c_str(),
147 aPort, aDevice, Global::stringifyDeviceType(aType),
148 aImplicit ? ":I" : "");
149
150 LogFlowThisFunc(("LEAVE - %s\n", getLogName()));
151 return S_OK;
152}
153
154/**
155 * Uninitializes the instance.
156 * Called from FinalRelease().
157 */
158void MediumAttachment::uninit()
159{
160 LogFlowThisFunc(("ENTER - %s\n", getLogName()));
161
162 /* Enclose the state transition Ready->InUninit->NotReady */
163 AutoUninitSpan autoUninitSpan(this);
164 if (autoUninitSpan.uninitDone())
165 return;
166
167 m->bd.free();
168
169 unconst(m->pMachine).setNull();
170
171 delete m;
172 m = NULL;
173
174 LogFlowThisFuncLeave();
175}
176
177// IHardDiskAttachment properties
178/////////////////////////////////////////////////////////////////////////////
179
180STDMETHODIMP MediumAttachment::COMGETTER(Medium)(IMedium **aHardDisk)
181{
182 LogFlowThisFuncEnter();
183
184 CheckComArgOutPointerValid(aHardDisk);
185
186 AutoCaller autoCaller(this);
187 if (FAILED(autoCaller.rc())) return autoCaller.rc();
188
189 AutoReadLock alock(this);
190
191 m->bd->pMedium.queryInterfaceTo(aHardDisk);
192
193 LogFlowThisFuncLeave();
194 return S_OK;
195}
196
197STDMETHODIMP MediumAttachment::COMGETTER(Controller)(BSTR *aController)
198{
199 LogFlowThisFuncEnter();
200
201 CheckComArgOutPointerValid(aController);
202
203 AutoCaller autoCaller(this);
204 if (FAILED(autoCaller.rc())) return autoCaller.rc();
205
206 /* m->controller is constant during life time, no need to lock */
207 m->bd->bstrControllerName.cloneTo(aController);
208
209 LogFlowThisFuncLeave();
210 return S_OK;
211}
212
213STDMETHODIMP MediumAttachment::COMGETTER(Port)(LONG *aPort)
214{
215 LogFlowThisFuncEnter();
216
217 CheckComArgOutPointerValid(aPort);
218
219 AutoCaller autoCaller(this);
220 if (FAILED(autoCaller.rc())) return autoCaller.rc();
221
222 /* m->bd->port is constant during life time, no need to lock */
223 *aPort = m->bd->lPort;
224
225 LogFlowThisFuncLeave();
226 return S_OK;
227}
228
229STDMETHODIMP MediumAttachment::COMGETTER(Device)(LONG *aDevice)
230{
231 LogFlowThisFuncEnter();
232
233 CheckComArgOutPointerValid(aDevice);
234
235 AutoCaller autoCaller(this);
236 if (FAILED(autoCaller.rc())) return autoCaller.rc();
237
238 /* m->bd->device is constant during life time, no need to lock */
239 *aDevice = m->bd->lDevice;
240
241 LogFlowThisFuncLeave();
242 return S_OK;
243}
244
245STDMETHODIMP MediumAttachment::COMGETTER(Type)(DeviceType_T *aType)
246{
247 LogFlowThisFuncEnter();
248
249 CheckComArgOutPointerValid(aType);
250
251 AutoCaller autoCaller(this);
252 if (FAILED(autoCaller.rc())) return autoCaller.rc();
253
254 /* m->bd->type is constant during life time, no need to lock */
255 *aType = m->bd->type;
256
257 LogFlowThisFuncLeave();
258 return S_OK;
259}
260
261STDMETHODIMP MediumAttachment::COMGETTER(Passthrough)(BOOL *aPassthrough)
262{
263 LogFlowThisFuncEnter();
264
265 CheckComArgOutPointerValid(aPassthrough);
266
267 AutoCaller autoCaller(this);
268 if (FAILED(autoCaller.rc())) return autoCaller.rc();
269
270 AutoReadLock lock(this);
271
272 *aPassthrough = m->bd->fPassthrough;
273
274 LogFlowThisFuncLeave();
275 return S_OK;
276}
277
278/**
279 * @note Locks this object for writing.
280 */
281bool MediumAttachment::rollback()
282{
283 LogFlowThisFunc(("ENTER - %s\n", getLogName()));
284
285 /* sanity */
286 AutoCaller autoCaller(this);
287 AssertComRCReturn (autoCaller.rc(), false);
288
289 AutoWriteLock alock(this);
290
291 bool changed = false;
292
293 if (m->bd.isBackedUp())
294 {
295 /* we need to check all data to see whether anything will be changed
296 * after rollback */
297 changed = m->bd.hasActualChanges();
298 m->bd.rollback();
299 }
300
301 LogFlowThisFunc(("LEAVE - %s - returning %RTbool\n", getLogName(), changed));
302 return changed;
303}
304
305/**
306 * @note Locks this object for writing.
307 */
308void MediumAttachment::commit()
309{
310 LogFlowThisFuncEnter();
311
312 /* sanity */
313 AutoCaller autoCaller(this);
314 AssertComRCReturnVoid (autoCaller.rc());
315
316 AutoWriteLock alock(this);
317
318 if (m->bd.isBackedUp())
319 m->bd.commit();
320
321 LogFlowThisFuncLeave();
322}
323
324bool MediumAttachment::isImplicit() const
325{
326 return m->bd->fImplicit;
327}
328
329void MediumAttachment::setImplicit(bool aImplicit)
330{
331 m->bd->fImplicit = aImplicit;
332}
333
334const ComObjPtr<Medium>& MediumAttachment::getMedium() const
335{
336 return m->bd->pMedium;
337}
338
339Bstr MediumAttachment::getControllerName() const
340{
341 return m->bd->bstrControllerName;
342}
343
344LONG MediumAttachment::getPort() const
345{
346 return m->bd->lPort;
347}
348
349LONG MediumAttachment::getDevice() const
350{
351 return m->bd->lDevice;
352}
353
354DeviceType_T MediumAttachment::getType() const
355{
356 return m->bd->type;
357}
358
359bool MediumAttachment::getPassthrough() const
360{
361 AutoReadLock lock(this);
362 return m->bd->fPassthrough;
363}
364
365bool MediumAttachment::matches(CBSTR aControllerName, LONG aPort, LONG aDevice)
366{
367 return ( aControllerName == m->bd->bstrControllerName
368 && aPort == m->bd->lPort
369 && aDevice == m->bd->lDevice);
370}
371
372/** Must be called from under this object's write lock. */
373void MediumAttachment::updateMedium(const ComObjPtr<Medium> &aMedium, bool aImplicit)
374{
375 m->bd.backup();
376 m->bd->pMedium = aMedium;
377 m->bd->fImplicit = aImplicit;
378}
379
380/** Must be called from under this object's write lock. */
381void MediumAttachment::updatePassthrough(bool aPassthrough)
382{
383 m->bd.backup();
384 m->bd->fPassthrough = aPassthrough;
385}
386
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use