b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync/* $Id$ */
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync/** @file
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync * VBoxService - Auto-mounting for Shared Folders.
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync */
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync/*
76110d8ef23142ec3bcab1f50622858bdb55c76dvboxsync * Copyright (C) 2010-2014 Oracle Corporation
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync *
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync * available from http://www.virtualbox.org. This file is free software;
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync * you can redistribute it and/or modify it under the terms of the GNU
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync * General Public License (GPL) as published by the Free Software
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync */
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync/*******************************************************************************
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync* Header Files *
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync*******************************************************************************/
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync#include <iprt/assert.h>
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync#include <iprt/dir.h>
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync#include <iprt/mem.h>
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync#include <iprt/path.h>
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync#include <iprt/string.h>
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync#include <iprt/semaphore.h>
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync#include <VBox/VBoxGuestLib.h>
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync#include "VBoxServiceInternal.h"
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync#include "VBoxServiceUtils.h"
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync#include <errno.h>
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync#include <grp.h>
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync#include <sys/mount.h>
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync#ifdef RT_OS_SOLARIS
28626a5957b49791b505bf66131448a847043763vboxsync# include <sys/mntent.h>
2f827df539da232220444c27f2b207a707a045b0vboxsync# include <sys/mnttab.h>
ae6cc8f82ba26e3940022ea7d26078bec3d2a05fvboxsync# include <sys/vfs.h>
2f827df539da232220444c27f2b207a707a045b0vboxsync#else
2f827df539da232220444c27f2b207a707a045b0vboxsync# include <mntent.h>
2f827df539da232220444c27f2b207a707a045b0vboxsync# include <paths.h>
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync#endif
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync#include <unistd.h>
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
9b0ba1d4360299b4e6ee23c946feb5a4f16c6d00vboxsyncRT_C_DECLS_BEGIN
9b0ba1d4360299b4e6ee23c946feb5a4f16c6d00vboxsync#include "../../linux/sharedfolders/vbsfmount.h"
9b0ba1d4360299b4e6ee23c946feb5a4f16c6d00vboxsyncRT_C_DECLS_END
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
7cca5a9aeb06913531b982bf772508d09b4c2f0bvboxsync#ifdef RT_OS_SOLARIS
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync# define VBOXSERVICE_AUTOMOUNT_DEFAULT_DIR "/mnt"
7cca5a9aeb06913531b982bf772508d09b4c2f0bvboxsync#else
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync# define VBOXSERVICE_AUTOMOUNT_DEFAULT_DIR "/media"
7cca5a9aeb06913531b982bf772508d09b4c2f0bvboxsync#endif
7cca5a9aeb06913531b982bf772508d09b4c2f0bvboxsync
2f827df539da232220444c27f2b207a707a045b0vboxsync#ifndef _PATH_MOUNTED
581bb0c43dececce2fbba05cfb77d9a59c88a078vboxsync #ifdef RT_OS_SOLARIS
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync #define _PATH_MOUNTED "/etc/mnttab"
581bb0c43dececce2fbba05cfb77d9a59c88a078vboxsync #else
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync #define _PATH_MOUNTED "/etc/mtab"
581bb0c43dececce2fbba05cfb77d9a59c88a078vboxsync #endif
2f827df539da232220444c27f2b207a707a045b0vboxsync#endif
2f827df539da232220444c27f2b207a707a045b0vboxsync
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync/*******************************************************************************
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync* Global Variables *
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync*******************************************************************************/
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync/** The semaphore we're blocking on. */
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsyncstatic RTSEMEVENTMULTI g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
69485a2b3107976ff92a4f3db3ea862e25544059vboxsync/** The Shared Folders service client ID. */
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsyncstatic uint32_t g_SharedFoldersSvcClientID = 0;
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
1a9a40add2c78bba007e3f5c876859967a8e9edfvboxsync
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync/** @copydoc VBOXSERVICE::pfnInit */
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsyncstatic DECLCALLBACK(int) VBoxServiceAutoMountInit(void)
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync{
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountInit\n");
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync int rc = RTSemEventMultiCreate(&g_AutoMountEvent);
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync AssertRCReturn(rc, rc);
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync rc = VbglR3SharedFolderConnect(&g_SharedFoldersSvcClientID);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync if (RT_SUCCESS(rc))
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync {
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountInit: Service Client ID: %#x\n", g_SharedFoldersSvcClientID);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync }
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync else
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync {
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync /* If the service was not found, we disable this service without
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync causing VBoxService to fail. */
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync if (rc == VERR_HGCM_SERVICE_NOT_FOUND) /* Host service is not available. */
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync {
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync VBoxServiceVerbose(0, "VBoxServiceAutoMountInit: Shared Folders service is not available\n");
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync rc = VERR_SERVICE_DISABLED;
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync }
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync else
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync VBoxServiceError("Control: Failed to connect to the Shared Folders service! Error: %Rrc\n", rc);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync RTSemEventMultiDestroy(g_AutoMountEvent);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync }
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync return rc;
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync}
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
7f9e93577d96c7f2a6977229c1baab57d5ec94e4vboxsync/** @todo Integrate into RTFsQueryMountpoint(). */
2f827df539da232220444c27f2b207a707a045b0vboxsyncstatic bool VBoxServiceAutoMountShareIsMounted(const char *pszShare,
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync char *pszMountPoint, size_t cbMountPoint)
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync{
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync AssertPtrReturn(pszShare, VERR_INVALID_PARAMETER);
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync AssertPtrReturn(pszMountPoint, VERR_INVALID_PARAMETER);
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync AssertReturn(cbMountPoint, VERR_INVALID_PARAMETER);
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync bool fMounted = false;
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync /* @todo What to do if we have a relative path in mtab instead
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync * of an absolute one ("temp" vs. "/media/temp")?
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync * procfs contains the full path but not the actual share name ...
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync * FILE *pFh = setmntent("/proc/mounts", "r+t"); */
2cb52dd865592ea8e27b588beb22898d189646b1vboxsync#ifdef RT_OS_SOLARIS
2cb52dd865592ea8e27b588beb22898d189646b1vboxsync FILE *pFh = fopen(_PATH_MOUNTED, "r");
2cb52dd865592ea8e27b588beb22898d189646b1vboxsync if (!pFh)
581bb0c43dececce2fbba05cfb77d9a59c88a078vboxsync VBoxServiceError("VBoxServiceAutoMountShareIsMounted: Could not open mount tab \"%s\"!\n",
581bb0c43dececce2fbba05cfb77d9a59c88a078vboxsync _PATH_MOUNTED);
2cb52dd865592ea8e27b588beb22898d189646b1vboxsync else
2cb52dd865592ea8e27b588beb22898d189646b1vboxsync {
2cb52dd865592ea8e27b588beb22898d189646b1vboxsync mnttab mntTab;
5b0adfbdd9550a026f5d6209743504562f791f97vboxsync while ((getmntent(pFh, &mntTab)))
2cb52dd865592ea8e27b588beb22898d189646b1vboxsync {
f2e1f71feb5d4ec79d46defcd71de0763234b1e2vboxsync if (!RTStrICmp(mntTab.mnt_special, pszShare))
2cb52dd865592ea8e27b588beb22898d189646b1vboxsync {
f2e1f71feb5d4ec79d46defcd71de0763234b1e2vboxsync fMounted = RTStrPrintf(pszMountPoint, cbMountPoint, "%s", mntTab.mnt_mountp)
2cb52dd865592ea8e27b588beb22898d189646b1vboxsync ? true : false;
2cb52dd865592ea8e27b588beb22898d189646b1vboxsync break;
2cb52dd865592ea8e27b588beb22898d189646b1vboxsync }
2cb52dd865592ea8e27b588beb22898d189646b1vboxsync }
2cb52dd865592ea8e27b588beb22898d189646b1vboxsync fclose(pFh);
2cb52dd865592ea8e27b588beb22898d189646b1vboxsync }
2cb52dd865592ea8e27b588beb22898d189646b1vboxsync#else
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync FILE *pFh = setmntent(_PATH_MOUNTED, "r+t");
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync if (pFh == NULL)
581bb0c43dececce2fbba05cfb77d9a59c88a078vboxsync VBoxServiceError("VBoxServiceAutoMountShareIsMounted: Could not open mount tab \"%s\"!\n",
581bb0c43dececce2fbba05cfb77d9a59c88a078vboxsync _PATH_MOUNTED);
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync else
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync {
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync mntent *pMntEnt;
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync while ((pMntEnt = getmntent(pFh)))
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync {
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync if (!RTStrICmp(pMntEnt->mnt_fsname, pszShare))
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync {
2f827df539da232220444c27f2b207a707a045b0vboxsync fMounted = RTStrPrintf(pszMountPoint, cbMountPoint, "%s", pMntEnt->mnt_dir)
2f827df539da232220444c27f2b207a707a045b0vboxsync ? true : false;
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync break;
2f827df539da232220444c27f2b207a707a045b0vboxsync }
2f827df539da232220444c27f2b207a707a045b0vboxsync }
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync endmntent(pFh);
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync }
2cb52dd865592ea8e27b588beb22898d189646b1vboxsync#endif
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsync
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsync VBoxServiceVerbose(4, "VBoxServiceAutoMountShareIsMounted: Share \"%s\" at mount point \"%s\" = %s\n",
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsync pszShare, fMounted ? pszMountPoint : "<None>", fMounted ? "Yes" : "No");
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync return fMounted;
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync}
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsyncstatic int VBoxServiceAutoMountUnmount(const char *pszMountPoint)
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync{
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync AssertPtrReturn(pszMountPoint, VERR_INVALID_PARAMETER);
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync int rc = VINF_SUCCESS;
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync uint8_t uTries = 0;
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync int r;
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync while (uTries++ < 3)
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync {
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync r = umount(pszMountPoint);
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync if (r == 0)
2f827df539da232220444c27f2b207a707a045b0vboxsync break;
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync RTThreadSleep(5000); /* Wait a while ... */
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync }
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync if (r == -1)
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync rc = RTErrConvertFromErrno(errno);
2f827df539da232220444c27f2b207a707a045b0vboxsync return rc;
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync}
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsyncstatic int VBoxServiceAutoMountPrepareMountPoint(const char *pszMountPoint, const char *pszShareName,
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync vbsf_mount_opts *pOpts)
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync{
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync AssertPtrReturn(pOpts, VERR_INVALID_PARAMETER);
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync AssertPtrReturn(pszMountPoint, VERR_INVALID_PARAMETER);
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync AssertPtrReturn(pszShareName, VERR_INVALID_PARAMETER);
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync RTFMODE fMode = RTFS_UNIX_IRWXU | RTFS_UNIX_IRWXG; /* Owner (=root) and the group (=vboxsf) have full access. */
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync int rc = RTDirCreateFullPath(pszMountPoint, fMode);
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync if (RT_SUCCESS(rc))
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync {
523f2a6676210ab8601d3fdb2fdabe7dcdea7d4cvboxsync rc = RTPathSetOwnerEx(pszMountPoint, NIL_RTUID /* Owner, unchanged */, pOpts->gid, RTPATH_F_ON_LINK);
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync if (RT_SUCCESS(rc))
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync {
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync rc = RTPathSetMode(pszMountPoint, fMode);
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync if (RT_FAILURE(rc))
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsync {
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsync if (rc == VERR_WRITE_PROTECT)
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsync {
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountPrepareMountPoint: Mount directory \"%s\" already is used/mounted\n", pszMountPoint);
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsync rc = VINF_SUCCESS;
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsync }
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsync else
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsync VBoxServiceError("VBoxServiceAutoMountPrepareMountPoint: Could not set mode %RTfmode for mount directory \"%s\", rc = %Rrc\n",
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsync fMode, pszMountPoint, rc);
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsync }
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync }
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync else
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync VBoxServiceError("VBoxServiceAutoMountPrepareMountPoint: Could not set permissions for mount directory \"%s\", rc = %Rrc\n",
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync pszMountPoint, rc);
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync }
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync else
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync VBoxServiceError("VBoxServiceAutoMountPrepareMountPoint: Could not create mount directory \"%s\" with mode %RTfmode, rc = %Rrc\n",
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync pszMountPoint, fMode, rc);
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync return rc;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync}
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsyncstatic int VBoxServiceAutoMountSharedFolder(const char *pszShareName, const char *pszMountPoint,
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync vbsf_mount_opts *pOpts)
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync{
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync AssertPtr(pOpts);
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync
515bedd29819574258817b27cd304587d407810fvboxsync int rc = VINF_SUCCESS;
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync char szAlreadyMountedTo[RTPATH_MAX];
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync bool fSkip = false;
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync /* Already mounted? */
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync if (VBoxServiceAutoMountShareIsMounted(pszShareName, szAlreadyMountedTo, sizeof(szAlreadyMountedTo)))
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync {
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync fSkip = true;
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync /* Do if it not mounted to our desired mount point */
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync if (RTStrICmp(pszMountPoint, szAlreadyMountedTo))
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync {
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder \"%s\" already mounted to \"%s\", unmounting ...\n",
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync pszShareName, szAlreadyMountedTo);
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync rc = VBoxServiceAutoMountUnmount(szAlreadyMountedTo);
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync if (RT_FAILURE(rc))
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync VBoxServiceError("VBoxServiceAutoMountWorker: Failed to unmount \"%s\", %s (%d)!\n",
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync szAlreadyMountedTo, strerror(errno), errno);
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync else
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync fSkip = false;
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync }
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync if (fSkip)
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder \"%s\" already mounted to \"%s\", skipping\n",
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync pszShareName, szAlreadyMountedTo);
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync }
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync if (!fSkip && RT_SUCCESS(rc))
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync rc = VBoxServiceAutoMountPrepareMountPoint(pszMountPoint, pszShareName, pOpts);
f5d67cb858e3b0b324de00cfbefb0e267238b78bvboxsync if (!fSkip && RT_SUCCESS(rc))
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync {
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync#ifdef RT_OS_SOLARIS
3adea7c30ebc76f2e5975ad9052a40c174f588f3vboxsync char achOptBuf[MAX_MNTOPT_STR] = { '\0', };
3adea7c30ebc76f2e5975ad9052a40c174f588f3vboxsync int flags = 0;
3adea7c30ebc76f2e5975ad9052a40c174f588f3vboxsync if (pOpts->ronly)
3adea7c30ebc76f2e5975ad9052a40c174f588f3vboxsync flags |= MS_RDONLY;
d857e2bd9418f4d7588db888e622f5df5c5d9eabvboxsync RTStrPrintf(achOptBuf, sizeof(achOptBuf), "uid=%d,gid=%d,dmode=%0o,fmode=%0o,dmask=%0o,fmask=%0o",
d857e2bd9418f4d7588db888e622f5df5c5d9eabvboxsync pOpts->uid, pOpts->gid, pOpts->dmode, pOpts->fmode, pOpts->dmask, pOpts->fmask);
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync int r = mount(pszShareName,
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync pszMountPoint,
3adea7c30ebc76f2e5975ad9052a40c174f588f3vboxsync flags | MS_OPTIONSTR,
c90d31f80888da118a5d230aabab08ad5c23c00dvboxsync "vboxfs",
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync NULL, /* char *dataptr */
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync 0, /* int datalen */
3adea7c30ebc76f2e5975ad9052a40c174f588f3vboxsync achOptBuf,
3adea7c30ebc76f2e5975ad9052a40c174f588f3vboxsync sizeof(achOptBuf));
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync if (r == 0)
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync {
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint);
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync }
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync else
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync {
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync if (errno != EBUSY) /* Share is already mounted? Then skip error msg. */
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync VBoxServiceError("VBoxServiceAutoMountWorker: Could not mount shared folder \"%s\" to \"%s\", error = %s\n",
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync pszShareName, pszMountPoint, strerror(errno));
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync }
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync#else /* !RT_OS_SOLARIS */
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync unsigned long flags = MS_NODEV;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync const char *szOptions = { "rw" };
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync struct vbsf_mount_info_new mntinf;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync mntinf.nullchar = '\0';
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync mntinf.signature[0] = VBSF_MOUNT_SIGNATURE_BYTE_0;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync mntinf.signature[1] = VBSF_MOUNT_SIGNATURE_BYTE_1;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync mntinf.signature[2] = VBSF_MOUNT_SIGNATURE_BYTE_2;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync mntinf.length = sizeof(mntinf);
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync mntinf.uid = pOpts->uid;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync mntinf.gid = pOpts->gid;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync mntinf.ttl = pOpts->ttl;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync mntinf.dmode = pOpts->dmode;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync mntinf.fmode = pOpts->fmode;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync mntinf.dmask = pOpts->dmask;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync mntinf.fmask = pOpts->fmask;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync strcpy(mntinf.name, pszShareName);
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync strcpy(mntinf.nls_name, "\0");
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync int r = mount(NULL,
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync pszMountPoint,
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync "vboxsf",
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync flags,
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync &mntinf);
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync if (r == 0)
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync {
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint);
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync r = vbsfmount_complete(pszShareName, pszMountPoint, flags, pOpts);
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync switch (r)
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync {
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync case 0: /* Success. */
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync errno = 0; /* Clear all errors/warnings. */
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync break;
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync case 1:
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync VBoxServiceError("VBoxServiceAutoMountWorker: Could not update mount table (failed to create memstream): %s\n", strerror(errno));
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync break;
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync case 2:
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync VBoxServiceError("VBoxServiceAutoMountWorker: Could not open mount table for update: %s\n", strerror(errno));
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync break;
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync case 3:
75e8721fd1fe3ee8c1dd3e8404381def8ae5ca53vboxsync /* VBoxServiceError("VBoxServiceAutoMountWorker: Could not add an entry to the mount table: %s\n", strerror(errno)); */
75e8721fd1fe3ee8c1dd3e8404381def8ae5ca53vboxsync errno = 0;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync break;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync default:
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync VBoxServiceError("VBoxServiceAutoMountWorker: Unknown error while completing mount operation: %d\n", r);
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync break;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync }
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync }
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync else /* r == -1, we got some error in errno. */
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync {
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync if (errno == EPROTO)
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync {
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Messed up share name, re-trying ...\n");
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync /* Sometimes the mount utility messes up the share name. Try to
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync * un-mangle it again. */
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync char szCWD[4096];
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync size_t cchCWD;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync if (!getcwd(szCWD, sizeof(szCWD)))
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync VBoxServiceError("VBoxServiceAutoMountWorker: Failed to get the current working directory\n");
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync cchCWD = strlen(szCWD);
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync if (!strncmp(pszMountPoint, szCWD, cchCWD))
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync {
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync while (pszMountPoint[cchCWD] == '/')
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync ++cchCWD;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync /* We checked before that we have enough space */
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync strcpy(mntinf.name, pszMountPoint + cchCWD);
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync }
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync r = mount(NULL, pszMountPoint, "vboxsf", flags, &mntinf);
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync }
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync if (errno == EPROTO)
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync {
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Re-trying with old mounting structure ...\n");
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync /* New mount tool with old vboxsf module? Try again using the old
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync * vbsf_mount_info_old structure. */
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync struct vbsf_mount_info_old mntinf_old;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync memcpy(&mntinf_old.name, &mntinf.name, MAX_HOST_NAME);
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync memcpy(&mntinf_old.nls_name, mntinf.nls_name, MAX_NLS_NAME);
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync mntinf_old.uid = mntinf.uid;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync mntinf_old.gid = mntinf.gid;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync mntinf_old.ttl = mntinf.ttl;
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync r = mount(NULL, pszMountPoint, "vboxsf", flags, &mntinf_old);
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync }
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync if (r == -1) /* Was there some error from one of the tries above? */
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync {
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync switch (errno)
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync {
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync /* If we get EINVAL here, the system already has mounted the Shared Folder to another
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync * mount point. */
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync case EINVAL:
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" already is mounted!\n", pszShareName);
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync /* Ignore this error! */
2f827df539da232220444c27f2b207a707a045b0vboxsync break;
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync case EBUSY:
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync /* Ignore these errors! */
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync break;
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync default:
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync VBoxServiceError("VBoxServiceAutoMountWorker: Could not mount shared folder \"%s\" to \"%s\": %s (%d)\n",
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync pszShareName, pszMountPoint, strerror(errno), errno);
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync rc = RTErrConvertFromErrno(errno);
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync break;
2f827df539da232220444c27f2b207a707a045b0vboxsync }
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync }
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync }
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync#endif /* !RT_OS_SOLARIS */
f46e7db81f80ea09725c6cc048fa0cad86573dc2vboxsync }
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Mounting returned with rc=%Rrc\n", rc);
56f538fa476fdbd9cc3d60438083a3f0d5f3ff7fvboxsync return rc;
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync}
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsyncstatic int VBoxServiceAutoMountProcessMappings(PVBGLR3SHAREDFOLDERMAPPING paMappings, uint32_t cMappings,
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync const char *pszMountDir, const char *pszSharePrefix, uint32_t uClientID)
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync{
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync if (cMappings == 0)
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync return VINF_SUCCESS;
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync AssertPtrReturn(paMappings, VERR_INVALID_PARAMETER);
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync AssertPtrReturn(pszMountDir, VERR_INVALID_PARAMETER);
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync AssertPtrReturn(pszSharePrefix, VERR_INVALID_PARAMETER);
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync AssertReturn(uClientID > 0, VERR_INVALID_PARAMETER);
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync int rc = VINF_SUCCESS;
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync for (uint32_t i = 0; i < cMappings && RT_SUCCESS(rc); i++)
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync {
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync char *pszShareName = NULL;
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync rc = VbglR3SharedFolderGetName(uClientID, paMappings[i].u32Root, &pszShareName);
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync if ( RT_SUCCESS(rc)
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync && *pszShareName)
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync {
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Connecting share %u (%s) ...\n", i+1, pszShareName);
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync char *pszShareNameFull = NULL;
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync if (RTStrAPrintf(&pszShareNameFull, "%s%s", pszSharePrefix, pszShareName) > 0)
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsync {
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync char szMountPoint[RTPATH_MAX];
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync rc = RTPathJoin(szMountPoint, sizeof(szMountPoint), pszMountDir, pszShareNameFull);
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync if (RT_SUCCESS(rc))
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync {
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync VBoxServiceVerbose(4, "VBoxServiceAutoMountWorker: Processing mount point \"%s\"\n", szMountPoint);
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsync
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync struct group *grp_vboxsf = getgrnam("vboxsf");
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync if (grp_vboxsf)
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync {
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync struct vbsf_mount_opts mount_opts =
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync {
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync 0, /* uid */
0fb42f85d3c82308466ce750f2126a11f56005dfvboxsync (int)grp_vboxsf->gr_gid, /* gid */
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync 0, /* ttl */
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync 0770, /* dmode, owner and group "vboxsf" have full access */
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync 0770, /* fmode, owner and group "vboxsf" have full access */
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync 0, /* dmask */
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync 0, /* fmask */
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync 0, /* ronly */
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync 0, /* noexec */
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync 0, /* nodev */
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync 0, /* nosuid */
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync 0, /* remount */
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync "\0", /* nls_name */
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync NULL, /* convertcp */
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync };
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsync
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync rc = VBoxServiceAutoMountSharedFolder(pszShareName, szMountPoint, &mount_opts);
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync }
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync else
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync VBoxServiceError("VBoxServiceAutoMountWorker: Group \"vboxsf\" does not exist\n");
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync }
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync else
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync VBoxServiceError("VBoxServiceAutoMountWorker: Unable to join mount point/prefix/shrae, rc = %Rrc\n", rc);
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync RTStrFree(pszShareNameFull);
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync }
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync else
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync VBoxServiceError("VBoxServiceAutoMountWorker: Unable to allocate full share name\n");
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync RTStrFree(pszShareName);
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync }
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync else
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder name for root node = %u, rc = %Rrc\n",
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync paMappings[i].u32Root, rc);
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync } /* for cMappings. */
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync return rc;
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync}
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync/** @copydoc VBOXSERVICE::pfnWorker */
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsyncDECLCALLBACK(int) VBoxServiceAutoMountWorker(bool volatile *pfShutdown)
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync{
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync /*
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync * Tell the control thread that it can continue
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync * spawning services.
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync */
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync RTThreadUserSignal(RTThreadSelf());
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync uint32_t cMappings;
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync PVBGLR3SHAREDFOLDERMAPPING paMappings;
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync int rc = VbglR3SharedFolderGetMappings(g_SharedFoldersSvcClientID, true /* Only process auto-mounted folders */,
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync &paMappings, &cMappings);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync if ( RT_SUCCESS(rc)
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync && cMappings)
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync {
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync char *pszMountDir;
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync rc = VbglR3SharedFolderGetMountDir(&pszMountDir);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync if (rc == VERR_NOT_FOUND)
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync rc = RTStrDupEx(&pszMountDir, VBOXSERVICE_AUTOMOUNT_DEFAULT_DIR);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync if (RT_SUCCESS(rc))
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync {
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder mount dir set to \"%s\"\n", pszMountDir);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync char *pszSharePrefix;
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync rc = VbglR3SharedFolderGetMountPrefix(&pszSharePrefix);
7753dc7a3bcd14c9ec9d969cbc1a0155b0673c06vboxsync if (RT_SUCCESS(rc))
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync {
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder mount prefix set to \"%s\"\n", pszSharePrefix);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync#ifdef USE_VIRTUAL_SHARES
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync /* Check for a fixed/virtual auto-mount share. */
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync if (VbglR3SharedFolderExists(g_SharedFoldersSvcClientID, "vbsfAutoMount"))
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync {
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Host supports auto-mount root\n");
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync }
4bb5cfa1f4d9e95d7d34b5d6ede18d9f4d433bc6vboxsync else
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync {
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync#endif
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Got %u shared folder mappings\n", cMappings);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync rc = VBoxServiceAutoMountProcessMappings(paMappings, cMappings, pszMountDir, pszSharePrefix, g_SharedFoldersSvcClientID);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync#ifdef USE_VIRTUAL_SHARES
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync }
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync#endif
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync RTStrFree(pszSharePrefix);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync } /* Mount share prefix. */
7753dc7a3bcd14c9ec9d969cbc1a0155b0673c06vboxsync else
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder mount prefix, rc = %Rrc\n", rc);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync RTStrFree(pszMountDir);
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync }
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync else
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder directory, rc = %Rrc\n", rc);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync VbglR3SharedFolderFreeMappings(paMappings);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync }
0fb42f85d3c82308466ce750f2126a11f56005dfvboxsync else if (RT_FAILURE(rc))
0fb42f85d3c82308466ce750f2126a11f56005dfvboxsync VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder mappings, rc = %Rrc\n", rc);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync else
0fb42f85d3c82308466ce750f2126a11f56005dfvboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: No shared folder mappings found\n");
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync /*
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync * Because this thread is a one-timer at the moment we don't want to break/change
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync * the semantics of the main thread's start/stop sub-threads handling.
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync *
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync * This thread exits so fast while doing its own startup in VBoxServiceStartServices()
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync * that this->fShutdown flag is set to true in VBoxServiceThread() before we have the
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync * chance to check for a service failure in VBoxServiceStartServices() to indicate
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync * a VBoxService startup error.
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync *
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync * Therefore *no* service threads are allowed to quit themselves and need to wait
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync * for the pfShutdown flag to be set by the main thread.
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync */
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync for (;;)
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync {
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync /* Do we need to shutdown? */
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync if (*pfShutdown)
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync break;
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync /* Let's sleep for a bit and let others run ... */
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync RTThreadSleep(500);
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync }
1313e5cbe01a41e7ccb1499d2d73c455a2495955vboxsync
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync RTSemEventMultiDestroy(g_AutoMountEvent);
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Finished with rc=%Rrc\n", rc);
a2410ed6c0ce63f29ac7132882e4e46d921f239dvboxsync return VINF_SUCCESS;
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync}
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync/** @copydoc VBOXSERVICE::pfnTerm */
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsyncstatic DECLCALLBACK(void) VBoxServiceAutoMountTerm(void)
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync{
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountTerm\n");
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync VbglR3SharedFolderDisconnect(g_SharedFoldersSvcClientID);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync g_SharedFoldersSvcClientID = 0;
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync if (g_AutoMountEvent != NIL_RTSEMEVENTMULTI)
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync {
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync RTSemEventMultiDestroy(g_AutoMountEvent);
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync }
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync return;
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync}
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync/** @copydoc VBOXSERVICE::pfnStop */
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsyncstatic DECLCALLBACK(void) VBoxServiceAutoMountStop(void)
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync{
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync /*
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync * We need this check because at the moment our auto-mount
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync * thread really is a one-timer which destroys the event itself
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync * after running.
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync */
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync if (g_AutoMountEvent != NIL_RTSEMEVENTMULTI)
6f045c8e519b0f50a4c2eb2906e5f5e2c4679fa8vboxsync RTSemEventMultiSignal(g_AutoMountEvent);
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync}
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync/**
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync * The 'automount' service description.
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync */
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsyncVBOXSERVICE g_AutoMount =
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync{
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync /* pszName. */
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync "automount",
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync /* pszDescription. */
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync "Auto-mount for Shared Folders",
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync /* pszUsage. */
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync NULL,
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync /* pszOptions. */
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync NULL,
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync /* methods */
1677ee4804e9f56456fd286d1f4b74321a6f48c6vboxsync VBoxServiceDefaultPreInit,
1677ee4804e9f56456fd286d1f4b74321a6f48c6vboxsync VBoxServiceDefaultOption,
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync VBoxServiceAutoMountInit,
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync VBoxServiceAutoMountWorker,
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync VBoxServiceAutoMountStop,
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync VBoxServiceAutoMountTerm
b6517c5cc3b7a38889416706905a3cf2fd010785vboxsync};