/** * Reads the volume descriptor and checks the parameters. Returns 0 on OK, 1 * on error. */ static int UDFLogVolume( uint8_t *data, struct Volume *vol) { uint32_t MT_L, N_PM, volume; uint32_t ii, type, length, pos; struct PartitionMaps *maps; volume = GETN4(16); Unicodedecode(&data[84], 128, vol->VolumeDesc); vol->BlockSize = GETN4(212); /* should be 2048 */ memset((void *)&vol->FSD, 0, sizeof(struct AD)); UDFLongAD(&data[248], &vol->FSD); //printf("File Set Descriptor: block: %d, part: %d\n", vol->FSD.Location, vol->FSD.Partition); MT_L = GETN4(264); /* should be 6 */ N_PM = GETN4(268); /* should be 1 */ vol->MapNum = N_PM; if ((N_PM >= 1) && (vol->Maps == NULL)) { vol->Maps = (struct PartitionMaps *)calloc(1, sizeof(struct PartitionMaps) * N_PM); } UDFExtentAD( &data[432], &vol->Length, &vol->Location); //printf("location: %d, length: %d\n", vol->Location, vol->Length); pos = 440; for (ii = 0; ii < N_PM; ii++) { maps = &vol->Maps[ii]; type = GETN1(pos); length = GETN1(pos+1); if (type == 1) { maps->MapType = UDF_TYPE1_MAP15; maps->VolSequenNum = GETN2(pos+2); maps->PartitionNum = GETN2(pos+4); } else if (type == 2) { struct EntityIdentifier ident; uint32_t version; UDFEntIdentifier(&data[pos+4], &ident); version = ((uint16_t)ident.indetifierSuffix[1] << 8) | (uint16_t)(ident.indetifierSuffix[0]); //printf("identifier: '%s', version: %04x\n", ident.identifier, version); if (strncmp(ident.identifier, UDF_ID_VIRTUAL, strlen(UDF_ID_VIRTUAL)) == 0) { if (version < 0x0200) maps->MapType = UDF_VIRTUAL_MAP15; else maps->MapType = UDF_VIRTUAL_MAP20; } else if (strncmp(ident.identifier, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE)) == 0) { maps->MapType = UDF_SPARABLE_MAP15; } else if (strncmp(ident.identifier, UDF_ID_METADATA, strlen(UDF_ID_METADATA)) == 0) { maps->MapType = UDF_METADATA_MAP25; } maps->VolSequenNum = GETN2(pos+36); maps->PartitionNum = GETN2(pos+38); maps->mdata.meta_file_loc = GETN4(pos+40); maps->mdata.mirror_file_loc = GETN4(pos+44); maps->mdata.bitmap_file_loc = GETN4(pos+48); maps->mdata.alloc_unit_size = GETN4(pos+52); maps->mdata.alig_unit_size = GETN2(pos+56); maps->mdata.flags = data[pos+58]; //printf("meta_loc: %u, mirr_loc: %u, bit_loc: %u, alloc_unit: %u, alig_unit: %hu, flags: %hhu\n", maps->mdata.meta_file_loc, maps->mdata.mirror_file_loc, maps->mdata.bitmap_file_loc, maps->mdata.alloc_unit_size, maps->mdata.alig_unit_size, maps->mdata.flags); } //printf("Volume Sequence Number: %hu, Partition Number: %hu\n", maps->VolSequenNum, maps->PartitionNum); pos += length; } //printf("volume: %d, MT_L: %d, N_PM: %d\n", volume, MT_L, N_PM); if (vol->BlockSize != DVD_VIDEO_LB_LEN) return 1; return 0; }
static int UDFGetAVDP( dvd_reader_t *device, struct avdp_t *avdp) { uint8_t Anchor_base[ DVD_VIDEO_LB_LEN + 2048 ]; uint8_t *Anchor = (uint8_t *)(((uintptr_t)Anchor_base & ~((uintptr_t)2047)) + 2048); uint32_t lbnum, MVDS_location, MVDS_length; uint16_t TagID; uint32_t lastsector; int terminate; struct avdp_t; if(GetUDFCache(device, AVDPCache, 0, avdp)) return 1; /* Find Anchor */ lastsector = 0; lbnum = 256; /* Try #1, prime anchor */ terminate = 0; for(;;) { if( DVDReadLBUDF( device, lbnum, 1, Anchor, 0 ) > 0 ) { UDFDescriptor( Anchor, &TagID ); } else { TagID = 0; } if (TagID != 2) { /* Not an anchor */ if( terminate ) return 0; /* Final try failed */ if( lastsector ) { /* We already found the last sector. Try #3, alternative * backup anchor. If that fails, don't try again. */ lbnum = lastsector; terminate = 1; } else { /* TODO: Find last sector of the disc (this is optional). */ if( lastsector ) /* Try #2, backup anchor */ lbnum = lastsector - 256; else /* Unable to find last sector */ return 0; } } else /* It's an anchor! We can leave */ break; } /* Main volume descriptor */ UDFExtentAD( &Anchor[ 16 ], &MVDS_length, &MVDS_location ); avdp->mvds.location = MVDS_location; avdp->mvds.length = MVDS_length; /* Backup volume descriptor */ UDFExtentAD( &Anchor[ 24 ], &MVDS_length, &MVDS_location ); avdp->rvds.location = MVDS_location; avdp->rvds.length = MVDS_length; SetUDFCache(device, AVDPCache, 0, avdp); return 1; }
static int UDFGetAVDP( dvd_reader_t *device, struct avdp_t *avdp) { uint8_t *Anchor; uint32_t lbnum, MVDS_location, MVDS_length; uint16_t TagID; uint32_t lastsector; int terminate; struct avdp_t; if(GetUDFCache(device, AVDPCache, 0, avdp)) { return 1; } /* Find Anchor */ lastsector = 0; lbnum = 256; /* Try #1, prime anchor */ terminate = 0; Anchor = dvdalign_lbmalloc(device, 1); if(!Anchor) { return 0; } for(;;) { if( DVDReadLBUDF( device, lbnum, 1, Anchor, 0 ) > 0 ) { UDFDescriptor( Anchor, &TagID ); } else { TagID = 0; } if (TagID != 2) { /* Not an anchor */ if( terminate ) { dvdalign_lbfree(device, Anchor); errno = EMEDIUMTYPE; return 0; /* Final try failed */ } if( lastsector ) { /* We already found the last sector. Try #3, alternative * backup anchor. If that fails, don't try again. */ lbnum = lastsector; terminate = 1; } else { /* TODO: Find last sector of the disc (this is optional). */ if( lastsector ) { /* Try #2, backup anchor */ lbnum = lastsector - 256; } else { /* Unable to find last sector */ dvdalign_lbfree(device, Anchor); errno = EMEDIUMTYPE; return 0; } } } else { /* It's an anchor! We can leave */ break; } } /* Main volume descriptor */ UDFExtentAD( &Anchor[ 16 ], &MVDS_length, &MVDS_location ); avdp->mvds.location = MVDS_location; avdp->mvds.length = MVDS_length; /* Backup volume descriptor */ UDFExtentAD( &Anchor[ 24 ], &MVDS_length, &MVDS_location ); avdp->rvds.location = MVDS_location; avdp->rvds.length = MVDS_length; SetUDFCache(device, AVDPCache, 0, avdp); dvdalign_lbfree(device, Anchor); return 1; }