VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp@ 51570

Last change on this file since 51570 was 51570, checked in by vboxsync, 11 years ago

Additions/common/VBoxService: provide default/null object implementations for service call-back functions.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.0 KB
Line 
1/* $Id: VBoxServiceAutoMount.cpp 51570 2014-06-06 15:53:52Z vboxsync $ */
2/** @file
3 * VBoxService - Auto-mounting for Shared Folders.
4 */
5
6/*
7 * Copyright (C) 2010-2012 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include <iprt/assert.h>
23#include <iprt/dir.h>
24#include <iprt/mem.h>
25#include <iprt/path.h>
26#include <iprt/string.h>
27#include <iprt/semaphore.h>
28#include <VBox/VBoxGuestLib.h>
29#include "VBoxServiceInternal.h"
30#include "VBoxServiceUtils.h"
31
32#include <errno.h>
33#include <grp.h>
34#include <sys/mount.h>
35#ifdef RT_OS_SOLARIS
36# include <sys/mntent.h>
37# include <sys/mnttab.h>
38# include <sys/vfs.h>
39#else
40# include <mntent.h>
41# include <paths.h>
42#endif
43#include <unistd.h>
44
45RT_C_DECLS_BEGIN
46#include "../../linux/sharedfolders/vbsfmount.h"
47RT_C_DECLS_END
48
49#ifdef RT_OS_SOLARIS
50# define VBOXSERVICE_AUTOMOUNT_DEFAULT_DIR "/mnt"
51#else
52# define VBOXSERVICE_AUTOMOUNT_DEFAULT_DIR "/media"
53#endif
54
55#ifndef _PATH_MOUNTED
56 #ifdef RT_OS_SOLARIS
57 #define _PATH_MOUNTED "/etc/mnttab"
58 #else
59 #define _PATH_MOUNTED "/etc/mtab"
60 #endif
61#endif
62
63/*******************************************************************************
64* Global Variables *
65*******************************************************************************/
66/** The semaphore we're blocking on. */
67static RTSEMEVENTMULTI g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
68/** The Shared Folders service client ID. */
69static uint32_t g_SharedFoldersSvcClientID = 0;
70
71
72/** @copydoc VBOXSERVICE::pfnInit */
73static DECLCALLBACK(int) VBoxServiceAutoMountInit(void)
74{
75 VBoxServiceVerbose(3, "VBoxServiceAutoMountInit\n");
76
77 int rc = RTSemEventMultiCreate(&g_AutoMountEvent);
78 AssertRCReturn(rc, rc);
79
80 rc = VbglR3SharedFolderConnect(&g_SharedFoldersSvcClientID);
81 if (RT_SUCCESS(rc))
82 {
83 VBoxServiceVerbose(3, "VBoxServiceAutoMountInit: Service Client ID: %#x\n", g_SharedFoldersSvcClientID);
84 }
85 else
86 {
87 /* If the service was not found, we disable this service without
88 causing VBoxService to fail. */
89 if (rc == VERR_HGCM_SERVICE_NOT_FOUND) /* Host service is not available. */
90 {
91 VBoxServiceVerbose(0, "VBoxServiceAutoMountInit: Shared Folders service is not available\n");
92 rc = VERR_SERVICE_DISABLED;
93 }
94 else
95 VBoxServiceError("Control: Failed to connect to the Shared Folders service! Error: %Rrc\n", rc);
96 RTSemEventMultiDestroy(g_AutoMountEvent);
97 g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
98 }
99
100 return rc;
101}
102
103
104/** @todo Integrate into RTFsQueryMountpoint(). */
105static bool VBoxServiceAutoMountShareIsMounted(const char *pszShare,
106 char *pszMountPoint, size_t cbMountPoint)
107{
108 AssertPtrReturn(pszShare, VERR_INVALID_PARAMETER);
109 AssertPtrReturn(pszMountPoint, VERR_INVALID_PARAMETER);
110 AssertReturn(cbMountPoint, VERR_INVALID_PARAMETER);
111
112 bool fMounted = false;
113 /* @todo What to do if we have a relative path in mtab instead
114 * of an absolute one ("temp" vs. "/media/temp")?
115 * procfs contains the full path but not the actual share name ...
116 * FILE *pFh = setmntent("/proc/mounts", "r+t"); */
117#ifdef RT_OS_SOLARIS
118 FILE *pFh = fopen(_PATH_MOUNTED, "r");
119 if (!pFh)
120 VBoxServiceError("VBoxServiceAutoMountShareIsMounted: Could not open mount tab \"%s\"!\n",
121 _PATH_MOUNTED);
122 else
123 {
124 mnttab mntTab;
125 while ((getmntent(pFh, &mntTab)))
126 {
127 if (!RTStrICmp(mntTab.mnt_special, pszShare))
128 {
129 fMounted = RTStrPrintf(pszMountPoint, cbMountPoint, "%s", mntTab.mnt_mountp)
130 ? true : false;
131 break;
132 }
133 }
134 fclose(pFh);
135 }
136#else
137 FILE *pFh = setmntent(_PATH_MOUNTED, "r+t");
138 if (pFh == NULL)
139 VBoxServiceError("VBoxServiceAutoMountShareIsMounted: Could not open mount tab \"%s\"!\n",
140 _PATH_MOUNTED);
141 else
142 {
143 mntent *pMntEnt;
144 while ((pMntEnt = getmntent(pFh)))
145 {
146 if (!RTStrICmp(pMntEnt->mnt_fsname, pszShare))
147 {
148 fMounted = RTStrPrintf(pszMountPoint, cbMountPoint, "%s", pMntEnt->mnt_dir)
149 ? true : false;
150 break;
151 }
152 }
153 endmntent(pFh);
154 }
155#endif
156
157 VBoxServiceVerbose(4, "VBoxServiceAutoMountShareIsMounted: Share \"%s\" at mount point \"%s\" = %s\n",
158 pszShare, fMounted ? pszMountPoint : "<None>", fMounted ? "Yes" : "No");
159 return fMounted;
160}
161
162
163static int VBoxServiceAutoMountUnmount(const char *pszMountPoint)
164{
165 AssertPtrReturn(pszMountPoint, VERR_INVALID_PARAMETER);
166
167 int rc = VINF_SUCCESS;
168 uint8_t uTries = 0;
169 int r;
170 while (uTries++ < 3)
171 {
172 r = umount(pszMountPoint);
173 if (r == 0)
174 break;
175 RTThreadSleep(5000); /* Wait a while ... */
176 }
177 if (r == -1)
178 rc = RTErrConvertFromErrno(errno);
179 return rc;
180}
181
182
183static int VBoxServiceAutoMountPrepareMountPoint(const char *pszMountPoint, const char *pszShareName,
184 vbsf_mount_opts *pOpts)
185{
186 AssertPtrReturn(pOpts, VERR_INVALID_PARAMETER);
187 AssertPtrReturn(pszMountPoint, VERR_INVALID_PARAMETER);
188 AssertPtrReturn(pszShareName, VERR_INVALID_PARAMETER);
189
190 RTFMODE fMode = RTFS_UNIX_IRWXU | RTFS_UNIX_IRWXG; /* Owner (=root) and the group (=vboxsf) have full access. */
191 int rc = RTDirCreateFullPath(pszMountPoint, fMode);
192 if (RT_SUCCESS(rc))
193 {
194 rc = RTPathSetOwnerEx(pszMountPoint, NIL_RTUID /* Owner, unchanged */, pOpts->gid, RTPATH_F_ON_LINK);
195 if (RT_SUCCESS(rc))
196 {
197 rc = RTPathSetMode(pszMountPoint, fMode);
198 if (RT_FAILURE(rc))
199 {
200 if (rc == VERR_WRITE_PROTECT)
201 {
202 VBoxServiceVerbose(3, "VBoxServiceAutoMountPrepareMountPoint: Mount directory \"%s\" already is used/mounted\n", pszMountPoint);
203 rc = VINF_SUCCESS;
204 }
205 else
206 VBoxServiceError("VBoxServiceAutoMountPrepareMountPoint: Could not set mode %RTfmode for mount directory \"%s\", rc = %Rrc\n",
207 fMode, pszMountPoint, rc);
208 }
209 }
210 else
211 VBoxServiceError("VBoxServiceAutoMountPrepareMountPoint: Could not set permissions for mount directory \"%s\", rc = %Rrc\n",
212 pszMountPoint, rc);
213 }
214 else
215 VBoxServiceError("VBoxServiceAutoMountPrepareMountPoint: Could not create mount directory \"%s\" with mode %RTfmode, rc = %Rrc\n",
216 pszMountPoint, fMode, rc);
217 return rc;
218}
219
220
221static int VBoxServiceAutoMountSharedFolder(const char *pszShareName, const char *pszMountPoint,
222 vbsf_mount_opts *pOpts)
223{
224 AssertPtr(pOpts);
225
226 int rc = VINF_SUCCESS;
227 char szAlreadyMountedTo[RTPATH_MAX];
228 bool fSkip = false;
229
230 /* Already mounted? */
231 if (VBoxServiceAutoMountShareIsMounted(pszShareName, szAlreadyMountedTo, sizeof(szAlreadyMountedTo)))
232 {
233 fSkip = true;
234 /* Do if it not mounted to our desired mount point */
235 if (RTStrICmp(pszMountPoint, szAlreadyMountedTo))
236 {
237 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder \"%s\" already mounted to \"%s\", unmounting ...\n",
238 pszShareName, szAlreadyMountedTo);
239 rc = VBoxServiceAutoMountUnmount(szAlreadyMountedTo);
240 if (RT_FAILURE(rc))
241 VBoxServiceError("VBoxServiceAutoMountWorker: Failed to unmount \"%s\", %s (%d)!\n",
242 szAlreadyMountedTo, strerror(errno), errno);
243 else
244 fSkip = false;
245 }
246 if (fSkip)
247 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder \"%s\" already mounted to \"%s\", skipping\n",
248 pszShareName, szAlreadyMountedTo);
249 }
250
251 if (!fSkip && RT_SUCCESS(rc))
252 rc = VBoxServiceAutoMountPrepareMountPoint(pszMountPoint, pszShareName, pOpts);
253 if (!fSkip && RT_SUCCESS(rc))
254 {
255#ifdef RT_OS_SOLARIS
256 char achOptBuf[MAX_MNTOPT_STR] = { '\0', };
257 int flags = 0;
258 if (pOpts->ronly)
259 flags |= MS_RDONLY;
260 RTStrPrintf(achOptBuf, sizeof(achOptBuf), "uid=%d,gid=%d", pOpts->uid, pOpts->gid);
261 int r = mount(pszShareName,
262 pszMountPoint,
263 flags | MS_OPTIONSTR,
264 "vboxfs",
265 NULL, /* char *dataptr */
266 0, /* int datalen */
267 achOptBuf,
268 sizeof(achOptBuf));
269 if (r == 0)
270 {
271 VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint);
272 }
273 else
274 {
275 if (errno != EBUSY) /* Share is already mounted? Then skip error msg. */
276 VBoxServiceError("VBoxServiceAutoMountWorker: Could not mount shared folder \"%s\" to \"%s\", error = %s\n",
277 pszShareName, pszMountPoint, strerror(errno));
278 }
279#else /* !RT_OS_SOLARIS */
280 unsigned long flags = MS_NODEV;
281
282 const char *szOptions = { "rw" };
283 struct vbsf_mount_info_new mntinf;
284
285 mntinf.nullchar = '\0';
286 mntinf.signature[0] = VBSF_MOUNT_SIGNATURE_BYTE_0;
287 mntinf.signature[1] = VBSF_MOUNT_SIGNATURE_BYTE_1;
288 mntinf.signature[2] = VBSF_MOUNT_SIGNATURE_BYTE_2;
289 mntinf.length = sizeof(mntinf);
290
291 mntinf.uid = pOpts->uid;
292 mntinf.gid = pOpts->gid;
293 mntinf.ttl = pOpts->ttl;
294 mntinf.dmode = pOpts->dmode;
295 mntinf.fmode = pOpts->fmode;
296 mntinf.dmask = pOpts->dmask;
297 mntinf.fmask = pOpts->fmask;
298
299 strcpy(mntinf.name, pszShareName);
300 strcpy(mntinf.nls_name, "\0");
301
302 int r = mount(NULL,
303 pszMountPoint,
304 "vboxsf",
305 flags,
306 &mntinf);
307 if (r == 0)
308 {
309 VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint);
310
311 r = vbsfmount_complete(pszShareName, pszMountPoint, flags, pOpts);
312 switch (r)
313 {
314 case 0: /* Success. */
315 errno = 0; /* Clear all errors/warnings. */
316 break;
317
318 case 1:
319 VBoxServiceError("VBoxServiceAutoMountWorker: Could not update mount table (failed to create memstream): %s\n", strerror(errno));
320 break;
321
322 case 2:
323 VBoxServiceError("VBoxServiceAutoMountWorker: Could not open mount table for update: %s\n", strerror(errno));
324 break;
325
326 case 3:
327 /* VBoxServiceError("VBoxServiceAutoMountWorker: Could not add an entry to the mount table: %s\n", strerror(errno)); */
328 errno = 0;
329 break;
330
331 default:
332 VBoxServiceError("VBoxServiceAutoMountWorker: Unknown error while completing mount operation: %d\n", r);
333 break;
334 }
335 }
336 else /* r == -1, we got some error in errno. */
337 {
338 if (errno == EPROTO)
339 {
340 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Messed up share name, re-trying ...\n");
341
342 /* Sometimes the mount utility messes up the share name. Try to
343 * un-mangle it again. */
344 char szCWD[4096];
345 size_t cchCWD;
346 if (!getcwd(szCWD, sizeof(szCWD)))
347 VBoxServiceError("VBoxServiceAutoMountWorker: Failed to get the current working directory\n");
348 cchCWD = strlen(szCWD);
349 if (!strncmp(pszMountPoint, szCWD, cchCWD))
350 {
351 while (pszMountPoint[cchCWD] == '/')
352 ++cchCWD;
353 /* We checked before that we have enough space */
354 strcpy(mntinf.name, pszMountPoint + cchCWD);
355 }
356 r = mount(NULL, pszMountPoint, "vboxsf", flags, &mntinf);
357 }
358 if (errno == EPROTO)
359 {
360 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Re-trying with old mounting structure ...\n");
361
362 /* New mount tool with old vboxsf module? Try again using the old
363 * vbsf_mount_info_old structure. */
364 struct vbsf_mount_info_old mntinf_old;
365 memcpy(&mntinf_old.name, &mntinf.name, MAX_HOST_NAME);
366 memcpy(&mntinf_old.nls_name, mntinf.nls_name, MAX_NLS_NAME);
367 mntinf_old.uid = mntinf.uid;
368 mntinf_old.gid = mntinf.gid;
369 mntinf_old.ttl = mntinf.ttl;
370 r = mount(NULL, pszMountPoint, "vboxsf", flags, &mntinf_old);
371 }
372 if (r == -1) /* Was there some error from one of the tries above? */
373 {
374 switch (errno)
375 {
376 /* If we get EINVAL here, the system already has mounted the Shared Folder to another
377 * mount point. */
378 case EINVAL:
379 VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" already is mounted!\n", pszShareName);
380 /* Ignore this error! */
381 break;
382 case EBUSY:
383 /* Ignore these errors! */
384 break;
385
386 default:
387 VBoxServiceError("VBoxServiceAutoMountWorker: Could not mount shared folder \"%s\" to \"%s\": %s (%d)\n",
388 pszShareName, pszMountPoint, strerror(errno), errno);
389 rc = RTErrConvertFromErrno(errno);
390 break;
391 }
392 }
393 }
394#endif /* !RT_OS_SOLARIS */
395 }
396 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Mounting returned with rc=%Rrc\n", rc);
397 return rc;
398}
399
400static int VBoxServiceAutoMountProcessMappings(PVBGLR3SHAREDFOLDERMAPPING paMappings, uint32_t cMappings,
401 const char *pszMountDir, const char *pszSharePrefix, uint32_t uClientID)
402{
403 if (cMappings == 0)
404 return VINF_SUCCESS;
405 AssertPtrReturn(paMappings, VERR_INVALID_PARAMETER);
406 AssertPtrReturn(pszMountDir, VERR_INVALID_PARAMETER);
407 AssertPtrReturn(pszSharePrefix, VERR_INVALID_PARAMETER);
408 AssertReturn(uClientID > 0, VERR_INVALID_PARAMETER);
409
410 int rc = VINF_SUCCESS;
411 for (uint32_t i = 0; i < cMappings && RT_SUCCESS(rc); i++)
412 {
413 char *pszShareName = NULL;
414 rc = VbglR3SharedFolderGetName(uClientID, paMappings[i].u32Root, &pszShareName);
415 if ( RT_SUCCESS(rc)
416 && *pszShareName)
417 {
418 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Connecting share %u (%s) ...\n", i+1, pszShareName);
419
420 char *pszShareNameFull = NULL;
421 if (RTStrAPrintf(&pszShareNameFull, "%s%s", pszSharePrefix, pszShareName) > 0)
422 {
423 char szMountPoint[RTPATH_MAX];
424 rc = RTPathJoin(szMountPoint, sizeof(szMountPoint), pszMountDir, pszShareNameFull);
425 if (RT_SUCCESS(rc))
426 {
427 VBoxServiceVerbose(4, "VBoxServiceAutoMountWorker: Processing mount point \"%s\"\n", szMountPoint);
428
429 struct group *grp_vboxsf = getgrnam("vboxsf");
430 if (grp_vboxsf)
431 {
432 struct vbsf_mount_opts mount_opts =
433 {
434 0, /* uid */
435 (int)grp_vboxsf->gr_gid, /* gid */
436 0, /* ttl */
437 0770, /* dmode, owner and group "vboxsf" have full access */
438 0770, /* fmode, owner and group "vboxsf" have full access */
439 0, /* dmask */
440 0, /* fmask */
441 0, /* ronly */
442 0, /* noexec */
443 0, /* nodev */
444 0, /* nosuid */
445 0, /* remount */
446 "\0", /* nls_name */
447 NULL, /* convertcp */
448 };
449
450 rc = VBoxServiceAutoMountSharedFolder(pszShareName, szMountPoint, &mount_opts);
451 }
452 else
453 VBoxServiceError("VBoxServiceAutoMountWorker: Group \"vboxsf\" does not exist\n");
454 }
455 else
456 VBoxServiceError("VBoxServiceAutoMountWorker: Unable to join mount point/prefix/shrae, rc = %Rrc\n", rc);
457 RTStrFree(pszShareNameFull);
458 }
459 else
460 VBoxServiceError("VBoxServiceAutoMountWorker: Unable to allocate full share name\n");
461 RTStrFree(pszShareName);
462 }
463 else
464 VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder name for root node = %u, rc = %Rrc\n",
465 paMappings[i].u32Root, rc);
466 } /* for cMappings. */
467 return rc;
468}
469
470
471/** @copydoc VBOXSERVICE::pfnWorker */
472DECLCALLBACK(int) VBoxServiceAutoMountWorker(bool volatile *pfShutdown)
473{
474 /*
475 * Tell the control thread that it can continue
476 * spawning services.
477 */
478 RTThreadUserSignal(RTThreadSelf());
479
480 uint32_t cMappings;
481 PVBGLR3SHAREDFOLDERMAPPING paMappings;
482 int rc = VbglR3SharedFolderGetMappings(g_SharedFoldersSvcClientID, true /* Only process auto-mounted folders */,
483 &paMappings, &cMappings);
484 if ( RT_SUCCESS(rc)
485 && cMappings)
486 {
487 char *pszMountDir;
488 rc = VbglR3SharedFolderGetMountDir(&pszMountDir);
489 if (rc == VERR_NOT_FOUND)
490 rc = RTStrDupEx(&pszMountDir, VBOXSERVICE_AUTOMOUNT_DEFAULT_DIR);
491 if (RT_SUCCESS(rc))
492 {
493 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder mount dir set to \"%s\"\n", pszMountDir);
494
495 char *pszSharePrefix;
496 rc = VbglR3SharedFolderGetMountPrefix(&pszSharePrefix);
497 if (RT_SUCCESS(rc))
498 {
499 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder mount prefix set to \"%s\"\n", pszSharePrefix);
500#ifdef USE_VIRTUAL_SHARES
501 /* Check for a fixed/virtual auto-mount share. */
502 if (VbglR3SharedFolderExists(g_SharedFoldersSvcClientID, "vbsfAutoMount"))
503 {
504 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Host supports auto-mount root\n");
505 }
506 else
507 {
508#endif
509 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Got %u shared folder mappings\n", cMappings);
510 rc = VBoxServiceAutoMountProcessMappings(paMappings, cMappings, pszMountDir, pszSharePrefix, g_SharedFoldersSvcClientID);
511#ifdef USE_VIRTUAL_SHARES
512 }
513#endif
514 RTStrFree(pszSharePrefix);
515 } /* Mount share prefix. */
516 else
517 VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder mount prefix, rc = %Rrc\n", rc);
518 RTStrFree(pszMountDir);
519 }
520 else
521 VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder directory, rc = %Rrc\n", rc);
522 VbglR3SharedFolderFreeMappings(paMappings);
523 }
524 else if (RT_FAILURE(rc))
525 VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder mappings, rc = %Rrc\n", rc);
526 else
527 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: No shared folder mappings found\n");
528
529 /*
530 * Because this thread is a one-timer at the moment we don't want to break/change
531 * the semantics of the main thread's start/stop sub-threads handling.
532 *
533 * This thread exits so fast while doing its own startup in VBoxServiceStartServices()
534 * that this->fShutdown flag is set to true in VBoxServiceThread() before we have the
535 * chance to check for a service failure in VBoxServiceStartServices() to indicate
536 * a VBoxService startup error.
537 *
538 * Therefore *no* service threads are allowed to quit themselves and need to wait
539 * for the pfShutdown flag to be set by the main thread.
540 */
541 for (;;)
542 {
543 /* Do we need to shutdown? */
544 if (*pfShutdown)
545 break;
546
547 /* Let's sleep for a bit and let others run ... */
548 RTThreadSleep(500);
549 }
550
551 RTSemEventMultiDestroy(g_AutoMountEvent);
552 g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
553
554 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Finished with rc=%Rrc\n", rc);
555 return VINF_SUCCESS;
556}
557
558/** @copydoc VBOXSERVICE::pfnTerm */
559static DECLCALLBACK(void) VBoxServiceAutoMountTerm(void)
560{
561 VBoxServiceVerbose(3, "VBoxServiceAutoMountTerm\n");
562
563 VbglR3SharedFolderDisconnect(g_SharedFoldersSvcClientID);
564 g_SharedFoldersSvcClientID = 0;
565
566 if (g_AutoMountEvent != NIL_RTSEMEVENTMULTI)
567 {
568 RTSemEventMultiDestroy(g_AutoMountEvent);
569 g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
570 }
571 return;
572}
573
574
575/** @copydoc VBOXSERVICE::pfnStop */
576static DECLCALLBACK(void) VBoxServiceAutoMountStop(void)
577{
578 /*
579 * We need this check because at the moment our auto-mount
580 * thread really is a one-timer which destroys the event itself
581 * after running.
582 */
583 if (g_AutoMountEvent != NIL_RTSEMEVENTMULTI)
584 RTSemEventMultiSignal(g_AutoMountEvent);
585}
586
587
588/**
589 * The 'automount' service description.
590 */
591VBOXSERVICE g_AutoMount =
592{
593 /* pszName. */
594 "automount",
595 /* pszDescription. */
596 "Auto-mount for Shared Folders",
597 /* pszUsage. */
598 NULL,
599 /* pszOptions. */
600 NULL,
601 /* methods */
602 VBoxServiceDefaultPreInit,
603 VBoxServiceDefaultOption,
604 VBoxServiceAutoMountInit,
605 VBoxServiceAutoMountWorker,
606 VBoxServiceAutoMountStop,
607 VBoxServiceAutoMountTerm
608};
Note: See TracBrowser for help on using the repository browser.

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