/* File: kextlist.m Version: 1.2 Author: Damien Bobillot (damien.bobillot.2002_kextlist@m4x.org) Licence: GNU GPL Compatibility: Mac OS X 10.3 (may work on MacOS X 10.0) Tool for listing all installed kernel extensions. 11/09/2004 - 1.0 - First version 05/08/2005 - 1.1 - Add support for kernel extension without "Contents" folder 05/11/2006 - 1.2 - Compiled as Universal Binary */ #include void printKextInfo(NSString* path, unsigned depth, BOOL hasContents); void processDirectory(NSString* path, unsigned depth); int main (int argc, const char * argv[]) { NSAutoreleasePool* _pool = [NSAutoreleasePool new]; processDirectory(@"/System/Library/Extensions", 0); [_pool release]; return 0; } void processDirectory(NSString* path, unsigned depth) { NSDirectoryEnumerator* direnum = [[NSFileManager defaultManager] enumeratorAtPath:path]; NSString* element; while((element = [direnum nextObject]) != nil) { [direnum skipDescendents]; if(![[element pathExtension] isEqualToString:@"kext"]) continue; NSString* kextPath = [path stringByAppendingPathComponent:element]; BOOL isDirectory; BOOL hasContents = [[NSFileManager defaultManager] fileExistsAtPath:[kextPath stringByAppendingPathComponent:@"Contents"] isDirectory:&isDirectory] && isDirectory; printKextInfo(kextPath, depth, hasContents); processDirectory([kextPath stringByAppendingPathComponent:hasContents ? @"Contents/PlugIns" : @"PlugIns"], depth + 1); } } void printKextInfo(NSString* path, unsigned depth, BOOL hasContents) { // Indentation char* indent = depth>0?depth>1?depth>2?"\t\t\t":"\t\t":"\t":""; // Read the Info.plist file NSPropertyListFormat format; NSData* plistData = [NSData dataWithContentsOfFile:[path stringByAppendingPathComponent:hasContents ? @"Contents/Info.plist" : @"Info.plist"]]; if(!plistData) { fprintf(stderr,"### %s : cannot open Info.plist\n",[[path lastPathComponent] UTF8String]); return; } NSString *error; NSDictionary* plist = [NSPropertyListSerialization propertyListFromData:plistData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error]; if(!plist) { fprintf(stderr,"### %s : %s\n",[[path lastPathComponent] UTF8String],[error UTF8String]); [error release]; return; } // Print file information fprintf(stdout,"%s%s\t(%s)\n",indent,[[path lastPathComponent] UTF8String],[[plist objectForKey:@"CFBundleIdentifier"] UTF8String]); // Read information NSDictionary* kextdict = [plist objectForKey:@"IOKitPersonalities"]; NSArray* kextnames = [kextdict allKeys]; int i; for( i=0; i<[kextnames count]; i++ ) { NSString* kextname = [kextnames objectAtIndex:i]; NSDictionary* kext = [kextdict objectForKey:kextname]; NSString* kextClass = [kext objectForKey:@"IOClass"]; NSString* kextProvider = [kext objectForKey:@"IOProviderClass"]; printf("%s\t•%s\t(%s : %s)\n",indent,[kextname UTF8String],[kextClass UTF8String],[kextProvider UTF8String]); } }