📄 udf.c
字号:
do { if( !UDFReadLB( partition.dvdhandle, i_lba++, 1, pi_lb ) ) { i_tag_id = 0; } else { UDFDescriptor( pi_lb , &i_tag_id ); } if( i_tag_id == 261 ) { UDFFileEntry( pi_lb, pi_file_type, p_file, partition ); return 1; } } while( ( i_lba <= partition.i_start + icb.i_location + ( icb.i_length - 1 ) / DVD_LB_SIZE ) && ( i_tag_id != 261 ) ); return 0;}/***************************************************************************** * UDFScanDir: serach filename in dir ***************************************************************************** * Dir: Location of directory to scan * FileName: Name of file to look for * FileICB: Location of ICB of the found file * return 1 on success, 0 on error; *****************************************************************************/static int UDFScanDir( struct ad_s dir, char * psz_filename, struct ad_s * p_file_icb, struct partition_s partition ){ uint8_t pi_lb[2*DVD_LB_SIZE]; uint32_t i_lba; uint16_t i_tag_id; uint8_t i_file_char; char psz_temp[DVD_LB_SIZE]; unsigned int p; /* Scan dir for ICB of file */ i_lba = partition.i_start + dir.i_location;#if 0 do { if( !UDFReadLB( partition.dvdhandle, i_lba++, 1, pi_lb ) ) { i_tag_id = 0; } else { p=0; while( p < DVD_LB_SIZE ) { UDFDescriptor( &pi_lb[p], &i_tag_id ); if( i_tag_id == 257 ) { p += UDFFileIdentifier( &pi_lb[p], &i_file_char, psz_temp, p_file_icb, partition ); if( !strcasecmp( psz_filename, psz_temp ) ) { return 1; } } else { p = DVD_LB_SIZE; } } } } while( i_lba <= partition.i_start + dir.i_location + ( dir.i_length - 1 ) / DVD_LB_SIZE );#else if( UDFReadLB( partition.dvdhandle, i_lba, 2, pi_lb ) <= 0 ) { return 0; } p = 0; while( p < dir.i_length ) { if( p > DVD_LB_SIZE ) { ++i_lba; p -= DVD_LB_SIZE; dir.i_length -= DVD_LB_SIZE; if( UDFReadLB( partition.dvdhandle, i_lba, 2, pi_lb ) <= 0 ) { return 0; } } UDFDescriptor( &pi_lb[p], &i_tag_id ); if( i_tag_id == 257 ) { p += UDFFileIdentifier( &pi_lb[p], &i_file_char, psz_temp, p_file_icb, partition ); if( !strcasecmp( psz_filename, psz_temp ) ) { return 1; } } else { return 0; } }#endif return 0;}/***************************************************************************** * UDFFindPartition: looks for a partition on the disc ***************************************************************************** * partnum: number of the partition, starting at 0 * part: structure to fill with the partition information * return 1 if partition found, 0 on error; *****************************************************************************/static int UDFFindPartition( int i_part_nb, struct partition_s *p_partition ){ uint8_t pi_lb[DVD_LB_SIZE]; uint8_t pi_anchor[DVD_LB_SIZE]; uint16_t i_tag_id; uint32_t i_lba; uint32_t i_MVDS_location; uint32_t i_MVDS_length; uint32_t i_last_sector; vlc_bool_t b_term; vlc_bool_t b_vol_valid; int i; /* Find Anchor */ i_last_sector = 0; /* try #1, prime anchor */ i_lba = 256; b_term = 0; /* Search anchor loop */ while( 1 ) { if( UDFReadLB( p_partition->dvdhandle, i_lba, 1, pi_anchor ) ) { UDFDescriptor( pi_anchor, &i_tag_id ); } else { i_tag_id = 0; } if( i_tag_id != 2 ) { /* not an anchor? */ if( b_term ) { /* final try failed */ return 0; } if( i_last_sector ) { /* we already found the last sector * try #3, alternative backup anchor */ i_lba = i_last_sector; /* but that's just about enough, then! */ b_term = 1; } else { /* TODO: find last sector of the disc (this is optional) */ if( i_last_sector ) { /* try #2, backup anchor */ i_lba = i_last_sector - 256; } else { /* unable to find last sector */ return 0; } } } else { /* it is an anchor! continue... */ break; } } /* main volume descriptor */ UDFExtentAD( &pi_anchor[16], &i_MVDS_length, &i_MVDS_location ); p_partition->b_valid = 0; b_vol_valid = 0; p_partition->pi_volume_desc[0] = '\0'; i = 1; /* Find Volume Descriptor */ do { i_lba = i_MVDS_location; do { if( !UDFReadLB( p_partition->dvdhandle, i_lba++, 1, pi_lb ) ) { i_tag_id = 0; } else { UDFDescriptor( pi_lb, &i_tag_id ); } if( ( i_tag_id == 5 ) && ( !p_partition->b_valid ) ) { /* Partition Descriptor */ UDFPartition( pi_lb, &p_partition->i_flags, &p_partition->i_number, p_partition->pi_contents, &p_partition->i_start, &p_partition->i_length ); p_partition->b_valid = ( i_part_nb == p_partition->i_number ); } else if( ( i_tag_id == 6 ) && ( !b_vol_valid) ) { /* Logical Volume Descriptor */ if( UDFLogVolume( pi_lb , p_partition->pi_volume_desc ) ) { /* TODO: sector size wrong! */ } else { b_vol_valid = 1; } } } while( ( i_lba <= i_MVDS_location + ( i_MVDS_length - 1 ) / DVD_LB_SIZE ) && ( i_tag_id != 8 ) && ( ( !p_partition->b_valid ) || ( !b_vol_valid ) ) ); if( ( !p_partition->b_valid ) || ( !b_vol_valid ) ) { /* backup volume descriptor */ UDFExtentAD( &pi_anchor[24], &i_MVDS_length, &i_MVDS_location ); } } while( i-- && ( ( !p_partition->b_valid ) || ( !b_vol_valid ) ) ); /* we only care for the partition, not the volume */ return( p_partition->b_valid);}/***************************************************************************** * DVDUDFFindFile: looks for a file on the UDF disc/imagefile ***************************************************************************** * Path has to be the absolute pathname on the UDF filesystem, * starting with '/'. * returns absolute LB number, or 0 on error *****************************************************************************/uint32_t DVDUDFFindFile( dvdcss_handle dvdhandle, char * psz_path ){ struct partition_s partition; struct ad_s root_icb; struct ad_s file; struct ad_s icb; uint32_t i_lba; uint16_t i_tag_id; uint8_t pi_lb[DVD_LB_SIZE]; uint8_t i_file_type; char psz_tokenline[DVD_LB_SIZE] = ""; char * psz_token; int i_partition; strcat( psz_tokenline, psz_path ); /* Init file descriptor of UDF filesystem (== DVD) */ partition.dvdhandle = dvdhandle; /* Find partition 0, standard partition for DVD-Video */ i_partition = 0; if( !UDFFindPartition( i_partition, &partition ) ) {#if 0 intf_ErrMsg( "dvd error: partition 0 not found" );#endif return 0; } /* Find root dir ICB */ i_lba = partition.i_start; do { if( !UDFReadLB( dvdhandle, i_lba++, 1, pi_lb ) ) { i_tag_id = 0; } else { UDFDescriptor( pi_lb, &i_tag_id ); } if( i_tag_id == 256 ) { /* File Set Descriptor */ UDFAD( &pi_lb[400], &root_icb, UDFADlong, partition ); } } while( ( i_lba < partition.i_start + partition.i_length ) && ( i_tag_id != 8) && ( i_tag_id != 256 ) ); if( i_tag_id != 256 ) {#if 0 intf_ErrMsg( "dvd error: bad UDF descriptor" );#endif return 0; } if( root_icb.i_partition != i_partition ) {#if 0 intf_ErrMsg( "dvd error: bad UDF partition" );#endif return 0; } /* Find root dir */ if( !UDFMapICB( root_icb, &i_file_type, &file, partition ) ) {#if 0 intf_ErrMsg( "dvd error: can't find root dir" );#endif return 0; } /* root dir should be dir */ if( i_file_type != 4 ) {#if 0 intf_ErrMsg( "dvd error: root dir error" );#endif return 0; } /* Tokenize filepath */ psz_token = strtok( psz_tokenline, "/" ); while( psz_token ) { if( !UDFScanDir( file, psz_token, &icb, partition ) ) {#if 0 intf_ErrMsg( "dvd error: scan dir error" );#endif return 0; } if( !UDFMapICB ( icb, &i_file_type, &file, partition ) ) {#if 0 intf_ErrMsg( "dvd error: ICB error" );#endif return 0; } psz_token = strtok( NULL, "/" ); } return partition.i_start + file.i_location;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -