59190ecd61435d19ba3515b876272aee7bd12298vboxsync/** @file
59190ecd61435d19ba3515b876272aee7bd12298vboxsync *
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * VBox host drivers - USB drivers - Filter & driver installation
59190ecd61435d19ba3515b876272aee7bd12298vboxsync *
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * Installation code
59190ecd61435d19ba3515b876272aee7bd12298vboxsync *
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2006-2011 Oracle Corporation
59190ecd61435d19ba3515b876272aee7bd12298vboxsync *
c55c68b6a3324172e9dc207926215845880b0f90vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
c55c68b6a3324172e9dc207926215845880b0f90vboxsync * available from http://www.virtualbox.org. This file is free software;
c55c68b6a3324172e9dc207926215845880b0f90vboxsync * you can redistribute it and/or modify it under the terms of the GNU
c55c68b6a3324172e9dc207926215845880b0f90vboxsync * General Public License (GPL) as published by the Free Software
c55c68b6a3324172e9dc207926215845880b0f90vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
c55c68b6a3324172e9dc207926215845880b0f90vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
c55c68b6a3324172e9dc207926215845880b0f90vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync */
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync/*******************************************************************************
59190ecd61435d19ba3515b876272aee7bd12298vboxsync* Header Files *
59190ecd61435d19ba3515b876272aee7bd12298vboxsync*******************************************************************************/
59190ecd61435d19ba3515b876272aee7bd12298vboxsync#include <windows.h>
59190ecd61435d19ba3515b876272aee7bd12298vboxsync#include <setupapi.h>
59190ecd61435d19ba3515b876272aee7bd12298vboxsync#include <newdev.h>
59190ecd61435d19ba3515b876272aee7bd12298vboxsync#include <iprt/assert.h>
59190ecd61435d19ba3515b876272aee7bd12298vboxsync#include <iprt/err.h>
59190ecd61435d19ba3515b876272aee7bd12298vboxsync#include <iprt/param.h>
59190ecd61435d19ba3515b876272aee7bd12298vboxsync#include <iprt/path.h>
59190ecd61435d19ba3515b876272aee7bd12298vboxsync#include <iprt/string.h>
59190ecd61435d19ba3515b876272aee7bd12298vboxsync#include <VBox/err.h>
59190ecd61435d19ba3515b876272aee7bd12298vboxsync#include <stdio.h>
59190ecd61435d19ba3515b876272aee7bd12298vboxsync#include <VBox/usblib.h>
df294ff29aab74013667896ef2d4f5bd1f782143vboxsync#include <VBox/VBoxDrvCfg-win.h>
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync/** Handle to the open device. */
59190ecd61435d19ba3515b876272aee7bd12298vboxsyncstatic HANDLE g_hUSBMonitor = INVALID_HANDLE_VALUE;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync/** Flags whether or not we started the service. */
59190ecd61435d19ba3515b876272aee7bd12298vboxsyncstatic bool g_fStartedService = false;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync/**
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * Attempts to start the service, creating it if necessary.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync *
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @returns 0 on success.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @returns -1 on failure.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @param fRetry Indicates retry call.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync */
59190ecd61435d19ba3515b876272aee7bd12298vboxsyncint usbMonStartService(void)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync{
df294ff29aab74013667896ef2d4f5bd1f782143vboxsync HRESULT hr = VBoxDrvCfgSvcStart(USBMON_SERVICE_NAME_W);
df294ff29aab74013667896ef2d4f5bd1f782143vboxsync if (hr != S_OK)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync {
df294ff29aab74013667896ef2d4f5bd1f782143vboxsync AssertMsgFailed(("couldn't start service, hr (0x%x)\n", hr));
59190ecd61435d19ba3515b876272aee7bd12298vboxsync return -1;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync }
df294ff29aab74013667896ef2d4f5bd1f782143vboxsync return 0;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync}
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync/**
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * Stops a possibly running service.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync *
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @returns 0 on success.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @returns -1 on failure.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync */
59190ecd61435d19ba3515b876272aee7bd12298vboxsyncint usbMonStopService(void)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync{
59190ecd61435d19ba3515b876272aee7bd12298vboxsync printf("usbMonStopService\n");
59190ecd61435d19ba3515b876272aee7bd12298vboxsync /*
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * Assume it didn't exist, so we'll create the service.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync */
59190ecd61435d19ba3515b876272aee7bd12298vboxsync int rc = -1;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync SC_HANDLE hSMgr = OpenSCManager(NULL, NULL, SERVICE_STOP | SERVICE_QUERY_STATUS);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync DWORD LastError = GetLastError(); NOREF(LastError);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync AssertMsg(hSMgr, ("OpenSCManager(,,delete) failed rc=%d\n", LastError));
59190ecd61435d19ba3515b876272aee7bd12298vboxsync if (hSMgr)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync {
df294ff29aab74013667896ef2d4f5bd1f782143vboxsync SC_HANDLE hService = OpenServiceW(hSMgr, USBMON_SERVICE_NAME_W, SERVICE_STOP | SERVICE_QUERY_STATUS);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync if (hService)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync {
59190ecd61435d19ba3515b876272aee7bd12298vboxsync /*
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * Stop the service.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync */
59190ecd61435d19ba3515b876272aee7bd12298vboxsync SERVICE_STATUS Status;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync QueryServiceStatus(hService, &Status);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync if (Status.dwCurrentState == SERVICE_STOPPED)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync rc = 0;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync else if (ControlService(hService, SERVICE_CONTROL_STOP, &Status))
59190ecd61435d19ba3515b876272aee7bd12298vboxsync {
59190ecd61435d19ba3515b876272aee7bd12298vboxsync int iWait = 100;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync while (Status.dwCurrentState == SERVICE_STOP_PENDING && iWait-- > 0)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync {
59190ecd61435d19ba3515b876272aee7bd12298vboxsync Sleep(100);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync QueryServiceStatus(hService, &Status);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync }
59190ecd61435d19ba3515b876272aee7bd12298vboxsync if (Status.dwCurrentState == SERVICE_STOPPED)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync rc = 0;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync else
59190ecd61435d19ba3515b876272aee7bd12298vboxsync AssertMsgFailed(("Failed to stop service. status=%d\n", Status.dwCurrentState));
59190ecd61435d19ba3515b876272aee7bd12298vboxsync }
59190ecd61435d19ba3515b876272aee7bd12298vboxsync else
59190ecd61435d19ba3515b876272aee7bd12298vboxsync {
59190ecd61435d19ba3515b876272aee7bd12298vboxsync DWORD LastError = GetLastError(); NOREF(LastError);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync AssertMsgFailed(("ControlService failed with LastError=%Rwa. status=%d\n", LastError, Status.dwCurrentState));
59190ecd61435d19ba3515b876272aee7bd12298vboxsync }
59190ecd61435d19ba3515b876272aee7bd12298vboxsync CloseServiceHandle(hService);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync }
59190ecd61435d19ba3515b876272aee7bd12298vboxsync else if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync rc = 0;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync else
59190ecd61435d19ba3515b876272aee7bd12298vboxsync {
59190ecd61435d19ba3515b876272aee7bd12298vboxsync DWORD LastError = GetLastError(); NOREF(LastError);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync AssertMsgFailed(("OpenService failed LastError=%Rwa\n", LastError));
59190ecd61435d19ba3515b876272aee7bd12298vboxsync }
59190ecd61435d19ba3515b876272aee7bd12298vboxsync CloseServiceHandle(hSMgr);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync }
59190ecd61435d19ba3515b876272aee7bd12298vboxsync return rc;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync}
59190ecd61435d19ba3515b876272aee7bd12298vboxsync/**
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * Release specified USB device to the host.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync *
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @returns VBox status code
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @param usVendorId Vendor id
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @param usProductId Product id
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @param usRevision Revision
59190ecd61435d19ba3515b876272aee7bd12298vboxsync */
59190ecd61435d19ba3515b876272aee7bd12298vboxsyncint usbMonReleaseDevice(USHORT usVendorId, USHORT usProductId, USHORT usRevision)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync{
59190ecd61435d19ba3515b876272aee7bd12298vboxsync USBSUP_RELEASE release;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync DWORD cbReturned = 0;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync printf("usbLibReleaseDevice %x %x %x\n", usVendorId, usProductId, usRevision);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync release.usVendorId = usVendorId;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync release.usProductId = usProductId;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync release.usRevision = usRevision;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync if (!DeviceIoControl(g_hUSBMonitor, SUPUSBFLT_IOCTL_RELEASE_DEVICE, &release, sizeof(release), NULL, 0, &cbReturned, NULL))
59190ecd61435d19ba3515b876272aee7bd12298vboxsync {
59190ecd61435d19ba3515b876272aee7bd12298vboxsync AssertMsgFailed(("DeviceIoControl failed with %d\n", GetLastError()));
59190ecd61435d19ba3515b876272aee7bd12298vboxsync return RTErrConvertFromWin32(GetLastError());
59190ecd61435d19ba3515b876272aee7bd12298vboxsync }
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync return VINF_SUCCESS;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync}
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync/**
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * Add USB device filter
59190ecd61435d19ba3515b876272aee7bd12298vboxsync *
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @returns VBox status code.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @param pszVendor Vendor filter string
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @param pszProduct Product filter string
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @param pszRevision Revision filter string
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @param ppID Pointer to filter id
59190ecd61435d19ba3515b876272aee7bd12298vboxsync */
59190ecd61435d19ba3515b876272aee7bd12298vboxsyncint usbMonInsertFilter(const char *pszVendor, const char *pszProduct, const char *pszRevision, void **ppID)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync{
59190ecd61435d19ba3515b876272aee7bd12298vboxsync USBFILTER filter;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync USBSUP_FLTADDOUT flt_add;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync DWORD cbReturned = 0;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync Assert(g_hUSBMonitor);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync printf("usblibInsertFilter %s %s %s\n", pszVendor, pszProduct, pszRevision);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync// strncpy(filter.szVendor, pszVendor, sizeof(filter.szVendor));
59190ecd61435d19ba3515b876272aee7bd12298vboxsync// strncpy(filter.szProduct, pszProduct, sizeof(filter.szProduct));
59190ecd61435d19ba3515b876272aee7bd12298vboxsync// strncpy(filter.szRevision, pszRevision, sizeof(filter.szRevision));
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync if (!DeviceIoControl(g_hUSBMonitor, SUPUSBFLT_IOCTL_ADD_FILTER, &filter, sizeof(filter), &flt_add, sizeof(flt_add), &cbReturned, NULL))
59190ecd61435d19ba3515b876272aee7bd12298vboxsync {
59190ecd61435d19ba3515b876272aee7bd12298vboxsync AssertMsgFailed(("DeviceIoControl failed with %d\n", GetLastError()));
59190ecd61435d19ba3515b876272aee7bd12298vboxsync return RTErrConvertFromWin32(GetLastError());
59190ecd61435d19ba3515b876272aee7bd12298vboxsync }
59190ecd61435d19ba3515b876272aee7bd12298vboxsync *ppID = (void *)flt_add.uId;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync return VINF_SUCCESS;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync}
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync/**
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * Remove USB device filter
59190ecd61435d19ba3515b876272aee7bd12298vboxsync *
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @returns VBox status code.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @param aID Filter id
59190ecd61435d19ba3515b876272aee7bd12298vboxsync */
59190ecd61435d19ba3515b876272aee7bd12298vboxsyncint usbMonRemoveFilter (void *aID)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync{
59190ecd61435d19ba3515b876272aee7bd12298vboxsync uintptr_t uId;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync DWORD cbReturned = 0;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync Assert(g_hUSBMonitor);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
821957136cf1ca193dec7c5c1041ba409e6a0bbbvboxsync printf("usblibRemoveFilter %p\n", aID);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync uId = (uintptr_t)aID;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync if (!DeviceIoControl(g_hUSBMonitor, SUPUSBFLT_IOCTL_REMOVE_FILTER, &uId, sizeof(uId), NULL, 0,&cbReturned, NULL))
59190ecd61435d19ba3515b876272aee7bd12298vboxsync {
59190ecd61435d19ba3515b876272aee7bd12298vboxsync AssertMsgFailed(("DeviceIoControl failed with %d\n", GetLastError()));
59190ecd61435d19ba3515b876272aee7bd12298vboxsync return RTErrConvertFromWin32(GetLastError());
59190ecd61435d19ba3515b876272aee7bd12298vboxsync }
59190ecd61435d19ba3515b876272aee7bd12298vboxsync return VINF_SUCCESS;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync}
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync/**
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * Initialize the USB monitor
59190ecd61435d19ba3515b876272aee7bd12298vboxsync *
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @returns VBox status code.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync */
59190ecd61435d19ba3515b876272aee7bd12298vboxsyncint usbMonitorInit()
59190ecd61435d19ba3515b876272aee7bd12298vboxsync{
59190ecd61435d19ba3515b876272aee7bd12298vboxsync int rc;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync USBSUP_VERSION version = {0};
59190ecd61435d19ba3515b876272aee7bd12298vboxsync DWORD cbReturned;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync printf("usbproxy: usbLibInit\n");
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync g_hUSBMonitor = CreateFile (USBMON_DEVICE_NAME,
59190ecd61435d19ba3515b876272aee7bd12298vboxsync GENERIC_READ | GENERIC_WRITE,
59190ecd61435d19ba3515b876272aee7bd12298vboxsync FILE_SHARE_READ | FILE_SHARE_WRITE,
59190ecd61435d19ba3515b876272aee7bd12298vboxsync NULL, // no SECURITY_ATTRIBUTES structure
59190ecd61435d19ba3515b876272aee7bd12298vboxsync OPEN_EXISTING, // No special create flags
59190ecd61435d19ba3515b876272aee7bd12298vboxsync FILE_ATTRIBUTE_SYSTEM,
59190ecd61435d19ba3515b876272aee7bd12298vboxsync NULL); // No template file
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync if (g_hUSBMonitor == INVALID_HANDLE_VALUE)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync {
59190ecd61435d19ba3515b876272aee7bd12298vboxsync usbMonStartService();
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync g_hUSBMonitor = CreateFile (USBMON_DEVICE_NAME,
59190ecd61435d19ba3515b876272aee7bd12298vboxsync GENERIC_READ | GENERIC_WRITE,
59190ecd61435d19ba3515b876272aee7bd12298vboxsync FILE_SHARE_READ | FILE_SHARE_WRITE,
59190ecd61435d19ba3515b876272aee7bd12298vboxsync NULL, // no SECURITY_ATTRIBUTES structure
59190ecd61435d19ba3515b876272aee7bd12298vboxsync OPEN_EXISTING, // No special create flags
59190ecd61435d19ba3515b876272aee7bd12298vboxsync FILE_ATTRIBUTE_SYSTEM,
59190ecd61435d19ba3515b876272aee7bd12298vboxsync NULL); // No template file
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync if (g_hUSBMonitor == INVALID_HANDLE_VALUE)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync {
59190ecd61435d19ba3515b876272aee7bd12298vboxsync /* AssertFailed(); */
59190ecd61435d19ba3515b876272aee7bd12298vboxsync printf("usbproxy: Unable to open filter driver!! (rc=%d)\n", GetLastError());
59190ecd61435d19ba3515b876272aee7bd12298vboxsync rc = VERR_FILE_NOT_FOUND;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync goto failure;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync }
59190ecd61435d19ba3515b876272aee7bd12298vboxsync }
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync /*
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * Check the version
59190ecd61435d19ba3515b876272aee7bd12298vboxsync */
59190ecd61435d19ba3515b876272aee7bd12298vboxsync cbReturned = 0;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync if (!DeviceIoControl(g_hUSBMonitor, SUPUSBFLT_IOCTL_GET_VERSION, NULL, 0,&version, sizeof(version), &cbReturned, NULL))
59190ecd61435d19ba3515b876272aee7bd12298vboxsync {
59190ecd61435d19ba3515b876272aee7bd12298vboxsync printf("usbproxy: Unable to query filter version!! (rc=%d)\n", GetLastError());
59190ecd61435d19ba3515b876272aee7bd12298vboxsync rc = VERR_VERSION_MISMATCH;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync goto failure;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync }
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync if (version.u32Major != USBMON_MAJOR_VERSION ||
59190ecd61435d19ba3515b876272aee7bd12298vboxsync version.u32Minor < USBMON_MINOR_VERSION)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync {
59190ecd61435d19ba3515b876272aee7bd12298vboxsync printf("usbproxy: Filter driver version mismatch!!\n");
59190ecd61435d19ba3515b876272aee7bd12298vboxsync rc = VERR_VERSION_MISMATCH;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync goto failure;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync }
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync return VINF_SUCCESS;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsyncfailure:
59190ecd61435d19ba3515b876272aee7bd12298vboxsync if (g_hUSBMonitor != INVALID_HANDLE_VALUE)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync {
59190ecd61435d19ba3515b876272aee7bd12298vboxsync CloseHandle(g_hUSBMonitor);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync g_hUSBMonitor = INVALID_HANDLE_VALUE;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync }
59190ecd61435d19ba3515b876272aee7bd12298vboxsync return rc;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync}
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync/**
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * Terminate the USB monitor
59190ecd61435d19ba3515b876272aee7bd12298vboxsync *
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * @returns VBox status code.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync */
59190ecd61435d19ba3515b876272aee7bd12298vboxsyncint usbMonitorTerm()
59190ecd61435d19ba3515b876272aee7bd12298vboxsync{
59190ecd61435d19ba3515b876272aee7bd12298vboxsync if (g_hUSBMonitor != INVALID_HANDLE_VALUE)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync {
59190ecd61435d19ba3515b876272aee7bd12298vboxsync CloseHandle(g_hUSBMonitor);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync g_hUSBMonitor = INVALID_HANDLE_VALUE;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync }
59190ecd61435d19ba3515b876272aee7bd12298vboxsync /*
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * If we started the service we might consider stopping it too.
59190ecd61435d19ba3515b876272aee7bd12298vboxsync *
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * Since this won't work unless the process starting it is the
59190ecd61435d19ba3515b876272aee7bd12298vboxsync * last user we might wanna skip this...
59190ecd61435d19ba3515b876272aee7bd12298vboxsync */
59190ecd61435d19ba3515b876272aee7bd12298vboxsync if (g_fStartedService)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync {
59190ecd61435d19ba3515b876272aee7bd12298vboxsync usbMonStopService();
59190ecd61435d19ba3515b876272aee7bd12298vboxsync g_fStartedService = false;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync }
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync return VINF_SUCCESS;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync}
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsyncint __cdecl main(int argc, char **argv)
59190ecd61435d19ba3515b876272aee7bd12298vboxsync{
59190ecd61435d19ba3515b876272aee7bd12298vboxsync int rc;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync printf("USB test\n");
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync rc = usbMonitorInit();
59190ecd61435d19ba3515b876272aee7bd12298vboxsync AssertRC(rc);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync void *pId1, *pId2;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync usbMonInsertFilter("0529", "0514", "0100", &pId1);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync usbMonInsertFilter("0A16", "2499", "0100", &pId2);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync printf("Waiting to capture device\n");
59190ecd61435d19ba3515b876272aee7bd12298vboxsync getchar();
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync printf("Releasing device\n");
59190ecd61435d19ba3515b876272aee7bd12298vboxsync usbMonReleaseDevice(0xA16, 0x2499, 0x100);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync usbMonRemoveFilter(pId1);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync usbMonRemoveFilter(pId2);
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync rc = usbMonitorTerm();
59190ecd61435d19ba3515b876272aee7bd12298vboxsync
59190ecd61435d19ba3515b876272aee7bd12298vboxsync return 0;
59190ecd61435d19ba3515b876272aee7bd12298vboxsync}