/** * Looks for partition on the disc. Returns 1 if partition found, 0 on error. * partnum: Number of the partition, starting at 0. * part: structure to fill with the partition information */ static int UDFFindPartition( dvd_reader_t *device, int partnum, struct Partition *part ) { uint8_t LogBlock_base[ DVD_VIDEO_LB_LEN + 2048 ]; uint8_t *LogBlock = (uint8_t *)(((uintptr_t)LogBlock_base & ~((uintptr_t)2047)) + 2048); uint32_t lbnum, MVDS_location, MVDS_length; uint16_t TagID; int i, volvalid; struct avdp_t avdp; if(!UDFGetAVDP(device, &avdp)) return 0; /* Main volume descriptor */ MVDS_location = avdp.mvds.location; MVDS_length = avdp.mvds.length; part->valid = 0; volvalid = 0; part->VolumeDesc[ 0 ] = '\0'; i = 1; do { /* Find Volume Descriptor */ lbnum = MVDS_location; do { if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) TagID = 0; else UDFDescriptor( LogBlock, &TagID ); if( ( TagID == 5 ) && ( !part->valid ) ) { /* Partition Descriptor */ UDFPartition( LogBlock, &part->Flags, &part->Number, part->Contents, &part->Start, &part->Length ); part->valid = ( partnum == part->Number ); } else if( ( TagID == 6 ) && ( !volvalid ) ) { /* Logical Volume Descriptor */ if( UDFLogVolume( LogBlock, part->VolumeDesc ) ) { /* TODO: sector size wrong! */ } else volvalid = 1; } } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 ) / DVD_VIDEO_LB_LEN ) && ( TagID != 8 ) && ( ( !part->valid ) || ( !volvalid ) ) ); if( ( !part->valid) || ( !volvalid ) ) { /* Backup volume descriptor */ MVDS_location = avdp.mvds.location; MVDS_length = avdp.mvds.length; } } while( i-- && ( ( !part->valid ) || ( !volvalid ) ) ); /* We only care for the partition, not the volume */ return part->valid; }
/** * Gets a Descriptor . * Returns 1 if descriptor found, 0 on error. * id, tagid of descriptor * bufsize, size of BlockBuf (must be >= DVD_VIDEO_LB_LEN) * and aligned for raw/O_DIRECT read. */ static int UDFGetDescriptor( dvd_reader_t *device, int id, uint8_t *descriptor, int bufsize) { uint32_t lbnum, MVDS_location, MVDS_length; struct avdp_t avdp; uint16_t TagID; uint32_t lastsector; int i, terminate; int desc_found = 0; /* Find Anchor */ lastsector = 0; lbnum = 256; /* Try #1, prime anchor */ terminate = 0; if(bufsize < DVD_VIDEO_LB_LEN) { return 0; } if(!UDFGetAVDP(device, &avdp)) { return 0; } /* Main volume descriptor */ MVDS_location = avdp.mvds.location; MVDS_length = avdp.mvds.length; i = 1; do { /* Find Descriptor */ lbnum = MVDS_location; do { if( DVDReadLBUDF( device, lbnum++, 1, descriptor, 0 ) <= 0 ) { TagID = 0; } else { UDFDescriptor( descriptor, &TagID ); } if( (TagID == id) && ( !desc_found ) ) { /* Descriptor */ desc_found = 1; } } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 ) / DVD_VIDEO_LB_LEN ) && ( TagID != 8 ) && ( !desc_found) ); if( !desc_found ) { /* Backup volume descriptor */ MVDS_location = avdp.rvds.location; MVDS_length = avdp.rvds.length; } } while( i-- && ( !desc_found ) ); return desc_found; }
/** * Looks for partition on the disc. Returns 1 if partition found, 0 on error. * partnum: Number of the partition, starting at 0. * part: structure to fill with the partition information */ static int UDFFindPartition( UDF_DATA *device, int partnum, struct Partition *part ) { uint8_t LogBlock_base[ DVD_VIDEO_LB_LEN + 2048 ]; uint8_t *LogBlock = (uint8_t *)(((uintptr_t)LogBlock_base & ~((uintptr_t)2047)) + 2048); uint32_t lbnum, MVDS_location, MVDS_length; uint16_t TagID; int i, volvalid; struct avdp_t avdp; uint8_t file_type; if(!UDFGetAVDP(device, &avdp)) return 0; /* Main volume descriptor */ MVDS_location = avdp.mvds.location; MVDS_length = avdp.mvds.length; part->valid = 0; volvalid = 0; //part->VolumeDesc[ 0 ] = '\0'; i = 1; do { /* Find Volume Descriptor */ lbnum = MVDS_location; do { if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) { return 0; TagID = 0; } else UDFDescriptor( LogBlock, &TagID ); if( ( TagID == 5 ) && ( !part->valid ) ) { /* Partition Descriptor */ UDFPartition( LogBlock, &part->Flags, &part->Number, part->Contents, &part->Start, &part->Length ); part->valid = ( partnum == part->Number ); } else if( ( TagID == 6 ) && ( !volvalid ) ) { /* Logical Volume Descriptor */ if( UDFLogVolume( LogBlock, &part->vol) ) { /* TODO: sector size wrong! */ } else volvalid = 1; } } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 ) / DVD_VIDEO_LB_LEN ) && ( TagID != 8 ) && ( ( !part->valid ) || ( !volvalid ) ) ); if( ( !part->valid) || ( !volvalid ) ) { /* Backup volume descriptor */ MVDS_location = avdp.mvds.location; MVDS_length = avdp.mvds.length; } } while( i-- && ( ( !part->valid ) || ( !volvalid ) ) ); /* load metadata for udf 2.50 */ if (volvalid == 1) { struct PartitionMaps *Maps; for (i = 0; i < (int)part->vol.MapNum; i++) { Maps = &part->vol.Maps[i]; if (Maps->MapType == UDF_METADATA_MAP25) { /* metadta file location */ //printf("metadata at partition: %d loc: %d\n", Maps->PartitionNum, Maps->mdata.meta_file_loc); lbnum = UDFGetBlock(part, Maps->PartitionNum, Maps->mdata.meta_file_loc); if( DVDReadLBUDF( device, lbnum, 1, LogBlock, 0 ) <= 0 ) { } else { UDFDescriptor( LogBlock, &TagID ); if (TagID == 266) { UDFExtFileEntry(LogBlock, &file_type, part, &Maps->meta_ad); } //UDFExtFileEntry(LogBlock, part, &Maps->meta_ad); //printf("ad: %u, %u, %x, %u\n", Maps->meta_ad.Location, Maps->meta_ad.Length, Maps->meta_ad.Flags, Maps->meta_ad.Partition); } //printf("mirror at partition: %d loc: %d\n", Maps->PartitionNum, Maps->mdata.mirror_file_loc); /* if( DVDReadLBUDF( device, part->Start + Maps->mdata.mirror_file_loc, 1, LogBlock, 0 ) <= 0 ) { } else { printf("%02x %02x %02x %02x\n", LogBlock[0], LogBlock[1], LogBlock[2], LogBlock[3]); } */ } } // use file set descriptor to find root icb /* lbnum = UDFGetBlock(part, part->vol.FSD.Partition, part->vol.FSD.Location); if( DVDReadLBUDF( device, lbnum, 1, LogBlock, 0 ) <= 0 ) { } else { printf("%02x %02x\n", LogBlock[0], LogBlock[1]); } */ } /* We only care for the partition, not the volume */ return part->valid; }