VirtualBox

source: vbox/trunk/src/VBox/Main/src-all/SharedFolderImpl.cpp@ 46876

Last change on this file since 46876 was 46820, checked in by vboxsync, 11 years ago

Main: do not include VirtualBoxImpl.h from code ending in VBoxC (causes unnecessary rebuilds), and make sure that the code still builds with VBOX_WITH_RESOURCE_USAGE_API unset

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.8 KB
Line 
1/** @file
2 *
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2013 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 "SharedFolderImpl.h"
19#if !defined(VBOX_COM_INPROC)
20# include "VirtualBoxImpl.h"
21# include "MachineImpl.h"
22#endif
23#include "ConsoleImpl.h"
24
25#include "AutoCaller.h"
26#include "Logging.h"
27
28#include <iprt/param.h>
29#include <iprt/cpp/utils.h>
30#include <iprt/path.h>
31
32/////////////////////////////////////////////////////////////////////////////
33// SharedFolder::Data structure
34/////////////////////////////////////////////////////////////////////////////
35
36struct SharedFolder::Data
37{
38 Data()
39 : fWritable(false),
40 fAutoMount(false)
41 { }
42
43 const Utf8Str strName;
44 const Utf8Str strHostPath;
45 bool fWritable;
46 bool fAutoMount;
47 Utf8Str strLastAccessError;
48};
49
50// constructor / destructor
51/////////////////////////////////////////////////////////////////////////////
52
53SharedFolder::SharedFolder()
54 : mParent(NULL),
55#if !defined(VBOX_COM_INPROC)
56 mMachine(NULL),
57 mVirtualBox(NULL)
58#else
59 mConsole(NULL)
60#endif
61{
62 m = new Data;
63}
64
65SharedFolder::~SharedFolder()
66{
67 delete m;
68 m = NULL;
69}
70
71HRESULT SharedFolder::FinalConstruct()
72{
73 return BaseFinalConstruct();
74}
75
76void SharedFolder::FinalRelease()
77{
78 uninit();
79 BaseFinalRelease();
80}
81
82// public initializer/uninitializer for internal purposes only
83/////////////////////////////////////////////////////////////////////////////
84
85#if !defined(VBOX_COM_INPROC)
86/**
87 * Initializes the shared folder object.
88 *
89 * This variant initializes a machine instance that lives in the server address space.
90 *
91 * @param aMachine parent Machine object
92 * @param aName logical name of the shared folder
93 * @param aHostPath full path to the shared folder on the host
94 * @param aWritable writable if true, readonly otherwise
95 * @param aAutoMount if auto mounted by guest true, false otherwise
96 * @param fFailOnError Whether to fail with an error if the shared folder path is bad.
97 *
98 * @return COM result indicator
99 */
100HRESULT SharedFolder::init(Machine *aMachine,
101 const Utf8Str &aName,
102 const Utf8Str &aHostPath,
103 bool aWritable,
104 bool aAutoMount,
105 bool fFailOnError)
106{
107 /* Enclose the state transition NotReady->InInit->Ready */
108 AutoInitSpan autoInitSpan(this);
109 AssertReturn(autoInitSpan.isOk(), E_FAIL);
110
111 unconst(mMachine) = aMachine;
112
113 HRESULT rc = protectedInit(aMachine, aName, aHostPath, aWritable, aAutoMount, fFailOnError);
114
115 /* Confirm a successful initialization when it's the case */
116 if (SUCCEEDED(rc))
117 autoInitSpan.setSucceeded();
118
119 return rc;
120}
121
122/**
123 * Initializes the shared folder object given another object
124 * (a kind of copy constructor). This object makes a private copy of data
125 * of the original object passed as an argument.
126 *
127 * @param aMachine parent Machine object
128 * @param aThat shared folder object to copy
129 *
130 * @return COM result indicator
131 */
132HRESULT SharedFolder::initCopy(Machine *aMachine, SharedFolder *aThat)
133{
134 ComAssertRet(aThat, E_INVALIDARG);
135
136 /* Enclose the state transition NotReady->InInit->Ready */
137 AutoInitSpan autoInitSpan(this);
138 AssertReturn(autoInitSpan.isOk(), E_FAIL);
139
140 unconst(mMachine) = aMachine;
141
142 HRESULT rc = protectedInit(aMachine,
143 aThat->m->strName,
144 aThat->m->strHostPath,
145 aThat->m->fWritable,
146 aThat->m->fAutoMount,
147 false /* fFailOnError */ );
148
149 /* Confirm a successful initialization when it's the case */
150 if (SUCCEEDED(rc))
151 autoInitSpan.setSucceeded();
152
153 return rc;
154}
155
156# if 0
157
158/**
159 * Initializes the shared folder object.
160 *
161 * This variant initializes a global instance that lives in the server address space. It is not presently used.
162 *
163 * @param aVirtualBox VirtualBox parent object
164 * @param aName logical name of the shared folder
165 * @param aHostPath full path to the shared folder on the host
166 * @param aWritable writable if true, readonly otherwise
167 * @param fFailOnError Whether to fail with an error if the shared folder path is bad.
168 *
169 * @return COM result indicator
170 */
171HRESULT SharedFolder::init(VirtualBox *aVirtualBox,
172 const Utf8Str &aName,
173 const Utf8Str &aHostPath,
174 bool aWritable,
175 bool aAutoMount,
176 bool fFailOnError)
177{
178 /* Enclose the state transition NotReady->InInit->Ready */
179 AutoInitSpan autoInitSpan(this);
180 AssertReturn(autoInitSpan.isOk(), E_FAIL);
181
182 unconst(mVirtualBox) = aVirtualBox;
183
184 HRESULT rc = protectedInit(aVirtualBox, aName, aHostPath, aWritable, aAutoMount);
185
186 /* Confirm a successful initialization when it's the case */
187 if (SUCCEEDED(rc))
188 autoInitSpan.setSucceeded();
189
190 return rc;
191}
192
193# endif
194
195#else
196
197/**
198 * Initializes the shared folder object.
199 *
200 * This variant initializes an instance that lives in the console address space.
201 *
202 * @param aConsole Console parent object
203 * @param aName logical name of the shared folder
204 * @param aHostPath full path to the shared folder on the host
205 * @param aWritable writable if true, readonly otherwise
206 * @param fFailOnError Whether to fail with an error if the shared folder path is bad.
207 *
208 * @return COM result indicator
209 */
210HRESULT SharedFolder::init(Console *aConsole,
211 const Utf8Str &aName,
212 const Utf8Str &aHostPath,
213 bool aWritable,
214 bool aAutoMount,
215 bool fFailOnError)
216{
217 /* Enclose the state transition NotReady->InInit->Ready */
218 AutoInitSpan autoInitSpan(this);
219 AssertReturn(autoInitSpan.isOk(), E_FAIL);
220
221 unconst(mConsole) = aConsole;
222
223 HRESULT rc = protectedInit(aConsole, aName, aHostPath, aWritable, aAutoMount, fFailOnError);
224
225 /* Confirm a successful initialization when it's the case */
226 if (SUCCEEDED(rc))
227 autoInitSpan.setSucceeded();
228
229 return rc;
230}
231#endif
232
233/**
234 * Shared initialization code. Called from the other constructors.
235 *
236 * @note
237 * Must be called from under the object's lock!
238 */
239HRESULT SharedFolder::protectedInit(VirtualBoxBase *aParent,
240 const Utf8Str &aName,
241 const Utf8Str &aHostPath,
242 bool aWritable,
243 bool aAutoMount,
244 bool fFailOnError)
245{
246 LogFlowThisFunc(("aName={%s}, aHostPath={%s}, aWritable={%d}, aAutoMount={%d}\n",
247 aName.c_str(), aHostPath.c_str(), aWritable, aAutoMount));
248
249 ComAssertRet(aParent && aName.isNotEmpty() && aHostPath.isNotEmpty(), E_INVALIDARG);
250
251 Utf8Str hostPath = aHostPath;
252 size_t hostPathLen = hostPath.length();
253
254 /* Remove the trailing slash unless it's a root directory
255 * (otherwise the comparison with the RTPathAbs() result will fail at least
256 * on Linux). Note that this isn't really necessary for the shared folder
257 * itself, since adding a mapping eventually results into a
258 * RTDirOpenFiltered() call (see HostServices/SharedFolders) that seems to
259 * accept both the slashified paths and not. */
260#if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
261 if (hostPathLen > 2 &&
262 RTPATH_IS_SEP (hostPath.c_str()[hostPathLen - 1]) &&
263 RTPATH_IS_VOLSEP (hostPath.c_str()[hostPathLen - 2]))
264 ;
265#else
266 if (hostPathLen == 1 && RTPATH_IS_SEP(hostPath[0]))
267 ;
268#endif
269 else
270 hostPath.stripTrailingSlash();
271
272 if (fFailOnError)
273 {
274 /* Check whether the path is full (absolute) */
275 char hostPathFull[RTPATH_MAX];
276 int vrc = RTPathAbsEx(NULL,
277 hostPath.c_str(),
278 hostPathFull,
279 sizeof (hostPathFull));
280 if (RT_FAILURE(vrc))
281 return setError(E_INVALIDARG,
282 tr("Invalid shared folder path: '%s' (%Rrc)"),
283 hostPath.c_str(), vrc);
284
285 if (RTPathCompare(hostPath.c_str(), hostPathFull) != 0)
286 return setError(E_INVALIDARG,
287 tr("Shared folder path '%s' is not absolute"),
288 hostPath.c_str());
289 }
290
291 unconst(mParent) = aParent;
292
293 unconst(m->strName) = aName;
294 unconst(m->strHostPath) = hostPath;
295 m->fWritable = aWritable;
296 m->fAutoMount = aAutoMount;
297
298 return S_OK;
299}
300
301/**
302 * Uninitializes the instance and sets the ready flag to FALSE.
303 * Called either from FinalRelease() or by the parent when it gets destroyed.
304 */
305void SharedFolder::uninit()
306{
307 LogFlowThisFunc(("\n"));
308
309 /* Enclose the state transition Ready->InUninit->NotReady */
310 AutoUninitSpan autoUninitSpan(this);
311 if (autoUninitSpan.uninitDone())
312 return;
313
314 unconst(mParent) = NULL;
315
316#if !defined(VBOX_COM_INPROC)
317 unconst(mMachine) = NULL;
318 unconst(mVirtualBox) = NULL;
319#else
320 unconst(mConsole) = NULL;
321#endif
322}
323
324// ISharedFolder properties
325/////////////////////////////////////////////////////////////////////////////
326
327STDMETHODIMP SharedFolder::COMGETTER(Name) (BSTR *aName)
328{
329 CheckComArgOutPointerValid(aName);
330
331 AutoCaller autoCaller(this);
332 if (FAILED(autoCaller.rc())) return autoCaller.rc();
333
334 /* mName is constant during life time, no need to lock */
335 m->strName.cloneTo(aName);
336
337 return S_OK;
338}
339
340STDMETHODIMP SharedFolder::COMGETTER(HostPath) (BSTR *aHostPath)
341{
342 CheckComArgOutPointerValid(aHostPath);
343
344 AutoCaller autoCaller(this);
345 if (FAILED(autoCaller.rc())) return autoCaller.rc();
346
347 /* mHostPath is constant during life time, no need to lock */
348 m->strHostPath.cloneTo(aHostPath);
349
350 return S_OK;
351}
352
353STDMETHODIMP SharedFolder::COMGETTER(Accessible) (BOOL *aAccessible)
354{
355 CheckComArgOutPointerValid(aAccessible);
356
357 AutoCaller autoCaller(this);
358 if (FAILED(autoCaller.rc())) return autoCaller.rc();
359
360 /* mName and mHostPath are constant during life time, no need to lock */
361
362 /* check whether the host path exists */
363 Utf8Str hostPath = m->strHostPath;
364 char hostPathFull[RTPATH_MAX];
365 int vrc = RTPathExists(hostPath.c_str()) ? RTPathReal(hostPath.c_str(),
366 hostPathFull,
367 sizeof(hostPathFull))
368 : VERR_PATH_NOT_FOUND;
369 if (RT_SUCCESS(vrc))
370 {
371 *aAccessible = TRUE;
372 return S_OK;
373 }
374
375 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
376
377 m->strLastAccessError = Utf8StrFmt(tr("'%s' is not accessible (%Rrc)"),
378 m->strHostPath.c_str(),
379 vrc);
380
381 LogWarningThisFunc(("m.lastAccessError=\"%s\"\n", m->strLastAccessError.c_str()));
382
383 *aAccessible = FALSE;
384 return S_OK;
385}
386
387STDMETHODIMP SharedFolder::COMGETTER(Writable) (BOOL *aWritable)
388{
389 CheckComArgOutPointerValid(aWritable);
390
391 AutoCaller autoCaller(this);
392 if (FAILED(autoCaller.rc())) return autoCaller.rc();
393
394 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
395
396 *aWritable = !!m->fWritable;
397
398 return S_OK;
399}
400
401STDMETHODIMP SharedFolder::COMGETTER(AutoMount) (BOOL *aAutoMount)
402{
403 CheckComArgOutPointerValid(aAutoMount);
404
405 AutoCaller autoCaller(this);
406 if (FAILED(autoCaller.rc())) return autoCaller.rc();
407
408 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
409
410 *aAutoMount = !!m->fAutoMount;
411
412 return S_OK;
413}
414
415STDMETHODIMP SharedFolder::COMGETTER(LastAccessError) (BSTR *aLastAccessError)
416{
417 CheckComArgOutPointerValid(aLastAccessError);
418
419 AutoCaller autoCaller(this);
420 if (FAILED(autoCaller.rc())) return autoCaller.rc();
421
422 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
423
424 m->strLastAccessError.cloneTo(aLastAccessError);
425
426 return S_OK;
427}
428
429const Utf8Str& SharedFolder::getName() const
430{
431 return m->strName;
432}
433
434const Utf8Str& SharedFolder::getHostPath() const
435{
436 return m->strHostPath;
437}
438
439bool SharedFolder::isWritable() const
440{
441 return m->fWritable;
442}
443
444bool SharedFolder::isAutoMounted() const
445{
446 return m->fAutoMount;
447}
448
449/* 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