/* DriveDetector.m $
This file is part of the HandBrake source code.
Homepage: .
It may be used under the terms of the GNU General Public License. */
#include
#include
#include
#include
#include
#include "DriveDetector.h"
#include "hb.h"
@interface DriveDetector (Private)
- (void) detectTimer: (NSTimer *) timer;
@end
@implementation DriveDetector
- (void) dealloc
{
[fDrives release];
[super dealloc];
}
- (id) initWithCallback: (id) target selector: (SEL) selector
{
fTarget = target;
fSelector = selector;
fCount = -1;
fDrives = [[NSMutableDictionary alloc] initWithCapacity: 1];
return self;
}
- (void) run
{
/* Set up a timer to check devices every second */
fTimer = [NSTimer scheduledTimerWithTimeInterval: 2.0 target: self
selector: @selector( detectTimer: ) userInfo: nil repeats: YES];
[[NSRunLoop currentRunLoop] addTimer: fTimer forMode:
NSModalPanelRunLoopMode];
/* Do a first update right away */
[fTimer fire];
}
- (void) stop
{
[fTimer invalidate];
}
- (void) detectTimer: (NSTimer *) timer
{
/* Scan DVD drives (stolen from VLC) */
io_object_t next_media;
mach_port_t master_port;
kern_return_t kern_result;
io_iterator_t media_iterator;
CFMutableDictionaryRef classes_to_match;
kern_result = IOMasterPort( MACH_PORT_NULL, &master_port );
if( kern_result != KERN_SUCCESS )
{
return;
}
classes_to_match = IOServiceMatching( kIODVDMediaClass );
if( classes_to_match == NULL )
{
return;
}
CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectableKey ),
kCFBooleanTrue );
kern_result = IOServiceGetMatchingServices( master_port,
classes_to_match, &media_iterator );
if( kern_result != KERN_SUCCESS )
{
return;
}
[fDrives removeAllObjects];
next_media = IOIteratorNext( media_iterator );
if( next_media )
{
char * name;
char psz_buf[0x32];
size_t dev_path_length;
CFTypeRef str_bsd_path;
do
{
str_bsd_path =
IORegistryEntryCreateCFProperty( next_media,
CFSTR( kIOBSDNameKey ),
kCFAllocatorDefault,
0 );
if( str_bsd_path == NULL )
{
IOObjectRelease( next_media );
continue;
}
snprintf( psz_buf, sizeof(psz_buf), "%s%c", _PATH_DEV, 'r' );
dev_path_length = strlen( psz_buf );
if( CFStringGetCString( (CFStringRef) str_bsd_path,
(char*)&psz_buf + dev_path_length,
sizeof(psz_buf) - dev_path_length,
kCFStringEncodingASCII ) )
{
if( ( name = hb_dvd_name( psz_buf ) ) )
{
[fDrives setObject: [NSString stringWithCString: psz_buf]
forKey: [NSString stringWithCString: name]];
}
}
CFRelease( str_bsd_path );
IOObjectRelease( next_media );
} while( ( next_media = IOIteratorNext( media_iterator ) ) );
}
IOObjectRelease( media_iterator );
if( [fDrives count] != fCount )
{
[fTarget performSelector: fSelector withObject: fDrives];
fCount = [fDrives count];
}
}
@end