VirtualBox

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

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

*: Added svn:keywords where missing.

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