int log_fat2_info(const struct fat_boot_sector*fh1, const struct fat_boot_sector*fh2, const upart_type_t upart_type, const unsigned int sector_size) { switch(upart_type) { case UP_FAT12: log_info("\nFAT12\n"); break; case UP_FAT16: log_info("\nFAT16\n"); break; case UP_FAT32: log_info("\nFAT32\n"); break; default: return 1; } log_info("sector_size %u %u\n", fat_sector_size(fh1),fat_sector_size(fh2)); log_info("cluster_size %u %u\n", fh1->sectors_per_cluster,fh2->sectors_per_cluster); log_info("reserved %u %u\n", le16(fh1->reserved),le16(fh2->reserved)); log_info("fats %u %u\n", fh1->fats,fh2->fats); log_info("dir_entries %u %u\n", get_dir_entries(fh1),get_dir_entries(fh2)); log_info("sectors %u %u\n", fat_sectors(fh1),fat_sectors(fh2)); log_info("media %02X %02X\n", fh1->media,fh2->media); log_info("fat_length %u %u\n", le16(fh1->fat_length),le16(fh2->fat_length)); log_info("secs_track %u %u\n", le16(fh1->secs_track),le16(fh2->secs_track)); log_info("heads %u %u\n", le16(fh1->heads),le16(fh2->heads)); log_info("hidden %u %u\n", (unsigned int)le32(fh1->hidden),(unsigned int)le32(fh2->hidden)); log_info("total_sect %u %u\n", (unsigned int)le32(fh1->total_sect),(unsigned int)le32(fh2->total_sect)); if(upart_type==UP_FAT32) { log_info("fat32_length %u %u\n", (unsigned int)le32(fh1->fat32_length),(unsigned int)le32(fh2->fat32_length)); log_info("flags %04X %04X\n", le16(fh1->flags),le16(fh2->flags)); log_info("version %u.%u %u.%u\n", fh1->version[0], fh1->version[1],fh2->version[0], fh2->version[1]); log_info("root_cluster %u %u\n", (unsigned int)le32(fh1->root_cluster),(unsigned int)le32(fh2->root_cluster)); log_info("info_sector %u %u\n", le16(fh1->info_sector),le16(fh2->info_sector)); log_info("backup_boot %u %u\n", le16(fh1->backup_boot),le16(fh2->backup_boot)); log_info("free_count "); if(fat32_get_free_count((const unsigned char*)fh1,sector_size)==0xFFFFFFFF) log_info("uninitialised "); else log_info("%lu ",fat32_get_free_count((const unsigned char*)fh1,sector_size)); if(fat32_get_free_count((const unsigned char*)fh2,sector_size)==0xFFFFFFFF) log_info("uninitialised"); else log_info("%lu",fat32_get_free_count((const unsigned char*)fh2,sector_size)); log_info("\nnext_free "); if(fat32_get_next_free((const unsigned char*)fh1,sector_size)==0xFFFFFFFF) log_info("uninitialised "); else log_info("%lu ",fat32_get_next_free((const unsigned char*)fh1,sector_size)); if(fat32_get_next_free((const unsigned char*)fh2,sector_size)==0xFFFFFFFF) log_info("uninitialised\n"); else log_info("%lu\n",fat32_get_next_free((const unsigned char*)fh2,sector_size)); } return 0; }
int dump_2fat_info_ncurses(const struct fat_boot_sector*fh1, const struct fat_boot_sector*fh2, const upart_type_t upart_type, const unsigned int sector_size) { switch(upart_type) { case UP_FAT12: wprintw(stdscr,"FAT : 12\n"); break; case UP_FAT16: wprintw(stdscr,"FAT : 16\n"); break; case UP_FAT32: wprintw(stdscr,"FAT : 32\n"); break; default: wprintw(stdscr,"Not a FAT\n"); return 1; } wprintw(stdscr,"cluster_size %u %u\n", fh1->sectors_per_cluster, fh2->sectors_per_cluster); wprintw(stdscr,"reserved %u %u\n", le16(fh1->reserved),le16(fh2->reserved)); if(fat_sectors(fh1)!=0 || fat_sectors(fh2)!=0) wprintw(stdscr,"sectors %u %u\n", fat_sectors(fh1), fat_sectors(fh2)); if(le32(fh1->total_sect)!=0 || le32(fh2->total_sect)!=0) wprintw(stdscr,"total_sect %u %u\n", (unsigned int)le32(fh1->total_sect), (unsigned int)le32(fh2->total_sect)); if(upart_type==UP_FAT32) { wprintw(stdscr,"fat32_length %u %u\n", (unsigned int)le32(fh1->fat32_length), (unsigned int)le32(fh2->fat32_length)); wprintw(stdscr,"root_cluster %u %u\n", (unsigned int)le32(fh1->root_cluster), (unsigned int)le32(fh2->root_cluster)); wprintw(stdscr,"free_count "); if(fat32_get_free_count((const unsigned char*)fh1,sector_size)==0xFFFFFFFF) wprintw(stdscr,"uninitialised "); else wprintw(stdscr,"%lu ",fat32_get_free_count((const unsigned char*)fh1,sector_size)); if(fat32_get_free_count((const unsigned char*)fh2,sector_size)==0xFFFFFFFF) wprintw(stdscr,"uninitialised\n"); else wprintw(stdscr,"%lu\n",fat32_get_free_count((const unsigned char*)fh2,sector_size)); wprintw(stdscr,"next_free "); if(fat32_get_next_free((const unsigned char*)fh1,sector_size)==0xFFFFFFFF) wprintw(stdscr,"uninitialised "); else wprintw(stdscr,"%lu ",fat32_get_next_free((const unsigned char*)fh1,sector_size)); if(fat32_get_next_free((const unsigned char*)fh2,sector_size)==0xFFFFFFFF) wprintw(stdscr,"uninitialised\n"); else wprintw(stdscr,"%lu\n",fat32_get_next_free((const unsigned char*)fh2,sector_size)); } else { wprintw(stdscr,"fat_length %u %u\n", le16(fh1->fat_length), le16(fh2->fat_length)); wprintw(stdscr,"dir_entries %u %u\n", get_dir_entries(fh1), get_dir_entries(fh2)); } return 0; }
static int log_fat_info(const struct fat_boot_sector*fh1, const upart_type_t upart_type, const unsigned int sector_size) { log_info("sector_size %u\n", fat_sector_size(fh1)); log_info("cluster_size %u\n", fh1->sectors_per_cluster); log_info("reserved %u\n", le16(fh1->reserved)); log_info("fats %u\n", fh1->fats); log_info("dir_entries %u\n", get_dir_entries(fh1)); log_info("sectors %u\n", fat_sectors(fh1)); log_info("media %02X\n", fh1->media); log_info("fat_length %u\n", le16(fh1->fat_length)); log_info("secs_track %u\n", le16(fh1->secs_track)); log_info("heads %u\n", le16(fh1->heads)); log_info("hidden %u\n", (unsigned int)le32(fh1->hidden)); log_info("total_sect %u\n", (unsigned int)le32(fh1->total_sect)); if(upart_type==UP_FAT32) { log_info("fat32_length %u\n", (unsigned int)le32(fh1->fat32_length)); log_info("flags %04X\n", le16(fh1->flags)); log_info("version %u.%u\n", fh1->version[0], fh1->version[1]); log_info("root_cluster %u\n", (unsigned int)le32(fh1->root_cluster)); log_info("info_sector %u\n", le16(fh1->info_sector)); log_info("backup_boot %u\n", le16(fh1->backup_boot)); if(fat32_get_free_count((const unsigned char*)fh1,sector_size)==0xFFFFFFFF) log_info("free_count uninitialised\n"); else log_info("free_count %lu\n",fat32_get_free_count((const unsigned char*)fh1,sector_size)); if(fat32_get_next_free((const unsigned char*)fh1,sector_size)==0xFFFFFFFF) log_info("next_free uninitialised\n"); else log_info("next_free %lu\n",fat32_get_next_free((const unsigned char*)fh1,sector_size)); } return 0; }
int dump_fat_info_ncurses(const struct fat_boot_sector*fh1, const upart_type_t upart_type, const unsigned int sector_size) { switch(upart_type) { case UP_FAT12: wprintw(stdscr,"FAT : 12\n"); break; case UP_FAT16: wprintw(stdscr,"FAT : 16\n"); break; case UP_FAT32: wprintw(stdscr,"FAT : 32\n"); break; default: wprintw(stdscr,"Not a FAT\n"); return 0; } wprintw(stdscr,"cluster_size %u\n", fh1->sectors_per_cluster); wprintw(stdscr,"reserved %u\n", le16(fh1->reserved)); if(fat_sectors(fh1)!=0) wprintw(stdscr,"sectors %u\n", fat_sectors(fh1)); if(le32(fh1->total_sect)!=0) wprintw(stdscr,"total_sect %u\n", (unsigned int)le32(fh1->total_sect)); if(upart_type==UP_FAT32) { wprintw(stdscr,"fat32_length %u\n", (unsigned int)le32(fh1->fat32_length)); wprintw(stdscr,"root_cluster %u\n", (unsigned int)le32(fh1->root_cluster)); wprintw(stdscr,"flags %04X\n", le16(fh1->flags)); wprintw(stdscr,"version %u.%u\n", fh1->version[0], fh1->version[1]); wprintw(stdscr,"root_cluster %u\n", (unsigned int)le32(fh1->root_cluster)); wprintw(stdscr,"info_sector %u\n", le16(fh1->info_sector)); wprintw(stdscr,"backup_boot %u\n", le16(fh1->backup_boot)); if(fat32_get_free_count((const unsigned char*)fh1,sector_size)==0xFFFFFFFF) wprintw(stdscr,"free_count uninitialised\n"); else wprintw(stdscr,"free_count %lu\n",fat32_get_free_count((const unsigned char*)fh1,sector_size)); if(fat32_get_next_free((const unsigned char*)fh1,sector_size)==0xFFFFFFFF) wprintw(stdscr,"next_free uninitialised\n"); else wprintw(stdscr,"next_free %lu\n",fat32_get_next_free((const unsigned char*)fh1,sector_size)); } else { wprintw(stdscr,"fat_length %u\n", le16(fh1->fat_length)); wprintw(stdscr,"dir_entries %u\n", get_dir_entries(fh1)); } return 0; }
static int header_check_fat(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new) { const struct fat_boot_sector *fat_header=(const struct fat_boot_sector *)buffer; uint64_t start_fat1,start_data,part_size; unsigned long int no_of_cluster,fat_length,fat_length_calc; if(!(le16(fat_header->marker)==0xAA55 && (fat_header->ignored[0]==0xeb || fat_header->ignored[0]==0xe9) && (fat_header->fats==1 || fat_header->fats==2))) return 0; /* Obviously not a FAT */ if(!((fat_header->ignored[0]==0xeb && fat_header->ignored[2]==0x90)||fat_header->ignored[0]==0xe9)) return 0; if(fat_sector_size(fat_header)==0 || fat_sector_size(fat_header)%512!=0) return 0; switch(fat_header->sectors_per_cluster) { case 1: case 2: case 4: case 8: case 16: case 32: case 64: case 128: break; default: return 0; } if(fat_header->fats!=1 && fat_header->fats!=2) return 0; if(fat_header->media!=0xF0 && fat_header->media<0xF8) return 0; fat_length=le16(fat_header->fat_length)>0?le16(fat_header->fat_length):le32(fat_header->fat32_length); part_size=(sectors(fat_header)>0?sectors(fat_header):le32(fat_header->total_sect)); start_fat1=le16(fat_header->reserved); start_data=start_fat1+fat_header->fats*fat_length+(get_dir_entries(fat_header)*32+fat_sector_size(fat_header)-1)/fat_sector_size(fat_header); no_of_cluster=(part_size-start_data)/fat_header->sectors_per_cluster; if(no_of_cluster<4085) { /* FAT12 */ if((get_dir_entries(fat_header)==0)||(get_dir_entries(fat_header)%16!=0)) return 0; if((le16(fat_header->fat_length)>256)||(le16(fat_header->fat_length)==0)) return 0; fat_length_calc=((no_of_cluster+2+fat_sector_size(fat_header)*2/3-1)*3/2/fat_sector_size(fat_header)); } else if(no_of_cluster<65525) { /* FAT16 */ if(le16(fat_header->fat_length)==0) return 0; if((get_dir_entries(fat_header)==0)||(get_dir_entries(fat_header)%16!=0)) return 0; fat_length_calc=((no_of_cluster+2+fat_sector_size(fat_header)/2-1)*2/fat_sector_size(fat_header)); } else { /* FAT32 */ if(sectors(fat_header)!=0) return 0; if(get_dir_entries(fat_header)!=0) return 0; if((le32(fat_header->root_cluster)<2) ||(le32(fat_header->root_cluster)>=2+no_of_cluster)) return 0; fat_length_calc=((no_of_cluster+2+fat_sector_size(fat_header)/4-1)*4/fat_sector_size(fat_header)); } if(fat_length<fat_length_calc) return 0; reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_fat.extension; file_recovery_new->calculated_file_size=(uint64_t) (sectors(fat_header)>0?sectors(fat_header):le32(fat_header->total_sect)) * fat_sector_size(fat_header); file_recovery_new->data_check=&data_check_size; file_recovery_new->file_check=&file_check_size; return 1; }
int main(int argc , char** argv) { fp = fopen( FS_FILENAME , "r+b"); fs_info= get_fs_info( fp ); if( argc > 1) { if( strcmp( argv[1] , "init" )==0 ) { fs_init( argv[2] , FS_SIZE ); return 0; }else if( strcmp( argv[1] , "print_fats" )==0 ) { print_fat_entries( strtol(argv[2] , NULL , 10) ); return 0; }else if( strcmp( argv[1] , "neat_test" )==0 ) { //add an entry into the root dir table struct dir_table_entry temp; strcpy(temp.name , "neat.txt"); temp.file_size = 0; temp.allocated = 1; temp.starting_cluster = allocate_fat_block(); fseek( fp , fs_info->data_start , SEEK_SET); fwrite( &temp , 1 , sizeof(struct dir_table_entry) , fp); //modify root table entry struct dir_table_entry temp_root; fseek( fp , sizeof(struct boot_sec) , SEEK_SET); fread( &temp_root , sizeof(struct dir_table_entry) , 1 , fp ); temp_root.file_size = (int)sizeof(struct dir_table_entry); //printf( "read name: %s\n" , temp_root.name); //printf( "read size: %d\n" , temp_root.file_size); fseek( fp , sizeof(struct boot_sec) , SEEK_SET); fwrite( &temp_root , 1 , sizeof(struct dir_table_entry), fp ); //read the data struct file_descriptor root_fd; root_fd.pointer = (int)sizeof(struct boot_sec); struct dir_table_entry* root_entry = get_file_entry( root_fd ); //printf( "name: %s\n" , root_entry->name ); //printf( "size: %d\n" , root_entry->file_size ); //read root dir entries struct dir_table_entry* root_entries = get_dir_entries( root_fd ); //printf("root entry filename: %s\n" , root_entries->name ); //printf("root entry starting_cluster: %d\n" , root_entries->starting_cluster ); //printf("root entry allocated: %d\n" , root_entries->allocated ); fclose( fp ); return 0; }else if( strcmp( argv[1] , "neat_write_test")== 0 ) { struct file_descriptor temp_fd; temp_fd.pointer = fs_info->data_start; struct dir_table_entry* temp_entry = get_file_entry( temp_fd ); temp_entry->file_size = 0; fseek(fp , temp_fd.pointer , SEEK_SET); fwrite( temp_entry , 1 , sizeof( struct dir_table_entry ) , fp); char mssg[2000]; memset( mssg , 'a' , sizeof( mssg )/2 ); memset( mssg + sizeof( mssg )/2 , 'b' , sizeof( mssg )/2 ); write_file( mssg , temp_fd , 0 , (int)sizeof( mssg ) ); }else if( strcmp( argv[1] , "neat_read_test") == 0 ) { struct file_descriptor temp_fd; temp_fd.pointer = fs_info->data_start; char* buff = (char*)malloc( strtol(argv[2] , NULL , 10) ); read_file( buff , temp_fd , 0 , strtol(argv[2] , NULL , 10) ); //printf("message: %s\n" , buff); }else if( strcmp( argv[1] , "misc_test") == 0 ) { /* struct file_descriptor temp_fd; temp_fd.pointer = sizeof(struct boot_sec); int index = find_file_index( temp_fd , "neat.txt" ); temp_fd.pointer = index; struct dir_table_entry* file_entry = get_file_entry( temp_fd ); //printf("index: %d\n" , index); //printf("filename: %s\n" , file_entry->name ); */ char** dirs = split_string( argv[2] , "/" ); int i; printf("arg_count: %d\n", arg_count ); for( i = 0 ; i < arg_count ; i++) { printf("dirs[%d]: %s\n" , i , dirs[i] ); } }else if( strcmp( argv[1] , "delete_test") == 0 ) { struct file_descriptor temp_fd; temp_fd.pointer = fs_info->data_start; //printf(" delete result: %d\n" ,delete_file( temp_fd ) ); }else if( strcmp( argv[1] , "delete") == 0 ) { struct file_descriptor* fd = open_file( argv[2] ); delete_file( *fd ); }else if( strcmp( argv[1] , "open_test") == 0 ) { printf("opening file %s ...\n" , argv[2] ); struct file_descriptor* fd = open_file( argv[2] ); printf(" pointer: %d\n" , (*fd).pointer ); struct dir_table_entry* temp = get_file_entry( *fd ); printf( " filename: %s\n" , temp->name ); printf( " fileseize: %d\n" , temp->file_size ); }else if( strcmp( argv[1] , "create") == 0 ) { if(argc >= 3) { create_file( argv[2] , strtol(argv[3] , NULL , 10) ); }else{ printf("not enough arguments\n"); } }else if( strcmp( argv[1] , "ls") == 0 ) { //printf("\nprinting dir contents...\n"); struct file_descriptor* fd = open_file( argv[2] ); struct dir_table_entry* items = get_dir_entries( *fd ); struct dir_table_entry* entry = get_file_entry( *fd ); int i; for( i = 0 ; i < entry->file_size/((int)sizeof(struct dir_table_entry)) ; i ++) { if( items[ i ].allocated ) { printf(" %s\n", items[ i ].name ); } } }else if( strcmp( argv[1] , "write") == 0 ) { printf("argc: %d\n" , argc); if( argc < 4) { printf("invalid number of arguments\nexiting...\n"); return 0; } struct file_descriptor* file = open_file( argv[2] ); if( file!=NULL ) { char buff[ strtol(argv[3] , NULL , 10) ]; memset( buff , 'a' , strtol(argv[3] , NULL , 10) ); write_file( buff , *file , 0 , strtol(argv[3] , NULL , 10) ); }else{ printf("error opening file for writing\n"); } }else if( strcmp( argv[1] , "read") == 0 ) { printf("argc: %d\n" , argc); if( argc < 4) { printf("invalid number of arguments\nexiting...\n"); return 0; } struct file_descriptor* file = open_file( argv[2] ); if( file!=NULL ) { char buff[ strtol(argv[3] , NULL , 10) + 1 ]; read_file( buff , *file , 0 , strtol(argv[3] , NULL , 10) ); buff[ strtol(argv[3] , NULL , 10) ] = '\0'; printf("read: %s\n" , buff); }else{ printf("error opening file for writing\n"); } } } fclose(fp); return 0; }
struct file_descriptor* open_file( char* path ) { printf("opening file %s ...\n" , path); int i; if( (strlen(path) == 1) && path[0]=='/' ) { i = 1; }else{ i = 0; } char** dirs = split_string( path , "/" ); printf(" arg_count: %d\n" , arg_count); int k; for( k = 0 ; k < arg_count ; k++) { printf( " dirs[%d]: %s\n" , k , dirs[k] ); } int entry_count = 0 , j = 0; struct dir_table_entry* cur_entries; struct file_descriptor cur_fd; struct dir_table_entry* cur_file_entry; //get root directory file descriptor cur_fd.pointer = sizeof( struct boot_sec ); int found_file = 0; while( i < arg_count && !found_file ) { cur_entries = get_dir_entries( cur_fd ); cur_file_entry = get_file_entry( cur_fd ); //printf("\nretrieved file %s \n" , cur_file_entry->name ); entry_count = cur_file_entry->file_size / (int)sizeof( struct dir_table_entry ); //printf("entry_count: %d\n" , entry_count); for( j = 0 ; j < entry_count ; j++ ) { //printf("printing entry[%d]...\n" , j); cur_file_entry = cur_entries + j; //printf(" name: %s\n" , cur_file_entry->name ); if( cur_file_entry->allocated ) { //printf(" looking for file %s...\n" , *(dirs + i) ); if( strcmp( cur_file_entry->name , *(dirs + i) ) == 0 ) { if( i == (arg_count -1)) found_file = 1; //printf( " found file!\n"); cur_fd.pointer = find_file_index( cur_fd , cur_file_entry->name ); //printf(" %s fd pointer: %d\n" , cur_file_entry->name , cur_fd.pointer ); /* struct file_descriptor* ret = (struct file_descriptor*)malloc( sizeof(struct file_descriptor) ); memcpy( ret , &cur_fd , sizeof( struct file_descriptor ) ); return ret; */ } } } i++; } if( !found_file ) printf("file not found!\n"); struct file_descriptor* ret = (struct file_descriptor*)malloc( sizeof(struct file_descriptor) ); memcpy( ret , &cur_fd , sizeof( struct file_descriptor ) ); return ret; }