_cdio_osx.c: add getting hw info. Get some read/write capabilities and

disc info.

*generic*: split off CD discmode classification so it can be used by
OSX

cdio: env -> p_env
This commit is contained in:
rocky
2004-08-28 09:15:41 +00:00
parent 19991ded7b
commit 1949a54ec9
5 changed files with 260 additions and 110 deletions

View File

@@ -1,5 +1,5 @@
/* /*
$Id: _cdio_generic.c,v 1.24 2004/08/13 13:04:37 rocky Exp $ $Id: _cdio_generic.c,v 1.25 2004/08/28 09:15:41 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org> Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com> Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -27,7 +27,7 @@
# include "config.h" # include "config.h"
#endif #endif
static const char _rcsid[] = "$Id: _cdio_generic.c,v 1.24 2004/08/13 13:04:37 rocky Exp $"; static const char _rcsid[] = "$Id: _cdio_generic.c,v 1.25 2004/08/28 09:15:41 rocky Exp $";
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -267,8 +267,6 @@ discmode_t
get_discmode_generic (void *p_user_data ) get_discmode_generic (void *p_user_data )
{ {
generic_img_private_t *p_env = p_user_data; generic_img_private_t *p_env = p_user_data;
track_t i_track;
discmode_t discmode=CDIO_DISC_MODE_NO_INFO;
/* See if this is a DVD. */ /* See if this is a DVD. */
cdio_dvd_struct_t dvd; /* DVD READ STRUCT for layer 0. */ cdio_dvd_struct_t dvd; /* DVD READ STRUCT for layer 0. */
@@ -287,6 +285,19 @@ get_discmode_generic (void *p_user_data )
} }
} }
return get_discmode_cd_generic(p_user_data);
}
/*!
Get disc type associated with cd object.
*/
discmode_t
get_discmode_cd_generic (void *p_user_data )
{
generic_img_private_t *p_env = p_user_data;
track_t i_track;
discmode_t discmode=CDIO_DISC_MODE_NO_INFO;
if (!p_env->toc_init) if (!p_env->toc_init)
p_env->cdio->op.read_toc (p_user_data); p_env->cdio->op.read_toc (p_user_data);

View File

@@ -1,5 +1,5 @@
/* /*
$Id: _cdio_osx.c,v 1.60 2004/08/27 02:59:25 rocky Exp $ $Id: _cdio_osx.c,v 1.61 2004/08/28 09:15:41 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com> Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
from vcdimager code: from vcdimager code:
@@ -34,7 +34,7 @@
#include "config.h" #include "config.h"
#endif #endif
static const char _rcsid[] = "$Id: _cdio_osx.c,v 1.60 2004/08/27 02:59:25 rocky Exp $"; static const char _rcsid[] = "$Id: _cdio_osx.c,v 1.61 2004/08/28 09:15:41 rocky Exp $";
#include <cdio/sector.h> #include <cdio/sector.h>
#include <cdio/util.h> #include <cdio/util.h>
@@ -70,9 +70,6 @@ static const char _rcsid[] = "$Id: _cdio_osx.c,v 1.60 2004/08/27 02:59:25 rocky
#include <paths.h> #include <paths.h>
#include <CoreFoundation/CoreFoundation.h> #include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFBase.h>
#include <CoreFoundation/CFNumber.h>
#include <CoreFoundation/CFString.h>
#include <IOKit/IOKitLib.h> #include <IOKit/IOKitLib.h>
#include <IOKit/IOBSD.h> #include <IOKit/IOBSD.h>
#include <IOKit/scsi-commands/IOSCSIMultimediaCommandsDevice.h> #include <IOKit/scsi-commands/IOSCSIMultimediaCommandsDevice.h>
@@ -80,10 +77,13 @@ static const char _rcsid[] = "$Id: _cdio_osx.c,v 1.60 2004/08/27 02:59:25 rocky
#include <IOKit/storage/IODVDTypes.h> #include <IOKit/storage/IODVDTypes.h>
#include <IOKit/storage/IOMedia.h> #include <IOKit/storage/IOMedia.h>
#include <IOKit/storage/IOCDMedia.h> #include <IOKit/storage/IOCDMedia.h>
#include <IOKit/storage/IODVDMedia.h>
#include <IOKit/storage/IOCDMediaBSDClient.h> #include <IOKit/storage/IOCDMediaBSDClient.h>
#include <IOKit/storage/IODVDMediaBSDClient.h> #include <IOKit/storage/IODVDMediaBSDClient.h>
#include <IOKit/storage/IOStorageDeviceCharacteristics.h> #include <IOKit/storage/IOStorageDeviceCharacteristics.h>
#define kIOCDBlockStorageDeviceClassString "IOCDBlockStorageDevice"
/* Note leadout is normally defined 0xAA, But on OSX 0xA0 is "lead in" while /* Note leadout is normally defined 0xAA, But on OSX 0xA0 is "lead in" while
0xA2 is "lead out". Don't ask me why. */ 0xA2 is "lead out". Don't ask me why. */
#define OSX_CDROM_LEADOUT_TRACK 0xA2 #define OSX_CDROM_LEADOUT_TRACK 0xA2
@@ -98,6 +98,7 @@ typedef enum {
_AM_OSX, _AM_OSX,
} access_mode_t; } access_mode_t;
#define MAX_SERVICE_NAME 1000
typedef struct { typedef struct {
/* Things common to all drivers like this. /* Things common to all drivers like this.
This must be first. */ This must be first. */
@@ -115,6 +116,7 @@ typedef struct {
lsn_t *pp_lba; lsn_t *pp_lba;
CFMutableDictionaryRef dict; CFMutableDictionaryRef dict;
io_service_t MediaClass_service; io_service_t MediaClass_service;
char psz_MediaClass_service[MAX_SERVICE_NAME];
SCSITaskDeviceInterface **pp_scsiTaskDeviceInterface; SCSITaskDeviceInterface **pp_scsiTaskDeviceInterface;
} _img_private_t; } _img_private_t;
@@ -192,9 +194,10 @@ init_osx(_img_private_t *p_env) {
p_env->MediaClass_service = IOIteratorNext( iterator ); p_env->MediaClass_service = IOIteratorNext( iterator );
IOObjectRelease( iterator ); IOObjectRelease( iterator );
/* search for kIOCDMediaClass */ /* search for kIOCDMediaClass or kIOCDVDMediaClass */
while( p_env->MediaClass_service && while( p_env->MediaClass_service &&
!IOObjectConformsTo( p_env->MediaClass_service, kIOCDMediaClass ) ) (!IOObjectConformsTo(p_env->MediaClass_service, kIOCDMediaClass)) &&
(!IOObjectConformsTo(p_env->MediaClass_service, kIODVDMediaClass)) )
{ {
ret = IORegistryEntryGetParentIterator( p_env->MediaClass_service, ret = IORegistryEntryGetParentIterator( p_env->MediaClass_service,
@@ -230,6 +233,9 @@ init_osx(_img_private_t *p_env) {
IOObjectRelease( p_env->MediaClass_service ); IOObjectRelease( p_env->MediaClass_service );
return false; return false;
} }
IORegistryEntryGetPath(p_env->MediaClass_service, kIOServicePlane,
p_env->psz_MediaClass_service);
return true; return true;
} }
@@ -329,6 +335,26 @@ run_scsi_cmd_osx( const void *p_user_data,
#endif #endif
} }
/***************************************************************************
* GetDeviceIterator - Gets an io_iterator_t for our class type
***************************************************************************/
static io_iterator_t
GetDeviceIterator ( const char * deviceClass )
{
IOReturn err = kIOReturnSuccess;
io_iterator_t iterator = MACH_PORT_NULL;
err = IOServiceGetMatchingServices ( kIOMasterPortDefault,
IOServiceMatching ( deviceClass ),
&iterator );
check ( err == kIOReturnSuccess );
return iterator;
}
/*************************************************************************** /***************************************************************************
* GetFeaturesFlagsForDrive -Gets the bitfield which represents the * GetFeaturesFlagsForDrive -Gets the bitfield which represents the
* features flags. * features flags.
@@ -370,24 +396,116 @@ GetFeaturesFlagsForDrive ( CFDictionaryRef dict,
return true; return true;
} }
/*!
Get disc type associated with the cd object.
*/
static discmode_t
get_discmode_osx (void *p_user_data)
{
_img_private_t *p_env = p_user_data;
char str[10];
int32_t i_discmode = CDIO_DISC_MODE_ERROR;
CFDictionaryRef propertiesDict = 0;
CFStringRef data;
propertiesDict = GetRegistryEntryProperties ( p_env->MediaClass_service );
if ( propertiesDict == 0 ) return i_discmode;
data = ( CFStringRef )
CFDictionaryGetValue ( propertiesDict, CFSTR ( kIODVDMediaTypeKey ) );
if( CFStringGetCString( data, str, sizeof(str),
kCFStringEncodingASCII ) ) {
if (0 == strncmp(str, "DVD+R", sizeof(str)) )
i_discmode = CDIO_DISC_MODE_DVD_PR;
else if (0 == strncmp(str, "DVD+RW", sizeof(str)) )
i_discmode = CDIO_DISC_MODE_DVD_PRW;
else if (0 == strncmp(str, "DVD-R", sizeof(str)) )
i_discmode = CDIO_DISC_MODE_DVD_R;
else if (0 == strncmp(str, "DVD-ROM", sizeof(str)) )
i_discmode = CDIO_DISC_MODE_DVD_ROM;
else if (0 == strncmp(str, "DVD-RAM", sizeof(str)) )
i_discmode = CDIO_DISC_MODE_DVD_RAM;
else if (0 == strncmp(str, "CD-ROM", sizeof(str)) )
i_discmode = CDIO_DISC_MODE_CD_DA;
else if (0 == strncmp(str, "CDR", sizeof(str)) )
i_discmode = CDIO_DISC_MODE_CD_DATA;
else if (0 == strncmp(str, "CDRW", sizeof(str)) )
i_discmode = CDIO_DISC_MODE_CD_DATA;
CFRelease( data );
}
CFRelease( propertiesDict );
if (CDIO_DISC_MODE_CD_DATA == i_discmode) {
/* Need to do more classification */
return get_discmode_cd_generic(p_user_data);
}
return i_discmode;
}
static io_service_t
get_drive_service_osx(const _img_private_t *p_env)
{
io_service_t service;
io_iterator_t service_iterator;
service_iterator = GetDeviceIterator ( kIOCDBlockStorageDeviceClassString );
if( service_iterator == MACH_PORT_NULL ) return 0;
service = IOIteratorNext( service_iterator );
if( service == 0 ) return 0;
do
{
char psz_service[MAX_SERVICE_NAME];
IORegistryEntryGetPath(service, kIOServicePlane, psz_service);
psz_service[MAX_SERVICE_NAME-1] = '\0';
/* FIXME: This is all hoaky. Here we need info from a parent class,
psz_service of what we opened above. We are relying on the
fact that the name will be a substring of the name we
openned with.
*/
if (0 == strncmp(psz_service, p_env->psz_MediaClass_service,
strlen(psz_service))) {
/* Found our device */
IOObjectRelease( service_iterator );
return service;
}
IOObjectRelease( service );
} while( ( service = IOIteratorNext( service_iterator ) ) != 0 );
IOObjectRelease( service_iterator );
return service;
}
static void static void
get_drive_cap_osx(const void *p_user_data, get_drive_cap_osx(const void *p_user_data,
/*out*/ cdio_drive_read_cap_t *p_read_cap, /*out*/ cdio_drive_read_cap_t *p_read_cap,
/*out*/ cdio_drive_write_cap_t *p_write_cap, /*out*/ cdio_drive_write_cap_t *p_write_cap,
/*out*/ cdio_drive_misc_cap_t *p_misc_cap) /*out*/ cdio_drive_misc_cap_t *p_misc_cap)
{ {
#if 1
*p_misc_cap = *p_write_cap = *p_read_cap = CDIO_DRIVE_CAP_UNKNOWN;
return;
#else
const _img_private_t *p_env = p_user_data; const _img_private_t *p_env = p_user_data;
uint32_t i_cdFlags; uint32_t i_cdFlags;
uint32_t i_dvdFlags; uint32_t i_dvdFlags;
properties = GetRegistryEntryProperties ( ??service ); io_service_t service = get_drive_service_osx(p_env);
if (! GetFeaturesFlagsForDrive ( properties, &i_cdFlags, &i_dvdFlags ) ) if( service == 0 ) goto err_exit;
return;
/* Found our device */
{
CFDictionaryRef properties = GetRegistryEntryProperties ( service );
if (! GetFeaturesFlagsForDrive ( properties, &i_cdFlags,
&i_dvdFlags ) ) {
IOObjectRelease( service );
goto err_exit;
}
/* Reader */ /* Reader */
@@ -422,32 +540,45 @@ get_drive_cap_osx(const void *p_user_data,
if ( 0 != (i_dvdFlags & kDVDFeaturesPlusRWMask ) if ( 0 != (i_dvdFlags & kDVDFeaturesPlusRWMask )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_PRW; *p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_PRW;
***/ ***/
#endif
/* FIXME: fill out */
*p_misc_cap = 0;
IOObjectRelease( service );
}
return;
err_exit:
*p_misc_cap = *p_write_cap = *p_read_cap = CDIO_DRIVE_CAP_UNKNOWN;
return;
} }
#if ADDED_DRIVE_INFO #if 1
/**************************************************************************** /****************************************************************************
* GetDriveDescription - Gets drive description. * GetDriveDescription - Gets drive description.
****************************************************************************/ ****************************************************************************/
static bool static bool
GetDriveDescription ( CFMutableDictionaryRef dict, get_hwinfo_osx ( const CdIo *p_cdio, /*out*/ cdio_hwinfo_t *hw_info)
/*out*/ cdio_hwinfo_t *hw_info)
{ {
_img_private_t *p_env = (_img_private_t *) p_cdio->env;
io_service_t service = get_drive_service_osx(p_env);
CFDictionaryRef deviceDict = NULL; if ( service == 0 ) return false;
/* Found our device */
{
CFStringRef vendor = NULL; CFStringRef vendor = NULL;
CFStringRef product = NULL; CFStringRef product = NULL;
CFStringRef revision = NULL; CFStringRef revision = NULL;
if ( dict != 0 ) return false; CFDictionaryRef properties = GetRegistryEntryProperties ( service );
CFDictionaryRef deviceDict = ( CFDictionaryRef )
deviceDict = ( CFDictionaryRef ) CFDictionaryGetValue ( properties,
CFDictionaryGetValue ( dict,
CFSTR ( kIOPropertyDeviceCharacteristicsKey ) ); CFSTR ( kIOPropertyDeviceCharacteristicsKey ) );
if ( deviceDict != 0 ) return false; if ( deviceDict == 0 ) return false;
vendor = ( CFStringRef ) vendor = ( CFStringRef )
CFDictionaryGetValue ( deviceDict, CFSTR ( kIOPropertyVendorNameKey ) ); CFDictionaryGetValue ( deviceDict, CFSTR ( kIOPropertyVendorNameKey ) );
@@ -468,14 +599,15 @@ GetDriveDescription ( CFMutableDictionaryRef dict,
CFRelease( product ); CFRelease( product );
revision = ( CFStringRef ) revision = ( CFStringRef )
CFDictionaryGetValue ( deviceDict, CFSTR ( kIOPropertyProductRevisionLevelKey ) ); CFDictionaryGetValue ( deviceDict,
CFSTR ( kIOPropertyProductRevisionLevelKey ) );
if( CFStringGetCString( product, if( CFStringGetCString( product,
(char *) &(hw_info->revision), (char *) &(hw_info->revision),
sizeof(hw_info->revision), sizeof(hw_info->revision),
kCFStringEncodingASCII ) ) kCFStringEncodingASCII ) )
CFRelease( revision ); CFRelease( revision );
}
return true; return true;
} }
@@ -661,6 +793,7 @@ _set_arg_osx (void *user_data, const char key[], const char value[])
return 0; return 0;
} }
#if 0
static void TestDevice(_img_private_t *p_env, io_service_t service) static void TestDevice(_img_private_t *p_env, io_service_t service)
{ {
SInt32 score; SInt32 score;
@@ -703,6 +836,7 @@ static void TestDevice(_img_private_t *p_env, io_service_t service)
( *mmcInterface )->Release ( mmcInterface ); ( *mmcInterface )->Release ( mmcInterface );
IODestroyPlugInInterface ( plugInInterface ); IODestroyPlugInInterface ( plugInInterface );
} }
#endif
/*! /*!
Read and cache the CD's Track Table of Contents and track info. Read and cache the CD's Track Table of Contents and track info.
@@ -1281,13 +1415,13 @@ cdio_open_osx (const char *psz_orig_source)
.eject_media = _eject_media_osx, .eject_media = _eject_media_osx,
.free = _free_osx, .free = _free_osx,
.get_arg = _get_arg_osx, .get_arg = _get_arg_osx,
.get_cdtext = get_cdtext_generic, .get_cdtext = get_cdtext_osx,
.get_default_device = cdio_get_default_device_osx, .get_default_device = cdio_get_default_device_osx,
.get_devices = cdio_get_devices_osx, .get_devices = cdio_get_devices_osx,
.get_discmode = get_discmode_generic, .get_discmode = get_discmode_osx,
.get_cdtext = get_cdtext_osx,
.get_drive_cap = get_drive_cap_osx, .get_drive_cap = get_drive_cap_osx,
.get_first_track_num= _get_first_track_num_osx, .get_first_track_num= _get_first_track_num_osx,
.get_hwinfo = get_hwinfo_osx,
.get_mcn = get_mcn_osx, .get_mcn = get_mcn_osx,
.get_num_tracks = _get_num_tracks_osx, .get_num_tracks = _get_num_tracks_osx,
.get_track_format = get_track_format_osx, .get_track_format = get_track_format_osx,

View File

@@ -1,5 +1,5 @@
/* /*
$Id: cdio.c,v 1.70 2004/08/27 11:23:40 rocky Exp $ $Id: cdio.c,v 1.71 2004/08/28 09:15:41 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com> Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org> Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
@@ -39,7 +39,7 @@
#include <cdio/logging.h> #include <cdio/logging.h>
#include "cdio_private.h" #include "cdio_private.h"
static const char _rcsid[] = "$Id: cdio.c,v 1.70 2004/08/27 11:23:40 rocky Exp $"; static const char _rcsid[] = "$Id: cdio.c,v 1.71 2004/08/28 09:15:41 rocky Exp $";
const char *track_format2str[6] = const char *track_format2str[6] =
@@ -597,10 +597,10 @@ cdio_get_hwinfo (const CdIo *p_cdio, cdio_hwinfo_t *hw_info)
then return NULL. then return NULL.
*/ */
char * char *
cdio_get_mcn (const CdIo *cdio) cdio_get_mcn (const CdIo *p_cdio)
{ {
if (cdio->op.get_mcn) { if (p_cdio->op.get_mcn) {
return cdio->op.get_mcn (cdio->env); return p_cdio->op.get_mcn (p_cdio->env);
} else { } else {
return NULL; return NULL;
} }
@@ -611,12 +611,12 @@ cdio_get_mcn (const CdIo *cdio)
CDIO_INVALID_TRACK is returned on error. CDIO_INVALID_TRACK is returned on error.
*/ */
track_t track_t
cdio_get_num_tracks (const CdIo *cdio) cdio_get_num_tracks (const CdIo *p_cdio)
{ {
if (cdio == NULL) return CDIO_INVALID_TRACK; if (p_cdio == NULL) return CDIO_INVALID_TRACK;
if (cdio->op.get_num_tracks) { if (p_cdio->op.get_num_tracks) {
return cdio->op.get_num_tracks (cdio->env); return p_cdio->op.get_num_tracks (p_cdio->env);
} else { } else {
return CDIO_INVALID_TRACK; return CDIO_INVALID_TRACK;
} }
@@ -626,12 +626,12 @@ cdio_get_num_tracks (const CdIo *cdio)
Get format of track. Get format of track.
*/ */
track_format_t track_format_t
cdio_get_track_format(const CdIo *cdio, track_t track_num) cdio_get_track_format(const CdIo *p_cdio, track_t i_track)
{ {
cdio_assert (cdio != NULL); cdio_assert (p_cdio != NULL);
if (cdio->op.get_track_format) { if (p_cdio->op.get_track_format) {
return cdio->op.get_track_format (cdio->env, track_num); return p_cdio->op.get_track_format (p_cdio->env, i_track);
} else { } else {
return TRACK_FORMAT_ERROR; return TRACK_FORMAT_ERROR;
} }

View File

@@ -1,5 +1,5 @@
/* /*
$Id: cdio_private.h,v 1.40 2004/08/27 02:50:13 rocky Exp $ $Id: cdio_private.h,v 1.41 2004/08/28 09:15:41 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com> Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -98,7 +98,7 @@ extern "C" {
/*! /*!
Get disc mode associated with cd_obj. Get disc mode associated with cd_obj.
*/ */
discmode_t (*get_discmode) (void *env); discmode_t (*get_discmode) (void *p_env);
/*! /*!
Return the what kind of device we've got. Return the what kind of device we've got.
@@ -113,7 +113,7 @@ extern "C" {
Return the number of of the first track. Return the number of of the first track.
CDIO_INVALID_TRACK is returned on error. CDIO_INVALID_TRACK is returned on error.
*/ */
track_t (*get_first_track_num) (void *env); track_t (*get_first_track_num) (void *p_env);
/*! /*!
Get the CD-ROM hardware info via a SCSI MMC INQUIRY command. Get the CD-ROM hardware info via a SCSI MMC INQUIRY command.

View File

@@ -1,5 +1,5 @@
/* /*
$Id: generic.h,v 1.1 2004/08/10 11:58:15 rocky Exp $ $Id: generic.h,v 1.2 2004/08/28 09:15:41 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com> Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
@@ -149,6 +149,11 @@ extern "C" {
*/ */
discmode_t get_discmode_generic (void *p_user_data ); discmode_t get_discmode_generic (void *p_user_data );
/*!
Same as above but only handles CD cases
*/
discmode_t get_discmode_cd_generic (void *p_user_data );
void set_cdtext_field_generic(void *user_data, track_t i_track, void set_cdtext_field_generic(void *user_data, track_t i_track,
track_t i_first_track, track_t i_first_track,
cdtext_field_t e_field, const char *psz_value); cdtext_field_t e_field, const char *psz_value);