【发布时间】:2017-01-29 13:01:55
【问题描述】:
我正在尝试从 OS X 上的数据 CD 中读取 2048 字节大小的普通数据扇区。
但是当我打开诸如“/dev/disk8”之类的设备时,我得到大小为 2352 的扇区,每个扇区的实际 Mode1 数据之前有一个 16 字节的标头。
即使使用 hexdump 等 BSD 工具,在读取 Apple 制作的较旧 CD 时也可以看到:
$ hexdump -n 512 -C /dev/disk8
00000000 00 ff ff ff ff ff ff ff ff ff ff 00 00 02 00 01 |................|
00000010 45 52 08 00 00 05 00 00 00 01 00 01 00 00 00 00 |ER..............|
00000020 00 04 00 00 00 10 00 05 00 01 00 00 00 1e 00 19 |................|
00000030 ff ff 00 00 00 41 00 05 07 01 00 00 00 4f 00 1f |.....A.......O..|
00000040 f8 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
实际扇区的数据从偏移量 0x10 开始,带有“ER”。但是“ER”应该在偏移量 0 处。
如何在我自己的应用程序中进行这项工作,而无需在单独的步骤中删除额外的数据?
我查看了“IOCDMediaBSDClient.h”和“IOCDTypes.h”中的各种ioctl 函数,但我找不到一个可以让我指定我只想从扇区中获取纯数据内容的函数。
我也相信我大约 15 年前编写的现有代码当时能够按需要处理这个问题,但从那时起 OS X 发生了一些变化,破坏了我的旧代码。现在我无法弄清楚如何解决这个问题。该代码使用ioctl 和DKIOCCDREAD,参数sectorArea=kCDSectorAreaUser 和sectorType=kCDSectorTypeMode1。但这给了我 16 字节的标头,就像普通的 read 调用一样,尽管据我了解,模式 1 意味着我应该得到没有任何标头的 2048 字节扇区。
【问题讨论】:
-
您是否尝试过使用
rdisk设备节点而不是disk节点? (即/dev/rdisk8) -
奇怪的是,
hexdump -n 512 -C /dev/rdisk8给出了一个错误(“无效参数”)。但是当我在“rdisk”上使用 open() 时,它可以与ioctl函数一起使用。所以,事实证明我的旧代码没有任何问题,我只是搞砸了使用正确的磁盘名称(我最初使用 rdisk 但后来将其更改为磁盘,因为我在访问“普通”磁盘时没有发现任何区别)。你喜欢写一个正确的答案吗?否则,我会做的。 -
酷,很高兴一切顺利。很高兴写一个答案。 :-)
-
hexdump -n 512 可能给出“无效参数”错误的原因是读取不是块对齐的。您需要使用块大小的倍数。 (如果无法说服
hexdump使用特定的块大小,则可能通过dd bs=管道) -
dd if=/dev/rdisk8 ibs=2352 obs=2048 count=1 | hexdump -C有点工作 - 它读取 CD 扇区但不会将它们转换为 2048,而且它似乎也无法跳过每个 2352 字节扇区的前 16 个字节,无论如何。因此,使用像dd这样的 cmd 复制 CD 数据扇区似乎仍然是不可能的,但这并不是这个问题的一部分。