#include "xiodevices.h"
#include <security_utilities/cfutilities.h>
#include <security_utilities/mach++.h>
#include <IOKit/IOMessage.h>
#include <IOKit/usb/IOUSBLib.h>
using namespace MachPlusPlus;
namespace Security {
namespace IOKit {
void XNotificationPort::add(DeviceMatch match, XReceiver &receiver, const char *type)
{
CFTypeRef valueRef = NULL;
const char *pclass = "";
CFRef<CFMutableDictionaryRef> theDict = match.dict();
if (theDict && CFDictionaryGetValueIfPresent(theDict, CFSTR(kIOProviderClassKey), &valueRef) &&
CFGetTypeID(valueRef) == CFStringGetTypeID())
pclass = cfString(static_cast<CFStringRef>(valueRef)).c_str();
mach_port_t pp = NotificationPort::port();
secdebug("iokit", "XNotificationPort::add - type: %s [port: %p (0x%08X), class: %s]",
type, mPortRef, pp, pclass);
io_iterator_t iterator;
Error::check(::IOServiceAddMatchingNotification(mPortRef, type,
match, ioNotify, &receiver, &iterator));
CFRetain(match);
secdebug("iokit", "dispatching INITIAL device match iterator %p", reinterpret_cast<void *>(iterator));
DeviceIterator it(iterator);
receiver.ioChange(it);
}
void XNotificationPort::addInterestNotification(XReceiver &receiver, io_service_t service,
const io_name_t interestType)
{
io_iterator_t iterator;
mach_port_t pp = NotificationPort::port();
secdebug("iokit", "XNotificationPort::addInterest - type: %s [port: %p (0x%08X), service: 0x%08X]",
interestType, mPortRef, pp, service); #if 1
CFRunLoopSourceRef notificationRunLoopSource = IONotificationPortGetRunLoopSource(mPortRef);
CFRunLoopSourceRef classRunLoopSource = NotificationPort::source();
kern_return_t kr = ::IOServiceAddInterestNotification(mPortRef, service, interestType, ioDeviceNotification, &receiver, &iterator);
const char *msgstr = mach_error_string(kr);
const char *msgtyp = mach_error_type(kr);
if (msgstr && msgtyp)
secdebug("iokit", " msg: %s, typ: %s", msgstr, msgtyp);
#else
Error::check(::IOServiceAddInterestNotification(mPortRef,
service, interestType, ioDeviceNotification, &receiver, &iterator));
#endif
}
void XNotificationPort::ioNotify(void *refCon, io_iterator_t iterator)
{
secdebug("iokit", "dispatching NEW device match iterator %p", reinterpret_cast<void *>(iterator));
DeviceIterator it(iterator);
reinterpret_cast<XReceiver *>(refCon)->ioChange(it);
}
void XNotificationPort::ioDeviceNotification(void *refCon, io_service_t service,
natural_t messageType, void *messageArgument)
{
secdebug("iokit", "dispatching NEW device notification iterator, service 0x%08X, msg: 0x%04X, arg: %p",
service, messageType, messageArgument);
const char *msgstr = mach_error_string(messageType);
const char *msgtyp = mach_error_type(messageType);
if (msgstr && msgtyp)
secdebug("iokit", " msg: %s, typ: %s", msgstr, msgtyp);
#if 0
secdebug("iokit", "kIOMessageServiceIsTerminated: 0x%04X", kIOMessageServiceIsTerminated);
secdebug("iokit", "kIOMessageServiceIsSuspended: 0x%04X", kIOMessageServiceIsSuspended);
secdebug("iokit", "kIOMessageServiceIsResumed: 0x%04X", kIOMessageServiceIsResumed);
secdebug("iokit", "kIOMessageServiceIsRequestingClose: 0x%04X", kIOMessageServiceIsRequestingClose);
secdebug("iokit", "kIOMessageServiceIsAttemptingOpen: 0x%04X", kIOMessageServiceIsAttemptingOpen);
secdebug("iokit", "kIOMessageServiceWasClosed: 0x%04X", kIOMessageServiceWasClosed);
secdebug("iokit", "kIOMessageServiceBusyStateChange: 0x%04X", kIOMessageServiceBusyStateChange);
secdebug("iokit", "kIOMessageServicePropertyChange: 0x%04X", kIOMessageServicePropertyChange);
secdebug("iokit", "kIOMessageCanDevicePowerOff: 0x%04X", kIOMessageCanDevicePowerOff);
secdebug("iokit", "kIOMessageDeviceWillPowerOff: 0x%04X", kIOMessageDeviceWillPowerOff);
secdebug("iokit", "kIOMessageDeviceWillNotPowerOff: 0x%04X", kIOMessageDeviceWillNotPowerOff);
secdebug("iokit", "kIOMessageDeviceHasPoweredOn: 0x%04X", kIOMessageDeviceHasPoweredOn);
secdebug("iokit", "kIOMessageCanSystemPowerOff: 0x%04X", kIOMessageCanSystemPowerOff);
secdebug("iokit", "iokit_vendor_specific_msg(0x000A): 0x%04X", iokit_vendor_specific_msg(0x000A));
#endif
if (service!=io_service_t(-1))
reinterpret_cast<XReceiver *>(refCon)->ioServiceChange(refCon, service, messageType, messageArgument);
}
} }