summaryrefslogtreecommitdiffstats
path: root/src/VBox/Main/src-all/SharedFolderImpl.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
commitf215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch)
tree6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Main/src-all/SharedFolderImpl.cpp
parentInitial commit. (diff)
downloadvirtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz
virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Main/src-all/SharedFolderImpl.cpp')
-rw-r--r--src/VBox/Main/src-all/SharedFolderImpl.cpp413
1 files changed, 413 insertions, 0 deletions
diff --git a/src/VBox/Main/src-all/SharedFolderImpl.cpp b/src/VBox/Main/src-all/SharedFolderImpl.cpp
new file mode 100644
index 00000000..a544a37f
--- /dev/null
+++ b/src/VBox/Main/src-all/SharedFolderImpl.cpp
@@ -0,0 +1,413 @@
+/* $Id: SharedFolderImpl.cpp $ */
+/** @file
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2022 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#define LOG_GROUP LOG_GROUP_MAIN_SHAREDFOLDER
+#include "SharedFolderImpl.h"
+#include "VirtualBoxImpl.h"
+#include "MachineImpl.h"
+#include "ConsoleImpl.h"
+
+#include "AutoCaller.h"
+
+#include <iprt/param.h>
+#include <iprt/cpp/utils.h>
+#include <iprt/path.h>
+
+/////////////////////////////////////////////////////////////////////////////
+// SharedFolder::Data structure
+/////////////////////////////////////////////////////////////////////////////
+
+struct SharedFolder::Data
+{
+ Data()
+ : fWritable(false),
+ fAutoMount(false)
+ { }
+
+ const Utf8Str strName;
+ const Utf8Str strHostPath;
+ bool fWritable;
+ bool fAutoMount;
+ const Utf8Str strAutoMountPoint;
+ Utf8Str strLastAccessError;
+};
+
+// constructor / destructor
+/////////////////////////////////////////////////////////////////////////////
+
+SharedFolder::SharedFolder()
+ : mParent(NULL),
+ mMachine(NULL),
+ mVirtualBox(NULL)
+{
+ m = new Data;
+}
+
+SharedFolder::~SharedFolder()
+{
+ delete m;
+ m = NULL;
+}
+
+HRESULT SharedFolder::FinalConstruct()
+{
+ return BaseFinalConstruct();
+}
+
+void SharedFolder::FinalRelease()
+{
+ uninit();
+ BaseFinalRelease();
+}
+
+// public initializer/uninitializer for internal purposes only
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Initializes the shared folder object.
+ *
+ * This variant initializes a machine instance that lives in the server address space.
+ *
+ * @param aMachine parent Machine object
+ * @param aName logical name of the shared folder
+ * @param aHostPath full path to the shared folder on the host
+ * @param aWritable writable if true, readonly otherwise
+ * @param aAutoMount if auto mounted by guest true, false otherwise
+ * @param aAutoMountPoint Where the guest should try auto mount it.
+ * @param fFailOnError Whether to fail with an error if the shared folder path is bad.
+ *
+ * @return COM result indicator
+ */
+HRESULT SharedFolder::init(Machine *aMachine,
+ const Utf8Str &aName,
+ const Utf8Str &aHostPath,
+ bool aWritable,
+ bool aAutoMount,
+ const Utf8Str &aAutoMountPoint,
+ bool fFailOnError)
+{
+ /* Enclose the state transition NotReady->InInit->Ready */
+ AutoInitSpan autoInitSpan(this);
+ AssertReturn(autoInitSpan.isOk(), E_FAIL);
+
+ unconst(mMachine) = aMachine;
+
+ HRESULT hrc = i_protectedInit(aMachine, aName, aHostPath, aWritable, aAutoMount, aAutoMountPoint, fFailOnError);
+
+ /* Confirm a successful initialization when it's the case */
+ if (SUCCEEDED(hrc))
+ autoInitSpan.setSucceeded();
+
+ return hrc;
+}
+
+/**
+ * Initializes the shared folder object given another object
+ * (a kind of copy constructor). This object makes a private copy of data
+ * of the original object passed as an argument.
+ *
+ * @param aMachine parent Machine object
+ * @param aThat shared folder object to copy
+ *
+ * @return COM result indicator
+ */
+HRESULT SharedFolder::initCopy(Machine *aMachine, SharedFolder *aThat)
+{
+ ComAssertRet(aThat, E_INVALIDARG);
+
+ /* Enclose the state transition NotReady->InInit->Ready */
+ AutoInitSpan autoInitSpan(this);
+ AssertReturn(autoInitSpan.isOk(), E_FAIL);
+
+ unconst(mMachine) = aMachine;
+
+ HRESULT hrc = i_protectedInit(aMachine,
+ aThat->m->strName,
+ aThat->m->strHostPath,
+ aThat->m->fWritable,
+ aThat->m->fAutoMount,
+ aThat->m->strAutoMountPoint,
+ false /* fFailOnError */ );
+
+ /* Confirm a successful initialization when it's the case */
+ if (SUCCEEDED(hrc))
+ autoInitSpan.setSucceeded();
+
+ return hrc;
+}
+
+# if 0
+
+/**
+ * Initializes the shared folder object.
+ *
+ * This variant initializes a global instance that lives in the server address space. It is not presently used.
+ *
+ * @param aVirtualBox VirtualBox parent object
+ * @param aName logical name of the shared folder
+ * @param aHostPath full path to the shared folder on the host
+ * @param aWritable writable if true, readonly otherwise
+ * @param aAutoMountPoint Where the guest should try auto mount it.
+ * @param fFailOnError Whether to fail with an error if the shared folder path is bad.
+ *
+ * @return COM result indicator
+ */
+HRESULT SharedFolder::init(VirtualBox *aVirtualBox,
+ const Utf8Str &aName,
+ const Utf8Str &aHostPath,
+ bool aWritable,
+ bool aAutoMount,
+ const Utf8Str &aAutoMountPoint,
+ bool fFailOnError)
+{
+ /* Enclose the state transition NotReady->InInit->Ready */
+ AutoInitSpan autoInitSpan(this);
+ AssertReturn(autoInitSpan.isOk(), E_FAIL);
+
+ unconst(mVirtualBox) = aVirtualBox;
+
+ HRESULT hrc = protectedInit(aVirtualBox, aName, aHostPath, aWritable, aAutoMount, aAutoMountPoint, fFailOnError);
+
+ /* Confirm a successful initialization when it's the case */
+ if (SUCCEEDED(hrc))
+ autoInitSpan.setSucceeded();
+
+ return hrc;
+}
+
+# endif
+
+/**
+ * Shared initialization code. Called from the other constructors.
+ *
+ * @note
+ * Must be called from under the object's lock!
+ */
+HRESULT SharedFolder::i_protectedInit(VirtualBoxBase *aParent,
+ const Utf8Str &aName,
+ const Utf8Str &aHostPath,
+ bool aWritable,
+ bool aAutoMount,
+ const Utf8Str &aAutoMountPoint,
+ bool fFailOnError)
+{
+ LogFlowThisFunc(("aName={%s}, aHostPath={%s}, aWritable={%d}, aAutoMount={%d}\n",
+ aName.c_str(), aHostPath.c_str(), aWritable, aAutoMount));
+
+ ComAssertRet(aParent && aName.isNotEmpty() && aHostPath.isNotEmpty(), E_INVALIDARG);
+
+ Utf8Str hostPath = aHostPath;
+ size_t hostPathLen = hostPath.length();
+
+ /* Remove the trailing slash unless it's a root directory
+ * (otherwise the comparison with the RTPathAbs() result will fail at least
+ * on Linux). Note that this isn't really necessary for the shared folder
+ * itself, since adding a mapping eventually results into a
+ * RTDirOpenFiltered() call (see HostServices/SharedFolders) that seems to
+ * accept both the slashified paths and not. */
+#if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
+ if ( hostPathLen > 2
+ && RTPATH_IS_SEP(hostPath.c_str()[hostPathLen - 1])
+ && RTPATH_IS_VOLSEP(hostPath.c_str()[hostPathLen - 2]))
+ ;
+#else
+ if (hostPathLen == 1 && RTPATH_IS_SEP(hostPath[0]))
+ ;
+#endif
+ else
+ hostPath.stripTrailingSlash();
+
+ if (fFailOnError)
+ {
+ /* Check whether the path is full (absolute) */
+ char hostPathFull[RTPATH_MAX];
+ int vrc = RTPathAbs(hostPath.c_str(),
+ hostPathFull,
+ sizeof(hostPathFull));
+ if (RT_FAILURE(vrc))
+ return setErrorBoth(E_INVALIDARG, vrc, tr("Invalid shared folder path: '%s' (%Rrc)"), hostPath.c_str(), vrc);
+
+ if (RTPathCompare(hostPath.c_str(), hostPathFull) != 0)
+ return setError(E_INVALIDARG, tr("Shared folder path '%s' is not absolute"), hostPath.c_str());
+
+ RTFSOBJINFO ObjInfo;
+ vrc = RTPathQueryInfoEx(hostPathFull, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
+ if (RT_FAILURE(vrc))
+ return setError(E_INVALIDARG, tr("RTPathQueryInfo failed on shared folder path '%s': %Rrc"), hostPathFull, vrc);
+
+ if (!RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode))
+ return setError(E_INVALIDARG, tr("Shared folder path '%s' is not a directory"), hostPathFull);
+ }
+
+ unconst(mParent) = aParent;
+
+ unconst(m->strName) = aName;
+ unconst(m->strHostPath) = hostPath;
+ m->fWritable = aWritable;
+ m->fAutoMount = aAutoMount;
+ unconst(m->strAutoMountPoint) = aAutoMountPoint;
+
+ return S_OK;
+}
+
+/**
+ * Uninitializes the instance and sets the ready flag to FALSE.
+ * Called either from FinalRelease() or by the parent when it gets destroyed.
+ */
+void SharedFolder::uninit()
+{
+ LogFlowThisFunc(("\n"));
+
+ /* Enclose the state transition Ready->InUninit->NotReady */
+ AutoUninitSpan autoUninitSpan(this);
+ if (autoUninitSpan.uninitDone())
+ return;
+
+ unconst(mParent) = NULL;
+ unconst(mMachine) = NULL;
+ unconst(mVirtualBox) = NULL;
+}
+
+// wrapped ISharedFolder properties
+/////////////////////////////////////////////////////////////////////////////
+HRESULT SharedFolder::getName(com::Utf8Str &aName)
+{
+ /* mName is constant during life time, no need to lock */
+ aName = m->strName;
+ return S_OK;
+}
+
+HRESULT SharedFolder::getHostPath(com::Utf8Str &aHostPath)
+{
+ /* mHostPath is constant during life time, no need to lock */
+ aHostPath = m->strHostPath;
+ return S_OK;
+}
+
+HRESULT SharedFolder::getAccessible(BOOL *aAccessible)
+{
+ /* mName and mHostPath are constant during life time, no need to lock */
+
+ /* check whether the host path exists */
+ Utf8Str hostPath = m->strHostPath;
+ char hostPathFull[RTPATH_MAX];
+ int vrc = RTPathExists(hostPath.c_str()) ? RTPathReal(hostPath.c_str(),
+ hostPathFull,
+ sizeof(hostPathFull))
+ : VERR_PATH_NOT_FOUND;
+ if (RT_SUCCESS(vrc))
+ {
+ *aAccessible = TRUE;
+ return S_OK;
+ }
+
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ m->strLastAccessError = Utf8StrFmt(tr("'%s' is not accessible (%Rrc)"),
+ m->strHostPath.c_str(),
+ vrc);
+
+ Log1WarningThisFunc(("m.lastAccessError=\"%s\"\n", m->strLastAccessError.c_str()));
+
+ *aAccessible = FALSE;
+
+ return S_OK;
+}
+
+HRESULT SharedFolder::getWritable(BOOL *aWritable)
+{
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+ *aWritable = m->fWritable;
+ return S_OK;
+}
+
+HRESULT SharedFolder::setWritable(BOOL aWritable)
+{
+ RT_NOREF(aWritable);
+ return E_NOTIMPL;
+}
+
+HRESULT SharedFolder::getAutoMount(BOOL *aAutoMount)
+{
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+ *aAutoMount = m->fAutoMount;
+ return S_OK;
+}
+
+HRESULT SharedFolder::setAutoMount(BOOL aAutoMount)
+{
+ RT_NOREF(aAutoMount);
+ return E_NOTIMPL;
+}
+
+HRESULT SharedFolder::getAutoMountPoint(com::Utf8Str &aAutoMountPoint)
+{
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+ aAutoMountPoint = m->strAutoMountPoint;
+ return S_OK;
+}
+
+HRESULT SharedFolder::setAutoMountPoint(com::Utf8Str const &aAutoMountPoint)
+{
+ RT_NOREF(aAutoMountPoint);
+ return E_NOTIMPL;
+}
+
+HRESULT SharedFolder::getLastAccessError(com::Utf8Str &aLastAccessError)
+{
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+ aLastAccessError = m->strLastAccessError;
+ return S_OK;
+}
+
+
+const Utf8Str& SharedFolder::i_getName() const
+{
+ return m->strName;
+}
+
+const Utf8Str& SharedFolder::i_getHostPath() const
+{
+ return m->strHostPath;
+}
+
+bool SharedFolder::i_isWritable() const
+{
+ return m->fWritable;
+}
+
+bool SharedFolder::i_isAutoMounted() const
+{
+ return m->fAutoMount;
+}
+
+const Utf8Str &SharedFolder::i_getAutoMountPoint() const
+{
+ return m->strAutoMountPoint;
+}
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */