VirtualBox

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

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

Automated rebranding to Oracle copyright/license strings via filemuncher

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