#import #import "RExplorer.h" #include mach_port_t gMasterPort; void callback(CFMachPortRef port, void *msg, CFIndex size, void *info); static void IOREInterestCallback( void * refcon, io_service_t service, natural_t messageType, void * messageArgument ); static void IOREMatchingCallback( void * refcon, io_iterator_t iterator ); @implementation NSDictionary (Compare) - (NSComparisonResult)compareNames:(NSDictionary *)dict2 { return [(NSString *)[self objectForKey:@"name"] caseInsensitiveCompare:(NSString *)[dict2 objectForKey:@"name"]]; } @end @implementation RExplorer static void addChildrenOfPlistToMapsRecursively(id plist, NSMapTable *_parentMap, NSMapTable *_keyMap) { // Adds all the children of the given plist to the map-tables. Does not add the plist itself. if ([plist isKindOfClass:[NSDictionary class]]) { NSEnumerator *keyEnum = [plist keyEnumerator]; NSString *curKey; id curChild; while ((curKey = [keyEnum nextObject]) != nil) { curChild = [plist objectForKey:curKey]; NSMapInsert(_parentMap, curChild, plist); NSMapInsert(_keyMap, curChild, curKey); addChildrenOfPlistToMapsRecursively(curChild, _parentMap, _keyMap); } } else if ([plist isKindOfClass:[NSArray class]]) { unsigned i, c = [plist count]; id curChild; for (i=0; iregistryHasQuieted = messageArgument ? FALSE : TRUE; } static void IOREMatchingCallback( void * refcon, io_iterator_t iterator ) { io_registry_entry_t entry; while ( (entry = IOIteratorNext( iterator )) ) { IOObjectRelease( entry ); } ((RExplorer *)refcon)->registryHasChanged = TRUE; } - (void)checkForUpdate:(NSTimer *)timer { kern_return_t kr; struct { mach_msg_header_t msgHdr; void * content[1024]; } msg; registryHasQuieted = FALSE; do { kr = mach_msg(&msg.msgHdr, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, sizeof(msg), port, 0, MACH_PORT_NULL); if (kr != KERN_SUCCESS) { break; } IODispatchCalloutFromMessage(NULL, &msg.msgHdr, notifyPort); } while ( TRUE ); if (registryHasChanged && registryHasQuieted) { registryHasChanged = FALSE; [self registryHasChanged]; } else if (autoUpdate) [self doUpdate]; return; } // search the dictionaries - (NSArray *)searchResultsForText:(NSString *)text searchKeys:(BOOL)keys searchValues:(BOOL)values { if (!keys && !values) { return [NSArray array]; } if (keys) { NSMutableArray *array = [NSMutableArray arrayWithArray:[self searchKeysResultsInDictionary:registryDict forText:text passedPath:@""]]; // do the root directory stuff here ... NSEnumerator *rootEnum = [[[registryDict objectForKey:@"properties"] allKeys] objectEnumerator]; id aRootEntry = nil; while (aRootEntry = [rootEnum nextObject]) { if ([aRootEntry isEqualToString:@"IOCatalogue"]) { // special case } } return [NSArray arrayWithArray:array]; } return [NSArray array]; } - (NSArray *)searchKeysResultsInDictionary:(NSDictionary *)dict forText:(NSString *)text passedPath:(NSString *)path { NSArray *children = [dict objectForKey:@"children"]; NSEnumerator *kidEnum = [children objectEnumerator]; id aKid = nil; NSMutableArray *array = [NSMutableArray array]; if ([(NSString *)[dict objectForKey:@"name"] length]) { if ([[[dict objectForKey:@"name"] uppercaseString] rangeOfString:[text uppercaseString]].length > 0) { [array addObject:[NSString stringWithFormat:@"%@:%@", path, [dict objectForKey:@"name"]]]; } } while (aKid = [kidEnum nextObject]) { [array addObjectsFromArray:[self searchKeysResultsInDictionary:aKid forText:text passedPath:[NSString stringWithFormat:@"%@:%@", path, [dict objectForKey:@"name"]]]]; } return [[array copy] autorelease]; } - (void)goToPath:(NSString *)path { NSString *newPath = [@":Root" stringByAppendingString:path]; int count = [[path componentsSeparatedByString:@":"] count]; if (count > 2) { count -= 2; } [browser setPath:newPath]; [self changeLevel:browser]; [browser scrollColumnToVisible:count]; return; } - (void)copy:(id)sender { NSString *currentPath = [[browser path] substringFromIndex:5]; [[NSPasteboard generalPasteboard] declareTypes: [NSArray arrayWithObject:NSStringPboardType] owner: [self class]]; [[NSPasteboard generalPasteboard] setString:currentPath forType:NSStringPboardType]; } - (void)updatePrefs:(id)sender { [[NSUserDefaults standardUserDefaults] setInteger:[updatePrefsMatrix selectedRow] forKey:@"UpdatePrefs"]; [[NSUserDefaults standardUserDefaults] synchronize]; } static void LogNSString( NSFileHandle *fileHandle, NSString *string) { char timeStr[16]; time_t t = time(NULL); strftime(timeStr, sizeof(timeStr), "%b %d %I:%M:%S", localtime(&t)); [fileHandle writeData:[[NSString stringWithFormat:@"%s %@\n", timeStr, string] dataUsingEncoding:NSASCIIStringEncoding]]; } -(void)application:(NSApplication *)sender runTest:(unsigned int)testToRun duration:(NSTimeInterval)duration { NSProcessInfo *processInfo = [NSProcessInfo processInfo]; NSString *logFileName = [NSString stringWithFormat:@"%@_%d.selftest.txt", [processInfo processName], [processInfo processIdentifier]]; NSString *logFileDir = [[NSHomeDirectory() stringByAppendingPathComponent:@"Library"] stringByAppendingPathComponent:@"Logs"]; NSString *logFilePath = [logFileDir stringByAppendingPathComponent:logFileName]; [[NSFileManager defaultManager] createDirectoryAtPath:[NSHomeDirectory() stringByAppendingPathComponent:@"Library"] attributes:nil]; [[NSFileManager defaultManager] createDirectoryAtPath:logFileDir attributes:nil]; [[NSFileManager defaultManager] createFileAtPath:logFilePath contents:nil attributes:nil]; NSFileHandle *logFile = [NSFileHandle fileHandleForWritingAtPath:logFilePath]; NSString *initMessage = [NSString stringWithFormat:@"Test:%d duration:%d", testToRun, (int)duration]; LogNSString( logFile, initMessage); NSDate *startTime = [NSDate date]; NSTimeInterval runningTime = 0; int j = 0; // register special defaults for testing ... do { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; LogNSString( logFile, [NSString stringWithFormat:@"Iteration: %d", j + 1]); LogNSString( logFile, @"Message: Start iterating all functions ..."); [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0]]; [self displayAboutWindow:self]; [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0]]; // for updates 20 times int i = 0; for (i=0;i<20;i++) { [self forceUpdate:self]; LogNSString( logFile, [NSString stringWithFormat:@"Output: ...forced update %d.", i+1]); [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; } LogNSString( logFile, [NSString stringWithFormat:@"Message: ...done with iterating all functions."]); runningTime = -[startTime timeIntervalSinceNow]; j++; [pool release]; } while (runningTime <= duration); LogNSString( logFile, [NSString stringWithFormat:@"Message: Test completed in %d seconds", (int)runningTime]); [logFile closeFile]; } - (void)applicationWillFinishLaunching:(NSNotification *)notification { // test self test // [self application:NSApp runTest:0 duration:0]; return; } @end