summaryrefslogtreecommitdiff
path: root/src/VBox/HostDrivers/VBoxUSB
diff options
context:
space:
mode:
authorvboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f>2022-01-13 07:29:50 +0000
committervboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f>2022-01-13 07:29:50 +0000
commit9e5dc8f7ed4c3c5d5159d7c4c6201e1158721276 (patch)
treeb6399b1126e25ebc5f2cdc2f3b59a5b5a4244e90 /src/VBox/HostDrivers/VBoxUSB
parentdd5db78dc0a3d0f85d123ad6373e4eacbd7d2807 (diff)
downloadVirtualBox-svn-9e5dc8f7ed4c3c5d5159d7c4c6201e1158721276.tar.gz
HostDrivers,Installer,Devices: Clean out the VBoxUSB driver which is completely unused since some time now, bugref:9808
git-svn-id: https://www.virtualbox.org/svn/vbox/trunk@93217 cfe28804-0f27-0410-a406-dd0f0b0b656f
Diffstat (limited to 'src/VBox/HostDrivers/VBoxUSB')
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/Makefile.kmk4
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/darwin/Info.plist89
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/darwin/Makefile.kmk94
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/darwin/USBLib-darwin.cpp201
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSB.cpp1890
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSBInterface.h65
-rwxr-xr-xsrc/VBox/HostDrivers/VBoxUSB/darwin/loadusb.sh70
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/darwin/testcase/Makefile.kup0
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/darwin/testcase/tstOpenUSBDev.cpp295
9 files changed, 1 insertions, 2707 deletions
diff --git a/src/VBox/HostDrivers/VBoxUSB/Makefile.kmk b/src/VBox/HostDrivers/VBoxUSB/Makefile.kmk
index 2a3e332f15d..d51d4bbbeb1 100644
--- a/src/VBox/HostDrivers/VBoxUSB/Makefile.kmk
+++ b/src/VBox/HostDrivers/VBoxUSB/Makefile.kmk
@@ -28,7 +28,7 @@ SUB_DEPTH = ../../../..
include $(KBUILD_PATH)/subheader.kmk
# Include sub-makefiles.
-if1of ($(KBUILD_TARGET), darwin solaris win)
+if1of ($(KBUILD_TARGET), solaris win)
include $(PATH_SUB_CURRENT)/$(KBUILD_TARGET)/Makefile.kmk
endif
@@ -49,8 +49,6 @@ USBLib_SOURCES = \
USBFilter.cpp
# OS specific bits if applicable.
-USBLib_SOURCES.darwin = \
- darwin/USBLib-darwin.cpp
USBLib_SOURCES.os2 = \
os2/usbcalls.c
USBLib_SOURCES.solaris = \
diff --git a/src/VBox/HostDrivers/VBoxUSB/darwin/Info.plist b/src/VBox/HostDrivers/VBoxUSB/darwin/Info.plist
deleted file mode 100644
index 16aac548116..00000000000
--- a/src/VBox/HostDrivers/VBoxUSB/darwin/Info.plist
+++ /dev/null
@@ -1,89 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>CFBundleDevelopmentRegion</key> <string>English</string>
- <key>CFBundleExecutable</key> <string>VBoxUSB</string>
- <key>CFBundleIdentifier</key> <string>org.virtualbox.kext.VBoxUSB</string>
- <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string>
- <key>CFBundleName</key> <string>VBoxUSB</string>
- <key>CFBundlePackageType</key> <string>KEXT</string>
- <key>CFBundleSignature</key> <string>????</string>
- <key>CFBundleVersion</key> <string>@VBOX_VERSION_MAJOR@.@VBOX_VERSION_MINOR@.@VBOX_VERSION_BUILD@</string>
- <key>CFBundleShortVersionString</key> <string>@VBOX_VERSION_MAJOR@.@VBOX_VERSION_MINOR@.@VBOX_VERSION_BUILD@</string>
- <key>CFBundleGetInfoString</key> <string>@VBOX_PRODUCT@ @VBOX_VERSION_STRING@, © 2007-@VBOX_C_YEAR@ @VBOX_VENDOR@</string>
- <key>IOKitPersonalities</key>
- <dict>
- <key>VBoxUSB</key>
- <dict>
- <key>CFBundleIdentifier</key> <string>org.virtualbox.kext.VBoxUSB</string>
- <key>IOClass</key> <string>org_virtualbox_VBoxUSB</string>
- <key>IOMatchCategory</key> <string>org_virtualbox_VBoxUSB</string>
- <key>IOProviderClass</key> <string>IOResources</string>
- <key>IOResourceMatch</key> <string>IOKit</string>
- <key>IOUserClientClass</key> <string>org_virtualbox_VBoxUSBClient</string>
- </dict>
- <key>VBoxUSBDevice</key>
- <dict>
- <key>CFBundleIdentifier</key> <string>org.virtualbox.kext.VBoxUSB</string>
- <key>IOClass</key> <string>org_virtualbox_VBoxUSBDevice</string>
- <key>IOProviderClass</key> <string>IOUSBDevice</string>
- <key>idVendor</key> <string>*</string>
- <key>idProduct</key> <string>*</string>
- <key>bcdDevice</key> <string>*</string>
- <key>IOProbeScore</key> <integer>9942</integer>
- <key>IOProviderMergeProperties</key>
- <dict>
- <key>IOCFPlugInTypes</key>
- <dict>
- <key>9dc7b780-9ec0-11d4-a54f-000a27052861</key> <string>IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle</string>
- </dict>
- <key>IOUserClientClass</key> <string>IOUSBDeviceUserClientV2</string>
- </dict>
- </dict>
- <key>VBoxUSBInterface</key>
- <dict>
- <key>CFBundleIdentifier</key> <string>org.virtualbox.kext.VBoxUSB</string>
- <key>IOClass</key> <string>org_virtualbox_VBoxUSBInterface</string>
- <key>IOProviderClass</key> <string>IOUSBInterface</string>
- <key>idVendor</key> <string>*</string>
- <key>idProduct</key> <string>*</string>
- <key>bcdDevice</key> <string>*</string>
- <key>bConfigurationValue</key> <string>*</string>
- <key>bInterfaceNumber</key> <string>*</string>
- <key>IOProbeScore</key> <integer>9942</integer>
- <key>IOProviderMergeProperties</key>
- <dict>
- <key>IOCFPlugInTypes</key>
- <dict>
- <key>2d9786c6-9ef3-11d4-ad51-000a27052861</key> <string>IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle</string>
- </dict>
- <key>IOUserClientClass</key> <string>IOUSBInterfaceUserClientV2</string>
- </dict>
- </dict>
- </dict>
- <key>OSBundleLibraries</key>
- <dict>
- <key>com.apple.iokit.IOUSBFamily</key> <string>3.0.0</string>
- <key>com.apple.iokit.IOUSBUserClient</key> <string>3.0.0</string>
- <key>com.apple.kpi.iokit</key> <string>9.0.0</string>
- <key>com.apple.kpi.bsd</key> <string>9.0.0</string>
- <key>com.apple.kpi.mach</key> <string>9.0.0</string>
- <key>com.apple.kpi.libkern</key> <string>9.0.0</string>
- <key>com.apple.kpi.unsupported</key> <string>9.0.0</string>
- <key>org.virtualbox.kext.VBoxDrv</key> <string>@VBOX_VERSION_MAJOR@.@VBOX_VERSION_MINOR@.@VBOX_VERSION_BUILD@</string>
- </dict>
- <key>OSBundleLibraries_x86_64</key>
- <dict>
- <key>com.apple.iokit.IOUSBFamily</key> <string>3.5.0a25</string>
- <key>com.apple.iokit.IOUSBUserClient</key> <string>3.5.0a25</string>
- <key>com.apple.kpi.iokit</key> <string>10.0.0d3</string>
- <key>com.apple.kpi.bsd</key> <string>10.0.0d3</string>
- <key>com.apple.kpi.mach</key> <string>10.0.0d3</string>
- <key>com.apple.kpi.libkern</key> <string>10.0.0d3</string>
- <key>com.apple.kpi.unsupported</key> <string>10.0.0d3</string>
- <key>org.virtualbox.kext.VBoxDrv</key> <string>@VBOX_VERSION_MAJOR@.@VBOX_VERSION_MINOR@.@VBOX_VERSION_BUILD@</string>
- </dict>
-</dict>
-</plist>
-
diff --git a/src/VBox/HostDrivers/VBoxUSB/darwin/Makefile.kmk b/src/VBox/HostDrivers/VBoxUSB/darwin/Makefile.kmk
deleted file mode 100644
index 06d490e45a5..00000000000
--- a/src/VBox/HostDrivers/VBoxUSB/darwin/Makefile.kmk
+++ /dev/null
@@ -1,94 +0,0 @@
-# $Id$
-## @file
-# Sub-Makefile for the Darwin VBoxUSB kernel extension.
-#
-
-#
-# Copyright (C) 2006-2022 Oracle Corporation
-#
-# This file is part of VirtualBox Open Source Edition (OSE), as
-# available from http://www.virtualbox.org. This file is free software;
-# you can redistribute it and/or modify it under the terms of the GNU
-# General Public License (GPL) as published by the Free Software
-# Foundation, in version 2 as it comes in the "COPYING" file of the
-# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
-# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
-#
-# The contents of this file may alternatively be used under the terms
-# of the Common Development and Distribution License Version 1.0
-# (CDDL) only, as it comes in the "COPYING.CDDL" file of the
-# VirtualBox OSE distribution, in which case the provisions of the
-# CDDL are applicable instead of those of the GPL.
-#
-# You may elect to license modified versions of this file under the
-# terms and conditions of either the GPL or the CDDL or both.
-#
-
-SUB_DEPTH = ../../../../..
-include $(KBUILD_PATH)/subheader.kmk
-ifn1of ($(KBUILD_TARGET_ARCH), arm64)
-
-#
-# VBoxUSB.kext - The Darwin Kernel Extension.
-#
-
-# Leopard (x86) and Snow Leopard (x86/amd64)
-SYSMODS.darwin += VBoxUSB
-VBoxUSB_TEMPLATE := VBOXR0DRV
-ifdef KMK_WITH_VERSION_COMPARE ## @todo @bugref{9790}: Remove after updating kmk.
-if "$(VBOX_DEF_MACOSX_VERSION_MIN)" vge "10.11" # The IOUSBDevice.h header was removed in 10.11.
-VBoxUSB_TEMPLATE := VBoxR0DrvOSX10.10
-endif
-endif ## @todo @bugref{9790}: Remove after updating kmk.
-VBoxUSB_INST = $(INST_VBOXUSB)Contents/MacOS/
-VBoxUSB_DEBUG_INST.darwin = $(patsubst %/,%,$(INST_VBOXUSB))
-VBoxUSB_INCS = \
- . \
- ..
-#VBoxUSB_LDFLAGS = -v -Wl,-whyload -Wl,-v -Wl,-whatsloaded
-VBoxUSB_SOURCES := \
- VBoxUSB.cpp \
- ../USBFilter.cpp \
- ../VBoxUSBFilterMgr.cpp
-
-INSTALLS += VBoxUSB.kext
-VBoxUSB.kext_INST = $(INST_VBOXUSB)Contents/
-VBoxUSB.kext_SOURCES = $(VBoxUSB.kext_0_OUTDIR)/Contents/Info.plist
-VBoxUSB.kext_CLEAN = $(VBoxUSB.kext_0_OUTDIR)/Contents/Info.plist
-VBoxUSB.kext_BLDDIRS = $(VBoxUSB.kext_0_OUTDIR)/Contents/
-
-$$(VBoxUSB.kext_0_OUTDIR)/Contents/Info.plist: $(PATH_SUB_CURRENT)/Info.plist $(VBOX_VERSION_MK) | $$(dir $$@)
- $(call MSG_GENERATE,VBoxUSB,$@,$<)
- $(QUIET)$(RM) -f $@
- $(QUIET)$(SED) \
- -e 's/@VBOX_VERSION_STRING@/$(VBOX_VERSION_STRING)/g' \
- -e 's/@VBOX_VERSION_MAJOR@/$(VBOX_VERSION_MAJOR)/g' \
- -e 's/@VBOX_VERSION_MINOR@/$(VBOX_VERSION_MINOR)/g' \
- -e 's/@VBOX_VERSION_BUILD@/$(VBOX_VERSION_BUILD)/g' \
- -e 's/@VBOX_VENDOR@/$(VBOX_VENDOR)/g' \
- -e 's/@VBOX_PRODUCT@/$(VBOX_PRODUCT)/g' \
- -e 's/@VBOX_C_YEAR@/$(VBOX_C_YEAR)/g' \
- --output $@ \
- $<
-
-$(evalcall2 VBOX_TEST_SIGN_KEXT,VBoxUSB)
-
-# Common manual loader script.
-INSTALLS += ScriptsUSB
-ScriptsUSB_INST = $(INST_DIST)
-ScriptsUSB_EXEC_SOURCES = \
- loadusb.sh
-
-ifdef VBOX_WITH_TESTCASES
-#
-# Testcase for doing some manual driver testing...
-#
-PROGRAMS += tstOpenUSBDev
-tstOpenUSBDev_TEMPLATE = VBOXR3TSTEXE
-tstOpenUSBDev_SOURCES = testcase/tstOpenUSBDev.cpp
-tstOpenUSBDev_LDFLAGS = -framework CoreFoundation -framework IOKit
-endif
-
-endif # ! arm64
-include $(FILE_KBUILD_SUB_FOOTER)
-
diff --git a/src/VBox/HostDrivers/VBoxUSB/darwin/USBLib-darwin.cpp b/src/VBox/HostDrivers/VBoxUSB/darwin/USBLib-darwin.cpp
deleted file mode 100644
index 3bd956a5787..00000000000
--- a/src/VBox/HostDrivers/VBoxUSB/darwin/USBLib-darwin.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-/** $Id$ */
-/** @file
- * USBLib - Library for wrapping up the VBoxUSB functionality, Darwin flavor.
- */
-
-/*
- * Copyright (C) 2007-2022 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * The contents of this file may alternatively be used under the terms
- * of the Common Development and Distribution License Version 1.0
- * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
- * VirtualBox OSE distribution, in which case the provisions of the
- * CDDL are applicable instead of those of the GPL.
- *
- * You may elect to license modified versions of this file under the
- * terms and conditions of either the GPL or the CDDL or both.
- */
-
-
-/*********************************************************************************************************************************
-* Header Files *
-*********************************************************************************************************************************/
-#include <VBox/usblib.h>
-#include <iprt/errcore.h>
-#include <VBox/log.h>
-#include "VBoxUSBInterface.h"
-
-#include <iprt/assert.h>
-#include <iprt/asm.h>
-
-#include <mach/mach_port.h>
-#include <IOKit/IOKitLib.h>
-
-
-/*********************************************************************************************************************************
-* Defined Constants And Macros *
-*********************************************************************************************************************************/
-/** The IOClass key of the service (see VBoxUSB.cpp / Info.plist). */
-#define IOCLASS_NAME "org_virtualbox_VBoxUSB"
-
-
-/*********************************************************************************************************************************
-* Global Variables *
-*********************************************************************************************************************************/
-/** Reference counter. */
-static uint32_t volatile g_cUsers = 0;
-/** The IOMasterPort. */
-static mach_port_t g_MasterPort = 0;
-/** The current service connection. */
-static io_connect_t g_Connection = 0;
-
-
-
-USBLIB_DECL(int) USBLibInit(void)
-{
- /*
- * Already open?
- * This isn't properly serialized, but we'll be fine with the current usage.
- */
- if (g_cUsers)
- {
- ASMAtomicIncU32(&g_cUsers);
- return VINF_SUCCESS;
- }
-
- /*
- * Finding the VBoxUSB service.
- */
- mach_port_t MasterPort;
- kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &MasterPort);
- if (kr != kIOReturnSuccess)
- {
- LogRel(("USBLib: IOMasterPort -> %#x\n", kr));
- return RTErrConvertFromDarwinKern(kr);
- }
-
- CFDictionaryRef ClassToMatch = IOServiceMatching(IOCLASS_NAME);
- if (!ClassToMatch)
- {
- LogRel(("USBLib: IOServiceMatching(\"%s\") failed.\n", IOCLASS_NAME));
- return VERR_GENERAL_FAILURE;
- }
-
- /* Create an io_iterator_t for all instances of our drivers class that exist in the IORegistry. */
- io_iterator_t Iterator;
- kr = IOServiceGetMatchingServices(g_MasterPort, ClassToMatch, &Iterator);
- if (kr != kIOReturnSuccess)
- {
- LogRel(("USBLib: IOServiceGetMatchingServices returned %#x\n", kr));
- return RTErrConvertFromDarwinKern(kr);
- }
-
- /* Get the first item in the iterator and release it. */
- io_service_t ServiceObject = IOIteratorNext(Iterator);
- IOObjectRelease(Iterator);
- if (!ServiceObject)
- {
- LogRel(("USBLib: Couldn't find any matches.\n"));
- return VERR_GENERAL_FAILURE;
- }
-
- /*
- * Open the service.
- * This will cause the user client class in VBoxUSB.cpp to be instantiated.
- */
- kr = IOServiceOpen(ServiceObject, mach_task_self(), VBOXUSB_DARWIN_IOSERVICE_COOKIE, &g_Connection);
- IOObjectRelease(ServiceObject);
- if (kr != kIOReturnSuccess)
- {
- LogRel(("USBLib: IOServiceOpen returned %#x\n", kr));
- return RTErrConvertFromDarwinKern(kr);
- }
-
- ASMAtomicIncU32(&g_cUsers);
- return VINF_SUCCESS;
-}
-
-
-USBLIB_DECL(int) USBLibTerm(void)
-{
- if (!g_cUsers)
- return VERR_WRONG_ORDER;
- if (ASMAtomicDecU32(&g_cUsers) != 0)
- return VINF_SUCCESS;
-
- /*
- * We're the last guy, close down the connection.
- */
- kern_return_t kr = IOServiceClose(g_Connection);
- if (kr != kIOReturnSuccess)
- {
- LogRel(("USBLib: Warning: IOServiceClose(%p) returned %#x\n", g_Connection, kr));
- AssertMsgFailed(("%#x\n", kr));
- }
- g_Connection = 0;
-
- return VINF_SUCCESS;
-}
-
-
-USBLIB_DECL(void *) USBLibAddFilter(PCUSBFILTER pFilter)
-{
- VBOXUSBADDFILTEROUT Out = { 0, VERR_WRONG_ORDER };
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
- IOByteCount cbOut = sizeof(Out);
- kern_return_t kr = IOConnectMethodStructureIStructureO(g_Connection,
- VBOXUSBMETHOD_ADD_FILTER,
- sizeof(*pFilter),
- &cbOut,
- (void *)pFilter,
- &Out);
-#else /* 10.5 and later */
- size_t cbOut = sizeof(Out);
- kern_return_t kr = IOConnectCallStructMethod(g_Connection,
- VBOXUSBMETHOD_ADD_FILTER,
- (void *)pFilter, sizeof(*pFilter),
- &Out, &cbOut);
-#endif /* 10.5 and later */
- if ( kr == kIOReturnSuccess
- && RT_SUCCESS(Out.rc))
- {
- Assert(cbOut == sizeof(Out));
- Assert((void *)Out.uId != NULL);
- return (void *)Out.uId;
- }
-
- AssertMsgFailed(("kr=%#x Out.rc=%Rrc\n", kr, Out.rc));
- return NULL;
-}
-
-
-USBLIB_DECL(void) USBLibRemoveFilter(void *pvId)
-{
- int rc = VERR_WRONG_ORDER;
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
- IOByteCount cbOut = sizeof(rc);
- kern_return_t kr = IOConnectMethodStructureIStructureO(g_Connection,
- VBOXUSBMETHOD_REMOVE_FILTER,
- sizeof(pvId),
- &cbOut,
- &pvId,
- &rc);
-#else /* 10.5 and later */
- size_t cbOut = sizeof(rc);
- kern_return_t kr = IOConnectCallStructMethod(g_Connection,
- VBOXUSBMETHOD_REMOVE_FILTER,
- (void *)&pvId, sizeof(pvId),
- &rc, &cbOut);
-#endif /* 10.5 and later */
- AssertMsg(kr == kIOReturnSuccess && RT_SUCCESS(rc), ("kr=%#x rc=%Rrc\n", kr, rc));
- NOREF(kr);
-}
-
diff --git a/src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSB.cpp b/src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSB.cpp
deleted file mode 100644
index 3d91e49b598..00000000000
--- a/src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSB.cpp
+++ /dev/null
@@ -1,1890 +0,0 @@
-/* $Id$ */
-/** @file
- * VirtualBox USB driver for Darwin.
- *
- * This driver is responsible for hijacking USB devices when any of the
- * VBoxSVC daemons requests it. It is also responsible for arbitrating
- * access to hijacked USB devices.
- */
-
-/*
- * Copyright (C) 2006-2022 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * The contents of this file may alternatively be used under the terms
- * of the Common Development and Distribution License Version 1.0
- * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
- * VirtualBox OSE distribution, in which case the provisions of the
- * CDDL are applicable instead of those of the GPL.
- *
- * You may elect to license modified versions of this file under the
- * terms and conditions of either the GPL or the CDDL or both.
- */
-
-
-/*********************************************************************************************************************************
-* Header Files *
-*********************************************************************************************************************************/
-#define LOG_GROUP LOG_GROUP_USB_DRV
-/* Deal with conflicts first.
- * (This is mess inherited from BSD. The *BSDs has clean this up long ago.) */
-#include <sys/param.h>
-#undef PVM
-#include <IOKit/IOLib.h> /* Assert as function */
-
-#include "VBoxUSBInterface.h"
-#include "VBoxUSBFilterMgr.h"
-#include <VBox/version.h>
-#include <VBox/usblib-darwin.h>
-#include <VBox/log.h>
-#include <iprt/types.h>
-#include <iprt/initterm.h>
-#include <iprt/assert.h>
-#include <iprt/semaphore.h>
-#include <iprt/process.h>
-#include <iprt/alloc.h>
-#include <iprt/errcore.h>
-#include <iprt/asm.h>
-
-#include <mach/kmod.h>
-#include <miscfs/devfs/devfs.h>
-#include <sys/conf.h>
-#include <sys/errno.h>
-#include <sys/ioccom.h>
-#include <sys/malloc.h>
-#include <sys/proc.h>
-#include <kern/task.h>
-#include <IOKit/IOService.h>
-#include <IOKit/IOUserClient.h>
-#include <IOKit/IOKitKeys.h>
-#include <IOKit/usb/USB.h>
-#include <IOKit/usb/IOUSBDevice.h>
-#include <IOKit/usb/IOUSBInterface.h>
-#include <IOKit/usb/IOUSBUserClient.h>
-
-/* private: */
-RT_C_DECLS_BEGIN
-extern void *get_bsdtask_info(task_t);
-RT_C_DECLS_END
-
-
-/*********************************************************************************************************************************
-* Defined Constants And Macros *
-*********************************************************************************************************************************/
-/** Locks the lists. */
-#define VBOXUSB_LOCK() do { int rc = RTSemFastMutexRequest(g_Mtx); AssertRC(rc); } while (0)
-/** Unlocks the lists. */
-#define VBOXUSB_UNLOCK() do { int rc = RTSemFastMutexRelease(g_Mtx); AssertRC(rc); } while (0)
-
-
-/*********************************************************************************************************************************
-* Internal Functions *
-*********************************************************************************************************************************/
-RT_C_DECLS_BEGIN
-static kern_return_t VBoxUSBStart(struct kmod_info *pKModInfo, void *pvData);
-static kern_return_t VBoxUSBStop(struct kmod_info *pKModInfo, void *pvData);
-RT_C_DECLS_END
-
-
-/*********************************************************************************************************************************
-* Structures and Typedefs *
-*********************************************************************************************************************************/
-/**
- * The service class.
- *
- * This is the management service that VBoxSVC and the VMs speak to.
- *
- * @remark The method prototypes are ordered somewhat after their order of
- * invocation, while the implementation is ordered by pair.
- */
-class org_virtualbox_VBoxUSB : public IOService
-{
- OSDeclareDefaultStructors(org_virtualbox_VBoxUSB);
-
-public:
- RTR0MEMEF_NEW_AND_DELETE_OPERATORS_IOKIT();
-
- /** @name IOService
- * @{ */
- virtual bool init(OSDictionary *pDictionary = 0);
- virtual bool start(IOService *pProvider);
- virtual bool open(IOService *pForClient, IOOptionBits fOptions = 0, void *pvArg = 0);
- virtual bool terminate(IOOptionBits fOptions);
- virtual void close(IOService *pForClient, IOOptionBits fOptions = 0);
- virtual void stop(IOService *pProvider);
- virtual void free();
- /** @} */
-
-private:
- /** Guard against the parent class growing and us using outdated headers. */
- uint8_t m_abSafetyPadding[256];
-};
-OSDefineMetaClassAndStructors(org_virtualbox_VBoxUSB, IOService);
-
-
-/**
- * The user client class that pairs up with org_virtualbox_VBoxUSB.
- */
-class org_virtualbox_VBoxUSBClient : public IOUserClient
-{
- OSDeclareDefaultStructors(org_virtualbox_VBoxUSBClient);
-
-public:
- RTR0MEMEF_NEW_AND_DELETE_OPERATORS_IOKIT();
-
- /** @name IOService & IOUserClient
- * @{ */
- virtual bool initWithTask(task_t OwningTask, void *pvSecurityId, UInt32 u32Type);
- virtual bool start(IOService *pProvider);
- virtual IOReturn clientClose(void);
- virtual IOReturn clientDied(void);
- virtual bool terminate(IOOptionBits fOptions = 0);
- virtual bool finalize(IOOptionBits fOptions);
- virtual void stop(IOService *pProvider);
- virtual void free();
- virtual IOExternalMethod *getTargetAndMethodForIndex(IOService **ppService, UInt32 iMethod);
- /** @} */
-
- /** @name User client methods
- * @{ */
- IOReturn addFilter(PUSBFILTER pFilter, PVBOXUSBADDFILTEROUT pOut, IOByteCount cbFilter, IOByteCount *pcbOut);
- IOReturn removeFilter(uintptr_t *puId, int *prc, IOByteCount cbIn, IOByteCount *pcbOut);
- /** @} */
-
- static bool isClientTask(task_t ClientTask);
-
-private:
- /** Guard against the parent class growing and us using outdated headers. */
- uint8_t m_abSafetyPadding[256];
- /** The service provider. */
- org_virtualbox_VBoxUSB *m_pProvider;
- /** The client task. */
- task_t m_Task;
- /** The client process. */
- RTPROCESS m_Process;
- /** Pointer to the next user client. */
- org_virtualbox_VBoxUSBClient * volatile m_pNext;
- /** List of user clients. Protected by g_Mtx. */
- static org_virtualbox_VBoxUSBClient * volatile s_pHead;
-};
-OSDefineMetaClassAndStructors(org_virtualbox_VBoxUSBClient, IOUserClient);
-
-
-/**
- * The IOUSBDevice driver class.
- *
- * The main purpose of this is hijack devices matching current filters.
- *
- * @remarks This is derived from IOUSBUserClientInit instead of IOService because we must make
- * sure IOUSBUserClientInit::start() gets invoked for this provider. The problem is that
- * there is some kind of magic that prevents this from happening if we boost the probe
- * score to high. With the result that we don't have the required plugin entry for
- * user land and consequently cannot open it.
- *
- * So, to avoid having to write a lot of code we just inherit from IOUSBUserClientInit
- * and make some possibly bold assumptions about it not changing. This just means
- * we'll have to keep an eye on the source apple releases or only call
- * IOUSBUserClientInit::start() and hand the rest of the super calls to IOService. For
- * now we're doing it by the C++ book.
- */
-class org_virtualbox_VBoxUSBDevice : public IOUSBUserClientInit
-{
- OSDeclareDefaultStructors(org_virtualbox_VBoxUSBDevice);
-
-public:
- RTR0MEMEF_NEW_AND_DELETE_OPERATORS_IOKIT();
-
- /** @name IOService
- * @{ */
- virtual bool init(OSDictionary *pDictionary = 0);
- virtual IOService *probe(IOService *pProvider, SInt32 *pi32Score);
- virtual bool start(IOService *pProvider);
- virtual bool terminate(IOOptionBits fOptions = 0);
- virtual void stop(IOService *pProvider);
- virtual void free();
- virtual IOReturn message(UInt32 enmMsg, IOService *pProvider, void *pvArg = 0);
- /** @} */
-
- static void scheduleReleaseByOwner(RTPROCESS Owner);
-private:
- /** Padding to guard against parent class expanding (see class remarks). */
- uint8_t m_abSafetyPadding[256];
- /** The interface we're driving (aka. the provider). */
- IOUSBDevice *m_pDevice;
- /** The owner process, meaning the VBoxSVC process. */
- RTPROCESS volatile m_Owner;
- /** The client process, meaning the VM process. */
- RTPROCESS volatile m_Client;
- /** The ID of the matching filter. */
- uintptr_t m_uId;
- /** Have we opened the device or not? */
- bool volatile m_fOpen;
- /** Should be open the device on the next close notification message? */
- bool volatile m_fOpenOnWasClosed;
- /** Whether to re-enumerate this device when the client closes it.
- * This is something we'll do when the filter owner dies. */
- bool volatile m_fReleaseOnClose;
- /** Whether we're being unloaded or not.
- * Only valid in stop(). */
- bool m_fBeingUnloaded;
- /** Pointer to the next device in the list. */
- org_virtualbox_VBoxUSBDevice * volatile m_pNext;
- /** Pointer to the list head. Protected by g_Mtx. */
- static org_virtualbox_VBoxUSBDevice * volatile s_pHead;
-
-#ifdef DEBUG
- /** The interest notifier. */
- IONotifier *m_pNotifier;
-
- static IOReturn MyInterestHandler(void *pvTarget, void *pvRefCon, UInt32 enmMsgType,
- IOService *pProvider, void * pvMsgArg, vm_size_t cbMsgArg);
-#endif
-};
-OSDefineMetaClassAndStructors(org_virtualbox_VBoxUSBDevice, IOUSBUserClientInit);
-
-
-/**
- * The IOUSBInterface driver class.
- *
- * The main purpose of this is hijack interfaces which device is driven
- * by org_virtualbox_VBoxUSBDevice.
- *
- * @remarks See org_virtualbox_VBoxUSBDevice for why we use IOUSBUserClientInit.
- */
-class org_virtualbox_VBoxUSBInterface : public IOUSBUserClientInit
-{
- OSDeclareDefaultStructors(org_virtualbox_VBoxUSBInterface);
-
-public:
- RTR0MEMEF_NEW_AND_DELETE_OPERATORS_IOKIT();
-
- /** @name IOService
- * @{ */
- virtual bool init(OSDictionary *pDictionary = 0);
- virtual IOService *probe(IOService *pProvider, SInt32 *pi32Score);
- virtual bool start(IOService *pProvider);
- virtual bool terminate(IOOptionBits fOptions = 0);
- virtual void stop(IOService *pProvider);
- virtual void free();
- virtual IOReturn message(UInt32 enmMsg, IOService *pProvider, void *pvArg = 0);
- /** @} */
-
-private:
- /** Padding to guard against parent class expanding (see class remarks). */
- uint8_t m_abSafetyPadding[256];
- /** The interface we're driving (aka. the provider). */
- IOUSBInterface *m_pInterface;
- /** Have we opened the device or not? */
- bool volatile m_fOpen;
- /** Should be open the device on the next close notification message? */
- bool volatile m_fOpenOnWasClosed;
-};
-OSDefineMetaClassAndStructors(org_virtualbox_VBoxUSBInterface, IOUSBUserClientInit);
-
-
-
-
-
-/*********************************************************************************************************************************
-* Global Variables *
-*********************************************************************************************************************************/
-/*
- * Declare the module stuff.
- */
-RT_C_DECLS_BEGIN
-extern kern_return_t _start(struct kmod_info *pKModInfo, void *pvData);
-extern kern_return_t _stop(struct kmod_info *pKModInfo, void *pvData);
-
-KMOD_EXPLICIT_DECL(VBoxDrv, VBOX_VERSION_STRING, _start, _stop)
-DECL_HIDDEN_DATA(kmod_start_func_t *) _realmain = VBoxUSBStart;
-DECL_HIDDEN_DATA(kmod_stop_func_t *) _antimain = VBoxUSBStop;
-DECL_HIDDEN_DATA(int) _kext_apple_cc = __APPLE_CC__;
-RT_C_DECLS_END
-
-/** Mutex protecting the lists. */
-static RTSEMFASTMUTEX g_Mtx = NIL_RTSEMFASTMUTEX;
-org_virtualbox_VBoxUSBClient * volatile org_virtualbox_VBoxUSBClient::s_pHead = NULL;
-org_virtualbox_VBoxUSBDevice * volatile org_virtualbox_VBoxUSBDevice::s_pHead = NULL;
-
-/** Global instance count - just for checking proving that everything is destroyed correctly. */
-static volatile uint32_t g_cInstances = 0;
-
-
-/**
- * Start the kernel module.
- */
-static kern_return_t VBoxUSBStart(struct kmod_info *pKModInfo, void *pvData)
-{
- RT_NOREF(pKModInfo, pvData);
- int rc;
- Log(("VBoxUSBStart\n"));
-
- /*
- * Initialize IPRT.
- */
- rc = RTR0Init(0);
- if (RT_SUCCESS(rc))
- {
- /*
- * Create the spinlock.
- */
- rc = RTSemFastMutexCreate(&g_Mtx);
- if (RT_SUCCESS(rc))
- {
- rc = VBoxUSBFilterInit();
- if (RT_SUCCESS(rc))
- {
-#if 0 /* testing */
- USBFILTER Flt;
- USBFilterInit(&Flt, USBFILTERTYPE_CAPTURE);
- USBFilterSetNumExact(&Flt, USBFILTERIDX_VENDOR_ID, 0x096e, true);
- uintptr_t uId;
- rc = VBoxUSBFilterAdd(&Flt, 1, &uId);
- printf("VBoxUSB: VBoxUSBFilterAdd #1 -> %d + %p\n", rc, uId);
-
- USBFilterInit(&Flt, USBFILTERTYPE_CAPTURE);
- USBFilterSetStringPattern(&Flt, USBFILTERIDX_PRODUCT_STR, "*DISK*", true);
- rc = VBoxUSBFilterAdd(&Flt, 2, &uId);
- printf("VBoxUSB: VBoxUSBFilterAdd #2 -> %d + %p\n", rc, uId);
-#endif
- return KMOD_RETURN_SUCCESS;
- }
- printf("VBoxUSB: VBoxUSBFilterInit failed (rc=%d)\n", rc);
- RTSemFastMutexDestroy(g_Mtx);
- g_Mtx = NIL_RTSEMFASTMUTEX;
- }
- else
- printf("VBoxUSB: RTSemFastMutexCreate failed (rc=%d)\n", rc);
- RTR0Term();
- }
- else
- printf("VBoxUSB: failed to initialize IPRT (rc=%d)\n", rc);
-
- return KMOD_RETURN_FAILURE;
-}
-
-
-/**
- * Stop the kernel module.
- */
-static kern_return_t VBoxUSBStop(struct kmod_info *pKModInfo, void *pvData)
-{
- RT_NOREF(pKModInfo, pvData);
- Log(("VBoxUSBStop: g_cInstances=%d\n", g_cInstances));
-
- /** @todo Fix problem with crashing when unloading a driver that's in use. */
-
- /*
- * Undo the work done during start (in reverse order).
- */
- VBoxUSBFilterTerm();
-
- int rc = RTSemFastMutexDestroy(g_Mtx);
- AssertRC(rc);
- g_Mtx = NIL_RTSEMFASTMUTEX;
-
- RTR0Term();
-
- Log(("VBoxUSBStop - done\n"));
- return KMOD_RETURN_SUCCESS;
-}
-
-
-
-
-
-#ifdef LOG_ENABLED
-/**
- * Gets the name of a IOKit message.
- *
- * @returns Message name (read only).
- * @param enmMsg The message.
- */
-DECLINLINE(const char *) DbgGetIOKitMessageName(UInt32 enmMsg)
-{
- switch (enmMsg)
- {
-# define MY_CASE(enm) case enm: return #enm; break
- MY_CASE(kIOMessageServiceIsTerminated);
- MY_CASE(kIOMessageServiceIsSuspended);
- MY_CASE(kIOMessageServiceIsResumed);
- MY_CASE(kIOMessageServiceIsRequestingClose);
- MY_CASE(kIOMessageServiceIsAttemptingOpen);
- MY_CASE(kIOMessageServiceWasClosed);
- MY_CASE(kIOMessageServiceBusyStateChange);
- MY_CASE(kIOMessageServicePropertyChange);
- MY_CASE(kIOMessageCanDevicePowerOff);
- MY_CASE(kIOMessageDeviceWillPowerOff);
- MY_CASE(kIOMessageDeviceWillNotPowerOff);
- MY_CASE(kIOMessageDeviceHasPoweredOn);
- MY_CASE(kIOMessageCanSystemPowerOff);
- MY_CASE(kIOMessageSystemWillPowerOff);
- MY_CASE(kIOMessageSystemWillNotPowerOff);
- MY_CASE(kIOMessageCanSystemSleep);
- MY_CASE(kIOMessageSystemWillSleep);
- MY_CASE(kIOMessageSystemWillNotSleep);
- MY_CASE(kIOMessageSystemHasPoweredOn);
- MY_CASE(kIOMessageSystemWillRestart);
- MY_CASE(kIOMessageSystemWillPowerOn);
- MY_CASE(kIOUSBMessageHubResetPort);
- MY_CASE(kIOUSBMessageHubSuspendPort);
- MY_CASE(kIOUSBMessageHubResumePort);
- MY_CASE(kIOUSBMessageHubIsDeviceConnected);
- MY_CASE(kIOUSBMessageHubIsPortEnabled);
- MY_CASE(kIOUSBMessageHubReEnumeratePort);
- MY_CASE(kIOUSBMessagePortHasBeenReset);
- MY_CASE(kIOUSBMessagePortHasBeenResumed);
- MY_CASE(kIOUSBMessageHubPortClearTT);
- MY_CASE(kIOUSBMessagePortHasBeenSuspended);
- MY_CASE(kIOUSBMessageFromThirdParty);
- MY_CASE(kIOUSBMessagePortWasNotSuspended);
- MY_CASE(kIOUSBMessageExpressCardCantWake);
-// MY_CASE(kIOUSBMessageCompositeDriverReconfigured);
-# undef MY_CASE
- }
- return "unknown";
-}
-#endif /* LOG_ENABLED */
-
-
-
-
-
-/*
- *
- * org_virtualbox_VBoxUSB
- *
- */
-
-
-/**
- * Initialize the object.
- * @remark Only for logging.
- */
-bool
-org_virtualbox_VBoxUSB::init(OSDictionary *pDictionary)
-{
- uint32_t cInstances = ASMAtomicIncU32(&g_cInstances);
- Log(("VBoxUSB::init([%p], %p) new g_cInstances=%d\n", this, pDictionary, cInstances));
- RT_NOREF_PV(cInstances);
-
- if (IOService::init(pDictionary))
- {
- /* init members. */
- return true;
- }
- ASMAtomicDecU32(&g_cInstances);
- return false;
-}
-
-
-/**
- * Free the object.
- * @remark Only for logging.
- */
-void
-org_virtualbox_VBoxUSB::free()
-{
- uint32_t cInstances = ASMAtomicDecU32(&g_cInstances); NOREF(cInstances);
- Log(("VBoxUSB::free([%p]) new g_cInstances=%d\n", this, cInstances));
- IOService::free();
-}
-
-
-/**
- * Start this service.
- */
-bool
-org_virtualbox_VBoxUSB::start(IOService *pProvider)
-{
- Log(("VBoxUSB::start([%p], %p {%s})\n", this, pProvider, pProvider->getName()));
-
- if (IOService::start(pProvider))
- {
- /* register the service. */
- registerService();
- return true;
- }
- return false;
-}
-
-
-/**
- * Stop this service.
- * @remark Only for logging.
- */
-void
-org_virtualbox_VBoxUSB::stop(IOService *pProvider)
-{
- Log(("VBoxUSB::stop([%p], %p (%s))\n", this, pProvider, pProvider->getName()));
- IOService::stop(pProvider);
-}
-
-
-/**
- * Stop this service.
- * @remark Only for logging.
- */
-bool
-org_virtualbox_VBoxUSB::open(IOService *pForClient, IOOptionBits fOptions/* = 0*/, void *pvArg/* = 0*/)
-{
- Log(("VBoxUSB::open([%p], %p, %#x, %p)\n", this, pForClient, fOptions, pvArg));
- bool fRc = IOService::open(pForClient, fOptions, pvArg);
- Log(("VBoxUSB::open([%p], %p, %#x, %p) -> %d\n", this, pForClient, fOptions, pvArg, fRc));
- return fRc;
-}
-
-
-/**
- * Stop this service.
- * @remark Only for logging.
- */
-void
-org_virtualbox_VBoxUSB::close(IOService *pForClient, IOOptionBits fOptions/* = 0*/)
-{
- Log(("VBoxUSB::close([%p], %p, %#x)\n", this, pForClient, fOptions));
- IOService::close(pForClient, fOptions);
-}
-
-
-/**
- * Terminate request.
- * @remark Only for logging.
- */
-bool
-org_virtualbox_VBoxUSB::terminate(IOOptionBits fOptions)
-{
- Log(("VBoxUSB::terminate([%p], %#x): g_cInstances=%d\n", this, fOptions, g_cInstances));
- bool fRc = IOService::terminate(fOptions);
- Log(("VBoxUSB::terminate([%p], %#x): returns %d\n", this, fOptions, fRc));
- return fRc;
-}
-
-
-
-
-
-
-
-
-
-
-
-/*
- *
- * org_virtualbox_VBoxUSBClient
- *
- */
-
-
-/**
- * Initializer called when the client opens the service.
- */
-bool
-org_virtualbox_VBoxUSBClient::initWithTask(task_t OwningTask, void *pvSecurityId, UInt32 u32Type)
-{
- if (!OwningTask)
- {
- Log(("VBoxUSBClient::initWithTask([%p], %p, %p, %#x) -> false (no task)\n", this, OwningTask, pvSecurityId, u32Type));
- return false;
- }
- if (u32Type != VBOXUSB_DARWIN_IOSERVICE_COOKIE)
- {
- Log(("VBoxUSBClient::initWithTask: Bade cookie %#x\n", u32Type));
- return false;
- }
-
- proc_t pProc = (proc_t)get_bsdtask_info(OwningTask); /* we need the pid */
- Log(("VBoxUSBClient::initWithTask([%p], %p(->%p:{.pid=%d}, %p, %#x)\n",
- this, OwningTask, pProc, pProc ? proc_pid(pProc) : -1, pvSecurityId, u32Type));
-
- if (IOUserClient::initWithTask(OwningTask, pvSecurityId , u32Type))
- {
- /*
- * In theory we have to call task_reference() to make sure that the task is
- * valid during the lifetime of this object. The pointer is only used to check
- * for the context this object is called in though and never dereferenced
- * or passed to anything which might, so we just skip this step.
- */
- m_pProvider = NULL;
- m_Task = OwningTask;
- m_Process = pProc ? proc_pid(pProc) : NIL_RTPROCESS;
- m_pNext = NULL;
-
- uint32_t cInstances = ASMAtomicIncU32(&g_cInstances);
- Log(("VBoxUSBClient::initWithTask([%p], %p(->%p:{.pid=%d}, %p, %#x) -> true; new g_cInstances=%d\n",
- this, OwningTask, pProc, pProc ? proc_pid(pProc) : -1, pvSecurityId, u32Type, cInstances));
- RT_NOREF_PV(cInstances);
- return true;
- }
-
- Log(("VBoxUSBClient::initWithTask([%p], %p(->%p:{.pid=%d}, %p, %#x) -> false\n",
- this, OwningTask, pProc, pProc ? proc_pid(pProc) : -1, pvSecurityId, u32Type));
- return false;
-}
-
-
-/**
- * Free the object.
- * @remark Only for logging.
- */
-void
-org_virtualbox_VBoxUSBClient::free()
-{
- uint32_t cInstances = ASMAtomicDecU32(&g_cInstances); NOREF(cInstances);
- Log(("VBoxUSBClient::free([%p]) new g_cInstances=%d\n", this, cInstances));
- IOUserClient::free();
-}
-
-
-/**
- * Start the client service.
- */
-bool
-org_virtualbox_VBoxUSBClient::start(IOService *pProvider)
-{
- Log(("VBoxUSBClient::start([%p], %p)\n", this, pProvider));
- if (IOUserClient::start(pProvider))
- {
- m_pProvider = OSDynamicCast(org_virtualbox_VBoxUSB, pProvider);
- if (m_pProvider)
- {
- /*
- * Add ourselves to the list of user clients.
- */
- VBOXUSB_LOCK();
-
- m_pNext = s_pHead;
- s_pHead = this;
-
- VBOXUSB_UNLOCK();
-
- return true;
- }
- Log(("VBoxUSBClient::start: %p isn't org_virtualbox_VBoxUSB\n", pProvider));
- }
- return false;
-}
-
-
-/**
- * Client exits normally.
- */
-IOReturn
-org_virtualbox_VBoxUSBClient::clientClose(void)
-{
- Log(("VBoxUSBClient::clientClose([%p:{.m_Process=%d}])\n", this, (int)m_Process));
-
- /*
- * Remove this process from the client list.
- */
- VBOXUSB_LOCK();
-
- org_virtualbox_VBoxUSBClient *pPrev = NULL;
- for (org_virtualbox_VBoxUSBClient *pCur = s_pHead; pCur; pCur = pCur->m_pNext)
- {
- if (pCur == this)
- {
- if (pPrev)
- pPrev->m_pNext = m_pNext;
- else
- s_pHead = m_pNext;
- m_pNext = NULL;
- break;
- }
- pPrev = pCur;
- }
-
- VBOXUSB_UNLOCK();
-
- /*
- * Drop all filters owned by this client.
- */
- if (m_Process != NIL_RTPROCESS)
- VBoxUSBFilterRemoveOwner(m_Process);
-
- /*
- * Schedule all devices owned (filtered) by this process for
- * immediate release or release upon close.
- */
- if (m_Process != NIL_RTPROCESS)
- org_virtualbox_VBoxUSBDevice::scheduleReleaseByOwner(m_Process);
-
- /*
- * Initiate termination.
- */
- m_pProvider = NULL;
- terminate();
-
- return kIOReturnSuccess;
-}
-
-
-/**
- * The client exits abnormally / forgets to do cleanups.
- * @remark Only for logging.
- */
-IOReturn
-org_virtualbox_VBoxUSBClient::clientDied(void)
-{
- Log(("VBoxUSBClient::clientDied([%p]) m_Task=%p R0Process=%p Process=%d\n",
- this, m_Task, RTR0ProcHandleSelf(), RTProcSelf()));
-
- /* IOUserClient::clientDied() calls clientClose... */
- return IOUserClient::clientDied();
-}
-
-
-/**
- * Terminate the service (initiate the destruction).
- * @remark Only for logging.
- */
-bool
-org_virtualbox_VBoxUSBClient::terminate(IOOptionBits fOptions)
-{
- /* kIOServiceRecursing, kIOServiceRequired, kIOServiceTerminate, kIOServiceSynchronous - interesting option bits */
- Log(("VBoxUSBClient::terminate([%p], %#x)\n", this, fOptions));
- return IOUserClient::terminate(fOptions);
-}
-
-
-/**
- * The final stage of the client service destruction.
- * @remark Only for logging.
- */
-bool
-org_virtualbox_VBoxUSBClient::finalize(IOOptionBits fOptions)
-{
- Log(("VBoxUSBClient::finalize([%p], %#x)\n", this, fOptions));
- return IOUserClient::finalize(fOptions);
-}
-
-
-/**
- * Stop the client service.
- */
-void
-org_virtualbox_VBoxUSBClient::stop(IOService *pProvider)
-{
- Log(("VBoxUSBClient::stop([%p])\n", this));
- IOUserClient::stop(pProvider);
-
- /*
- * Paranoia.
- */
- VBOXUSB_LOCK();
-
- org_virtualbox_VBoxUSBClient *pPrev = NULL;
- for (org_virtualbox_VBoxUSBClient *pCur = s_pHead; pCur; pCur = pCur->m_pNext)
- {
- if (pCur == this)
- {
- if (pPrev)
- pPrev->m_pNext = m_pNext;
- else
- s_pHead = m_pNext;
- m_pNext = NULL;
- break;
- }
- pPrev = pCur;
- }
-
- VBOXUSB_UNLOCK();
-}
-
-
-/**
- * Translate a user method index into a service object and an external method structure.
- *
- * @returns Pointer to external method structure descripting the method.
- * NULL if the index isn't valid.
- * @param ppService Where to store the service object on success.
- * @param iMethod The method index.
- */
-IOExternalMethod *
-org_virtualbox_VBoxUSBClient::getTargetAndMethodForIndex(IOService **ppService, UInt32 iMethod)
-{
- static IOExternalMethod s_aMethods[VBOXUSBMETHOD_END] =
- {
- /*[VBOXUSBMETHOD_ADD_FILTER] = */
- {
- (IOService *)0, /* object */
- (IOMethod)&org_virtualbox_VBoxUSBClient::addFilter, /* func */
- kIOUCStructIStructO, /* flags - struct input (count0) and struct output (count1) */
- sizeof(USBFILTER), /* count0 - size of the input struct. */
- sizeof(VBOXUSBADDFILTEROUT) /* count1 - size of the return struct. */
- },
- /* [VBOXUSBMETHOD_FILTER_REMOVE] = */
- {
- (IOService *)0, /* object */
- (IOMethod)&org_virtualbox_VBoxUSBClient::removeFilter, /* func */
- kIOUCStructIStructO, /* flags - struct input (count0) and struct output (count1) */
- sizeof(uintptr_t), /* count0 - size of the input (id) */
- sizeof(int) /* count1 - size of the output (rc) */
- },
- };
-
- if (RT_UNLIKELY(iMethod >= RT_ELEMENTS(s_aMethods)))
- return NULL;
-
- *ppService = this;
- return &s_aMethods[iMethod];
-}
-
-
-/**
- * Add filter user request.
- *
- * @returns IOKit status code.
- * @param pFilter The filter to add.
- * @param pOut Pointer to the output structure.
- * @param cbFilter Size of the filter structure.
- * @param pcbOut In/Out - sizeof(*pOut).
- */
-IOReturn
-org_virtualbox_VBoxUSBClient::addFilter(PUSBFILTER pFilter, PVBOXUSBADDFILTEROUT pOut, IOByteCount cbFilter, IOByteCount *pcbOut)
-{
- Log(("VBoxUSBClient::addFilter: [%p:{.m_Process=%d}] pFilter=%p pOut=%p\n", this, (int)m_Process, pFilter, pOut));
-
- /*
- * Validate input.
- */
- if (RT_UNLIKELY( cbFilter != sizeof(*pFilter)
- || *pcbOut != sizeof(*pOut)))
- {
- printf("VBoxUSBClient::addFilter: cbFilter=%#x expected %#x; *pcbOut=%#x expected %#x\n",
- (int)cbFilter, (int)sizeof(*pFilter), (int)*pcbOut, (int)sizeof(*pOut));
- return kIOReturnBadArgument;
- }
-
- /*
- * Log the filter details.
- */
-#ifdef DEBUG
- Log2(("VBoxUSBClient::addFilter: idVendor=%#x idProduct=%#x bcdDevice=%#x bDeviceClass=%#x bDeviceSubClass=%#x bDeviceProtocol=%#x bBus=%#x bPort=%#x\n",
- USBFilterGetNum(pFilter, USBFILTERIDX_VENDOR_ID),
- USBFilterGetNum(pFilter, USBFILTERIDX_PRODUCT_ID),
- USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_REV),
- USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_CLASS),
- USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_SUB_CLASS),
- USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_PROTOCOL),
- USBFilterGetNum(pFilter, USBFILTERIDX_BUS),
- USBFilterGetNum(pFilter, USBFILTERIDX_PORT)));
- Log2(("VBoxUSBClient::addFilter: Manufacturer=%s Product=%s Serial=%s\n",
- USBFilterGetString(pFilter, USBFILTERIDX_MANUFACTURER_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_MANUFACTURER_STR) : "<null>",
- USBFilterGetString(pFilter, USBFILTERIDX_PRODUCT_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_PRODUCT_STR) : "<null>",
- USBFilterGetString(pFilter, USBFILTERIDX_SERIAL_NUMBER_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_SERIAL_NUMBER_STR) : "<null>"));
-#endif
-
- /*
- * Since we cannot query the bus number, make sure the filter
- * isn't requiring that field to be present.
- */
- int rc = USBFilterSetMustBePresent(pFilter, USBFILTERIDX_BUS, false /* fMustBePresent */); AssertRC(rc);
-
- /*
- * Add the filter.
- */
- pOut->uId = 0;
- pOut->rc = VBoxUSBFilterAdd(pFilter, m_Process, &pOut->uId);
-
- Log(("VBoxUSBClient::addFilter: returns *pOut={.rc=%d, .uId=%p}\n", pOut->rc, (void *)pOut->uId));
- return kIOReturnSuccess;
-}
-
-
-/**
- * Removes filter user request.
- *
- * @returns IOKit status code.
- * @param puId Where to get the filter ID.
- * @param prc Where to store the return code.
- * @param cbIn sizeof(*puId).
- * @param pcbOut In/Out - sizeof(*prc).
- */
-IOReturn
-org_virtualbox_VBoxUSBClient::removeFilter(uintptr_t *puId, int *prc, IOByteCount cbIn, IOByteCount *pcbOut)
-{
- Log(("VBoxUSBClient::removeFilter: [%p:{.m_Process=%d}] *puId=%p m_Proc\n", this, (int)m_Process, *puId));
-
- /*
- * Validate input.
- */
- if (RT_UNLIKELY( cbIn != sizeof(*puId)
- || *pcbOut != sizeof(*prc)))
- {
- printf("VBoxUSBClient::removeFilter: cbIn=%#x expected %#x; *pcbOut=%#x expected %#x\n",
- (int)cbIn, (int)sizeof(*puId), (int)*pcbOut, (int)sizeof(*prc));
- return kIOReturnBadArgument;
- }
-
- /*
- * Remove the filter.
- */
- *prc = VBoxUSBFilterRemove(m_Process, *puId);
-
- Log(("VBoxUSBClient::removeFilter: returns *prc=%d\n", *prc));
- return kIOReturnSuccess;
-}
-
-
-/**
- * Checks whether the specified task is a VBoxUSB client task or not.
- *
- * This is used to validate clients trying to open any of the device
- * or interfaces that we've hijacked.
- *
- * @returns true / false.
- * @param ClientTask The task.
- *
- * @remark This protecting against other user clients is not currently implemented
- * as it turned out to be more bothersome than first imagined.
- */
-/* static*/ bool
-org_virtualbox_VBoxUSBClient::isClientTask(task_t ClientTask)
-{
- VBOXUSB_LOCK();
-
- for (org_virtualbox_VBoxUSBClient *pCur = s_pHead; pCur; pCur = pCur->m_pNext)
- if (pCur->m_Task == ClientTask)
- {
- VBOXUSB_UNLOCK();
- return true;
- }
-
- VBOXUSB_UNLOCK();
- return false;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/*
- *
- * org_virtualbox_VBoxUSBDevice
- *
- */
-
-/**
- * Initialize instance data.
- *
- * @returns Success indicator.
- * @param pDictionary The dictionary that will become the registry entry's
- * property table, or NULL. Hand it up to our parents.
- */
-bool
-org_virtualbox_VBoxUSBDevice::init(OSDictionary *pDictionary)
-{
- uint32_t cInstances = ASMAtomicIncU32(&g_cInstances);
- Log(("VBoxUSBDevice::init([%p], %p) new g_cInstances=%d\n", this, pDictionary, cInstances));
- RT_NOREF_PV(cInstances);
-
- m_pDevice = NULL;
- m_Owner = NIL_RTPROCESS;
- m_Client = NIL_RTPROCESS;
- m_uId = ~(uintptr_t)0;
- m_fOpen = false;
- m_fOpenOnWasClosed = false;
- m_fReleaseOnClose = false;
- m_fBeingUnloaded = false;
- m_pNext = NULL;
-#ifdef DEBUG
- m_pNotifier = NULL;
-#endif
-
- return IOUSBUserClientInit::init(pDictionary);
-}
-
-/**
- * Free the object.
- * @remark Only for logging.
- */
-void
-org_virtualbox_VBoxUSBDevice::free()
-{
- uint32_t cInstances = ASMAtomicDecU32(&g_cInstances); NOREF(cInstances);
- Log(("VBoxUSBDevice::free([%p]) new g_cInstances=%d\n", this, cInstances));
- IOUSBUserClientInit::free();
-}
-
-
-/**
- * The device/driver probing.
- *
- * I/O Kit will iterate all device drivers suitable for this kind of device
- * (this is something it figures out from the property file) and call their
- * probe() method in order to try determine which is the best match for the
- * device. We will match the device against the registered filters and set
- * a ridiculously high score if we find it, thus making it extremely likely
- * that we'll be the first driver to be started. We'll also set a couple of
- * attributes so that it's not necessary to do a rematch in init to find
- * the appropriate filter (might not be necessary..., see todo).
- *
- * @returns Service instance to be started and *pi32Score if matching.
- * NULL if not a device suitable for this driver.
- *
- * @param pProvider The provider instance.
- * @param pi32Score Where to store the probe score.
- */
-IOService *
-org_virtualbox_VBoxUSBDevice::probe(IOService *pProvider, SInt32 *pi32Score)
-{
- Log(("VBoxUSBDevice::probe([%p], %p {%s}, %p={%d})\n", this,
- pProvider, pProvider->getName(), pi32Score, pi32Score ? *pi32Score : 0));
-
- /*
- * Check against filters.
- */
- USBFILTER Device;
- USBFilterInit(&Device, USBFILTERTYPE_CAPTURE);
-
- static const struct
- {
- const char *pszName;
- USBFILTERIDX enmIdx;
- bool fNumeric;
- } s_aProps[] =
- {
- { kUSBVendorID, USBFILTERIDX_VENDOR_ID, true },
- { kUSBProductID, USBFILTERIDX_PRODUCT_ID, true },
- { kUSBDeviceReleaseNumber, USBFILTERIDX_DEVICE_REV, true },
- { kUSBDeviceClass, USBFILTERIDX_DEVICE_CLASS, true },
- { kUSBDeviceSubClass, USBFILTERIDX_DEVICE_SUB_CLASS, true },
- { kUSBDeviceProtocol, USBFILTERIDX_DEVICE_PROTOCOL, true },
- { "PortNum", USBFILTERIDX_PORT, true },
- /// @todo { , USBFILTERIDX_BUS, true }, - must be derived :-/
- /// Seems to be the upper byte of locationID and our "grand parent" has a USBBusNumber prop.
- { "USB Vendor Name", USBFILTERIDX_MANUFACTURER_STR, false },
- { "USB Product Name", USBFILTERIDX_PRODUCT_STR, false },
- { "USB Serial Number", USBFILTERIDX_SERIAL_NUMBER_STR, false },
- };
- for (unsigned i = 0; i < RT_ELEMENTS(s_aProps); i++)
- {
- OSObject *pObj = pProvider->getProperty(s_aProps[i].pszName);
- if (!pObj)
- continue;
- if (s_aProps[i].fNumeric)
- {
- OSNumber *pNum = OSDynamicCast(OSNumber, pObj);
- if (pNum)
- {
- uint16_t u16 = pNum->unsigned16BitValue();
- Log2(("VBoxUSBDevice::probe: %d/%s - %#x (32bit=%#x)\n", i, s_aProps[i].pszName, u16, pNum->unsigned32BitValue()));
- int vrc = USBFilterSetNumExact(&Device, s_aProps[i].enmIdx, u16, true);
- if (RT_FAILURE(vrc))
- Log(("VBoxUSBDevice::probe: pObj=%p pNum=%p - %d/%s - rc=%d!\n", pObj, pNum, i, s_aProps[i].pszName, vrc));
- }
- else
- Log(("VBoxUSBDevice::probe: pObj=%p pNum=%p - %d/%s!\n", pObj, pNum, i, s_aProps[i].pszName));
- }
- else
- {
- OSString *pStr = OSDynamicCast(OSString, pObj);
- if (pStr)
- {
- Log2(("VBoxUSBDevice::probe: %d/%s - %s\n", i, s_aProps[i].pszName, pStr->getCStringNoCopy()));
- int vrc = USBFilterSetStringExact(&Device, s_aProps[i].enmIdx, pStr->getCStringNoCopy(),
- true /*fMustBePresent*/, true /*fPurge*/);
- if (RT_FAILURE(vrc))
- Log(("VBoxUSBDevice::probe: pObj=%p pStr=%p - %d/%s - rc=%d!\n", pObj, pStr, i, s_aProps[i].pszName, vrc));
- }
- else
- Log(("VBoxUSBDevice::probe: pObj=%p pStr=%p - %d/%s\n", pObj, pStr, i, s_aProps[i].pszName));
- }
- }
- /** @todo try figure the blasted bus number */
-
- /*
- * Run filters on it.
- */
- uintptr_t uId = 0;
- RTPROCESS Owner = VBoxUSBFilterMatch(&Device, &uId);
- USBFilterDelete(&Device);
- if (Owner == NIL_RTPROCESS)
- {
- Log(("VBoxUSBDevice::probe: returns NULL uId=%d\n", uId));
- return NULL;
- }
-
- /*
- * It matched. Save the owner in the provider registry (hope that works).
- */
- /*IOService *pRet = IOUSBUserClientInit::probe(pProvider, pi32Score); - call always returns NULL on 10.11+ */
- /*AssertMsg(pRet == this, ("pRet=%p this=%p *pi32Score=%d \n", pRet, this, pi32Score ? *pi32Score : 0)); - call always returns NULL on 10.11+ */
- IOService *pRet = this;
- m_Owner = Owner;
- m_uId = uId;
- Log(("%p: m_Owner=%d m_uId=%d\n", this, (int)m_Owner, (int)m_uId));
- *pi32Score = _1G;
- Log(("VBoxUSBDevice::probe: returns %p and *pi32Score=%d\n", pRet, *pi32Score));
- return pRet;
-}
-
-
-/**
- * Try start the device driver.
- *
- * We will do device linking, copy the filter and owner properties from the provider,
- * set the client property, retain the device, and try open (seize) the device.
- *
- * @returns Success indicator.
- * @param pProvider The provider instance.
- */
-bool
-org_virtualbox_VBoxUSBDevice::start(IOService *pProvider)
-{
- Log(("VBoxUSBDevice::start([%p:{.m_Owner=%d, .m_uId=%p}], %p {%s})\n",
- this, m_Owner, m_uId, pProvider, pProvider->getName()));
-
- m_pDevice = OSDynamicCast(IOUSBDevice, pProvider);
- if (!m_pDevice)
- {
- printf("VBoxUSBDevice::start([%p], %p {%s}): failed!\n", (void *)this, (void *)pProvider, pProvider->getName());
- return false;
- }
-
-#ifdef DEBUG
- /* for some extra log messages */
- m_pNotifier = pProvider->registerInterest(gIOGeneralInterest,
- &org_virtualbox_VBoxUSBDevice::MyInterestHandler,
- this, /* pvTarget */
- NULL); /* pvRefCon */
-#endif
-
- /*
- * Exploit IOUSBUserClientInit to process IOProviderMergeProperties.
- */
- IOUSBUserClientInit::start(pProvider); /* returns false */
-
- /*
- * Link ourselves into the list of hijacked device.
- */
- VBOXUSB_LOCK();
-
- m_pNext = s_pHead;
- s_pHead = this;
-
- VBOXUSB_UNLOCK();
-
- /*
- * Set the VBoxUSB properties.
- */
- if (!setProperty(VBOXUSB_OWNER_KEY, (unsigned long long)m_Owner, sizeof(m_Owner) * 8 /* bits */))
- Log(("VBoxUSBDevice::start: failed to set the '" VBOXUSB_OWNER_KEY "' property!\n"));
- if (!setProperty(VBOXUSB_CLIENT_KEY, (unsigned long long)m_Client, sizeof(m_Client) * 8 /* bits */))
- Log(("VBoxUSBDevice::start: failed to set the '" VBOXUSB_CLIENT_KEY "' property!\n"));
- if (!setProperty(VBOXUSB_FILTER_KEY, (unsigned long long)m_uId, sizeof(m_uId) * 8 /* bits */))
- Log(("VBoxUSBDevice::start: failed to set the '" VBOXUSB_FILTER_KEY "' property!\n"));
-
- /*
- * Retain and open the device.
- */
- m_pDevice->retain();
- m_fOpen = m_pDevice->open(this, kIOServiceSeize, 0);
- if (!m_fOpen)
- Log(("VBoxUSBDevice::start: failed to open the device!\n"));
- m_fOpenOnWasClosed = !m_fOpen;
-
- Log(("VBoxUSBDevice::start: returns %d\n", true));
- return true;
-}
-
-
-/**
- * Stop the device driver.
- *
- * We'll unlink the device, start device re-enumeration and close it. And call
- * the parent stop method of course.
- *
- * @param pProvider The provider instance.
- */
-void
-org_virtualbox_VBoxUSBDevice::stop(IOService *pProvider)
-{
- Log(("VBoxUSBDevice::stop([%p], %p {%s})\n", this, pProvider, pProvider->getName()));
-
- /*
- * Remove ourselves from the list of device.
- */
- VBOXUSB_LOCK();
-
- org_virtualbox_VBoxUSBDevice *pPrev = NULL;
- for (org_virtualbox_VBoxUSBDevice *pCur = s_pHead; pCur; pCur = pCur->m_pNext)
- {
- if (pCur == this)
- {
- if (pPrev)
- pPrev->m_pNext = m_pNext;
- else
- s_pHead = m_pNext;
- m_pNext = NULL;
- break;
- }
- pPrev = pCur;
- }
-
- VBOXUSB_UNLOCK();
-
- /*
- * Should we release the device?
- */
- if (m_fBeingUnloaded)
- {
- if (m_pDevice)
- {
- IOReturn irc = m_pDevice->ReEnumerateDevice(0); NOREF(irc);
- Log(("VBoxUSBDevice::stop([%p], %p {%s}): m_pDevice=%p unload & ReEnumerateDevice -> %#x\n",
- this, pProvider, pProvider->getName(), m_pDevice, irc));
- }
- else
- {
- IOUSBDevice *pDevice = OSDynamicCast(IOUSBDevice, pProvider);
- if (pDevice)
- {
- IOReturn irc = pDevice->ReEnumerateDevice(0); NOREF(irc);
- Log(("VBoxUSBDevice::stop([%p], %p {%s}): pDevice=%p unload & ReEnumerateDevice -> %#x\n",
- this, pProvider, pProvider->getName(), pDevice, irc));
- }
- else
- Log(("VBoxUSBDevice::stop([%p], %p {%s}): failed to cast provider to IOUSBDevice\n",
- this, pProvider, pProvider->getName()));
- }
- }
- else if (m_fReleaseOnClose)
- {
- ASMAtomicWriteBool(&m_fReleaseOnClose, false);
- if (m_pDevice)
- {
- IOReturn irc = m_pDevice->ReEnumerateDevice(0); NOREF(irc);
- Log(("VBoxUSBDevice::stop([%p], %p {%s}): m_pDevice=%p close & ReEnumerateDevice -> %#x\n",
- this, pProvider, pProvider->getName(), m_pDevice, irc));
- }
- }
-
- /*
- * Close and release the IOUSBDevice if didn't do that already in message().
- */
- if (m_pDevice)
- {
- /* close it */
- if (m_fOpen)
- {
- m_fOpenOnWasClosed = false;
- m_fOpen = false;
- m_pDevice->close(this, 0);
- }
-
- /* release it (see start()) */
- m_pDevice->release();
- m_pDevice = NULL;
- }
-
-#ifdef DEBUG
- /* avoid crashing on unload. */
- if (m_pNotifier)
- {
- m_pNotifier->release();
- m_pNotifier = NULL;
- }
-#endif
-
- IOUSBUserClientInit::stop(pProvider);
- Log(("VBoxUSBDevice::stop: returns void\n"));
-}
-
-
-/**
- * Terminate the service (initiate the destruction).
- * @remark Only for logging.
- */
-bool
-org_virtualbox_VBoxUSBDevice::terminate(IOOptionBits fOptions)
-{
- /* kIOServiceRecursing, kIOServiceRequired, kIOServiceTerminate, kIOServiceSynchronous - interesting option bits */
- Log(("VBoxUSBDevice::terminate([%p], %#x)\n", this, fOptions));
-
- /*
- * There aren't too many reasons why we gets terminated.
- * The most common one is that the device is being unplugged. Another is
- * that we've triggered reenumeration. In both cases we'll get a
- * kIOMessageServiceIsTerminated message before we're stopped.
- *
- * But, when we're unloaded the provider service isn't terminated, and
- * for some funny reason we're frequently causing kernel panics when the
- * device is detached (after we're unloaded). So, for now, let's try
- * re-enumerate it in stop.
- *
- * To avoid creating unnecessary trouble we'll try guess if we're being
- * unloaded from the option bit mask. (kIOServiceRecursing is private btw.)
- */
- /** @todo would be nice if there was a documented way of doing the unload detection this, or
- * figure out what exactly we're doing wrong in the unload scenario. */
- if ((fOptions & 0xffff) == (kIOServiceRequired | kIOServiceSynchronous))
- m_fBeingUnloaded = true;
-
- return IOUSBUserClientInit::terminate(fOptions);
-}
-
-
-/**
- * Intercept open requests and only let Mr. Right (the VM process) open the device.
- * This is where it all gets a bit complicated...
- *
- * @return Status code.
- *
- * @param enmMsg The message number.
- * @param pProvider Pointer to the provider instance.
- * @param pvArg Message argument.
- */
-IOReturn
-org_virtualbox_VBoxUSBDevice::message(UInt32 enmMsg, IOService *pProvider, void *pvArg)
-{
- Log(("VBoxUSBDevice::message([%p], %#x {%s}, %p {%s}, %p) - pid=%d\n",
- this, enmMsg, DbgGetIOKitMessageName(enmMsg), pProvider, pProvider->getName(), pvArg, RTProcSelf()));
-
- IOReturn irc;
- switch (enmMsg)
- {
- /*
- * This message is send to the current IOService client from IOService::handleOpen(),
- * expecting it to call pProvider->close() if it agrees to the other party seizing
- * the service. It is also called in IOService::didTerminate() and perhaps some other
- * odd places. The way to find out is to examin the pvArg, which would be including
- * kIOServiceSeize if it's the handleOpen case.
- *
- * How to validate that the other end is actually our VM process? Well, IOKit doesn't
- * provide any clue about the new client really. But fortunately, it seems like the
- * calling task/process context when the VM tries to open the device is the VM process.
- * We'll ASSUME this'll remain like this for now...
- */
- case kIOMessageServiceIsRequestingClose:
- irc = kIOReturnExclusiveAccess;
- /* If it's not a seize request, assume it's didTerminate and pray that it isn't a rouge driver.
- ... weird, doesn't seem to match for the post has-terminated messages. */
- if (!((uintptr_t)pvArg & kIOServiceSeize))
- {
- Log(("VBoxUSBDevice::message([%p],%p {%s}, %p) - pid=%d: not seize - closing...\n",
- this, pProvider, pProvider->getName(), pvArg, RTProcSelf()));
- m_fOpen = false;
- m_fOpenOnWasClosed = false;
- if (m_pDevice)
- m_pDevice->close(this, 0);
- m_Client = NIL_RTPROCESS;
- irc = kIOReturnSuccess;
- }
- else
- {
- if (org_virtualbox_VBoxUSBClient::isClientTask(current_task()))
- {
- Log(("VBoxUSBDevice::message([%p],%p {%s}, %p) - pid=%d task=%p: client process, closing.\n",
- this, pProvider, pProvider->getName(), pvArg, RTProcSelf(), current_task()));
- m_fOpen = false;
- m_fOpenOnWasClosed = false;
- if (m_pDevice)
- m_pDevice->close(this, 0);
- m_fOpenOnWasClosed = true;
- m_Client = RTProcSelf();
- irc = kIOReturnSuccess;
- }
- else
- Log(("VBoxUSBDevice::message([%p],%p {%s}, %p) - pid=%d task=%p: not client process!\n",
- this, pProvider, pProvider->getName(), pvArg, RTProcSelf(), current_task()));
- }
- if (!setProperty(VBOXUSB_CLIENT_KEY, (unsigned long long)m_Client, sizeof(m_Client) * 8 /* bits */))
- Log(("VBoxUSBDevice::message: failed to set the '" VBOXUSB_CLIENT_KEY "' property!\n"));
- break;
-
- /*
- * The service was closed by the current client.
- * Update the client property, check for scheduled re-enumeration and re-open.
- *
- * Note that we will not be called if we're doing the closing. (Even if we was
- * called in that case, the code should be able to handle it.)
- */
- case kIOMessageServiceWasClosed:
- /*
- * Update the client property value.
- */
- if (m_Client != NIL_RTPROCESS)
- {
- m_Client = NIL_RTPROCESS;
- if (!setProperty(VBOXUSB_CLIENT_KEY, (unsigned long long)m_Client, sizeof(m_Client) * 8 /* bits */))
- Log(("VBoxUSBDevice::message: failed to set the '" VBOXUSB_CLIENT_KEY "' property!\n"));
- }
-
- if (m_pDevice)
- {
- /*
- * Should we release the device?
- */
- if (ASMAtomicXchgBool(&m_fReleaseOnClose, false))
- {
- m_fOpenOnWasClosed = false;
- irc = m_pDevice->ReEnumerateDevice(0);
- Log(("VBoxUSBDevice::message([%p], %p {%s}) - ReEnumerateDevice() -> %#x\n",
- this, pProvider, pProvider->getName(), irc));
- }
- /*
- * Should we attempt to re-open the device?
- */
- else if (m_fOpenOnWasClosed)
- {
- Log(("VBoxUSBDevice::message: attempting to re-open the device...\n"));
- m_fOpenOnWasClosed = false;
- m_fOpen = m_pDevice->open(this, kIOServiceSeize, 0);
- if (!m_fOpen)
- Log(("VBoxUSBDevice::message: failed to open the device!\n"));
- m_fOpenOnWasClosed = !m_fOpen;
- }
- }
-
- irc = IOUSBUserClientInit::message(enmMsg, pProvider, pvArg);
- break;
-
- /*
- * The IOUSBDevice is shutting down, so close it if we've opened it.
- */
- case kIOMessageServiceIsTerminated:
- m_fBeingUnloaded = false;
- ASMAtomicWriteBool(&m_fReleaseOnClose, false);
- if (m_pDevice)
- {
- /* close it */
- if (m_fOpen)
- {
- m_fOpen = false;
- m_fOpenOnWasClosed = false;
- Log(("VBoxUSBDevice::message: closing the device (%p)...\n", m_pDevice));
- m_pDevice->close(this, 0);
- }
-
- /* release it (see start()) */
- Log(("VBoxUSBDevice::message: releasing the device (%p)...\n", m_pDevice));
- m_pDevice->release();
- m_pDevice = NULL;
- }
-
- irc = IOUSBUserClientInit::message(enmMsg, pProvider, pvArg);
- break;
-
- default:
- irc = IOUSBUserClientInit::message(enmMsg, pProvider, pvArg);
- break;
- }
-
- Log(("VBoxUSBDevice::message([%p], %#x {%s}, %p {%s}, %p) -> %#x\n",
- this, enmMsg, DbgGetIOKitMessageName(enmMsg), pProvider, pProvider->getName(), pvArg, irc));
- return irc;
-}
-
-
-/**
- * Schedule all devices belonging to the specified process for release.
- *
- * Devices that aren't currently in use will be released immediately.
- *
- * @param Owner The owner process.
- */
-/* static */ void
-org_virtualbox_VBoxUSBDevice::scheduleReleaseByOwner(RTPROCESS Owner)
-{
- Log2(("VBoxUSBDevice::scheduleReleaseByOwner: Owner=%d\n", Owner));
- AssertReturnVoid(Owner && Owner != NIL_RTPROCESS);
-
- /*
- * Walk the list of devices looking for device belonging to this process.
- *
- * If we release a device, we have to lave the spinlock and will therefore
- * have to restart the search.
- */
- VBOXUSB_LOCK();
-
- org_virtualbox_VBoxUSBDevice *pCur;
- do
- {
- for (pCur = s_pHead; pCur; pCur = pCur->m_pNext)
- {
- Log2(("VBoxUSBDevice::scheduleReleaseByOwner: pCur=%p m_Owner=%d (%s) m_fReleaseOnClose=%d\n",
- pCur, pCur->m_Owner, pCur->m_Owner == Owner ? "match" : "mismatch", pCur->m_fReleaseOnClose));
- if (pCur->m_Owner == Owner)
- {
- /* make sure we won't hit it again. */
- pCur->m_Owner = NIL_RTPROCESS;
- IOUSBDevice *pDevice = pCur->m_pDevice;
- if ( pDevice
- && !pCur->m_fReleaseOnClose)
- {
- pCur->m_fOpenOnWasClosed = false;
- if (pCur->m_Client != NIL_RTPROCESS)
- {
- /* It's currently open, so just schedule it for re-enumeration on close. */
- ASMAtomicWriteBool(&pCur->m_fReleaseOnClose, true);
- Log(("VBoxUSBDevice::scheduleReleaseByOwner: %p {%s} - used by %d\n",
- pDevice, pDevice->getName(), pCur->m_Client));
- }
- else
- {
- /*
- * Get the USBDevice object and do the re-enumeration now.
- * Retain the device so we don't run into any trouble.
- */
- pDevice->retain();
- VBOXUSB_UNLOCK();
-
- IOReturn irc = pDevice->ReEnumerateDevice(0); NOREF(irc);
- Log(("VBoxUSBDevice::scheduleReleaseByOwner: %p {%s} - ReEnumerateDevice -> %#x\n",
- pDevice, pDevice->getName(), irc));
-
- pDevice->release();
- VBOXUSB_LOCK();
- break;
- }
- }
- }
- }
- } while (pCur);
-
- VBOXUSB_UNLOCK();
-}
-
-
-#ifdef DEBUG
-/*static*/ IOReturn
-org_virtualbox_VBoxUSBDevice::MyInterestHandler(void *pvTarget, void *pvRefCon, UInt32 enmMsgType,
- IOService *pProvider, void * pvMsgArg, vm_size_t cbMsgArg)
-{
- org_virtualbox_VBoxUSBDevice *pThis = (org_virtualbox_VBoxUSBDevice *)pvTarget;
- if (!pThis)
- return kIOReturnError;
-
- switch (enmMsgType)
- {
- case kIOMessageServiceIsAttemptingOpen:
- /* pvMsgArg == the open() fOptions, so we could check for kIOServiceSeize if we care.
- We'll also get a kIIOServiceRequestingClose message() for that... */
- Log(("VBoxUSBDevice::MyInterestHandler: kIOMessageServiceIsAttemptingOpen - pvRefCon=%p pProvider=%p pvMsgArg=%p cbMsgArg=%d\n",
- pvRefCon, pProvider, pvMsgArg, cbMsgArg));
- break;
-
- case kIOMessageServiceWasClosed:
- Log(("VBoxUSBDevice::MyInterestHandler: kIOMessageServiceWasClosed - pvRefCon=%p pProvider=%p pvMsgArg=%p cbMsgArg=%d\n",
- pvRefCon, pProvider, pvMsgArg, cbMsgArg));
- break;
-
- case kIOMessageServiceIsTerminated:
- Log(("VBoxUSBDevice::MyInterestHandler: kIOMessageServiceIsTerminated - pvRefCon=%p pProvider=%p pvMsgArg=%p cbMsgArg=%d\n",
- pvRefCon, pProvider, pvMsgArg, cbMsgArg));
- break;
-
- case kIOUSBMessagePortHasBeenReset:
- Log(("VBoxUSBDevice::MyInterestHandler: kIOUSBMessagePortHasBeenReset - pvRefCon=%p pProvider=%p pvMsgArg=%p cbMsgArg=%d\n",
- pvRefCon, pProvider, pvMsgArg, cbMsgArg));
- break;
-
- default:
- Log(("VBoxUSBDevice::MyInterestHandler: %#x (%s) - pvRefCon=%p pProvider=%p pvMsgArg=%p cbMsgArg=%d\n",
- enmMsgType, DbgGetIOKitMessageName(enmMsgType), pvRefCon, pProvider, pvMsgArg, cbMsgArg));
- break;
- }
-
- return kIOReturnSuccess;
-}
-#endif /* DEBUG */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/*
- *
- * org_virtualbox_VBoxUSBInterface
- *
- */
-
-/**
- * Initialize our data members.
- */
-bool
-org_virtualbox_VBoxUSBInterface::init(OSDictionary *pDictionary)
-{
- uint32_t cInstances = ASMAtomicIncU32(&g_cInstances);
- Log(("VBoxUSBInterface::init([%p], %p) new g_cInstances=%d\n", this, pDictionary, cInstances));
- RT_NOREF_PV(cInstances);
-
- m_pInterface = NULL;
- m_fOpen = false;
- m_fOpenOnWasClosed = false;
-
- return IOUSBUserClientInit::init(pDictionary);
-}
-
-
-/**
- * Free the object.
- * @remark Only for logging.
- */
-void
-org_virtualbox_VBoxUSBInterface::free()
-{
- uint32_t cInstances = ASMAtomicDecU32(&g_cInstances); NOREF(cInstances);
- Log(("VBoxUSBInterfaces::free([%p]) new g_cInstances=%d\n", this, cInstances));
- IOUSBUserClientInit::free();
-}
-
-
-/**
- * Probe the interface to see if we're the right driver for it.
- *
- * We implement this similarly to org_virtualbox_VBoxUSBDevice, except that
- * we don't bother matching filters but instead just check if the parent is
- * handled by org_virtualbox_VBoxUSBDevice or not.
- */
-IOService *
-org_virtualbox_VBoxUSBInterface::probe(IOService *pProvider, SInt32 *pi32Score)
-{
- Log(("VBoxUSBInterface::probe([%p], %p {%s}, %p={%d})\n", this,
- pProvider, pProvider->getName(), pi32Score, pi32Score ? *pi32Score : 0));
-
- /*
- * Check if VBoxUSBDevice is the parent's driver.
- */
- bool fHijackIt = false;
- const IORegistryPlane *pServicePlane = getPlane(kIOServicePlane);
- IORegistryEntry *pParent = pProvider->getParentEntry(pServicePlane);
- if (pParent)
- {
- Log(("VBoxUSBInterface::probe: pParent=%p {%s}\n", pParent, pParent->getName()));
-
- OSIterator *pSiblings = pParent->getChildIterator(pServicePlane);
- if (pSiblings)
- {
- IORegistryEntry *pSibling;
- while ( (pSibling = OSDynamicCast(IORegistryEntry, pSiblings->getNextObject())) )
- {
- const OSMetaClass *pMetaClass = pSibling->getMetaClass();
- Log2(("sibling: %p - %s - %s\n", pMetaClass, pSibling->getName(), pMetaClass->getClassName()));
- if (pMetaClass == &org_virtualbox_VBoxUSBDevice::gMetaClass)
- {
- fHijackIt = true;
- break;
- }
- }
- pSiblings->release();
- }
- }
- if (!fHijackIt)
- {
- Log(("VBoxUSBInterface::probe: returns NULL\n"));
- return NULL;
- }
-
- /* IOService *pRet = IOUSBUserClientInit::probe(pProvider, pi32Score); - call always returns NULL on 10.11+ */
- IOService *pRet = this;
- *pi32Score = _1G;
- Log(("VBoxUSBInterface::probe: returns %p and *pi32Score=%d - hijack it.\n", pRet, *pi32Score));
- return pRet;
-}
-
-
-/**
- * Start the driver (this), retain and open the USB interface object (pProvider).
- */
-bool
-org_virtualbox_VBoxUSBInterface::start(IOService *pProvider)
-{
- Log(("VBoxUSBInterface::start([%p], %p {%s})\n", this, pProvider, pProvider->getName()));
-
- /*
- * Exploit IOUSBUserClientInit to process IOProviderMergeProperties.
- */
- IOUSBUserClientInit::start(pProvider); /* returns false */
-
- /*
- * Retain the and open the interface (stop() or message() cleans up).
- */
- bool fRc = true;
- m_pInterface = OSDynamicCast(IOUSBInterface, pProvider);
- if (m_pInterface)
- {
- m_pInterface->retain();
- m_fOpen = m_pInterface->open(this, kIOServiceSeize, 0);
- if (!m_fOpen)
- Log(("VBoxUSBInterface::start: failed to open the interface!\n"));
- m_fOpenOnWasClosed = !m_fOpen;
- }
- else
- {
- printf("VBoxUSBInterface::start([%p], %p {%s}): failed!\n", (void *)this, (void *)pProvider, pProvider->getName());
- fRc = false;
- }
-
- Log(("VBoxUSBInterface::start: returns %d\n", fRc));
- return fRc;
-}
-
-
-/**
- * Close and release the USB interface object (pProvider) and stop the driver (this).
- */
-void
-org_virtualbox_VBoxUSBInterface::stop(IOService *pProvider)
-{
- Log(("org_virtualbox_VBoxUSBInterface::stop([%p], %p {%s})\n", this, pProvider, pProvider->getName()));
-
- /*
- * Close and release the IOUSBInterface if didn't do that already in message().
- */
- if (m_pInterface)
- {
- /* close it */
- if (m_fOpen)
- {
- m_fOpenOnWasClosed = false;
- m_fOpen = false;
- m_pInterface->close(this, 0);
- }
-
- /* release it (see start()) */
- m_pInterface->release();
- m_pInterface = NULL;
- }
-
- IOUSBUserClientInit::stop(pProvider);
- Log(("VBoxUSBInterface::stop: returns void\n"));
-}
-
-
-/**
- * Terminate the service (initiate the destruction).
- * @remark Only for logging.
- */
-bool
-org_virtualbox_VBoxUSBInterface::terminate(IOOptionBits fOptions)
-{
- /* kIOServiceRecursing, kIOServiceRequired, kIOServiceTerminate, kIOServiceSynchronous - interesting option bits */
- Log(("VBoxUSBInterface::terminate([%p], %#x)\n", this, fOptions));
- return IOUSBUserClientInit::terminate(fOptions);
-}
-
-
-/**
- * @copydoc org_virtualbox_VBoxUSBDevice::message
- */
-IOReturn
-org_virtualbox_VBoxUSBInterface::message(UInt32 enmMsg, IOService *pProvider, void *pvArg)
-{
- Log(("VBoxUSBInterface::message([%p], %#x {%s}, %p {%s}, %p)\n",
- this, enmMsg, DbgGetIOKitMessageName(enmMsg), pProvider, pProvider->getName(), pvArg));
-
- IOReturn irc;
- switch (enmMsg)
- {
- /*
- * See explanation in org_virtualbox_VBoxUSBDevice::message.
- */
- case kIOMessageServiceIsRequestingClose:
- irc = kIOReturnExclusiveAccess;
- if (!((uintptr_t)pvArg & kIOServiceSeize))
- {
- Log(("VBoxUSBInterface::message([%p],%p {%s}, %p) - pid=%d: not seize - closing...\n",
- this, pProvider, pProvider->getName(), pvArg, RTProcSelf()));
- m_fOpen = false;
- m_fOpenOnWasClosed = false;
- if (m_pInterface)
- m_pInterface->close(this, 0);
- irc = kIOReturnSuccess;
- }
- else
- {
- if (org_virtualbox_VBoxUSBClient::isClientTask(current_task()))
- {
- Log(("VBoxUSBInterface::message([%p],%p {%s}, %p) - pid=%d task=%p: client process, closing.\n",
- this, pProvider, pProvider->getName(), pvArg, RTProcSelf(), current_task()));
- m_fOpen = false;
- m_fOpenOnWasClosed = false;
- if (m_pInterface)
- m_pInterface->close(this, 0);
- m_fOpenOnWasClosed = true;
- irc = kIOReturnSuccess;
- }
- else
- Log(("VBoxUSBInterface::message([%p],%p {%s}, %p) - pid=%d task=%p: not client process!\n",
- this, pProvider, pProvider->getName(), pvArg, RTProcSelf(), current_task()));
- }
- break;
-
- /*
- * The service was closed by the current client, check for re-open.
- */
- case kIOMessageServiceWasClosed:
- if (m_pInterface && m_fOpenOnWasClosed)
- {
- Log(("VBoxUSBInterface::message: attempting to re-open the interface...\n"));
- m_fOpenOnWasClosed = false;
- m_fOpen = m_pInterface->open(this, kIOServiceSeize, 0);
- if (!m_fOpen)
- Log(("VBoxUSBInterface::message: failed to open the interface!\n"));
- m_fOpenOnWasClosed = !m_fOpen;
- }
-
- irc = IOUSBUserClientInit::message(enmMsg, pProvider, pvArg);
- break;
-
- /*
- * The IOUSBInterface/Device is shutting down, so close and release.
- */
- case kIOMessageServiceIsTerminated:
- if (m_pInterface)
- {
- /* close it */
- if (m_fOpen)
- {
- m_fOpen = false;
- m_fOpenOnWasClosed = false;
- m_pInterface->close(this, 0);
- }
-
- /* release it (see start()) */
- m_pInterface->release();
- m_pInterface = NULL;
- }
-
- irc = IOUSBUserClientInit::message(enmMsg, pProvider, pvArg);
- break;
-
- default:
- irc = IOUSBUserClientInit::message(enmMsg, pProvider, pvArg);
- break;
- }
-
- Log(("VBoxUSBInterface::message([%p], %#x {%s}, %p {%s}, %p) -> %#x\n",
- this, enmMsg, DbgGetIOKitMessageName(enmMsg), pProvider, pProvider->getName(), pvArg, irc));
- return irc;
-}
-
diff --git a/src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSBInterface.h b/src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSBInterface.h
deleted file mode 100644
index 6944e3e85a2..00000000000
--- a/src/VBox/HostDrivers/VBoxUSB/darwin/VBoxUSBInterface.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/** $Id$ */
-/** @file
- * VirtualBox USB Driver User<->Kernel Interface.
- */
-
-/*
- * Copyright (C) 2007-2022 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * The contents of this file may alternatively be used under the terms
- * of the Common Development and Distribution License Version 1.0
- * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
- * VirtualBox OSE distribution, in which case the provisions of the
- * CDDL are applicable instead of those of the GPL.
- *
- * You may elect to license modified versions of this file under the
- * terms and conditions of either the GPL or the CDDL or both.
- */
-
-#ifndef VBOX_INCLUDED_SRC_VBoxUSB_darwin_VBoxUSBInterface_h
-#define VBOX_INCLUDED_SRC_VBoxUSB_darwin_VBoxUSBInterface_h
-#ifndef RT_WITHOUT_PRAGMA_ONCE
-# pragma once
-#endif
-
-#include <VBox/usbfilter.h>
-
-/**
- * org_virtualbox_VBoxUSBClient method indexes.
- */
-typedef enum VBOXUSBMETHOD
-{
- /** org_virtualbox_VBoxUSBClient::addFilter */
- VBOXUSBMETHOD_ADD_FILTER = 0,
- /** org_virtualbox_VBoxUSBClient::removeFilter */
- VBOXUSBMETHOD_REMOVE_FILTER,
- /** End/max. */
- VBOXUSBMETHOD_END
-} VBOXUSBMETHOD;
-
-/**
- * Output from a VBOXUSBMETHOD_ADD_FILTER call.
- */
-typedef struct VBOXUSBADDFILTEROUT
-{
- /** The ID. */
- uintptr_t uId;
- /** The return code. */
- int rc;
-} VBOXUSBADDFILTEROUT;
-/** Pointer to a VBOXUSBADDFILTEROUT. */
-typedef VBOXUSBADDFILTEROUT *PVBOXUSBADDFILTEROUT;
-
-/** Cookie used to fend off some unwanted clients to the IOService. */
-#define VBOXUSB_DARWIN_IOSERVICE_COOKIE UINT32_C(0x62735556) /* 'VUsb' */
-
-#endif /* !VBOX_INCLUDED_SRC_VBoxUSB_darwin_VBoxUSBInterface_h */
-
diff --git a/src/VBox/HostDrivers/VBoxUSB/darwin/loadusb.sh b/src/VBox/HostDrivers/VBoxUSB/darwin/loadusb.sh
deleted file mode 100755
index b470a10c6cf..00000000000
--- a/src/VBox/HostDrivers/VBoxUSB/darwin/loadusb.sh
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/bash
-## @file
-# For development.
-#
-
-#
-# Copyright (C) 2006-2022 Oracle Corporation
-#
-# This file is part of VirtualBox Open Source Edition (OSE), as
-# available from http://www.virtualbox.org. This file is free software;
-# you can redistribute it and/or modify it under the terms of the GNU
-# General Public License (GPL) as published by the Free Software
-# Foundation, in version 2 as it comes in the "COPYING" file of the
-# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
-# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
-#
-# The contents of this file may alternatively be used under the terms
-# of the Common Development and Distribution License Version 1.0
-# (CDDL) only, as it comes in the "COPYING.CDDL" file of the
-# VirtualBox OSE distribution, in which case the provisions of the
-# CDDL are applicable instead of those of the GPL.
-#
-# You may elect to license modified versions of this file under the
-# terms and conditions of either the GPL or the CDDL or both.
-#
-
-SCRIPT_NAME="loadusb"
-XNU_VERSION=`LC_ALL=C uname -r | LC_ALL=C cut -d . -f 1`
-
-DRVNAME="VBoxUSB.kext"
-BUNDLE="org.virtualbox.kext.VBoxUSB"
-
-DEP_DRVNAME="VBoxDrv.kext"
-DEP_BUNDLE="org.virtualbox.kext.VBoxDrv"
-
-
-DIR=`dirname "$0"`
-DIR=`cd "$DIR" && pwd`
-DEP_DIR="$DIR/$DEP_DRVNAME"
-DIR="$DIR/$DRVNAME"
-if [ ! -d "$DIR" ]; then
- echo "Cannot find $DIR or it's not a directory..."
- exit 1;
-fi
-if [ ! -d "$DEP_DIR" ]; then
- echo "Cannot find $DEP_DIR or it's not a directory... (dependency)"
- exit 1;
-fi
-if [ -n "$*" ]; then
- OPTS="$*"
-else
- OPTS="-t"
-fi
-
-trap "sudo chown -R `whoami` $DIR $DEP_DIR; exit 1" INT
-
-# Try unload any existing instance first.
-LOADED=`kextstat -b $BUNDLE -l`
-if test -n "$LOADED"; then
- echo "${SCRIPT_NAME}.sh: Unloading $BUNDLE..."
- sudo kextunload -v 6 -b $BUNDLE
- LOADED=`kextstat -b $BUNDLE -l`
- if test -n "$LOADED"; then
- echo "${SCRIPT_NAME}.sh: failed to unload $BUNDLE, see above..."
- exit 1;
- fi
- echo "${SCRIPT_NAME}.sh: Successfully unloaded $BUNDLE"
-fi
-
-# We are now done since VBoxUSB.kext is no longer used.
diff --git a/src/VBox/HostDrivers/VBoxUSB/darwin/testcase/Makefile.kup b/src/VBox/HostDrivers/VBoxUSB/darwin/testcase/Makefile.kup
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/src/VBox/HostDrivers/VBoxUSB/darwin/testcase/Makefile.kup
+++ /dev/null
diff --git a/src/VBox/HostDrivers/VBoxUSB/darwin/testcase/tstOpenUSBDev.cpp b/src/VBox/HostDrivers/VBoxUSB/darwin/testcase/tstOpenUSBDev.cpp
deleted file mode 100644
index 1c2d1d386ee..00000000000
--- a/src/VBox/HostDrivers/VBoxUSB/darwin/testcase/tstOpenUSBDev.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-/* $Id$ */
-/** @file
- * Testcase that attempts to locate and open the specified device.
- */
-
-/*
- * Copyright (C) 2006-2022 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * The contents of this file may alternatively be used under the terms
- * of the Common Development and Distribution License Version 1.0
- * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
- * VirtualBox OSE distribution, in which case the provisions of the
- * CDDL are applicable instead of those of the GPL.
- *
- * You may elect to license modified versions of this file under the
- * terms and conditions of either the GPL or the CDDL or both.
- */
-
-
-/*********************************************************************************************************************************
-* Header Files *
-*********************************************************************************************************************************/
-#include <mach/mach.h>
-#include <Carbon/Carbon.h>
-#include <IOKit/IOKitLib.h>
-#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
-#include <IOKit/scsi/SCSITaskLib.h>
-#include <mach/mach_error.h>
-#include <IOKit/usb/IOUSBLib.h>
-#include <IOKit/IOCFPlugIn.h>
-
-#include <iprt/err.h>
-#include <iprt/mem.h>
-#include <iprt/string.h>
-#include <iprt/process.h>
-#include <iprt/assert.h>
-#include <iprt/thread.h>
-#include <iprt/getopt.h>
-#include <iprt/initterm.h>
-#include <iprt/stream.h>
-
-
-/**
- * Gets an unsigned 32-bit integer value.
- *
- * @returns Success indicator (true/false).
- * @param DictRef The dictionary.
- * @param KeyStrRef The key name.
- * @param pu32 Where to store the key value.
- */
-static bool tstDictGetU32(CFMutableDictionaryRef DictRef, CFStringRef KeyStrRef, uint32_t *pu32)
-{
- CFTypeRef ValRef = CFDictionaryGetValue(DictRef, KeyStrRef);
- if (ValRef)
- {
- if (CFNumberGetValue((CFNumberRef)ValRef, kCFNumberSInt32Type, pu32))
- return true;
- }
- *pu32 = 0;
- return false;
-}
-
-
-/**
- * Gets an unsigned 64-bit integer value.
- *
- * @returns Success indicator (true/false).
- * @param DictRef The dictionary.
- * @param KeyStrRef The key name.
- * @param pu64 Where to store the key value.
- */
-static bool tstDictGetU64(CFMutableDictionaryRef DictRef, CFStringRef KeyStrRef, uint64_t *pu64)
-{
- CFTypeRef ValRef = CFDictionaryGetValue(DictRef, KeyStrRef);
- if (ValRef)
- {
- if (CFNumberGetValue((CFNumberRef)ValRef, kCFNumberSInt64Type, pu64))
- return true;
- }
- *pu64 = 0;
- return false;
-}
-
-
-static int tstDoWork(io_object_t USBDevice, const char *argv0)
-{
- /*
- * Create a plugin interface for the device and query its IOUSBDeviceInterface.
- */
- int vrc = VINF_SUCCESS;
- SInt32 Score = 0;
- IOCFPlugInInterface **ppPlugInInterface = NULL;
- IOReturn irc = IOCreatePlugInInterfaceForService(USBDevice, kIOUSBDeviceUserClientTypeID,
- kIOCFPlugInInterfaceID, &ppPlugInInterface, &Score);
- if (irc == kIOReturnSuccess)
- {
- IOUSBDeviceInterface245 **ppDevI = NULL;
- HRESULT hrc = (*ppPlugInInterface)->QueryInterface(ppPlugInInterface,
- CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID245),
- (LPVOID *)&ppDevI);
- irc = IODestroyPlugInInterface(ppPlugInInterface); Assert(irc == kIOReturnSuccess);
- ppPlugInInterface = NULL;
- if (hrc == S_OK)
- {
- /*
- * Try open the device for exclusive access.
- */
- irc = (*ppDevI)->USBDeviceOpenSeize(ppDevI);
- if (irc == kIOReturnExclusiveAccess)
- {
- RTThreadSleep(20);
- irc = (*ppDevI)->USBDeviceOpenSeize(ppDevI);
- }
- if (irc == kIOReturnSuccess)
- {
-#if 0
- /*
- * Re-enumerate the device and bail out.
- */
- irc = (*ppDevI)->USBDeviceReEnumerate(ppDevI, 0);
- if (irc != kIOReturnSuccess)
- {
- vrc = RTErrConvertFromDarwinIO(irc);
- RTPrintf("%s: Failed to re-enumerate the device, irc=%#x (vrc=%Rrc).\n", argv0, irc, vrc);
- }
-#endif
-
- (*ppDevI)->USBDeviceClose(ppDevI);
- }
- else if (irc == kIOReturnExclusiveAccess)
- {
- vrc = VERR_SHARING_VIOLATION;
- RTPrintf("%s: The device is being used by another process (irc=kIOReturnExclusiveAccess)\n", argv0);
- }
- else
- {
- vrc = VERR_OPEN_FAILED;
- RTPrintf("%s: Failed to open the device, irc=%#x (vrc=%Rrc).\n", argv0, irc, vrc);
- }
- }
- else
- {
- vrc = VERR_OPEN_FAILED;
- RTPrintf("%s: Failed to create plugin interface for the device, hrc=%#x (vrc=%Rrc).\n", argv0, hrc, vrc);
- }
-
- (*ppDevI)->Release(ppDevI);
- }
- else
- {
- vrc = RTErrConvertFromDarwinIO(irc);
- RTPrintf("%s: Failed to open the device, plug-in creation failed with irc=%#x (vrc=%Rrc).\n", argv0, irc, vrc);
- }
-
- return vrc;
-}
-
-
-static int tstSyntax(const char *argv0)
-{
- RTPrintf("syntax: %s [criteria]\n"
- "\n"
- "Criteria:\n"
- " -l <location>\n"
- " -s <session>\n"
- , argv0);
- return 1;
-}
-
-
-int main(int argc, char **argv)
-{
- RTR3InitExe(argc, &argv, 0);
-
- /*
- * Show help if not arguments.
- */
- if (argc <= 1)
- return tstSyntax(argv[0]);
-
- /*
- * Parse arguments.
- */
- static const RTGETOPTDEF g_aOptions[] =
- {
- { "--location", 'l', RTGETOPT_REQ_UINT32 },
- { "--session", 's', RTGETOPT_REQ_UINT64 },
- };
-
- kern_return_t krc;
- uint64_t u64SessionId = 0;
- uint32_t u32LocationId = 0;
-
- int ch;
- RTGETOPTUNION ValueUnion;
- RTGETOPTSTATE GetState;
- RTGetOptInit(&GetState, argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), 1, 0 /* fFlags */);
- while ((ch = RTGetOpt(&GetState, &ValueUnion)))
- {
- switch (ch)
- {
- case 'l':
- u32LocationId = ValueUnion.u32;
- break;
- case 's':
- u64SessionId = ValueUnion.u64;
- break;
- case 'h':
- return tstSyntax(argv[0]);
- case 'V':
- RTPrintf("$Revision$\n");
- return 0;
-
- default:
- return RTGetOptPrintError(ch, &ValueUnion);
- }
- }
-
- /*
- * Open the master port.
- */
- mach_port_t MasterPort = MACH_PORT_NULL;
- krc = IOMasterPort(MACH_PORT_NULL, &MasterPort);
- if (krc != KERN_SUCCESS)
- {
- RTPrintf("%s: IOMasterPort -> %x\n", argv[0], krc);
- return 1;
- }
-
- /*
- * Iterate the USB devices and find all that matches.
- */
- CFMutableDictionaryRef RefMatchingDict = IOServiceMatching(kIOUSBDeviceClassName);
- if (!RefMatchingDict)
- {
- RTPrintf("%s: IOServiceMatching failed\n", argv[0]);
- return 1;
- }
-
- io_iterator_t USBDevices = IO_OBJECT_NULL;
- IOReturn irc = IOServiceGetMatchingServices(MasterPort, RefMatchingDict, &USBDevices);
- if (irc != kIOReturnSuccess)
- {
- RTPrintf("%s: IOServiceGetMatchingServices -> %#x\n", argv[0], irc);
- return 1;
- }
- RefMatchingDict = NULL; /* the reference is consumed by IOServiceGetMatchingServices. */
-
- unsigned cDevices = 0;
- unsigned cMatches = 0;
- io_object_t USBDevice;
- while ((USBDevice = IOIteratorNext(USBDevices)))
- {
- cDevices++;
- CFMutableDictionaryRef PropsRef = 0;
- krc = IORegistryEntryCreateCFProperties(USBDevice, &PropsRef, kCFAllocatorDefault, kNilOptions);
- if (krc == KERN_SUCCESS)
- {
- uint64_t u64CurSessionId;
- uint32_t u32CurLocationId;
- if ( ( !u64SessionId
- || ( tstDictGetU64(PropsRef, CFSTR("sessionID"), &u64CurSessionId)
- && u64CurSessionId == u64SessionId))
- && ( !u32LocationId
- || ( tstDictGetU32(PropsRef, CFSTR(kUSBDevicePropertyLocationID), &u32CurLocationId)
- && u32CurLocationId == u32LocationId))
- )
- {
- cMatches++;
- CFRelease(PropsRef);
- tstDoWork(USBDevice, argv[0]);
- }
- else
- CFRelease(PropsRef);
- }
- IOObjectRelease(USBDevice);
- }
- IOObjectRelease(USBDevices);
-
- /*
- * Bitch if we didn't find anything matching the criteria.
- */
- if (!cMatches)
- RTPrintf("%s: No matching devices found from a total of %d.\n", argv[0], cDevices);
- return !cMatches;
-}
-