VirtualBox

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

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

Main: remove templates for 'weak' com pointers which do nothing anyway

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