VirtualBox

source: vbox/trunk/src/VBox/Additions/darwin/VBoxSF/VBoxSF.cpp@ 78351

Last change on this file since 78351 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.1 KB
Line 
1/* $Id: VBoxSF.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * VBoxSF - Darwin Shared Folders, KEXT entry points.
4 */
5
6/*
7 * Copyright (C) 2013-2019 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#define LOG_GROUP LOG_GROUP_SHARED_FOLDERS
23#include "VBoxSFInternal.h"
24
25#include <iprt/asm.h>
26#include <iprt/assert.h>
27#include <iprt/initterm.h>
28#include <VBox/version.h>
29#include <VBox/log.h>
30
31
32/*********************************************************************************************************************************
33* Internal Functions *
34*********************************************************************************************************************************/
35static kern_return_t vboxSfDwnModuleLoad(struct kmod_info *pKModInfo, void *pvData);
36static kern_return_t vboxSfDwnModuleUnload(struct kmod_info *pKModInfo, void *pvData);
37
38
39/*********************************************************************************************************************************
40* Global Variables *
41*********************************************************************************************************************************/
42/** The VBoxGuest service if we've managed to connect to it already. */
43static IOService *g_pVBoxGuest = NULL;
44/** The shared folder service client structure. */
45VBGLSFCLIENT g_SfClientDarwin = { UINT32_MAX, NULL };
46/** Number of active mounts. Used for unload prevention. */
47uint32_t volatile g_cVBoxSfMounts = 0;
48
49/** VFS table entry for our file system (for vfs_fsremove). */
50static vfstable_t g_pVBoxSfVfsTableEntry;
51/** For vfs_fsentry. */
52static struct vnodeopv_desc *g_apVBoxSfVnodeOpDescList[] =
53{
54 &g_VBoxSfVnodeOpvDesc,
55};
56/** VFS registration structure. */
57static struct vfs_fsentry g_VBoxSfFsEntry =
58{
59 .vfe_vfsops = &g_VBoxSfVfsOps,
60 .vfe_vopcnt = RT_ELEMENTS(g_apVBoxSfVnodeOpDescList),
61 .vfe_opvdescs = g_apVBoxSfVnodeOpDescList,
62 .vfe_fstypenum = -1,
63 .vfe_fsname = VBOXSF_DARWIN_FS_NAME,
64 .vfe_flags = VFS_TBLTHREADSAFE /* Required. */
65 | VFS_TBLFSNODELOCK /* Required. */
66 | VFS_TBLNOTYPENUM /* No historic file system number. */
67 | VFS_TBL64BITREADY, /* Can handle 64-bit processes */
68 /** @todo add VFS_TBLREADDIR_EXTENDED */
69 .vfe_reserv = { NULL, NULL },
70};
71
72
73/**
74 * Declare the module stuff.
75 */
76RT_C_DECLS_BEGIN
77extern kern_return_t _start(struct kmod_info *pKModInfo, void *pvData);
78extern kern_return_t _stop(struct kmod_info *pKModInfo, void *pvData);
79
80KMOD_EXPLICIT_DECL(VBoxSF, VBOX_VERSION_STRING, _start, _stop)
81DECLHIDDEN(kmod_start_func_t *) _realmain = vboxSfDwnModuleLoad;
82DECLHIDDEN(kmod_stop_func_t *) _antimain = vboxSfDwnModuleUnload;
83DECLHIDDEN(int) _kext_apple_cc = __APPLE_CC__;
84RT_C_DECLS_END
85
86
87/**
88 * Connect to VBoxGuest and host shared folders service.
89 *
90 * @returns true if connected, false if not.
91 */
92bool vboxSfDwnConnect(void)
93{
94 /*
95 * Grab VBoxGuest - since it's a dependency of this module, it shouldn't be hard.
96 */
97 if (!g_pVBoxGuest)
98 {
99 OSDictionary *pServiceMatcher = IOService::serviceMatching("org_virtualbox_VBoxGuest");
100 if (pServiceMatcher)
101 {
102 IOService *pVBoxGuest = IOService::waitForMatchingService(pServiceMatcher, 10 * RT_NS_1SEC);
103 if (pVBoxGuest)
104 g_pVBoxGuest = pVBoxGuest;
105 else
106 LogRel(("vboxSfDwnConnect: IOService::waitForMatchingService failed!!\n"));
107 }
108 else
109 LogRel(("vboxSfDwnConnect: serviceMatching failed\n"));
110 }
111
112 if (g_pVBoxGuest)
113 {
114 /*
115 * Get hold of the shared folders service if we haven't already.
116 */
117 if (g_SfClientDarwin.handle != NULL)
118 return true;
119
120 int rc = VbglR0SfConnect(&g_SfClientDarwin);
121 if (RT_SUCCESS(rc))
122 {
123 rc = VbglR0SfSetUtf8(&g_SfClientDarwin);
124 if (RT_SUCCESS(rc))
125 return true;
126
127 LogRel(("VBoxSF: VbglR0SfSetUtf8 failed: %Rrc\n", rc));
128
129 VbglR0SfDisconnect(&g_SfClientDarwin);
130 g_SfClientDarwin.handle = NULL;
131 }
132 else
133 LogRel(("VBoxSF: VbglR0SfConnect failed: %Rrc\n", rc));
134 }
135
136 return false;
137}
138
139
140/**
141 * Start the kernel module.
142 */
143static kern_return_t vboxSfDwnModuleLoad(struct kmod_info *pKModInfo, void *pvData)
144{
145 RT_NOREF(pKModInfo, pvData);
146#ifdef DEBUG
147 printf("vboxSfDwnModuleLoad\n");
148 RTLogBackdoorPrintf("vboxSfDwnModuleLoad\n");
149#endif
150
151 /*
152 * Initialize IPRT and the ring-0 guest library.
153 */
154 int rc = RTR0Init(0);
155 if (RT_SUCCESS(rc))
156 {
157 rc = VbglR0SfInit();
158 if (RT_SUCCESS(rc))
159 {
160 /*
161 * Register the file system.
162 */
163 rc = vfs_fsadd(&g_VBoxSfFsEntry, &g_pVBoxSfVfsTableEntry);
164 if (rc == 0)
165 {
166 /*
167 * Try find VBoxGuest and connect to the shared folders service on the host.
168 */
169 /** @todo should we just ignore the error here and retry at mount time?
170 * Technically, VBoxGuest should be available since it's one of our
171 * dependencies... */
172 vboxSfDwnConnect();
173
174 /*
175 * We're done for now. We'll deal with
176 */
177 LogRel(("VBoxSF: loaded\n"));
178 return KERN_SUCCESS;
179 }
180
181 printf("VBoxSF: vfs_fsadd failed: %d\n", rc);
182 RTLogBackdoorPrintf("VBoxSF: vfs_fsadd failed: %d\n", rc);
183 VbglR0SfTerm();
184 }
185 else
186 {
187 printf("VBoxSF: VbglR0SfInit failed: %d\n", rc);
188 RTLogBackdoorPrintf("VBoxSF: VbglR0SfInit failed: %Rrc\n", rc);
189 }
190 RTR0Term();
191 }
192 else
193 {
194 printf("VBoxSF: RTR0Init failed: %d\n", rc);
195 RTLogBackdoorPrintf("VBoxSF: RTR0Init failed: %Rrc\n", rc);
196 }
197 return KERN_FAILURE;
198}
199
200
201/**
202 * Stop the kernel module.
203 */
204static kern_return_t vboxSfDwnModuleUnload(struct kmod_info *pKModInfo, void *pvData)
205{
206 RT_NOREF(pKModInfo, pvData);
207#ifdef DEBUG
208 printf("vboxSfDwnModuleUnload\n");
209 RTLogBackdoorPrintf("vboxSfDwnModuleUnload\n");
210#endif
211
212
213 /*
214 * Are we busy? If so fail. Otherwise try deregister the file system.
215 */
216 if (g_cVBoxSfMounts > 0)
217 {
218 LogRel(("VBoxSF: Refusing to unload with %u active mounts\n", g_cVBoxSfMounts));
219 return KERN_NO_ACCESS;
220 }
221
222 if (g_pVBoxSfVfsTableEntry)
223 {
224 int rc = vfs_fsremove(g_pVBoxSfVfsTableEntry);
225 if (rc != 0)
226 {
227 LogRel(("VBoxSF: vfs_fsremove failed: %d\n", rc));
228 return KERN_NO_ACCESS;
229 }
230 }
231
232 /*
233 * Disconnect and terminate libraries we're using.
234 */
235 if (g_SfClientDarwin.handle != NULL)
236 {
237 VbglR0SfDisconnect(&g_SfClientDarwin);
238 g_SfClientDarwin.handle = NULL;
239 }
240
241 if (g_pVBoxGuest)
242 {
243 g_pVBoxGuest->release();
244 g_pVBoxGuest = NULL;
245 }
246
247 VbglR0SfTerm();
248 RTR0Term();
249 return KERN_SUCCESS;
250}
251
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