📄 cdrom.c
字号:
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 + -