VirtualBox

source: vbox/trunk/src/VBox/Main/src-all/ConsoleSharedFolderImpl.cpp@ 106061

Last change on this file since 106061 was 106061, checked in by vboxsync, 2 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.4 KB
Line 
1/* $Id: ConsoleSharedFolderImpl.cpp 106061 2024-09-16 14:03:52Z 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.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 "ConsoleSharedFolderImpl.h"
30#include "ConsoleImpl.h"
31
32#include "AutoCaller.h"
33
34#include <iprt/param.h>
35#include <iprt/cpp/utils.h>
36#include <iprt/path.h>
37
38/////////////////////////////////////////////////////////////////////////////
39// ConsoleSharedFolder::Data structure
40/////////////////////////////////////////////////////////////////////////////
41
42struct ConsoleSharedFolder::Data
43{
44 Data()
45 : fWritable(false),
46 fAutoMount(false),
47 enmSymlinkPolicy(SymlinkPolicy_None)
48 { }
49
50 const Utf8Str strName;
51 const Utf8Str strHostPath;
52 bool fWritable;
53 bool fAutoMount;
54 const Utf8Str strAutoMountPoint;
55 Utf8Str strLastAccessError;
56 SymlinkPolicy_T enmSymlinkPolicy;
57};
58
59// constructor / destructor
60/////////////////////////////////////////////////////////////////////////////
61
62ConsoleSharedFolder::ConsoleSharedFolder()
63 : mParent(NULL),
64 mConsole(NULL)
65{
66 m = new Data;
67}
68
69ConsoleSharedFolder::~ConsoleSharedFolder()
70{
71 delete m;
72 m = NULL;
73}
74
75HRESULT ConsoleSharedFolder::FinalConstruct()
76{
77 return BaseFinalConstruct();
78}
79
80void ConsoleSharedFolder::FinalRelease()
81{
82 uninit();
83 BaseFinalRelease();
84}
85
86// public initializer/uninitializer for internal purposes only
87/////////////////////////////////////////////////////////////////////////////
88
89/**
90 * Initializes the shared folder object.
91 *
92 * This variant initializes an instance that lives in the console address space.
93 *
94 * @param aConsole Console parent object
95 * @param aName logical name of the shared folder
96 * @param aHostPath full path to the shared folder on the host
97 * @param aWritable writable if true, readonly otherwise
98 * @param aAutoMount if auto mounted by guest true, false otherwise
99 * @param aAutoMountPoint Where the guest should try auto mount it.
100 * @param fFailOnError Whether to fail with an error if the shared folder path is bad.
101 *
102 * @return COM result indicator
103 */
104HRESULT ConsoleSharedFolder::init(Console *aConsole,
105 const Utf8Str &aName,
106 const Utf8Str &aHostPath,
107 bool aWritable,
108 bool aAutoMount,
109 const Utf8Str &aAutoMountPoint,
110 bool fFailOnError)
111{
112 /* Enclose the state transition NotReady->InInit->Ready */
113 AutoInitSpan autoInitSpan(this);
114 AssertReturn(autoInitSpan.isOk(), E_FAIL);
115
116 unconst(mConsole) = aConsole;
117
118 HRESULT hrc = i_protectedInit(aConsole, aName, aHostPath, aWritable, aAutoMount, aAutoMountPoint, fFailOnError);
119
120 /* Confirm a successful initialization when it's the case */
121 if (SUCCEEDED(hrc))
122 autoInitSpan.setSucceeded();
123
124 return hrc;
125}
126
127/**
128 * Shared initialization code. Called from the other constructors.
129 *
130 * @note
131 * Must be called from under the object's lock!
132 */
133HRESULT ConsoleSharedFolder::i_protectedInit(VirtualBoxBase *aParent,
134 const Utf8Str &aName,
135 const Utf8Str &aHostPath,
136 bool aWritable,
137 bool aAutoMount,
138 const Utf8Str &aAutoMountPoint,
139 bool fFailOnError)
140{
141 LogFlowThisFunc(("aName={%s}, aHostPath={%s}, aWritable={%d}, aAutoMount={%d}\n",
142 aName.c_str(), aHostPath.c_str(), aWritable, aAutoMount));
143
144 ComAssertRet(aParent && aName.isNotEmpty() && aHostPath.isNotEmpty(), E_INVALIDARG);
145
146 Utf8Str hostPath = aHostPath;
147 size_t hostPathLen = hostPath.length();
148
149 /* Remove the trailing slash unless it's a root directory
150 * (otherwise the comparison with the RTPathAbs() result will fail at least
151 * on Linux). Note that this isn't really necessary for the shared folder
152 * itself, since adding a mapping eventually results into a
153 * RTDirOpenFiltered() call (see HostServices/SharedFolders) that seems to
154 * accept both the slashified paths and not. */
155#if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
156 if ( hostPathLen > 2
157 && RTPATH_IS_SEP(hostPath.c_str()[hostPathLen - 1])
158 && RTPATH_IS_VOLSEP(hostPath.c_str()[hostPathLen - 2]))
159 ;
160#else
161 if (hostPathLen == 1 && RTPATH_IS_SEP(hostPath[0]))
162 ;
163#endif
164 else
165 hostPath.stripTrailingSlash();
166
167 if (fFailOnError)
168 {
169 /* Check whether the path is full (absolute) */
170 char hostPathFull[RTPATH_MAX];
171 int vrc = RTPathAbs(hostPath.c_str(),
172 hostPathFull,
173 sizeof(hostPathFull));
174 if (RT_FAILURE(vrc))
175 return setErrorBoth(E_INVALIDARG, vrc, tr("Invalid shared folder path: '%s' (%Rrc)"), hostPath.c_str(), vrc);
176
177 if (RTPathCompare(hostPath.c_str(), hostPathFull) != 0)
178 return setError(E_INVALIDARG, tr("Shared folder path '%s' is not absolute"), hostPath.c_str());
179
180 RTFSOBJINFO ObjInfo;
181 vrc = RTPathQueryInfoEx(hostPathFull, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
182 if (RT_FAILURE(vrc))
183 return setError(E_INVALIDARG, tr("RTPathQueryInfo failed on shared folder path '%s': %Rrc"), hostPathFull, vrc);
184
185 if (!RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode))
186 return setError(E_INVALIDARG, tr("Shared folder path '%s' is not a directory"), hostPathFull);
187 }
188
189 unconst(mParent) = aParent;
190
191 unconst(m->strName) = aName;
192 unconst(m->strHostPath) = hostPath;
193 m->fWritable = aWritable;
194 m->fAutoMount = aAutoMount;
195 unconst(m->strAutoMountPoint) = aAutoMountPoint;
196
197 return S_OK;
198}
199
200/**
201 * Uninitializes the instance and sets the ready flag to FALSE.
202 * Called either from FinalRelease() or by the parent when it gets destroyed.
203 */
204void ConsoleSharedFolder::uninit()
205{
206 LogFlowThisFunc(("\n"));
207
208 /* Enclose the state transition Ready->InUninit->NotReady */
209 AutoUninitSpan autoUninitSpan(this);
210 if (autoUninitSpan.uninitDone())
211 return;
212
213 unconst(mParent) = NULL;
214 unconst(mConsole) = NULL;
215}
216
217// wrapped ISharedFolder properties
218/////////////////////////////////////////////////////////////////////////////
219HRESULT ConsoleSharedFolder::getName(com::Utf8Str &aName)
220{
221 /* mName is constant during life time, no need to lock */
222 aName = m->strName;
223 return S_OK;
224}
225
226HRESULT ConsoleSharedFolder::getHostPath(com::Utf8Str &aHostPath)
227{
228 /* mHostPath is constant during life time, no need to lock */
229 aHostPath = m->strHostPath;
230 return S_OK;
231}
232
233HRESULT ConsoleSharedFolder::getAccessible(BOOL *aAccessible)
234{
235 /* mName and mHostPath are constant during life time, no need to lock */
236
237 /* check whether the host path exists */
238 Utf8Str hostPath = m->strHostPath;
239 char hostPathFull[RTPATH_MAX];
240 int vrc = RTPathExists(hostPath.c_str()) ? RTPathReal(hostPath.c_str(),
241 hostPathFull,
242 sizeof(hostPathFull))
243 : VERR_PATH_NOT_FOUND;
244 if (RT_SUCCESS(vrc))
245 {
246 *aAccessible = TRUE;
247 return S_OK;
248 }
249
250 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
251
252 m->strLastAccessError = Utf8StrFmt(tr("'%s' is not accessible (%Rrc)"),
253 m->strHostPath.c_str(),
254 vrc);
255
256 Log1WarningThisFunc(("m.lastAccessError=\"%s\"\n", m->strLastAccessError.c_str()));
257
258 *aAccessible = FALSE;
259
260 return S_OK;
261}
262
263HRESULT ConsoleSharedFolder::getWritable(BOOL *aWritable)
264{
265 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
266 *aWritable = m->fWritable;
267 return S_OK;
268}
269
270HRESULT ConsoleSharedFolder::setWritable(BOOL aWritable)
271{
272 RT_NOREF(aWritable);
273 return E_NOTIMPL;
274}
275
276HRESULT ConsoleSharedFolder::getAutoMount(BOOL *aAutoMount)
277{
278 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
279 *aAutoMount = m->fAutoMount;
280 return S_OK;
281}
282
283HRESULT ConsoleSharedFolder::setAutoMount(BOOL aAutoMount)
284{
285 RT_NOREF(aAutoMount);
286 return E_NOTIMPL;
287}
288
289HRESULT ConsoleSharedFolder::getAutoMountPoint(com::Utf8Str &aAutoMountPoint)
290{
291 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
292 aAutoMountPoint = m->strAutoMountPoint;
293 return S_OK;
294}
295
296HRESULT ConsoleSharedFolder::setAutoMountPoint(com::Utf8Str const &aAutoMountPoint)
297{
298 RT_NOREF(aAutoMountPoint);
299 return E_NOTIMPL;
300}
301
302HRESULT ConsoleSharedFolder::getLastAccessError(com::Utf8Str &aLastAccessError)
303{
304 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
305 aLastAccessError = m->strLastAccessError;
306 return S_OK;
307}
308
309HRESULT ConsoleSharedFolder::getSymlinkPolicy(SymlinkPolicy_T *aSymlinkPolicy)
310{
311 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
312 *aSymlinkPolicy = m->enmSymlinkPolicy;
313 return S_OK;
314}
315
316HRESULT ConsoleSharedFolder::setSymlinkPolicy(SymlinkPolicy_T aSymlinkPolicy)
317{
318 RT_NOREF(aSymlinkPolicy);
319 return E_NOTIMPL;
320}
321
322const Utf8Str& ConsoleSharedFolder::i_getName() const
323{
324 return m->strName;
325}
326
327const Utf8Str& ConsoleSharedFolder::i_getHostPath() const
328{
329 return m->strHostPath;
330}
331
332bool ConsoleSharedFolder::i_isWritable() const
333{
334 return m->fWritable;
335}
336
337bool ConsoleSharedFolder::i_isAutoMounted() const
338{
339 return m->fAutoMount;
340}
341
342const Utf8Str &ConsoleSharedFolder::i_getAutoMountPoint() const
343{
344 return m->strAutoMountPoint;
345}
346
347SymlinkPolicy_T ConsoleSharedFolder::i_getSymlinkPolicy() const
348{
349 return m->enmSymlinkPolicy;
350}
351
352/* 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