diff --git a/tools/diskwrite.c b/tools/diskwrite.c index 7ac93a2..5f50f85 100644 --- a/tools/diskwrite.c +++ b/tools/diskwrite.c @@ -120,7 +120,9 @@ void write_cluster_value(fat_info *info, uint32_t value, uint32_t cluster){ } } -int write_file(char *path, fat_info *info, FILE *file){ +int read_file(fat_info *info, uint32_t first_cluster, file_t *file, buffer_t *buffer, FILE *disk); + +int create_file(char *path, fat_info *info, FILE *file){ FILE *ifile = fopen(path, "r"); if(!ifile){ printf("Failed to open file: %s\nAborting...\n", path); @@ -140,13 +142,14 @@ int write_file(char *path, fat_info *info, FILE *file){ } //create file in root dir file_t dirent = {0}; - memcpy(dirent.filename, path, 8); int extoffset = 0; while(*(path + extoffset) != '.' && *(path + extoffset)){ extoffset++; } + memcpy(dirent.filename, path, 8 > extoffset ? extoffset : 8); verbose && printf("File extension at %d\n", extoffset); - memcpy(dirent.ext, path + extoffset, 3); + verbose && printf("file ext: %s\n", path + extoffset); + memmove(dirent.ext, path + extoffset + 1, 3); dirent.size_bytes = ifsize; verbose && printf("Writing %u sectors\n", ifsize/(info->bpb.bytes_per_sector * info->bpb.sectors_per_cluster) + 1); uint32_t last_cluster = 0; @@ -164,12 +167,48 @@ int write_file(char *path, fat_info *info, FILE *file){ verbose && printf("last cluster: %d\n", last_cluster); write_cluster_value(info, FILE_END, last_cluster); + buffer_t root_dir_buffer = 0; + uint32_t dirent_count = read_file(info, info->bpb.root_dir_cluster, 0, &root_dir_buffer, file)/sizeof(file_t); + + //searching for a free dirent + file_t *root_dir = (file_t *)root_dir_buffer; + uint32_t free_file_index = 0; + while(root_dir[free_file_index].filename[0] && free_file_index < dirent_count){ + free_file_index++; + } + if(free_file_index >= dirent_count){ + //!FIXME + verbose && printf("could not find free dirent; this will be fixed in a later version\n"); + exit(-1); + } + root_dir[free_file_index] = dirent; + verbose && printf("Found a free dirent at index %u\n", free_file_index); + for(uint32_t i = 0; i < (dirent_count * sizeof(file_t)) / info->bpb.bytes_per_sector /info->bpb.sectors_per_cluster; i++){ + write_sector(file, (info->bpb.reserved_sectors + (info->bpb.fat_count * info->bpb.sectors_per_fat) + info->file_table[i] * info->bpb.sectors_per_cluster), info->bpb.sectors_per_cluster, (buffer_t)(root_dir + i * info->bpb.sectors_per_cluster * info->bpb.bytes_per_sector)); + + } } -int read_file(fat_info *info, uint32_t first_cluster, file_t *file, buffer_t buffer){ +int read_file(fat_info *info, uint32_t first_cluster, file_t *file, buffer_t *buffer, FILE *disk){ + uint32_t cluster_size_bytes = info->bpb.bytes_per_sector * info->bpb.sectors_per_cluster; if(file == 0){ - buffer_t buf; - + verbose && printf("Reading starting from cluster %d\n", first_cluster); + buffer_t buf = malloc(1); + uint32_t allocated = 0; + uint32_t cluster = first_cluster; + do { + allocated++; + buf = realloc(buf, cluster_size_bytes * allocated); + verbose && printf("Reallocated to %u, ptr: %p\n", allocated * cluster_size_bytes, buf); + read_sector(disk, info->bpb.reserved_sectors + (info->bpb.fat_count * info->bpb.sectors_per_fat) + cluster * info->bpb.sectors_per_cluster, info->bpb.sectors_per_cluster, buf + (allocated * cluster_size_bytes)); + cluster = info->file_table[cluster]; + }while(cluster != FILE_END); + if(*buffer != 0){ + free(buffer); + } + verbose && printf("Read %d cluster starting from cluster %d\n", allocated, first_cluster); + *buffer = buf; + return allocated * cluster_size_bytes; } } @@ -238,7 +277,7 @@ int main(int argc, char **argv){ detect_repair_fs(output_file, &info); verbose && printf("Finished. Exiting...\n"); for(int i = 0; i < filec; i++){ - write_file(files[i], &info, output_file); + create_file(files[i], &info, output_file); } fat_write_back(output_file, &info); return 0;