X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faccess%2Fvcd%2Fcdrom.c;h=9eaa93924c61e8a4fabc9038d961e6105532430b;hb=9630c00c6b310e1a824f0bce00de89f0f777484f;hp=5c04bd1a587abfa030af8d7f6e993823e2981876;hpb=8aa24cfe361b893a626016211e05f41c544f5c1b;p=vlc diff --git a/modules/access/vcd/cdrom.c b/modules/access/vcd/cdrom.c index 5c04bd1a58..9eaa93924c 100644 --- a/modules/access/vcd/cdrom.c +++ b/modules/access/vcd/cdrom.c @@ -1,8 +1,8 @@ /**************************************************************************** * cdrom.c: cdrom tools ***************************************************************************** - * Copyright (C) 1998-2001 VideoLAN - * $Id: cdrom.c,v 1.12 2003/05/22 12:00:57 gbazin Exp $ + * Copyright (C) 1998-2001 the VideoLAN team + * $Id$ * * Authors: Johan Bilien * Gildas Bazin @@ -20,34 +20,37 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** * Preamble *****************************************************************************/ -#include -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif #include +#include #ifdef HAVE_UNISTD_H # include #endif -#include -#include -#include -#include #include - -#ifdef HAVE_SYS_IOCTL_H -# include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_FCNTL_H +# include #endif #if defined( SYS_BSDI ) # include -#elif defined ( SYS_DARWIN ) +#elif defined ( __APPLE__ ) # include # include # include @@ -63,12 +66,16 @@ #elif defined( WIN32 ) # include # include -#else +#elif defined (__linux__) +# include # include +#else +# error FIXME #endif #include "cdrom_internals.h" #include "cdrom.h" +#include /***************************************************************************** * ioctl_Open: Opens a VCD device or file and returns an opaque handle @@ -155,7 +162,7 @@ vcddev_t *ioctl_Open( vlc_object_t *p_this, const char *psz_dev ) *****************************************************************************/ void ioctl_Close( vlc_object_t * p_this, vcddev_t *p_vcddev ) { - if( p_vcddev->psz_dev ) free( p_vcddev->psz_dev ); + free( p_vcddev->psz_dev ); if( p_vcddev->i_vcdimage_handle != -1 ) { @@ -221,7 +228,7 @@ int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev, * vcd device mode */ -#if defined( SYS_DARWIN ) +#if defined( __APPLE__ ) CDTOC *pTOC; int i_descriptors; @@ -232,7 +239,7 @@ int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev, return 0; } - i_descriptors = darwin_getNumberOfDescriptors( pTOC ); + i_descriptors = CDTOCGetDescriptorCount( pTOC ); i_tracks = darwin_getNumberOfTracks( pTOC, i_descriptors ); if( pp_sectors ) @@ -251,7 +258,7 @@ int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev, pTrackDescriptors = pTOC->descriptors; - for( i_tracks = 0, i = 0; i <= i_descriptors; i++ ) + for( i_tracks = 0, i = 0; i < i_descriptors; i++ ) { track = pTrackDescriptors[i].point; @@ -351,8 +358,8 @@ int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev, if( *pp_sectors == NULL || p_fulltoc == NULL ) { - if( *pp_sectors ) free( *pp_sectors ); - if( p_fulltoc ) free( p_fulltoc ); + free( *pp_sectors ); + free( p_fulltoc ); msg_Err( p_this, "out of memory" ); CloseHandle( hEvent ); return 0; @@ -454,7 +461,7 @@ int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev, if( *pp_sectors == NULL ) { msg_Err( p_this, "out of memory" ); - return NULL; + return 0; } toc_entries.address_format = CD_LBA_FORMAT; @@ -581,7 +588,7 @@ int ioctl_ReadSectors( vlc_object_t *p_this, const vcddev_t *p_vcddev, * vcd device mode */ -#if defined( SYS_DARWIN ) +#if defined( __APPLE__ ) dk_cd_read_t cd_read; memset( &cd_read, 0, sizeof(cd_read) ); @@ -688,8 +695,21 @@ int ioctl_ReadSectors( vlc_object_t *p_this, const vcddev_t *p_vcddev, VCD_SECTOR_SIZE * i_nb, &dwBytesReturned, NULL ) == 0 ) { - if( i_type == VCD_TYPE ) free( p_block ); - return -1; + if( i_type == VCD_TYPE ) + { + /* Retry in YellowMode2 */ + cdrom_raw.TrackMode = YellowMode2; + if( DeviceIoControl( p_vcddev->h_device_handle, + IOCTL_CDROM_RAW_READ, &cdrom_raw, + sizeof(RAW_READ_INFO), p_block, + VCD_SECTOR_SIZE * i_nb, &dwBytesReturned, + NULL ) == 0 ) + { + free( p_block ); + return -1; + } + } + else return -1; } } @@ -817,13 +837,26 @@ static int OpenVCDImage( vlc_object_t * p_this, const char *psz_dev, char *p_pos; char *psz_vcdfile = NULL; char *psz_cuefile = NULL; - FILE *cuefile; + FILE *cuefile = NULL; char line[1024]; /* Check if we are dealing with a .cue file */ p_pos = strrchr( psz_dev, '.' ); if( p_pos && !strcmp( p_pos, ".cue" ) ) { + /* psz_dev must be the cue file. Let's assume there's a .bin + * file with the same filename */ + if( p_pos ) + { + psz_vcdfile = malloc( p_pos - psz_dev + 5 /* ".bin" */ ); + strncpy( psz_vcdfile, psz_dev, p_pos - psz_dev ); + strcpy( psz_vcdfile + (p_pos - psz_dev), ".bin"); + } + else + { + psz_vcdfile = malloc( strlen(psz_dev) + 5 /* ".bin" */ ); + sprintf( psz_vcdfile, "%s.bin", psz_dev ); + } psz_cuefile = strdup( psz_dev ); } else @@ -841,14 +874,30 @@ static int OpenVCDImage( vlc_object_t * p_this, const char *psz_dev, psz_cuefile = malloc( strlen(psz_dev) + 5 /* ".cue" */ ); sprintf( psz_cuefile, "%s.cue", psz_dev ); } + /* If we need to look up the .cue file, then we don't have to look for the vcd */ + psz_vcdfile = strdup( psz_dev ); } /* Open the cue file and try to parse it */ msg_Dbg( p_this,"trying .cue file: %s", psz_cuefile ); - cuefile = fopen( psz_cuefile, "rt" ); - if( cuefile && fscanf( cuefile, "FILE %c", line ) && + cuefile = utf8_fopen( psz_cuefile, "rt" ); + if( cuefile == NULL ) + { + i_ret = -1; + msg_Dbg( p_this, "could not find .cue file" ); + goto error; + } + + msg_Dbg( p_this,"using vcd image file: %s", psz_vcdfile ); + p_vcddev->i_vcdimage_handle = utf8_open( psz_vcdfile, + O_RDONLY | O_NONBLOCK | O_BINARY, 0666 ); + + if( p_vcddev->i_vcdimage_handle == -1 && + fscanf( cuefile, "FILE %c", line ) && fgets( line, 1024, cuefile ) ) { + /* We have a cue file, but no valid vcd file yet */ + free( psz_vcdfile ); p_pos = strchr( line, '"' ); if( p_pos ) { @@ -865,15 +914,17 @@ static int OpenVCDImage( vlc_object_t * p_this, const char *psz_dev, } else psz_vcdfile = strdup( line ); } + msg_Dbg( p_this,"using vcd image file: %s", psz_vcdfile ); + p_vcddev->i_vcdimage_handle = utf8_open( psz_vcdfile, + O_RDONLY | O_NONBLOCK | O_BINARY, 0666 ); } - if( psz_vcdfile ) + if( p_vcddev->i_vcdimage_handle == -1) { - msg_Dbg( p_this,"using vcd image file: %s", psz_vcdfile ); - p_vcddev->i_vcdimage_handle = open( psz_vcdfile, - O_RDONLY | O_NONBLOCK | O_BINARY ); - i_ret = (p_vcddev->i_vcdimage_handle == -1) ? -1 : 0; + i_ret = -1; + goto error; } + else i_ret = 0; /* Try to parse the i_tracks and p_sectors info so we can just forget * about the cuefile */ @@ -919,9 +970,10 @@ static int OpenVCDImage( vlc_object_t * p_this, const char *psz_dev, } +error: if( cuefile ) fclose( cuefile ); - if( psz_cuefile ) free( psz_cuefile ); - if( psz_vcdfile ) free( psz_vcdfile ); + free( psz_cuefile ); + free( psz_vcdfile ); return i_ret; } @@ -936,11 +988,10 @@ static void CloseVCDImage( vlc_object_t * p_this, vcddev_t *p_vcddev ) else return; - if( p_vcddev->p_sectors ) - free( p_vcddev->p_sectors ); + free( p_vcddev->p_sectors ); } -#if defined( SYS_DARWIN ) +#if defined( __APPLE__ ) /**************************************************************************** * darwin_getTOC: get the TOC ****************************************************************************/ @@ -973,7 +1024,7 @@ static CDTOC *darwin_getTOC( vlc_object_t * p_this, const vcddev_t *p_vcddev ) } /* get service iterator for the device */ - if( ( ret = IOServiceGetMatchingServices( + if( ( ret = IOServiceGetMatchingServices( port, IOBSDNameMatching( port, 0, psz_devname ), &iterator ) ) != KERN_SUCCESS ) { @@ -985,10 +1036,10 @@ static CDTOC *darwin_getTOC( vlc_object_t * p_this, const vcddev_t *p_vcddev ) service = IOIteratorNext( iterator ); IOObjectRelease( iterator ); - /* search for kIOCDMediaClass */ + /* search for kIOCDMediaClass */ while( service && !IOObjectConformsTo( service, kIOCDMediaClass ) ) { - if( ( ret = IORegistryEntryGetParentIterator( service, + if( ( ret = IORegistryEntryGetParentIterator( service, kIOServicePlane, &iterator ) ) != KERN_SUCCESS ) { msg_Err( p_this, "IORegistryEntryGetParentIterator: 0x%08x", ret ); @@ -1037,55 +1088,35 @@ static CDTOC *darwin_getTOC( vlc_object_t * p_this, const vcddev_t *p_vcddev ) } CFRelease( properties ); - IOObjectRelease( service ); - - return( pTOC ); -} - -/**************************************************************************** - * darwin_getNumberOfDescriptors: get number of descriptors in TOC - ****************************************************************************/ -static int darwin_getNumberOfDescriptors( CDTOC *pTOC ) -{ - int i_descriptors; - - /* get TOC length */ - i_descriptors = pTOC->length; - - /* remove the first and last session */ - i_descriptors -= ( sizeof(pTOC->sessionFirst) + - sizeof(pTOC->sessionLast) ); - - /* divide the length by the size of a single descriptor */ - i_descriptors /= sizeof(CDTOCDescriptor); + IOObjectRelease( service ); - return( i_descriptors ); + return( pTOC ); } /**************************************************************************** - * darwin_getNumberOfTracks: get number of tracks in TOC + * darwin_getNumberOfTracks: get number of tracks in TOC ****************************************************************************/ static int darwin_getNumberOfTracks( CDTOC *pTOC, int i_descriptors ) { u_char track; - int i, i_tracks = 0; - CDTOCDescriptor *pTrackDescriptors; + int i, i_tracks = 0; + CDTOCDescriptor *pTrackDescriptors = NULL; - pTrackDescriptors = pTOC->descriptors; + pTrackDescriptors = (CDTOCDescriptor *)pTOC->descriptors; - for( i = i_descriptors; i >= 0; i-- ) + for( i = i_descriptors; i > 0; i-- ) { track = pTrackDescriptors[i].point; if( track > CD_MAX_TRACK_NO || track < CD_MIN_TRACK_NO ) continue; - i_tracks++; + i_tracks++; } return( i_tracks ); } -#endif /* SYS_DARWIN */ +#endif /* __APPLE__ */ #if defined( WIN32 ) /***************************************************************************** @@ -1129,10 +1160,8 @@ static int win32_vcd_open( vlc_object_t * p_this, const char *psz_dev, hASPI = LoadLibrary( "wnaspi32.dll" ); if( hASPI != NULL ) { - (FARPROC) lpGetSupport = GetProcAddress( hASPI, - "GetASPI32SupportInfo" ); - (FARPROC) lpSendCommand = GetProcAddress( hASPI, - "SendASPI32Command" ); + lpGetSupport = (void *)GetProcAddress( hASPI, "GetASPI32SupportInfo" ); + lpSendCommand = (void *)GetProcAddress( hASPI, "SendASPI32Command" ); } if( hASPI == NULL || lpGetSupport == NULL || lpSendCommand == NULL )