3 * Copyright (c) 2006-2012 by Roland Riegel <feedback@roland-riegel.de>
5 * This file is free software; you can redistribute it and/or modify
6 * it under the terms of either the GNU General Public License version 2
7 * or the GNU Lesser General Public License version 2.1, both as
8 * published by the Free Software Foundation.
11 #include "byteordering.h"
12 #include "partition.h"
14 #include "fat_config.h"
15 #include "sd-reader_config.h"
19 #if USE_DYNAMIC_MEMORY
24 * \addtogroup fat FAT support
26 * This module implements FAT16/FAT32 read and write access.
28 * The following features are supported:
29 * - File names up to 31 characters long.
30 * - Unlimited depth of subdirectories.
31 * - Short 8.3 and long filenames.
32 * - Creating and deleting files.
33 * - Reading and writing from and to files.
35 * - File sizes of up to 4 gigabytes.
41 * FAT implementation (license: GPLv2 or LGPLv2.1)
43 * \author Roland Riegel
47 * \addtogroup fat_config FAT configuration
48 * Preprocessor defines to configure the FAT implementation.
52 * \addtogroup fat_fs FAT access
53 * Basic functions for handling a FAT filesystem.
57 * \addtogroup fat_file FAT file functions
58 * Functions for managing files.
62 * \addtogroup fat_dir FAT directory functions
63 * Functions for managing directories.
70 #define FAT16_CLUSTER_FREE 0x0000
71 #define FAT16_CLUSTER_RESERVED_MIN 0xfff0
72 #define FAT16_CLUSTER_RESERVED_MAX 0xfff6
73 #define FAT16_CLUSTER_BAD 0xfff7
74 #define FAT16_CLUSTER_LAST_MIN 0xfff8
75 #define FAT16_CLUSTER_LAST_MAX 0xffff
77 #define FAT32_CLUSTER_FREE 0x00000000
78 #define FAT32_CLUSTER_RESERVED_MIN 0x0ffffff0
79 #define FAT32_CLUSTER_RESERVED_MAX 0x0ffffff6
80 #define FAT32_CLUSTER_BAD 0x0ffffff7
81 #define FAT32_CLUSTER_LAST_MIN 0x0ffffff8
82 #define FAT32_CLUSTER_LAST_MAX 0x0fffffff
84 #define FAT_DIRENTRY_DELETED 0xe5
85 #define FAT_DIRENTRY_LFNLAST (1 << 6)
86 #define FAT_DIRENTRY_LFNSEQMASK ((1 << 6) - 1)
88 /* Each entry within the directory table has a size of 32 bytes
89 * and either contains a 8.3 DOS-style file name or a part of a
90 * long file name, which may consist of several directory table
93 * multi-byte integer values are stored little-endian!
95 * 8.3 file name entry:
96 * ====================
97 * offset length description
98 * 0 8 name (space padded)
99 * 8 3 extension (space padded)
100 * 11 1 attributes (FAT_ATTRIB_*)
102 * long file name (lfn) entry ordering for a single file name:
103 * ===========================================================
108 * 8.3 entry (see above)
112 * offset length description
114 * 1 2 unicode character 1
115 * 3 3 unicode character 2
116 * 5 3 unicode character 3
117 * 7 3 unicode character 4
118 * 9 3 unicode character 5
119 * 11 1 attribute (always 0x0f)
120 * 12 1 type (reserved, always 0)
122 * 14 2 unicode character 6
123 * 16 2 unicode character 7
124 * 18 2 unicode character 8
125 * 20 2 unicode character 9
126 * 22 2 unicode character 10
127 * 24 2 unicode character 11
128 * 26 2 cluster (unused, always 0)
129 * 28 2 unicode character 12
130 * 30 2 unicode character 13
132 * The ordinal field contains a descending number, from n to 1.
133 * For the n'th lfn entry the ordinal field is or'ed with 0x40.
134 * For deleted lfn entries, the ordinal field is set to 0xe5.
137 struct fat_header_struct
144 uint16_t sector_size;
145 uint16_t cluster_size;
147 offset_t cluster_zero_offset;
149 offset_t root_dir_offset;
150 #if FAT_FAT32_SUPPORT
151 cluster_t root_dir_cluster;
157 struct partition_struct* partition;
158 struct fat_header_struct header;
159 cluster_t cluster_free;
162 struct fat_file_struct
164 struct fat_fs_struct* fs;
165 struct fat_dir_entry_struct dir_entry;
167 cluster_t pos_cluster;
170 struct fat_dir_struct
172 struct fat_fs_struct* fs;
173 struct fat_dir_entry_struct dir_entry;
174 cluster_t entry_cluster;
175 uint16_t entry_offset;
178 struct fat_read_dir_callback_arg
180 struct fat_dir_entry_struct* dir_entry;
181 uintptr_t bytes_read;
188 struct fat_usage_count_callback_arg
190 cluster_t cluster_count;
191 uintptr_t buffer_size;
194 #if !USE_DYNAMIC_MEMORY
195 static struct fat_fs_struct fat_fs_handles[FAT_FS_COUNT];
196 static struct fat_file_struct fat_file_handles[FAT_FILE_COUNT];
197 static struct fat_dir_struct fat_dir_handles[FAT_DIR_COUNT];
200 static uint8_t fat_read_header(struct fat_fs_struct* fs);
201 static cluster_t fat_get_next_cluster(const struct fat_fs_struct* fs, cluster_t cluster_num);
202 static offset_t fat_cluster_offset(const struct fat_fs_struct* fs, cluster_t cluster_num);
203 static uint8_t fat_dir_entry_read_callback(uint8_t* buffer, offset_t offset, void* p);
205 static uint8_t fat_calc_83_checksum(const uint8_t* file_name_83);
208 static uint8_t fat_get_fs_free_16_callback(uint8_t* buffer, offset_t offset, void* p);
209 #if FAT_FAT32_SUPPORT
210 static uint8_t fat_get_fs_free_32_callback(uint8_t* buffer, offset_t offset, void* p);
213 #if FAT_WRITE_SUPPORT
214 static cluster_t fat_append_clusters(struct fat_fs_struct* fs, cluster_t cluster_num, cluster_t count);
215 static uint8_t fat_free_clusters(struct fat_fs_struct* fs, cluster_t cluster_num);
216 static uint8_t fat_terminate_clusters(struct fat_fs_struct* fs, cluster_t cluster_num);
217 static uint8_t fat_clear_cluster(const struct fat_fs_struct* fs, cluster_t cluster_num);
218 static uintptr_t fat_clear_cluster_callback(uint8_t* buffer, offset_t offset, void* p);
219 static 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);
220 static uint8_t fat_write_dir_entry(const struct fat_fs_struct* fs, struct fat_dir_entry_struct* dir_entry);
221 #if FAT_DATETIME_SUPPORT
222 static void fat_set_file_modification_date(struct fat_dir_entry_struct* dir_entry, uint16_t year, uint8_t month, uint8_t day);
223 static void fat_set_file_modification_time(struct fat_dir_entry_struct* dir_entry, uint8_t hour, uint8_t min, uint8_t sec);
229 * Opens a FAT filesystem.
231 * \param[in] partition Discriptor of partition on which the filesystem resides.
232 * \returns 0 on error, a FAT filesystem descriptor on success.
235 struct fat_fs_struct* fat_open(struct partition_struct* partition)
238 #if FAT_WRITE_SUPPORT
239 !partition->device_write ||
240 !partition->device_write_interval
247 #if USE_DYNAMIC_MEMORY
248 struct fat_fs_struct* fs = malloc(sizeof(*fs));
252 struct fat_fs_struct* fs = fat_fs_handles;
254 for(i = 0; i < FAT_FS_COUNT; ++i)
261 if(i >= FAT_FS_COUNT)
265 memset(fs, 0, sizeof(*fs));
267 fs->partition = partition;
268 if(!fat_read_header(fs))
270 #if USE_DYNAMIC_MEMORY
283 * Closes a FAT filesystem.
285 * When this function returns, the given filesystem descriptor
288 * \param[in] fs The filesystem to close.
291 void fat_close(struct fat_fs_struct* fs)
296 #if USE_DYNAMIC_MEMORY
305 * Reads and parses the header of a FAT filesystem.
307 * \param[in,out] fs The filesystem for which to parse the header.
308 * \returns 0 on failure, 1 on success.
310 uint8_t fat_read_header(struct fat_fs_struct* fs)
315 struct partition_struct* partition = fs->partition;
319 /* read fat parameters */
320 #if FAT_FAT32_SUPPORT
325 offset_t partition_offset = (offset_t) partition->offset * 512;
326 if(!partition->device_read(partition_offset + 0x0b, buffer, sizeof(buffer)))
329 uint16_t bytes_per_sector = read16(&buffer[0x00]);
330 uint16_t reserved_sectors = read16(&buffer[0x03]);
331 uint8_t sectors_per_cluster = buffer[0x02];
332 uint8_t fat_copies = buffer[0x05];
333 uint16_t max_root_entries = read16(&buffer[0x06]);
334 uint16_t sector_count_16 = read16(&buffer[0x08]);
335 uint16_t sectors_per_fat = read16(&buffer[0x0b]);
336 uint32_t sector_count = read32(&buffer[0x15]);
337 #if FAT_FAT32_SUPPORT
338 uint32_t sectors_per_fat32 = read32(&buffer[0x19]);
339 uint32_t cluster_root_dir = read32(&buffer[0x21]);
342 if(sector_count == 0)
344 if(sector_count_16 == 0)
345 /* illegal volume size */
348 sector_count = sector_count_16;
350 #if FAT_FAT32_SUPPORT
351 if(sectors_per_fat != 0)
352 sectors_per_fat32 = sectors_per_fat;
353 else if(sectors_per_fat32 == 0)
354 /* this is neither FAT16 nor FAT32 */
357 if(sectors_per_fat == 0)
358 /* this is not a FAT16 */
362 /* determine the type of FAT we have here */
363 uint32_t data_sector_count = sector_count
365 #if FAT_FAT32_SUPPORT
366 - sectors_per_fat32 * fat_copies
368 - (uint32_t) sectors_per_fat * fat_copies
370 - ((max_root_entries * 32 + bytes_per_sector - 1) / bytes_per_sector);
371 uint32_t data_cluster_count = data_sector_count / sectors_per_cluster;
372 if(data_cluster_count < 4085)
373 /* this is a FAT12, not supported */
375 else if(data_cluster_count < 65525)
376 /* this is a FAT16 */
377 partition->type = PARTITION_TYPE_FAT16;
379 /* this is a FAT32 */
380 partition->type = PARTITION_TYPE_FAT32;
382 /* fill header information */
383 struct fat_header_struct* header = &fs->header;
384 memset(header, 0, sizeof(*header));
386 header->size = (offset_t) sector_count * bytes_per_sector;
388 header->fat_offset = /* jump to partition */
391 (offset_t) reserved_sectors * bytes_per_sector;
392 header->fat_size = (data_cluster_count + 2) * (partition->type == PARTITION_TYPE_FAT16 ? 2 : 4);
394 header->sector_size = bytes_per_sector;
395 header->cluster_size = (uint16_t) bytes_per_sector * sectors_per_cluster;
397 #if FAT_FAT32_SUPPORT
398 if(partition->type == PARTITION_TYPE_FAT16)
401 header->root_dir_offset = /* jump to fats */
403 /* jump to root directory entries */
404 (offset_t) fat_copies * sectors_per_fat * bytes_per_sector;
406 header->cluster_zero_offset = /* jump to root directory entries */
407 header->root_dir_offset +
408 /* skip root directory entries */
409 (offset_t) max_root_entries * 32;
411 #if FAT_FAT32_SUPPORT
414 header->cluster_zero_offset = /* jump to fats */
417 (offset_t) fat_copies * sectors_per_fat32 * bytes_per_sector;
419 header->root_dir_cluster = cluster_root_dir;
428 * Retrieves the next following cluster of a given cluster.
430 * Using the filesystem file allocation table, this function returns
431 * the number of the cluster containing the data directly following
432 * the data within the cluster with the given number.
434 * \param[in] fs The filesystem for which to determine the next cluster.
435 * \param[in] cluster_num The number of the cluster for which to determine its successor.
436 * \returns The wanted cluster number, or 0 on error.
438 cluster_t fat_get_next_cluster(const struct fat_fs_struct* fs, cluster_t cluster_num)
440 if(!fs || cluster_num < 2)
443 #if FAT_FAT32_SUPPORT
444 if(fs->partition->type == PARTITION_TYPE_FAT32)
446 /* read appropriate fat entry */
448 if(!fs->partition->device_read(fs->header.fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
451 /* determine next cluster from fat */
452 cluster_num = ltoh32(fat_entry);
454 if(cluster_num == FAT32_CLUSTER_FREE ||
455 cluster_num == FAT32_CLUSTER_BAD ||
456 (cluster_num >= FAT32_CLUSTER_RESERVED_MIN && cluster_num <= FAT32_CLUSTER_RESERVED_MAX) ||
457 (cluster_num >= FAT32_CLUSTER_LAST_MIN && cluster_num <= FAT32_CLUSTER_LAST_MAX))
463 /* read appropriate fat entry */
465 if(!fs->partition->device_read(fs->header.fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
468 /* determine next cluster from fat */
469 cluster_num = ltoh16(fat_entry);
471 if(cluster_num == FAT16_CLUSTER_FREE ||
472 cluster_num == FAT16_CLUSTER_BAD ||
473 (cluster_num >= FAT16_CLUSTER_RESERVED_MIN && cluster_num <= FAT16_CLUSTER_RESERVED_MAX) ||
474 (cluster_num >= FAT16_CLUSTER_LAST_MIN && cluster_num <= FAT16_CLUSTER_LAST_MAX))
481 #if DOXYGEN || FAT_WRITE_SUPPORT
484 * Appends a new cluster chain to an existing one.
486 * Set cluster_num to zero to create a completely new one.
488 * \param[in] fs The file system on which to operate.
489 * \param[in] cluster_num The cluster to which to append the new chain.
490 * \param[in] count The number of clusters to allocate.
491 * \returns 0 on failure, the number of the first new cluster on success.
493 cluster_t fat_append_clusters(struct fat_fs_struct* fs, cluster_t cluster_num, cluster_t count)
498 device_read_t device_read = fs->partition->device_read;
499 device_write_t device_write = fs->partition->device_write;
500 offset_t fat_offset = fs->header.fat_offset;
501 cluster_t count_left = count;
502 cluster_t cluster_current = fs->cluster_free;
503 cluster_t cluster_next = 0;
504 cluster_t cluster_count;
505 uint16_t fat_entry16;
506 #if FAT_FAT32_SUPPORT
507 uint32_t fat_entry32;
508 uint8_t is_fat32 = (fs->partition->type == PARTITION_TYPE_FAT32);
511 cluster_count = fs->header.fat_size / sizeof(fat_entry32);
514 cluster_count = fs->header.fat_size / sizeof(fat_entry16);
516 fs->cluster_free = 0;
517 for(cluster_t cluster_left = cluster_count; cluster_left > 0; --cluster_left, ++cluster_current)
519 if(cluster_current < 2 || cluster_current >= cluster_count)
522 #if FAT_FAT32_SUPPORT
525 if(!device_read(fat_offset + (offset_t) cluster_current * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32)))
531 if(!device_read(fat_offset + (offset_t) cluster_current * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16)))
535 #if FAT_FAT32_SUPPORT
538 /* check if this is a free cluster */
539 if(fat_entry32 != HTOL32(FAT32_CLUSTER_FREE))
542 /* If we don't need this free cluster for the
543 * current allocation, we keep it in mind for
548 fs->cluster_free = cluster_current;
552 /* allocate cluster */
553 if(cluster_next == 0)
554 fat_entry32 = HTOL32(FAT32_CLUSTER_LAST_MAX);
556 fat_entry32 = htol32(cluster_next);
558 if(!device_write(fat_offset + (offset_t) cluster_current * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32)))
564 /* check if this is a free cluster */
565 if(fat_entry16 != HTOL16(FAT16_CLUSTER_FREE))
568 /* If we don't need this free cluster for the
569 * current allocation, we keep it in mind for
574 fs->cluster_free = cluster_current;
578 /* allocate cluster */
579 if(cluster_next == 0)
580 fat_entry16 = HTOL16(FAT16_CLUSTER_LAST_MAX);
582 fat_entry16 = htol16((uint16_t) cluster_next);
584 if(!device_write(fat_offset + (offset_t) cluster_current * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16)))
588 cluster_next = cluster_current;
597 /* We allocated a new cluster chain. Now join
598 * it with the existing one (if any).
602 #if FAT_FAT32_SUPPORT
605 fat_entry32 = htol32(cluster_next);
607 if(!device_write(fat_offset + (offset_t) cluster_num * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32)))
613 fat_entry16 = htol16((uint16_t) cluster_next);
615 if(!device_write(fat_offset + (offset_t) cluster_num * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16)))
624 /* No space left on device or writing error.
625 * Free up all clusters already allocated.
627 fat_free_clusters(fs, cluster_next);
633 #if DOXYGEN || FAT_WRITE_SUPPORT
636 * Frees a cluster chain, or a part thereof.
638 * Marks the specified cluster and all clusters which are sequentially
639 * referenced by it as free. They may then be used again for future
642 * \note If this function is used for freeing just a part of a cluster
643 * chain, the new end of the chain is not correctly terminated
644 * within the FAT. Use fat_terminate_clusters() instead.
646 * \param[in] fs The filesystem on which to operate.
647 * \param[in] cluster_num The starting cluster of the chain which to free.
648 * \returns 0 on failure, 1 on success.
649 * \see fat_terminate_clusters
651 uint8_t fat_free_clusters(struct fat_fs_struct* fs, cluster_t cluster_num)
653 if(!fs || cluster_num < 2)
656 offset_t fat_offset = fs->header.fat_offset;
657 #if FAT_FAT32_SUPPORT
658 if(fs->partition->type == PARTITION_TYPE_FAT32)
663 if(!fs->partition->device_read(fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
666 /* get next cluster of current cluster before freeing current cluster */
667 uint32_t cluster_num_next = ltoh32(fat_entry);
669 if(cluster_num_next == FAT32_CLUSTER_FREE)
671 if(cluster_num_next == FAT32_CLUSTER_BAD ||
672 (cluster_num_next >= FAT32_CLUSTER_RESERVED_MIN &&
673 cluster_num_next <= FAT32_CLUSTER_RESERVED_MAX
677 if(cluster_num_next >= FAT32_CLUSTER_LAST_MIN && cluster_num_next <= FAT32_CLUSTER_LAST_MAX)
678 cluster_num_next = 0;
680 /* We know we will free the cluster, so remember it as
681 * free for the next allocation.
683 if(!fs->cluster_free)
684 fs->cluster_free = cluster_num;
687 fat_entry = HTOL32(FAT32_CLUSTER_FREE);
688 fs->partition->device_write(fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry));
690 /* We continue in any case here, even if freeing the cluster failed.
691 * The cluster is lost, but maybe we can still free up some later ones.
694 cluster_num = cluster_num_next;
703 if(!fs->partition->device_read(fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
706 /* get next cluster of current cluster before freeing current cluster */
707 uint16_t cluster_num_next = ltoh16(fat_entry);
709 if(cluster_num_next == FAT16_CLUSTER_FREE)
711 if(cluster_num_next == FAT16_CLUSTER_BAD ||
712 (cluster_num_next >= FAT16_CLUSTER_RESERVED_MIN &&
713 cluster_num_next <= FAT16_CLUSTER_RESERVED_MAX
717 if(cluster_num_next >= FAT16_CLUSTER_LAST_MIN && cluster_num_next <= FAT16_CLUSTER_LAST_MAX)
718 cluster_num_next = 0;
721 fat_entry = HTOL16(FAT16_CLUSTER_FREE);
722 fs->partition->device_write(fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry));
724 /* We continue in any case here, even if freeing the cluster failed.
725 * The cluster is lost, but maybe we can still free up some later ones.
728 cluster_num = cluster_num_next;
736 #if DOXYGEN || FAT_WRITE_SUPPORT
739 * Frees a part of a cluster chain and correctly terminates the rest.
741 * Marks the specified cluster as the new end of a cluster chain and
742 * frees all following clusters.
744 * \param[in] fs The filesystem on which to operate.
745 * \param[in] cluster_num The new end of the cluster chain.
746 * \returns 0 on failure, 1 on success.
747 * \see fat_free_clusters
749 uint8_t fat_terminate_clusters(struct fat_fs_struct* fs, cluster_t cluster_num)
751 if(!fs || cluster_num < 2)
754 /* fetch next cluster before overwriting the cluster entry */
755 cluster_t cluster_num_next = fat_get_next_cluster(fs, cluster_num);
757 /* mark cluster as the last one */
758 #if FAT_FAT32_SUPPORT
759 if(fs->partition->type == PARTITION_TYPE_FAT32)
761 uint32_t fat_entry = HTOL32(FAT32_CLUSTER_LAST_MAX);
762 if(!fs->partition->device_write(fs->header.fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
768 uint16_t fat_entry = HTOL16(FAT16_CLUSTER_LAST_MAX);
769 if(!fs->partition->device_write(fs->header.fat_offset + (offset_t) cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
773 /* free remaining clusters */
775 return fat_free_clusters(fs, cluster_num_next);
781 #if DOXYGEN || FAT_WRITE_SUPPORT
784 * Clears a single cluster.
786 * The complete cluster is filled with zeros.
788 * \param[in] fs The filesystem on which to operate.
789 * \param[in] cluster_num The cluster to clear.
790 * \returns 0 on failure, 1 on success.
792 uint8_t fat_clear_cluster(const struct fat_fs_struct* fs, cluster_t cluster_num)
797 offset_t cluster_offset = fat_cluster_offset(fs, cluster_num);
800 memset(zero, 0, sizeof(zero));
801 return fs->partition->device_write_interval(cluster_offset,
803 fs->header.cluster_size,
804 fat_clear_cluster_callback,
810 #if DOXYGEN || FAT_WRITE_SUPPORT
813 * Callback function for clearing a cluster.
815 uintptr_t fat_clear_cluster_callback(uint8_t* buffer, offset_t offset, void* p)
826 * Calculates the offset of the specified cluster.
828 * \param[in] fs The filesystem on which to operate.
829 * \param[in] cluster_num The cluster whose offset to calculate.
830 * \returns The cluster offset.
832 offset_t fat_cluster_offset(const struct fat_fs_struct* fs, cluster_t cluster_num)
834 if(!fs || cluster_num < 2)
837 return fs->header.cluster_zero_offset + (offset_t) (cluster_num - 2) * fs->header.cluster_size;
842 * Retrieves the directory entry of a path.
844 * The given path may both describe a file or a directory.
846 * \param[in] fs The FAT filesystem on which to search.
847 * \param[in] path The path of which to read the directory entry.
848 * \param[out] dir_entry The directory entry to fill.
849 * \returns 0 on failure, 1 on success.
852 uint8_t fat_get_dir_entry_of_path(struct fat_fs_struct* fs, const char* path, struct fat_dir_entry_struct* dir_entry)
854 if(!fs || !path || path[0] == '\0' || !dir_entry)
860 /* begin with the root directory */
861 memset(dir_entry, 0, sizeof(*dir_entry));
862 dir_entry->attributes = FAT_ATTRIB_DIR;
869 struct fat_dir_struct* dd = fat_open_dir(fs, dir_entry);
873 /* extract the next hierarchy we will search for */
874 const char* sub_path = strchr(path, '/');
875 uint8_t length_to_sep;
878 length_to_sep = sub_path - path;
883 length_to_sep = strlen(path);
884 sub_path = path + length_to_sep;
887 /* read directory entries */
888 while(fat_read_dir(dd, dir_entry))
890 /* check if we have found the next hierarchy */
891 if((strlen(dir_entry->long_name) != length_to_sep ||
892 strncmp(path, dir_entry->long_name, length_to_sep) != 0))
898 if(path[length_to_sep] == '\0')
899 /* we iterated through the whole path and have found the file */
902 if(dir_entry->attributes & FAT_ATTRIB_DIR)
904 /* we found a parent directory of the file we are searching for */
909 /* a parent of the file exists, but not the file itself */
921 * Opens a file on a FAT filesystem.
923 * \param[in] fs The filesystem on which the file to open lies.
924 * \param[in] dir_entry The directory entry of the file to open.
925 * \returns The file handle, or 0 on failure.
926 * \see fat_close_file
928 struct fat_file_struct* fat_open_file(struct fat_fs_struct* fs, const struct fat_dir_entry_struct* dir_entry)
930 if(!fs || !dir_entry || (dir_entry->attributes & FAT_ATTRIB_DIR))
933 #if USE_DYNAMIC_MEMORY
934 struct fat_file_struct* fd = malloc(sizeof(*fd));
938 struct fat_file_struct* fd = fat_file_handles;
940 for(i = 0; i < FAT_FILE_COUNT; ++i)
947 if(i >= FAT_FILE_COUNT)
951 memcpy(&fd->dir_entry, dir_entry, sizeof(*dir_entry));
954 fd->pos_cluster = dir_entry->cluster;
963 * \param[in] fd The file handle of the file to close.
966 void fat_close_file(struct fat_file_struct* fd)
970 #if FAT_DELAY_DIRENTRY_UPDATE
971 /* write directory entry */
972 fat_write_dir_entry(fd->fs, &fd->dir_entry);
975 #if USE_DYNAMIC_MEMORY
985 * Reads data from a file.
987 * The data requested is read from the current file location.
989 * \param[in] fd The file handle of the file from which to read.
990 * \param[out] buffer The buffer into which to write.
991 * \param[in] buffer_len The amount of data to read.
992 * \returns The number of bytes read, 0 on end of file, or -1 on failure.
993 * \see fat_write_file
995 intptr_t fat_read_file(struct fat_file_struct* fd, uint8_t* buffer, uintptr_t buffer_len)
997 /* check arguments */
998 if(!fd || !buffer || buffer_len < 1)
1001 /* determine number of bytes to read */
1002 if(fd->pos + buffer_len > fd->dir_entry.file_size)
1003 buffer_len = fd->dir_entry.file_size - fd->pos;
1007 uint16_t cluster_size = fd->fs->header.cluster_size;
1008 cluster_t cluster_num = fd->pos_cluster;
1009 uintptr_t buffer_left = buffer_len;
1010 uint16_t first_cluster_offset = (uint16_t) (fd->pos & (cluster_size - 1));
1012 /* find cluster in which to start reading */
1015 cluster_num = fd->dir_entry.cluster;
1027 uint32_t pos = fd->pos;
1028 while(pos >= cluster_size)
1030 pos -= cluster_size;
1031 cluster_num = fat_get_next_cluster(fd->fs, cluster_num);
1041 /* calculate data size to copy from cluster */
1042 offset_t cluster_offset = fat_cluster_offset(fd->fs, cluster_num) + first_cluster_offset;
1043 uint16_t copy_length = cluster_size - first_cluster_offset;
1044 if(copy_length > buffer_left)
1045 copy_length = buffer_left;
1048 if(!fd->fs->partition->device_read(cluster_offset, buffer, copy_length))
1049 return buffer_len - buffer_left;
1051 /* calculate new file position */
1052 buffer += copy_length;
1053 buffer_left -= copy_length;
1054 fd->pos += copy_length;
1056 if(first_cluster_offset + copy_length >= cluster_size)
1058 /* we are on a cluster boundary, so get the next cluster */
1059 if((cluster_num = fat_get_next_cluster(fd->fs, cluster_num)))
1061 first_cluster_offset = 0;
1065 fd->pos_cluster = 0;
1066 return buffer_len - buffer_left;
1070 fd->pos_cluster = cluster_num;
1072 } while(buffer_left > 0); /* check if we are done */
1077 #if DOXYGEN || FAT_WRITE_SUPPORT
1080 * Writes data to a file.
1082 * The data is written to the current file location.
1084 * \param[in] fd The file handle of the file to which to write.
1085 * \param[in] buffer The buffer from which to read the data to be written.
1086 * \param[in] buffer_len The amount of data to write.
1087 * \returns The number of bytes written (0 or something less than \c buffer_len on disk full) or -1 on failure.
1088 * \see fat_read_file
1090 intptr_t fat_write_file(struct fat_file_struct* fd, const uint8_t* buffer, uintptr_t buffer_len)
1092 /* check arguments */
1093 if(!fd || !buffer || buffer_len < 1)
1095 if(fd->pos > fd->dir_entry.file_size)
1098 uint16_t cluster_size = fd->fs->header.cluster_size;
1099 cluster_t cluster_num = fd->pos_cluster;
1100 uintptr_t buffer_left = buffer_len;
1101 uint16_t first_cluster_offset = (uint16_t) (fd->pos & (cluster_size - 1));
1103 /* find cluster in which to start writing */
1106 cluster_num = fd->dir_entry.cluster;
1113 fd->dir_entry.cluster = cluster_num = fat_append_clusters(fd->fs, 0, 1);
1125 uint32_t pos = fd->pos;
1126 cluster_t cluster_num_next;
1127 while(pos >= cluster_size)
1129 pos -= cluster_size;
1130 cluster_num_next = fat_get_next_cluster(fd->fs, cluster_num);
1131 if(!cluster_num_next)
1134 return -1; /* current file position points beyond end of file */
1136 /* the file exactly ends on a cluster boundary, and we append to it */
1137 cluster_num_next = fat_append_clusters(fd->fs, cluster_num, 1);
1138 if(!cluster_num_next)
1142 cluster_num = cluster_num_next;
1150 /* calculate data size to write to cluster */
1151 offset_t cluster_offset = fat_cluster_offset(fd->fs, cluster_num) + first_cluster_offset;
1152 uint16_t write_length = cluster_size - first_cluster_offset;
1153 if(write_length > buffer_left)
1154 write_length = buffer_left;
1156 /* write data which fits into the current cluster */
1157 if(!fd->fs->partition->device_write(cluster_offset, buffer, write_length))
1160 /* calculate new file position */
1161 buffer += write_length;
1162 buffer_left -= write_length;
1163 fd->pos += write_length;
1165 if(first_cluster_offset + write_length >= cluster_size)
1167 /* we are on a cluster boundary, so get the next cluster */
1168 cluster_t cluster_num_next = fat_get_next_cluster(fd->fs, cluster_num);
1169 if(!cluster_num_next && buffer_left > 0)
1170 /* we reached the last cluster, append a new one */
1171 cluster_num_next = fat_append_clusters(fd->fs, cluster_num, 1);
1172 if(!cluster_num_next)
1174 fd->pos_cluster = 0;
1178 cluster_num = cluster_num_next;
1179 first_cluster_offset = 0;
1182 fd->pos_cluster = cluster_num;
1184 } while(buffer_left > 0); /* check if we are done */
1186 /* update directory entry */
1187 if(fd->pos > fd->dir_entry.file_size)
1189 #if !FAT_DELAY_DIRENTRY_UPDATE
1190 uint32_t size_old = fd->dir_entry.file_size;
1193 /* update file size */
1194 fd->dir_entry.file_size = fd->pos;
1196 #if !FAT_DELAY_DIRENTRY_UPDATE
1197 /* write directory entry */
1198 if(!fat_write_dir_entry(fd->fs, &fd->dir_entry))
1200 /* We do not return an error here since we actually wrote
1201 * some data to disk. So we calculate the amount of data
1202 * we wrote to disk and which lies within the old file size.
1204 buffer_left = fd->pos - size_old;
1210 return buffer_len - buffer_left;
1216 * Repositions the read/write file offset.
1218 * Changes the file offset where the next call to fat_read_file()
1219 * or fat_write_file() starts reading/writing.
1221 * If the new offset is beyond the end of the file, fat_resize_file()
1222 * is implicitly called, i.e. the file is expanded.
1224 * The new offset can be given in different ways determined by
1225 * the \c whence parameter:
1226 * - \b FAT_SEEK_SET: \c *offset is relative to the beginning of the file.
1227 * - \b FAT_SEEK_CUR: \c *offset is relative to the current file position.
1228 * - \b FAT_SEEK_END: \c *offset is relative to the end of the file.
1230 * The resulting absolute offset is written to the location the \c offset
1231 * parameter points to.
1233 * Calling this function can also be used to retrieve the current file position:
1235 int32_t file_pos = 0;
1236 if(!fat_seek_file(fd, &file_pos, FAT_SEEK_CUR))
1240 // file_pos now contains the absolute file position
1243 * \param[in] fd The file decriptor of the file on which to seek.
1244 * \param[in,out] offset A pointer to the new offset, as affected by the \c whence
1245 * parameter. The function writes the new absolute offset
1246 * to this location before it returns.
1247 * \param[in] whence Affects the way \c offset is interpreted, see above.
1248 * \returns 0 on failure, 1 on success.
1250 uint8_t fat_seek_file(struct fat_file_struct* fd, int32_t* offset, uint8_t whence)
1255 uint32_t new_pos = fd->pos;
1265 new_pos = fd->dir_entry.file_size + *offset;
1271 if(new_pos > fd->dir_entry.file_size
1272 #if FAT_WRITE_SUPPORT
1273 && !fat_resize_file(fd, new_pos)
1279 fd->pos_cluster = 0;
1281 *offset = (int32_t) new_pos;
1285 #if DOXYGEN || FAT_WRITE_SUPPORT
1288 * Resizes a file to have a specific size.
1290 * Enlarges or shrinks the file pointed to by the file descriptor to have
1291 * exactly the specified size.
1293 * If the file is truncated, all bytes having an equal or larger offset
1294 * than the given size are lost. If the file is expanded, the additional
1295 * bytes are allocated.
1297 * \note Please be aware that this function just allocates or deallocates disk
1298 * space, it does not explicitely clear it. To avoid data leakage, this
1299 * must be done manually.
1301 * \param[in] fd The file decriptor of the file which to resize.
1302 * \param[in] size The new size of the file.
1303 * \returns 0 on failure, 1 on success.
1305 uint8_t fat_resize_file(struct fat_file_struct* fd, uint32_t size)
1310 cluster_t cluster_num = fd->dir_entry.cluster;
1311 uint16_t cluster_size = fd->fs->header.cluster_size;
1312 uint32_t size_new = size;
1316 if(cluster_num == 0 && size_new == 0)
1317 /* the file stays empty */
1320 /* seek to the next cluster as long as we need the space */
1321 while(size_new > cluster_size)
1323 /* get next cluster of file */
1324 cluster_t cluster_num_next = fat_get_next_cluster(fd->fs, cluster_num);
1325 if(cluster_num_next)
1327 cluster_num = cluster_num_next;
1328 size_new -= cluster_size;
1336 if(size_new > cluster_size || cluster_num == 0)
1338 /* Allocate new cluster chain and append
1339 * it to the existing one, if available.
1341 cluster_t cluster_count = (size_new + cluster_size - 1) / cluster_size;
1342 cluster_t cluster_new_chain = fat_append_clusters(fd->fs, cluster_num, cluster_count);
1343 if(!cluster_new_chain)
1348 cluster_num = cluster_new_chain;
1349 fd->dir_entry.cluster = cluster_num;
1353 /* write new directory entry */
1354 fd->dir_entry.file_size = size;
1356 fd->dir_entry.cluster = 0;
1357 if(!fat_write_dir_entry(fd->fs, &fd->dir_entry))
1362 /* free all clusters of file */
1363 fat_free_clusters(fd->fs, cluster_num);
1365 else if(size_new <= cluster_size)
1367 /* free all clusters no longer needed */
1368 fat_terminate_clusters(fd->fs, cluster_num);
1373 /* correct file position */
1377 fd->pos_cluster = 0;
1386 * Opens a directory.
1388 * \param[in] fs The filesystem on which the directory to open resides.
1389 * \param[in] dir_entry The directory entry which stands for the directory to open.
1390 * \returns An opaque directory descriptor on success, 0 on failure.
1391 * \see fat_close_dir
1393 struct fat_dir_struct* fat_open_dir(struct fat_fs_struct* fs, const struct fat_dir_entry_struct* dir_entry)
1395 if(!fs || !dir_entry || !(dir_entry->attributes & FAT_ATTRIB_DIR))
1398 #if USE_DYNAMIC_MEMORY
1399 struct fat_dir_struct* dd = malloc(sizeof(*dd));
1403 struct fat_dir_struct* dd = fat_dir_handles;
1405 for(i = 0; i < FAT_DIR_COUNT; ++i)
1412 if(i >= FAT_DIR_COUNT)
1416 memcpy(&dd->dir_entry, dir_entry, sizeof(*dir_entry));
1418 dd->entry_cluster = dir_entry->cluster;
1419 dd->entry_offset = 0;
1426 * Closes a directory descriptor.
1428 * This function destroys a directory descriptor which was
1429 * previously obtained by calling fat_open_dir(). When this
1430 * function returns, the given descriptor will be invalid.
1432 * \param[in] dd The directory descriptor to close.
1435 void fat_close_dir(struct fat_dir_struct* dd)
1438 #if USE_DYNAMIC_MEMORY
1447 * Reads the next directory entry contained within a parent directory.
1449 * \param[in] dd The descriptor of the parent directory from which to read the entry.
1450 * \param[out] dir_entry Pointer to a buffer into which to write the directory entry information.
1451 * \returns 0 on failure, 1 on success.
1452 * \see fat_reset_dir
1454 uint8_t fat_read_dir(struct fat_dir_struct* dd, struct fat_dir_entry_struct* dir_entry)
1456 if(!dd || !dir_entry)
1459 /* get current position of directory handle */
1460 struct fat_fs_struct* fs = dd->fs;
1461 const struct fat_header_struct* header = &fs->header;
1462 uint16_t cluster_size = header->cluster_size;
1463 cluster_t cluster_num = dd->entry_cluster;
1464 uint16_t cluster_offset = dd->entry_offset;
1465 struct fat_read_dir_callback_arg arg;
1467 if(cluster_offset >= cluster_size)
1469 /* The latest call hit the border of the last cluster in
1470 * the chain, but it still returned a directory entry.
1471 * So we now reset the handle and signal the caller the
1472 * end of the listing.
1478 /* reset callback arguments */
1479 memset(&arg, 0, sizeof(arg));
1480 memset(dir_entry, 0, sizeof(*dir_entry));
1481 arg.dir_entry = dir_entry;
1483 /* check if we read from the root directory */
1484 if(cluster_num == 0)
1486 #if FAT_FAT32_SUPPORT
1487 if(fs->partition->type == PARTITION_TYPE_FAT32)
1488 cluster_num = header->root_dir_cluster;
1491 cluster_size = header->cluster_zero_offset - header->root_dir_offset;
1496 while(!arg.finished)
1498 /* read directory entries up to the cluster border */
1499 uint16_t cluster_left = cluster_size - cluster_offset;
1500 offset_t pos = cluster_offset;
1501 if(cluster_num == 0)
1502 pos += header->root_dir_offset;
1504 pos += fat_cluster_offset(fs, cluster_num);
1507 if(!fs->partition->device_read_interval(pos,
1511 fat_dir_entry_read_callback,
1516 cluster_offset += arg.bytes_read;
1518 if(cluster_offset >= cluster_size)
1520 /* we reached the cluster border and switch to the next cluster */
1522 /* get number of next cluster */
1523 if((cluster_num = fat_get_next_cluster(fs, cluster_num)) != 0)
1529 /* we are at the end of the cluster chain */
1532 /* directory entry not found, reset directory handle */
1538 /* The current execution of the function has been successful,
1539 * so we can not signal an end of the directory listing to
1540 * the caller, but must wait for the next call. So we keep an
1541 * invalid cluster offset to mark this directory handle's
1542 * traversal as finished.
1550 dd->entry_cluster = cluster_num;
1551 dd->entry_offset = cluster_offset;
1553 return arg.finished;
1558 * Resets a directory handle.
1560 * Resets the directory handle such that reading restarts
1561 * with the first directory entry.
1563 * \param[in] dd The directory handle to reset.
1564 * \returns 0 on failure, 1 on success.
1567 uint8_t fat_reset_dir(struct fat_dir_struct* dd)
1572 dd->entry_cluster = dd->dir_entry.cluster;
1573 dd->entry_offset = 0;
1579 * Callback function for reading a directory entry.
1581 * Interprets a raw directory entry and puts the contained
1582 * information into a fat_dir_entry_struct structure.
1584 * For a single file there may exist multiple directory
1585 * entries. All except the last one are lfn entries, which
1586 * contain parts of the long filename. The last directory
1587 * entry is a traditional 8.3 style one. It contains all
1588 * other information like size, cluster, date and time.
1590 * \param[in] buffer A pointer to 32 bytes of raw data.
1591 * \param[in] offset The absolute offset of the raw data.
1592 * \param[in,out] p An argument structure controlling operation.
1593 * \returns 0 on failure or completion, 1 if reading has
1596 uint8_t fat_dir_entry_read_callback(uint8_t* buffer, offset_t offset, void* p)
1598 struct fat_read_dir_callback_arg* arg = p;
1599 struct fat_dir_entry_struct* dir_entry = arg->dir_entry;
1601 arg->bytes_read += 32;
1603 /* skip deleted or empty entries */
1604 if(buffer[0] == FAT_DIRENTRY_DELETED || !buffer[0])
1612 #if !FAT_LFN_SUPPORT
1613 /* skip lfn entries */
1614 if(buffer[11] == 0x0f)
1618 char* long_name = dir_entry->long_name;
1620 if(buffer[11] == 0x0f)
1622 /* checksum validation */
1623 if(arg->checksum == 0 || arg->checksum != buffer[13])
1625 /* reset directory entry */
1626 memset(dir_entry, 0, sizeof(*dir_entry));
1628 arg->checksum = buffer[13];
1629 dir_entry->entry_offset = offset;
1632 /* lfn supports unicode, but we do not, for now.
1633 * So we assume pure ascii and read only every
1636 uint16_t char_offset = ((buffer[0] & 0x3f) - 1) * 13;
1637 const uint8_t char_mapping[] = { 1, 3, 5, 7, 9, 14, 16, 18, 20, 22, 24, 28, 30 };
1638 for(uint8_t i = 0; i <= 12 && char_offset + i < sizeof(dir_entry->long_name) - 1; ++i)
1639 long_name[char_offset + i] = buffer[char_mapping[i]];
1647 /* if we do not have a long name or the previous lfn does not match, take the 8.3 name */
1648 if(long_name[0] == '\0' || arg->checksum != fat_calc_83_checksum(buffer))
1651 /* reset directory entry */
1652 memset(dir_entry, 0, sizeof(*dir_entry));
1653 dir_entry->entry_offset = offset;
1656 for(i = 0; i < 8; ++i)
1658 if(buffer[i] == ' ')
1660 long_name[i] = buffer[i];
1662 /* Windows NT and later versions do not store lfn entries
1663 * for 8.3 names which have a lowercase basename, extension
1664 * or both when everything else is uppercase. They use two
1665 * extra bits to signal a lowercase basename or extension.
1667 if((buffer[12] & 0x08) && buffer[i] >= 'A' && buffer[i] <= 'Z')
1668 long_name[i] += 'a' - 'A';
1670 if(long_name[0] == 0x05)
1671 long_name[0] = (char) FAT_DIRENTRY_DELETED;
1673 if(buffer[8] != ' ')
1675 long_name[i++] = '.';
1680 if(buffer[j] == ' ')
1682 long_name[i] = buffer[j];
1684 /* See above for the lowercase 8.3 name handling of
1685 * Windows NT and later.
1687 if((buffer[12] & 0x10) && buffer[j] >= 'A' && buffer[j] <= 'Z')
1688 long_name[i] += 'a' - 'A';
1694 long_name[i] = '\0';
1697 /* extract properties of file and store them within the structure */
1698 dir_entry->attributes = buffer[11];
1699 dir_entry->cluster = read16(&buffer[26]);
1700 #if FAT_FAT32_SUPPORT
1701 dir_entry->cluster |= ((cluster_t) read16(&buffer[20])) << 16;
1703 dir_entry->file_size = read32(&buffer[28]);
1705 #if FAT_DATETIME_SUPPORT
1706 dir_entry->modification_time = read16(&buffer[22]);
1707 dir_entry->modification_date = read16(&buffer[24]);
1715 #if DOXYGEN || FAT_LFN_SUPPORT
1718 * Calculates the checksum for 8.3 names used within the
1719 * corresponding lfn directory entries.
1721 * \param[in] file_name_83 The 11-byte file name buffer.
1722 * \returns The checksum of the given file name.
1724 uint8_t fat_calc_83_checksum(const uint8_t* file_name_83)
1726 uint8_t checksum = file_name_83[0];
1727 for(uint8_t i = 1; i < 11; ++i)
1728 checksum = ((checksum >> 1) | (checksum << 7)) + file_name_83[i];
1734 #if DOXYGEN || FAT_WRITE_SUPPORT
1737 * Searches for space where to store a directory entry.
1739 * \param[in] fs The filesystem on which to operate.
1740 * \param[in] parent The directory in which to search.
1741 * \param[in] dir_entry The directory entry for which to search space.
1742 * \returns 0 on failure, a device offset on success.
1744 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)
1746 if(!fs || !dir_entry)
1749 /* search for a place where to write the directory entry to disk */
1751 uint8_t free_dir_entries_needed = (strlen(dir_entry->long_name) + 12) / 13 + 1;
1752 uint8_t free_dir_entries_found = 0;
1754 cluster_t cluster_num = parent->dir_entry.cluster;
1755 offset_t dir_entry_offset = 0;
1756 offset_t offset = 0;
1757 offset_t offset_to = 0;
1758 #if FAT_FAT32_SUPPORT
1759 uint8_t is_fat32 = (fs->partition->type == PARTITION_TYPE_FAT32);
1762 if(cluster_num == 0)
1764 #if FAT_FAT32_SUPPORT
1767 cluster_num = fs->header.root_dir_cluster;
1772 /* we read/write from the root directory entry */
1773 offset = fs->header.root_dir_offset;
1774 offset_to = fs->header.cluster_zero_offset;
1775 dir_entry_offset = offset;
1781 if(offset == offset_to)
1783 if(cluster_num == 0)
1784 /* We iterated through the whole root directory and
1785 * could not find enough space for the directory entry.
1791 /* We reached a cluster boundary and have to
1792 * switch to the next cluster.
1795 cluster_t cluster_next = fat_get_next_cluster(fs, cluster_num);
1798 cluster_next = fat_append_clusters(fs, cluster_num, 1);
1802 /* we appended a new cluster and know it is free */
1803 dir_entry_offset = fs->header.cluster_zero_offset +
1804 (offset_t) (cluster_next - 2) * fs->header.cluster_size;
1806 /* clear cluster to avoid garbage directory entries */
1807 fat_clear_cluster(fs, cluster_next);
1811 cluster_num = cluster_next;
1814 offset = fat_cluster_offset(fs, cluster_num);
1815 offset_to = offset + fs->header.cluster_size;
1816 dir_entry_offset = offset;
1818 free_dir_entries_found = 0;
1822 /* read next lfn or 8.3 entry */
1824 if(!fs->partition->device_read(offset, &first_char, sizeof(first_char)))
1827 /* check if we found a free directory entry */
1828 if(first_char == FAT_DIRENTRY_DELETED || !first_char)
1830 /* check if we have the needed number of available entries */
1832 ++free_dir_entries_found;
1833 if(free_dir_entries_found >= free_dir_entries_needed)
1842 dir_entry_offset = offset;
1844 free_dir_entries_found = 0;
1849 return dir_entry_offset;
1853 #if DOXYGEN || FAT_WRITE_SUPPORT
1856 * Writes a directory entry to disk.
1858 * \note The file name is not checked for invalid characters.
1860 * \note The generation of the short 8.3 file name is quite
1861 * simple. The first eight characters are used for the filename.
1862 * The extension, if any, is made up of the first three characters
1863 * following the last dot within the long filename. If the
1864 * filename (without the extension) is longer than eight characters,
1865 * the lower byte of the cluster number replaces the last two
1866 * characters to avoid name clashes. In any other case, it is your
1867 * responsibility to avoid name clashes.
1869 * \param[in] fs The filesystem on which to operate.
1870 * \param[in] dir_entry The directory entry to write.
1871 * \returns 0 on failure, 1 on success.
1873 uint8_t fat_write_dir_entry(const struct fat_fs_struct* fs, struct fat_dir_entry_struct* dir_entry)
1875 if(!fs || !dir_entry)
1878 #if FAT_DATETIME_SUPPORT
1887 fat_get_datetime(&year, &month, &day, &hour, &min, &sec);
1888 fat_set_file_modification_date(dir_entry, year, month, day);
1889 fat_set_file_modification_time(dir_entry, hour, min, sec);
1893 device_write_t device_write = fs->partition->device_write;
1894 offset_t offset = dir_entry->entry_offset;
1895 const char* name = dir_entry->long_name;
1896 uint8_t name_len = strlen(name);
1898 uint8_t lfn_entry_count = (name_len + 12) / 13;
1902 /* write 8.3 entry */
1904 /* generate 8.3 file name */
1905 memset(&buffer[0], ' ', 11);
1906 char* name_ext = strrchr(name, '.');
1907 if(name_ext && *++name_ext)
1909 uint8_t name_ext_len = strlen(name_ext);
1910 name_len -= name_ext_len + 1;
1912 if(name_ext_len > 3)
1919 memcpy(&buffer[8], name_ext, name_ext_len);
1924 memcpy(buffer, name, name_len);
1927 /* For now, we create lfn entries for all files,
1928 * except the "." and ".." directory references.
1929 * This is to avoid difficulties with capitalization,
1930 * as 8.3 filenames allow uppercase letters only.
1932 * Theoretically it would be possible to leave
1933 * the 8.3 entry alone if the basename and the
1934 * extension have no mixed capitalization.
1936 if(name[0] == '.' &&
1937 ((name[1] == '.' && name[2] == '\0') ||
1940 lfn_entry_count = 0;
1946 memcpy(buffer, name, 8);
1948 /* Minimize 8.3 name clashes by appending
1949 * the lower byte of the cluster number.
1951 uint8_t num = dir_entry->cluster & 0xff;
1953 buffer[6] = (num < 0xa0) ? ('0' + (num >> 4)) : ('a' + (num >> 4));
1955 buffer[7] = (num < 0x0a) ? ('0' + num) : ('a' + num);
1960 if(buffer[0] == FAT_DIRENTRY_DELETED)
1963 /* fill directory entry buffer */
1964 memset(&buffer[11], 0, sizeof(buffer) - 11);
1965 buffer[0x0b] = dir_entry->attributes;
1966 #if FAT_DATETIME_SUPPORT
1967 write16(&buffer[0x16], dir_entry->modification_time);
1968 write16(&buffer[0x18], dir_entry->modification_date);
1970 #if FAT_FAT32_SUPPORT
1971 write16(&buffer[0x14], (uint16_t) (dir_entry->cluster >> 16));
1973 write16(&buffer[0x1a], dir_entry->cluster);
1974 write32(&buffer[0x1c], dir_entry->file_size);
1978 if(!device_write(offset + (uint16_t) lfn_entry_count * 32, buffer, sizeof(buffer)))
1980 if(!device_write(offset, buffer, sizeof(buffer)))
1985 /* calculate checksum of 8.3 name */
1986 uint8_t checksum = fat_calc_83_checksum(buffer);
1988 /* write lfn entries */
1989 for(uint8_t lfn_entry = lfn_entry_count; lfn_entry > 0; --lfn_entry)
1991 memset(buffer, 0xff, sizeof(buffer));
1994 const char* long_name_curr = name + (lfn_entry - 1) * 13;
1998 buffer[i++] = *long_name_curr;
2011 if(!*long_name_curr++)
2015 /* set index of lfn entry */
2016 buffer[0x00] = lfn_entry;
2017 if(lfn_entry == lfn_entry_count)
2018 buffer[0x00] |= FAT_DIRENTRY_LFNLAST;
2020 /* mark as lfn entry */
2021 buffer[0x0b] = 0x0f;
2023 /* set 8.3 checksum */
2024 buffer[0x0d] = checksum;
2026 /* clear reserved bytes */
2032 device_write(offset, buffer, sizeof(buffer));
2034 offset += sizeof(buffer);
2042 #if DOXYGEN || FAT_WRITE_SUPPORT
2047 * Creates a file and obtains the directory entry of the
2048 * new file. If the file to create already exists, the
2049 * directory entry of the existing file will be returned
2050 * within the dir_entry parameter.
2052 * \note The file name is not checked for invalid characters.
2054 * \note The generation of the short 8.3 file name is quite
2055 * simple. The first eight characters are used for the filename.
2056 * The extension, if any, is made up of the first three characters
2057 * following the last dot within the long filename. If the
2058 * filename (without the extension) is longer than eight characters,
2059 * the lower byte of the cluster number replaces the last two
2060 * characters to avoid name clashes. In any other case, it is your
2061 * responsibility to avoid name clashes.
2063 * \param[in] parent The handle of the directory in which to create the file.
2064 * \param[in] file The name of the file to create.
2065 * \param[out] dir_entry The directory entry to fill for the new (or existing) file.
2066 * \returns 0 on failure, 1 on success, 2 if the file already existed.
2067 * \see fat_delete_file
2069 uint8_t fat_create_file(struct fat_dir_struct* parent, const char* file, struct fat_dir_entry_struct* dir_entry)
2071 if(!parent || !file || !file[0] || !dir_entry)
2074 /* check if the file already exists */
2077 if(!fat_read_dir(parent, dir_entry))
2080 if(strcmp(file, dir_entry->long_name) == 0)
2082 fat_reset_dir(parent);
2087 struct fat_fs_struct* fs = parent->fs;
2089 /* prepare directory entry with values already known */
2090 memset(dir_entry, 0, sizeof(*dir_entry));
2091 strncpy(dir_entry->long_name, file, sizeof(dir_entry->long_name) - 1);
2093 /* find place where to store directory entry */
2094 if(!(dir_entry->entry_offset = fat_find_offset_for_dir_entry(fs, parent, dir_entry)))
2097 /* write directory entry to disk */
2098 if(!fat_write_dir_entry(fs, dir_entry))
2105 #if DOXYGEN || FAT_WRITE_SUPPORT
2108 * Deletes a file or directory.
2110 * If a directory is deleted without first deleting its
2111 * subdirectories and files, disk space occupied by these
2112 * files will get wasted as there is no chance to release
2113 * it and mark it as free.
2115 * \param[in] fs The filesystem on which to operate.
2116 * \param[in] dir_entry The directory entry of the file to delete.
2117 * \returns 0 on failure, 1 on success.
2118 * \see fat_create_file
2120 uint8_t fat_delete_file(struct fat_fs_struct* fs, struct fat_dir_entry_struct* dir_entry)
2122 if(!fs || !dir_entry)
2125 /* get offset of the file's directory entry */
2126 offset_t dir_entry_offset = dir_entry->entry_offset;
2127 if(!dir_entry_offset)
2134 /* read directory entry */
2135 if(!fs->partition->device_read(dir_entry_offset, buffer, sizeof(buffer)))
2138 /* mark the directory entry as deleted */
2139 buffer[0] = FAT_DIRENTRY_DELETED;
2141 /* write back entry */
2142 if(!fs->partition->device_write(dir_entry_offset, buffer, sizeof(buffer)))
2145 /* check if we deleted the whole entry */
2146 if(buffer[11] != 0x0f)
2149 dir_entry_offset += 32;
2152 /* mark the directory entry as deleted */
2153 uint8_t first_char = FAT_DIRENTRY_DELETED;
2154 if(!fs->partition->device_write(dir_entry_offset, &first_char, 1))
2158 /* We deleted the directory entry. The next thing to do is
2159 * marking all occupied clusters as free.
2161 return (dir_entry->cluster == 0 || fat_free_clusters(fs, dir_entry->cluster));
2165 #if DOXYGEN || FAT_WRITE_SUPPORT
2168 * Moves or renames a file.
2170 * Changes a file's name, optionally moving it into another
2171 * directory as well. Before calling this function, the
2172 * target file name must not exist. Moving a file to a
2173 * different filesystem (i.e. \a parent_new doesn't lie on
2174 * \a fs) is not supported.
2176 * After successfully renaming (and moving) the file, the
2177 * given directory entry is updated such that it points to
2178 * the file's new location.
2180 * \note The notes which apply to fat_create_file() also
2181 * apply to this function.
2183 * \param[in] fs The filesystem on which to operate.
2184 * \param[in,out] dir_entry The directory entry of the file to move.
2185 * \param[in] parent_new The handle of the new parent directory of the file.
2186 * \param[in] file_new The file's new name.
2187 * \returns 0 on failure, 1 on success.
2188 * \see fat_create_file, fat_delete_file, fat_move_dir
2190 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)
2192 if(!fs || !dir_entry || !parent_new || (file_new && !file_new[0]))
2194 if(fs != parent_new->fs)
2197 /* use existing file name if none has been specified */
2199 file_new = dir_entry->long_name;
2201 /* create file with new file name */
2202 struct fat_dir_entry_struct dir_entry_new;
2203 if(!fat_create_file(parent_new, file_new, &dir_entry_new))
2206 /* copy members of directory entry which do not change with rename */
2207 dir_entry_new.attributes = dir_entry->attributes;
2208 #if FAT_DATETIME_SUPPORT
2209 dir_entry_new.modification_time = dir_entry->modification_time;
2210 dir_entry_new.modification_date = dir_entry->modification_date;
2212 dir_entry_new.cluster = dir_entry->cluster;
2213 dir_entry_new.file_size = dir_entry->file_size;
2215 /* make the new file name point to the old file's content */
2216 if(!fat_write_dir_entry(fs, &dir_entry_new))
2218 fat_delete_file(fs, &dir_entry_new);
2222 /* delete the old file, but not its clusters, which have already been remapped above */
2223 dir_entry->cluster = 0;
2224 if(!fat_delete_file(fs, dir_entry))
2227 *dir_entry = dir_entry_new;
2232 #if DOXYGEN || FAT_WRITE_SUPPORT
2235 * Creates a directory.
2237 * Creates a directory and obtains its directory entry.
2238 * If the directory to create already exists, its
2239 * directory entry will be returned within the dir_entry
2242 * \note The notes which apply to fat_create_file() also
2243 * apply to this function.
2245 * \param[in] parent The handle of the parent directory of the new directory.
2246 * \param[in] dir The name of the directory to create.
2247 * \param[out] dir_entry The directory entry to fill for the new directory.
2248 * \returns 0 on failure, 1 on success.
2249 * \see fat_delete_dir
2251 uint8_t fat_create_dir(struct fat_dir_struct* parent, const char* dir, struct fat_dir_entry_struct* dir_entry)
2253 if(!parent || !dir || !dir[0] || !dir_entry)
2256 /* check if the file or directory already exists */
2257 while(fat_read_dir(parent, dir_entry))
2259 if(strcmp(dir, dir_entry->long_name) == 0)
2261 fat_reset_dir(parent);
2266 struct fat_fs_struct* fs = parent->fs;
2268 /* allocate cluster which will hold directory entries */
2269 cluster_t dir_cluster = fat_append_clusters(fs, 0, 1);
2273 /* clear cluster to prevent bogus directory entries */
2274 fat_clear_cluster(fs, dir_cluster);
2276 memset(dir_entry, 0, sizeof(*dir_entry));
2277 dir_entry->attributes = FAT_ATTRIB_DIR;
2279 /* create "." directory self reference */
2280 dir_entry->entry_offset = fs->header.cluster_zero_offset +
2281 (offset_t) (dir_cluster - 2) * fs->header.cluster_size;
2282 dir_entry->long_name[0] = '.';
2283 dir_entry->cluster = dir_cluster;
2284 if(!fat_write_dir_entry(fs, dir_entry))
2286 fat_free_clusters(fs, dir_cluster);
2290 /* create ".." parent directory reference */
2291 dir_entry->entry_offset += 32;
2292 dir_entry->long_name[1] = '.';
2293 dir_entry->cluster = parent->dir_entry.cluster;
2294 if(!fat_write_dir_entry(fs, dir_entry))
2296 fat_free_clusters(fs, dir_cluster);
2300 /* fill directory entry */
2301 strncpy(dir_entry->long_name, dir, sizeof(dir_entry->long_name) - 1);
2302 dir_entry->cluster = dir_cluster;
2304 /* find place where to store directory entry */
2305 if(!(dir_entry->entry_offset = fat_find_offset_for_dir_entry(fs, parent, dir_entry)))
2307 fat_free_clusters(fs, dir_cluster);
2311 /* write directory to disk */
2312 if(!fat_write_dir_entry(fs, dir_entry))
2314 fat_free_clusters(fs, dir_cluster);
2324 * Deletes a directory.
2326 * This is just a synonym for fat_delete_file().
2327 * If a directory is deleted without first deleting its
2328 * subdirectories and files, disk space occupied by these
2329 * files will get wasted as there is no chance to release
2330 * it and mark it as free.
2332 * \param[in] fs The filesystem on which to operate.
2333 * \param[in] dir_entry The directory entry of the directory to delete.
2334 * \returns 0 on failure, 1 on success.
2335 * \see fat_create_dir
2338 uint8_t fat_delete_dir(struct fat_fs_struct* fs, struct fat_dir_entry_struct* dir_entry);
2343 * Moves or renames a directory.
2345 * This is just a synonym for fat_move_file().
2347 * \param[in] fs The filesystem on which to operate.
2348 * \param[in,out] dir_entry The directory entry of the directory to move.
2349 * \param[in] parent_new The handle of the new parent directory.
2350 * \param[in] dir_new The directory's new name.
2351 * \returns 0 on failure, 1 on success.
2352 * \see fat_create_dir, fat_delete_dir, fat_move_file
2355 uint8_t fat_move_dir(struct fat_fs_struct* fs, struct fat_dir_entry_struct* dir_entry, struct fat_dir_struct* parent_new, const char* dir_new);
2358 #if DOXYGEN || FAT_DATETIME_SUPPORT
2361 * Returns the modification date of a file.
2363 * \param[in] dir_entry The directory entry of which to return the modification date.
2364 * \param[out] year The year the file was last modified.
2365 * \param[out] month The month the file was last modified.
2366 * \param[out] day The day the file was last modified.
2368 void fat_get_file_modification_date(const struct fat_dir_entry_struct* dir_entry, uint16_t* year, uint8_t* month, uint8_t* day)
2373 *year = 1980 + ((dir_entry->modification_date >> 9) & 0x7f);
2374 *month = (dir_entry->modification_date >> 5) & 0x0f;
2375 *day = (dir_entry->modification_date >> 0) & 0x1f;
2379 #if DOXYGEN || FAT_DATETIME_SUPPORT
2382 * Returns the modification time of a file.
2384 * \param[in] dir_entry The directory entry of which to return the modification time.
2385 * \param[out] hour The hour the file was last modified.
2386 * \param[out] min The min the file was last modified.
2387 * \param[out] sec The sec the file was last modified.
2389 void fat_get_file_modification_time(const struct fat_dir_entry_struct* dir_entry, uint8_t* hour, uint8_t* min, uint8_t* sec)
2394 *hour = (dir_entry->modification_time >> 11) & 0x1f;
2395 *min = (dir_entry->modification_time >> 5) & 0x3f;
2396 *sec = ((dir_entry->modification_time >> 0) & 0x1f) * 2;
2400 #if DOXYGEN || (FAT_WRITE_SUPPORT && FAT_DATETIME_SUPPORT)
2403 * Sets the modification time of a date.
2405 * \param[in] dir_entry The directory entry for which to set the modification date.
2406 * \param[in] year The year the file was last modified.
2407 * \param[in] month The month the file was last modified.
2408 * \param[in] day The day the file was last modified.
2410 void fat_set_file_modification_date(struct fat_dir_entry_struct* dir_entry, uint16_t year, uint8_t month, uint8_t day)
2415 dir_entry->modification_date =
2416 ((year - 1980) << 9) |
2417 ((uint16_t) month << 5) |
2418 ((uint16_t) day << 0);
2422 #if DOXYGEN || (FAT_WRITE_SUPPORT && FAT_DATETIME_SUPPORT)
2425 * Sets the modification time of a file.
2427 * \param[in] dir_entry The directory entry for which to set the modification time.
2428 * \param[in] hour The year the file was last modified.
2429 * \param[in] min The month the file was last modified.
2430 * \param[in] sec The day the file was last modified.
2432 void fat_set_file_modification_time(struct fat_dir_entry_struct* dir_entry, uint8_t hour, uint8_t min, uint8_t sec)
2437 dir_entry->modification_time =
2438 ((uint16_t) hour << 11) |
2439 ((uint16_t) min << 5) |
2440 ((uint16_t) sec >> 1) ;
2446 * Returns the amount of total storage capacity of the filesystem in bytes.
2448 * \param[in] fs The filesystem on which to operate.
2449 * \returns 0 on failure, the filesystem size in bytes otherwise.
2451 offset_t fat_get_fs_size(const struct fat_fs_struct* fs)
2456 #if FAT_FAT32_SUPPORT
2457 if(fs->partition->type == PARTITION_TYPE_FAT32)
2458 return (offset_t) (fs->header.fat_size / 4 - 2) * fs->header.cluster_size;
2461 return (offset_t) (fs->header.fat_size / 2 - 2) * fs->header.cluster_size;
2466 * Returns the amount of free storage capacity on the filesystem in bytes.
2468 * \note As the FAT filesystem is cluster based, this function does not
2469 * return continuous values but multiples of the cluster size.
2471 * \param[in] fs The filesystem on which to operate.
2472 * \returns 0 on failure, the free filesystem space in bytes otherwise.
2474 offset_t fat_get_fs_free(const struct fat_fs_struct* fs)
2480 struct fat_usage_count_callback_arg count_arg;
2481 count_arg.cluster_count = 0;
2482 count_arg.buffer_size = sizeof(fat);
2484 offset_t fat_offset = fs->header.fat_offset;
2485 uint32_t fat_size = fs->header.fat_size;
2488 uintptr_t length = UINTPTR_MAX - 1;
2489 if(fat_size < length)
2492 if(!fs->partition->device_read_interval(fat_offset,
2496 #if FAT_FAT32_SUPPORT
2497 (fs->partition->type == PARTITION_TYPE_FAT16) ?
2498 fat_get_fs_free_16_callback :
2499 fat_get_fs_free_32_callback,
2501 fat_get_fs_free_16_callback,
2508 fat_offset += length;
2512 return (offset_t) count_arg.cluster_count * fs->header.cluster_size;
2517 * Callback function used for counting free clusters in a FAT.
2519 uint8_t fat_get_fs_free_16_callback(uint8_t* buffer, offset_t offset, void* p)
2521 struct fat_usage_count_callback_arg* count_arg = (struct fat_usage_count_callback_arg*) p;
2522 uintptr_t buffer_size = count_arg->buffer_size;
2526 for(uintptr_t i = 0; i < buffer_size; i += 2, buffer += 2)
2528 uint16_t cluster = read16(buffer);
2529 if(cluster == HTOL16(FAT16_CLUSTER_FREE))
2530 ++(count_arg->cluster_count);
2536 #if DOXYGEN || FAT_FAT32_SUPPORT
2539 * Callback function used for counting free clusters in a FAT32.
2541 uint8_t fat_get_fs_free_32_callback(uint8_t* buffer, offset_t offset, void* p)
2543 struct fat_usage_count_callback_arg* count_arg = (struct fat_usage_count_callback_arg*) p;
2544 uintptr_t buffer_size = count_arg->buffer_size;
2548 for(uintptr_t i = 0; i < buffer_size; i += 4, buffer += 4)
2550 uint32_t cluster = read32(buffer);
2551 if(cluster == HTOL32(FAT32_CLUSTER_FREE))
2552 ++(count_arg->cluster_count);