📄 dvd_reader.c
字号:
} } if( strlen( path_copy ) >= 9 ) { if( !strcasecmp( &(path_copy[ strlen( path_copy ) - 9 ]), "/video_ts" ) ) { path_copy[ strlen( path_copy ) - 9 ] = '\0'; if(path_copy[0] == '\0') { path_copy[0] = '/'; path_copy[1] = '\0'; } } }#if defined(SYS_BSD) if( ( fe = getfsfile( path_copy ) ) ) { dev_name = bsd_block2char( fe->fs_spec ); if(verbose >= 1) { fprintf( stderr, "libdvdread: Attempting to use device %s" " mounted on %s%s\n", dev_name, fe->fs_file, have_css ? " for CSS authentication" : ""); } auth_drive = DVDOpenImageFile( dev_name, have_css ); if(!auth_drive) { internal_errno = errno; } }#elif defined(__sun) mntfile = fopen( MNTTAB, "r" ); if( mntfile ) { struct mnttab mp; int res; while( ( res = getmntent( mntfile, &mp ) ) != -1 ) { if( res == 0 && !strcmp( mp.mnt_mountp, path_copy ) ) { dev_name = sun_block2char( mp.mnt_special ); if(verbose >= 1) { fprintf( stderr, "libdvdread: Attempting to use device %s" " mounted on %s%s\n", dev_name, mp.mnt_mountp, have_css ? " for CSS authentication" : ""); } auth_drive = DVDOpenImageFile( dev_name, have_css ); if(!auth_drive) { internal_errno = errno; } break; } } fclose( mntfile ); }#elif defined(__linux__) || defined(__CYGWIN__) mntfile = fopen( MOUNTED, "r" ); if( mntfile ) { struct mntent *me; while( ( me = getmntent( mntfile ) ) ) { if( !strcmp( me->mnt_dir, path_copy ) ) { if(verbose >= 1) { fprintf( stderr, "libdvdread: Attempting to use device %s" " mounted on %s%s\n", me->mnt_fsname, me->mnt_dir, have_css ? " for CSS authentication" : ""); } auth_drive = DVDOpenImageFile( me->mnt_fsname, have_css ); if(!auth_drive) { internal_errno = errno; } dev_name = strdup(me->mnt_fsname); break; } } fclose( mntfile ); }#elif defined(__MINGW32__) dev_name = strdup(path); auth_drive = DVDOpenImageFile( path, have_css );#endif if( !dev_name ) { if(verbose >= 1) { fprintf( stderr, "libdvdread: Couldn't find device name.\n" ); } } else if( !auth_drive ) { if(verbose >= 1) { fprintf( stderr, "libdvdread: Device %s inaccessible%s: %s\n", dev_name, have_css ? ", CSS authentication not available" : "", strerror(internal_errno)); } } free( dev_name ); free( path_copy ); /** * If we've opened a drive, just use that. */ if( auth_drive ) { return auth_drive; } /** * Otherwise, we now try to open the directory tree instead. */ return DVDOpenPath( path ); } /* If it's none of the above, screw it. */ if(verbose >= 1) { fprintf( stderr, "libdvdread: Could not open %s\n", path ); } return 0;}void DVDClose( dvd_reader_t *dvd ){ if( dvd ) { if( dvd->dev ) dvdinput_close( dvd->dev ); if( dvd->path_root ) free( dvd->path_root ); if( dvd->udfcache ) FreeUDFCache( dvd, dvd->udfcache ); if(dvd->align) { if(dvd->verbose >= 0) { fprintf(stderr, "libdvdread: DVDClose(): Memory leak in align functions\n"); } } free( dvd ); }}void DVDInit(void){ dvdinput_setup();}void DVDFinish(void){ dvdinput_free();}/** * Open an unencrypted file on a DVD image file. */static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *dvd, char *filename ){ uint32_t start, len; dvd_file_t *dvd_file; start = UDFFindFile( dvd, filename, &len ); if( !start ) return 0; dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) ); if( !dvd_file ) return 0; dvd_file->dvd = dvd; dvd_file->lb_start = start; dvd_file->seek_pos = 0; memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) ); memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) ); dvd_file->filesize = len / DVD_VIDEO_LB_LEN; return dvd_file;}/** * Searches for <file> in directory <path>, ignoring case. * Returns 0 and full filename in <filename>. * or -1 on file not found. * or -2 on path not found. */static int findDirFile( const char *path, const char *file, char *filename ) { DIR *dir; struct dirent *ent; dir = opendir( path ); if( !dir ) return -2; while( ( ent = readdir( dir ) ) != NULL ) { if( !strcasecmp( ent->d_name, file ) ) { sprintf( filename, "%s%s%s", path, ( ( path[ strlen( path ) - 1 ] == '/' ) ? "" : "/" ), ent->d_name ); closedir(dir); return 0; } } closedir(dir); return -1;}static int findDVDFile( dvd_reader_t *dvd, const char *file, char *filename ){ char video_path[ PATH_MAX + 1 ]; const char *nodirfile; int ret; /* Strip off the directory for our search */ if( !strncasecmp( "/VIDEO_TS/", file, 10 ) ) { nodirfile = &(file[ 10 ]); } else { nodirfile = file; } ret = findDirFile( dvd->path_root, nodirfile, filename ); if( ret < 0 ) { /* Try also with adding the path, just in case. */ sprintf( video_path, "%s/VIDEO_TS/", dvd->path_root ); ret = findDirFile( video_path, nodirfile, filename ); if( ret < 0 ) { /* Try with the path, but in lower case. */ sprintf( video_path, "%s/video_ts/", dvd->path_root ); ret = findDirFile( video_path, nodirfile, filename ); if( ret < 0 ) { return 0; } } } return 1;}/** * Open an unencrypted file from a DVD directory tree. */static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, char *filename ){ char full_path[ PATH_MAX + 1 ]; dvd_file_t *dvd_file; struct stat fileinfo; dvd_input_t dev; /* Get the full path of the file. */ if( !findDVDFile( dvd, filename, full_path ) ) return 0; dev = dvdinput_open( full_path ); if( !dev ) return 0; dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) ); if( !dvd_file ) return 0; dvd_file->dvd = dvd; dvd_file->lb_start = 0; dvd_file->seek_pos = 0; memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) ); memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) ); dvd_file->filesize = 0; if( stat( full_path, &fileinfo ) < 0 ) { if(dvd->verbose >= 1) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); } free( dvd_file ); return 0; } dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN; dvd_file->title_devs[ 0 ] = dev; dvd_file->filesize = dvd_file->title_sizes[ 0 ]; return dvd_file;}static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd, int title, int menu ){ char filename[ MAX_UDF_FILE_NAME_LEN ]; uint32_t start, len; dvd_file_t *dvd_file; if( title == 0 ) { sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" ); } else { sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 ); } start = UDFFindFile( dvd, filename, &len ); if( start == 0 ) return 0; dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) ); if( !dvd_file ) return 0; dvd_file->dvd = dvd; /*Hack*/ dvd_file->css_title = title << 1 | menu; dvd_file->lb_start = start; dvd_file->seek_pos = 0; memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) ); memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) ); dvd_file->filesize = len / DVD_VIDEO_LB_LEN; /* Calculate the complete file size for every file in the VOBS */ if( !menu ) { int cur; for( cur = 2; cur < 10; cur++ ) { sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur ); if( !UDFFindFile( dvd, filename, &len ) ) break; dvd_file->filesize += len / DVD_VIDEO_LB_LEN; } } if( dvd->css_state == 1 /* Need key init */ ) {// initAllCSSKeys( dvd );// dvd->css_state = 2; } /* if( dvdinput_title( dvd_file->dvd->dev, (int)start ) < 0 ) { fprintf( stderr, "libdvdread: Error cracking CSS key for %s\n", filename ); } */ return dvd_file;}static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, int title, int menu ){ char filename[ MAX_UDF_FILE_NAME_LEN ]; char full_path[ PATH_MAX + 1 ]; struct stat fileinfo; dvd_file_t *dvd_file; int i; dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) ); if( !dvd_file ) return 0; dvd_file->dvd = dvd; /*Hack*/ dvd_file->css_title = title << 1 | menu; dvd_file->lb_start = 0; dvd_file->seek_pos = 0; memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) ); memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) ); dvd_file->filesize = 0; if( menu ) { dvd_input_t dev; if( title == 0 ) { sprintf( filename, "VIDEO_TS.VOB" ); } else { sprintf( filename, "VTS_%02i_0.VOB", title ); } if( !findDVDFile( dvd, filename, full_path ) ) { free( dvd_file ); return 0; } dev = dvdinput_open( full_path ); if( dev == NULL ) { free( dvd_file ); return 0; } if( stat( full_path, &fileinfo ) < 0 ) { if(dvd->verbose >= 1) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); } free( dvd_file ); return 0; } dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN; dvd_file->title_devs[ 0 ] = dev; dvdinput_title( dvd_file->title_devs[0], 0); dvd_file->filesize = dvd_file->title_sizes[ 0 ]; } else { for( i = 0; i < 9; ++i ) { sprintf( filename, "VTS_%02i_%i.VOB", title, i + 1 ); if( !findDVDFile( dvd, filename, full_path ) ) { break; } if( stat( full_path, &fileinfo ) < 0 ) { if(dvd->verbose >= 1) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); } break; } dvd_file->title_sizes[ i ] = fileinfo.st_size / DVD_VIDEO_LB_LEN; dvd_file->title_devs[ i ] = dvdinput_open( full_path ); dvdinput_title( dvd_file->title_devs[ i ], 0 ); dvd_file->filesize += dvd_file->title_sizes[ i ]; } if( !dvd_file->title_devs[ 0 ] ) { free( dvd_file ); return 0; } } return dvd_file;}dvd_file_t *DVDOpenFile( dvd_reader_t *dvd, int titlenum, dvd_read_domain_t domain ){ char filename[ MAX_UDF_FILE_NAME_LEN ]; /* Check arguments. */ if( dvd == NULL || titlenum < 0 ) { errno = EINVAL; return NULL; } switch( domain ) { case DVD_READ_INFO_FILE: if( titlenum == 0 ) { sprintf( filename, "/VIDEO_TS/VIDEO_TS.IFO" ); } else { sprintf( filename, "/VIDEO_TS/VTS_%02i_0.IFO", titlenum ); } break; case DVD_READ_INFO_BACKUP_FILE: if( titlenum == 0 ) { sprintf( filename, "/VIDEO_TS/VIDEO_TS.BUP" ); } else { sprintf( filename, "/VIDEO_TS/VTS_%02i_0.BUP", titlenum ); } break; case DVD_READ_MENU_VOBS: if( dvd->isImageFile ) { return DVDOpenVOBUDF( dvd, titlenum, 1 ); } else { return DVDOpenVOBPath( dvd, titlenum, 1 ); } break; case DVD_READ_TITLE_VOBS: if( titlenum == 0 ) return 0; if( dvd->isImageFile ) { return DVDOpenVOBUDF( dvd, titlenum, 0 ); } else { return DVDOpenVOBPath( dvd, titlenum, 0 ); } break; default: if(dvd->verbose >= 1) { fprintf( stderr, "libdvdread: Invalid domain for file open.\n" ); } errno = EINVAL; return NULL; } if( dvd->isImageFile ) { return DVDOpenFileUDF( dvd, filename ); } else { return DVDOpenFilePath( dvd, filename ); }}void DVDCloseFile( dvd_file_t *dvd_file ){ int i; if( dvd_file ) { if( dvd_file->dvd->isImageFile ) { ; } else { for( i = 0; i < 9; ++i ) { if( dvd_file->title_devs[ i ] ) { dvdinput_close( dvd_file->title_devs[i] ); } } } free( dvd_file ); dvd_file = 0; }}static int DVDFileStatVOBUDF(dvd_reader_t *dvd, int title, int menu, dvd_stat_t *statbuf){ char filename[ MAX_UDF_FILE_NAME_LEN ]; uint32_t size; off_t tot_size; off_t parts_size[9]; int nr_parts = 0; int n; if( title == 0 ) { sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" ); } else { sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 ); } if(!UDFFindFile( dvd, filename, &size )) { return -1; } tot_size = size; nr_parts = 1; parts_size[0] = size; if( !menu ) { int cur; for( cur = 2; cur < 10; cur++ ) { sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur ); if( !UDFFindFile( dvd, filename, &size ) ) { break; } parts_size[nr_parts] = size; tot_size += size; nr_parts++; } } statbuf->size = tot_size; statbuf->nr_parts = nr_parts; for(n = 0; n < nr_parts; n++) { statbuf->parts_size[n] = parts_size[n]; } return 0;}static int DVDFileStatVOBPath( dvd_reader_t *dvd, int title, int menu, dvd_stat_t *statbuf ){ char filename[ MAX_UDF_FILE_NAME_LEN ]; char full_path[ PATH_MAX + 1 ]; struct stat fileinfo; off_t tot_size; off_t parts_size[9]; int nr_parts = 0; int n; if( title == 0 ) { sprintf( filename, "VIDEO_TS.VOB" ); } else { sprintf( filename, "VTS_%02d_%d.VOB", title, menu ? 0 : 1 ); } if( !findDVDFile( dvd, filename, full_path ) ) { return -1; } if( stat( full_path, &fileinfo ) < 0 ) { if(dvd->verbose >= 1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -