1/* 2 * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24// 25// xiodevices - additional code for finding and tracking devices via IOKit 26// >>> move this iodevices.cpp when final 27// 28#include "xiodevices.h" 29#include <security_utilities/cfutilities.h> 30#include <security_utilities/mach++.h> 31#include <IOKit/IOMessage.h> 32#include <IOKit/usb/IOUSBLib.h> 33 34using namespace MachPlusPlus; 35 36namespace Security { 37namespace IOKit { 38 39void XNotificationPort::add(DeviceMatch match, XReceiver &receiver, const char *type) 40{ 41 // The kIOProviderClassKey key is required in a matching dictionary. We extract it 42 // here only for debugging purposes 43 44 CFTypeRef valueRef = NULL; 45 const char *pclass = ""; 46 CFRef<CFMutableDictionaryRef> theDict = match.dict(); 47 if (theDict && CFDictionaryGetValueIfPresent(theDict, CFSTR(kIOProviderClassKey), &valueRef) && 48 CFGetTypeID(valueRef) == CFStringGetTypeID()) 49 pclass = cfString(static_cast<CFStringRef>(valueRef)).c_str(); 50 51 // type is usually IOServiceMatched 52 mach_port_t pp = NotificationPort::port(); 53 secdebug("iokit", "XNotificationPort::add - type: %s [port: %p (0x%08X), class: %s]", 54 type, mPortRef, pp, pclass); 55 56// CFShow(match.dict()); 57 // p (void)CFShow(match.dict()) 58 io_iterator_t iterator; 59 Error::check(::IOServiceAddMatchingNotification(mPortRef, type, 60 match, ioNotify, &receiver, &iterator)); 61 CFRetain(match); // compensate for IOSAMN not retaining its argument 62 63 // run initial iterator to process existing devices 64 secdebug("iokit", "dispatching INITIAL device match iterator %p", reinterpret_cast<void *>(iterator)); 65 DeviceIterator it(iterator); 66 receiver.ioChange(it); 67} 68 69void XNotificationPort::addInterestNotification(XReceiver &receiver, io_service_t service, 70 const io_name_t interestType) 71{ 72 io_iterator_t iterator; 73 mach_port_t pp = NotificationPort::port(); 74// MachPlusPlus::Port(pp).dump(0); 75 secdebug("iokit", "XNotificationPort::addInterest - type: %s [port: %p (0x%08X), service: 0x%08X]", 76 interestType, mPortRef, pp, service); // IOServiceMatched 77#if 1 78 CFRunLoopSourceRef notificationRunLoopSource = IONotificationPortGetRunLoopSource(mPortRef); 79 CFRunLoopSourceRef classRunLoopSource = NotificationPort::source(); 80// IONotificationPortRef r_notify_port = IONotificationPortCreate(0); 81 kern_return_t kr = ::IOServiceAddInterestNotification(mPortRef, //,r_notify_port 82 service, interestType, ioDeviceNotification, &receiver, &iterator); 83 const char *msgstr = mach_error_string(kr); 84 const char *msgtyp = mach_error_type(kr); 85 if (msgstr && msgtyp) 86 secdebug("iokit", " msg: %s, typ: %s", msgstr, msgtyp); 87// Error::check(kr); 88// if(r_notify_port) IOObjectRelease((io_object_t)r_notify_port); 89#else 90 Error::check(::IOServiceAddInterestNotification(mPortRef, 91 service, interestType, ioDeviceNotification, &receiver, &iterator)); 92#endif 93} 94 95// callbacks 96 97void XNotificationPort::ioNotify(void *refCon, io_iterator_t iterator) 98{ 99 secdebug("iokit", "dispatching NEW device match iterator %p", reinterpret_cast<void *>(iterator)); 100 DeviceIterator it(iterator); 101 reinterpret_cast<XReceiver *>(refCon)->ioChange(it); 102} 103 104void XNotificationPort::ioDeviceNotification(void *refCon, io_service_t service, 105 natural_t messageType, void *messageArgument) 106{ 107 secdebug("iokit", "dispatching NEW device notification iterator, service 0x%08X, msg: 0x%04X, arg: %p", 108 service, messageType, messageArgument); 109 110 const char *msgstr = mach_error_string(messageType); 111 const char *msgtyp = mach_error_type(messageType); 112 if (msgstr && msgtyp) 113 secdebug("iokit", " msg: %s, typ: %s", msgstr, msgtyp); 114 115#if 0 116 secdebug("iokit", "kIOMessageServiceIsTerminated: 0x%04X", kIOMessageServiceIsTerminated); 117 secdebug("iokit", "kIOMessageServiceIsSuspended: 0x%04X", kIOMessageServiceIsSuspended); 118 secdebug("iokit", "kIOMessageServiceIsResumed: 0x%04X", kIOMessageServiceIsResumed); 119 secdebug("iokit", "kIOMessageServiceIsRequestingClose: 0x%04X", kIOMessageServiceIsRequestingClose); 120 secdebug("iokit", "kIOMessageServiceIsAttemptingOpen: 0x%04X", kIOMessageServiceIsAttemptingOpen); 121 secdebug("iokit", "kIOMessageServiceWasClosed: 0x%04X", kIOMessageServiceWasClosed); 122 secdebug("iokit", "kIOMessageServiceBusyStateChange: 0x%04X", kIOMessageServiceBusyStateChange); 123 secdebug("iokit", "kIOMessageServicePropertyChange: 0x%04X", kIOMessageServicePropertyChange); 124 secdebug("iokit", "kIOMessageCanDevicePowerOff: 0x%04X", kIOMessageCanDevicePowerOff); 125 secdebug("iokit", "kIOMessageDeviceWillPowerOff: 0x%04X", kIOMessageDeviceWillPowerOff); 126 secdebug("iokit", "kIOMessageDeviceWillNotPowerOff: 0x%04X", kIOMessageDeviceWillNotPowerOff); 127 secdebug("iokit", "kIOMessageDeviceHasPoweredOn: 0x%04X", kIOMessageDeviceHasPoweredOn); 128 secdebug("iokit", "kIOMessageCanSystemPowerOff: 0x%04X", kIOMessageCanSystemPowerOff); 129 secdebug("iokit", "iokit_vendor_specific_msg(0x000A): 0x%04X", iokit_vendor_specific_msg(0x000A)); 130#endif 131 132// assert(service!=io_service_t(-1)); 133 if (service!=io_service_t(-1)) 134 reinterpret_cast<XReceiver *>(refCon)->ioServiceChange(refCon, service, messageType, messageArgument); 135} 136 137 138} // end namespace IOKit 139} // end namespace Security 140 141 142