#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <limits.h>
#include <mach/mach_interface.h>
#include <IOKit/IOKitLib.h>
#include <CoreFoundation/CFRunLoop.h>
mach_port_t masterPort;
mach_port_t notifyPort;
CFRunLoopSourceRef cfSource;
void ServiceInterestCallback(void * refcon, io_service_t service,
natural_t messageType, void * messageArgument )
{
io_name_t name;
assert( refcon == (void *) masterPort );
if( KERN_SUCCESS == IORegistryEntryGetName( service, name ))
printf(name);
else
printf("???");
printf(": messageType %08lx, arg %08lx\n",
messageType, messageArgument);
}
void ServiceArrivalCallback( void * refcon, io_iterator_t iter )
{
kern_return_t kr;
io_object_t obj;
io_name_t name;
io_string_t path;
mach_port_t note;
CFDictionaryRef dict;
IONotificationPortRef notify = (IONotificationPortRef) refcon;
while( (obj = IOIteratorNext( iter))) {
assert( KERN_SUCCESS == (
kr = IORegistryEntryGetName( obj, name )
));
printf("name:%s(%d)\n", name, obj);
dict = IOCreateDisplayInfoDictionary( obj, kNilOptions );
if( dict) {
CFShow( dict );
CFRelease( dict );
}
kr = IORegistryEntryGetPath( obj, kIOServicePlane, path );
if( KERN_SUCCESS == kr) {
printf("path:%s\n", path);
if( KERN_SUCCESS != (
kr = IOServiceAddInterestNotification(
notify,
obj, kIOGeneralInterest,
&ServiceInterestCallback, (void *) masterPort,
¬e )
)) printf("IOServiceAddInterestNotification(%lx)\n", kr);
IOObjectRelease( obj );
}
}
}
void notifyTest( char * arg )
{
kern_return_t kr;
io_iterator_t note1, note2;
io_service_t obj;
const char * type;
IONotificationPortRef notify;
assert( 0 != (
notify = IONotificationPortCreate( masterPort )
));
type = kIOMatchedNotification; assert( KERN_SUCCESS == (
kr = IOServiceAddMatchingNotification(
notify,
type,
IOServiceMatching( arg ),
&ServiceArrivalCallback, (void *) notify,
¬e1 )
));
printf("IOServiceAddMatchingNotification: %s: ", type );
ServiceArrivalCallback ( (void *) notify, note1 );
printf("\n");
type = kIOBusyInterest;
obj = IORegistryEntryFromPath( masterPort, kIOServicePlane ":/");
assert( obj );
assert( KERN_SUCCESS == (
kr = IOServiceAddInterestNotification(
notify,
obj, type,
&ServiceInterestCallback, (void *) masterPort,
¬e2 )
));
CFRunLoopAddSource(CFRunLoopGetCurrent(),
IONotificationPortGetRunLoopSource(notify),
kCFRunLoopDefaultMode);
printf("waiting...\n");
CFRunLoopRun();
IOObjectRelease( note1 );
IOObjectRelease( note2 );
}
int
main(int argc, char **argv)
{
kern_return_t kr;
assert( KERN_SUCCESS == (
kr = IOMasterPort( bootstrap_port,
&masterPort)
));
if( argc > 1)
notifyTest( argv[1] );
else
printf("%s className\n", argv[0]);
printf("Exit\n");
}