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

📄 udf.c

📁 VLC媒体播放程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * udf.c: udf filesystem tools. ***************************************************************************** * Mainly used to find asolute logical block adress of *.ifo files. It only * contains the basic udf handling functions ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN * $Id: udf.c,v 1.5 2003/03/03 14:21:08 gbazin Exp $ * * Author: St閜hane Borel <stef@via.ecp.fr> * * based on: *  - dvdudf by Christian Wolff <scarabaeus@convergence.de> *  - fixes by Billy Biggs <vektor@dumbterm.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <stdio.h>#include <string.h>#include <fcntl.h>#include <vlc/vlc.h>#ifdef HAVE_UNISTD_H#   include <unistd.h>#endif#ifdef STRNCASECMP_IN_STRINGS_H#   include <strings.h>#endif#ifdef GOD_DAMN_DMCA#   include "dvdcss.h"#else#   include <dvdcss/dvdcss.h>#endif#include "dvd.h"#include "ifo.h"#define UDFADshort      1#define UDFADlong       2#define UDFADext        4typedef struct partition_s{    vlc_bool_t    b_valid;    uint8_t       pi_volume_desc[128];    uint16_t      i_flags;    uint16_t      i_number;    uint8_t       pi_contents[32];    uint32_t      i_access_type;    uint32_t      i_start;    uint32_t      i_length;    dvdcss_handle dvdhandle;} partition_t;typedef struct ad_s{    uint32_t    i_location;    uint32_t    i_length;    uint8_t     i_flags;    uint16_t    i_partition;} ad_t;/* for direct data access, LSB first */#define GETN1(p) ((uint8_t)pi_data[p])#define GETN2(p) ((uint16_t)pi_data[p]|((uint16_t)pi_data[(p)+1]<<8))#define GETN4(p) ((uint32_t)pi_data[p]|((uint32_t)pi_data[(p)+1]<<8)|((uint32_t)pi_data[(p)+2]<<16)|((uint32_t)pi_data[(p)+3]<<24))#define GETN(p,n,target) memcpy(target,&pi_data[p],n)/***************************************************************************** * UDFReadLB: reads absolute Logical Block of the disc ***************************************************************************** * Returns number of read bytes on success, 0 on error *****************************************************************************/static int UDFReadLB( dvdcss_handle dvdhandle, off_t i_lba,                      size_t i_block_count, uint8_t *pi_data ){    if( dvdcss_seek( dvdhandle, i_lba, DVDCSS_NOFLAGS ) < 0 )    {#if 0        intf_ErrMsg( "dvd error: block %i not found", i_lba );#endif        return 0;    }    return dvdcss_read( dvdhandle, pi_data, i_block_count, DVDCSS_NOFLAGS );}/***************************************************************************** * UDFDecode: decode unicode encoded udf data *****************************************************************************/static int UDFDecode( uint8_t * pi_data, int i_len, char * psz_target ){    int     p = 1;    int     i = 0;    if( !( pi_data[0] & 0x18 ) )    {        psz_target[0] = '\0';        return 0;    }    if( pi_data[0] & 0x10 )    {        /* ignore MSB of unicode16 */        p++;        while( p < i_len )        {            psz_target[i++] = pi_data[p+=2];        }    }    else    {        while( p < i_len )        {            psz_target[i++] = pi_data[p++];        }    }    psz_target[i]='\0';    return 0;}#if 0/** * **/int UDFEntity (uint8_t *data, uint8_t *Flags, char *Identifier){    Flags[0] = data[0];    strncpy (Identifier, &data[1], 5);    return 0;}#endif/***************************************************************************** * UDFDescriptor: gives a tag ID from your data to find out what it refers to *****************************************************************************/static int UDFDescriptor( uint8_t * pi_data, uint16_t * pi_tag_id ){    pi_tag_id[0] = GETN2( 0 );    /* TODO: check CRC 'n stuff */    return 0;}/***************************************************************************** * UDFExtendAD: main volume information *****************************************************************************/static int UDFExtentAD ( uint8_t * pi_data, uint32_t * pi_length,                         uint32_t * pi_location){    pi_length[0] = GETN4( 0 );    pi_location[0] = GETN4( 4 );    return 0;}/***************************************************************************** * UDFAD: file set information *****************************************************************************/static int UDFAD( uint8_t * pi_data, struct ad_s * p_ad, uint8_t i_type,                  struct partition_s partition ){    p_ad->i_length = GETN4( 0 );    p_ad->i_flags = p_ad->i_length >> 30;    p_ad->i_length &= 0x3FFFFFFF;    switch( i_type )    {        case UDFADshort:            p_ad->i_location = GETN4( 4 );            /* use number of current partition */            p_ad->i_partition = partition.i_number;             break;        case UDFADlong:            p_ad->i_location = GETN4( 4 );            p_ad->i_partition = GETN2( 8 );            break;        case UDFADext:            p_ad->i_location = GETN4( 12 );            p_ad->i_partition = GETN2( 16 );            break;    }    return 0;}/***************************************************************************** * UDFICB: takes Information Control Block from pi_data *****************************************************************************/static int UDFICB( uint8_t * pi_data, uint8_t * pi_file_type,                   uint16_t * pi_flags){    pi_file_type[0] = GETN1( 11 );    pi_flags[0] = GETN2( 18 );    return 0;}/***************************************************************************** * UDFPartition: gets partition descriptor *****************************************************************************/static int UDFPartition( uint8_t * pi_data, uint16_t * pi_flags,                         uint16_t * pi_nb, byte_t * ps_contents,                         uint32_t * pi_start, uint32_t * pi_length ){    pi_flags[0] = GETN2( 20 );    pi_nb[0] = GETN2( 22 );    GETN( 24, 32, ps_contents );    pi_start[0] = GETN4( 188 );    pi_length[0] = GETN4( 192 );    return 0;}/***************************************************************************** * UDFLogVolume: reads the volume descriptor and checks the parameters ***************************************************************************** * Returns 0 on OK, 1 on error *****************************************************************************/static int UDFLogVolume( uint8_t * pi_data, byte_t * p_volume_descriptor ){    uint32_t i_lb_size;    uint32_t i_MT_L;    uint32_t i_N_PM;    UDFDecode( &pi_data[84], 128, (char *)p_volume_descriptor );    i_lb_size = GETN4( 212 );        /* should be 2048 */    i_MT_L = GETN4( 264 );        /* should be 6 */    i_N_PM = GETN4( 268 );        /* should be 1 */    if( i_lb_size != DVD_LB_SIZE )    {#if 0        intf_ErrMsg( "dvd error: invalid UDF sector size (%d)", i_lb_size );#endif        return 1;    }    return 0;}/***************************************************************************** * UDFFileEntry: fills a ad_t struct with information at pi_data *****************************************************************************/static int UDFFileEntry( uint8_t * pi_data, uint8_t * pi_file_type,                         struct ad_s * p_ad, struct partition_s partition ){    uint8_t  i_file_type;    uint16_t i_flags;    uint32_t i_L_EA;    uint32_t i_L_AD;    unsigned int p;    UDFICB( &pi_data[16], &i_file_type, &i_flags );    pi_file_type[0] = i_file_type;    i_L_EA = GETN4( 168 );    i_L_AD = GETN4( 172 );    p = 176 + i_L_EA;    while( p < 176 + i_L_EA + i_L_AD )    {        switch( i_flags & 0x07 )        {        case 0:            UDFAD( &pi_data[p], p_ad, UDFADshort, partition );            p += 0x08;            break;        case 1:            UDFAD( &pi_data[p], p_ad, UDFADlong, partition );            p += 0x10;            break;        case 2:            UDFAD( &pi_data[p], p_ad, UDFADext, partition );            p += 0x14;            break;        case 3:            switch( i_L_AD )            {            case 0x08:                UDFAD( &pi_data[p], p_ad, UDFADshort, partition );                break;            case 0x10:                UDFAD( &pi_data[p], p_ad, UDFADlong, partition );                break;            case 0x14:                UDFAD( &pi_data[p], p_ad, UDFADext, partition );                break;            }        default:            p += i_L_AD;            break;        }    }    return 0;}/***************************************************************************** * UDFFileIdentifier: gives filename and characteristics of pi_data *****************************************************************************/static int UDFFileIdentifier( uint8_t * pi_data, uint8_t * pi_file_info,                              char * psz_filename, struct ad_s * p_file_icb,                              struct partition_s partition ){    uint8_t  i_L_FI;    uint16_t i_L_IU;    pi_file_info[0] = GETN1( 18 );    i_L_FI = GETN1( 19 );    UDFAD( &pi_data[20], p_file_icb, UDFADlong, partition );    i_L_IU = GETN2( 36 );    if( i_L_FI )    {        UDFDecode( &pi_data[38+i_L_IU], i_L_FI, psz_filename );    }    else    {        psz_filename[0]='\0';    }    return  4 * ( ( 38 + i_L_FI + i_L_IU + 3 ) / 4 );}/***************************************************************************** * UDFMapICB: Maps ICB to FileAD ***************************************************************************** * ICB: Location of ICB of directory to scan * FileType: Type of the file * File: Location of file the ICB is pointing to * return 1 on success, 0 on error; *****************************************************************************/static int UDFMapICB( struct ad_s icb, uint8_t * pi_file_type,                      struct ad_s * p_file, struct partition_s partition ){    uint8_t  pi_lb[DVD_LB_SIZE];    uint32_t i_lba;    uint16_t i_tag_id;    i_lba = partition.i_start + icb.i_location;

⌨️ 快捷键说明

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