Adds a scripts directory to the repository.
[HandBrake.git] / macosx / DriveDetector.m
blob61f7229601123d5d961e41f64bdede887715ee5b
1 /* DriveDetector.m $
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. */
7 #include <paths.h>
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"
14 #include "hb.h"
16 @interface DriveDetector (Private)
18 - (void) detectTimer: (NSTimer *) timer;
20 @end
22 @implementation DriveDetector
24 - (void) dealloc
26     [fDrives release];
27     [super dealloc];
30 - (id) initWithCallback: (id) target selector: (SEL) selector
32     fTarget   = target;
33     fSelector = selector;
34     
35     fCount  = -1;
36     fDrives = [[NSMutableDictionary alloc] initWithCapacity: 1];
37     
38     return self;
41 - (void) run
43     /* Set up a timer to check devices every second */
44     fTimer = [NSTimer scheduledTimerWithTimeInterval: 1.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 */
50     [fTimer fire];
53 - (void) stop
55     [fTimer invalidate];
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 )
69     {
70         return;
71     }
73     classes_to_match = IOServiceMatching( kIODVDMediaClass );
74     if( classes_to_match == NULL )
75     {
76         return;
77     }
79     CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectableKey ),
80                           kCFBooleanTrue );
82     kern_result = IOServiceGetMatchingServices( master_port,
83             classes_to_match, &media_iterator );
84     if( kern_result != KERN_SUCCESS )
85     {
86         return;
87     }
89     [fDrives removeAllObjects];
91     next_media = IOIteratorNext( media_iterator );
92     if( next_media )
93     {
94         char * name;
95         char psz_buf[0x32];
96         size_t dev_path_length;
97         CFTypeRef str_bsd_path;
98         do
99         {
100             str_bsd_path =
101                 IORegistryEntryCreateCFProperty( next_media,
102                                                  CFSTR( kIOBSDNameKey ),
103                                                  kCFAllocatorDefault,
104                                                  0 );
105             if( str_bsd_path == NULL )
106             {
107                 IOObjectRelease( next_media );
108                 continue;
109             }
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 ) )
118             {
119                 if( ( name = hb_dvd_name( psz_buf ) ) )
120                 {
121                     [fDrives setObject: [NSString stringWithCString: psz_buf]
122                         forKey: [NSString stringWithCString: name]];
123                 }
124             }
126             CFRelease( str_bsd_path );
128             IOObjectRelease( next_media );
130         } while( ( next_media = IOIteratorNext( media_iterator ) ) );
131     }
133     IOObjectRelease( media_iterator );
135     if( [fDrives count] != fCount )
136     {
137         [fTarget performSelector: fSelector withObject: fDrives];
138         fCount = [fDrives count];
139     }
142 @end