VirtualBox

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

Last change on this file since 30760 was 30681, checked in by vboxsync, 14 years ago

Main: COM header cleanup (remove obscure and unused templates), second try

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