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

📄 cdrom.c

📁 vlc源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    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 */        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");        psz_cuefile = strdup( psz_dev );    }    else    {        /* psz_dev must be the actual vcd file. Let's assume there's a .cue         * file with the same filename */        if( p_pos )        {            psz_cuefile = malloc( p_pos - psz_dev + 5 /* ".cue" */ );            strncpy( psz_cuefile, psz_dev, p_pos - psz_dev );            strcpy( psz_cuefile + (p_pos - psz_dev), ".cue");        }        else        {            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 = utf8_fopen( psz_cuefile, "rt" );    if( cuefile == NULL )    {        msg_Dbg( p_this, "could not find .cue file" );        goto error;    }    msg_Dbg( p_this,"guessing vcd image file: %s", psz_vcdfile );    p_vcddev->i_vcdimage_handle = utf8_open( psz_vcdfile,                                    O_RDONLY | O_NONBLOCK | O_BINARY, 0666 );     while( fgets( line, 1024, cuefile ) && !b_found )    {        /* We have a cue file, but no valid vcd file yet */        char filename[1024];        char type[16];        int i_temp = sscanf( line, "FILE \"%1023[^\"]\" %15s", filename, type );        *p_pos = 0;        switch( i_temp )        {            case 2:                msg_Dbg( p_this, "the cue file says the data file is %s", type );                if( strcasecmp( type, "BINARY" ) )                    goto error; /* Error if not binary, otherwise treat as case 1 */            case 1:                if( p_vcddev->i_vcdimage_handle == -1 )                {                    msg_Dbg( p_this, "we could not find the data file, but we found a new path" );                    free( psz_vcdfile);                    if( *filename != '/' && ((p_pos = strrchr( psz_cuefile, '/' ))                        || (p_pos = strrchr( psz_cuefile, '\\' ) )) )                    {                        psz_vcdfile = malloc( strlen(filename) +                                      (p_pos - psz_cuefile + 1) + 1 );                        strncpy( psz_vcdfile, psz_cuefile, (p_pos - psz_cuefile + 1) );                        strcpy( psz_vcdfile + (p_pos - psz_cuefile + 1), filename );                    } else psz_vcdfile = strdup( filename );                    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 );                }                b_found = true;            default:                break;        }    }    if( p_vcddev->i_vcdimage_handle == -1)        goto error;    /* Try to parse the i_tracks and p_sectors info so we can just forget     * about the cuefile */    size_t i_tracks = 0;    while( fgets( line, 1024, cuefile ) )    {        /* look for a TRACK line */        char psz_dummy[9];        if( !sscanf( line, "%9s", psz_dummy ) || strcmp(psz_dummy, "TRACK") )            continue;        /* look for an INDEX line */        while( fgets( line, 1024, cuefile ) )        {            int i_num, i_min, i_sec, i_frame;            if( (sscanf( line, "%*9s %2u %2u:%2u:%2u", &i_num,                         &i_min, &i_sec, &i_frame ) != 4) || (i_num != 1) )                continue;            int *buf = realloc (p_sectors, (i_tracks + 1) * sizeof (int));            if (buf == NULL)                goto error;            p_sectors = buf;            p_sectors[i_tracks] = MSF_TO_LBA(i_min, i_sec, i_frame);            msg_Dbg( p_this, "vcd track %i begins at sector:%i",                     i_tracks, p_sectors[i_tracks] );            i_tracks++;            break;        }    }    /* fill in the last entry */    int *buf = realloc (p_sectors, (i_tracks + 1) * sizeof (int));    if (buf == NULL)        goto error;    p_sectors = buf;    p_sectors[i_tracks] = lseek(p_vcddev->i_vcdimage_handle, 0, SEEK_END)                                 / VCD_SECTOR_SIZE;    msg_Dbg( p_this, "vcd track %i, begins at sector:%i",             i_tracks, p_sectors[i_tracks] );    p_vcddev->i_tracks = ++i_tracks;    p_vcddev->p_sectors = p_sectors;    i_ret = 0;error:    if( cuefile ) fclose( cuefile );    free( p_sectors );    free( psz_cuefile );    free( psz_vcdfile );    return i_ret;}/**************************************************************************** * CloseVCDImage: closes a vcd image opened by OpenVCDImage ****************************************************************************/static void CloseVCDImage( vlc_object_t * p_this, vcddev_t *p_vcddev ){    if( p_vcddev->i_vcdimage_handle != -1 )        close( p_vcddev->i_vcdimage_handle );    else        return;    free( p_vcddev->p_sectors );}#if defined( __APPLE__ )/**************************************************************************** * darwin_getTOC: get the TOC ****************************************************************************/static CDTOC *darwin_getTOC( vlc_object_t * p_this, const vcddev_t *p_vcddev ){    mach_port_t port;    char *psz_devname;    kern_return_t ret;    CDTOC *pTOC = NULL;    io_iterator_t iterator;    io_registry_entry_t service;    CFMutableDictionaryRef properties;    CFDataRef data;    /* get the device name */    if( ( psz_devname = strrchr( p_vcddev->psz_dev, '/') ) != NULL )        ++psz_devname;    else        psz_devname = p_vcddev->psz_dev;    /* unraw the device name */    if( *psz_devname == 'r' )        ++psz_devname;    /* get port for IOKit communication */    if( ( ret = IOMasterPort( MACH_PORT_NULL, &port ) ) != KERN_SUCCESS )    {        msg_Err( p_this, "IOMasterPort: 0x%08x", ret );        return( NULL );    }    /* get service iterator for the device */    if( ( ret = IOServiceGetMatchingServices(                    port, IOBSDNameMatching( port, 0, psz_devname ),                    &iterator ) ) != KERN_SUCCESS )    {        msg_Err( p_this, "IOServiceGetMatchingServices: 0x%08x", ret );        return( NULL );    }    /* first service */    service = IOIteratorNext( iterator );    IOObjectRelease( iterator );    /* search for kIOCDMediaClass */    while( service && !IOObjectConformsTo( service, kIOCDMediaClass ) )    {        if( ( ret = IORegistryEntryGetParentIterator( service,                        kIOServicePlane, &iterator ) ) != KERN_SUCCESS )        {            msg_Err( p_this, "IORegistryEntryGetParentIterator: 0x%08x", ret );            IOObjectRelease( service );            return( NULL );        }        IOObjectRelease( service );        service = IOIteratorNext( iterator );        IOObjectRelease( iterator );    }    if( service == NULL )    {        msg_Err( p_this, "search for kIOCDMediaClass came up empty" );        return( NULL );    }    /* create a CF dictionary containing the TOC */    if( ( ret = IORegistryEntryCreateCFProperties( service, &properties,                    kCFAllocatorDefault, kNilOptions ) ) != KERN_SUCCESS )    {        msg_Err( p_this, "IORegistryEntryCreateCFProperties: 0x%08x", ret );        IOObjectRelease( service );        return( NULL );    }    /* get the TOC from the dictionary */    if( ( data = (CFDataRef) CFDictionaryGetValue( properties,                                    CFSTR(kIOCDMediaTOCKey) ) ) != NULL )    {        CFRange range;        CFIndex buf_len;        buf_len = CFDataGetLength( data ) + 1;        range = CFRangeMake( 0, buf_len );        if( ( pTOC = (CDTOC *)malloc( buf_len ) ) != NULL )        {            CFDataGetBytes( data, range, (u_char *)pTOC );        }    }    else    {        msg_Err( p_this, "CFDictionaryGetValue failed" );    }    CFRelease( properties );    IOObjectRelease( service );    return( pTOC );}/**************************************************************************** * 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 = NULL;    pTrackDescriptors = (CDTOCDescriptor *)pTOC->descriptors;    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++;    }    return( i_tracks );}#endif /* __APPLE__ */#if defined( WIN32 )/***************************************************************************** * win32_vcd_open: open vcd drive ***************************************************************************** * Load and use aspi if it is available, otherwise use IOCTLs on WinNT/2K/XP. *****************************************************************************/static int win32_vcd_open( vlc_object_t * p_this, const char *psz_dev,                           vcddev_t *p_vcddev ){    /* Initializations */    p_vcddev->h_device_handle = NULL;    p_vcddev->i_sid = 0;    p_vcddev->hASPI = 0;    p_vcddev->lpSendCommand = 0;    if( WIN_NT )    {        char psz_win32_drive[7];        msg_Dbg( p_this, "using winNT/2K/XP ioctl layer" );        sprintf( psz_win32_drive, "\\\\.\\%c:", psz_dev[0] );        p_vcddev->h_device_handle = CreateFile( psz_win32_drive, GENERIC_READ,                                            FILE_SHARE_READ | FILE_SHARE_WRITE,                                            NULL, OPEN_EXISTING,                                            FILE_FLAG_NO_BUFFERING |                                            FILE_FLAG_RANDOM_ACCESS, NULL );        return (p_vcddev->h_device_handle == NULL) ? -1 : 0;    }    else    {        HMODULE hASPI = NULL;        long (*lpGetSupport)( void ) = NULL;        long (*lpSendCommand)( void* ) = NULL;        DWORD dwSupportInfo;        int i, j, i_hostadapters;        char c_drive = psz_dev[0];        hASPI = LoadLibrary( "wnaspi32.dll" );        if( hASPI != NULL )        {            lpGetSupport = (void *)GetProcAddress( hASPI, "GetASPI32SupportInfo" );            lpSendCommand = (void *)GetProcAddress( hASPI, "SendASPI32Command" );        }        if( hASPI == NULL || lpGetSupport == NULL || lpSendCommand == NULL )        {            msg_Dbg( p_this,                     "unable to load aspi or get aspi function pointers" );            if( hASPI ) FreeLibrary( hASPI );            return -1;        }        /* ASPI support seems to be there */        dwSupportInfo = lpGetSupport();        if( HIBYTE( LOWORD ( dwSupportInfo ) ) == SS_NO_ADAPTERS )        {            msg_Dbg( p_this, "no host adapters found (aspi)" );            FreeLibrary( hASPI );            return -1;        }        if( HIBYTE( LOWORD ( dwSupportInfo ) ) != SS_COMP )        {            msg_Dbg( p_this, "unable to initalize aspi layer" );            FreeLibrary( hASPI );            return -1;        }        i_hostadapters = LOBYTE( LOWORD( dwSupportInfo ) );        if( i_hostadapters == 0 )        {            FreeLibrary( hASPI );            return -1;        }        c_drive = c_drive > 'Z' ? c_drive - 'a' : c_drive - 'A';        for( i = 0; i < i_hostadapters; i++ )        {          for( j = 0; j < 15; j++ )          {              struct SRB_GetDiskInfo srbDiskInfo;              srbDiskInfo.SRB_Cmd         = SC_GET_DISK_INFO;              srbDiskInfo.SRB_HaId        = i;              srbDiskInfo.SRB_Flags       = 0;              srbDiskInfo.SRB_Hdr_Rsvd    = 0;              srbDiskInfo.SRB_Target      = j;              srbDiskInfo.SRB_Lun         = 0;              lpSendCommand( (void*) &srbDiskInfo );              if( (srbDiskInfo.SRB_Status == SS_COMP) &&                  (srbDiskInfo.SRB_Int13HDriveInfo == c_drive) )              {                  /* Make sure this is a cdrom device */                  struct SRB_GDEVBlock   srbGDEVBlock;                  memset( &srbGDEVBlock, 0, sizeof(struct SRB_GDEVBlock) );                  srbGDEVBlock.SRB_Cmd    = SC_GET_DEV_TYPE;                  srbGDEVBlock.SRB_HaId   = i;                  srbGDEVBlock.SRB_Target = j;                  lpSendCommand( (void*) &srbGDEVBlock );                  if( ( srbGDEVBlock.SRB_Status == SS_COMP ) &&                      ( srbGDEVBlock.SRB_DeviceType == DTYPE_CDROM ) )                  {                      p_vcddev->i_sid = MAKEWORD( i, j );                      p_vcddev->hASPI = (long)hASPI;                      p_vcddev->lpSendCommand = lpSendCommand;                      msg_Dbg( p_this, "using aspi layer" );                      return 0;                  }                  else                  {                      FreeLibrary( hASPI );                      msg_Dbg( p_this, "%c: is not a cdrom drive",                               psz_dev[0] );                      return -1;                  }              }          }        }        FreeLibrary( hASPI );        msg_Dbg( p_this, "unable to get haid and target (aspi)" );    }    return -1;}#endif /* WIN32 */

⌨️ 快捷键说明

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