iodisplayregistry.c [plain text]
#include <assert.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOCFSerialize.h>
static mach_port_t masterPort;
static void indent(Boolean node, int depth, UInt64 stackOfBits);
static void properties(io_registry_entry_t service,
int depth,
UInt64 stackOfBits);
static void traverse(unsigned int options,
io_name_t plane, io_iterator_t services,
io_registry_entry_t first,
int depth, UInt64 stackOfBits);
enum {
kDoPropsOption = 1,
kDoRootOption = 2
};
int main(int argc, char **argv)
{
io_registry_entry_t root;
char * plane;
unsigned int options;
kern_return_t status; int arg;
plane = kIOServicePlane;
options = kDoPropsOption;
for(arg = 1; arg < argc; arg++)
{
if ('-' == argv[arg][0]) switch(argv[arg][1])
{
case 'h':
printf("%s [-p] [-r] [-h] [plane]\n", argv[0]);
exit(0);
break;
case 'p':
options &= ~kDoPropsOption;
break;
case 'r':
options |= kDoRootOption;
break;
}
else
{
plane = argv[arg];
}
}
status = IOMasterPort(bootstrap_port, &masterPort);
assert(status == KERN_SUCCESS);
root = IORegistryGetRootEntry(masterPort);
assert(root);
traverse(options, plane, 0, root, 0, 0);
exit(0);
}
void traverse(unsigned int options,
io_name_t plane, io_iterator_t services,
io_registry_entry_t serviceUpNext,
int depth, UInt64 stackOfBits)
{
io_registry_entry_t service; Boolean doProps;
while ( (service = serviceUpNext) )
{
io_iterator_t children;
Boolean hasChildren;
io_name_t name;
kern_return_t status;
io_registry_entry_t child;
int busy;
serviceUpNext = IOIteratorNext(services);
status = IORegistryEntryGetChildIterator(service,
plane,
&children);
assert(status == KERN_SUCCESS);
child = IOIteratorNext(children); hasChildren = child ? true : false;
if (serviceUpNext)
stackOfBits |= (1 << depth);
else
stackOfBits &= ~(1 << depth);
if (hasChildren)
stackOfBits |= (2 << depth);
else
stackOfBits &= ~(2 << depth);
indent(true, depth, stackOfBits);
status = IORegistryEntryGetName(service, name);
assert(status == KERN_SUCCESS);
printf("%s", name);
if (strcmp("Root", name))
doProps = (options & kDoPropsOption) != 0;
else
doProps = (options & kDoRootOption) != 0;
status = IOObjectGetClass(service, name);
assert(status == KERN_SUCCESS);
printf(" <class %s", name);
status = IOServiceGetBusyState(service, &busy);
if(status == KERN_SUCCESS)
printf(", busy %d", busy);
printf(", retain count %d>\n", IOObjectGetRetainCount(service));
if (doProps)
properties(service, depth, stackOfBits);
traverse(options, plane, children, child, depth + 1, stackOfBits);
IOObjectRelease(children); children = 0;
IOObjectRelease(service); service = 0;
}
}
struct indent_ctxt {
int depth;
UInt64 stackOfBits;
};
static void printCFString(CFStringRef string)
{
CFIndex len;
char * buffer;
len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(string),
CFStringGetSystemEncoding()) + sizeof('\0');
buffer = malloc(len);
if (buffer && CFStringGetCString(string, buffer, len,
CFStringGetSystemEncoding()) )
printf(buffer);
if (buffer)
free(buffer);
}
static void printEntry(const void *key, const void *value, void *context)
{
struct indent_ctxt * ctxt = context;
#if 1
CFDataRef data;
indent(false, ctxt->depth, ctxt->stackOfBits);
printf(" ");
printCFString( (CFStringRef)key );
printf(" = ");
data = IOCFSerialize((CFStringRef)value, kNilOptions);
if( data) {
if( 10000 > CFDataGetLength(data))
printf(CFDataGetBytePtr(data));
else
printf("<is BIG>");
CFRelease(data);
} else
printf("<IOCFSerialize failed>");
printf("\n");
#else
CFStringRef keyStr = (CFStringRef) key;
CFStringRef valueStr = CFCopyDescription((CFTypeRef) val);
CFStringRef outStr;
indent(false, ctxt->depth, ctxt->stackOfBits);
outStr = CFStringCreateWithFormat(kCFAllocatorDefault, 0,
CFSTR(" %@ = %@\n"), keyStr, valueStr);
assert(outStr);
printCFString(outStr);
CFRelease(valueStr);
CFRelease(outStr);
#endif
}
static void properties(io_registry_entry_t service,
int depth,
UInt64 stackOfBits)
{
CFDictionaryRef dictionary; kern_return_t status; struct indent_ctxt context;
context.depth = depth;
context.stackOfBits = stackOfBits;
indent(false, context.depth, context.stackOfBits);
printf("{\n");
status = IORegistryEntryCreateCFProperties(service,
(CFTypeRef *) &dictionary,
kCFAllocatorDefault, kNilOptions);
assert( KERN_SUCCESS == status );
assert( CFDictionaryGetTypeID() == CFGetTypeID(dictionary));
CFDictionaryApplyFunction(dictionary,
(CFDictionaryApplierFunction) printEntry, &context);
CFRelease(dictionary);
indent(false, context.depth, context.stackOfBits);
printf("}\n");
indent(false, context.depth, context.stackOfBits);
printf("\n");
}
void indent(Boolean node, int depth, UInt64 stackOfBits)
{
int i;
if (node)
{
for (i = 0; i < depth; i++)
printf( (stackOfBits & (1 << i)) ? "| " : " " );
printf("+-o ");
}
else {
for (i = 0; i <= depth + 1; i++)
printf( (stackOfBits & (1 << i)) ? "| " : " " );
}
}