⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdrom.c

📁 vlc源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/**************************************************************************** * cdrom.c: cdrom tools ***************************************************************************** * Copyright (C) 1998-2001 the VideoLAN team * $Id: 5fa97052ee8b4f440db88fbc6f8a47fd475d50fc $ * * Authors: Johan Bilien <jobi@via.ecp.fr> *          Gildas Bazin <gbazin@netcourrier.com> *          Jon Lech Johansen <jon-vl@nanocrew.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_access.h>#ifdef HAVE_UNISTD_H#   include <unistd.h>#endif#include <errno.h>#ifdef HAVE_SYS_TYPES_H#   include <sys/types.h>#endif#ifdef HAVE_SYS_STAT_H#   include <sys/stat.h>#endif#ifdef HAVE_FCNTL_H#   include <fcntl.h>#endif#if defined( SYS_BSDI )#   include <dvd.h>#elif defined ( __APPLE__ )#   include <CoreFoundation/CFBase.h>#   include <IOKit/IOKitLib.h>#   include <IOKit/storage/IOCDTypes.h>#   include <IOKit/storage/IOCDMedia.h>#   include <IOKit/storage/IOCDMediaBSDClient.h>#elif defined( HAVE_SCSIREQ_IN_SYS_SCSIIO_H )#   include <sys/inttypes.h>#   include <sys/cdio.h>#   include <sys/scsiio.h>#elif defined( HAVE_IOC_TOC_HEADER_IN_SYS_CDIO_H )#   include <sys/cdio.h>#   include <sys/cdrio.h>#elif defined( WIN32 )#   include <windows.h>#   include <winioctl.h>#elif defined (__linux__)#   include <sys/ioctl.h>#   include <linux/cdrom.h>#else#   error FIXME#endif#include "cdrom_internals.h"#include "cdrom.h"#include <vlc_charset.h>/***************************************************************************** * ioctl_Open: Opens a VCD device or file and returns an opaque handle *****************************************************************************/vcddev_t *ioctl_Open( vlc_object_t *p_this, const char *psz_dev ){    int i_ret;    int b_is_file;    vcddev_t *p_vcddev;#ifndef WIN32    struct stat fileinfo;#endif    if( !psz_dev ) return NULL;    /*     *  Initialize structure with default values     */    p_vcddev = (vcddev_t *)malloc( sizeof(vcddev_t) );    if( p_vcddev == NULL )        return NULL;    p_vcddev->i_vcdimage_handle = -1;    p_vcddev->psz_dev = NULL;    b_is_file = 1;    /*     *  Check if we are dealing with a device or a file (vcd image)     */#ifdef WIN32    if( (strlen( psz_dev ) == 2 && psz_dev[1] == ':') )    {        b_is_file = 0;    }#else    if( utf8_stat( psz_dev, &fileinfo ) < 0 )    {        free( p_vcddev );        return NULL;    }    /* Check if this is a block/char device */    if( S_ISBLK( fileinfo.st_mode ) || S_ISCHR( fileinfo.st_mode ) )        b_is_file = 0;#endif    if( b_is_file )    {        i_ret = OpenVCDImage( p_this, psz_dev, p_vcddev );    }    else    {        /*         *  open the vcd device         */#ifdef WIN32        i_ret = win32_vcd_open( p_this, psz_dev, p_vcddev );#else        p_vcddev->i_device_handle = -1;        p_vcddev->i_device_handle = open( psz_dev, O_RDONLY | O_NONBLOCK );        i_ret = (p_vcddev->i_device_handle == -1) ? -1 : 0;#endif    }    if( i_ret == 0 )    {        p_vcddev->psz_dev = (char *)strdup( psz_dev );    }    else    {        free( p_vcddev );        p_vcddev = NULL;    }    return p_vcddev;}/***************************************************************************** * ioctl_Close: Closes an already opened VCD device or file. *****************************************************************************/void ioctl_Close( vlc_object_t * p_this, vcddev_t *p_vcddev ){    free( p_vcddev->psz_dev );    if( p_vcddev->i_vcdimage_handle != -1 )    {        /*         *  vcd image mode         */        CloseVCDImage( p_this, p_vcddev );        return;    }    /*     *  vcd device mode     */#ifdef WIN32    if( p_vcddev->h_device_handle )        CloseHandle( p_vcddev->h_device_handle );    if( p_vcddev->hASPI )        FreeLibrary( (HMODULE)p_vcddev->hASPI );#else    if( p_vcddev->i_device_handle != -1 )        close( p_vcddev->i_device_handle );#endif}/***************************************************************************** * ioctl_GetTracksMap: Read the Table of Content, fill in the pp_sectors map *                     if pp_sectors is not null and return the number of *                     tracks available. *****************************************************************************/int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev,                        int **pp_sectors ){    int i_tracks = 0;    if( p_vcddev->i_vcdimage_handle != -1 )    {        /*         *  vcd image mode         */        i_tracks = p_vcddev->i_tracks;        if( pp_sectors )        {            *pp_sectors = malloc( (i_tracks + 1) * sizeof(int) );            if( *pp_sectors == NULL )                return 0;            memcpy( *pp_sectors, p_vcddev->p_sectors,                    (i_tracks + 1) * sizeof(int) );        }        return i_tracks;    }    else    {        /*         *  vcd device mode         */#if defined( __APPLE__ )        CDTOC *pTOC;        int i_descriptors;        if( ( pTOC = darwin_getTOC( p_this, p_vcddev ) ) == NULL )        {            msg_Err( p_this, "failed to get the TOC" );            return 0;        }        i_descriptors = CDTOCGetDescriptorCount( pTOC );        i_tracks = darwin_getNumberOfTracks( pTOC, i_descriptors );        if( pp_sectors )        {            int i, i_leadout = -1;            CDTOCDescriptor *pTrackDescriptors;            u_char track;            *pp_sectors = malloc( (i_tracks + 1) * sizeof(int) );            if( *pp_sectors == NULL )            {                darwin_freeTOC( pTOC );                return 0;            }            pTrackDescriptors = pTOC->descriptors;            for( i_tracks = 0, i = 0; i < i_descriptors; i++ )            {                track = pTrackDescriptors[i].point;                if( track == 0xA2 )                    i_leadout = i;                if( track > CD_MAX_TRACK_NO || track < CD_MIN_TRACK_NO )                    continue;                (*pp_sectors)[i_tracks++] =                    CDConvertMSFToLBA( pTrackDescriptors[i].p );            }            if( i_leadout == -1 )            {                msg_Err( p_this, "leadout not found" );                free( *pp_sectors );                darwin_freeTOC( pTOC );                return 0;            }            /* set leadout sector */            (*pp_sectors)[i_tracks] =                CDConvertMSFToLBA( pTrackDescriptors[i_leadout].p );        }        darwin_freeTOC( pTOC );#elif defined( WIN32 )        if( p_vcddev->hASPI )        {            HANDLE hEvent;            struct SRB_ExecSCSICmd ssc;            uint8_t p_tocheader[ 4 ];            /* Create the transfer completion event */            hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );            if( hEvent == NULL )            {                return -1;            }            memset( &ssc, 0, sizeof( ssc ) );            ssc.SRB_Cmd         = SC_EXEC_SCSI_CMD;            ssc.SRB_Flags       = SRB_DIR_IN | SRB_EVENT_NOTIFY;            ssc.SRB_HaId        = LOBYTE( p_vcddev->i_sid );            ssc.SRB_Target      = HIBYTE( p_vcddev->i_sid );            ssc.SRB_SenseLen    = SENSE_LEN;            ssc.SRB_PostProc = (LPVOID) hEvent;            ssc.SRB_CDBLen      = 10;            /* Operation code */            ssc.CDBByte[ 0 ] = READ_TOC;            /* Format */            ssc.CDBByte[ 2 ] = READ_TOC_FORMAT_TOC;            /* Starting track */            ssc.CDBByte[ 6 ] = 0;            /* Allocation length and buffer */            ssc.SRB_BufLen = sizeof( p_tocheader );            ssc.SRB_BufPointer  = p_tocheader;            ssc.CDBByte[ 7 ] = ( ssc.SRB_BufLen >>  8 ) & 0xff;            ssc.CDBByte[ 8 ] = ( ssc.SRB_BufLen       ) & 0xff;            /* Initiate transfer */            ResetEvent( hEvent );            p_vcddev->lpSendCommand( (void*) &ssc );            /* If the command has still not been processed, wait until it's             * finished */            if( ssc.SRB_Status == SS_PENDING )                WaitForSingleObject( hEvent, INFINITE );            /* check that the transfer went as planned */            if( ssc.SRB_Status != SS_COMP )            {                CloseHandle( hEvent );                return 0;            }            i_tracks = p_tocheader[3] - p_tocheader[2] + 1;            if( pp_sectors )            {                int i, i_toclength;                uint8_t *p_fulltoc;                i_toclength = 4 /* header */ + p_tocheader[0] +                              ((unsigned int)p_tocheader[1] << 8);                p_fulltoc = malloc( i_toclength );                *pp_sectors = malloc( (i_tracks + 1) * sizeof(int) );                if( *pp_sectors == NULL || p_fulltoc == NULL )                {                    free( *pp_sectors );                    free( p_fulltoc );                    CloseHandle( hEvent );                    return 0;                }                /* Allocation length and buffer */                ssc.SRB_BufLen = i_toclength;                ssc.SRB_BufPointer  = p_fulltoc;                ssc.CDBByte[ 7 ] = ( ssc.SRB_BufLen >>  8 ) & 0xff;                ssc.CDBByte[ 8 ] = ( ssc.SRB_BufLen       ) & 0xff;                /* Initiate transfer */                ResetEvent( hEvent );                p_vcddev->lpSendCommand( (void*) &ssc );                /* If the command has still not been processed, wait until it's                 * finished */                if( ssc.SRB_Status == SS_PENDING )                    WaitForSingleObject( hEvent, INFINITE );                /* check that the transfer went as planned */                if( ssc.SRB_Status != SS_COMP )                    i_tracks = 0;                for( i = 0 ; i <= i_tracks ; i++ )                {                    int i_index = 8 + 8 * i;                    (*pp_sectors)[ i ] = ((int)p_fulltoc[ i_index ] << 24) +                                         ((int)p_fulltoc[ i_index+1 ] << 16) +                                         ((int)p_fulltoc[ i_index+2 ] << 8) +                                         (int)p_fulltoc[ i_index+3 ];                    msg_Dbg( p_this, "p_sectors: %i, %i", i, (*pp_sectors)[i]);                }                free( p_fulltoc );            }            CloseHandle( hEvent );        }        else        {            DWORD dwBytesReturned;            CDROM_TOC cdrom_toc;            if( DeviceIoControl( p_vcddev->h_device_handle,                                 IOCTL_CDROM_READ_TOC,                                 NULL, 0, &cdrom_toc, sizeof(CDROM_TOC),                                 &dwBytesReturned, NULL ) == 0 )            {                msg_Err( p_this, "could not read TOCHDR" );                return 0;            }            i_tracks = cdrom_toc.LastTrack - cdrom_toc.FirstTrack + 1;            if( pp_sectors )            {                int i;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -