3 --- /dev/null 2006-09-03 09:28:05.000000000 -0700
4 +++ interface/osx_interface.c 2006-09-03 09:35:39.000000000 -0700
6 +/******************************************************************
7 + * CopyPolicy: GNU Public License 2 applies
8 + * Copyright (C) 1998 Monty xiphmont@mit.edu
9 + ******************************************************************/
16 +#include <sys/syslimits.h>
18 +#include "osx_interface.h"
21 +char *osx_bsd_device_for_media(io_object_t media)
24 + size_t dev_path_length;
25 + CFTypeRef str_bsd_path;
28 + str_bsd_path = IORegistryEntryCreateCFProperty(media,
29 + CFSTR(kIOBSDNameKey), kCFAllocatorDefault, 0);
31 + if(str_bsd_path == NULL) {
35 + snprintf(buf, sizeof(buf), "%s%c", _PATH_DEV, 'r' );
36 + dev_path_length = strlen(buf);
38 + if (CFStringGetCString(str_bsd_path,
39 + buf + dev_path_length,
40 + sizeof(buf) - dev_path_length,
41 + kCFStringEncodingASCII)) {
42 + result = strdup(buf);
46 + CFRelease(str_bsd_path);
50 +int osx_enumerate_devices(cdrom_drive *d,
51 + int (*device_found)(cdrom_drive *, io_object_t, void *),
57 + CFMutableDictionaryRef classes_to_match;
58 + kern_return_t kern_result;
59 + io_iterator_t media_iterator;
60 + io_object_t next_media;
62 + /* get port for IOKit communication */
63 + if ((ret = IOMasterPort(MACH_PORT_NULL, &port)) != KERN_SUCCESS) {
64 + cderror(d,"099: IOMasterPort fail\n");
68 + classes_to_match = IOServiceMatching(kIOCDMediaClass);
69 + if(classes_to_match == NULL) {
70 + cderror(d,"099: IOServiceMatching: NULL\n");
74 + CFDictionarySetValue(classes_to_match, CFSTR(kIOMediaEjectableKey),
77 + kern_result = IOServiceGetMatchingServices(port, classes_to_match,
79 + if (kern_result != KERN_SUCCESS) {
80 + cderror(d,"099: IOServiceGetMatchingServices fail\n");
86 + next_media = IOIteratorNext(media_iterator);
87 + if (next_media == 0) {
91 + if (!device_found(d, next_media, data))
93 + IOObjectRelease(next_media);
95 + if (next_media) IOObjectRelease(next_media);
96 + IOObjectRelease(media_iterator);
101 +static int find_first_device(cdrom_drive *d, io_object_t io, void *data)
103 + io_object_t *dev = (io_object_t *)data;
105 + IOObjectRetain(io);
109 +io_object_t osx_default_device(cdrom_drive *d)
112 + osx_enumerate_devices(d, find_first_device, (void *)&io);
116 +int osx_read_toc(cdrom_drive *d)
123 + CFMutableDictionaryRef properties;
127 + devname = strrchr(d->dev, '/');
129 + if (devname != NULL) {
135 + if (*devname == 'r') devname++;
137 + /* create a CF dictionary containing the TOC */
138 + ret = IORegistryEntryCreateCFProperties(d->io, &properties,
139 + kCFAllocatorDefault, kNilOptions);
141 + if( ret != KERN_SUCCESS) {
142 + cderror(d, "099: IORegistryEntryCreateCFProperties fail\n");
146 + /* get the TOC from the dictionary */
147 + data = (CFDataRef)CFDictionaryGetValue(properties,
148 + CFSTR(kIOCDMediaTOCKey));
150 + cderror(d, "099: CFDictionaryGetValue fail\n");
154 + buf_len = CFDataGetLength(data) + 1;
155 + range = CFRangeMake(0, buf_len);
157 + d->raw_toc = (CDTOC *)malloc(buf_len);
158 + if (d->raw_toc == NULL) {
159 + cderror(d, "099: toc malloc fail\n");
160 + CFRelease(properties);
163 + CFDataGetBytes(data, range, (u_char *)d->raw_toc);
165 + CFRelease(properties);
167 + d->descriptor_count = CDTOCGetDescriptorCount(d->raw_toc);
170 + for (i = 0; i < d->descriptor_count; i++) {
171 + int track_num = d->raw_toc->descriptors[i].point;
172 + CDMSF msf = d->raw_toc->descriptors[i].p;
173 + int start_sector = CDConvertMSFToLBA(msf);
174 + if (track_num == 0xa2) {
178 + "track_num = %d start sector %d msf: %d,%d,%d\n",
179 + track_num, start_sector,
180 + msf.minute, msf.second, msf.frame);
181 + if (track_num > 99 || track_num < 1) {
183 + // track_num = 160 start sector 4350 msf: 1,0,0
184 + // track_num = 161 start sector 67350 msf: 15,0,0
185 + // track_num = 162 start sector 330645 msf: 73,30,45
188 + // XXX don't know what happens here. tracks 0xa0, 0xa1, 0xa2 (leadout)
190 + d->disc_toc[d->tracks].bTrack = track_num;
191 + d->disc_toc[d->tracks].bFlags = (d->raw_toc->descriptors[i].adr << 4) |
192 + d->raw_toc->descriptors[i].control;
193 + d->disc_toc[d->tracks].dwStartSector = start_sector;
196 + d->disc_toc[d->tracks].bTrack = 0xaa;
197 + d->disc_toc[d->tracks].bFlags = (d->raw_toc->descriptors[i].adr << 4) |
198 + d->raw_toc->descriptors[leadout].control;
199 + d->disc_toc[d->tracks].dwStartSector = CDConvertMSFToLBA(
200 + d->raw_toc->descriptors[leadout].p);
205 +int osx_open_device_orig(cdrom_drive *d, io_object_t io)
208 + d->io = osx_default_device(d);
210 + IOObjectRetain(io);
213 + d->dev = osx_bsd_device_for_media(d->io);
215 + IOObjectRelease(d->io);
219 + d->fd = open(d->dev, O_RDONLY | O_NONBLOCK, 0);
220 + d->enable_cdda = osx_enable_cdda;
221 + d->read_toc = osx_read_toc;
222 + d->read_audio = osx_read_audio;
223 + d->set_speed = osx_set_speed;
227 + IOObjectRelease(d->io);
238 +int osx_open_device(cdrom_drive *d)
240 + osx_open_device_orig(d, NULL);
243 +int osx_set_speed(cdrom_drive *d, int speed)
248 +int osx_enable_cdda(cdrom_drive *d, int enable)
253 +long osx_read_audio(cdrom_drive *d, void *buf, long begin, long sectors)
255 + dk_cd_read_t cd_read;
257 + // fprintf(stderr, "read_audio %p, %d, %d\n", buf, begin, sectors);
259 + memset(&cd_read, 0, sizeof(cd_read));
261 + cd_read.offset = begin * kCDSectorSizeCDDA;
262 + cd_read.sectorArea = kCDSectorAreaUser;
263 + cd_read.sectorType = kCDSectorTypeCDDA;
265 + cd_read.buffer = buf;
266 + cd_read.bufferLength = kCDSectorSizeCDDA * sectors;
268 + if( ioctl(d->fd, DKIOCCDREAD, &cd_read) == -1) {
271 + return cd_read.bufferLength / kCDSectorSizeCDDA;