X-Git-Url: http://git.droids-corp.org/?p=protos%2Fimu.git;a=blobdiff_plain;f=fat.c;h=367d48965248090d93c9910d6733784b6392dc6f;hp=e62f4cf917257c65d9e0b75579d29b2640b5dbaf;hb=de6cbbfa24c5af2030ab1a46ee94bcc8b35910b9;hpb=8d98ff2833dbd04ec343be49c416166e523ad889 diff --git a/fat.c b/fat.c index e62f4cf..367d489 100644 --- a/fat.c +++ b/fat.c @@ -1,5 +1,5 @@ -/* +/* * Copyright (c) 2006-2012 by Roland Riegel * * This file is free software; you can redistribute it and/or modify @@ -24,7 +24,7 @@ * \addtogroup fat FAT support * * This module implements FAT16/FAT32 read and write access. - * + * * The following features are supported: * - File names up to 31 characters long. * - Unlimited depth of subdirectories. @@ -33,7 +33,7 @@ * - Reading and writing from and to files. * - File resizing. * - File sizes of up to 4 gigabytes. - * + * * @{ */ /** @@ -106,7 +106,7 @@ * LFN entry 2 * LFN entry 1 * 8.3 entry (see above) - * + * * lfn entry: * ========== * offset length description @@ -128,7 +128,7 @@ * 26 2 cluster (unused, always 0) * 28 2 unicode character 12 * 30 2 unicode character 13 - * + * * The ordinal field contains a descending number, from n to 1. * For the n'th lfn entry the ordinal field is or'ed with 0x40. * For deleted lfn entries, the ordinal field is set to 0xe5. @@ -242,24 +242,24 @@ struct fat_fs_struct* fat_open(struct partition_struct* partition) 0 #endif ) - return 0; + return 0; #if USE_DYNAMIC_MEMORY struct fat_fs_struct* fs = malloc(sizeof(*fs)); if(!fs) - return 0; + return 0; #else struct fat_fs_struct* fs = fat_fs_handles; uint8_t i; for(i = 0; i < FAT_FS_COUNT; ++i) { - if(!fs->partition) - break; + if(!fs->partition) + break; - ++fs; + ++fs; } if(i >= FAT_FS_COUNT) - return 0; + return 0; #endif memset(fs, 0, sizeof(*fs)); @@ -268,13 +268,13 @@ struct fat_fs_struct* fat_open(struct partition_struct* partition) if(!fat_read_header(fs)) { #if USE_DYNAMIC_MEMORY - free(fs); + free(fs); #else - fs->partition = 0; + fs->partition = 0; #endif - return 0; + return 0; } - + return fs; } @@ -291,7 +291,7 @@ struct fat_fs_struct* fat_open(struct partition_struct* partition) void fat_close(struct fat_fs_struct* fs) { if(!fs) - return; + return; #if USE_DYNAMIC_MEMORY free(fs); @@ -310,11 +310,11 @@ void fat_close(struct fat_fs_struct* fs) uint8_t fat_read_header(struct fat_fs_struct* fs) { if(!fs) - return 0; + return 0; struct partition_struct* partition = fs->partition; if(!partition) - return 0; + return 0; /* read fat parameters */ #if FAT_FAT32_SUPPORT @@ -324,7 +324,7 @@ uint8_t fat_read_header(struct fat_fs_struct* fs) #endif offset_t partition_offset = (offset_t) partition->offset * 512; if(!partition->device_read(partition_offset + 0x0b, buffer, sizeof(buffer))) - return 0; + return 0; uint16_t bytes_per_sector = read16(&buffer[0x00]); uint16_t reserved_sectors = read16(&buffer[0x03]); @@ -341,54 +341,54 @@ uint8_t fat_read_header(struct fat_fs_struct* fs) if(sector_count == 0) { - if(sector_count_16 == 0) - /* illegal volume size */ - return 0; - else - sector_count = sector_count_16; + if(sector_count_16 == 0) + /* illegal volume size */ + return 0; + else + sector_count = sector_count_16; } #if FAT_FAT32_SUPPORT if(sectors_per_fat != 0) - sectors_per_fat32 = sectors_per_fat; + sectors_per_fat32 = sectors_per_fat; else if(sectors_per_fat32 == 0) - /* this is neither FAT16 nor FAT32 */ - return 0; + /* this is neither FAT16 nor FAT32 */ + return 0; #else if(sectors_per_fat == 0) - /* this is not a FAT16 */ - return 0; + /* this is not a FAT16 */ + return 0; #endif /* determine the type of FAT we have here */ uint32_t data_sector_count = sector_count - - reserved_sectors + - reserved_sectors #if FAT_FAT32_SUPPORT - - sectors_per_fat32 * fat_copies + - sectors_per_fat32 * fat_copies #else - - (uint32_t) sectors_per_fat * fat_copies + - (uint32_t) sectors_per_fat * fat_copies #endif - - ((max_root_entries * 32 + bytes_per_sector - 1) / bytes_per_sector); + - ((max_root_entries * 32 + bytes_per_sector - 1) / bytes_per_sector); uint32_t data_cluster_count = data_sector_count / sectors_per_cluster; if(data_cluster_count < 4085) - /* this is a FAT12, not supported */ - return 0; + /* this is a FAT12, not supported */ + return 0; else if(data_cluster_count < 65525) - /* this is a FAT16 */ - partition->type = PARTITION_TYPE_FAT16; + /* this is a FAT16 */ + partition->type = PARTITION_TYPE_FAT16; else - /* this is a FAT32 */ - partition->type = PARTITION_TYPE_FAT32; + /* this is a FAT32 */ + partition->type = PARTITION_TYPE_FAT32; /* fill header information */ struct fat_header_struct* header = &fs->header; memset(header, 0, sizeof(*header)); - + header->size = (offset_t) sector_count * bytes_per_sector; header->fat_offset = /* jump to partition */ - partition_offset + - /* jump to fat */ - (offset_t) reserved_sectors * bytes_per_sector; + partition_offset + + /* jump to fat */ + (offset_t) reserved_sectors * bytes_per_sector; header->fat_size = (data_cluster_count + 2) * (partition->type == PARTITION_TYPE_FAT16 ? 2 : 4); header->sector_size = bytes_per_sector; @@ -398,25 +398,25 @@ uint8_t fat_read_header(struct fat_fs_struct* fs) if(partition->type == PARTITION_TYPE_FAT16) #endif { - header->root_dir_offset = /* jump to fats */ - header->fat_offset + - /* jump to root directory entries */ - (offset_t) fat_copies * sectors_per_fat * bytes_per_sector; - - header->cluster_zero_offset = /* jump to root directory entries */ - header->root_dir_offset + - /* skip root directory entries */ - (offset_t) max_root_entries * 32; + header->root_dir_offset = /* jump to fats */ + header->fat_offset + + /* jump to root directory entries */ + (offset_t) fat_copies * sectors_per_fat * bytes_per_sector; + + header->cluster_zero_offset = /* jump to root directory entries */ + header->root_dir_offset + + /* skip root directory entries */ + (offset_t) max_root_entries * 32; } #if FAT_FAT32_SUPPORT else { - header->cluster_zero_offset = /* jump to fats */ - header->fat_offset + - /* skip fats */ - (offset_t) fat_copies * sectors_per_fat32 * bytes_per_sector; + header->cluster_zero_offset = /* jump to fats */ + header->fat_offset + + /* skip fats */ + (offset_t) fat_copies * sectors_per_fat32 * bytes_per_sector; - header->root_dir_cluster = cluster_root_dir; + header->root_dir_cluster = cluster_root_dir; } #endif @@ -438,41 +438,41 @@ uint8_t fat_read_header(struct fat_fs_struct* fs) cluster_t fat_get_next_cluster(const struct fat_fs_struct* fs, cluster_t cluster_num) { if(!fs || cluster_num < 2) - return 0; + return 0; #if FAT_FAT32_SUPPORT if(fs->partition->type == PARTITION_TYPE_FAT32) { - /* read appropriate fat entry */ - uint32_t fat_entry; - if(!fs->partition->device_read(fs->header.fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry))) - return 0; - - /* determine next cluster from fat */ - cluster_num = ltoh32(fat_entry); - - if(cluster_num == FAT32_CLUSTER_FREE || - cluster_num == FAT32_CLUSTER_BAD || - (cluster_num >= FAT32_CLUSTER_RESERVED_MIN && cluster_num <= FAT32_CLUSTER_RESERVED_MAX) || - (cluster_num >= FAT32_CLUSTER_LAST_MIN && cluster_num <= FAT32_CLUSTER_LAST_MAX)) - return 0; + /* read appropriate fat entry */ + uint32_t fat_entry; + if(!fs->partition->device_read(fs->header.fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry))) + return 0; + + /* determine next cluster from fat */ + cluster_num = ltoh32(fat_entry); + + if(cluster_num == FAT32_CLUSTER_FREE || + cluster_num == FAT32_CLUSTER_BAD || + (cluster_num >= FAT32_CLUSTER_RESERVED_MIN && cluster_num <= FAT32_CLUSTER_RESERVED_MAX) || + (cluster_num >= FAT32_CLUSTER_LAST_MIN && cluster_num <= FAT32_CLUSTER_LAST_MAX)) + return 0; } else #endif { - /* read appropriate fat entry */ - uint16_t fat_entry; - if(!fs->partition->device_read(fs->header.fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry))) - return 0; - - /* determine next cluster from fat */ - cluster_num = ltoh16(fat_entry); - - if(cluster_num == FAT16_CLUSTER_FREE || - cluster_num == FAT16_CLUSTER_BAD || - (cluster_num >= FAT16_CLUSTER_RESERVED_MIN && cluster_num <= FAT16_CLUSTER_RESERVED_MAX) || - (cluster_num >= FAT16_CLUSTER_LAST_MIN && cluster_num <= FAT16_CLUSTER_LAST_MAX)) - return 0; + /* read appropriate fat entry */ + uint16_t fat_entry; + if(!fs->partition->device_read(fs->header.fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry))) + return 0; + + /* determine next cluster from fat */ + cluster_num = ltoh16(fat_entry); + + if(cluster_num == FAT16_CLUSTER_FREE || + cluster_num == FAT16_CLUSTER_BAD || + (cluster_num >= FAT16_CLUSTER_RESERVED_MIN && cluster_num <= FAT16_CLUSTER_RESERVED_MAX) || + (cluster_num >= FAT16_CLUSTER_LAST_MIN && cluster_num <= FAT16_CLUSTER_LAST_MAX)) + return 0; } return cluster_num; @@ -493,7 +493,7 @@ cluster_t fat_get_next_cluster(const struct fat_fs_struct* fs, cluster_t cluster cluster_t fat_append_clusters(struct fat_fs_struct* fs, cluster_t cluster_num, cluster_t count) { if(!fs) - return 0; + return 0; device_read_t device_read = fs->partition->device_read; device_write_t device_write = fs->partition->device_write; @@ -508,116 +508,116 @@ cluster_t fat_append_clusters(struct fat_fs_struct* fs, cluster_t cluster_num, c uint8_t is_fat32 = (fs->partition->type == PARTITION_TYPE_FAT32); if(is_fat32) - cluster_count = fs->header.fat_size / sizeof(fat_entry32); + cluster_count = fs->header.fat_size / sizeof(fat_entry32); else #endif - cluster_count = fs->header.fat_size / sizeof(fat_entry16); + cluster_count = fs->header.fat_size / sizeof(fat_entry16); fs->cluster_free = 0; for(cluster_t cluster_left = cluster_count; cluster_left > 0; --cluster_left, ++cluster_current) { - if(cluster_current < 2 || cluster_current >= cluster_count) - cluster_current = 2; + if(cluster_current < 2 || cluster_current >= cluster_count) + cluster_current = 2; #if FAT_FAT32_SUPPORT - if(is_fat32) - { - if(!device_read(fat_offset + (offset_t) cluster_current * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32))) - return 0; - } - else -#endif - { - if(!device_read(fat_offset + (offset_t) cluster_current * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16))) - return 0; - } + if(is_fat32) + { + if(!device_read(fat_offset + (offset_t) cluster_current * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32))) + return 0; + } + else +#endif + { + if(!device_read(fat_offset + (offset_t) cluster_current * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16))) + return 0; + } #if FAT_FAT32_SUPPORT - if(is_fat32) - { - /* check if this is a free cluster */ - if(fat_entry32 != HTOL32(FAT32_CLUSTER_FREE)) - continue; - - /* If we don't need this free cluster for the - * current allocation, we keep it in mind for - * the next time. - */ - if(count_left == 0) - { - fs->cluster_free = cluster_current; - break; - } - - /* allocate cluster */ - if(cluster_next == 0) - fat_entry32 = HTOL32(FAT32_CLUSTER_LAST_MAX); - else - fat_entry32 = htol32(cluster_next); - - if(!device_write(fat_offset + (offset_t) cluster_current * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32))) - break; - } - else -#endif - { - /* check if this is a free cluster */ - if(fat_entry16 != HTOL16(FAT16_CLUSTER_FREE)) - continue; - - /* If we don't need this free cluster for the - * current allocation, we keep it in mind for - * the next time. - */ - if(count_left == 0) - { - fs->cluster_free = cluster_current; - break; - } - - /* allocate cluster */ - if(cluster_next == 0) - fat_entry16 = HTOL16(FAT16_CLUSTER_LAST_MAX); - else - fat_entry16 = htol16((uint16_t) cluster_next); - - if(!device_write(fat_offset + (offset_t) cluster_current * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16))) - break; - } - - cluster_next = cluster_current; - --count_left; + if(is_fat32) + { + /* check if this is a free cluster */ + if(fat_entry32 != HTOL32(FAT32_CLUSTER_FREE)) + continue; + + /* If we don't need this free cluster for the + * current allocation, we keep it in mind for + * the next time. + */ + if(count_left == 0) + { + fs->cluster_free = cluster_current; + break; + } + + /* allocate cluster */ + if(cluster_next == 0) + fat_entry32 = HTOL32(FAT32_CLUSTER_LAST_MAX); + else + fat_entry32 = htol32(cluster_next); + + if(!device_write(fat_offset + (offset_t) cluster_current * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32))) + break; + } + else +#endif + { + /* check if this is a free cluster */ + if(fat_entry16 != HTOL16(FAT16_CLUSTER_FREE)) + continue; + + /* If we don't need this free cluster for the + * current allocation, we keep it in mind for + * the next time. + */ + if(count_left == 0) + { + fs->cluster_free = cluster_current; + break; + } + + /* allocate cluster */ + if(cluster_next == 0) + fat_entry16 = HTOL16(FAT16_CLUSTER_LAST_MAX); + else + fat_entry16 = htol16((uint16_t) cluster_next); + + if(!device_write(fat_offset + (offset_t) cluster_current * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16))) + break; + } + + cluster_next = cluster_current; + --count_left; } do { - if(count_left > 0) - break; - - /* We allocated a new cluster chain. Now join - * it with the existing one (if any). - */ - if(cluster_num >= 2) - { + if(count_left > 0) + break; + + /* We allocated a new cluster chain. Now join + * it with the existing one (if any). + */ + if(cluster_num >= 2) + { #if FAT_FAT32_SUPPORT - if(is_fat32) - { - fat_entry32 = htol32(cluster_next); + if(is_fat32) + { + fat_entry32 = htol32(cluster_next); - if(!device_write(fat_offset + (offset_t) cluster_num * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32))) - break; - } - else + if(!device_write(fat_offset + (offset_t) cluster_num * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32))) + break; + } + else #endif - { - fat_entry16 = htol16((uint16_t) cluster_next); + { + fat_entry16 = htol16((uint16_t) cluster_next); - if(!device_write(fat_offset + (offset_t) cluster_num * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16))) - break; - } - } + if(!device_write(fat_offset + (offset_t) cluster_num * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16))) + break; + } + } - return cluster_next; + return cluster_next; } while(0); @@ -651,82 +651,82 @@ cluster_t fat_append_clusters(struct fat_fs_struct* fs, cluster_t cluster_num, c uint8_t fat_free_clusters(struct fat_fs_struct* fs, cluster_t cluster_num) { if(!fs || cluster_num < 2) - return 0; + return 0; offset_t fat_offset = fs->header.fat_offset; #if FAT_FAT32_SUPPORT if(fs->partition->type == PARTITION_TYPE_FAT32) { - uint32_t fat_entry; - while(cluster_num) - { - if(!fs->partition->device_read(fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry))) - return 0; - - /* get next cluster of current cluster before freeing current cluster */ - uint32_t cluster_num_next = ltoh32(fat_entry); - - if(cluster_num_next == FAT32_CLUSTER_FREE) - return 1; - if(cluster_num_next == FAT32_CLUSTER_BAD || - (cluster_num_next >= FAT32_CLUSTER_RESERVED_MIN && - cluster_num_next <= FAT32_CLUSTER_RESERVED_MAX - ) - ) - return 0; - if(cluster_num_next >= FAT32_CLUSTER_LAST_MIN && cluster_num_next <= FAT32_CLUSTER_LAST_MAX) - cluster_num_next = 0; - - /* We know we will free the cluster, so remember it as - * free for the next allocation. - */ - if(!fs->cluster_free) - fs->cluster_free = cluster_num; - - /* free cluster */ - fat_entry = HTOL32(FAT32_CLUSTER_FREE); - fs->partition->device_write(fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)); - - /* We continue in any case here, even if freeing the cluster failed. - * The cluster is lost, but maybe we can still free up some later ones. - */ - - cluster_num = cluster_num_next; - } + uint32_t fat_entry; + while(cluster_num) + { + if(!fs->partition->device_read(fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry))) + return 0; + + /* get next cluster of current cluster before freeing current cluster */ + uint32_t cluster_num_next = ltoh32(fat_entry); + + if(cluster_num_next == FAT32_CLUSTER_FREE) + return 1; + if(cluster_num_next == FAT32_CLUSTER_BAD || + (cluster_num_next >= FAT32_CLUSTER_RESERVED_MIN && + cluster_num_next <= FAT32_CLUSTER_RESERVED_MAX + ) + ) + return 0; + if(cluster_num_next >= FAT32_CLUSTER_LAST_MIN && cluster_num_next <= FAT32_CLUSTER_LAST_MAX) + cluster_num_next = 0; + + /* We know we will free the cluster, so remember it as + * free for the next allocation. + */ + if(!fs->cluster_free) + fs->cluster_free = cluster_num; + + /* free cluster */ + fat_entry = HTOL32(FAT32_CLUSTER_FREE); + fs->partition->device_write(fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)); + + /* We continue in any case here, even if freeing the cluster failed. + * The cluster is lost, but maybe we can still free up some later ones. + */ + + cluster_num = cluster_num_next; + } } else #endif { - uint16_t fat_entry; - while(cluster_num) - { - if(!fs->partition->device_read(fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry))) - return 0; - - /* get next cluster of current cluster before freeing current cluster */ - uint16_t cluster_num_next = ltoh16(fat_entry); - - if(cluster_num_next == FAT16_CLUSTER_FREE) - return 1; - if(cluster_num_next == FAT16_CLUSTER_BAD || - (cluster_num_next >= FAT16_CLUSTER_RESERVED_MIN && - cluster_num_next <= FAT16_CLUSTER_RESERVED_MAX - ) - ) - return 0; - if(cluster_num_next >= FAT16_CLUSTER_LAST_MIN && cluster_num_next <= FAT16_CLUSTER_LAST_MAX) - cluster_num_next = 0; - - /* free cluster */ - fat_entry = HTOL16(FAT16_CLUSTER_FREE); - fs->partition->device_write(fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)); - - /* We continue in any case here, even if freeing the cluster failed. - * The cluster is lost, but maybe we can still free up some later ones. - */ - - cluster_num = cluster_num_next; - } + uint16_t fat_entry; + while(cluster_num) + { + if(!fs->partition->device_read(fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry))) + return 0; + + /* get next cluster of current cluster before freeing current cluster */ + uint16_t cluster_num_next = ltoh16(fat_entry); + + if(cluster_num_next == FAT16_CLUSTER_FREE) + return 1; + if(cluster_num_next == FAT16_CLUSTER_BAD || + (cluster_num_next >= FAT16_CLUSTER_RESERVED_MIN && + cluster_num_next <= FAT16_CLUSTER_RESERVED_MAX + ) + ) + return 0; + if(cluster_num_next >= FAT16_CLUSTER_LAST_MIN && cluster_num_next <= FAT16_CLUSTER_LAST_MAX) + cluster_num_next = 0; + + /* free cluster */ + fat_entry = HTOL16(FAT16_CLUSTER_FREE); + fs->partition->device_write(fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)); + + /* We continue in any case here, even if freeing the cluster failed. + * The cluster is lost, but maybe we can still free up some later ones. + */ + + cluster_num = cluster_num_next; + } } return 1; @@ -749,7 +749,7 @@ uint8_t fat_free_clusters(struct fat_fs_struct* fs, cluster_t cluster_num) uint8_t fat_terminate_clusters(struct fat_fs_struct* fs, cluster_t cluster_num) { if(!fs || cluster_num < 2) - return 0; + return 0; /* fetch next cluster before overwriting the cluster entry */ cluster_t cluster_num_next = fat_get_next_cluster(fs, cluster_num); @@ -758,23 +758,23 @@ uint8_t fat_terminate_clusters(struct fat_fs_struct* fs, cluster_t cluster_num) #if FAT_FAT32_SUPPORT if(fs->partition->type == PARTITION_TYPE_FAT32) { - uint32_t fat_entry = HTOL32(FAT32_CLUSTER_LAST_MAX); - if(!fs->partition->device_write(fs->header.fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry))) - return 0; + uint32_t fat_entry = HTOL32(FAT32_CLUSTER_LAST_MAX); + if(!fs->partition->device_write(fs->header.fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry))) + return 0; } else #endif { - uint16_t fat_entry = HTOL16(FAT16_CLUSTER_LAST_MAX); - if(!fs->partition->device_write(fs->header.fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry))) - return 0; + uint16_t fat_entry = HTOL16(FAT16_CLUSTER_LAST_MAX); + if(!fs->partition->device_write(fs->header.fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry))) + return 0; } /* free remaining clusters */ if(cluster_num_next) - return fat_free_clusters(fs, cluster_num_next); + return fat_free_clusters(fs, cluster_num_next); else - return 1; + return 1; } #endif @@ -792,18 +792,18 @@ uint8_t fat_terminate_clusters(struct fat_fs_struct* fs, cluster_t cluster_num) uint8_t fat_clear_cluster(const struct fat_fs_struct* fs, cluster_t cluster_num) { if(cluster_num < 2) - return 0; + return 0; offset_t cluster_offset = fat_cluster_offset(fs, cluster_num); uint8_t zero[16]; memset(zero, 0, sizeof(zero)); return fs->partition->device_write_interval(cluster_offset, - zero, - fs->header.cluster_size, - fat_clear_cluster_callback, - 0 - ); + zero, + fs->header.cluster_size, + fat_clear_cluster_callback, + 0 + ); } #endif @@ -829,7 +829,7 @@ uintptr_t fat_clear_cluster_callback(uint8_t* buffer, offset_t offset, void* p) offset_t fat_cluster_offset(const struct fat_fs_struct* fs, cluster_t cluster_num) { if(!fs || cluster_num < 2) - return 0; + return 0; return fs->header.cluster_zero_offset + (offset_t) (cluster_num - 2) * fs->header.cluster_size; } @@ -849,10 +849,10 @@ offset_t fat_cluster_offset(const struct fat_fs_struct* fs, cluster_t cluster_nu uint8_t fat_get_dir_entry_of_path(struct fat_fs_struct* fs, const char* path, struct fat_dir_entry_struct* dir_entry) { if(!fs || !path || path[0] == '\0' || !dir_entry) - return 0; + return 0; if(path[0] == '/') - ++path; + ++path; /* begin with the root directory */ memset(dir_entry, 0, sizeof(*dir_entry)); @@ -860,56 +860,56 @@ uint8_t fat_get_dir_entry_of_path(struct fat_fs_struct* fs, const char* path, st while(1) { - if(path[0] == '\0') - return 1; - - struct fat_dir_struct* dd = fat_open_dir(fs, dir_entry); - if(!dd) - break; - - /* extract the next hierarchy we will search for */ - const char* sub_path = strchr(path, '/'); - uint8_t length_to_sep; - if(sub_path) - { - length_to_sep = sub_path - path; - ++sub_path; - } - else - { - length_to_sep = strlen(path); - sub_path = path + length_to_sep; - } - - /* read directory entries */ - while(fat_read_dir(dd, dir_entry)) - { - /* check if we have found the next hierarchy */ - if((strlen(dir_entry->long_name) != length_to_sep || - strncmp(path, dir_entry->long_name, length_to_sep) != 0)) - continue; - - fat_close_dir(dd); - dd = 0; - - if(path[length_to_sep] == '\0') - /* we iterated through the whole path and have found the file */ - return 1; - - if(dir_entry->attributes & FAT_ATTRIB_DIR) - { - /* we found a parent directory of the file we are searching for */ - path = sub_path; - break; - } - - /* a parent of the file exists, but not the file itself */ - return 0; - } - - fat_close_dir(dd); + if(path[0] == '\0') + return 1; + + struct fat_dir_struct* dd = fat_open_dir(fs, dir_entry); + if(!dd) + break; + + /* extract the next hierarchy we will search for */ + const char* sub_path = strchr(path, '/'); + uint8_t length_to_sep; + if(sub_path) + { + length_to_sep = sub_path - path; + ++sub_path; + } + else + { + length_to_sep = strlen(path); + sub_path = path + length_to_sep; + } + + /* read directory entries */ + while(fat_read_dir(dd, dir_entry)) + { + /* check if we have found the next hierarchy */ + if((strlen(dir_entry->long_name) != length_to_sep || + strncmp(path, dir_entry->long_name, length_to_sep) != 0)) + continue; + + fat_close_dir(dd); + dd = 0; + + if(path[length_to_sep] == '\0') + /* we iterated through the whole path and have found the file */ + return 1; + + if(dir_entry->attributes & FAT_ATTRIB_DIR) + { + /* we found a parent directory of the file we are searching for */ + path = sub_path; + break; + } + + /* a parent of the file exists, but not the file itself */ + return 0; + } + + fat_close_dir(dd); } - + return 0; } @@ -925,26 +925,26 @@ uint8_t fat_get_dir_entry_of_path(struct fat_fs_struct* fs, const char* path, st struct fat_file_struct* fat_open_file(struct fat_fs_struct* fs, const struct fat_dir_entry_struct* dir_entry) { if(!fs || !dir_entry || (dir_entry->attributes & FAT_ATTRIB_DIR)) - return 0; + return 0; #if USE_DYNAMIC_MEMORY struct fat_file_struct* fd = malloc(sizeof(*fd)); if(!fd) - return 0; + return 0; #else struct fat_file_struct* fd = fat_file_handles; uint8_t i; for(i = 0; i < FAT_FILE_COUNT; ++i) { - if(!fd->fs) - break; + if(!fd->fs) + break; - ++fd; + ++fd; } if(i >= FAT_FILE_COUNT) - return 0; + return 0; #endif - + memcpy(&fd->dir_entry, dir_entry, sizeof(*dir_entry)); fd->fs = fs; fd->pos = 0; @@ -965,14 +965,14 @@ void fat_close_file(struct fat_file_struct* fd) if(fd) { #if FAT_DELAY_DIRENTRY_UPDATE - /* write directory entry */ - fat_write_dir_entry(fd->fs, &fd->dir_entry); + /* write directory entry */ + fat_write_dir_entry(fd->fs, &fd->dir_entry); #endif #if USE_DYNAMIC_MEMORY - free(fd); + free(fd); #else - fd->fs = 0; + fd->fs = 0; #endif } } @@ -980,7 +980,7 @@ void fat_close_file(struct fat_file_struct* fd) /** * \ingroup fat_file * Reads data from a file. - * + * * The data requested is read from the current file location. * * \param[in] fd The file handle of the file from which to read. @@ -993,14 +993,14 @@ intptr_t fat_read_file(struct fat_file_struct* fd, uint8_t* buffer, uintptr_t bu { /* check arguments */ if(!fd || !buffer || buffer_len < 1) - return -1; + return -1; /* determine number of bytes to read */ if(fd->pos + buffer_len > fd->dir_entry.file_size) - buffer_len = fd->dir_entry.file_size - fd->pos; + buffer_len = fd->dir_entry.file_size - fd->pos; if(buffer_len == 0) - return 0; - + return 0; + uint16_t cluster_size = fd->fs->header.cluster_size; cluster_t cluster_num = fd->pos_cluster; uintptr_t buffer_left = buffer_len; @@ -1009,62 +1009,62 @@ intptr_t fat_read_file(struct fat_file_struct* fd, uint8_t* buffer, uintptr_t bu /* find cluster in which to start reading */ if(!cluster_num) { - cluster_num = fd->dir_entry.cluster; - - if(!cluster_num) - { - if(!fd->pos) - return 0; - else - return -1; - } - - if(fd->pos) - { - uint32_t pos = fd->pos; - while(pos >= cluster_size) - { - pos -= cluster_size; - cluster_num = fat_get_next_cluster(fd->fs, cluster_num); - if(!cluster_num) - return -1; - } - } + cluster_num = fd->dir_entry.cluster; + + if(!cluster_num) + { + if(!fd->pos) + return 0; + else + return -1; + } + + if(fd->pos) + { + uint32_t pos = fd->pos; + while(pos >= cluster_size) + { + pos -= cluster_size; + cluster_num = fat_get_next_cluster(fd->fs, cluster_num); + if(!cluster_num) + return -1; + } + } } - + /* read data */ do { - /* calculate data size to copy from cluster */ - offset_t cluster_offset = fat_cluster_offset(fd->fs, cluster_num) + first_cluster_offset; - uint16_t copy_length = cluster_size - first_cluster_offset; - if(copy_length > buffer_left) - copy_length = buffer_left; - - /* read data */ - if(!fd->fs->partition->device_read(cluster_offset, buffer, copy_length)) - return buffer_len - buffer_left; - - /* calculate new file position */ - buffer += copy_length; - buffer_left -= copy_length; - fd->pos += copy_length; - - if(first_cluster_offset + copy_length >= cluster_size) - { - /* we are on a cluster boundary, so get the next cluster */ - if((cluster_num = fat_get_next_cluster(fd->fs, cluster_num))) - { - first_cluster_offset = 0; - } - else - { - fd->pos_cluster = 0; - return buffer_len - buffer_left; - } - } - - fd->pos_cluster = cluster_num; + /* calculate data size to copy from cluster */ + offset_t cluster_offset = fat_cluster_offset(fd->fs, cluster_num) + first_cluster_offset; + uint16_t copy_length = cluster_size - first_cluster_offset; + if(copy_length > buffer_left) + copy_length = buffer_left; + + /* read data */ + if(!fd->fs->partition->device_read(cluster_offset, buffer, copy_length)) + return buffer_len - buffer_left; + + /* calculate new file position */ + buffer += copy_length; + buffer_left -= copy_length; + fd->pos += copy_length; + + if(first_cluster_offset + copy_length >= cluster_size) + { + /* we are on a cluster boundary, so get the next cluster */ + if((cluster_num = fat_get_next_cluster(fd->fs, cluster_num))) + { + first_cluster_offset = 0; + } + else + { + fd->pos_cluster = 0; + return buffer_len - buffer_left; + } + } + + fd->pos_cluster = cluster_num; } while(buffer_left > 0); /* check if we are done */ @@ -1075,7 +1075,7 @@ intptr_t fat_read_file(struct fat_file_struct* fd, uint8_t* buffer, uintptr_t bu /** * \ingroup fat_file * Writes data to a file. - * + * * The data is written to the current file location. * * \param[in] fd The file handle of the file to which to write. @@ -1088,9 +1088,9 @@ intptr_t fat_write_file(struct fat_file_struct* fd, const uint8_t* buffer, uintp { /* check arguments */ if(!fd || !buffer || buffer_len < 1) - return -1; + return -1; if(fd->pos > fd->dir_entry.file_size) - return -1; + return -1; uint16_t cluster_size = fd->fs->header.cluster_size; cluster_t cluster_num = fd->pos_cluster; @@ -1100,83 +1100,83 @@ intptr_t fat_write_file(struct fat_file_struct* fd, const uint8_t* buffer, uintp /* find cluster in which to start writing */ if(!cluster_num) { - cluster_num = fd->dir_entry.cluster; - - if(!cluster_num) - { - if(!fd->pos) - { - /* empty file */ - fd->dir_entry.cluster = cluster_num = fat_append_clusters(fd->fs, 0, 1); - if(!cluster_num) - return 0; - } - else - { - return -1; - } - } - - if(fd->pos) - { - uint32_t pos = fd->pos; - cluster_t cluster_num_next; - while(pos >= cluster_size) - { - pos -= cluster_size; - cluster_num_next = fat_get_next_cluster(fd->fs, cluster_num); - if(!cluster_num_next) - { - if(pos != 0) - return -1; /* current file position points beyond end of file */ - - /* the file exactly ends on a cluster boundary, and we append to it */ - cluster_num_next = fat_append_clusters(fd->fs, cluster_num, 1); - if(!cluster_num_next) - return 0; - } - - cluster_num = cluster_num_next; - } - } + cluster_num = fd->dir_entry.cluster; + + if(!cluster_num) + { + if(!fd->pos) + { + /* empty file */ + fd->dir_entry.cluster = cluster_num = fat_append_clusters(fd->fs, 0, 1); + if(!cluster_num) + return 0; + } + else + { + return -1; + } + } + + if(fd->pos) + { + uint32_t pos = fd->pos; + cluster_t cluster_num_next; + while(pos >= cluster_size) + { + pos -= cluster_size; + cluster_num_next = fat_get_next_cluster(fd->fs, cluster_num); + if(!cluster_num_next) + { + if(pos != 0) + return -1; /* current file position points beyond end of file */ + + /* the file exactly ends on a cluster boundary, and we append to it */ + cluster_num_next = fat_append_clusters(fd->fs, cluster_num, 1); + if(!cluster_num_next) + return 0; + } + + cluster_num = cluster_num_next; + } + } } - + /* write data */ do { - /* calculate data size to write to cluster */ - offset_t cluster_offset = fat_cluster_offset(fd->fs, cluster_num) + first_cluster_offset; - uint16_t write_length = cluster_size - first_cluster_offset; - if(write_length > buffer_left) - write_length = buffer_left; - - /* write data which fits into the current cluster */ - if(!fd->fs->partition->device_write(cluster_offset, buffer, write_length)) - break; - - /* calculate new file position */ - buffer += write_length; - buffer_left -= write_length; - fd->pos += write_length; - - if(first_cluster_offset + write_length >= cluster_size) - { - /* we are on a cluster boundary, so get the next cluster */ - cluster_t cluster_num_next = fat_get_next_cluster(fd->fs, cluster_num); - if(!cluster_num_next && buffer_left > 0) - /* we reached the last cluster, append a new one */ - cluster_num_next = fat_append_clusters(fd->fs, cluster_num, 1); - if(!cluster_num_next) - { - fd->pos_cluster = 0; - break; - } - - cluster_num = cluster_num_next; - first_cluster_offset = 0; - } - - fd->pos_cluster = cluster_num; + /* calculate data size to write to cluster */ + offset_t cluster_offset = fat_cluster_offset(fd->fs, cluster_num) + first_cluster_offset; + uint16_t write_length = cluster_size - first_cluster_offset; + if(write_length > buffer_left) + write_length = buffer_left; + + /* write data which fits into the current cluster */ + if(!fd->fs->partition->device_write(cluster_offset, buffer, write_length)) + break; + + /* calculate new file position */ + buffer += write_length; + buffer_left -= write_length; + fd->pos += write_length; + + if(first_cluster_offset + write_length >= cluster_size) + { + /* we are on a cluster boundary, so get the next cluster */ + cluster_t cluster_num_next = fat_get_next_cluster(fd->fs, cluster_num); + if(!cluster_num_next && buffer_left > 0) + /* we reached the last cluster, append a new one */ + cluster_num_next = fat_append_clusters(fd->fs, cluster_num, 1); + if(!cluster_num_next) + { + fd->pos_cluster = 0; + break; + } + + cluster_num = cluster_num_next; + first_cluster_offset = 0; + } + + fd->pos_cluster = cluster_num; } while(buffer_left > 0); /* check if we are done */ @@ -1184,23 +1184,23 @@ intptr_t fat_write_file(struct fat_file_struct* fd, const uint8_t* buffer, uintp if(fd->pos > fd->dir_entry.file_size) { #if !FAT_DELAY_DIRENTRY_UPDATE - uint32_t size_old = fd->dir_entry.file_size; + uint32_t size_old = fd->dir_entry.file_size; #endif - /* update file size */ - fd->dir_entry.file_size = fd->pos; + /* update file size */ + fd->dir_entry.file_size = fd->pos; #if !FAT_DELAY_DIRENTRY_UPDATE - /* write directory entry */ - if(!fat_write_dir_entry(fd->fs, &fd->dir_entry)) - { - /* We do not return an error here since we actually wrote - * some data to disk. So we calculate the amount of data - * we wrote to disk and which lies within the old file size. - */ - buffer_left = fd->pos - size_old; - fd->pos = size_old; - } + /* write directory entry */ + if(!fat_write_dir_entry(fd->fs, &fd->dir_entry)) + { + /* We do not return an error here since we actually wrote + * some data to disk. So we calculate the amount of data + * we wrote to disk and which lies within the old file size. + */ + buffer_left = fd->pos - size_old; + fd->pos = size_old; + } #endif } @@ -1236,7 +1236,7 @@ intptr_t fat_write_file(struct fat_file_struct* fd, const uint8_t* buffer, uintp } // file_pos now contains the absolute file position \endcode - * + * * \param[in] fd The file decriptor of the file on which to seek. * \param[in,out] offset A pointer to the new offset, as affected by the \c whence * parameter. The function writes the new absolute offset @@ -1247,22 +1247,22 @@ intptr_t fat_write_file(struct fat_file_struct* fd, const uint8_t* buffer, uintp uint8_t fat_seek_file(struct fat_file_struct* fd, int32_t* offset, uint8_t whence) { if(!fd || !offset) - return 0; + return 0; uint32_t new_pos = fd->pos; switch(whence) { - case FAT_SEEK_SET: - new_pos = *offset; - break; - case FAT_SEEK_CUR: - new_pos += *offset; - break; - case FAT_SEEK_END: - new_pos = fd->dir_entry.file_size + *offset; - break; - default: - return 0; + case FAT_SEEK_SET: + new_pos = *offset; + break; + case FAT_SEEK_CUR: + new_pos += *offset; + break; + case FAT_SEEK_END: + new_pos = fd->dir_entry.file_size + *offset; + break; + default: + return 0; } if(new_pos > fd->dir_entry.file_size @@ -1270,7 +1270,7 @@ uint8_t fat_seek_file(struct fat_file_struct* fd, int32_t* offset, uint8_t whenc && !fat_resize_file(fd, new_pos) #endif ) - return 0; + return 0; fd->pos = new_pos; fd->pos_cluster = 0; @@ -1302,7 +1302,7 @@ uint8_t fat_seek_file(struct fat_file_struct* fd, int32_t* offset, uint8_t whenc uint8_t fat_resize_file(struct fat_file_struct* fd, uint32_t size) { if(!fd) - return 0; + return 0; cluster_t cluster_num = fd->dir_entry.cluster; uint16_t cluster_size = fd->fs->header.cluster_size; @@ -1310,68 +1310,68 @@ uint8_t fat_resize_file(struct fat_file_struct* fd, uint32_t size) do { - if(cluster_num == 0 && size_new == 0) - /* the file stays empty */ - break; - - /* seek to the next cluster as long as we need the space */ - while(size_new > cluster_size) - { - /* get next cluster of file */ - cluster_t cluster_num_next = fat_get_next_cluster(fd->fs, cluster_num); - if(cluster_num_next) - { - cluster_num = cluster_num_next; - size_new -= cluster_size; - } - else - { - break; - } - } - - if(size_new > cluster_size || cluster_num == 0) - { - /* Allocate new cluster chain and append - * it to the existing one, if available. - */ - cluster_t cluster_count = (size_new + cluster_size - 1) / cluster_size; - cluster_t cluster_new_chain = fat_append_clusters(fd->fs, cluster_num, cluster_count); - if(!cluster_new_chain) - return 0; - - if(!cluster_num) - { - cluster_num = cluster_new_chain; - fd->dir_entry.cluster = cluster_num; - } - } - - /* write new directory entry */ - fd->dir_entry.file_size = size; - if(size == 0) - fd->dir_entry.cluster = 0; - if(!fat_write_dir_entry(fd->fs, &fd->dir_entry)) - return 0; - - if(size == 0) - { - /* free all clusters of file */ - fat_free_clusters(fd->fs, cluster_num); - } - else if(size_new <= cluster_size) - { - /* free all clusters no longer needed */ - fat_terminate_clusters(fd->fs, cluster_num); - } + if(cluster_num == 0 && size_new == 0) + /* the file stays empty */ + break; + + /* seek to the next cluster as long as we need the space */ + while(size_new > cluster_size) + { + /* get next cluster of file */ + cluster_t cluster_num_next = fat_get_next_cluster(fd->fs, cluster_num); + if(cluster_num_next) + { + cluster_num = cluster_num_next; + size_new -= cluster_size; + } + else + { + break; + } + } + + if(size_new > cluster_size || cluster_num == 0) + { + /* Allocate new cluster chain and append + * it to the existing one, if available. + */ + cluster_t cluster_count = (size_new + cluster_size - 1) / cluster_size; + cluster_t cluster_new_chain = fat_append_clusters(fd->fs, cluster_num, cluster_count); + if(!cluster_new_chain) + return 0; + + if(!cluster_num) + { + cluster_num = cluster_new_chain; + fd->dir_entry.cluster = cluster_num; + } + } + + /* write new directory entry */ + fd->dir_entry.file_size = size; + if(size == 0) + fd->dir_entry.cluster = 0; + if(!fat_write_dir_entry(fd->fs, &fd->dir_entry)) + return 0; + + if(size == 0) + { + /* free all clusters of file */ + fat_free_clusters(fd->fs, cluster_num); + } + else if(size_new <= cluster_size) + { + /* free all clusters no longer needed */ + fat_terminate_clusters(fd->fs, cluster_num); + } } while(0); /* correct file position */ if(size < fd->pos) { - fd->pos = size; - fd->pos_cluster = 0; + fd->pos = size; + fd->pos_cluster = 0; } return 1; @@ -1390,26 +1390,26 @@ uint8_t fat_resize_file(struct fat_file_struct* fd, uint32_t size) struct fat_dir_struct* fat_open_dir(struct fat_fs_struct* fs, const struct fat_dir_entry_struct* dir_entry) { if(!fs || !dir_entry || !(dir_entry->attributes & FAT_ATTRIB_DIR)) - return 0; + return 0; #if USE_DYNAMIC_MEMORY struct fat_dir_struct* dd = malloc(sizeof(*dd)); if(!dd) - return 0; + return 0; #else struct fat_dir_struct* dd = fat_dir_handles; uint8_t i; for(i = 0; i < FAT_DIR_COUNT; ++i) { - if(!dd->fs) - break; + if(!dd->fs) + break; - ++dd; + ++dd; } if(i >= FAT_DIR_COUNT) - return 0; + return 0; #endif - + memcpy(&dd->dir_entry, dir_entry, sizeof(*dir_entry)); dd->fs = fs; dd->entry_cluster = dir_entry->cluster; @@ -1433,9 +1433,9 @@ void fat_close_dir(struct fat_dir_struct* dd) { if(dd) #if USE_DYNAMIC_MEMORY - free(dd); + free(dd); #else - dd->fs = 0; + dd->fs = 0; #endif } @@ -1451,7 +1451,7 @@ void fat_close_dir(struct fat_dir_struct* dd) uint8_t fat_read_dir(struct fat_dir_struct* dd, struct fat_dir_entry_struct* dir_entry) { if(!dd || !dir_entry) - return 0; + return 0; /* get current position of directory handle */ struct fat_fs_struct* fs = dd->fs; @@ -1463,13 +1463,13 @@ uint8_t fat_read_dir(struct fat_dir_struct* dd, struct fat_dir_entry_struct* dir if(cluster_offset >= cluster_size) { - /* The latest call hit the border of the last cluster in - * the chain, but it still returned a directory entry. - * So we now reset the handle and signal the caller the - * end of the listing. - */ - fat_reset_dir(dd); - return 0; + /* The latest call hit the border of the last cluster in + * the chain, but it still returned a directory entry. + * So we now reset the handle and signal the caller the + * end of the listing. + */ + fat_reset_dir(dd); + return 0; } /* reset callback arguments */ @@ -1481,67 +1481,67 @@ uint8_t fat_read_dir(struct fat_dir_struct* dd, struct fat_dir_entry_struct* dir if(cluster_num == 0) { #if FAT_FAT32_SUPPORT - if(fs->partition->type == PARTITION_TYPE_FAT32) - cluster_num = header->root_dir_cluster; - else + if(fs->partition->type == PARTITION_TYPE_FAT32) + cluster_num = header->root_dir_cluster; + else #endif - cluster_size = header->cluster_zero_offset - header->root_dir_offset; + cluster_size = header->cluster_zero_offset - header->root_dir_offset; } /* read entries */ uint8_t buffer[32]; while(!arg.finished) { - /* read directory entries up to the cluster border */ - uint16_t cluster_left = cluster_size - cluster_offset; - offset_t pos = cluster_offset; - if(cluster_num == 0) - pos += header->root_dir_offset; - else - pos += fat_cluster_offset(fs, cluster_num); - - arg.bytes_read = 0; - if(!fs->partition->device_read_interval(pos, - buffer, - sizeof(buffer), - cluster_left, - fat_dir_entry_read_callback, - &arg) - ) - return 0; - - cluster_offset += arg.bytes_read; - - if(cluster_offset >= cluster_size) - { - /* we reached the cluster border and switch to the next cluster */ - - /* get number of next cluster */ - if((cluster_num = fat_get_next_cluster(fs, cluster_num)) != 0) - { - cluster_offset = 0; - continue; - } - - /* we are at the end of the cluster chain */ - if(!arg.finished) - { - /* directory entry not found, reset directory handle */ - fat_reset_dir(dd); - return 0; - } - else - { - /* The current execution of the function has been successful, - * so we can not signal an end of the directory listing to - * the caller, but must wait for the next call. So we keep an - * invalid cluster offset to mark this directory handle's - * traversal as finished. - */ - } - - break; - } + /* read directory entries up to the cluster border */ + uint16_t cluster_left = cluster_size - cluster_offset; + offset_t pos = cluster_offset; + if(cluster_num == 0) + pos += header->root_dir_offset; + else + pos += fat_cluster_offset(fs, cluster_num); + + arg.bytes_read = 0; + if(!fs->partition->device_read_interval(pos, + buffer, + sizeof(buffer), + cluster_left, + fat_dir_entry_read_callback, + &arg) + ) + return 0; + + cluster_offset += arg.bytes_read; + + if(cluster_offset >= cluster_size) + { + /* we reached the cluster border and switch to the next cluster */ + + /* get number of next cluster */ + if((cluster_num = fat_get_next_cluster(fs, cluster_num)) != 0) + { + cluster_offset = 0; + continue; + } + + /* we are at the end of the cluster chain */ + if(!arg.finished) + { + /* directory entry not found, reset directory handle */ + fat_reset_dir(dd); + return 0; + } + else + { + /* The current execution of the function has been successful, + * so we can not signal an end of the directory listing to + * the caller, but must wait for the next call. So we keep an + * invalid cluster offset to mark this directory handle's + * traversal as finished. + */ + } + + break; + } } dd->entry_cluster = cluster_num; @@ -1564,7 +1564,7 @@ uint8_t fat_read_dir(struct fat_dir_struct* dd, struct fat_dir_entry_struct* dir uint8_t fat_reset_dir(struct fat_dir_struct* dd) { if(!dd) - return 0; + return 0; dd->entry_cluster = dd->dir_entry.cluster; dd->entry_offset = 0; @@ -1577,13 +1577,13 @@ uint8_t fat_reset_dir(struct fat_dir_struct* dd) * * Interprets a raw directory entry and puts the contained * information into a fat_dir_entry_struct structure. - * + * * For a single file there may exist multiple directory * entries. All except the last one are lfn entries, which * contain parts of the long filename. The last directory * entry is a traditional 8.3 style one. It contains all * other information like size, cluster, date and time. - * + * * \param[in] buffer A pointer to 32 bytes of raw data. * \param[in] offset The absolute offset of the raw data. * \param[in,out] p An argument structure controlling operation. @@ -1601,111 +1601,111 @@ uint8_t fat_dir_entry_read_callback(uint8_t* buffer, offset_t offset, void* p) if(buffer[0] == FAT_DIRENTRY_DELETED || !buffer[0]) { #if FAT_LFN_SUPPORT - arg->checksum = 0; + arg->checksum = 0; #endif - return 1; + return 1; } #if !FAT_LFN_SUPPORT /* skip lfn entries */ if(buffer[11] == 0x0f) - return 1; + return 1; #endif char* long_name = dir_entry->long_name; #if FAT_LFN_SUPPORT if(buffer[11] == 0x0f) { - /* checksum validation */ - if(arg->checksum == 0 || arg->checksum != buffer[13]) - { - /* reset directory entry */ - memset(dir_entry, 0, sizeof(*dir_entry)); - - arg->checksum = buffer[13]; - dir_entry->entry_offset = offset; - } - - /* lfn supports unicode, but we do not, for now. - * So we assume pure ascii and read only every - * second byte. - */ - uint16_t char_offset = ((buffer[0] & 0x3f) - 1) * 13; - const uint8_t char_mapping[] = { 1, 3, 5, 7, 9, 14, 16, 18, 20, 22, 24, 28, 30 }; - for(uint8_t i = 0; i <= 12 && char_offset + i < sizeof(dir_entry->long_name) - 1; ++i) - long_name[char_offset + i] = buffer[char_mapping[i]]; - - return 1; + /* checksum validation */ + if(arg->checksum == 0 || arg->checksum != buffer[13]) + { + /* reset directory entry */ + memset(dir_entry, 0, sizeof(*dir_entry)); + + arg->checksum = buffer[13]; + dir_entry->entry_offset = offset; + } + + /* lfn supports unicode, but we do not, for now. + * So we assume pure ascii and read only every + * second byte. + */ + uint16_t char_offset = ((buffer[0] & 0x3f) - 1) * 13; + const uint8_t char_mapping[] = { 1, 3, 5, 7, 9, 14, 16, 18, 20, 22, 24, 28, 30 }; + for(uint8_t i = 0; i <= 12 && char_offset + i < sizeof(dir_entry->long_name) - 1; ++i) + long_name[char_offset + i] = buffer[char_mapping[i]]; + + return 1; } else #endif { #if FAT_LFN_SUPPORT - /* if we do not have a long name or the previous lfn does not match, take the 8.3 name */ - if(long_name[0] == '\0' || arg->checksum != fat_calc_83_checksum(buffer)) -#endif - { - /* reset directory entry */ - memset(dir_entry, 0, sizeof(*dir_entry)); - dir_entry->entry_offset = offset; - - uint8_t i; - for(i = 0; i < 8; ++i) - { - if(buffer[i] == ' ') - break; - long_name[i] = buffer[i]; - - /* Windows NT and later versions do not store lfn entries - * for 8.3 names which have a lowercase basename, extension - * or both when everything else is uppercase. They use two - * extra bits to signal a lowercase basename or extension. - */ - if((buffer[12] & 0x08) && buffer[i] >= 'A' && buffer[i] <= 'Z') - long_name[i] += 'a' - 'A'; - } - if(long_name[0] == 0x05) - long_name[0] = (char) FAT_DIRENTRY_DELETED; - - if(buffer[8] != ' ') - { - long_name[i++] = '.'; - - uint8_t j = 8; - for(; j < 11; ++j) - { - if(buffer[j] == ' ') - break; - long_name[i] = buffer[j]; - - /* See above for the lowercase 8.3 name handling of - * Windows NT and later. - */ - if((buffer[12] & 0x10) && buffer[j] >= 'A' && buffer[j] <= 'Z') - long_name[i] += 'a' - 'A'; - - ++i; - } - } - - long_name[i] = '\0'; - } - - /* extract properties of file and store them within the structure */ - dir_entry->attributes = buffer[11]; - dir_entry->cluster = read16(&buffer[26]); + /* if we do not have a long name or the previous lfn does not match, take the 8.3 name */ + if(long_name[0] == '\0' || arg->checksum != fat_calc_83_checksum(buffer)) +#endif + { + /* reset directory entry */ + memset(dir_entry, 0, sizeof(*dir_entry)); + dir_entry->entry_offset = offset; + + uint8_t i; + for(i = 0; i < 8; ++i) + { + if(buffer[i] == ' ') + break; + long_name[i] = buffer[i]; + + /* Windows NT and later versions do not store lfn entries + * for 8.3 names which have a lowercase basename, extension + * or both when everything else is uppercase. They use two + * extra bits to signal a lowercase basename or extension. + */ + if((buffer[12] & 0x08) && buffer[i] >= 'A' && buffer[i] <= 'Z') + long_name[i] += 'a' - 'A'; + } + if(long_name[0] == 0x05) + long_name[0] = (char) FAT_DIRENTRY_DELETED; + + if(buffer[8] != ' ') + { + long_name[i++] = '.'; + + uint8_t j = 8; + for(; j < 11; ++j) + { + if(buffer[j] == ' ') + break; + long_name[i] = buffer[j]; + + /* See above for the lowercase 8.3 name handling of + * Windows NT and later. + */ + if((buffer[12] & 0x10) && buffer[j] >= 'A' && buffer[j] <= 'Z') + long_name[i] += 'a' - 'A'; + + ++i; + } + } + + long_name[i] = '\0'; + } + + /* extract properties of file and store them within the structure */ + dir_entry->attributes = buffer[11]; + dir_entry->cluster = read16(&buffer[26]); #if FAT_FAT32_SUPPORT - dir_entry->cluster |= ((cluster_t) read16(&buffer[20])) << 16; + dir_entry->cluster |= ((cluster_t) read16(&buffer[20])) << 16; #endif - dir_entry->file_size = read32(&buffer[28]); + dir_entry->file_size = read32(&buffer[28]); #if FAT_DATETIME_SUPPORT - dir_entry->modification_time = read16(&buffer[22]); - dir_entry->modification_date = read16(&buffer[24]); + dir_entry->modification_time = read16(&buffer[22]); + dir_entry->modification_date = read16(&buffer[24]); #endif - arg->finished = 1; - return 0; + arg->finished = 1; + return 0; } } @@ -1722,7 +1722,7 @@ uint8_t fat_calc_83_checksum(const uint8_t* file_name_83) { uint8_t checksum = file_name_83[0]; for(uint8_t i = 1; i < 11; ++i) - checksum = ((checksum >> 1) | (checksum << 7)) + file_name_83[i]; + checksum = ((checksum >> 1) | (checksum << 7)) + file_name_83[i]; return checksum; } @@ -1741,7 +1741,7 @@ uint8_t fat_calc_83_checksum(const uint8_t* file_name_83) offset_t fat_find_offset_for_dir_entry(struct fat_fs_struct* fs, const struct fat_dir_struct* parent, const struct fat_dir_entry_struct* dir_entry) { if(!fs || !dir_entry) - return 0; + return 0; /* search for a place where to write the directory entry to disk */ #if FAT_LFN_SUPPORT @@ -1759,88 +1759,88 @@ offset_t fat_find_offset_for_dir_entry(struct fat_fs_struct* fs, const struct fa if(cluster_num == 0) { #if FAT_FAT32_SUPPORT - if(is_fat32) - { - cluster_num = fs->header.root_dir_cluster; - } - else -#endif - { - /* we read/write from the root directory entry */ - offset = fs->header.root_dir_offset; - offset_to = fs->header.cluster_zero_offset; - dir_entry_offset = offset; - } + if(is_fat32) + { + cluster_num = fs->header.root_dir_cluster; + } + else +#endif + { + /* we read/write from the root directory entry */ + offset = fs->header.root_dir_offset; + offset_to = fs->header.cluster_zero_offset; + dir_entry_offset = offset; + } } - + while(1) { - if(offset == offset_to) - { - if(cluster_num == 0) - /* We iterated through the whole root directory and - * could not find enough space for the directory entry. - */ - return 0; - - if(offset) - { - /* We reached a cluster boundary and have to - * switch to the next cluster. - */ - - cluster_t cluster_next = fat_get_next_cluster(fs, cluster_num); - if(!cluster_next) - { - cluster_next = fat_append_clusters(fs, cluster_num, 1); - if(!cluster_next) - return 0; - - /* we appended a new cluster and know it is free */ - dir_entry_offset = fs->header.cluster_zero_offset + - (offset_t) (cluster_next - 2) * fs->header.cluster_size; - - /* clear cluster to avoid garbage directory entries */ - fat_clear_cluster(fs, cluster_next); - - break; - } - cluster_num = cluster_next; - } - - offset = fat_cluster_offset(fs, cluster_num); - offset_to = offset + fs->header.cluster_size; - dir_entry_offset = offset; + if(offset == offset_to) + { + if(cluster_num == 0) + /* We iterated through the whole root directory and + * could not find enough space for the directory entry. + */ + return 0; + + if(offset) + { + /* We reached a cluster boundary and have to + * switch to the next cluster. + */ + + cluster_t cluster_next = fat_get_next_cluster(fs, cluster_num); + if(!cluster_next) + { + cluster_next = fat_append_clusters(fs, cluster_num, 1); + if(!cluster_next) + return 0; + + /* we appended a new cluster and know it is free */ + dir_entry_offset = fs->header.cluster_zero_offset + + (offset_t) (cluster_next - 2) * fs->header.cluster_size; + + /* clear cluster to avoid garbage directory entries */ + fat_clear_cluster(fs, cluster_next); + + break; + } + cluster_num = cluster_next; + } + + offset = fat_cluster_offset(fs, cluster_num); + offset_to = offset + fs->header.cluster_size; + dir_entry_offset = offset; #if FAT_LFN_SUPPORT - free_dir_entries_found = 0; -#endif - } - - /* read next lfn or 8.3 entry */ - uint8_t first_char; - if(!fs->partition->device_read(offset, &first_char, sizeof(first_char))) - return 0; - - /* check if we found a free directory entry */ - if(first_char == FAT_DIRENTRY_DELETED || !first_char) - { - /* check if we have the needed number of available entries */ + free_dir_entries_found = 0; +#endif + } + + /* read next lfn or 8.3 entry */ + uint8_t first_char; + if(!fs->partition->device_read(offset, &first_char, sizeof(first_char))) + return 0; + + /* check if we found a free directory entry */ + if(first_char == FAT_DIRENTRY_DELETED || !first_char) + { + /* check if we have the needed number of available entries */ #if FAT_LFN_SUPPORT - ++free_dir_entries_found; - if(free_dir_entries_found >= free_dir_entries_needed) + ++free_dir_entries_found; + if(free_dir_entries_found >= free_dir_entries_needed) #endif - break; + break; - offset += 32; - } - else - { - offset += 32; - dir_entry_offset = offset; + offset += 32; + } + else + { + offset += 32; + dir_entry_offset = offset; #if FAT_LFN_SUPPORT - free_dir_entries_found = 0; + free_dir_entries_found = 0; #endif - } + } } return dir_entry_offset; @@ -1870,20 +1870,20 @@ offset_t fat_find_offset_for_dir_entry(struct fat_fs_struct* fs, const struct fa uint8_t fat_write_dir_entry(const struct fat_fs_struct* fs, struct fat_dir_entry_struct* dir_entry) { if(!fs || !dir_entry) - return 0; - + return 0; + #if FAT_DATETIME_SUPPORT { - uint16_t year; - uint8_t month; - uint8_t day; - uint8_t hour; - uint8_t min; - uint8_t sec; - - fat_get_datetime(&year, &month, &day, &hour, &min, &sec); - fat_set_file_modification_date(dir_entry, year, month, day); - fat_set_file_modification_time(dir_entry, hour, min, sec); + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t min; + uint8_t sec; + + fat_get_datetime(&year, &month, &day, &hour, &min, &sec); + fat_set_file_modification_date(dir_entry, year, month, day); + fat_set_file_modification_time(dir_entry, hour, min, sec); } #endif @@ -1903,59 +1903,59 @@ uint8_t fat_write_dir_entry(const struct fat_fs_struct* fs, struct fat_dir_entry char* name_ext = strrchr(name, '.'); if(name_ext && *++name_ext) { - uint8_t name_ext_len = strlen(name_ext); - name_len -= name_ext_len + 1; + uint8_t name_ext_len = strlen(name_ext); + name_len -= name_ext_len + 1; - if(name_ext_len > 3) + if(name_ext_len > 3) #if FAT_LFN_SUPPORT - name_ext_len = 3; + name_ext_len = 3; #else - return 0; + return 0; #endif - - memcpy(&buffer[8], name_ext, name_ext_len); + + memcpy(&buffer[8], name_ext, name_ext_len); } - + if(name_len <= 8) { - memcpy(buffer, name, name_len); + memcpy(buffer, name, name_len); #if FAT_LFN_SUPPORT - /* For now, we create lfn entries for all files, - * except the "." and ".." directory references. - * This is to avoid difficulties with capitalization, - * as 8.3 filenames allow uppercase letters only. - * - * Theoretically it would be possible to leave - * the 8.3 entry alone if the basename and the - * extension have no mixed capitalization. - */ - if(name[0] == '.' && - ((name[1] == '.' && name[2] == '\0') || - name[1] == '\0') - ) - lfn_entry_count = 0; + /* For now, we create lfn entries for all files, + * except the "." and ".." directory references. + * This is to avoid difficulties with capitalization, + * as 8.3 filenames allow uppercase letters only. + * + * Theoretically it would be possible to leave + * the 8.3 entry alone if the basename and the + * extension have no mixed capitalization. + */ + if(name[0] == '.' && + ((name[1] == '.' && name[2] == '\0') || + name[1] == '\0') + ) + lfn_entry_count = 0; #endif } else { #if FAT_LFN_SUPPORT - memcpy(buffer, name, 8); + memcpy(buffer, name, 8); - /* Minimize 8.3 name clashes by appending - * the lower byte of the cluster number. - */ - uint8_t num = dir_entry->cluster & 0xff; + /* Minimize 8.3 name clashes by appending + * the lower byte of the cluster number. + */ + uint8_t num = dir_entry->cluster & 0xff; - buffer[6] = (num < 0xa0) ? ('0' + (num >> 4)) : ('a' + (num >> 4)); - num &= 0x0f; - buffer[7] = (num < 0x0a) ? ('0' + num) : ('a' + num); + buffer[6] = (num < 0xa0) ? ('0' + (num >> 4)) : ('a' + (num >> 4)); + num &= 0x0f; + buffer[7] = (num < 0x0a) ? ('0' + num) : ('a' + num); #else - return 0; + return 0; #endif } if(buffer[0] == FAT_DIRENTRY_DELETED) - buffer[0] = 0x05; + buffer[0] = 0x05; /* fill directory entry buffer */ memset(&buffer[11], 0, sizeof(buffer) - 11); @@ -1976,62 +1976,62 @@ uint8_t fat_write_dir_entry(const struct fat_fs_struct* fs, struct fat_dir_entry #else if(!device_write(offset, buffer, sizeof(buffer))) #endif - return 0; - + return 0; + #if FAT_LFN_SUPPORT /* calculate checksum of 8.3 name */ uint8_t checksum = fat_calc_83_checksum(buffer); - + /* write lfn entries */ for(uint8_t lfn_entry = lfn_entry_count; lfn_entry > 0; --lfn_entry) { - memset(buffer, 0xff, sizeof(buffer)); - - /* set file name */ - const char* long_name_curr = name + (lfn_entry - 1) * 13; - uint8_t i = 1; - while(i < 0x1f) - { - buffer[i++] = *long_name_curr; - buffer[i++] = 0; - - switch(i) - { - case 0x0b: - i = 0x0e; - break; - case 0x1a: - i = 0x1c; - break; - } - - if(!*long_name_curr++) - break; - } - - /* set index of lfn entry */ - buffer[0x00] = lfn_entry; - if(lfn_entry == lfn_entry_count) - buffer[0x00] |= FAT_DIRENTRY_LFNLAST; - - /* mark as lfn entry */ - buffer[0x0b] = 0x0f; - - /* set 8.3 checksum */ - buffer[0x0d] = checksum; - - /* clear reserved bytes */ - buffer[0x0c] = 0; - buffer[0x1a] = 0; - buffer[0x1b] = 0; - - /* write entry */ - device_write(offset, buffer, sizeof(buffer)); - - offset += sizeof(buffer); + memset(buffer, 0xff, sizeof(buffer)); + + /* set file name */ + const char* long_name_curr = name + (lfn_entry - 1) * 13; + uint8_t i = 1; + while(i < 0x1f) + { + buffer[i++] = *long_name_curr; + buffer[i++] = 0; + + switch(i) + { + case 0x0b: + i = 0x0e; + break; + case 0x1a: + i = 0x1c; + break; + } + + if(!*long_name_curr++) + break; + } + + /* set index of lfn entry */ + buffer[0x00] = lfn_entry; + if(lfn_entry == lfn_entry_count) + buffer[0x00] |= FAT_DIRENTRY_LFNLAST; + + /* mark as lfn entry */ + buffer[0x0b] = 0x0f; + + /* set 8.3 checksum */ + buffer[0x0d] = checksum; + + /* clear reserved bytes */ + buffer[0x0c] = 0; + buffer[0x1a] = 0; + buffer[0x1b] = 0; + + /* write entry */ + device_write(offset, buffer, sizeof(buffer)); + + offset += sizeof(buffer); } #endif - + return 1; } #endif @@ -2066,19 +2066,19 @@ uint8_t fat_write_dir_entry(const struct fat_fs_struct* fs, struct fat_dir_entry uint8_t fat_create_file(struct fat_dir_struct* parent, const char* file, struct fat_dir_entry_struct* dir_entry) { if(!parent || !file || !file[0] || !dir_entry) - return 0; + return 0; /* check if the file already exists */ while(1) { - if(!fat_read_dir(parent, dir_entry)) - break; - - if(strcmp(file, dir_entry->long_name) == 0) - { - fat_reset_dir(parent); - return 2; - } + if(!fat_read_dir(parent, dir_entry)) + break; + + if(strcmp(file, dir_entry->long_name) == 0) + { + fat_reset_dir(parent); + return 2; + } } struct fat_fs_struct* fs = parent->fs; @@ -2089,12 +2089,12 @@ uint8_t fat_create_file(struct fat_dir_struct* parent, const char* file, struct /* find place where to store directory entry */ if(!(dir_entry->entry_offset = fat_find_offset_for_dir_entry(fs, parent, dir_entry))) - return 0; - + return 0; + /* write directory entry to disk */ if(!fat_write_dir_entry(fs, dir_entry)) - return 0; - + return 0; + return 1; } #endif @@ -2108,7 +2108,7 @@ uint8_t fat_create_file(struct fat_dir_struct* parent, const char* file, struct * subdirectories and files, disk space occupied by these * files will get wasted as there is no chance to release * it and mark it as free. - * + * * \param[in] fs The filesystem on which to operate. * \param[in] dir_entry The directory entry of the file to delete. * \returns 0 on failure, 1 on success. @@ -2117,39 +2117,39 @@ uint8_t fat_create_file(struct fat_dir_struct* parent, const char* file, struct uint8_t fat_delete_file(struct fat_fs_struct* fs, struct fat_dir_entry_struct* dir_entry) { if(!fs || !dir_entry) - return 0; + return 0; /* get offset of the file's directory entry */ offset_t dir_entry_offset = dir_entry->entry_offset; if(!dir_entry_offset) - return 0; + return 0; #if FAT_LFN_SUPPORT uint8_t buffer[12]; while(1) { - /* read directory entry */ - if(!fs->partition->device_read(dir_entry_offset, buffer, sizeof(buffer))) - return 0; - - /* mark the directory entry as deleted */ - buffer[0] = FAT_DIRENTRY_DELETED; - - /* write back entry */ - if(!fs->partition->device_write(dir_entry_offset, buffer, sizeof(buffer))) - return 0; - - /* check if we deleted the whole entry */ - if(buffer[11] != 0x0f) - break; - - dir_entry_offset += 32; + /* read directory entry */ + if(!fs->partition->device_read(dir_entry_offset, buffer, sizeof(buffer))) + return 0; + + /* mark the directory entry as deleted */ + buffer[0] = FAT_DIRENTRY_DELETED; + + /* write back entry */ + if(!fs->partition->device_write(dir_entry_offset, buffer, sizeof(buffer))) + return 0; + + /* check if we deleted the whole entry */ + if(buffer[11] != 0x0f) + break; + + dir_entry_offset += 32; } #else /* mark the directory entry as deleted */ uint8_t first_char = FAT_DIRENTRY_DELETED; if(!fs->partition->device_write(dir_entry_offset, &first_char, 1)) - return 0; + return 0; #endif /* We deleted the directory entry. The next thing to do is @@ -2169,7 +2169,7 @@ uint8_t fat_delete_file(struct fat_fs_struct* fs, struct fat_dir_entry_struct* d * target file name must not exist. Moving a file to a * different filesystem (i.e. \a parent_new doesn't lie on * \a fs) is not supported. - * + * * After successfully renaming (and moving) the file, the * given directory entry is updated such that it points to * the file's new location. @@ -2187,18 +2187,18 @@ uint8_t fat_delete_file(struct fat_fs_struct* fs, struct fat_dir_entry_struct* d uint8_t fat_move_file(struct fat_fs_struct* fs, struct fat_dir_entry_struct* dir_entry, struct fat_dir_struct* parent_new, const char* file_new) { if(!fs || !dir_entry || !parent_new || (file_new && !file_new[0])) - return 0; + return 0; if(fs != parent_new->fs) - return 0; + return 0; /* use existing file name if none has been specified */ if(!file_new) - file_new = dir_entry->long_name; + file_new = dir_entry->long_name; /* create file with new file name */ struct fat_dir_entry_struct dir_entry_new; if(!fat_create_file(parent_new, file_new, &dir_entry_new)) - return 0; + return 0; /* copy members of directory entry which do not change with rename */ dir_entry_new.attributes = dir_entry->attributes; @@ -2212,14 +2212,14 @@ uint8_t fat_move_file(struct fat_fs_struct* fs, struct fat_dir_entry_struct* dir /* make the new file name point to the old file's content */ if(!fat_write_dir_entry(fs, &dir_entry_new)) { - fat_delete_file(fs, &dir_entry_new); - return 0; + fat_delete_file(fs, &dir_entry_new); + return 0; } - + /* delete the old file, but not its clusters, which have already been remapped above */ dir_entry->cluster = 0; if(!fat_delete_file(fs, dir_entry)) - return 0; + return 0; *dir_entry = dir_entry_new; return 1; @@ -2248,16 +2248,16 @@ uint8_t fat_move_file(struct fat_fs_struct* fs, struct fat_dir_entry_struct* dir uint8_t fat_create_dir(struct fat_dir_struct* parent, const char* dir, struct fat_dir_entry_struct* dir_entry) { if(!parent || !dir || !dir[0] || !dir_entry) - return 0; + return 0; /* check if the file or directory already exists */ while(fat_read_dir(parent, dir_entry)) { - if(strcmp(dir, dir_entry->long_name) == 0) - { - fat_reset_dir(parent); - return 0; - } + if(strcmp(dir, dir_entry->long_name) == 0) + { + fat_reset_dir(parent); + return 0; + } } struct fat_fs_struct* fs = parent->fs; @@ -2265,23 +2265,23 @@ uint8_t fat_create_dir(struct fat_dir_struct* parent, const char* dir, struct fa /* allocate cluster which will hold directory entries */ cluster_t dir_cluster = fat_append_clusters(fs, 0, 1); if(!dir_cluster) - return 0; + return 0; /* clear cluster to prevent bogus directory entries */ fat_clear_cluster(fs, dir_cluster); - + memset(dir_entry, 0, sizeof(*dir_entry)); dir_entry->attributes = FAT_ATTRIB_DIR; /* create "." directory self reference */ dir_entry->entry_offset = fs->header.cluster_zero_offset + - (offset_t) (dir_cluster - 2) * fs->header.cluster_size; + (offset_t) (dir_cluster - 2) * fs->header.cluster_size; dir_entry->long_name[0] = '.'; dir_entry->cluster = dir_cluster; if(!fat_write_dir_entry(fs, dir_entry)) { - fat_free_clusters(fs, dir_cluster); - return 0; + fat_free_clusters(fs, dir_cluster); + return 0; } /* create ".." parent directory reference */ @@ -2290,8 +2290,8 @@ uint8_t fat_create_dir(struct fat_dir_struct* parent, const char* dir, struct fa dir_entry->cluster = parent->dir_entry.cluster; if(!fat_write_dir_entry(fs, dir_entry)) { - fat_free_clusters(fs, dir_cluster); - return 0; + fat_free_clusters(fs, dir_cluster); + return 0; } /* fill directory entry */ @@ -2301,15 +2301,15 @@ uint8_t fat_create_dir(struct fat_dir_struct* parent, const char* dir, struct fa /* find place where to store directory entry */ if(!(dir_entry->entry_offset = fat_find_offset_for_dir_entry(fs, parent, dir_entry))) { - fat_free_clusters(fs, dir_cluster); - return 0; + fat_free_clusters(fs, dir_cluster); + return 0; } /* write directory to disk */ if(!fat_write_dir_entry(fs, dir_entry)) { - fat_free_clusters(fs, dir_cluster); - return 0; + fat_free_clusters(fs, dir_cluster); + return 0; } return 1; @@ -2325,7 +2325,7 @@ uint8_t fat_create_dir(struct fat_dir_struct* parent, const char* dir, struct fa * subdirectories and files, disk space occupied by these * files will get wasted as there is no chance to release * it and mark it as free. - * + * * \param[in] fs The filesystem on which to operate. * \param[in] dir_entry The directory entry of the directory to delete. * \returns 0 on failure, 1 on success. @@ -2340,7 +2340,7 @@ uint8_t fat_delete_dir(struct fat_fs_struct* fs, struct fat_dir_entry_struct* di * Moves or renames a directory. * * This is just a synonym for fat_move_file(). - * + * * \param[in] fs The filesystem on which to operate. * \param[in,out] dir_entry The directory entry of the directory to move. * \param[in] parent_new The handle of the new parent directory. @@ -2365,7 +2365,7 @@ uint8_t fat_move_dir(struct fat_fs_struct* fs, struct fat_dir_entry_struct* dir_ void fat_get_file_modification_date(const struct fat_dir_entry_struct* dir_entry, uint16_t* year, uint8_t* month, uint8_t* day) { if(!dir_entry) - return; + return; *year = 1980 + ((dir_entry->modification_date >> 9) & 0x7f); *month = (dir_entry->modification_date >> 5) & 0x0f; @@ -2386,7 +2386,7 @@ void fat_get_file_modification_date(const struct fat_dir_entry_struct* dir_entry void fat_get_file_modification_time(const struct fat_dir_entry_struct* dir_entry, uint8_t* hour, uint8_t* min, uint8_t* sec) { if(!dir_entry) - return; + return; *hour = (dir_entry->modification_time >> 11) & 0x1f; *min = (dir_entry->modification_time >> 5) & 0x3f; @@ -2407,12 +2407,12 @@ void fat_get_file_modification_time(const struct fat_dir_entry_struct* dir_entry void fat_set_file_modification_date(struct fat_dir_entry_struct* dir_entry, uint16_t year, uint8_t month, uint8_t day) { if(!dir_entry) - return; + return; dir_entry->modification_date = - ((year - 1980) << 9) | - ((uint16_t) month << 5) | - ((uint16_t) day << 0); + ((year - 1980) << 9) | + ((uint16_t) month << 5) | + ((uint16_t) day << 0); } #endif @@ -2429,12 +2429,12 @@ void fat_set_file_modification_date(struct fat_dir_entry_struct* dir_entry, uint void fat_set_file_modification_time(struct fat_dir_entry_struct* dir_entry, uint8_t hour, uint8_t min, uint8_t sec) { if(!dir_entry) - return; + return; dir_entry->modification_time = - ((uint16_t) hour << 11) | - ((uint16_t) min << 5) | - ((uint16_t) sec >> 1) ; + ((uint16_t) hour << 11) | + ((uint16_t) min << 5) | + ((uint16_t) sec >> 1) ; } #endif @@ -2448,14 +2448,14 @@ void fat_set_file_modification_time(struct fat_dir_entry_struct* dir_entry, uint offset_t fat_get_fs_size(const struct fat_fs_struct* fs) { if(!fs) - return 0; + return 0; #if FAT_FAT32_SUPPORT if(fs->partition->type == PARTITION_TYPE_FAT32) - return (offset_t) (fs->header.fat_size / 4 - 2) * fs->header.cluster_size; + return (offset_t) (fs->header.fat_size / 4 - 2) * fs->header.cluster_size; else #endif - return (offset_t) (fs->header.fat_size / 2 - 2) * fs->header.cluster_size; + return (offset_t) (fs->header.fat_size / 2 - 2) * fs->header.cluster_size; } /** @@ -2471,7 +2471,7 @@ offset_t fat_get_fs_size(const struct fat_fs_struct* fs) offset_t fat_get_fs_free(const struct fat_fs_struct* fs) { if(!fs) - return 0; + return 0; uint8_t fat[32]; struct fat_usage_count_callback_arg count_arg; @@ -2482,28 +2482,28 @@ offset_t fat_get_fs_free(const struct fat_fs_struct* fs) uint32_t fat_size = fs->header.fat_size; while(fat_size > 0) { - uintptr_t length = UINTPTR_MAX - 1; - if(fat_size < length) - length = fat_size; - - if(!fs->partition->device_read_interval(fat_offset, - fat, - sizeof(fat), - length, + uintptr_t length = UINTPTR_MAX - 1; + if(fat_size < length) + length = fat_size; + + if(!fs->partition->device_read_interval(fat_offset, + fat, + sizeof(fat), + length, #if FAT_FAT32_SUPPORT - (fs->partition->type == PARTITION_TYPE_FAT16) ? - fat_get_fs_free_16_callback : - fat_get_fs_free_32_callback, + (fs->partition->type == PARTITION_TYPE_FAT16) ? + fat_get_fs_free_16_callback : + fat_get_fs_free_32_callback, #else - fat_get_fs_free_16_callback, + fat_get_fs_free_16_callback, #endif - &count_arg - ) - ) - return 0; + &count_arg + ) + ) + return 0; - fat_offset += length; - fat_size -= length; + fat_offset += length; + fat_size -= length; } return (offset_t) count_arg.cluster_count * fs->header.cluster_size; @@ -2520,9 +2520,9 @@ uint8_t fat_get_fs_free_16_callback(uint8_t* buffer, offset_t offset, void* p) for(uintptr_t i = 0; i < buffer_size; i += 2, buffer += 2) { - uint16_t cluster = read16(buffer); - if(cluster == HTOL16(FAT16_CLUSTER_FREE)) - ++(count_arg->cluster_count); + uint16_t cluster = read16(buffer); + if(cluster == HTOL16(FAT16_CLUSTER_FREE)) + ++(count_arg->cluster_count); } return 1; @@ -2540,9 +2540,9 @@ uint8_t fat_get_fs_free_32_callback(uint8_t* buffer, offset_t offset, void* p) for(uintptr_t i = 0; i < buffer_size; i += 4, buffer += 4) { - uint32_t cluster = read32(buffer); - if(cluster == HTOL32(FAT32_CLUSTER_FREE)) - ++(count_arg->cluster_count); + uint32_t cluster = read32(buffer); + if(cluster == HTOL32(FAT32_CLUSTER_FREE)) + ++(count_arg->cluster_count); } return 1;