static int UDFCacheDir( UDF_DIR *device, struct AD Dir, struct Partition *partition, struct AD *FileICB) { char filename[ MAX_UDF_FILE_NAME_LEN ]; uint8_t directory_base[ 2 * DVD_VIDEO_LB_LEN + 2048]; uint8_t *directory = (uint8_t *)(((uintptr_t)directory_base & ~((uintptr_t)2047)) + 2048); uint32_t lbnum; uint16_t TagID; uint8_t filechar; unsigned int p; uint8_t *cached_dir_base = NULL, *cached_dir; uint32_t dir_lba; struct AD tmpICB; int in_cache = 0; uint32_t file_num = 0; /* Scan dir for ICB of file */ //lbnum = partition->Start + Dir.Location; lbnum = UDFGetBlock(partition, Dir.Partition, Dir.Location); if(BDUDFCacheLevel(device->udf_data, -1) > 0) { /* caching */ if(!GetBDUDFCache(device->udf_data, LBUDFCache, lbnum, &cached_dir)) { dir_lba = (Dir.Length + DVD_VIDEO_LB_LEN) / DVD_VIDEO_LB_LEN; if((cached_dir_base = (uint8_t*)malloc(dir_lba * DVD_VIDEO_LB_LEN + 2048)) == NULL) return 0; cached_dir = (uint8_t *)(((uintptr_t)cached_dir_base & ~((uintptr_t)2047)) + 2048); if( DVDReadLBUDF( device->udf_data, lbnum, dir_lba, cached_dir, 0) <= 0 ) { free(cached_dir_base); cached_dir_base = NULL; cached_dir = NULL; } /* if(cached_dir) { fprintf(stderr, "malloc dir: %d\n", dir_lba * DVD_VIDEO_LB_LEN); } */ { uint8_t *data[2]; data[0] = cached_dir_base; data[1] = cached_dir; SetUDFCache(device->udf_data, LBUDFCache, lbnum, data); } } else in_cache = 1; if(cached_dir == NULL) return 0; p = 0; device->aloc_num = 5; device->file_name = malloc(256 * device->aloc_num); while( p < Dir.Length ) { UDFDescriptor( &cached_dir[ p ], &TagID ); //printf("aaa TagID: %d, len: %d\n", TagID, Dir.Length); if( TagID == 257 ) { p += UDFFileIdentifier( &cached_dir[ p ], &filechar, filename, &tmpICB ); if (filename[0] == '\0') continue; if (file_num + 1 > device->aloc_num) { device->aloc_num += 5; device->file_name = realloc((void *)device->file_name, 256 * device->aloc_num); } //printf("add filename: '%s'\n", filename); strncpy((char *)(device->file_name + file_num), filename, 256); device->file_num = ++file_num; } else { return 0; } } return 1; } if( DVDReadLBUDF( device->udf_data, lbnum, 2, directory, 0 ) <= 0 ) return 0; p = 0; while( p < Dir.Length ) { if( p > DVD_VIDEO_LB_LEN ) { ++lbnum; p -= DVD_VIDEO_LB_LEN; Dir.Length -= DVD_VIDEO_LB_LEN; if( DVDReadLBUDF( device->udf_data, lbnum, 2, directory, 0 ) <= 0 ) { return 0; } } UDFDescriptor( &directory[ p ], &TagID ); if( TagID == 257 ) { p += UDFFileIdentifier( &directory[ p ], &filechar, filename, FileICB ); //printf("filename2: %s\n", filename); } } return 0; }
/** * Dir: Location of directory to scan * FileName: Name of file to look for * FileICB: Location of ICB of the found file * return 1 on success, 0 on error; */ static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileName, struct Partition *partition, struct AD *FileICB, int cache_file_info) { char filename[ MAX_UDF_FILE_NAME_LEN ]; uint8_t directory_base[ 2 * DVD_VIDEO_LB_LEN + 2048]; uint8_t *directory = (uint8_t *)(((uintptr_t)directory_base & ~((uintptr_t)2047)) + 2048); uint32_t lbnum; uint16_t TagID; uint8_t filechar; unsigned int p; uint8_t *cached_dir_base = NULL, *cached_dir; uint32_t dir_lba; struct AD tmpICB; int found = 0; int in_cache = 0; /* Scan dir for ICB of file */ lbnum = partition->Start + Dir.Location; if(DVDUDFCacheLevel(device, -1) > 0) { /* caching */ if(!GetUDFCache(device, LBUDFCache, lbnum, &cached_dir)) { dir_lba = (Dir.Length + DVD_VIDEO_LB_LEN) / DVD_VIDEO_LB_LEN; if((cached_dir_base = malloc(dir_lba * DVD_VIDEO_LB_LEN + 2048)) == NULL) return 0; cached_dir = (uint8_t *)(((uintptr_t)cached_dir_base & ~((uintptr_t)2047)) + 2048); if( DVDReadLBUDF( device, lbnum, dir_lba, cached_dir, 0) <= 0 ) { free(cached_dir_base); cached_dir_base = NULL; cached_dir = NULL; } /* if(cached_dir) { fprintf(stderr, "malloc dir: %d\n", dir_lba * DVD_VIDEO_LB_LEN); } */ { uint8_t *data[2]; data[0] = cached_dir_base; data[1] = cached_dir; SetUDFCache(device, LBUDFCache, lbnum, data); } } else in_cache = 1; if(cached_dir == NULL) { free(cached_dir_base); return 0; } p = 0; while( p < Dir.Length ) { UDFDescriptor( &cached_dir[ p ], &TagID ); if( TagID == 257 ) { p += UDFFileIdentifier( &cached_dir[ p ], &filechar, filename, &tmpICB ); if(cache_file_info && !in_cache) { uint8_t tmpFiletype; struct AD tmpFile; if( !strcasecmp( FileName, filename ) ) { memcpy(FileICB, &tmpICB, sizeof(tmpICB)); found = 1; } UDFMapICB(device, tmpICB, &tmpFiletype, partition, &tmpFile); } else { if( !strcasecmp( FileName, filename ) ) { memcpy(FileICB, &tmpICB, sizeof(tmpICB)); return 1; } } } else { if(cache_file_info && (!in_cache) && found) return 1; return 0; } } if(cache_file_info && (!in_cache) && found) return 1; return 0; } if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) return 0; p = 0; while( p < Dir.Length ) { if( p > DVD_VIDEO_LB_LEN ) { ++lbnum; p -= DVD_VIDEO_LB_LEN; Dir.Length -= DVD_VIDEO_LB_LEN; if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) { return 0; } } UDFDescriptor( &directory[ p ], &TagID ); if( TagID == 257 ) { p += UDFFileIdentifier( &directory[ p ], &filechar, filename, FileICB ); if( !strcasecmp( FileName, filename ) ) { return 1; } } else return 0; } return 0; }
/** * Dir: Location of directory to scan * FileName: Name of file to look for * FileICB: Location of ICB of the found file * return 1 on success, 0 on error; */ static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileName, struct Partition *partition, struct AD *FileICB, int cache_file_info) { char filename[ MAX_UDF_FILE_NAME_LEN ]; uint8_t *directory; uint32_t lbnum; uint16_t TagID; uint8_t filechar; unsigned int p; uint8_t *cached_dir = NULL; uint32_t dir_lba; struct AD tmpICB; int found = 0; int in_cache = 0; /* Scan dir for ICB of file */ lbnum = partition->Start + Dir.Location; if(DVDUDFCacheLevel(device, -1) > 0) { /* caching */ if(!GetUDFCache(device, LBUDFCache, lbnum, &cached_dir)) { dir_lba = (Dir.Length + DVD_VIDEO_LB_LEN) / DVD_VIDEO_LB_LEN; if((cached_dir = dvdalign_lbmalloc(device, dir_lba)) == NULL) { return 0; } if( DVDReadLBUDF( device, lbnum, dir_lba, cached_dir, 0) <= 0 ) { dvdalign_lbfree(device, cached_dir); cached_dir = NULL; } SetUDFCache(device, LBUDFCache, lbnum, &cached_dir); } else { in_cache = 1; } if(cached_dir == NULL) { return 0; } p = 0; while( p < Dir.Length ) { UDFDescriptor( &cached_dir[ p ], &TagID ); if( TagID == 257 ) { p += UDFFileIdentifier( &cached_dir[ p ], &filechar, filename, &tmpICB ); if(cache_file_info && !in_cache) { uint8_t tmpFiletype; struct AD tmpFile; if( !strcasecmp( FileName, filename ) ) { *FileICB = tmpICB; found = 1; } UDFMapICB(device, tmpICB, &tmpFiletype, partition, &tmpFile); } else { if( !strcasecmp( FileName, filename ) ) { *FileICB = tmpICB; return 1; } } } else { if(cache_file_info && (!in_cache) && found) { return 1; } return 0; } } if(cache_file_info && (!in_cache) && found) { return 1; } return 0; } directory = dvdalign_lbmalloc(device, 2); if(!directory) { return 0; } if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) { dvdalign_lbfree(device, directory); return 0; } p = 0; while( p < Dir.Length ) { if( p > DVD_VIDEO_LB_LEN ) { ++lbnum; p -= DVD_VIDEO_LB_LEN; Dir.Length -= DVD_VIDEO_LB_LEN; if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) { dvdalign_lbfree(device, directory); return 0; } } UDFDescriptor( &directory[ p ], &TagID ); if( TagID == 257 ) { p += UDFFileIdentifier( &directory[ p ], &filechar, filename, FileICB ); if( !strcasecmp( FileName, filename ) ) { dvdalign_lbfree(device, directory); return 1; } } else { dvdalign_lbfree(device, directory); return 0; } } dvdalign_lbfree(device, directory); return 0; }