VirtualBox

Changeset 2600 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
May 11, 2007 11:38:05 PM (18 years ago)
Author:
vboxsync
Message:

Implemented USB attach and detach notifications. (darwin)

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/darwin/iokit.cpp

    r2587 r2600  
    119119
    120120
     121#if 0 /* unused */
    121122/**
    122123 * Gets an unsigned 32-bit integer value.
     
    138139    return false;
    139140}
     141#endif
    140142
    141143
     
    187189
    188190
    189 
    190 void        DarwinSubscribeUSBNotifications(void)
    191 {
    192 
    193 }
    194 
    195 void        DarwinUnsubscribeUSBNotifications(void)
    196 {
    197 
     191/**
     192 * Notification data created by DarwinSubscribeUSBNotifications, used by
     193 * the callbacks and finally freed by DarwinUnsubscribeUSBNotifications.
     194 */
     195typedef struct DARWINUSBNOTIFY
     196{
     197    /** The notification port.
     198     * It's shared between the notification callbacks. */
     199    IONotificationPortRef NotifyPort;
     200    /** The run loop source for NotifyPort. */
     201    CFRunLoopSourceRef NotifyRLSrc;
     202    /** The attach notification iterator. */
     203    io_iterator_t AttachIterator;
     204    /** The detach notificaiton iterator. */
     205    io_iterator_t DetachIterator;
     206   
     207} DARWINUSBNOTIFY, *PDARWINUSBNOTIFY;
     208
     209
     210/**
     211 * Run thru an interrator.
     212 *
     213 * The docs says this is necessary to start getting notifications,
     214 * so this function is called in the callbacks and right after
     215 * registering the notification.
     216 *
     217 * @param   pIterator   The iterator reference.
     218 */
     219static void darwinDrainIterator(io_iterator_t pIterator)
     220{
     221    io_object_t Object;
     222    while ((Object = IOIteratorNext(pIterator)))
     223        IOObjectRelease(Object);
     224}
     225
     226
     227/**
     228 * Callback for the attach notifications.
     229 *
     230 * @param   pvNotify        Our data.
     231 * @param   NotifyIterator  The notification iterator.
     232 */
     233static void darwinUSBAttachNotification(void *pvNotify, io_iterator_t NotifyIterator)
     234{
     235    NOREF(pvNotify); //PDARWINUSBNOTIFY pNotify = (PDARWINUSBNOTIFY)pvNotify;
     236    darwinDrainIterator(NotifyIterator);
     237}
     238
     239
     240/**
     241 * Callback for the detach notifications.
     242 *
     243 * @param   pvNotify        Our data.
     244 * @param   NotifyIterator  The notification iterator.
     245 */
     246static void darwinUSBDetachNotification(void *pvNotify, io_iterator_t NotifyIterator)
     247{
     248    NOREF(pvNotify); //PDARWINUSBNOTIFY pNotify = (PDARWINUSBNOTIFY)pvNotify;
     249    darwinDrainIterator(NotifyIterator);
     250}
     251
     252
     253/**
     254 * Subscribes the run loop to USB notification events relevant to
     255 * device attach/detach.
     256 *
     257 * The source mode for these events is defined as VBOX_IOKIT_MODE_STRING
     258 * so that the caller can listen to events from this mode only and
     259 * re-evalutate the list of attached devices whenever an event arrives.
     260 *
     261 * @returns opaque for passing to the unsubscribe function. If NULL
     262 *          something unexpectedly failed during subscription.
     263 */
     264void *DarwinSubscribeUSBNotifications(void)
     265{
     266    AssertReturn(darwinOpenMasterPort(), NULL);
     267
     268    PDARWINUSBNOTIFY pNotify = (PDARWINUSBNOTIFY)RTMemAllocZ(sizeof(*pNotify));
     269    AssertReturn(pNotify, NULL);
     270
     271    /*
     272     * Create the notification port, bake it into a runloop source which we
     273     * then add to our run loop.
     274     */
     275    pNotify->NotifyPort = IONotificationPortCreate(g_MasterPort);
     276    Assert(pNotify->NotifyPort);
     277    if (pNotify->NotifyPort)
     278    {
     279        pNotify->NotifyRLSrc = IONotificationPortGetRunLoopSource(pNotify->NotifyPort);
     280        Assert(pNotify->NotifyRLSrc);
     281        if (pNotify->NotifyRLSrc)
     282        {
     283            CFRunLoopAddSource(CFRunLoopGetCurrent(), pNotify->NotifyRLSrc, CFSTR(VBOX_IOKIT_MODE_STRING));
     284
     285            /*
     286             * Create the notifcation callback.
     287             */
     288            kern_return_t rc = IOServiceAddMatchingNotification(pNotify->NotifyPort,
     289                                                                kIOPublishNotification,
     290                                                                IOServiceMatching(kIOUSBDeviceClassName),
     291                                                                darwinUSBAttachNotification,
     292                                                                pNotify,
     293                                                                &pNotify->AttachIterator);
     294            if (rc == KERN_SUCCESS)
     295            {
     296                darwinDrainIterator(pNotify->AttachIterator);
     297                rc = IOServiceAddMatchingNotification(pNotify->NotifyPort,
     298                                                      kIOTerminatedNotification,
     299                                                      IOServiceMatching(kIOUSBDeviceClassName),
     300                                                      darwinUSBDetachNotification,
     301                                                      pNotify,
     302                                                      &pNotify->DetachIterator);
     303                if (rc == KERN_SUCCESS)
     304                {
     305                    darwinDrainIterator(pNotify->DetachIterator);
     306                    return pNotify;
     307                }
     308                IOObjectRelease(pNotify->AttachIterator);
     309            }
     310            CFRunLoopRemoveSource(CFRunLoopGetCurrent(), pNotify->NotifyRLSrc, CFSTR(VBOX_IOKIT_MODE_STRING));
     311        }
     312        IONotificationPortDestroy(pNotify->NotifyPort);
     313    }
     314
     315    RTMemFree(pNotify);
     316    return NULL;
     317}
     318
     319
     320/**
     321 * Unsubscribe the run loop from USB notification subscribed to
     322 * by DarwinSubscribeUSBNotifications.
     323 *
     324 * @param   pvOpaque    The return value from DarwinSubscribeUSBNotifications.
     325 */
     326void DarwinUnsubscribeUSBNotifications(void *pvOpaque)
     327{
     328    PDARWINUSBNOTIFY pNotify = (PDARWINUSBNOTIFY)pvOpaque;
     329    if (!pNotify)
     330        return;
     331
     332    IOObjectRelease(pNotify->AttachIterator);
     333    pNotify->AttachIterator = NULL;
     334    IOObjectRelease(pNotify->DetachIterator);
     335    pNotify->DetachIterator = NULL;
     336
     337    CFRunLoopRemoveSource(CFRunLoopGetCurrent(), pNotify->NotifyRLSrc, CFSTR(VBOX_IOKIT_MODE_STRING));
     338    IONotificationPortDestroy(pNotify->NotifyPort);
     339    pNotify->NotifyRLSrc = NULL;
     340    pNotify->NotifyPort = NULL;
     341
     342    RTMemFree(pNotify);
    198343}
    199344
  • trunk/src/VBox/Main/darwin/iokit.h

    r2587 r2600  
    4747PDARWINDVD  DarwinGetDVDDrives(void);
    4848#ifdef VBOX_WITH_USB
    49 void        DarwinSubscribeUSBNotifications(void);
    50 void        DarwinUnsubscribeUSBNotifications(void);
     49void *      DarwinSubscribeUSBNotifications(void);
     50void        DarwinUnsubscribeUSBNotifications(void *pvOpaque);
    5151PUSBDEVICE  DarwinGetUSBDevices(void);
    5252#endif
  • trunk/src/VBox/Main/include/USBProxyService.h

    r2587 r2600  
    235235     * This is NULL if the service thread isn't running. */
    236236    CFRunLoopRef mServiceRunLoopRef;
    237 
     237    /** The opaque value returned by DarwinSubscribeUSBNotifications. */
     238    void *mNotifyOpaque;
    238239};
    239240# endif /* __DARWIN__ */
Note: See TracChangeset for help on using the changeset viewer.

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