_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) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -27,7 +27,7 @@
# include "config.h"
#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 <stdlib.h>
@@ -267,8 +267,6 @@ discmode_t
get_discmode_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;
/* See if this is a DVD. */
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)
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>
from vcdimager code:
@@ -34,7 +34,7 @@
#include "config.h"
#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/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 <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFBase.h>
#include <CoreFoundation/CFNumber.h>
#include <CoreFoundation/CFString.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOBSD.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/IOMedia.h>
#include <IOKit/storage/IOCDMedia.h>
#include <IOKit/storage/IODVDMedia.h>
#include <IOKit/storage/IOCDMediaBSDClient.h>
#include <IOKit/storage/IODVDMediaBSDClient.h>
#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
#define kIOCDBlockStorageDeviceClassString "IOCDBlockStorageDevice"
/* Note leadout is normally defined 0xAA, But on OSX 0xA0 is "lead in" while
0xA2 is "lead out". Don't ask me why. */
#define OSX_CDROM_LEADOUT_TRACK 0xA2
@@ -98,6 +98,7 @@ typedef enum {
_AM_OSX,
} access_mode_t;
#define MAX_SERVICE_NAME 1000
typedef struct {
/* Things common to all drivers like this.
This must be first. */
@@ -115,6 +116,7 @@ typedef struct {
lsn_t *pp_lba;
CFMutableDictionaryRef dict;
io_service_t MediaClass_service;
char psz_MediaClass_service[MAX_SERVICE_NAME];
SCSITaskDeviceInterface **pp_scsiTaskDeviceInterface;
} _img_private_t;
@@ -192,9 +194,10 @@ init_osx(_img_private_t *p_env) {
p_env->MediaClass_service = IOIteratorNext( iterator );
IOObjectRelease( iterator );
/* search for kIOCDMediaClass */
/* search for kIOCDMediaClass or kIOCDVDMediaClass */
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,
@@ -230,6 +233,9 @@ init_osx(_img_private_t *p_env) {
IOObjectRelease( p_env->MediaClass_service );
return false;
}
IORegistryEntryGetPath(p_env->MediaClass_service, kIOServicePlane,
p_env->psz_MediaClass_service);
return true;
}
@@ -329,6 +335,26 @@ run_scsi_cmd_osx( const void *p_user_data,
#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
* features flags.
@@ -370,112 +396,218 @@ GetFeaturesFlagsForDrive ( CFDictionaryRef dict,
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
get_drive_cap_osx(const void *p_user_data,
/*out*/ cdio_drive_read_cap_t *p_read_cap,
/*out*/ cdio_drive_write_cap_t *p_write_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;
uint32_t i_cdFlags;
uint32_t i_dvdFlags;
properties = GetRegistryEntryProperties ( ??service );
io_service_t service = get_drive_service_osx(p_env);
if( service == 0 ) goto err_exit;
if (! GetFeaturesFlagsForDrive ( properties, &i_cdFlags, &i_dvdFlags ) )
return;
/* Reader */
if ( 0 != (i_cdFlags & kCDFeaturesAnalogAudioMask) )
*p_read_cap |= CDIO_DRIVE_CAP_READ_AUDIO;
if ( 0 != (i_cdFlags & kCDFeaturesWriteOnceMask) )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_CD_R;
if ( 0 != (i_cdFlags & kCDFeaturesCDDAStreamAccurateMask) )
*p_read_cap |= CDIO_DRIVE_CAP_READ_CD_DA;
if ( 0 != (i_dvdFlags & kDVDFeaturesReadStructuresMask) )
/* Found our device */
{
CFDictionaryRef properties = GetRegistryEntryProperties ( service );
if (! GetFeaturesFlagsForDrive ( properties, &i_cdFlags,
&i_dvdFlags ) ) {
IOObjectRelease( service );
goto err_exit;
}
/* Reader */
if ( 0 != (i_cdFlags & kCDFeaturesAnalogAudioMask) )
*p_read_cap |= CDIO_DRIVE_CAP_READ_AUDIO;
if ( 0 != (i_cdFlags & kCDFeaturesWriteOnceMask) )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_CD_R;
if ( 0 != (i_cdFlags & kCDFeaturesCDDAStreamAccurateMask) )
*p_read_cap |= CDIO_DRIVE_CAP_READ_CD_DA;
if ( 0 != (i_dvdFlags & kDVDFeaturesReadStructuresMask) )
*p_read_cap |= CDIO_DRIVE_CAP_READ_DVD_ROM;
if ( 0 != (i_cdFlags & kCDFeaturesReWriteableMask) )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_CD_RW;
if ( 0 != (i_dvdFlags & kDVDFeaturesWriteOnceMask) )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_R;
if ( 0 != (i_dvdFlags & kDVDFeaturesRandomWriteableMask) )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_RAM;
if ( 0 != (i_dvdFlags & kDVDFeaturesReWriteableMask) )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_RW;
/***
if ( 0 != (i_dvdFlags & kDVDFeaturesPlusRMask) )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_PR;
if ( 0 != (i_dvdFlags & kDVDFeaturesPlusRWMask )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_PRW;
***/
if ( 0 != (i_cdFlags & kCDFeaturesReWriteableMask) )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_CD_RW;
if ( 0 != (i_dvdFlags & kDVDFeaturesWriteOnceMask) )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_R;
if ( 0 != (i_dvdFlags & kDVDFeaturesRandomWriteableMask) )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_RAM;
if ( 0 != (i_dvdFlags & kDVDFeaturesReWriteableMask) )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_RW;
/* FIXME: fill out */
*p_misc_cap = 0;
/***
if ( 0 != (i_dvdFlags & kDVDFeaturesPlusRMask) )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_PR;
IOObjectRelease( service );
}
if ( 0 != (i_dvdFlags & kDVDFeaturesPlusRWMask )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_PRW;
***/
#endif
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.
****************************************************************************/
static bool
GetDriveDescription ( CFMutableDictionaryRef dict,
/*out*/ cdio_hwinfo_t *hw_info)
get_hwinfo_osx ( const CdIo *p_cdio, /*out*/ cdio_hwinfo_t *hw_info)
{
CFDictionaryRef deviceDict = NULL;
CFStringRef vendor = NULL;
CFStringRef product = NULL;
CFStringRef revision = NULL;
if ( dict != 0 ) return false;
deviceDict = ( CFDictionaryRef )
CFDictionaryGetValue ( dict,
CFSTR ( kIOPropertyDeviceCharacteristicsKey ) );
_img_private_t *p_env = (_img_private_t *) p_cdio->env;
io_service_t service = get_drive_service_osx(p_env);
if ( deviceDict != 0 ) return false;
if ( service == 0 ) return false;
vendor = ( CFStringRef )
CFDictionaryGetValue ( deviceDict, CFSTR ( kIOPropertyVendorNameKey ) );
if( CFStringGetCString( vendor,
(char *) &(hw_info->vendor),
sizeof(hw_info->vendor),
kCFStringEncodingASCII ) )
CFRelease( vendor );
product = ( CFStringRef )
CFDictionaryGetValue ( deviceDict, CFSTR ( kIOPropertyProductNameKey ) );
if( CFStringGetCString( product,
(char *) &(hw_info->model),
sizeof(hw_info->model),
kCFStringEncodingASCII ) )
CFRelease( product );
revision = ( CFStringRef )
CFDictionaryGetValue ( deviceDict, CFSTR ( kIOPropertyProductRevisionLevelKey ) );
if( CFStringGetCString( product,
(char *) &(hw_info->revision),
sizeof(hw_info->revision),
kCFStringEncodingASCII ) )
CFRelease( revision );
/* Found our device */
{
CFStringRef vendor = NULL;
CFStringRef product = NULL;
CFStringRef revision = NULL;
CFDictionaryRef properties = GetRegistryEntryProperties ( service );
CFDictionaryRef deviceDict = ( CFDictionaryRef )
CFDictionaryGetValue ( properties,
CFSTR ( kIOPropertyDeviceCharacteristicsKey ) );
if ( deviceDict == 0 ) return false;
vendor = ( CFStringRef )
CFDictionaryGetValue ( deviceDict, CFSTR ( kIOPropertyVendorNameKey ) );
if( CFStringGetCString( vendor,
(char *) &(hw_info->vendor),
sizeof(hw_info->vendor),
kCFStringEncodingASCII ) )
CFRelease( vendor );
product = ( CFStringRef )
CFDictionaryGetValue ( deviceDict, CFSTR ( kIOPropertyProductNameKey ) );
if( CFStringGetCString( product,
(char *) &(hw_info->model),
sizeof(hw_info->model),
kCFStringEncodingASCII ) )
CFRelease( product );
revision = ( CFStringRef )
CFDictionaryGetValue ( deviceDict,
CFSTR ( kIOPropertyProductRevisionLevelKey ) );
if( CFStringGetCString( product,
(char *) &(hw_info->revision),
sizeof(hw_info->revision),
kCFStringEncodingASCII ) )
CFRelease( revision );
}
return true;
}
@@ -661,6 +793,7 @@ _set_arg_osx (void *user_data, const char key[], const char value[])
return 0;
}
#if 0
static void TestDevice(_img_private_t *p_env, io_service_t service)
{
SInt32 score;
@@ -703,6 +836,7 @@ static void TestDevice(_img_private_t *p_env, io_service_t service)
( *mmcInterface )->Release ( mmcInterface );
IODestroyPlugInInterface ( plugInInterface );
}
#endif
/*!
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,
.free = _free_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_devices = cdio_get_devices_osx,
.get_discmode = get_discmode_generic,
.get_cdtext = get_cdtext_osx,
.get_discmode = get_discmode_osx,
.get_drive_cap = get_drive_cap_osx,
.get_first_track_num= _get_first_track_num_osx,
.get_hwinfo = get_hwinfo_osx,
.get_mcn = get_mcn_osx,
.get_num_tracks = _get_num_tracks_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) 2001 Herbert Valerio Riedel <hvr@gnu.org>
@@ -39,7 +39,7 @@
#include <cdio/logging.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] =
@@ -597,10 +597,10 @@ cdio_get_hwinfo (const CdIo *p_cdio, cdio_hwinfo_t *hw_info)
then return NULL.
*/
char *
cdio_get_mcn (const CdIo *cdio)
cdio_get_mcn (const CdIo *p_cdio)
{
if (cdio->op.get_mcn) {
return cdio->op.get_mcn (cdio->env);
if (p_cdio->op.get_mcn) {
return p_cdio->op.get_mcn (p_cdio->env);
} else {
return NULL;
}
@@ -611,12 +611,12 @@ cdio_get_mcn (const CdIo *cdio)
CDIO_INVALID_TRACK is returned on error.
*/
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) {
return cdio->op.get_num_tracks (cdio->env);
if (p_cdio->op.get_num_tracks) {
return p_cdio->op.get_num_tracks (p_cdio->env);
} else {
return CDIO_INVALID_TRACK;
}
@@ -626,12 +626,12 @@ cdio_get_num_tracks (const CdIo *cdio)
Get format of track.
*/
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) {
return cdio->op.get_track_format (cdio->env, track_num);
if (p_cdio->op.get_track_format) {
return p_cdio->op.get_track_format (p_cdio->env, i_track);
} else {
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>
@@ -98,7 +98,7 @@ extern "C" {
/*!
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.
@@ -113,7 +113,7 @@ extern "C" {
Return the number of of the first track.
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.

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>
@@ -149,6 +149,11 @@ extern "C" {
*/
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,
track_t i_first_track,
cdtext_field_t e_field, const char *psz_value);