diff -ruib ../../../../versions/libdvdread_patch1/libdvdread/src/dvd_udf.c ./dvd_udf.c --- ../../../../versions/libdvdread_patch1/libdvdread/src/dvd_udf.c 2008-10-10 16:01:11.000000000 +0900 +++ ./dvd_udf.c 2008-10-10 16:20:12.000000000 +0900 @@ -536,6 +536,104 @@ return 0; } +/* TagID 266 + * The differences in ExtFile are indicated below: + * struct extfile_entry { + * struct desc_tag tag; + * struct icb_tag icbtag; + * uint32_t uid; + * uint32_t gid; + * uint32_t perm; + * uint16_t link_cnt; + * uint8_t rec_format; + * uint8_t rec_disp_attr; + * uint32_t rec_len; + * uint64_t inf_len; + * uint64_t obj_size; // NEW + * uint64_t logblks_rec; + * struct timestamp atime; + * struct timestamp mtime; + * struct timestamp ctime; // NEW + * struct timestamp attrtime; + * uint32_t ckpoint; + * uint32_t reserved1; // NEW + * struct long_ad ex_attr_icb; + * struct long_ad streamdir_icb; // NEW + * struct regid imp_id; + * uint64_t unique_id; + * uint32_t l_ea; + * uint32_t l_ad; + * uint8_t data[1]; + * } __packed; + * + * So old "l_ea" is now +216 + * + * Lund + */ +static int UDFExtFileEntry( uint8_t *data, uint8_t *FileType, + struct Partition *partition, struct FileAD *fad ) +{ + uint16_t flags; + uint32_t L_EA, L_AD; + unsigned int p; + unsigned int curr_ad; + + UDFICB( &data[ 16 ], FileType, &flags ); + + /* Init ad for an empty file (i.e. there isn't a AD, L_AD == 0 ) */ + fad->Length = GETN8(56); // 64-bit. + + L_EA = GETN4( 208); + L_AD = GETN4( 212); + p = 216 + L_EA; + curr_ad = 0; + while( p < 216 + L_EA + L_AD ) { + struct AD *ad; + + if (curr_ad >= UDF_MAX_AD_CHAINS) return 0; +#ifdef DEBUG + fprintf(stderr, "libdvdread: reading AD chain %d\r\n", curr_ad); +#endif + ad = &fad->AD_chain[curr_ad]; + ad->Partition = partition->Number; + ad->Flags = 0; + curr_ad++; + + switch( flags & 0x0007 ) { + case 0: + UDFShortAD( &data[ p ], ad, partition ); + p += 8; + break; + case 1: + UDFLongAD( &data[ p ], ad ); + p += 16; + break; + case 2: + UDFExtAD( &data[ p ], ad ); + p += 20; + break; + case 3: + switch( L_AD ) { + case 8: + UDFShortAD( &data[ p ], ad, partition ); + break; + case 16: + UDFLongAD( &data[ p ], ad ); + break; + case 20: + UDFExtAD( &data[ p ], ad ); + break; + } + p += L_AD; + break; + default: + p += L_AD; + break; + } + } + return 0; +} + static int UDFFileIdentifier( uint8_t *data, uint8_t *FileCharacteristics, char *FileName, struct AD *FileICB ) { @@ -588,8 +686,18 @@ SetUDFCache(device, MapCache, tmpmap.lbn, &tmpmap); return 1; }; + + /* ExtendedFileInfo */ + if( TagID == 266 ) { + UDFExtFileEntry( LogBlock, FileType, partition, File ); + memcpy(&tmpmap.file, File, sizeof(tmpmap.file)); + tmpmap.filetype = *FileType; + SetUDFCache(device, MapCache, tmpmap.lbn, &tmpmap); + return 1; + } + } while( ( lbnum <= partition->Start + ICB.Location + ( ICB.Length - 1 ) - / DVD_VIDEO_LB_LEN ) && ( TagID != 261 ) ); + / DVD_VIDEO_LB_LEN ) && ( TagID != 261 ) && (TagID != 266) ); return 0; } @@ -937,6 +1045,23 @@ TagID = 0; else UDFDescriptor( LogBlock, &TagID ); + /* + * It seems that someone added a FileType of 250, which seems to be + * a "redirect" style file entry. If we discover such an entry, we + * add on the "location" to partition->Start, and try again. + * Who added this? Is there any official guide somewhere? + * 2008/09/17 lundman + * Should we handle 261(250) as well? FileEntry+redirect + */ + if( TagID == 266 ) { + UDFExtFileEntry( LogBlock, &filetype, &partition, &File ); + if (filetype == 250) { + partition.Start += File.AD_chain[0].Location; + lbnum = partition.Start; + SetUDFCache(device, PartitionCache, 0, &partition); + continue; + } + } /* File Set Descriptor */ if( TagID == 256 ) /* File Set Descriptor */ @@ -947,8 +1072,10 @@ /* Sanity checks. */ if( TagID != 256 ) return NULL; - if( RootICB.Partition != 0 ) - return NULL; + /* This following test will fail under UDF2.50 images, as it is no longer + * valid */ + /*if( RootICB.Partition != 0 ) + return NULL;*/ SetUDFCache(device, RootICBCache, 0, &RootICB); }