3 This file is part of the HandBrake source code.
4 Homepage: <http://handbrake.m0k.org/>.
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 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DisableDvdAutoDetect"] == 0)
45 /* Set up a timer to check devices every second */
46 fTimer = [NSTimer scheduledTimerWithTimeInterval: 1.0 target: self
47 selector: @selector( detectTimer: ) userInfo: nil repeats: YES];
48 [[NSRunLoop currentRunLoop] addTimer: fTimer forMode:
49 NSModalPanelRunLoopMode];
51 /* Do a first update right away */
61 - (void) detectTimer: (NSTimer *) timer
63 /* Scan DVD drives (stolen from VLC) */
64 io_object_t next_media;
65 mach_port_t master_port;
66 kern_return_t kern_result;
67 io_iterator_t media_iterator;
68 CFMutableDictionaryRef classes_to_match;
70 kern_result = IOMasterPort( MACH_PORT_NULL, &master_port );
71 if( kern_result != KERN_SUCCESS )
76 classes_to_match = IOServiceMatching( kIODVDMediaClass );
77 if( classes_to_match == NULL )
82 CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectableKey ),
85 kern_result = IOServiceGetMatchingServices( master_port,
86 classes_to_match, &media_iterator );
87 if( kern_result != KERN_SUCCESS )
92 [fDrives removeAllObjects];
94 next_media = IOIteratorNext( media_iterator );
99 size_t dev_path_length;
100 CFTypeRef str_bsd_path;
104 IORegistryEntryCreateCFProperty( next_media,
105 CFSTR( kIOBSDNameKey ),
108 if( str_bsd_path == NULL )
110 IOObjectRelease( next_media );
114 snprintf( psz_buf, sizeof(psz_buf), "%s%c", _PATH_DEV, 'r' );
115 dev_path_length = strlen( psz_buf );
117 if( CFStringGetCString( (CFStringRef) str_bsd_path,
118 (char*)&psz_buf + dev_path_length,
119 sizeof(psz_buf) - dev_path_length,
120 kCFStringEncodingASCII ) )
122 if( ( name = hb_dvd_name( psz_buf ) ) )
124 [fDrives setObject: [NSString stringWithCString: psz_buf]
125 forKey: [NSString stringWithCString: name]];
129 CFRelease( str_bsd_path );
131 IOObjectRelease( next_media );
133 } while( ( next_media = IOIteratorNext( media_iterator ) ) );
136 IOObjectRelease( media_iterator );
138 if( [fDrives count] != fCount )
140 [fTarget performSelector: fSelector withObject: fDrives];
141 fCount = [fDrives count];