VirtualBox

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

最後變更 在這個檔案從108046是 108046,由 vboxsync 提交於 6 週 前

doc/manual,include/VBox,Frontends/{VBoxManage,VirtualBox/src},Main/{include,SharedFolder,Console,Machine,VirtualBox,VirtualBox.xidl}: Added global shared folders and adjusted fetching and handling of folders between shared folder types bugref:3544

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 15.5 KB
 
1/* $Id: SharedFolderImpl.cpp 108046 2025-02-04 05:24:54Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.alldomusa.eu.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 enmSymlinkPolicy(SymlinkPolicy_None)
50 { }
51
52 const Utf8Str strName;
53 const Utf8Str strHostPath;
54 bool fWritable;
55 bool fAutoMount;
56 Utf8Str strAutoMountPoint;
57 Utf8Str strLastAccessError;
58 SymlinkPolicy_T enmSymlinkPolicy;
59};
60
61// constructor / destructor
62/////////////////////////////////////////////////////////////////////////////
63
64SharedFolder::SharedFolder()
65 : mParent(NULL),
66 mMachine(NULL),
67 mVirtualBox(NULL)
68{
69 m = new Data;
70}
71
72SharedFolder::~SharedFolder()
73{
74 delete m;
75 m = NULL;
76}
77
78HRESULT SharedFolder::FinalConstruct()
79{
80 return BaseFinalConstruct();
81}
82
83void SharedFolder::FinalRelease()
84{
85 uninit();
86 BaseFinalRelease();
87}
88
89// public initializer/uninitializer for internal purposes only
90/////////////////////////////////////////////////////////////////////////////
91
92/**
93 * Initializes the shared folder object.
94 *
95 * This variant initializes a machine instance that lives in the server address space.
96 *
97 * @param aMachine parent Machine object
98 * @param aName logical name of the shared folder
99 * @param aHostPath full path to the shared folder on the host
100 * @param aWritable writable if true, readonly otherwise
101 * @param aAutoMount if auto mounted by guest true, false otherwise
102 * @param aAutoMountPoint Where the guest should try auto mount it.
103 * @param fFailOnError Whether to fail with an error if the shared folder path is bad.
104 * @param enmSymlinkPolicy The symbolic link creation policy to apply.
105 *
106 * @return COM result indicator
107 */
108HRESULT SharedFolder::init(Machine *aMachine,
109 const Utf8Str &aName,
110 const Utf8Str &aHostPath,
111 bool aWritable,
112 bool aAutoMount,
113 const Utf8Str &aAutoMountPoint,
114 bool fFailOnError,
115 SymlinkPolicy_T enmSymlinkPolicy)
116{
117 /* Enclose the state transition NotReady->InInit->Ready */
118 AutoInitSpan autoInitSpan(this);
119 AssertReturn(autoInitSpan.isOk(), E_FAIL);
120
121 unconst(mMachine) = aMachine;
122
123 HRESULT hrc = i_protectedInit(aMachine, aName, aHostPath, aWritable, aAutoMount, aAutoMountPoint, fFailOnError,
124 enmSymlinkPolicy);
125
126 /* Confirm a successful initialization when it's the case */
127 if (SUCCEEDED(hrc))
128 autoInitSpan.setSucceeded();
129
130 return hrc;
131}
132
133/**
134 * Initializes the shared folder object given another object
135 * (a kind of copy constructor). This object makes a private copy of data
136 * of the original object passed as an argument.
137 *
138 * @param aMachine parent Machine object
139 * @param aThat shared folder object to copy
140 *
141 * @return COM result indicator
142 */
143HRESULT SharedFolder::initCopy(Machine *aMachine, SharedFolder *aThat)
144{
145 ComAssertRet(aThat, E_INVALIDARG);
146
147 /* Enclose the state transition NotReady->InInit->Ready */
148 AutoInitSpan autoInitSpan(this);
149 AssertReturn(autoInitSpan.isOk(), E_FAIL);
150
151 unconst(mMachine) = aMachine;
152
153 HRESULT hrc = i_protectedInit(aMachine,
154 aThat->m->strName,
155 aThat->m->strHostPath,
156 aThat->m->fWritable,
157 aThat->m->fAutoMount,
158 aThat->m->strAutoMountPoint,
159 false /* fFailOnError */,
160 aThat->m->enmSymlinkPolicy);
161
162 /* Confirm a successful initialization when it's the case */
163 if (SUCCEEDED(hrc))
164 autoInitSpan.setSucceeded();
165
166 return hrc;
167}
168
169
170/**
171 * Initializes the shared folder object.
172 *
173 * This variant initializes a global instance that lives in the server address space.
174 *
175 * @param aVirtualBox VirtualBox parent object
176 * @param aName logical name of the shared folder
177 * @param aHostPath full path to the shared folder on the host
178 * @param aWritable writable if true, readonly otherwise
179 * @param aAutoMount if auto mounted by guest true, false otherwise
180 * @param aAutoMountPoint Where the guest should try auto mount it.
181 * @param fFailOnError Whether to fail with an error if the shared folder path is bad.
182 * @param enmSymlinkPolicy The symbolic link creation policy to apply.
183 *
184 * @return COM result indicator
185 */
186HRESULT SharedFolder::init(VirtualBox *aVirtualBox,
187 const Utf8Str &aName,
188 const Utf8Str &aHostPath,
189 bool aWritable,
190 bool aAutoMount,
191 const Utf8Str &aAutoMountPoint,
192 bool fFailOnError,
193 SymlinkPolicy_T enmSymlinkPolicy)
194{
195 /* Enclose the state transition NotReady->InInit->Ready */
196 AutoInitSpan autoInitSpan(this);
197 AssertReturn(autoInitSpan.isOk(), E_FAIL);
198
199 unconst(mVirtualBox) = aVirtualBox;
200
201 HRESULT hrc = i_protectedInit(aVirtualBox, aName, aHostPath, aWritable, aAutoMount, aAutoMountPoint, fFailOnError,
202 enmSymlinkPolicy);
203
204 /* Confirm a successful initialization when it's the case */
205 if (SUCCEEDED(hrc))
206 autoInitSpan.setSucceeded();
207
208 return hrc;
209}
210
211/**
212 * Initializes the shared folder object.
213 *
214 * This variant initializes a global instance that lives in the server address space.
215 *
216 * @param aVirtualBox VirtualBox parent object
217 * @param rData Settings shared folder
218 *
219 * @return COM result indicator
220 */
221HRESULT SharedFolder::init(VirtualBox *aVirtualBox, const settings::SharedFolder &rData)
222{
223 /* Enclose the state transition NotReady->InInit->Ready */
224 AutoInitSpan autoInitSpan(this);
225 AssertReturn(autoInitSpan.isOk(), E_FAIL);
226
227 unconst(mVirtualBox) = aVirtualBox;
228 HRESULT hrc = i_protectedInit(aVirtualBox, rData.strName, rData.strHostPath,
229 rData.fWritable, rData.fAutoMount, rData.strAutoMountPoint,
230 false, rData.enmSymlinkPolicy);
231
232 /* Confirm a successful initialization or not: */
233 if (SUCCEEDED(hrc))
234 autoInitSpan.setSucceeded();
235 else
236 autoInitSpan.setFailed(hrc);
237 return hrc;
238}
239
240
241/**
242 * Shared initialization code. Called from the other constructors.
243 *
244 * @note
245 * Must be called from under the object's lock!
246 */
247HRESULT SharedFolder::i_protectedInit(VirtualBoxBase *aParent,
248 const Utf8Str &aName,
249 const Utf8Str &aHostPath,
250 bool aWritable,
251 bool aAutoMount,
252 const Utf8Str &aAutoMountPoint,
253 bool fFailOnError,
254 SymlinkPolicy_T enmSymlinkPolicy)
255{
256 LogFlowThisFunc(("aName={%s}, aHostPath={%s}, aWritable={%d}, aAutoMount={%d} enmSymlinkPolicy={%d}\n",
257 aName.c_str(), aHostPath.c_str(), aWritable, aAutoMount, enmSymlinkPolicy));
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 = RTPathAbs(hostPath.c_str(),
287 hostPathFull,
288 sizeof(hostPathFull));
289 if (RT_FAILURE(vrc))
290 return setErrorBoth(E_INVALIDARG, vrc, tr("Invalid shared folder path: '%s' (%Rrc)"), hostPath.c_str(), vrc);
291
292 if (RTPathCompare(hostPath.c_str(), hostPathFull) != 0)
293 return setError(E_INVALIDARG, tr("Shared folder path '%s' is not absolute"), hostPath.c_str());
294
295 RTFSOBJINFO ObjInfo;
296 vrc = RTPathQueryInfoEx(hostPathFull, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
297 if (RT_FAILURE(vrc))
298 return setError(E_INVALIDARG, tr("RTPathQueryInfo failed on shared folder path '%s': %Rrc"), hostPathFull, vrc);
299
300 if (!RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode))
301 return setError(E_INVALIDARG, tr("Shared folder path '%s' is not a directory"), hostPathFull);
302 }
303
304 unconst(mParent) = aParent;
305
306 unconst(m->strName) = aName;
307 unconst(m->strHostPath) = hostPath;
308 m->fWritable = aWritable;
309 m->fAutoMount = aAutoMount;
310 m->strAutoMountPoint = aAutoMountPoint;
311 m->enmSymlinkPolicy = enmSymlinkPolicy;
312
313 return S_OK;
314}
315
316/**
317 * Uninitializes the instance and sets the ready flag to FALSE.
318 * Called either from FinalRelease() or by the parent when it gets destroyed.
319 */
320void SharedFolder::uninit()
321{
322 LogFlowThisFunc(("\n"));
323
324 /* Enclose the state transition Ready->InUninit->NotReady */
325 AutoUninitSpan autoUninitSpan(this);
326 if (autoUninitSpan.uninitDone())
327 return;
328
329 unconst(mParent) = NULL;
330 unconst(mMachine) = NULL;
331 unconst(mVirtualBox) = NULL;
332}
333
334HRESULT SharedFolder::i_saveSettings(settings::SharedFolder &data)
335{
336 AutoCaller autoCaller(this);
337 if (FAILED(autoCaller.hrc())) return autoCaller.hrc();
338
339 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
340 AssertReturn(!m->strName.isEmpty(), E_FAIL);
341 data.strName = m->strName;
342 data.strHostPath = m->strHostPath;
343 data.fWritable = m->fWritable != FALSE;
344 data.fAutoMount = m->fAutoMount != FALSE;
345 data.strAutoMountPoint = m->strAutoMountPoint;
346 data.enmSymlinkPolicy = m->enmSymlinkPolicy;
347
348 return S_OK;
349}
350
351// wrapped ISharedFolder properties
352/////////////////////////////////////////////////////////////////////////////
353HRESULT SharedFolder::getName(com::Utf8Str &aName)
354{
355 /* mName is constant during life time, no need to lock */
356 aName = m->strName;
357 return S_OK;
358}
359
360HRESULT SharedFolder::getHostPath(com::Utf8Str &aHostPath)
361{
362 /* mHostPath is constant during life time, no need to lock */
363 aHostPath = m->strHostPath;
364 return S_OK;
365}
366
367HRESULT SharedFolder::getAccessible(BOOL *aAccessible)
368{
369 /* mName and mHostPath are constant during life time, no need to lock */
370
371 /* check whether the host path exists */
372 Utf8Str hostPath = m->strHostPath;
373 char hostPathFull[RTPATH_MAX];
374 int vrc = RTPathExists(hostPath.c_str()) ? RTPathReal(hostPath.c_str(),
375 hostPathFull,
376 sizeof(hostPathFull))
377 : VERR_PATH_NOT_FOUND;
378 if (RT_SUCCESS(vrc))
379 {
380 *aAccessible = TRUE;
381 return S_OK;
382 }
383
384 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
385
386 m->strLastAccessError = Utf8StrFmt(tr("'%s' is not accessible (%Rrc)"),
387 m->strHostPath.c_str(),
388 vrc);
389
390 Log1WarningThisFunc(("m.lastAccessError=\"%s\"\n", m->strLastAccessError.c_str()));
391
392 *aAccessible = FALSE;
393
394 return S_OK;
395}
396
397HRESULT SharedFolder::getWritable(BOOL *aWritable)
398{
399 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
400 *aWritable = m->fWritable;
401 return S_OK;
402}
403
404HRESULT SharedFolder::setWritable(BOOL aWritable)
405{
406 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
407 m->fWritable = RT_BOOL(aWritable);
408 return S_OK;
409}
410
411HRESULT SharedFolder::getAutoMount(BOOL *aAutoMount)
412{
413 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
414 *aAutoMount = m->fAutoMount;
415 return S_OK;
416}
417
418HRESULT SharedFolder::setAutoMount(BOOL aAutoMount)
419{
420 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
421 m->fAutoMount = RT_BOOL(aAutoMount);
422 return S_OK;
423}
424
425HRESULT SharedFolder::getAutoMountPoint(com::Utf8Str &aAutoMountPoint)
426{
427 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
428 aAutoMountPoint = m->strAutoMountPoint;
429 return S_OK;
430}
431
432HRESULT SharedFolder::setAutoMountPoint(com::Utf8Str const &aAutoMountPoint)
433{
434 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
435 m->strAutoMountPoint = aAutoMountPoint;
436 return S_OK;
437}
438
439HRESULT SharedFolder::getLastAccessError(com::Utf8Str &aLastAccessError)
440{
441 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
442 aLastAccessError = m->strLastAccessError;
443 return S_OK;
444}
445
446HRESULT SharedFolder::getSymlinkPolicy(SymlinkPolicy_T *aSymlinkPolicy)
447{
448 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
449 *aSymlinkPolicy = m->enmSymlinkPolicy;
450 return S_OK;
451}
452
453HRESULT SharedFolder::setSymlinkPolicy(SymlinkPolicy_T aSymlinkPolicy)
454{
455 switch (aSymlinkPolicy)
456 {
457 case SymlinkPolicy_AllowedToAnyTarget:
458 case SymlinkPolicy_AllowedInShareSubtree:
459 case SymlinkPolicy_AllowedToRelativeTargets:
460 case SymlinkPolicy_Forbidden:
461 break;
462 default:
463 return setError(E_INVALIDARG, tr("The symbolic link policy specified (%d) is invalid."), aSymlinkPolicy);
464 }
465
466 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
467 m->enmSymlinkPolicy = aSymlinkPolicy;
468 return S_OK;
469}
470
471const Utf8Str& SharedFolder::i_getName() const
472{
473 return m->strName;
474}
475
476const Utf8Str& SharedFolder::i_getHostPath() const
477{
478 return m->strHostPath;
479}
480
481bool SharedFolder::i_isWritable() const
482{
483 return m->fWritable;
484}
485
486bool SharedFolder::i_isAutoMounted() const
487{
488 return m->fAutoMount;
489}
490
491const Utf8Str &SharedFolder::i_getAutoMountPoint() const
492{
493 return m->strAutoMountPoint;
494}
495
496SymlinkPolicy_T SharedFolder::i_getSymlinkPolicy() const
497{
498 return m->enmSymlinkPolicy;
499}
500
501/* vi: set tabstop=4 shiftwidth=4 expandtab: */
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette