Чтение файловой системы UDF, раздел метаданных bluray, libdvdread с образами ISO - PullRequest
3 голосов
/ 12 января 2012

Так что это может быть слишком конкретным и слишком большим для того, чтобы кто-то мог его прочитать, чтобы кто-то мог помочь.Но, может быть, есть кто-то, кто делал это раньше.

В настоящее время я использую надежную, но не очень точную библиотеку libdvdread для чтения файлов / устройств ISO.Но конкретная реализация не так важна в этом случае.Больше о том, КАК читать файловые системы UDF.Я прочитал как PDF-файлы Ecma-167, так и udf260, много.

Итак, сначала давайте посмотрим на ISO-образ из IMGBURN, который работает, точно так же, как изображение, скопированное из розничной продажи..

Блоки расположены следующим образом:

Block  32 TagID:    1 TAGID_PRI_VOL
Block  33 TagID:    4 TAGID_IMP_VOL
Block  34 TagID:    5 TAGID_PARTITION
Block  35 TagID:    6 TAGID_LOGVOL
Block  36 TagID:    7 TAGID_UNALLOC_SPACE
Block  37 TagID:    8 TAGID_TERM
Block  64 TagID:    9 TAGID_LOGVOL_INTEGRITY
Block  65 TagID:    8 TAGID_TERM
Block 256 TagID:    2 TAGID_ANCHOR
Block 288 TagID:  266 TAGID_EXTFENTRY
Block 320 TagID:  256 TAGID_FSD
Block 321 TagID:    8 TAGID_TERM
Block 322 TagID:  266 TAGID_EXTFENTRY
Block 323 TagID:  257 TAGID_FID
Block 324 TagID:  266 TAGID_EXTFENTRY
Block 325 TagID:  266 TAGID_EXTFENTRY
Block 326 TagID:  257 TAGID_FID
Block 327 TagID:  266 TAGID_EXTFENTRY

Итак, мы начинаем читать образ ISO;

* Read Block 256 which is    2 TAGID_ANCHOR
* Read Block  32 which is    1 TAGID_PRI_VOL
* Read Block  33 which is    4 TAGID_IMP_VOL
* Read Block  34 which is    5 TAGID_PARTITION
Partiton: number 0, start 288, length 2291200, AccessType 1
* Read Block  35 which is    6 TAGID_LOGVOL
LogVolume 2048:70:2
Volume 0 type 01 (len 6) Seq 0001 Part 0000
Volume 1 type 02:
Partition identifier: '*UDF Metadata Partition'
 Metadata Partition MainLoc 00000000, MirrorLoc 0022F5A9, BitmapLoc FFFFFFFF, AllocSize 00000020, AlignSize 0020, Flags 1.
returning Start 288
Found partition at 288 length 2291200
Starting scan from 288 (metadata adjusted)

Пока все хорошо.Вы можете видеть, что я взял «расположение основного файла метаданных», в этом примере 0, и добавил его в начало раздела, чтобы искать FSD.Похоже, что это работает даже с примерами, где «местоположение основного файла метаданных» не равно 0. Подробнее об этом позже.

Теперь ищем FSD, первый элемент, который мы находим:

* Read Block 288 which is  266 TAGID_EXTFENTRY
TagID 266 with filetype 250
   Metadata Main at location 32 (+partition.start 320)

Ecma-167 определяет тип файла = 250 имеет «основной файл метаданных», а AD.Location указывает на метаданные.Также можно найти filetype = 251 (зеркальный файл метаданных)

Я использую местоположение «основного файла метаданных» (здесь, 32) в качестве косвенного указателя, где «действительно» искать FSD.По какой-то причине это раздел. Начало + Местоположение (288 + 32) = 320.

В блоке 320 мы находим FSD.Так что, возможно, я на правильном пути.

Now Scanning from 320
* Read Block 320 which is  256 TAGID_FSD
RootICB at 2 length 2048
MapICB starting at 320,2 -> 322

Отлично, мы читаем FSD, и у него есть RootICB в "+2".Теперь я ожидал, что это будет «partition.Start + 2» (288 + 2), но это не работает.Что работает, так это "FSD_Location + 2" (320 + 2).Может ли это быть действительно так?

В ISO-дисках DVD FSD_Location = 0 (первый блок в разделе, так как на пути нет EXTFileInfo + 250), поэтому использование этой логики все еще работает.

Предположим, что это правильно;

* Read Block 322 which is  266 TAGID_EXTFENTRY
libdvdread: reading AD chain 0
UDFMapICB TagID 266 ExtFile with filetype 4
Part.Start 288 FSD loc 320 RootICB 2 (len 2048) File has loc 3

Таким образом, блок на 322 действительно является ExtFileInfo, filetype == 4 (каталог) и живет в местоположении = +3.Опять же, это выглядит как "fsd_location + 3" = 323.

Found '/' at 323 (size 152).
* Read Block 323 which is  257 TAGID_FID
DVDReadDir(.)
DVDReadDir(BDMV)
etc

Success.В список попадает все содержимое.

Вот тут я запутался.Я использую OSX "newfs_udf", чтобы создать себе тестовый образ UDF;

