VirtualBox

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

Last change on this file since 75293 was 75293, checked in by vboxsync, 7 years ago

add/darwin/VBoxSF: More renaming, header separation and cleaning up.

  • 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 75293 2018-11-06 16:15:09Z vboxsync $ */
2/** @file
3 * VBoxSF - Darwin Shared Folders, KEXT entry points.
4 */
5
6/*
7 * Copyright (C) 2013-2018 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#define LOG_GROUP LOG_GROUP_DEFAULT
23#include "VBoxSFInternal.h"
24
25#include <iprt/asm.h>
26#include <iprt/assert.h>
27#include <VBox/version.h>
28#include <VBox/log.h>
29
30
31/*********************************************************************************************************************************
32* Structures and Typedefs *
33*********************************************************************************************************************************/
34/**
35 * The service class for dealing with Share Folder filesystem.
36 */
37class org_virtualbox_VBoxVFS : public IOService
38{
39 OSDeclareDefaultStructors(org_virtualbox_VBoxVFS);
40
41private:
42 IOService * waitForCoreService(void);
43
44 IOService * coreService;
45
46public:
47 virtual bool start(IOService *pProvider);
48 virtual void stop(IOService *pProvider);
49};
50
51OSDefineMetaClassAndStructors(org_virtualbox_VBoxVFS, IOService);
52
53
54/*********************************************************************************************************************************
55* Global Variables *
56*********************************************************************************************************************************/
57
58/**
59 * Declare the module stuff.
60 */
61RT_C_DECLS_BEGIN
62static kern_return_t VBoxVFSModuleLoad(struct kmod_info *pKModInfo, void *pvData);
63static kern_return_t VBoxVFSModuleUnLoad(struct kmod_info *pKModInfo, void *pvData);
64extern kern_return_t _start(struct kmod_info *pKModInfo, void *pvData);
65extern kern_return_t _stop(struct kmod_info *pKModInfo, void *pvData);
66KMOD_EXPLICIT_DECL(VBoxVFS, VBOX_VERSION_STRING, _start, _stop)
67DECLHIDDEN(kmod_start_func_t *) _realmain = VBoxVFSModuleLoad;
68DECLHIDDEN(kmod_stop_func_t *) _antimain = VBoxVFSModuleUnLoad;
69DECLHIDDEN(int) _kext_apple_cc = __APPLE_CC__;
70RT_C_DECLS_END
71
72/** The number of IOService class instances. */
73static bool volatile g_fInstantiated = 0;
74/* Global connection to the host service */
75VBGLSFCLIENT g_vboxSFClient;
76/* VBoxVFS filesystem handle. Needed for FS unregistering. */
77static vfstable_t g_oVBoxVFSHandle;
78
79
80/**
81 * KEXT Module BSD entry point
82 */
83static kern_return_t VBoxVFSModuleLoad(struct kmod_info *pKModInfo, void *pvData)
84{
85 int rc;
86
87 /* Initialize the R0 guest library. */
88#if 0
89 rc = VbglR0SfInit();
90 if (RT_FAILURE(rc))
91 return KERN_FAILURE;
92#endif
93
94 PINFO("VirtualBox " VBOX_VERSION_STRING " shared folders "
95 "driver is loaded");
96
97 return KERN_SUCCESS;
98}
99
100
101/**
102 * KEXT Module BSD exit point
103 */
104static kern_return_t VBoxVFSModuleUnLoad(struct kmod_info *pKModInfo, void *pvData)
105{
106 int rc;
107
108#if 0
109 VbglR0SfTerm();
110#endif
111
112 PINFO("VirtualBox " VBOX_VERSION_STRING " shared folders driver is unloaded");
113
114 return KERN_SUCCESS;
115}
116
117
118/**
119 * Register VBoxFS filesystem.
120 *
121 * @returns IPRT status code.
122 */
123int VBoxVFSRegisterFilesystem(void)
124{
125 struct vfs_fsentry oVFsEntry;
126 int rc;
127
128 memset(&oVFsEntry, 0, sizeof(oVFsEntry));
129 /* Attach filesystem operations set */
130 oVFsEntry.vfe_vfsops = &g_oVBoxVFSOpts;
131 /* Attach vnode operations */
132 oVFsEntry.vfe_vopcnt = g_cVBoxVFSVnodeOpvDescListSize;
133 oVFsEntry.vfe_opvdescs = g_VBoxVFSVnodeOpvDescList;
134 /* Set flags */
135 oVFsEntry.vfe_flags =
136#if ARCH_BITS == 64
137 VFS_TBL64BITREADY |
138#endif
139 VFS_TBLTHREADSAFE |
140 VFS_TBLFSNODELOCK |
141 VFS_TBLNOTYPENUM;
142
143 memcpy(oVFsEntry.vfe_fsname, VBOXSF_DARWIN_FS_NAME, MFSNAMELEN);
144
145 rc = vfs_fsadd(&oVFsEntry, &g_oVBoxVFSHandle);
146 if (rc)
147 {
148 PINFO("Unable to register VBoxVFS filesystem (%d)", rc);
149 return VERR_GENERAL_FAILURE;
150 }
151
152 PINFO("VBoxVFS filesystem successfully registered");
153 return VINF_SUCCESS;
154}
155
156/**
157 * Unregister VBoxFS filesystem.
158 *
159 * @returns IPRT status code.
160 */
161int VBoxVFSUnRegisterFilesystem(void)
162{
163 int rc;
164
165 if (g_oVBoxVFSHandle == 0)
166 return VERR_INVALID_PARAMETER;
167
168 rc = vfs_fsremove(g_oVBoxVFSHandle);
169 if (rc)
170 {
171 PINFO("Unable to unregister VBoxVFS filesystem (%d)", rc);
172 return VERR_GENERAL_FAILURE;
173 }
174
175 g_oVBoxVFSHandle = 0;
176
177 PINFO("VBoxVFS filesystem successfully unregistered");
178 return VINF_SUCCESS;
179}
180
181
182/**
183 * Start this service.
184 */
185bool org_virtualbox_VBoxVFS::start(IOService *pProvider)
186{
187 int rc;
188
189 if (!IOService::start(pProvider))
190 return false;
191
192 /* Low level initialization should be performed only once */
193 if (!ASMAtomicCmpXchgBool(&g_fInstantiated, true, false))
194 {
195 IOService::stop(pProvider);
196 return false;
197 }
198
199 /* Wait for VBoxGuest to be started */
200 coreService = waitForCoreService();
201 if (coreService)
202 {
203 rc = VbglR0SfInit();
204 if (RT_SUCCESS(rc))
205 {
206 /* Connect to the host service. */
207 rc = VbglR0SfConnect(&g_vboxSFClient);
208 if (RT_SUCCESS(rc))
209 {
210 PINFO("VBox client connected");
211 rc = VbglR0SfSetUtf8(&g_vboxSFClient);
212 if (RT_SUCCESS(rc))
213 {
214 rc = VBoxVFSRegisterFilesystem();
215 if (RT_SUCCESS(rc))
216 {
217 registerService();
218 PINFO("Successfully started I/O kit class instance");
219 return true;
220 }
221 PERROR("Unable to register VBoxVFS filesystem");
222 }
223 else
224 {
225 PERROR("VbglR0SfSetUtf8 failed: rc=%d", rc);
226 }
227 VbglR0SfDisconnect(&g_vboxSFClient);
228 }
229 else
230 {
231 PERROR("Failed to get connection to host: rc=%d", rc);
232 }
233 VbglR0SfTerm();
234 }
235 else
236 {
237 PERROR("Failed to initialize low level library");
238 }
239 coreService->release();
240 }
241 else
242 {
243 PERROR("VBoxGuest KEXT not started");
244 }
245
246 ASMAtomicXchgBool(&g_fInstantiated, false);
247 IOService::stop(pProvider);
248
249 return false;
250}
251
252
253/**
254 * Stop this service.
255 */
256void org_virtualbox_VBoxVFS::stop(IOService *pProvider)
257{
258 int rc;
259
260 AssertReturnVoid(ASMAtomicReadBool(&g_fInstantiated));
261
262 rc = VBoxVFSUnRegisterFilesystem();
263 if (RT_FAILURE(rc))
264 {
265 PERROR("VBoxVFS filesystem is busy. Make sure all "
266 "shares are unmounted (%d)", rc);
267 }
268
269 VbglR0SfDisconnect(&g_vboxSFClient);
270 PINFO("VBox client disconnected");
271
272 VbglR0SfTerm();
273 PINFO("Low level uninit done");
274
275 coreService->release();
276 PINFO("VBoxGuest service released");
277
278 IOService::stop(pProvider);
279
280 ASMAtomicWriteBool(&g_fInstantiated, false);
281
282 PINFO("Successfully stopped I/O kit class instance");
283}
284
285
286/**
287 * Wait for VBoxGuest.kext to be started
288 */
289IOService * org_virtualbox_VBoxVFS::waitForCoreService(void)
290{
291 IOService *service;
292
293 OSDictionary *serviceToMatch = serviceMatching("org_virtualbox_VBoxGuest");
294 if (!serviceToMatch)
295 {
296 PINFO("unable to create matching dictionary");
297 return NULL;
298 }
299
300 /* Wait 10 seconds for VBoxGuest to be started */
301 service = waitForMatchingService(serviceToMatch, 10ULL * 1000000000ULL);
302 serviceToMatch->release();
303
304 return service;
305}
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