VirtualBox

Changeset 3764 in vbox


Ignore:
Timestamp:
Jul 22, 2007 1:19:02 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
23092
Message:

Drop holdDevice(). darwin changes.

Location:
trunk/src/VBox/Main
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/Makefile.kmk

    r3758 r3764  
    219219endif
    220220
    221 ## Alternative USB filtering.
    222 #ifeq ($(filter-out darwin,$(BUILD_TARGET)),)
    223 #VBoxSVC_DEFS += VBOX_WITH_USBFILTER
    224 #VBoxSVC_LIBS += $(PATH_LIB)/USBLib$(VBOX_SUFF_LIB)
    225 #endif
     221# Alternative USB filtering.
     222ifeq ($(filter-out darwin,$(BUILD_TARGET)),)
     223VBoxSVC_DEFS += VBOX_WITH_USBFILTER
     224VBoxSVC_LIBS += $(PATH_LIB)/USBLib$(VBOX_SUFF_LIB)
     225endif
    226226
    227227
  • trunk/src/VBox/Main/USBProxyService.cpp

    r3758 r3764  
    456456
    457457
     458#ifdef VBOX_WITH_USBFILTER
     459/*static*/ void USBProxyService::initFilterFromDevice (PUSBFILTER aFilter, HostUSBDevice *aDevice)
     460{
     461    PCUSBDEVICE pDev = aDevice->mUsb;
     462    int vrc;
     463
     464    vrc = USBFilterSetNumExact (aFilter, USBFILTERIDX_VENDOR_ID,         pDev->idVendor,         true); AssertRC(vrc);
     465    vrc = USBFilterSetNumExact (aFilter, USBFILTERIDX_PRODUCT_ID,        pDev->idProduct,        true); AssertRC(vrc);
     466    vrc = USBFilterSetNumExact (aFilter, USBFILTERIDX_DEVICE_REV,        pDev->bcdDevice,        true); AssertRC(vrc);
     467    vrc = USBFilterSetNumExact (aFilter, USBFILTERIDX_DEVICE_CLASS,      pDev->bDeviceClass,     true); AssertRC(vrc);
     468    vrc = USBFilterSetNumExact (aFilter, USBFILTERIDX_DEVICE_SUB_CLASS,  pDev->bDeviceSubClass,  true); AssertRC(vrc);
     469    vrc = USBFilterSetNumExact (aFilter, USBFILTERIDX_DEVICE_PROTOCOL,   pDev->bDeviceProtocol,  true); AssertRC(vrc);
     470    vrc = USBFilterSetNumExact (aFilter, USBFILTERIDX_PORT,              pDev->bPort,            true); AssertRC(vrc);
     471    vrc = USBFilterSetNumExact (aFilter, USBFILTERIDX_BUS,               pDev->bBus,            false); AssertRC(vrc); /* not available on darwin yet... */
     472    if (pDev->pszSerialNumber)
     473    {
     474        vrc = USBFilterSetStringExact (aFilter, USBFILTERIDX_SERIAL_NUMBER_STR, pDev->pszSerialNumber, true);
     475        AssertRC (vrc);
     476    }
     477    if (pDev->pszProduct)
     478    {
     479        vrc = USBFilterSetStringExact (aFilter, USBFILTERIDX_PRODUCT_STR, pDev->pszProduct, true);
     480        AssertRC (vrc);
     481    }
     482    if (pDev->pszManufacturer)
     483    {
     484        vrc = USBFilterSetStringExact (aFilter, USBFILTERIDX_MANUFACTURER_STR, pDev->pszManufacturer, true);
     485        AssertRC (vrc);
     486    }
     487}
     488#endif /* VBOX_WITH_USBFILTER */
     489
     490
    458491bool USBProxyService::updateDeviceStateFake (HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice)
    459492{
     
    561594
    562595
    563 int USBProxyService::holdDevice (HostUSBDevice * /* aDevice */)
    564 {
    565     return VERR_NOT_IMPLEMENTED;
    566 }
    567 
    568 
    569596void USBProxyService::detachingDevice (HostUSBDevice * /* aDevice */)
    570597{
  • trunk/src/VBox/Main/darwin/iokit.cpp

    r3665 r3764  
    4242
    4343#include <VBox/log.h>
     44#include <VBox/err.h>
    4445#include <iprt/mem.h>
    4546#include <iprt/string.h>
     47#include <iprt/process.h>
    4648#include <iprt/assert.h>
     49#include <iprt/thread.h>
    4750
    4851#include "iokit.h"
     
    5558#define MY_CHECK_CREFS(cRefs)   do { AssertMsg(cRefs < 25, ("%ld\n", cRefs)); NOREF(cRefs); } while (0)
    5659
     60/** Contains the pid of the current client. If 0, the kernel is the current client. */
     61#define VBOXUSB_CLIENT_KEY  "VBoxUSB-Client"
     62/** Contains the pid of the filter owner (i.e. the VBoxSVC pid). */
     63#define VBOXUSB_OWNER_KEY   "VBoxUSB-Owner"
     64/** The VBoxUSBDevice class name. */
     65#define VBOXUSBDEVICE_CLASS_NAME "org_virtualbox_VBoxUSBDevice"
     66
    5767
    5868/*******************************************************************************
     
    162172    *pu64 = 0;
    163173    return false;
     174}
     175
     176
     177/**
     178 * Gets a RTPROCESS value.
     179 *
     180 * @returns Success indicator (true/false).
     181 * @param   DictRef     The dictionary.
     182 * @param   KeyStrRef   The key name.
     183 * @param   pProcess    Where to store the key value.
     184 */
     185static bool darwinDictGetProccess(CFMutableDictionaryRef DictRef, CFStringRef KeyStrRef, PRTPROCESS pProcess)
     186{
     187    switch (sizeof(*pProcess))
     188    {
     189        case sizeof(uint16_t):  return darwinDictGetU16(DictRef, KeyStrRef, (uint16_t *)pProcess);
     190        case sizeof(uint32_t):  return darwinDictGetU32(DictRef, KeyStrRef, (uint32_t *)pProcess);
     191        case sizeof(uint64_t):  return darwinDictGetU64(DictRef, KeyStrRef, (uint64_t *)pProcess);
     192        default:
     193            AssertMsgFailedReturn(("%d\n", sizeof(*pProcess)), false);
     194    }
    164195}
    165196
     
    630661        return;
    631662
     663    RTPROCESS Owner = NIL_RTPROCESS;
     664    RTPROCESS Client = NIL_RTPROCESS;
    632665    bool fUserClientOnly = true;
    633666    bool fConfigured = false;
     
    686719            }
    687720        }
     721        /*
     722         * Not an interface, could it be VBoxUSBDevice?
     723         * If it is, get the owner and client properties.
     724         */
     725        else if (    krc == KERN_SUCCESS
     726                 &&  !strcmp(szName, VBOXUSBDEVICE_CLASS_NAME))
     727        {
     728            CFMutableDictionaryRef PropsRef = 0;
     729            krc = IORegistryEntryCreateCFProperties(Interface, &PropsRef, kCFAllocatorDefault, kNilOptions);
     730            if (krc == KERN_SUCCESS)
     731            {
     732                darwinDictGetProccess(PropsRef, CFSTR(VBOXUSB_OWNER_KEY), &Owner);
     733                darwinDictGetProccess(PropsRef, CFSTR(VBOXUSB_CLIENT_KEY), &Client);
     734                CFRelease(PropsRef);
     735            }
     736        }
     737
    688738        IOObjectRelease(Interface);
    689739    }
     
    693743     * Calc the status.
    694744     */
    695     if (fUserClientOnly)
    696         /** @todo how to detect other user client?!? */
     745    if (    Owner != NIL_RTPROCESS
     746        &&  !Owner)
     747    {
     748        if (Owner == RTProcSelf())
     749            pCur->enmState = Client == NIL_RTPROCESS || !Client
     750                           ? USBDEVICESTATE_HELD_BY_PROXY
     751                           : USBDEVICESTATE_USED_BY_GUEST;
     752        else
     753            pCur->enmState = USBDEVICESTATE_USED_BY_HOST;
     754    }
     755    else if (fUserClientOnly)
     756        /** @todo how to detect other user client?!? - Look for IOUSBUserClient! */
    697757        pCur->enmState = !fConfigured
    698758                       ? USBDEVICESTATE_UNUSED
    699759                       : USBDEVICESTATE_USED_BY_HOST_CAPTURABLE;
    700 
    701760    else if (!fInUse)
    702761        pCur->enmState = USBDEVICESTATE_UNUSED;
     
    909968}
    910969
     970
     971/**
     972 * Triggers re-enumeration of a device.
     973 *
     974 * @returns VBox status code.
     975 * @param   pCur    The USBDEVICE structure for the device.
     976 */
     977int DarwinReEnumerateUSBDevice(PCUSBDEVICE pCur)
     978{
     979    int vrc;
     980    const char *pszAddress = pCur->pszAddress;
     981    AssertPtrReturn(pszAddress, VERR_INVALID_POINTER);
     982    AssertReturn(darwinOpenMasterPort(), VERR_GENERAL_FAILURE);
     983
     984    /*
     985     * This code is a short version of the Open method in USBProxyDevice-darwin.cpp stuff.
     986     * Fixes made to this code probably applies there too!
     987     */
     988
     989    CFMutableDictionaryRef RefMatchingDict = IOServiceMatching(kIOUSBDeviceClassName);
     990    AssertReturn(RefMatchingDict, NULL);
     991
     992    uint64_t u64SessionId = 0;
     993    uint32_t u32LocationId = 0;
     994    const char *psz = pszAddress;
     995    do
     996    {
     997        const char chValue = *psz;
     998        AssertReleaseReturn(psz[1] == '=', VERR_INTERNAL_ERROR);
     999        uint64_t u64Value;
     1000        int rc = RTStrToUInt64Ex(psz + 2, (char **)&psz, 0, &u64Value);
     1001        AssertReleaseRCReturn(rc, rc);
     1002        AssertReleaseReturn(!*psz || *psz == ';', rc);
     1003        switch (chValue)
     1004        {
     1005            case 'l':
     1006                u32LocationId = (uint32_t)u64Value;
     1007                break;
     1008            case 's':
     1009                u64SessionId = u64Value;
     1010                break;
     1011            case 'p':
     1012            case 'v':
     1013            {
     1014#if 0 /* Guess what, this doesn't 'ing work either! */
     1015                SInt32 i32 = (int16_t)u64Value;
     1016                CFNumberRef Num = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i32);
     1017                AssertBreak(Num,);
     1018                CFDictionarySetValue(RefMatchingDict, chValue == 'p' ? CFSTR(kUSBProductID) : CFSTR(kUSBVendorID), Num);
     1019                CFRelease(Num);
     1020#endif
     1021                break;
     1022            }
     1023            default:
     1024                AssertReleaseMsgFailedReturn(("chValue=%#x\n", chValue), VERR_INTERNAL_ERROR);
     1025        }
     1026        if (*psz == ';')
     1027            psz++;
     1028    } while (*psz);
     1029
     1030    io_iterator_t USBDevices = NULL;
     1031    IOReturn irc = IOServiceGetMatchingServices(g_MasterPort, RefMatchingDict, &USBDevices);
     1032    AssertMsgReturn(irc == kIOReturnSuccess, ("irc=%#x\n", irc), NULL);
     1033    RefMatchingDict = NULL; /* the reference is consumed by IOServiceGetMatchingServices. */
     1034
     1035    unsigned cMatches = 0;
     1036    io_object_t USBDevice;
     1037    while ((USBDevice = IOIteratorNext(USBDevices)))
     1038    {
     1039        cMatches++;
     1040        CFMutableDictionaryRef PropsRef = 0;
     1041        kern_return_t krc = IORegistryEntryCreateCFProperties(USBDevice, &PropsRef, kCFAllocatorDefault, kNilOptions);
     1042        if (krc == KERN_SUCCESS)
     1043        {
     1044            uint64_t u64CurSessionId;
     1045            uint32_t u32CurLocationId;
     1046            if (    (    !u64SessionId
     1047                     || (   darwinDictGetU64(PropsRef, CFSTR("sessionID"), &u64CurSessionId)
     1048                         && u64CurSessionId == u64SessionId))
     1049                &&  (   !u32LocationId
     1050                     || (   darwinDictGetU32(PropsRef, CFSTR(kUSBDevicePropertyLocationID), &u32CurLocationId)
     1051                         && u32CurLocationId == u32LocationId))
     1052                )
     1053            {
     1054                CFRelease(PropsRef);
     1055                break;
     1056            }
     1057            CFRelease(PropsRef);
     1058        }
     1059        IOObjectRelease(USBDevice);
     1060    }
     1061    IOObjectRelease(USBDevices);
     1062    USBDevices = NULL;
     1063    if (!USBDevice)
     1064    {
     1065        LogRel(("USB: Device '%s' not found (%d pid+vid matches)\n", pszAddress, cMatches));
     1066        IOObjectRelease(USBDevices);
     1067        return VERR_VUSB_DEVICE_NAME_NOT_FOUND;
     1068    }
     1069
     1070    /*
     1071     * Create a plugin interface for the device and query its IOUSBDeviceInterface.
     1072     */
     1073    SInt32 Score = 0;
     1074    IOCFPlugInInterface **ppPlugInInterface = NULL;
     1075    irc = IOCreatePlugInInterfaceForService(USBDevice, kIOUSBDeviceUserClientTypeID,
     1076                                            kIOCFPlugInInterfaceID, &ppPlugInInterface, &Score);
     1077    if (irc == kIOReturnSuccess)
     1078    {
     1079        IOUSBDeviceInterface245 **ppDevI = NULL;
     1080        HRESULT hrc = (*ppPlugInInterface)->QueryInterface(ppPlugInInterface,
     1081                                                           CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID245),
     1082                                                           (LPVOID *)&ppDevI);
     1083        irc = IODestroyPlugInInterface(ppPlugInInterface); Assert(irc == kIOReturnSuccess);
     1084        ppPlugInInterface = NULL;
     1085        if (hrc == S_OK)
     1086        {
     1087            /*
     1088             * Try open the device for exclusive access.
     1089             */
     1090            irc = (*ppDevI)->USBDeviceOpenSeize(ppDevI);
     1091            if (irc == kIOReturnExclusiveAccess)
     1092            {
     1093                RTThreadSleep(20);
     1094                irc = (*ppDevI)->USBDeviceOpenSeize(ppDevI);
     1095            }
     1096            if (irc == kIOReturnSuccess)
     1097            {
     1098                /*
     1099                 * Re-enumerate the device and bail out.
     1100                 */
     1101                irc = (*ppDevI)->USBDeviceReEnumerate(ppDevI, 0);
     1102                if (irc != kIOReturnSuccess)
     1103                {
     1104                    LogRel(("USB: Failed to open device '%s', plug-in creation failed with irc=%#x.\n", pszAddress, irc));
     1105                    vrc = RTErrConvertFromDarwinIO(irc);
     1106                }
     1107
     1108                (*ppDevI)->USBDeviceClose(ppDevI);
     1109            }
     1110            else if (irc == kIOReturnExclusiveAccess)
     1111            {
     1112                LogRel(("USB: Device '%s' is being used by another process\n", pszAddress));
     1113                vrc = VERR_SHARING_VIOLATION;
     1114            }
     1115            else
     1116            {
     1117                LogRel(("USB: Failed to open device '%s', irc=%#x.\n", pszAddress, irc));
     1118                vrc = VERR_OPEN_FAILED;
     1119            }
     1120        }
     1121        else
     1122        {
     1123            LogRel(("USB: Failed to create plugin interface for device '%s', hrc=%#x.\n", pszAddress, hrc));
     1124            vrc = VERR_OPEN_FAILED;
     1125        }
     1126
     1127        (*ppDevI)->Release(ppDevI);
     1128    }
     1129    else
     1130    {
     1131        LogRel(("USB: Failed to open device '%s', plug-in creation failed with irc=%#x.\n", pszAddress, irc));
     1132        vrc = RTErrConvertFromDarwinIO(irc);
     1133    }
     1134
     1135    return vrc;
     1136}
     1137
    9111138#endif /* VBOX_WITH_USB */
    9121139
  • trunk/src/VBox/Main/darwin/iokit.h

    r3662 r3764  
    5151PUSBDEVICE  DarwinGetUSBDevices(void);
    5252void        DarwinFreeUSBDeviceFromIOKit(PUSBDEVICE pCur);
     53int         DarwinReEnumerateUSBDevice(PCUSBDEVICE pCur);
    5354#endif
    5455__END_DECLS
  • trunk/src/VBox/Main/include/HostUSBDeviceImpl.h

    r3668 r3764  
    8484
    8585    /** Additional internal states.
    86      * The async detach stuff for Darwin is a two stage journey with a variation 
     86     * The async detach stuff for Darwin is a two stage journey with a variation
    8787     * (filters) depending on who won the race to lock the Host object.
    88      * 
    89      * @remark Trying out mac os x style enum naming convention here. nice or what? 
     88     *
     89     * @remark Trying out mac os x style enum naming convention here. nice or what?
    9090     */
    9191    typedef enum
    92     { 
     92    {
    9393        /** Nothing is pending here, check mPendingState. */
    94         kNothingPending, 
     94        kNothingPending,
    9595        /** 1st stage of the detch, waiting for the logical detach notification. */
    96         kDetachingPendingDetach, 
    97         /** 1st stage of the detch, waiting for the logical detach notification - re-run filters. 
     96        kDetachingPendingDetach,
     97        /** 1st stage of the detch, waiting for the logical detach notification - re-run filters.
    9898         * Prev: kDetachingPendingDetach */
    99         kDetachingPendingDetachFilters, 
    100         /** 2nd stage of the detach, waiting for the logical attach notification. 
     99        kDetachingPendingDetachFilters,
     100        /** 2nd stage of the detach, waiting for the logical attach notification.
    101101         * Prev: kDetachingPendingDetach */
    102102        kDetachingPendingAttach,
    103         /** 2nd stage of the detach, waiting for the logical attach notification - re-run filters. 
     103        /** 2nd stage of the detach, waiting for the logical attach notification - re-run filters.
    104104         * Prev: kDetachingPendingDetachFilters */
    105105        kDetachingPendingAttachFilters
     
    163163    /** Same as mPendingState but for the internal states. */
    164164    InternalState mPendingStateEx;
    165     /** RTTimeNanoTS() of when mIsStatePending was set or mDetaching changed 
     165    /** RTTimeNanoTS() of when mIsStatePending was set or mDetaching changed
    166166     * from kNotDetaching. For operations that cannot be cancelled it's 0. */
    167167    uint64_t mPendingSince;
     
    179179#ifdef RT_OS_LINUX
    180180    friend class USBProxyServiceLinux;
     181#endif
     182#ifdef RT_OS_DARWIN
     183    /** One-shot filter id. */
     184    void *mOneShotId;
     185
     186    friend class USBProxyServiceDarwin;
    181187#endif
    182188};
  • trunk/src/VBox/Main/include/USBProxyService.h

    r3758 r3764  
    6464
    6565    /**
    66      * The device is to be held so that the host OS will not start using it.
    67      *
    68      * @returns VBox status code.
    69      * @param   aDevice     The device in question.
    70      */
    71     virtual int holdDevice (HostUSBDevice *aDevice);
    72 
    73     /**
    7466     * The device is going to be detached from a VM.
    7567     *
     
    137129     */
    138130    static uint64_t calcSerialHash (const char *aSerial);
     131
     132#ifdef VBOX_WITH_USBFILTER
     133    /**
     134     * Initializes a filter with the data from the specified device.
     135     *
     136     * @param   aFilter     The filter to fill.
     137     * @param   aDevice     The device to fill it with.
     138     */
     139    static void initFilterFromDevice (PUSBFILTER aFilter, HostUSBDevice *aDevice);
     140#endif
    139141
    140142protected:
     
    270272
    271273    virtual int captureDevice (HostUSBDevice *aDevice);
    272     virtual int holdDevice (HostUSBDevice *aDevice);
    273274    virtual void detachingDevice (HostUSBDevice *aDevice);
    274275    virtual int releaseDevice (HostUSBDevice *aDevice);
     
    291292     * not including newly attached devices. */
    292293    bool mWaitABitNextTime;
     294#ifndef VBOX_WITH_USBFILTER
    293295    /** Whether we've got a fake async event and should return without entering the runloop. */
    294296    bool volatile mFakeAsync;
     297#endif
    295298    /** Whether we've successfully initialized the USBLib and should call USBLibTerm in the destructor. */
    296299    bool mUSBLibInitialized;
     
    312315
    313316    virtual int captureDevice (HostUSBDevice *aDevice);
    314     virtual int holdDevice (HostUSBDevice *aDevice);
    315317    virtual int releaseDevice (HostUSBDevice *aDevice);
    316318    virtual bool updateDeviceState (HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice);
     
    354356
    355357    virtual int captureDevice (HostUSBDevice *aDevice);
    356     virtual int holdDevice (HostUSBDevice *aDevice);
    357358    virtual int releaseDevice (HostUSBDevice *aDevice);
    358359    virtual bool updateDeviceState (HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice);
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette