VirtualBox

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

Last change on this file since 107044 was 106061, checked in by vboxsync, 2 months ago

Copyright year updates by scm.

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