# mkfile 1G roger.iso
# newfs_udf -eu -r 2.60 -v HIGHLANDER roger.iso
# hdiutil attach -imagekey diskimage-class=CRawDiskImage -nomount roger.iso
# hdiutil mount -nobrowse roger.iso
# mkdir /Volumes/HIGHLANDER/A.DIRECTORY.ENTRY

Блоки:

Block  20 TagID:    1 TAGID_PRI_VOL
Block  21 TagID:    4 TAGID_IMP_VOL
Block  22 TagID:    5 TAGID_PARTITION
Block  23 TagID:    6 TAGID_LOGVOL
Block  24 TagID:    7 TAGID_UNALLOC_SPACE
Block  25 TagID:    8 TAGID_TERM
Block  36 TagID:    9 TAGID_LOGVOL_INTEGRITY
Block  37 TagID:    8 TAGID_TERM
Block 256 TagID:    2 TAGID_ANCHOR
Block 257 TagID:  264 TAGID_SPACE_BITMAP
Block 289 TagID:  266 TAGID_EXTFENTRY
Block 290 TagID:  266 TAGID_EXTFENTRY
Block 291 TagID:  256 TAGID_FSD
Block 292 TagID:  266 TAGID_EXTFENTRY
Block 293 TagID:  266 TAGID_EXTFENTRY
Block 294 TagID:  266 TAGID_EXTFENTRY
Block 295 TagID:  266 TAGID_EXTFENTRY
Block 296 TagID:  266 TAGID_EXTFENTRY
Block 323 TagID:  264 TAGID_SPACE_BITMAP
Block 449 TagID:  259 TAGID_INDIRECTENTRY

Чтение этого ISO также работает хорошо, по крайней мере на начальном этапе;

* Read Block 256 which is    2 TAGID_ANCHOR
* Read Block  20 which is    1 TAGID_PRI_VOL
* Read Block  21 which is    4 TAGID_IMP_VOL
* Read Block  22 which is    5 TAGID_PARTITION
Partiton: number 0, start 257, length 523774, AccessType 4
* Read Block  23 which is    6 TAGID_LOGVOL
LogVolume 2048:70:2
Volume 0 type 01 (len 6) Seq 0001 Part 0000
Volume 1 type 02:
Partition identifier: '*UDF Metadata Partition'
 Metadata Partition MainLoc 00000020, MirrorLoc 0007FDFD, BitmapLoc 00000021, AllocSize 00000020, AlignSize 0001, Flags 0.
returning Start 257
Found partition at 257 length 523774
Starting scan from 289 (metadata adjusted)

* Read Block 289 which is  266 TAGID_EXTFENTRY
TagID 266 with filetype 250
   Metadata Main at location 34 (+partition.start 291)

* Read Block 291 which is  256 TAGID_FSD
RootICB at 1 length 2048

* Read Block 292 which is  266 TAGID_EXTFENTRY
UDFMapICB TagID 266 ExtFile with filetype 4
Part.Start 257 FSD loc 291 RootICB 1 (len 2048) File has loc 34

Обратите внимание, что раздел метаданных здесь +32, добавив, что мы правильно находим ExtFileInfo + Filetype = 250.Тогда это +34, что правильно дает нам FSD!

У FSD есть RootICB в +34, опять же из FSD, что составляет 291 + 34 = 325.

И оно потеряно.Я бы предположил, что это ДОЛЖНО быть 292, но;

... В списке блоков вы можете видеть, что вообще нет FID.Если посмотреть на hexdump этого ISO-образа, в блоке 292 можно найти «A.DIRECTORY.ENTRY», который является ExtFileEntry.Тот самый, который отправил нас на поиски metadata-main-file-location.

Я думал, что ExtFileInfo содержит только один (1) файловый дескриптор с ICB, указывающим на его данные.И все же, внутри этого блока со смещением +380 или около того у нас есть root (null), "A.DIRECTORY.ENTRY" и ".Trashes".

Я думаю, мой вопрос заключается в том, сжимает ли OSX FIDв ExtFileEntry как-нибудь?и обойтись без блоков FID.Это "действительный"?Как я могу обнаружить эту ситуацию?Есть ли что-то в этом ExtFileInfo, которое указывает, что я не должен «следовать за Location, чтобы искать FID» и «продолжать анализировать этот блок для большего количества записей».

При вычислении ICB я должен использовать «fsd_location + icb.location "для каталогов, но с файлами (для чтения фактических данных файла) я должен использовать" partition.Start + icb.location ".Это работает, как и ожидалось (список каталогов и файлы не имеют различий), но это не кажется правильным.

Если вы все это прочитали, вы потрясающие :) Теперь, если вы могли бы просто дать мне несколько подсказок ...

1 Ответ

4 голосов
/ 13 января 2012

ОК. Я чувствую, что все поняла, как из источников ECMA 167, так и из источников BSD UDF. Отсутствие магии заключалось в том, что тип ICBTAG.Flags = 3, где вместо списка «AD» в конце блока он помещает фактическое «содержимое файла» в пространство AD. Какой-то стиль «экономии пространства», если размер файла меньше 2048 байт.

Также отменено использование FSD в качестве смещения при наличии метаданных. Все содержимое каталога должно содержаться в файле метаданных (основной и зеркальный).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...