2016-09-21 18 views
1

Я пытаюсь читать простые 2048 байт размера секторов данных с компакт-диска данных на OS X.Как читать простые сектора данных (mode1) с компакт-диска на OS X

Но когда я открываю устройство, такое как «/ dev/disk8», я получаю секторы размером 2352 с 16-байтным заголовком перед фактическими данными режима 1 каждого сектора.

Даже с BSD инструментами, такими как шестнадцатеричное это можно увидеть, при чтении старой CD, сделанного Apple:

$ 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.

Как я могу сделать эту работу в своем приложении без необходимости удаления дополнительных данных на отдельный шаг?

Я просмотрел различные функции ioctl в «IOCDMediaBSDClient.h» и «IOCDTypes.h», но не смог найти тот, который позволяет мне указать, что я хочу получить только простой контент данных из секторов.

Я также считаю, что мой существующий код, который я написал около 15 лет назад, смог справиться с этим по своему желанию, но с тех пор что-то изменилось в OS X, нарушив мой старый код. И теперь я не могу понять, как это исправить. В этом коде используется ioctl с DKIOCCDREAD с параметрами sectorArea=kCDSectorAreaUser и sectorType=kCDSectorTypeMode1. Но это дает мне 16-байтовый заголовок, как и обычный вызов read, хотя Mode1 означает, что я должен получать 2048 байтовых секторов без заголовков, насколько я понимаю.

+1

Вы пытались использовать узел устройства rdisk вместо узла 'disk'? (т. е. '/ dev/rdisk8') – pmdj

+1

Как ни странно,' hexdump -n 512 -C/dev/rdisk8' дает ошибку («Недопустимый аргумент»). Но когда я использую open() на «rdisk», он работает с функцией 'ioctl'. Итак, оказывается, что в моем старом коде ничего не сломалось, я просто испортился, используя правильное имя диска (я использовал rdisk изначально, но позже изменил его на диск, потому что не видел разницы при доступе к «нормальным» дискам). Вам нравится писать правильный ответ? В противном случае я это сделаю. –

+0

Прохладный, рад, что получилось ОК. Счастлив написать ответ. :-) – pmdj

ответ

1

Как установлено в разделе комментариев, ответ заключается в использовании символьного устройства (rdisk), а не узла блока (диска). Насколько мне известно, различие недостаточно хорошо документировано, а для жестких дисков и твердотельных накопителей на самом деле довольно мало - в большинстве случаев вы можете использовать их. Для оптических дисков по какой-либо причине существенно отличается.

Я изучил это некоторое время назад, но, к сожалению, я забыл детали этого. Если вас это интересует, вы найдете реализацию в пакетах исходных кодов «IOStorageFamily» и «IOCDStorageFamily» на сайте Apple https://opensource.apple.com/.

Файлы кода, которые вы используете, это те, что относятся к «клиентам BSD» - IOMediaBSDClient.cpp/.h в IOStorageFamily и IOMediaBSDClient.cpp/.h для компакт-дисков. Элементы ioctls устройства блока («диска») обрабатываются сначала в dkioctl_bdev(), а затем перенаправляются на общий dkioctl(), который, в свою очередь, вызывает метод IOCDMediaBSDClient::ioctl(). Символьное устройство («rdisk») вместо этого использует dkioctl_cdev().

+0

Также необходимо использовать вызов 'ioctl (DKIOCCDREAD)' для чтения с диска, а не 'read()', поскольку последний просто приводит к возврату ошибки. Это также означает, что нельзя использовать 'hexdump' или' dd' для копирования секторов данных с компакт-диска, я думаю. На диске вопросов vs rdisk - у меня сложилось впечатление, что rdisk обходит кэш-память дискового хранилища ОС, тогда как на диске нет. Не уверен в этом. (См. Также http://superuser.com/a/631601/41872) –

+1

Собственно, в этом комментарии объясняется, что делает rdisk (т.е. небуферизованный доступ, который может потребовать правильного выравнивания): http://superuser.com/a/892768/ 41872 –