VirtualBox

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

Last change on this file since 75380 was 75380, checked in by vboxsync, 6 years ago

Main,VBoxManage,FE/Qt: Extended the createSharedFolder and ISharedFolder methods with a mount poit parameter/attribute for use when auto-mounting. This is especially useful for Windows and OS/2 guests which operates with drive letters. The change has not yet trickled down to the guest interface and VBoxService.

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