iso9660重新回顾

读取ISO9660格式文件的过程主要分为3步:

读取PVD,地址是0x210,也可以说是2分16秒,或者LSN=16,其实都是一个地方。用dd命令把碟片从光驱里抓出来,保存成ISO文件放在电脑里,不需要把整张碟抓出,只需要抓取前面的2M字节左右,用来方便分析光盘的结构。

前面说了,第16个扇区的地址,计算起来就是16x2048 = 32k,转成16进制就是0x8000。

用UE打开刚才抓到ISO文件,转到0x8000的地方,就是下面图片的样子。首先看到CD001,就是ISO9660的格式标记。

然后后面在140 offset的地方是path table的扇区地址,156的地方是root dir record,长度是34个字节。一般Linux的标准是读取这个root record,而不是走path table的流程。

通过根记录这个节点,就可以不断遍历整个目录树,但速度会比较慢。如果想一次性读取到所有目录里的文件,就可以走path table的流程,这部分Linux里面没有实现,但普通DVD的软件里面是这样做的。

从图片里高度选中的部分是根记录的入口扇区,可以看出是0x17,也就是23扇区里面就是记录根目录节点的详细资料。



struct iso_primary_descriptor {
	char type			[ISODCL (  1,   1)]; /* 711 */
	char id				[ISODCL (  2,   6)];
	char version			[ISODCL (  7,   7)]; /* 711 */
	char unused1			[ISODCL (  8,   8)];
	char system_id			[ISODCL (  9,  40)]; /* achars */
	char volume_id			[ISODCL ( 41,  72)]; /* dchars */
	char unused2			[ISODCL ( 73,  80)];
	char volume_space_size		[ISODCL ( 81,  88)]; /* 733 */
	char unused3			[ISODCL ( 89, 120)];
	char volume_set_size		[ISODCL (121, 124)]; /* 723 */
	char volume_sequence_number	[ISODCL (125, 128)]; /* 723 */
	char logical_block_size		[ISODCL (129, 132)]; /* 723 */
	char path_table_size		[ISODCL (133, 140)]; /* 733 */
	char type_l_path_table		[ISODCL (141, 144)]; /* 731 */
	char opt_type_l_path_table	[ISODCL (145, 148)]; /* 731 */
	char type_m_path_table		[ISODCL (149, 152)]; /* 732 */
	char opt_type_m_path_table	[ISODCL (153, 156)]; /* 732 */
	char root_directory_record	[ISODCL (157, 190)]; /* 9.1 */
	char volume_set_id		[ISODCL (191, 318)]; /* dchars */
	char publisher_id		[ISODCL (319, 446)]; /* achars */
	char preparer_id		[ISODCL (447, 574)]; /* achars */
	char application_id		[ISODCL (575, 702)]; /* achars */
	char copyright_file_id		[ISODCL (703, 739)]; /* 7.5 dchars */
	char abstract_file_id		[ISODCL (740, 776)]; /* 7.5 dchars */
	char bibliographic_file_id	[ISODCL (777, 813)]; /* 7.5 dchars */
	char creation_date		[ISODCL (814, 830)]; /* 8.4.26.1 */
	char modification_date		[ISODCL (831, 847)]; /* 8.4.26.1 */
	char expiration_date		[ISODCL (848, 864)]; /* 8.4.26.1 */
	char effective_date		[ISODCL (865, 881)]; /* 8.4.26.1 */
	char file_structure_version	[ISODCL (882, 882)]; /* 711 */
	char unused4			[ISODCL (883, 883)];
	char application_data		[ISODCL (884, 1395)];
	char unused5			[ISODCL (1396, 2048)];
};

/* Almost the same as the primary descriptor but two fields are specified */


按照之前的方法计算一下,23x2048 = 46k,用16进制表示为:0xb800,查看相关的数据如下图所示:

第一个项目是当前目录,也就是./目录,然后是当前目录下的其他文件或目录,每一项里面都有extent的地址,如果是文件就指向文件的实际数据入口,如果是目录,则表示子目录的入口。一个记录是目录还是文件是由flag项里面的第2位表示的,一般flag == 0x02就是目录,如果0x00就是文件。如果一个目录的flag == 0x06,则表示它是一个associated file,意思是关联的文件。但根据ecma119的说明,一个目录不应该被定义成关联文件,所以这个地方是有问题的.在Linux下会看不到这个目录,估计是某个条件判断过滤掉了。如最后一个目录是VIDEO_TS,但标记因为是0x06,所以Linux下是看不到的。但是如果进入这个目录的实际位置,也就是0x26的地方,就可以看到里面是有内容的。


根目录信息

这里面的数据结构是dir record,结构体是这样的:

struct iso_directory_record {
	char length			[ISODCL (1, 1)]; /* 711 */
	char ext_attr_length		[ISODCL (2, 2)]; /* 711 */
	char extent			[ISODCL (3, 10)]; /* 733 */
	char size			[ISODCL (11, 18)]; /* 733 */
	char date			[ISODCL (19, 25)]; /* 7 by 711 */
	char flags			[ISODCL (26, 26)];
	char file_unit_size		[ISODCL (27, 27)]; /* 711 */
	char interleave			[ISODCL (28, 28)]; /* 711 */
	char volume_sequence_number	[ISODCL (29, 32)]; /* 723 */
	unsigned char name_len		[ISODCL (33, 33)]; /* 711 */
	char name			[0];
} __attribute__((packed));

进入0x26扇区,也就是0x13000的位置:

可以看到VIDEO_TS.VOB这些文件,就是刚才VIDEO_TS目录下面的文件了。



下面再写一下path table的方式,从之前PVD的地方看到,path table的入口是0x13,也就是0x9800的位置。这里只记录目录的入口,而且所有目录部分层次,都是按照平摊的方式列出,那么假如一个扇区放不完会怎么办,那么理论上应该要继续判断下一个扇区,因为Linux里面没有实现,实际上也还没有遇到过这种情况,暂时不做讨论了。

从path table上也能找到VIDEO_TS这个目录的入口地址同样为0x26.


路径表的结构比较简单:

struct iso_path_table{
	unsigned char  name_len[2];	/* 721 */
	char extent[4];		/* 731 */
	char  parent[2];	/* 721 */
	char name[0];
} __attribute__((packed));



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值