static int UDFShortAD( quint8 *data, struct AD *ad ) { ad->Length = GETN4(0); ad->Flags = ad->Length >> 30; ad->Length &= 0x3FFFFFFF; ad->Location = GETN4(4); return 0; }
static int UDFFileEntry( uint8_t *data, uint8_t *FileType, struct Partition *partition, struct AD *ad ) { uint16_t flags; uint32_t L_EA, L_AD; unsigned int p; UDFICB( &data[ 16 ], FileType, &flags ); /* Init ad for an empty file (i.e. there isn't a AD, L_AD == 0 ) */ ad->Length = GETN4( 60 ); /* Really 8 bytes a 56 */ ad->Flags = 0; ad->Location = 0; /* what should we put here? */ ad->Partition = partition->Number; /* use number of current partition */ L_EA = GETN4( 168 ); L_AD = GETN4( 172 ); if (176 + L_EA + L_AD > DVD_VIDEO_LB_LEN) return 0; p = 176 + L_EA; while( p < 176 + L_EA + L_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 UDFShortAD( uint8_t *data, struct AD *ad, struct Partition *partition ) { uint32_t leng = GETN4(0); ad->Flags = leng >> 30; ad->Length = (leng & 0x3FFFFFFF); ad->Location = GETN4(4); ad->Partition = partition->Number; /* use number of current partition */ return 0; }
static int UDFPartition( quint8 *data, quint16 *Flags, quint16 *Number, char *Contents, quint32 *Start, quint32 *Length ) { *Flags = GETN2(20); *Number = GETN2(22); GETN(24, 32, Contents); *Start = GETN4(188); *Length = GETN4(192); return 0; }
static int UDFPartition( uint8_t *data, uint16_t *Flags, uint16_t *Number, char *Contents, uint32_t *Start, uint32_t *Length ) { *Flags = GETN2(20); *Number = GETN2(22); GETN(24, 32, Contents); *Start = GETN4(188); *Length = GETN4(192); return 0; }
/** * Reads the volume descriptor and checks the parameters. Returns 0 on OK, 1 * on error. */ static int UDFLogVolume( uint8_t *data, char *VolumeDescriptor ) { uint32_t lbsize, MT_L, N_PM; Unicodedecode(&data[84], 128, VolumeDescriptor); lbsize = GETN4(212); /* should be 2048 */ MT_L = GETN4(264); /* should be 6 */ N_PM = GETN4(268); /* should be 1 */ if (lbsize != DVD_VIDEO_LB_LEN) return 1; return 0; }
static int UDFShortAD( uint8_t *data, struct AD *ad, struct Partition *partition ) { ad->Length = GETN4(0); ad->Flags = ad->Length >> 30; ad->Length &= 0x3FFFFFFF; ad->Location = GETN4(4); ad->Partition = partition->Number; /* use number of current partition */ return 0; }
static int UDFExtAD( uint8_t *data, struct AD *ad ) { ad->Length = GETN4(0); ad->Flags = ad->Length >> 30; ad->Length &= 0x3FFFFFFF; ad->Location = GETN4(12); ad->Partition = GETN2(16); /* GETN(10, 6, Use); */ return 0; }
static int UDFExtAD( uint8_t *data, struct AD *ad ) { uint32_t leng = GETN4(0); ad->Flags = leng >> 30; ad->Length = (leng & 0x3FFFFFFF); ad->Location = GETN4(12); ad->Partition = GETN2(16); /* GETN(10, 6, Use); */ return 0; }
static int UDFLongAD( uint8_t *data, struct AD *ad ) { ad->Length = GETN4(0); ad->Flags = ad->Length >> 30; ad->Length &= 0x3FFFFFFF; ad->Location = GETN4(4); ad->Partition = GETN2(8); //GETN(10, 6, Use); return 0; }
static int UDFExtFileEntry(uint8_t *data, struct Partition *partition, struct AD *ad) { int nRet = -1; uint8_t FileType; uint16_t TagID; uint16_t flags; uint32_t L_EA, L_AD; unsigned int p; UDFDescriptor( data, &TagID ); if (TagID != 266) { //printf("Not ExtFileEntry!!!\n"); return nRet; } UDFICB( &data[ 16 ], &FileType, &flags ); ad->Length = GETN4( 60 ); /* Really 8 bytes a 56 */ ad->Flags = 0; ad->Location = 0; /* what should we put here? */ ad->Partition = partition->Number; /* use number of current partition */ L_EA = GETN4( 208 ); L_AD = GETN4( 212 ); if (216 + L_EA + L_AD > DVD_VIDEO_LB_LEN) return nRet; p = 216 + L_EA; while( p < 216 + L_EA + L_AD ) { switch( flags & 0x0007 ) { case 0: UDFShortAD( &data[ p ], ad, partition ); p += 8; break; case 1: UDFLongAD( &data[ p ], ad ); p += 16; break; default: p += L_AD; break; } } return nRet; }
static int UDFLogVolume( quint8 *data, char *VolumeDescriptor ) { quint32 lbsize; Unicodedecode(&data[84], 128, VolumeDescriptor); lbsize = GETN4(212); /* should be 2048 */ if (lbsize != DVD_VIDEO_LB_LEN) return 1; return 0; }
static int UDFExtFileEntry( quint8 *data, struct FileAD *fad ) { quint32 L_EA, L_AD; unsigned int p; UDFICB( &data[ 16 ], &fad->Type, &fad->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; fad->num_AD = 0; while( p < 216 + L_EA + L_AD ) { p += UDFAD( &data[ p ], L_AD, fad ); } return 0; }
static int UDFAdEntry( quint8 *data, struct FileAD *fad ) { quint32 L_AD; unsigned int p; L_AD = GETN4(20); p = 24; while( p < 24 + L_AD ) { p += UDFAD( &data[ p ], L_AD, fad ); } return 0; }
static int UDFFileEntry( quint8 *data, struct FileAD *fad ) { quint32 L_EA, L_AD; unsigned int p; UDFICB( &data[ 16 ], &fad->Type, &fad->Flags ); fad->Length = GETN8( 56 ); /* Was 4 bytes at 60, changed for 64bit. */ L_EA = GETN4( 168 ); L_AD = GETN4( 172 ); if (176 + L_EA + L_AD > DVD_VIDEO_LB_LEN) return 0; p = 176 + L_EA; fad->num_AD = 0; while( p < 176 + L_EA + L_AD ) { p += UDFAD( &data[ p ], L_AD, fad ); } return 0; }
static int UDFExtentAD( uint8_t *data, uint32_t *Length, uint32_t *Location ) { *Length = GETN4(0); *Location = GETN4(4); return 0; }
static int UDFExtFileEntry( uint8_t *data, uint8_t *FileType, struct Partition *partition, struct AD *ad ) { uint16_t flags; uint32_t L_EA, L_AD; unsigned int p; struct AD temp_ad; int is_init = 0; memset((void *)&temp_ad, 0, sizeof(struct AD)); UDFICB( &data[ 16 ], FileType, &flags ); /* Init ad for an empty file (i.e. there isn't a AD, L_AD == 0 ) */ //ad->Length = GETN4( 60 ); /* Really 8 bytes a 56 */ ad->Length = 0; ad->Flags = 0; ad->Location = 0; /* what should we put here? */ ad->Partition = partition->Number; /* use number of current partition */ L_EA = GETN4( 208 ); L_AD = GETN4( 212 ); if (216 + L_EA + L_AD > DVD_VIDEO_LB_LEN) return 0; p = 216 + L_EA; while( p < 216 + L_EA + L_AD ) { switch( flags & 0x0007 ) { case 0: UDFShortAD( &data[ p ], &temp_ad, partition ); p += 8; break; case 1: UDFLongAD( &data[ p ], &temp_ad ); p += 16; break; case 2: UDFExtAD( &data[ p ], &temp_ad ); p += 20; break; case 3: switch( L_AD ) { case 8: UDFShortAD( &data[ p ], &temp_ad, partition ); break; case 16: UDFLongAD( &data[ p ], &temp_ad ); break; case 20: UDFExtAD( &data[ p ], &temp_ad ); break; } p += L_AD; break; default: p += L_AD; break; } if (is_init == 0) { memcpy((void *)ad, (void *)&temp_ad, sizeof(struct AD)); is_init = 1; } else { // only update file size ad->Length += temp_ad.Length; } } return 0; }
/** * 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 UDFExtentAD( quint8 *data, quint32 *Length, quint32 *Location ) { *Length = GETN4(0); *Location = GETN4(4); return 0; }