VirtualBox

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

Last change on this file since 52881 was 50919, checked in by vboxsync, 11 years ago

6183 src-all/SharedFolderImpl.cpp

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.0 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 = i_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 = i_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 = i_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::i_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// wrapped ISharedFolder properties
325/////////////////////////////////////////////////////////////////////////////
326HRESULT SharedFolder::getName(com::Utf8Str &aName)
327{
328 /* mName is constant during life time, no need to lock */
329 aName = m->strName;
330
331 return S_OK;
332}
333
334HRESULT SharedFolder::getHostPath(com::Utf8Str &aHostPath)
335{
336 /* mHostPath is constant during life time, no need to lock */
337 aHostPath = m->strHostPath;
338
339 return S_OK;
340}
341
342HRESULT SharedFolder::getAccessible(BOOL *aAccessible)
343{
344 /* mName and mHostPath are constant during life time, no need to lock */
345
346 /* check whether the host path exists */
347 Utf8Str hostPath = m->strHostPath;
348 char hostPathFull[RTPATH_MAX];
349 int vrc = RTPathExists(hostPath.c_str()) ? RTPathReal(hostPath.c_str(),
350 hostPathFull,
351 sizeof(hostPathFull))
352 : VERR_PATH_NOT_FOUND;
353 if (RT_SUCCESS(vrc))
354 {
355 *aAccessible = TRUE;
356 return S_OK;
357 }
358
359 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
360
361 m->strLastAccessError = Utf8StrFmt(tr("'%s' is not accessible (%Rrc)"),
362 m->strHostPath.c_str(),
363 vrc);
364
365 LogWarningThisFunc(("m.lastAccessError=\"%s\"\n", m->strLastAccessError.c_str()));
366
367 *aAccessible = FALSE;
368
369 return S_OK;
370}
371
372HRESULT SharedFolder::getWritable(BOOL *aWritable)
373{
374 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
375
376 *aWritable = !!m->fWritable;
377
378 return S_OK;
379}
380
381HRESULT SharedFolder::getAutoMount(BOOL *aAutoMount)
382{
383 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
384
385 *aAutoMount = !!m->fAutoMount;
386
387 return S_OK;
388}
389
390HRESULT SharedFolder::getLastAccessError(com::Utf8Str &aLastAccessError)
391{
392 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
393
394 aLastAccessError = m->strLastAccessError;
395
396 return S_OK;
397}
398
399
400const Utf8Str& SharedFolder::i_getName() const
401{
402 return m->strName;
403}
404
405const Utf8Str& SharedFolder::i_getHostPath() const
406{
407 return m->strHostPath;
408}
409
410bool SharedFolder::i_isWritable() const
411{
412 return m->fWritable;
413}
414
415bool SharedFolder::i_isAutoMounted() const
416{
417 return m->fAutoMount;
418}
419
420/* 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