VirtualBox

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

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

Recently missed header updates.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.1 KB
Line 
1/* $Id: VBoxServiceAutoMount.cpp 51729 2014-06-26 05:54:43Z vboxsync $ */
2/** @file
3 * VBoxService - Auto-mounting for Shared Folders.
4 */
5
6/*
7 * Copyright (C) 2010-2014 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. 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,dmode=%0o,fmode=%0o,dmask=%0o,fmask=%0o",
261 pOpts->uid, pOpts->gid, pOpts->dmode, pOpts->fmode, pOpts->dmask, pOpts->fmask);
262 int r = mount(pszShareName,
263 pszMountPoint,
264 flags | MS_OPTIONSTR,
265 "vboxfs",
266 NULL, /* char *dataptr */
267 0, /* int datalen */
268 achOptBuf,
269 sizeof(achOptBuf));
270 if (r == 0)
271 {
272 VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint);
273 }
274 else
275 {
276 if (errno != EBUSY) /* Share is already mounted? Then skip error msg. */
277 VBoxServiceError("VBoxServiceAutoMountWorker: Could not mount shared folder \"%s\" to \"%s\", error = %s\n",
278 pszShareName, pszMountPoint, strerror(errno));
279 }
280#else /* !RT_OS_SOLARIS */
281 unsigned long flags = MS_NODEV;
282
283 const char *szOptions = { "rw" };
284 struct vbsf_mount_info_new mntinf;
285
286 mntinf.nullchar = '\0';
287 mntinf.signature[0] = VBSF_MOUNT_SIGNATURE_BYTE_0;
288 mntinf.signature[1] = VBSF_MOUNT_SIGNATURE_BYTE_1;
289 mntinf.signature[2] = VBSF_MOUNT_SIGNATURE_BYTE_2;
290 mntinf.length = sizeof(mntinf);
291
292 mntinf.uid = pOpts->uid;
293 mntinf.gid = pOpts->gid;
294 mntinf.ttl = pOpts->ttl;
295 mntinf.dmode = pOpts->dmode;
296 mntinf.fmode = pOpts->fmode;
297 mntinf.dmask = pOpts->dmask;
298 mntinf.fmask = pOpts->fmask;
299
300 strcpy(mntinf.name, pszShareName);
301 strcpy(mntinf.nls_name, "\0");
302
303 int r = mount(NULL,
304 pszMountPoint,
305 "vboxsf",
306 flags,
307 &mntinf);
308 if (r == 0)
309 {
310 VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint);
311
312 r = vbsfmount_complete(pszShareName, pszMountPoint, flags, pOpts);
313 switch (r)
314 {
315 case 0: /* Success. */
316 errno = 0; /* Clear all errors/warnings. */
317 break;
318
319 case 1:
320 VBoxServiceError("VBoxServiceAutoMountWorker: Could not update mount table (failed to create memstream): %s\n", strerror(errno));
321 break;
322
323 case 2:
324 VBoxServiceError("VBoxServiceAutoMountWorker: Could not open mount table for update: %s\n", strerror(errno));
325 break;
326
327 case 3:
328 /* VBoxServiceError("VBoxServiceAutoMountWorker: Could not add an entry to the mount table: %s\n", strerror(errno)); */
329 errno = 0;
330 break;
331
332 default:
333 VBoxServiceError("VBoxServiceAutoMountWorker: Unknown error while completing mount operation: %d\n", r);
334 break;
335 }
336 }
337 else /* r == -1, we got some error in errno. */
338 {
339 if (errno == EPROTO)
340 {
341 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Messed up share name, re-trying ...\n");
342
343 /* Sometimes the mount utility messes up the share name. Try to
344 * un-mangle it again. */
345 char szCWD[4096];
346 size_t cchCWD;
347 if (!getcwd(szCWD, sizeof(szCWD)))
348 VBoxServiceError("VBoxServiceAutoMountWorker: Failed to get the current working directory\n");
349 cchCWD = strlen(szCWD);
350 if (!strncmp(pszMountPoint, szCWD, cchCWD))
351 {
352 while (pszMountPoint[cchCWD] == '/')
353 ++cchCWD;
354 /* We checked before that we have enough space */
355 strcpy(mntinf.name, pszMountPoint + cchCWD);
356 }
357 r = mount(NULL, pszMountPoint, "vboxsf", flags, &mntinf);
358 }
359 if (errno == EPROTO)
360 {
361 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Re-trying with old mounting structure ...\n");
362
363 /* New mount tool with old vboxsf module? Try again using the old
364 * vbsf_mount_info_old structure. */
365 struct vbsf_mount_info_old mntinf_old;
366 memcpy(&mntinf_old.name, &mntinf.name, MAX_HOST_NAME);
367 memcpy(&mntinf_old.nls_name, mntinf.nls_name, MAX_NLS_NAME);
368 mntinf_old.uid = mntinf.uid;
369 mntinf_old.gid = mntinf.gid;
370 mntinf_old.ttl = mntinf.ttl;
371 r = mount(NULL, pszMountPoint, "vboxsf", flags, &mntinf_old);
372 }
373 if (r == -1) /* Was there some error from one of the tries above? */
374 {
375 switch (errno)
376 {
377 /* If we get EINVAL here, the system already has mounted the Shared Folder to another
378 * mount point. */
379 case EINVAL:
380 VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" already is mounted!\n", pszShareName);
381 /* Ignore this error! */
382 break;
383 case EBUSY:
384 /* Ignore these errors! */
385 break;
386
387 default:
388 VBoxServiceError("VBoxServiceAutoMountWorker: Could not mount shared folder \"%s\" to \"%s\": %s (%d)\n",
389 pszShareName, pszMountPoint, strerror(errno), errno);
390 rc = RTErrConvertFromErrno(errno);
391 break;
392 }
393 }
394 }
395#endif /* !RT_OS_SOLARIS */
396 }
397 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Mounting returned with rc=%Rrc\n", rc);
398 return rc;
399}
400
401static int VBoxServiceAutoMountProcessMappings(PVBGLR3SHAREDFOLDERMAPPING paMappings, uint32_t cMappings,
402 const char *pszMountDir, const char *pszSharePrefix, uint32_t uClientID)
403{
404 if (cMappings == 0)
405 return VINF_SUCCESS;
406 AssertPtrReturn(paMappings, VERR_INVALID_PARAMETER);
407 AssertPtrReturn(pszMountDir, VERR_INVALID_PARAMETER);
408 AssertPtrReturn(pszSharePrefix, VERR_INVALID_PARAMETER);
409 AssertReturn(uClientID > 0, VERR_INVALID_PARAMETER);
410
411 int rc = VINF_SUCCESS;
412 for (uint32_t i = 0; i < cMappings && RT_SUCCESS(rc); i++)
413 {
414 char *pszShareName = NULL;
415 rc = VbglR3SharedFolderGetName(uClientID, paMappings[i].u32Root, &pszShareName);
416 if ( RT_SUCCESS(rc)
417 && *pszShareName)
418 {
419 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Connecting share %u (%s) ...\n", i+1, pszShareName);
420
421 char *pszShareNameFull = NULL;
422 if (RTStrAPrintf(&pszShareNameFull, "%s%s", pszSharePrefix, pszShareName) > 0)
423 {
424 char szMountPoint[RTPATH_MAX];
425 rc = RTPathJoin(szMountPoint, sizeof(szMountPoint), pszMountDir, pszShareNameFull);
426 if (RT_SUCCESS(rc))
427 {
428 VBoxServiceVerbose(4, "VBoxServiceAutoMountWorker: Processing mount point \"%s\"\n", szMountPoint);
429
430 struct group *grp_vboxsf = getgrnam("vboxsf");
431 if (grp_vboxsf)
432 {
433 struct vbsf_mount_opts mount_opts =
434 {
435 0, /* uid */
436 (int)grp_vboxsf->gr_gid, /* gid */
437 0, /* ttl */
438 0770, /* dmode, owner and group "vboxsf" have full access */
439 0770, /* fmode, owner and group "vboxsf" have full access */
440 0, /* dmask */
441 0, /* fmask */
442 0, /* ronly */
443 0, /* noexec */
444 0, /* nodev */
445 0, /* nosuid */
446 0, /* remount */
447 "\0", /* nls_name */
448 NULL, /* convertcp */
449 };
450
451 rc = VBoxServiceAutoMountSharedFolder(pszShareName, szMountPoint, &mount_opts);
452 }
453 else
454 VBoxServiceError("VBoxServiceAutoMountWorker: Group \"vboxsf\" does not exist\n");
455 }
456 else
457 VBoxServiceError("VBoxServiceAutoMountWorker: Unable to join mount point/prefix/shrae, rc = %Rrc\n", rc);
458 RTStrFree(pszShareNameFull);
459 }
460 else
461 VBoxServiceError("VBoxServiceAutoMountWorker: Unable to allocate full share name\n");
462 RTStrFree(pszShareName);
463 }
464 else
465 VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder name for root node = %u, rc = %Rrc\n",
466 paMappings[i].u32Root, rc);
467 } /* for cMappings. */
468 return rc;
469}
470
471
472/** @copydoc VBOXSERVICE::pfnWorker */
473DECLCALLBACK(int) VBoxServiceAutoMountWorker(bool volatile *pfShutdown)
474{
475 /*
476 * Tell the control thread that it can continue
477 * spawning services.
478 */
479 RTThreadUserSignal(RTThreadSelf());
480
481 uint32_t cMappings;
482 PVBGLR3SHAREDFOLDERMAPPING paMappings;
483 int rc = VbglR3SharedFolderGetMappings(g_SharedFoldersSvcClientID, true /* Only process auto-mounted folders */,
484 &paMappings, &cMappings);
485 if ( RT_SUCCESS(rc)
486 && cMappings)
487 {
488 char *pszMountDir;
489 rc = VbglR3SharedFolderGetMountDir(&pszMountDir);
490 if (rc == VERR_NOT_FOUND)
491 rc = RTStrDupEx(&pszMountDir, VBOXSERVICE_AUTOMOUNT_DEFAULT_DIR);
492 if (RT_SUCCESS(rc))
493 {
494 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder mount dir set to \"%s\"\n", pszMountDir);
495
496 char *pszSharePrefix;
497 rc = VbglR3SharedFolderGetMountPrefix(&pszSharePrefix);
498 if (RT_SUCCESS(rc))
499 {
500 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder mount prefix set to \"%s\"\n", pszSharePrefix);
501#ifdef USE_VIRTUAL_SHARES
502 /* Check for a fixed/virtual auto-mount share. */
503 if (VbglR3SharedFolderExists(g_SharedFoldersSvcClientID, "vbsfAutoMount"))
504 {
505 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Host supports auto-mount root\n");
506 }
507 else
508 {
509#endif
510 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Got %u shared folder mappings\n", cMappings);
511 rc = VBoxServiceAutoMountProcessMappings(paMappings, cMappings, pszMountDir, pszSharePrefix, g_SharedFoldersSvcClientID);
512#ifdef USE_VIRTUAL_SHARES
513 }
514#endif
515 RTStrFree(pszSharePrefix);
516 } /* Mount share prefix. */
517 else
518 VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder mount prefix, rc = %Rrc\n", rc);
519 RTStrFree(pszMountDir);
520 }
521 else
522 VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder directory, rc = %Rrc\n", rc);
523 VbglR3SharedFolderFreeMappings(paMappings);
524 }
525 else if (RT_FAILURE(rc))
526 VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder mappings, rc = %Rrc\n", rc);
527 else
528 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: No shared folder mappings found\n");
529
530 /*
531 * Because this thread is a one-timer at the moment we don't want to break/change
532 * the semantics of the main thread's start/stop sub-threads handling.
533 *
534 * This thread exits so fast while doing its own startup in VBoxServiceStartServices()
535 * that this->fShutdown flag is set to true in VBoxServiceThread() before we have the
536 * chance to check for a service failure in VBoxServiceStartServices() to indicate
537 * a VBoxService startup error.
538 *
539 * Therefore *no* service threads are allowed to quit themselves and need to wait
540 * for the pfShutdown flag to be set by the main thread.
541 */
542 for (;;)
543 {
544 /* Do we need to shutdown? */
545 if (*pfShutdown)
546 break;
547
548 /* Let's sleep for a bit and let others run ... */
549 RTThreadSleep(500);
550 }
551
552 RTSemEventMultiDestroy(g_AutoMountEvent);
553 g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
554
555 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Finished with rc=%Rrc\n", rc);
556 return VINF_SUCCESS;
557}
558
559/** @copydoc VBOXSERVICE::pfnTerm */
560static DECLCALLBACK(void) VBoxServiceAutoMountTerm(void)
561{
562 VBoxServiceVerbose(3, "VBoxServiceAutoMountTerm\n");
563
564 VbglR3SharedFolderDisconnect(g_SharedFoldersSvcClientID);
565 g_SharedFoldersSvcClientID = 0;
566
567 if (g_AutoMountEvent != NIL_RTSEMEVENTMULTI)
568 {
569 RTSemEventMultiDestroy(g_AutoMountEvent);
570 g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
571 }
572 return;
573}
574
575
576/** @copydoc VBOXSERVICE::pfnStop */
577static DECLCALLBACK(void) VBoxServiceAutoMountStop(void)
578{
579 /*
580 * We need this check because at the moment our auto-mount
581 * thread really is a one-timer which destroys the event itself
582 * after running.
583 */
584 if (g_AutoMountEvent != NIL_RTSEMEVENTMULTI)
585 RTSemEventMultiSignal(g_AutoMountEvent);
586}
587
588
589/**
590 * The 'automount' service description.
591 */
592VBOXSERVICE g_AutoMount =
593{
594 /* pszName. */
595 "automount",
596 /* pszDescription. */
597 "Auto-mount for Shared Folders",
598 /* pszUsage. */
599 NULL,
600 /* pszOptions. */
601 NULL,
602 /* methods */
603 VBoxServiceDefaultPreInit,
604 VBoxServiceDefaultOption,
605 VBoxServiceAutoMountInit,
606 VBoxServiceAutoMountWorker,
607 VBoxServiceAutoMountStop,
608 VBoxServiceAutoMountTerm
609};
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