VirtualBox

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

Last change on this file since 40128 was 40128, checked in by vboxsync, 13 years ago

VBoxService: Fixed unknown command line parameter handling of sub-services.

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