VirtualBox

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

Last change on this file since 25326 was 25326, checked in by vboxsync, 15 years ago

Main/Machine+MediumAttachment: fix loading the passthrough setting

File size: 10.0 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 aPassthrough Wether accesses are directly passed to the host drive.
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 aPassthrough)
113{
114 LogFlowThisFuncEnter();
115 LogFlowThisFunc(("aParent=%p aMedium=%p aControllerName=%ls aPort=%d aDevice=%d aType=%d aPassthrough=%d\n", aParent, aMedium, aControllerName.raw(), aPort, aDevice, aType, aPassthrough));
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 = aPassthrough;
136 /* Newly created attachments never have an implicitly created medium
137 * associated with them. Implicit diff image creation happens later. */
138 m->bd->fImplicit = false;
139
140 /* Confirm a successful initialization when it's the case */
141 autoInitSpan.setSucceeded();
142
143 /* Construct a short log name for this attachment. */
144 Utf8Str ctlName(aControllerName);
145 const char *psz = strpbrk(ctlName.c_str(), " \t:-");
146 mLogName = Utf8StrFmt("MA%p[%.*s:%u:%u:%s%s]",
147 this,
148 psz ? psz - ctlName.c_str() : 4, ctlName.c_str(),
149 aPort, aDevice, Global::stringifyDeviceType(aType),
150 m->bd->fImplicit ? ":I" : "");
151
152 LogFlowThisFunc(("LEAVE - %s\n", getLogName()));
153 return S_OK;
154}
155
156/**
157 * Uninitializes the instance.
158 * Called from FinalRelease().
159 */
160void MediumAttachment::uninit()
161{
162 LogFlowThisFunc(("ENTER - %s\n", getLogName()));
163
164 /* Enclose the state transition Ready->InUninit->NotReady */
165 AutoUninitSpan autoUninitSpan(this);
166 if (autoUninitSpan.uninitDone())
167 return;
168
169 m->bd.free();
170
171 unconst(m->pMachine).setNull();
172
173 delete m;
174 m = NULL;
175
176 LogFlowThisFuncLeave();
177}
178
179// IHardDiskAttachment properties
180/////////////////////////////////////////////////////////////////////////////
181
182STDMETHODIMP MediumAttachment::COMGETTER(Medium)(IMedium **aHardDisk)
183{
184 LogFlowThisFuncEnter();
185
186 CheckComArgOutPointerValid(aHardDisk);
187
188 AutoCaller autoCaller(this);
189 if (FAILED(autoCaller.rc())) return autoCaller.rc();
190
191 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
192
193 m->bd->pMedium.queryInterfaceTo(aHardDisk);
194
195 LogFlowThisFuncLeave();
196 return S_OK;
197}
198
199STDMETHODIMP MediumAttachment::COMGETTER(Controller)(BSTR *aController)
200{
201 LogFlowThisFuncEnter();
202
203 CheckComArgOutPointerValid(aController);
204
205 AutoCaller autoCaller(this);
206 if (FAILED(autoCaller.rc())) return autoCaller.rc();
207
208 /* m->controller is constant during life time, no need to lock */
209 m->bd->bstrControllerName.cloneTo(aController);
210
211 LogFlowThisFuncLeave();
212 return S_OK;
213}
214
215STDMETHODIMP MediumAttachment::COMGETTER(Port)(LONG *aPort)
216{
217 LogFlowThisFuncEnter();
218
219 CheckComArgOutPointerValid(aPort);
220
221 AutoCaller autoCaller(this);
222 if (FAILED(autoCaller.rc())) return autoCaller.rc();
223
224 /* m->bd->port is constant during life time, no need to lock */
225 *aPort = m->bd->lPort;
226
227 LogFlowThisFuncLeave();
228 return S_OK;
229}
230
231STDMETHODIMP MediumAttachment::COMGETTER(Device)(LONG *aDevice)
232{
233 LogFlowThisFuncEnter();
234
235 CheckComArgOutPointerValid(aDevice);
236
237 AutoCaller autoCaller(this);
238 if (FAILED(autoCaller.rc())) return autoCaller.rc();
239
240 /* m->bd->device is constant during life time, no need to lock */
241 *aDevice = m->bd->lDevice;
242
243 LogFlowThisFuncLeave();
244 return S_OK;
245}
246
247STDMETHODIMP MediumAttachment::COMGETTER(Type)(DeviceType_T *aType)
248{
249 LogFlowThisFuncEnter();
250
251 CheckComArgOutPointerValid(aType);
252
253 AutoCaller autoCaller(this);
254 if (FAILED(autoCaller.rc())) return autoCaller.rc();
255
256 /* m->bd->type is constant during life time, no need to lock */
257 *aType = m->bd->type;
258
259 LogFlowThisFuncLeave();
260 return S_OK;
261}
262
263STDMETHODIMP MediumAttachment::COMGETTER(Passthrough)(BOOL *aPassthrough)
264{
265 LogFlowThisFuncEnter();
266
267 CheckComArgOutPointerValid(aPassthrough);
268
269 AutoCaller autoCaller(this);
270 if (FAILED(autoCaller.rc())) return autoCaller.rc();
271
272 AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
273
274 *aPassthrough = m->bd->fPassthrough;
275
276 LogFlowThisFuncLeave();
277 return S_OK;
278}
279
280/**
281 * @note Locks this object for writing.
282 */
283bool MediumAttachment::rollback()
284{
285 LogFlowThisFunc(("ENTER - %s\n", getLogName()));
286
287 /* sanity */
288 AutoCaller autoCaller(this);
289 AssertComRCReturn (autoCaller.rc(), false);
290
291 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
292
293 bool changed = false;
294
295 if (m->bd.isBackedUp())
296 {
297 /* we need to check all data to see whether anything will be changed
298 * after rollback */
299 changed = m->bd.hasActualChanges();
300 m->bd.rollback();
301 }
302
303 LogFlowThisFunc(("LEAVE - %s - returning %RTbool\n", getLogName(), changed));
304 return changed;
305}
306
307/**
308 * @note Locks this object for writing.
309 */
310void MediumAttachment::commit()
311{
312 LogFlowThisFuncEnter();
313
314 /* sanity */
315 AutoCaller autoCaller(this);
316 AssertComRCReturnVoid (autoCaller.rc());
317
318 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
319
320 if (m->bd.isBackedUp())
321 m->bd.commit();
322
323 LogFlowThisFuncLeave();
324}
325
326bool MediumAttachment::isImplicit() const
327{
328 return m->bd->fImplicit;
329}
330
331void MediumAttachment::setImplicit(bool aImplicit)
332{
333 m->bd->fImplicit = aImplicit;
334}
335
336const ComObjPtr<Medium>& MediumAttachment::getMedium() const
337{
338 return m->bd->pMedium;
339}
340
341Bstr MediumAttachment::getControllerName() const
342{
343 return m->bd->bstrControllerName;
344}
345
346LONG MediumAttachment::getPort() const
347{
348 return m->bd->lPort;
349}
350
351LONG MediumAttachment::getDevice() const
352{
353 return m->bd->lDevice;
354}
355
356DeviceType_T MediumAttachment::getType() const
357{
358 return m->bd->type;
359}
360
361bool MediumAttachment::getPassthrough() const
362{
363 AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
364 return m->bd->fPassthrough;
365}
366
367bool MediumAttachment::matches(CBSTR aControllerName, LONG aPort, LONG aDevice)
368{
369 return ( aControllerName == m->bd->bstrControllerName
370 && aPort == m->bd->lPort
371 && aDevice == m->bd->lDevice);
372}
373
374/** Must be called from under this object's write lock. */
375void MediumAttachment::updateMedium(const ComObjPtr<Medium> &aMedium, bool aImplicit)
376{
377 m->bd.backup();
378 m->bd->pMedium = aMedium;
379 m->bd->fImplicit = aImplicit;
380}
381
382/** Must be called from under this object's write lock. */
383void MediumAttachment::updatePassthrough(bool aPassthrough)
384{
385 m->bd.backup();
386 m->bd->fPassthrough = aPassthrough;
387}
388
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