VirtualBox

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

Last change on this file since 62873 was 62485, checked in by vboxsync, 8 years ago

(C) 2016

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