3 This file is part of the HandBrake source code.
4 Homepage: <http://handbrake.fr/>.
5 It may be used under the terms of the GNU General Public License. */
8 #include <IOKit/IOKitLib.h>
9 #include <IOKit/IOBSD.h>
10 #include <IOKit/storage/IOMedia.h>
11 #include <IOKit/storage/IODVDMedia.h>
13 #include "DriveDetector.h"
16 @interface DriveDetector (Private)
18 - (void) detectTimer: (NSTimer *) timer;
22 @implementation DriveDetector
30 - (id) initWithCallback: (id) target selector: (SEL) selector
36 fDrives = [[NSMutableDictionary alloc] initWithCapacity: 1];
43 /* Set up a timer to check devices every second */
44 fTimer = [NSTimer scheduledTimerWithTimeInterval: 2.0 target: self
45 selector: @selector( detectTimer: ) userInfo: nil repeats: YES];
46 [[NSRunLoop currentRunLoop] addTimer: fTimer forMode:
47 NSModalPanelRunLoopMode];
49 /* Do a first update right away */
58 - (void) detectTimer: (NSTimer *) timer
60 /* Scan DVD drives (stolen from VLC) */
61 io_object_t next_media;
62 mach_port_t master_port;
63 kern_return_t kern_result;
64 io_iterator_t media_iterator;
65 CFMutableDictionaryRef classes_to_match;
67 kern_result = IOMasterPort( MACH_PORT_NULL, &master_port );
68 if( kern_result != KERN_SUCCESS )
73 classes_to_match = IOServiceMatching( kIODVDMediaClass );
74 if( classes_to_match == NULL )
79 CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectableKey ),
82 kern_result = IOServiceGetMatchingServices( master_port,
83 classes_to_match, &media_iterator );
84 if( kern_result != KERN_SUCCESS )
89 [fDrives removeAllObjects];
91 next_media = IOIteratorNext( media_iterator );
96 size_t dev_path_length;
97 CFTypeRef str_bsd_path;
101 IORegistryEntryCreateCFProperty( next_media,
102 CFSTR( kIOBSDNameKey ),
105 if( str_bsd_path == NULL )
107 IOObjectRelease( next_media );
111 snprintf( psz_buf, sizeof(psz_buf), "%s%c", _PATH_DEV, 'r' );
112 dev_path_length = strlen( psz_buf );
114 if( CFStringGetCString( (CFStringRef) str_bsd_path,
115 (char*)&psz_buf + dev_path_length,
116 sizeof(psz_buf) - dev_path_length,
117 kCFStringEncodingASCII ) )
119 if( ( name = hb_dvd_name( psz_buf ) ) )
121 [fDrives setObject: [NSString stringWithCString: psz_buf]
122 forKey: [NSString stringWithCString: name]];
126 CFRelease( str_bsd_path );
128 IOObjectRelease( next_media );
130 } while( ( next_media = IOIteratorNext( media_iterator ) ) );
133 IOObjectRelease( media_iterator );
135 if( [fDrives count] != fCount )
137 [fTarget performSelector: fSelector withObject: fDrives];
138 fCount = [fDrives count];