VirtualBox

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

Last change on this file since 104479 was 98341, checked in by vboxsync, 22 months ago

Main: bugref:4784: rename MachineSharedFolder to SharedFolder [build fix]

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