[libdvdnav-devel] [PATCH 2/2] Read the first File Set Descriptor Sequence from the LVD

Jean-Baptiste Kempf jb at videolan.org
Thu Jul 31 04:17:08 CEST 2014


See ECMA TR-071 and ECMA-167

libdvdread is very likely to fail on discs/images that store their File
Set Descriptor at the end of the disc/image rather than at the
beginning. This is due to the "strategy" libdvdread uses to find it:
libdvdread scans sequentially from the beginning of the disc/image for
the File Set Descriptor and identifies it by a single byte tag.

Aside from wasting lots of time on discs/images that store their File
Set Descriptor at the end there is quite a good chance to stumble
across a random data block that accidentally starts with this tag (and
failing on it) before finding the real File Set Descriptor.

As far as I can see, at least CDBurnerXP seems to (be able to) create
such images - at least if my interpretation of the Implementation
Identifier "NMS DVDProLib" is correct.

Original patch by Mario 'BitKoenig' Holbe
---
 src/dvd_udf.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/dvd_udf.c b/src/dvd_udf.c
index 7302b55..82885a2 100644
--- a/src/dvd_udf.c
+++ b/src/dvd_udf.c
@@ -82,6 +82,7 @@ struct Partition {
   uint32_t AccessType;
   uint32_t Start;
   uint32_t Length;
+  uint32_t FSD_Location;
 };
 
 struct AD {
@@ -773,8 +774,16 @@ static int UDFFindPartition( dvd_reader_t *device, int partnum,
         /* Logical Volume Descriptor */
         if( UDFLogVolume( LogBlock, part->VolumeDesc ) ) {
           /* TODO: sector size wrong! */
-        } else
-          volvalid = 1;
+        } else {
+          struct AD ad;
+          UDFLongAD( LogBlock + 248, &ad);
+          if(part->Number == ad.Partition) {
+            part->FSD_Location = ad.Location;
+            volvalid = 1;
+          } else {
+            /* TODO: Oups, how to handle this? */
+          }
+        }
       }
 
     } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 )
@@ -817,7 +826,10 @@ uint32_t UDFFindFile( dvd_reader_t *device, char *filename,
     SetUDFCache(device, PartitionCache, 0, &partition);
 
     /* Find root dir ICB */
-    lbnum = partition.Start;
+    lbnum = partition.Start + partition.FSD_Location;
+    /*
+    fprintf(stderr, "Looking for FSD at 0x%x\n", lbnum);
+    */
     do {
       if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 )
         TagID = 0;
-- 
2.0.3



More information about the libdvdnav-devel mailing list