VirtualBox

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

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

Main: bugref:4784: seperated SharedFolder API between VboxSVC and VM process (fixed issues from previous attempt on this)

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