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

📄 cdrom.c

📁 vlc源码
💻 C
📖 第 1 页 / 共 3 页
字号:
                *pp_sectors = malloc( (i_tracks + 1) * sizeof(int) );                if( *pp_sectors == NULL )                    return 0;                for( i = 0 ; i <= i_tracks ; i++ )                {                    (*pp_sectors)[ i ] = MSF_TO_LBA2(                                           cdrom_toc.TrackData[i].Address[1],                                           cdrom_toc.TrackData[i].Address[2],                                           cdrom_toc.TrackData[i].Address[3] );                    msg_Dbg( p_this, "p_sectors: %i, %i", i, (*pp_sectors)[i]);                }            }        }#elif defined( HAVE_IOC_TOC_HEADER_IN_SYS_CDIO_H ) \       || defined( HAVE_SCSIREQ_IN_SYS_SCSIIO_H )        struct ioc_toc_header tochdr;        struct ioc_read_toc_entry toc_entries;        if( ioctl( p_vcddev->i_device_handle, CDIOREADTOCHEADER, &tochdr )            == -1 )        {            msg_Err( p_this, "could not read TOCHDR" );            return 0;        }        i_tracks = tochdr.ending_track - tochdr.starting_track + 1;        if( pp_sectors )        {             int i;             *pp_sectors = malloc( (i_tracks + 1) * sizeof(int) );             if( *pp_sectors == NULL )                 return 0;             toc_entries.address_format = CD_LBA_FORMAT;             toc_entries.starting_track = 0;             toc_entries.data_len = ( i_tracks + 1 ) *                                        sizeof( struct cd_toc_entry );             toc_entries.data = (struct cd_toc_entry *)                                    malloc( toc_entries.data_len );             if( toc_entries.data == NULL )             {                 free( *pp_sectors );                 return 0;             }             /* Read the TOC */             if( ioctl( p_vcddev->i_device_handle, CDIOREADTOCENTRYS,                        &toc_entries ) == -1 )             {                 msg_Err( p_this, "could not read the TOC" );                 free( *pp_sectors );                 free( toc_entries.data );                 return 0;             }             /* Fill the p_sectors structure with the track/sector matches */             for( i = 0 ; i <= i_tracks ; i++ )             {#if defined( HAVE_SCSIREQ_IN_SYS_SCSIIO_H )                 /* FIXME: is this ok? */                 (*pp_sectors)[ i ] = toc_entries.data[i].addr.lba;#else                 (*pp_sectors)[ i ] = ntohl( toc_entries.data[i].addr.lba );#endif             }        }#else        struct cdrom_tochdr   tochdr;        struct cdrom_tocentry tocent;        /* First we read the TOC header */        if( ioctl( p_vcddev->i_device_handle, CDROMREADTOCHDR, &tochdr )            == -1 )        {            msg_Err( p_this, "could not read TOCHDR" );            return 0;        }        i_tracks = tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1;        if( pp_sectors )        {            int i;            *pp_sectors = malloc( (i_tracks + 1) * sizeof(int) );            if( *pp_sectors == NULL )                return 0;            /* Fill the p_sectors structure with the track/sector matches */            for( i = 0 ; i <= i_tracks ; i++ )            {                tocent.cdte_format = CDROM_LBA;                tocent.cdte_track =                    ( i == i_tracks ) ? CDROM_LEADOUT : tochdr.cdth_trk0 + i;                if( ioctl( p_vcddev->i_device_handle, CDROMREADTOCENTRY,                           &tocent ) == -1 )                {                    msg_Err( p_this, "could not read TOCENTRY" );                    free( *pp_sectors );                    return 0;                }                (*pp_sectors)[ i ] = tocent.cdte_addr.lba;            }        }#endif        return i_tracks;    }}/**************************************************************************** * ioctl_ReadSector: Read VCD or CDDA sectors ****************************************************************************/int ioctl_ReadSectors( vlc_object_t *p_this, const vcddev_t *p_vcddev,                       int i_sector, uint8_t *p_buffer, int i_nb, int i_type ){    uint8_t *p_block;    int i;    if( i_type == VCD_TYPE ) p_block = malloc( VCD_SECTOR_SIZE * i_nb );    else p_block = p_buffer;    if( p_vcddev->i_vcdimage_handle != -1 )    {        /*         *  vcd image mode         */        if( lseek( p_vcddev->i_vcdimage_handle, i_sector * VCD_SECTOR_SIZE,                   SEEK_SET ) == -1 )        {            msg_Err( p_this, "Could not lseek to sector %d", i_sector );            if( i_type == VCD_TYPE ) free( p_block );            return -1;        }        if( read( p_vcddev->i_vcdimage_handle, p_block, VCD_SECTOR_SIZE * i_nb)            == -1 )        {            msg_Err( p_this, "Could not read sector %d", i_sector );            if( i_type == VCD_TYPE ) free( p_block );            return -1;        }    }    else    {        /*         *  vcd device mode         */#if defined( __APPLE__ )        dk_cd_read_t cd_read;        memset( &cd_read, 0, sizeof(cd_read) );        cd_read.offset = i_sector * VCD_SECTOR_SIZE;        cd_read.sectorArea = kCDSectorAreaSync | kCDSectorAreaHeader |                             kCDSectorAreaSubHeader | kCDSectorAreaUser |                             kCDSectorAreaAuxiliary;        cd_read.sectorType = kCDSectorTypeUnknown;        cd_read.buffer = p_block;        cd_read.bufferLength = VCD_SECTOR_SIZE * i_nb;        if( ioctl( p_vcddev->i_device_handle, DKIOCCDREAD, &cd_read ) == -1 )        {            msg_Err( p_this, "could not read block %d", i_sector );            if( i_type == VCD_TYPE ) free( p_block );            return -1;        }#elif defined( WIN32 )        if( p_vcddev->hASPI )        {            HANDLE hEvent;            struct SRB_ExecSCSICmd ssc;            /* Create the transfer completion event */            hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );            if( hEvent == NULL )            {                if( i_type == VCD_TYPE ) free( p_block );                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      = 12;            /* Operation code */            ssc.CDBByte[ 0 ] = READ_CD;            /* Sector type */            ssc.CDBByte[ 1 ] = i_type == VCD_TYPE ? SECTOR_TYPE_MODE2_FORM2 :                                                    SECTOR_TYPE_CDDA;            /* Start of LBA */            ssc.CDBByte[ 2 ] = ( i_sector >> 24 ) & 0xff;            ssc.CDBByte[ 3 ] = ( i_sector >> 16 ) & 0xff;            ssc.CDBByte[ 4 ] = ( i_sector >>  8 ) & 0xff;            ssc.CDBByte[ 5 ] = ( i_sector       ) & 0xff;            /* Transfer length */            ssc.CDBByte[ 6 ] = ( i_nb >> 16 ) & 0xff;            ssc.CDBByte[ 7 ] = ( i_nb >> 8  ) & 0xff;            ssc.CDBByte[ 8 ] = ( i_nb       ) & 0xff;            /* Data selection */            ssc.CDBByte[ 9 ] = i_type == VCD_TYPE ? READ_CD_RAW_MODE2 :                                                    READ_CD_USERDATA;            /* Result buffer */            ssc.SRB_BufPointer  = p_block;            ssc.SRB_BufLen = VCD_SECTOR_SIZE * i_nb;            /* 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 );            }            CloseHandle( hEvent );            /* check that the transfer went as planned */            if( ssc.SRB_Status != SS_COMP )            {                if( i_type == VCD_TYPE ) free( p_block );                return -1;            }        }        else        {            DWORD dwBytesReturned;            RAW_READ_INFO cdrom_raw;            /* Initialize CDROM_RAW_READ structure */            cdrom_raw.DiskOffset.QuadPart = CD_SECTOR_SIZE * i_sector;            cdrom_raw.SectorCount = i_nb;            cdrom_raw.TrackMode =  i_type == VCD_TYPE ? XAForm2 : CDDA;            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 )            {                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;            }        }#elif defined( HAVE_SCSIREQ_IN_SYS_SCSIIO_H )        struct scsireq  sc;        int i_ret;        memset( &sc, 0, sizeof(sc) );        sc.cmd[0] = 0xBE;        sc.cmd[1] = i_type == VCD_TYPE ? SECTOR_TYPE_MODE2_FORM2:                                         SECTOR_TYPE_CDDA;        sc.cmd[2] = (i_sector >> 24) & 0xff;        sc.cmd[3] = (i_sector >> 16) & 0xff;        sc.cmd[4] = (i_sector >>  8) & 0xff;        sc.cmd[5] = (i_sector >>  0) & 0xff;        sc.cmd[6] = (i_nb >> 16) & 0xff;        sc.cmd[7] = (i_nb >>  8) & 0xff;        sc.cmd[8] = (i_nb      ) & 0xff;        sc.cmd[9] = i_type == VCD_TYPE ? READ_CD_RAW_MODE2 : READ_CD_USERDATA;        sc.cmd[10] = 0; /* sub channel */        sc.cmdlen = 12;        sc.databuf = (caddr_t)p_block;        sc.datalen = VCD_SECTOR_SIZE * i_nb;        sc.senselen = sizeof( sc.sense );        sc.flags = SCCMD_READ;        sc.timeout = 10000;        i_ret = ioctl( i_fd, SCIOCCOMMAND, &sc );        if( i_ret == -1 )        {            msg_Err( p_this, "SCIOCCOMMAND failed" );            if( i_type == VCD_TYPE ) free( p_block );            return -1;        }        if( sc.retsts || sc.error )        {            msg_Err( p_this, "SCSI command failed: status %d error %d\n",                             sc.retsts, sc.error );            if( i_type == VCD_TYPE ) free( p_block );           return -1;        }#elif defined( HAVE_IOC_TOC_HEADER_IN_SYS_CDIO_H )        int i_size = VCD_SECTOR_SIZE;        if( ioctl( p_vcddev->i_device_handle, CDRIOCSETBLOCKSIZE, &i_size )            == -1 )        {            msg_Err( p_this, "Could not set block size" );            if( i_type == VCD_TYPE ) free( p_block );            return( -1 );        }        if( lseek( p_vcddev->i_device_handle,                   i_sector * VCD_SECTOR_SIZE, SEEK_SET ) == -1 )        {            msg_Err( p_this, "Could not lseek to sector %d", i_sector );            if( i_type == VCD_TYPE ) free( p_block );            return( -1 );        }        if( read( p_vcddev->i_device_handle,                  p_block, VCD_SECTOR_SIZE * i_nb ) == -1 )        {            msg_Err( p_this, "Could not read sector %d", i_sector );            if( i_type == VCD_TYPE ) free( p_block );            return( -1 );        }#else        for( i = 0; i < i_nb; i++ )        {            int i_dummy = i_sector + i + 2 * CD_FRAMES;#define p_msf ((struct cdrom_msf0 *)(p_block + i * VCD_SECTOR_SIZE))            p_msf->minute =   i_dummy / (CD_FRAMES * CD_SECS);            p_msf->second = ( i_dummy % (CD_FRAMES * CD_SECS) ) / CD_FRAMES;            p_msf->frame =  ( i_dummy % (CD_FRAMES * CD_SECS) ) % CD_FRAMES;#undef p_msf            if( ioctl( p_vcddev->i_device_handle, CDROMREADRAW,                       p_block + i * VCD_SECTOR_SIZE ) == -1 )            {                msg_Err( p_this, "could not read block %i from disc",                         i_sector );                if( i == 0 )                {                    if( i_type == VCD_TYPE ) free( p_block );                    return( -1 );                }                else break;            }        }#endif    }    /* For VCDs, we don't want to keep the header and footer of the     * sectors read */    if( i_type == VCD_TYPE )    {        for( i = 0; i < i_nb; i++ )        {            memcpy( p_buffer + i * VCD_DATA_SIZE,                    p_block + i * VCD_SECTOR_SIZE + VCD_DATA_START,                    VCD_DATA_SIZE );        }        free( p_block );    }    return( 0 );}/**************************************************************************** * Private functions ****************************************************************************//**************************************************************************** * OpenVCDImage: try to open a vcd image from a .cue file ****************************************************************************/static int OpenVCDImage( vlc_object_t * p_this, const char *psz_dev,                         vcddev_t *p_vcddev ){    int i_ret = -1;    char *p_pos;    char *psz_vcdfile = NULL;    char *psz_cuefile = NULL;    FILE *cuefile     = NULL;    int *p_sectors    = NULL;    char line[1024];    bool b_found      = false;    /* Check if we are dealing with a .cue file */    p_pos = strrchr( psz_dev, '.' );

⌨️ 快捷键说明

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