VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/MediumFormatImpl.cpp@ 37586

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

Main/Medium: Fix incorrect forcing of absolute paths for non-file based media. Triggered with iSCSI, causing strange full location values. Also clean up code a bit which checks backend capabilities.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.3 KB
Line 
1/* $Id: MediumFormatImpl.cpp 37586 2011-06-22 11:49:40Z vboxsync $ */
2/** @file
3 *
4 * VirtualBox COM class implementation
5 */
6
7/*
8 * Copyright (C) 2008-2011 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "MediumFormatImpl.h"
20#include "AutoCaller.h"
21#include "Logging.h"
22
23#include <VBox/vd.h>
24
25#include <iprt/cpp/utils.h>
26
27// constructor / destructor
28/////////////////////////////////////////////////////////////////////////////
29
30DEFINE_EMPTY_CTOR_DTOR(MediumFormat)
31
32HRESULT MediumFormat::FinalConstruct()
33{
34 return BaseFinalConstruct();
35}
36
37void MediumFormat::FinalRelease()
38{
39 uninit();
40
41 BaseFinalRelease();
42}
43
44// public initializer/uninitializer for internal purposes only
45/////////////////////////////////////////////////////////////////////////////
46
47/**
48 * Initializes the hard disk format object.
49 *
50 * @param aVDInfo Pointer to a backend info object.
51 */
52HRESULT MediumFormat::init(const VDBACKENDINFO *aVDInfo)
53{
54 LogFlowThisFunc(("aVDInfo=%p\n", aVDInfo));
55
56 ComAssertRet(aVDInfo, E_INVALIDARG);
57
58 /* Enclose the state transition NotReady->InInit->Ready */
59 AutoInitSpan autoInitSpan(this);
60 AssertReturn(autoInitSpan.isOk(), E_FAIL);
61
62 /* The ID of the backend */
63 unconst(m.strId) = aVDInfo->pszBackend;
64 /* The Name of the backend */
65 /* Use id for now as long as VDBACKENDINFO hasn't any extra
66 * name/description field. */
67 unconst(m.strName) = aVDInfo->pszBackend;
68 /* The capabilities of the backend. Assumes 1:1 mapping! */
69 unconst(m.capabilities) = aVDInfo->uBackendCaps;
70 /* Save the supported file extensions in a list */
71 if (aVDInfo->paFileExtensions)
72 {
73 PCVDFILEEXTENSION papExtension = aVDInfo->paFileExtensions;
74 while (papExtension->pszExtension != NULL)
75 {
76 DeviceType_T devType;
77
78 unconst(m.llFileExtensions).push_back(papExtension->pszExtension);
79
80 switch(papExtension->enmType)
81 {
82 case VDTYPE_HDD:
83 devType = DeviceType_HardDisk;
84 break;
85 case VDTYPE_DVD:
86 devType = DeviceType_DVD;
87 break;
88 case VDTYPE_FLOPPY:
89 devType = DeviceType_Floppy;
90 break;
91 default:
92 AssertMsgFailed(("Invalid enm type %d!\n", papExtension->enmType));
93 return E_INVALIDARG;
94 }
95
96 unconst(m.llDeviceTypes).push_back(devType);
97 ++papExtension;
98 }
99 }
100 /* Save a list of configure properties */
101 if (aVDInfo->paConfigInfo)
102 {
103 PCVDCONFIGINFO pa = aVDInfo->paConfigInfo;
104 /* Walk through all available keys */
105 while (pa->pszKey != NULL)
106 {
107 Utf8Str defaultValue("");
108 DataType_T dt;
109 ULONG flags = static_cast <ULONG>(pa->uKeyFlags);
110 /* Check for the configure data type */
111 switch (pa->enmValueType)
112 {
113 case VDCFGVALUETYPE_INTEGER:
114 {
115 dt = DataType_Int32;
116 /* If there is a default value get them in the right format */
117 if (pa->pszDefaultValue)
118 defaultValue = pa->pszDefaultValue;
119 break;
120 }
121 case VDCFGVALUETYPE_BYTES:
122 {
123 dt = DataType_Int8;
124 /* If there is a default value get them in the right format */
125 if (pa->pszDefaultValue)
126 {
127 /* Copy the bytes over - treated simply as a string */
128 defaultValue = pa->pszDefaultValue;
129 flags |= DataFlags_Array;
130 }
131 break;
132 }
133 case VDCFGVALUETYPE_STRING:
134 {
135 dt = DataType_String;
136 /* If there is a default value get them in the right format */
137 if (pa->pszDefaultValue)
138 defaultValue = pa->pszDefaultValue;
139 break;
140 }
141
142 default:
143 AssertMsgFailed(("Invalid enm type %d!\n", pa->enmValueType));
144 return E_INVALIDARG;
145 }
146
147 /// @todo add extendedFlags to Property when we reach the 32 bit
148 /// limit (or make the argument ULONG64 after checking that COM is
149 /// capable of defining enums (used to represent bit flags) that
150 /// contain 64-bit values)
151 ComAssertRet(pa->uKeyFlags == ((ULONG)pa->uKeyFlags), E_FAIL);
152
153 /* Create one property structure */
154 const Property prop = { Utf8Str(pa->pszKey),
155 Utf8Str(""),
156 dt,
157 flags,
158 defaultValue };
159 unconst(m.llProperties).push_back(prop);
160 ++pa;
161 }
162 }
163
164 /* Confirm a successful initialization */
165 autoInitSpan.setSucceeded();
166
167 return S_OK;
168}
169
170/**
171 * Uninitializes the instance and sets the ready flag to FALSE.
172 * Called either from FinalRelease() or by the parent when it gets destroyed.
173 */
174void MediumFormat::uninit()
175{
176 LogFlowThisFunc(("\n"));
177
178 /* Enclose the state transition Ready->InUninit->NotReady */
179 AutoUninitSpan autoUninitSpan(this);
180 if (autoUninitSpan.uninitDone())
181 return;
182
183 unconst(m.llProperties).clear();
184 unconst(m.llFileExtensions).clear();
185 unconst(m.llDeviceTypes).clear();
186 unconst(m.capabilities) = 0;
187 unconst(m.strName).setNull();
188 unconst(m.strId).setNull();
189}
190
191// IMediumFormat properties
192/////////////////////////////////////////////////////////////////////////////
193
194STDMETHODIMP MediumFormat::COMGETTER(Id)(BSTR *aId)
195{
196 CheckComArgOutPointerValid(aId);
197
198 AutoCaller autoCaller(this);
199 if (FAILED(autoCaller.rc())) return autoCaller.rc();
200
201 /* this is const, no need to lock */
202 m.strId.cloneTo(aId);
203
204 return S_OK;
205}
206
207STDMETHODIMP MediumFormat::COMGETTER(Name)(BSTR *aName)
208{
209 CheckComArgOutPointerValid(aName);
210
211 AutoCaller autoCaller(this);
212 if (FAILED(autoCaller.rc())) return autoCaller.rc();
213
214 /* this is const, no need to lock */
215 m.strName.cloneTo(aName);
216
217 return S_OK;
218}
219
220STDMETHODIMP MediumFormat::COMGETTER(Capabilities)(ULONG *aCaps)
221{
222 CheckComArgOutPointerValid(aCaps);
223
224 AutoCaller autoCaller(this);
225 if (FAILED(autoCaller.rc())) return autoCaller.rc();
226
227 /* m.capabilities is const, no need to lock */
228
229 /// @todo add COMGETTER(ExtendedCapabilities) when we reach the 32 bit
230 /// limit (or make the argument ULONG64 after checking that COM is capable
231 /// of defining enums (used to represent bit flags) that contain 64-bit
232 /// values)
233 ComAssertRet(m.capabilities == ((ULONG)m.capabilities), E_FAIL);
234
235 *aCaps = (ULONG) m.capabilities;
236
237 return S_OK;
238}
239
240STDMETHODIMP MediumFormat::DescribeFileExtensions(ComSafeArrayOut(BSTR, aFileExtensions),
241 ComSafeArrayOut(DeviceType_T, aDeviceTypes))
242{
243 CheckComArgOutSafeArrayPointerValid(aFileExtensions);
244
245 AutoCaller autoCaller(this);
246 if (FAILED(autoCaller.rc())) return autoCaller.rc();
247
248 /* this is const, no need to lock */
249 com::SafeArray<BSTR> fileExtentions(m.llFileExtensions.size());
250 int i = 0;
251 for (StrList::const_iterator it = m.llFileExtensions.begin();
252 it != m.llFileExtensions.end();
253 ++it, ++i)
254 (*it).cloneTo(&fileExtentions[i]);
255 fileExtentions.detachTo(ComSafeArrayOutArg(aFileExtensions));
256
257 com::SafeArray<DeviceType_T> deviceTypes(m.llDeviceTypes.size());
258 i = 0;
259 for (DeviceTypeList::const_iterator it = m.llDeviceTypes.begin();
260 it != m.llDeviceTypes.end();
261 ++it, ++i)
262 deviceTypes[i] = (*it);
263 deviceTypes.detachTo(ComSafeArrayOutArg(aDeviceTypes));
264
265 return S_OK;
266}
267
268STDMETHODIMP MediumFormat::DescribeProperties(ComSafeArrayOut(BSTR, aNames),
269 ComSafeArrayOut(BSTR, aDescriptions),
270 ComSafeArrayOut(DataType_T, aTypes),
271 ComSafeArrayOut(ULONG, aFlags),
272 ComSafeArrayOut(BSTR, aDefaults))
273{
274 CheckComArgOutSafeArrayPointerValid(aNames);
275 CheckComArgOutSafeArrayPointerValid(aDescriptions);
276 CheckComArgOutSafeArrayPointerValid(aTypes);
277 CheckComArgOutSafeArrayPointerValid(aFlags);
278 CheckComArgOutSafeArrayPointerValid(aDefaults);
279
280 AutoCaller autoCaller(this);
281 if (FAILED(autoCaller.rc())) return autoCaller.rc();
282
283 /* this is const, no need to lock */
284 size_t c = m.llProperties.size();
285 com::SafeArray<BSTR> propertyNames(c);
286 com::SafeArray<BSTR> propertyDescriptions(c);
287 com::SafeArray<DataType_T> propertyTypes(c);
288 com::SafeArray<ULONG> propertyFlags(c);
289 com::SafeArray<BSTR> propertyDefaults(c);
290
291 int i = 0;
292 for (PropertyList::const_iterator it = m.llProperties.begin();
293 it != m.llProperties.end();
294 ++it, ++i)
295 {
296 const Property &prop = (*it);
297 prop.strName.cloneTo(&propertyNames[i]);
298 prop.strDescription.cloneTo(&propertyDescriptions[i]);
299 propertyTypes[i] = prop.type;
300 propertyFlags[i] = prop.flags;
301 prop.strDefaultValue.cloneTo(&propertyDefaults[i]);
302 }
303
304 propertyNames.detachTo(ComSafeArrayOutArg(aNames));
305 propertyDescriptions.detachTo(ComSafeArrayOutArg(aDescriptions));
306 propertyTypes.detachTo(ComSafeArrayOutArg(aTypes));
307 propertyFlags.detachTo(ComSafeArrayOutArg(aFlags));
308 propertyDefaults.detachTo(ComSafeArrayOutArg(aDefaults));
309
310 return S_OK;
311}
312
313// IMediumFormat methods
314/////////////////////////////////////////////////////////////////////////////
315
316// public methods only for internal purposes
317/////////////////////////////////////////////////////////////////////////////
318/* vi: set tabstop=4 shiftwidth=4 expandtab: */
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