VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxUSB/darwin/USBLib-darwin.cpp@ 80074

Last change on this file since 80074 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: 7.4 KB
Line 
1/** $Id: USBLib-darwin.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * USBLib - Library for wrapping up the VBoxUSB functionality, Darwin flavor.
4 */
5
6/*
7 * Copyright (C) 2007-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 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <VBox/usblib.h>
32#include <iprt/errcore.h>
33#include <VBox/log.h>
34#include "VBoxUSBInterface.h"
35
36#include <iprt/assert.h>
37#include <iprt/asm.h>
38
39#include <mach/mach_port.h>
40#include <IOKit/IOKitLib.h>
41
42
43/*********************************************************************************************************************************
44* Defined Constants And Macros *
45*********************************************************************************************************************************/
46/** The IOClass key of the service (see VBoxUSB.cpp / Info.plist). */
47#define IOCLASS_NAME "org_virtualbox_VBoxUSB"
48
49
50/*********************************************************************************************************************************
51* Global Variables *
52*********************************************************************************************************************************/
53/** Reference counter. */
54static uint32_t volatile g_cUsers = 0;
55/** The IOMasterPort. */
56static mach_port_t g_MasterPort = 0;
57/** The current service connection. */
58static io_connect_t g_Connection = 0;
59
60
61
62USBLIB_DECL(int) USBLibInit(void)
63{
64 /*
65 * Already open?
66 * This isn't properly serialized, but we'll be fine with the current usage.
67 */
68 if (g_cUsers)
69 {
70 ASMAtomicIncU32(&g_cUsers);
71 return VINF_SUCCESS;
72 }
73
74 /*
75 * Finding the VBoxUSB service.
76 */
77 mach_port_t MasterPort;
78 kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &MasterPort);
79 if (kr != kIOReturnSuccess)
80 {
81 LogRel(("USBLib: IOMasterPort -> %#x\n", kr));
82 return RTErrConvertFromDarwinKern(kr);
83 }
84
85 CFDictionaryRef ClassToMatch = IOServiceMatching(IOCLASS_NAME);
86 if (!ClassToMatch)
87 {
88 LogRel(("USBLib: IOServiceMatching(\"%s\") failed.\n", IOCLASS_NAME));
89 return VERR_GENERAL_FAILURE;
90 }
91
92 /* Create an io_iterator_t for all instances of our drivers class that exist in the IORegistry. */
93 io_iterator_t Iterator;
94 kr = IOServiceGetMatchingServices(g_MasterPort, ClassToMatch, &Iterator);
95 if (kr != kIOReturnSuccess)
96 {
97 LogRel(("USBLib: IOServiceGetMatchingServices returned %#x\n", kr));
98 return RTErrConvertFromDarwinKern(kr);
99 }
100
101 /* Get the first item in the iterator and release it. */
102 io_service_t ServiceObject = IOIteratorNext(Iterator);
103 IOObjectRelease(Iterator);
104 if (!ServiceObject)
105 {
106 LogRel(("USBLib: Couldn't find any matches.\n"));
107 return VERR_GENERAL_FAILURE;
108 }
109
110 /*
111 * Open the service.
112 * This will cause the user client class in VBoxUSB.cpp to be instantiated.
113 */
114 kr = IOServiceOpen(ServiceObject, mach_task_self(), VBOXUSB_DARWIN_IOSERVICE_COOKIE, &g_Connection);
115 IOObjectRelease(ServiceObject);
116 if (kr != kIOReturnSuccess)
117 {
118 LogRel(("USBLib: IOServiceOpen returned %#x\n", kr));
119 return RTErrConvertFromDarwinKern(kr);
120 }
121
122 ASMAtomicIncU32(&g_cUsers);
123 return VINF_SUCCESS;
124}
125
126
127USBLIB_DECL(int) USBLibTerm(void)
128{
129 if (!g_cUsers)
130 return VERR_WRONG_ORDER;
131 if (ASMAtomicDecU32(&g_cUsers) != 0)
132 return VINF_SUCCESS;
133
134 /*
135 * We're the last guy, close down the connection.
136 */
137 kern_return_t kr = IOServiceClose(g_Connection);
138 if (kr != kIOReturnSuccess)
139 {
140 LogRel(("USBLib: Warning: IOServiceClose(%p) returned %#x\n", g_Connection, kr));
141 AssertMsgFailed(("%#x\n", kr));
142 }
143 g_Connection = 0;
144
145 return VINF_SUCCESS;
146}
147
148
149USBLIB_DECL(void *) USBLibAddFilter(PCUSBFILTER pFilter)
150{
151 VBOXUSBADDFILTEROUT Out = { 0, VERR_WRONG_ORDER };
152#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
153 IOByteCount cbOut = sizeof(Out);
154 kern_return_t kr = IOConnectMethodStructureIStructureO(g_Connection,
155 VBOXUSBMETHOD_ADD_FILTER,
156 sizeof(*pFilter),
157 &cbOut,
158 (void *)pFilter,
159 &Out);
160#else /* 10.5 and later */
161 size_t cbOut = sizeof(Out);
162 kern_return_t kr = IOConnectCallStructMethod(g_Connection,
163 VBOXUSBMETHOD_ADD_FILTER,
164 (void *)pFilter, sizeof(*pFilter),
165 &Out, &cbOut);
166#endif /* 10.5 and later */
167 if ( kr == kIOReturnSuccess
168 && RT_SUCCESS(Out.rc))
169 {
170 Assert(cbOut == sizeof(Out));
171 Assert((void *)Out.uId != NULL);
172 return (void *)Out.uId;
173 }
174
175 AssertMsgFailed(("kr=%#x Out.rc=%Rrc\n", kr, Out.rc));
176 return NULL;
177}
178
179
180USBLIB_DECL(void) USBLibRemoveFilter(void *pvId)
181{
182 int rc = VERR_WRONG_ORDER;
183#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
184 IOByteCount cbOut = sizeof(rc);
185 kern_return_t kr = IOConnectMethodStructureIStructureO(g_Connection,
186 VBOXUSBMETHOD_REMOVE_FILTER,
187 sizeof(pvId),
188 &cbOut,
189 &pvId,
190 &rc);
191#else /* 10.5 and later */
192 size_t cbOut = sizeof(rc);
193 kern_return_t kr = IOConnectCallStructMethod(g_Connection,
194 VBOXUSBMETHOD_REMOVE_FILTER,
195 (void *)&pvId, sizeof(pvId),
196 &rc, &cbOut);
197#endif /* 10.5 and later */
198 AssertMsg(kr == kIOReturnSuccess && RT_SUCCESS(rc), ("kr=%#x rc=%Rrc\n", kr, rc));
199 NOREF(kr);
200}
201
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