3 * Copyright (c) 2006-2009 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"
17 #include <cfg/debug.h>
21 #if USE_DYNAMIC_MEMORY
26 * \addtogroup fat FAT support
28 * This module implements FAT16/FAT32 read and write access.
30 * The following features are supported:
31 * - File names up to 31 characters long.
32 * - Unlimited depth of subdirectories.
33 * - Short 8.3 and long filenames.
34 * - Creating and deleting files.
35 * - Reading and writing from and to files.
37 * - File sizes of up to 4 gigabytes.
43 * FAT implementation (license: GPLv2 or LGPLv2.1)
45 * \author Roland Riegel
49 * \addtogroup fat_config FAT configuration
50 * Preprocessor defines to configure the FAT implementation.
54 * \addtogroup fat_fs FAT access
55 * Basic functions for handling a FAT filesystem.
59 * \addtogroup fat_file FAT file functions
60 * Functions for managing files.
64 * \addtogroup fat_dir FAT directory functions
65 * Functions for managing directories.
72 #define FAT16_CLUSTER_FREE 0x0000
73 #define FAT16_CLUSTER_RESERVED_MIN 0xfff0
74 #define FAT16_CLUSTER_RESERVED_MAX 0xfff6
75 #define FAT16_CLUSTER_BAD 0xfff7
76 #define FAT16_CLUSTER_LAST_MIN 0xfff8
77 #define FAT16_CLUSTER_LAST_MAX 0xffff
79 #define FAT32_CLUSTER_FREE 0x00000000
80 #define FAT32_CLUSTER_RESERVED_MIN 0x0ffffff0
81 #define FAT32_CLUSTER_RESERVED_MAX 0x0ffffff6
82 #define FAT32_CLUSTER_BAD 0x0ffffff7
83 #define FAT32_CLUSTER_LAST_MIN 0x0ffffff8
84 #define FAT32_CLUSTER_LAST_MAX 0x0fffffff
86 #define FAT_DIRENTRY_DELETED 0xe5
87 #define FAT_DIRENTRY_LFNLAST (1 << 6)
88 #define FAT_DIRENTRY_LFNSEQMASK ((1 << 6) - 1)
90 /* Each entry within the directory table has a size of 32 bytes
91 * and either contains a 8.3 DOS-style file name or a part of a
92 * long file name, which may consist of several directory table
95 * multi-byte integer values are stored little-endian!
97 * 8.3 file name entry:
98 * ====================
99 * offset length description
100 * 0 8 name (space padded)
101 * 8 3 extension (space padded)
102 * 11 1 attributes (FAT_ATTRIB_*)
104 * long file name (lfn) entry ordering for a single file name:
105 * ===========================================================
110 * 8.3 entry (see above)
114 * offset length description
116 * 1 2 unicode character 1
117 * 3 3 unicode character 2
118 * 5 3 unicode character 3
119 * 7 3 unicode character 4
120 * 9 3 unicode character 5
121 * 11 1 attribute (always 0x0f)
122 * 12 1 type (reserved, always 0)
124 * 14 2 unicode character 6
125 * 16 2 unicode character 7
126 * 18 2 unicode character 8
127 * 20 2 unicode character 9
128 * 22 2 unicode character 10
129 * 24 2 unicode character 11
130 * 26 2 cluster (unused, always 0)
131 * 28 2 unicode character 12
132 * 30 2 unicode character 13
134 * The ordinal field contains a descending number, from n to 1.
135 * For the n'th lfn entry the ordinal field is or'ed with 0x40.
136 * For deleted lfn entries, the ordinal field is set to 0xe5.
139 struct fat_header_struct
146 uint16_t sector_size;
147 uint16_t cluster_size;
149 offset_t cluster_zero_offset;
151 offset_t root_dir_offset;
152 #if FAT_FAT32_SUPPORT
153 cluster_t root_dir_cluster;
159 struct partition_struct* partition;
160 struct fat_header_struct header;
163 struct fat_file_struct
165 struct fat_fs_struct* fs;
166 struct fat_dir_entry_struct dir_entry;
168 cluster_t pos_cluster;
171 struct fat_dir_struct
173 struct fat_fs_struct* fs;
174 struct fat_dir_entry_struct dir_entry;
175 cluster_t entry_cluster;
176 uint16_t entry_offset;
179 struct fat_read_dir_callback_arg
181 struct fat_dir_entry_struct* dir_entry;
182 uintptr_t bytes_read;
186 struct fat_usage_count_callback_arg
188 cluster_t cluster_count;
189 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);
204 static uint8_t fat_interpret_dir_entry(struct fat_dir_entry_struct* dir_entry, const uint8_t* raw_entry);
206 static uint8_t fat_get_fs_free_16_callback(uint8_t* buffer, offset_t offset, void* p);
207 #if FAT_FAT32_SUPPORT
208 static uint8_t fat_get_fs_free_32_callback(uint8_t* buffer, offset_t offset, void* p);
211 #if FAT_WRITE_SUPPORT
212 static cluster_t fat_append_clusters(const struct fat_fs_struct* fs, cluster_t cluster_num, cluster_t count);
213 static uint8_t fat_free_clusters(const struct fat_fs_struct* fs, cluster_t cluster_num);
214 static uint8_t fat_terminate_clusters(const struct fat_fs_struct* fs, cluster_t cluster_num);
215 static uint8_t fat_clear_cluster(const struct fat_fs_struct* fs, cluster_t cluster_num);
216 static uintptr_t fat_clear_cluster_callback(uint8_t* buffer, offset_t offset, void* p);
217 static offset_t fat_find_offset_for_dir_entry(const struct fat_fs_struct* fs, const struct fat_dir_struct* parent, const struct fat_dir_entry_struct* dir_entry);
218 static uint8_t fat_write_dir_entry(const struct fat_fs_struct* fs, struct fat_dir_entry_struct* dir_entry);
219 #if FAT_DATETIME_SUPPORT
220 static void fat_set_file_modification_date(struct fat_dir_entry_struct* dir_entry, uint16_t year, uint8_t month, uint8_t day);
221 static void fat_set_file_modification_time(struct fat_dir_entry_struct* dir_entry, uint8_t hour, uint8_t min, uint8_t sec);
227 * Opens a FAT filesystem.
229 * \param[in] partition Discriptor of partition on which the filesystem resides.
230 * \returns 0 on error, a FAT filesystem descriptor on success.
233 struct fat_fs_struct* fat_open(struct partition_struct* partition)
236 #if FAT_WRITE_SUPPORT
237 !partition->device_write ||
238 !partition->device_write_interval
245 #if USE_DYNAMIC_MEMORY
246 struct fat_fs_struct* fs = malloc(sizeof(*fs));
250 struct fat_fs_struct* fs = fat_fs_handles;
252 for(i = 0; i < FAT_FS_COUNT; ++i)
259 if(i >= FAT_FS_COUNT)
263 memset(fs, 0, sizeof(*fs));
265 fs->partition = partition;
266 if(!fat_read_header(fs))
268 #if USE_DYNAMIC_MEMORY
281 * Closes a FAT filesystem.
283 * When this function returns, the given filesystem descriptor
286 * \param[in] fs The filesystem to close.
289 void fat_close(struct fat_fs_struct* fs)
294 #if USE_DYNAMIC_MEMORY
303 * Reads and parses the header of a FAT filesystem.
305 * \param[inout] fs The filesystem for which to parse the header.
306 * \returns 0 on failure, 1 on success.
308 uint8_t fat_read_header(struct fat_fs_struct* fs)
313 struct partition_struct* partition = fs->partition;
317 /* read fat parameters */
318 #if FAT_FAT32_SUPPORT
323 offset_t partition_offset = (offset_t) partition->offset * 512;
324 if(!partition->device_read(partition_offset + 0x0b, buffer, sizeof(buffer)))
327 uint16_t bytes_per_sector = ltoh16(*((uint16_t*) &buffer[0x00]));
328 uint16_t reserved_sectors = ltoh16(*((uint16_t*) &buffer[0x03]));
329 uint8_t sectors_per_cluster = buffer[0x02];
330 uint8_t fat_copies = buffer[0x05];
331 uint16_t max_root_entries = ltoh16(*((uint16_t*) &buffer[0x06]));
332 uint16_t sector_count_16 = ltoh16(*((uint16_t*) &buffer[0x08]));
333 uint16_t sectors_per_fat = ltoh16(*((uint16_t*) &buffer[0x0b]));
334 uint32_t sector_count = ltoh32(*((uint32_t*) &buffer[0x15]));
335 #if FAT_FAT32_SUPPORT
336 uint32_t sectors_per_fat32 = ltoh32(*((uint32_t*) &buffer[0x19]));
337 uint32_t cluster_root_dir = ltoh32(*((uint32_t*) &buffer[0x21]));
340 if(sector_count == 0)
342 if(sector_count_16 == 0)
343 /* illegal volume size */
346 sector_count = sector_count_16;
348 #if FAT_FAT32_SUPPORT
349 if(sectors_per_fat != 0)
350 sectors_per_fat32 = sectors_per_fat;
351 else if(sectors_per_fat32 == 0)
352 /* this is neither FAT16 nor FAT32 */
355 if(sectors_per_fat == 0)
356 /* this is not a FAT16 */
360 /* determine the type of FAT we have here */
361 uint32_t data_sector_count = sector_count
363 #if FAT_FAT32_SUPPORT
364 - sectors_per_fat32 * fat_copies
366 - (uint32_t) sectors_per_fat * fat_copies
368 - ((max_root_entries * 32 + bytes_per_sector - 1) / bytes_per_sector);
369 uint32_t data_cluster_count = data_sector_count / sectors_per_cluster;
370 if(data_cluster_count < 4085)
371 /* this is a FAT12, not supported */
373 else if(data_cluster_count < 65525)
374 /* this is a FAT16 */
375 partition->type = PARTITION_TYPE_FAT16;
377 /* this is a FAT32 */
378 partition->type = PARTITION_TYPE_FAT32;
380 /* fill header information */
381 struct fat_header_struct* header = &fs->header;
382 memset(header, 0, sizeof(*header));
384 header->size = (offset_t) sector_count * bytes_per_sector;
386 header->fat_offset = /* jump to partition */
389 (offset_t) reserved_sectors * bytes_per_sector;
390 header->fat_size = (data_cluster_count + 2) * (partition->type == PARTITION_TYPE_FAT16 ? 2 : 4);
392 header->sector_size = bytes_per_sector;
393 header->cluster_size = (uint16_t) bytes_per_sector * sectors_per_cluster;
395 #if FAT_FAT32_SUPPORT
396 if(partition->type == PARTITION_TYPE_FAT16)
399 header->root_dir_offset = /* jump to fats */
401 /* jump to root directory entries */
402 (offset_t) fat_copies * sectors_per_fat * bytes_per_sector;
404 header->cluster_zero_offset = /* jump to root directory entries */
405 header->root_dir_offset +
406 /* skip root directory entries */
407 (offset_t) max_root_entries * 32;
409 #if FAT_FAT32_SUPPORT
412 header->cluster_zero_offset = /* jump to fats */
415 (offset_t) fat_copies * sectors_per_fat32 * bytes_per_sector;
417 header->root_dir_cluster = cluster_root_dir;
426 * Retrieves the next following cluster of a given cluster.
428 * Using the filesystem file allocation table, this function returns
429 * the number of the cluster containing the data directly following
430 * the data within the cluster with the given number.
432 * \param[in] fs The filesystem for which to determine the next cluster.
433 * \param[in] cluster_num The number of the cluster for which to determine its successor.
434 * \returns The wanted cluster number, or 0 on error.
436 cluster_t fat_get_next_cluster(const struct fat_fs_struct* fs, cluster_t cluster_num)
438 if(!fs || cluster_num < 2)
441 #if FAT_FAT32_SUPPORT
442 if(fs->partition->type == PARTITION_TYPE_FAT32)
444 /* read appropriate fat entry */
446 if(!fs->partition->device_read(fs->header.fat_offset + cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
449 /* determine next cluster from fat */
450 cluster_num = ltoh32(fat_entry);
452 if(cluster_num == FAT32_CLUSTER_FREE ||
453 cluster_num == FAT32_CLUSTER_BAD ||
454 (cluster_num >= FAT32_CLUSTER_RESERVED_MIN && cluster_num <= FAT32_CLUSTER_RESERVED_MAX) ||
455 (cluster_num >= FAT32_CLUSTER_LAST_MIN && cluster_num <= FAT32_CLUSTER_LAST_MAX))
461 /* read appropriate fat entry */
463 if(!fs->partition->device_read(fs->header.fat_offset + cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
466 /* determine next cluster from fat */
467 cluster_num = ltoh16(fat_entry);
469 if(cluster_num == FAT16_CLUSTER_FREE ||
470 cluster_num == FAT16_CLUSTER_BAD ||
471 (cluster_num >= FAT16_CLUSTER_RESERVED_MIN && cluster_num <= FAT16_CLUSTER_RESERVED_MAX) ||
472 (cluster_num >= FAT16_CLUSTER_LAST_MIN && cluster_num <= FAT16_CLUSTER_LAST_MAX))
479 #if FAT_WRITE_SUPPORT
482 * Appends a new cluster chain to an existing one.
484 * Set cluster_num to zero to create a completely new one.
486 * \param[in] fs The file system on which to operate.
487 * \param[in] cluster_num The cluster to which to append the new chain.
488 * \param[in] count The number of clusters to allocate.
489 * \returns 0 on failure, the number of the first new cluster on success.
491 cluster_t fat_append_clusters(const struct fat_fs_struct* fs, cluster_t cluster_num, cluster_t count)
496 device_read_t device_read = fs->partition->device_read;
497 device_write_t device_write = fs->partition->device_write;
498 offset_t fat_offset = fs->header.fat_offset;
499 cluster_t count_left = count;
500 cluster_t cluster_next = 0;
501 cluster_t cluster_max;
502 uint16_t fat_entry16;
503 #if FAT_FAT32_SUPPORT
504 uint32_t fat_entry32;
505 uint8_t is_fat32 = (fs->partition->type == PARTITION_TYPE_FAT32);
508 cluster_max = fs->header.fat_size / sizeof(fat_entry32);
511 cluster_max = fs->header.fat_size / sizeof(fat_entry16);
513 cluster_t cluster_new=0;
514 for(cluster_new = 2; cluster_new < cluster_max; ++cluster_new)
516 #if FAT_FAT32_SUPPORT
519 if(!device_read(fat_offset + cluster_new * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32)))
525 if(!device_read(fat_offset + cluster_new * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16)))
529 #if FAT_FAT32_SUPPORT
532 /* check if this is a free cluster */
533 if(fat_entry32 != HTOL32(FAT32_CLUSTER_FREE))
536 /* allocate cluster */
537 if(cluster_next == 0)
538 fat_entry32 = HTOL32(FAT32_CLUSTER_LAST_MAX);
540 fat_entry32 = htol32(cluster_next);
542 if(!device_write(fat_offset + cluster_new * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32)))
548 /* check if this is a free cluster */
549 if(fat_entry16 != HTOL16(FAT16_CLUSTER_FREE))
552 /* allocate cluster */
553 if(cluster_next == 0)
554 fat_entry16 = HTOL16(FAT16_CLUSTER_LAST_MAX);
556 fat_entry16 = htol16((uint16_t) cluster_next);
558 if(!device_write(fat_offset + cluster_new * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16)))
562 cluster_next = cluster_new;
563 if(--count_left == 0)
572 /* We allocated a new cluster chain. Now join
573 * it with the existing one (if any).
577 #if FAT_FAT32_SUPPORT
580 fat_entry32 = htol32(cluster_next);
582 if(!device_write(fat_offset + cluster_num * sizeof(fat_entry32), (uint8_t*) &fat_entry32, sizeof(fat_entry32)))
588 fat_entry16 = htol16((uint16_t) cluster_next);
590 if(!device_write(fat_offset + cluster_num * sizeof(fat_entry16), (uint8_t*) &fat_entry16, sizeof(fat_entry16)))
599 /* No space left on device or writing error.
600 * Free up all clusters already allocated.
602 fat_free_clusters(fs, cluster_next);
608 #if FAT_WRITE_SUPPORT
611 * Frees a cluster chain, or a part thereof.
613 * Marks the specified cluster and all clusters which are sequentially
614 * referenced by it as free. They may then be used again for future
617 * \note If this function is used for freeing just a part of a cluster
618 * chain, the new end of the chain is not correctly terminated
619 * within the FAT. Use fat_terminate_clusters() instead.
621 * \param[in] fs The filesystem on which to operate.
622 * \param[in] cluster_num The starting cluster of the chain which to free.
623 * \returns 0 on failure, 1 on success.
624 * \see fat_terminate_clusters
626 uint8_t fat_free_clusters(const struct fat_fs_struct* fs, cluster_t cluster_num)
628 if(!fs || cluster_num < 2)
631 offset_t fat_offset = fs->header.fat_offset;
632 #if FAT_FAT32_SUPPORT
633 if(fs->partition->type == PARTITION_TYPE_FAT32)
638 if(!fs->partition->device_read(fat_offset + cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
641 /* get next cluster of current cluster before freeing current cluster */
642 uint32_t cluster_num_next = ltoh32(fat_entry);
644 if(cluster_num_next == FAT32_CLUSTER_FREE)
646 if(cluster_num_next == FAT32_CLUSTER_BAD ||
647 (cluster_num_next >= FAT32_CLUSTER_RESERVED_MIN &&
648 cluster_num_next <= FAT32_CLUSTER_RESERVED_MAX
652 if(cluster_num_next >= FAT32_CLUSTER_LAST_MIN && cluster_num_next <= FAT32_CLUSTER_LAST_MAX)
653 cluster_num_next = 0;
656 fat_entry = HTOL32(FAT32_CLUSTER_FREE);
657 fs->partition->device_write(fat_offset + cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry));
659 /* We continue in any case here, even if freeing the cluster failed.
660 * The cluster is lost, but maybe we can still free up some later ones.
663 cluster_num = cluster_num_next;
672 if(!fs->partition->device_read(fat_offset + cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
675 /* get next cluster of current cluster before freeing current cluster */
676 uint16_t cluster_num_next = ltoh16(fat_entry);
678 if(cluster_num_next == FAT16_CLUSTER_FREE)
680 if(cluster_num_next == FAT16_CLUSTER_BAD ||
681 (cluster_num_next >= FAT16_CLUSTER_RESERVED_MIN &&
682 cluster_num_next <= FAT16_CLUSTER_RESERVED_MAX
686 if(cluster_num_next >= FAT16_CLUSTER_LAST_MIN && cluster_num_next <= FAT16_CLUSTER_LAST_MAX)
687 cluster_num_next = 0;
690 fat_entry = HTOL16(FAT16_CLUSTER_FREE);
691 fs->partition->device_write(fat_offset + cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry));
693 /* We continue in any case here, even if freeing the cluster failed.
694 * The cluster is lost, but maybe we can still free up some later ones.
697 cluster_num = cluster_num_next;
705 #if FAT_WRITE_SUPPORT
708 * Frees a part of a cluster chain and correctly terminates the rest.
710 * Marks the specified cluster as the new end of a cluster chain and
711 * frees all following clusters.
713 * \param[in] fs The filesystem on which to operate.
714 * \param[in] cluster_num The new end of the cluster chain.
715 * \returns 0 on failure, 1 on success.
716 * \see fat_free_clusters
718 uint8_t fat_terminate_clusters(const struct fat_fs_struct* fs, cluster_t cluster_num)
720 if(!fs || cluster_num < 2)
723 /* fetch next cluster before overwriting the cluster entry */
724 cluster_t cluster_num_next = fat_get_next_cluster(fs, cluster_num);
726 /* mark cluster as the last one */
727 #if FAT_FAT32_SUPPORT
728 if(fs->partition->type == PARTITION_TYPE_FAT32)
730 uint32_t fat_entry = HTOL32(FAT32_CLUSTER_LAST_MAX);
731 if(!fs->partition->device_write(fs->header.fat_offset + cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
737 uint16_t fat_entry = HTOL16(FAT16_CLUSTER_LAST_MAX);
738 if(!fs->partition->device_write(fs->header.fat_offset + cluster_num * sizeof(fat_entry), (uint8_t*) &fat_entry, sizeof(fat_entry)))
742 /* free remaining clusters */
744 return fat_free_clusters(fs, cluster_num_next);
750 #if FAT_WRITE_SUPPORT
753 * Clears a single cluster.
755 * The complete cluster is filled with zeros.
757 * \param[in] fs The filesystem on which to operate.
758 * \param[in] cluster_num The cluster to clear.
759 * \returns 0 on failure, 1 on success.
761 uint8_t fat_clear_cluster(const struct fat_fs_struct* fs, cluster_t cluster_num)
766 offset_t cluster_offset = fat_cluster_offset(fs, cluster_num);
769 memset(zero, 0, sizeof(zero));
770 return fs->partition->device_write_interval(cluster_offset,
772 fs->header.cluster_size,
773 fat_clear_cluster_callback,
779 #if FAT_WRITE_SUPPORT
782 * Callback function for clearing a cluster.
784 uintptr_t fat_clear_cluster_callback(uint8_t* buffer, offset_t offset, void* p)
792 * Calculates the offset of the specified cluster.
794 * \param[in] fs The filesystem on which to operate.
795 * \param[in] cluster_num The cluster whose offset to calculate.
796 * \returns The cluster offset.
798 offset_t fat_cluster_offset(const struct fat_fs_struct* fs, cluster_t cluster_num)
800 if(!fs || cluster_num < 2)
803 return fs->header.cluster_zero_offset + (offset_t) (cluster_num - 2) * fs->header.cluster_size;
808 * Retrieves the directory entry of a path.
810 * The given path may both describe a file or a directory.
812 * \param[in] fs The FAT filesystem on which to search.
813 * \param[in] path The path of which to read the directory entry.
814 * \param[out] dir_entry The directory entry to fill.
815 * \returns 0 on failure, 1 on success.
818 uint8_t fat_get_dir_entry_of_path(struct fat_fs_struct* fs, const char* path, struct fat_dir_entry_struct* dir_entry)
820 if(!fs || !path || path[0] == '\0' || !dir_entry)
826 /* begin with the root directory */
827 memset(dir_entry, 0, sizeof(*dir_entry));
828 dir_entry->attributes = FAT_ATTRIB_DIR;
835 struct fat_dir_struct* dd = fat_open_dir(fs, dir_entry);
839 /* extract the next hierarchy we will search for */
840 const char* sub_path = strchr(path, '/');
841 uint8_t length_to_sep;
844 length_to_sep = sub_path - path;
849 length_to_sep = strlen(path);
850 sub_path = path + length_to_sep;
853 /* read directory entries */
854 while(fat_read_dir(dd, dir_entry))
856 /* check if we have found the next hierarchy */
857 if((strlen(dir_entry->long_name) != length_to_sep ||
858 strncmp(path, dir_entry->long_name, length_to_sep) != 0))
864 if(path[length_to_sep] == '\0')
865 /* we iterated through the whole path and have found the file */
868 if(dir_entry->attributes & FAT_ATTRIB_DIR)
870 /* we found a parent directory of the file we are searching for */
875 /* a parent of the file exists, but not the file itself */
887 * Opens a file on a FAT filesystem.
889 * \param[in] fs The filesystem on which the file to open lies.
890 * \param[in] dir_entry The directory entry of the file to open.
891 * \returns The file handle, or 0 on failure.
892 * \see fat_close_file
894 struct fat_file_struct* fat_open_file(struct fat_fs_struct* fs, const struct fat_dir_entry_struct* dir_entry)
896 if(!fs || !dir_entry || (dir_entry->attributes & FAT_ATTRIB_DIR))
899 #if USE_DYNAMIC_MEMORY
900 struct fat_file_struct* fd = malloc(sizeof(*fd));
904 struct fat_file_struct* fd = fat_file_handles;
906 for(i = 0; i < FAT_FILE_COUNT; ++i)
913 if(i >= FAT_FILE_COUNT)
917 memcpy(&fd->dir_entry, dir_entry, sizeof(*dir_entry));
920 fd->pos_cluster = dir_entry->cluster;
929 * \param[in] fd The file handle of the file to close.
932 void fat_close_file(struct fat_file_struct* fd)
935 #if USE_DYNAMIC_MEMORY
944 * Reads data from a file.
946 * The data requested is read from the current file location.
948 * \param[in] fd The file handle of the file from which to read.
949 * \param[out] buffer The buffer into which to write.
950 * \param[in] buffer_len The amount of data to read.
951 * \returns The number of bytes read, 0 on end of file, or -1 on failure.
952 * \see fat_write_file
954 intptr_t fat_read_file(struct fat_file_struct* fd, uint8_t* buffer, uintptr_t buffer_len)
956 /* check arguments */
957 if(!fd || !buffer || buffer_len < 1)
960 /* determine number of bytes to read */
961 if(fd->pos + buffer_len > fd->dir_entry.file_size)
962 buffer_len = fd->dir_entry.file_size - fd->pos;
966 uint16_t cluster_size = fd->fs->header.cluster_size;
967 cluster_t cluster_num = fd->pos_cluster;
968 uintptr_t buffer_left = buffer_len;
969 uint16_t first_cluster_offset = (uint16_t) (fd->pos & (cluster_size - 1));
971 /* find cluster in which to start reading */
974 cluster_num = fd->dir_entry.cluster;
986 uint32_t pos = fd->pos;
987 while(pos >= cluster_size)
990 cluster_num = fat_get_next_cluster(fd->fs, cluster_num);
1000 /* calculate data size to copy from cluster */
1001 offset_t cluster_offset = fat_cluster_offset(fd->fs, cluster_num) + first_cluster_offset;
1002 uint16_t copy_length = cluster_size - first_cluster_offset;
1003 if(copy_length > buffer_left)
1004 copy_length = buffer_left;
1007 if(!fd->fs->partition->device_read(cluster_offset, buffer, copy_length))
1008 return buffer_len - buffer_left;
1010 /* calculate new file position */
1011 buffer += copy_length;
1012 buffer_left -= copy_length;
1013 fd->pos += copy_length;
1015 if(first_cluster_offset + copy_length >= cluster_size)
1017 /* we are on a cluster boundary, so get the next cluster */
1018 if((cluster_num = fat_get_next_cluster(fd->fs, cluster_num)))
1020 first_cluster_offset = 0;
1024 fd->pos_cluster = 0;
1025 return buffer_len - buffer_left;
1029 fd->pos_cluster = cluster_num;
1031 } while(buffer_left > 0); /* check if we are done */
1038 * Writes data to a file.
1040 * The data is written to the current file location.
1042 * \param[in] fd The file handle of the file to which to write.
1043 * \param[in] buffer The buffer from which to read the data to be written.
1044 * \param[in] buffer_len The amount of data to write.
1045 * \returns The number of bytes written, 0 on disk full, or -1 on failure.
1046 * \see fat_read_file
1048 intptr_t fat_write_file(struct fat_file_struct* fd, const uint8_t* buffer, uintptr_t buffer_len)
1050 /* check arguments */
1051 if(!fd || !buffer || buffer_len < 1)
1053 if(fd->pos > fd->dir_entry.file_size)
1056 uint16_t cluster_size = fd->fs->header.cluster_size;
1057 cluster_t cluster_num = fd->pos_cluster;
1058 uintptr_t buffer_left = buffer_len;
1059 uint16_t first_cluster_offset = (uint16_t) (fd->pos & (cluster_size - 1));
1061 /* find cluster in which to start writing */
1064 cluster_num = fd->dir_entry.cluster;
1071 fd->dir_entry.cluster = cluster_num = fat_append_clusters(fd->fs, 0, 1);
1083 uint32_t pos = fd->pos;
1084 cluster_t cluster_num_next;
1085 while(pos >= cluster_size)
1087 pos -= cluster_size;
1088 cluster_num_next = fat_get_next_cluster(fd->fs, cluster_num);
1089 if(!cluster_num_next && pos == 0)
1090 /* the file exactly ends on a cluster boundary, and we append to it */
1091 cluster_num_next = fat_append_clusters(fd->fs, cluster_num, 1);
1092 if(!cluster_num_next)
1095 cluster_num = cluster_num_next;
1103 /* calculate data size to write to cluster */
1104 offset_t cluster_offset = fat_cluster_offset(fd->fs, cluster_num) + first_cluster_offset;
1105 uint16_t write_length = cluster_size - first_cluster_offset;
1106 if(write_length > buffer_left)
1107 write_length = buffer_left;
1109 /* write data which fits into the current cluster */
1110 if(!fd->fs->partition->device_write(cluster_offset, buffer, write_length))
1113 /* calculate new file position */
1114 buffer += write_length;
1115 buffer_left -= write_length;
1116 fd->pos += write_length;
1118 if(first_cluster_offset + write_length >= cluster_size)
1120 /* we are on a cluster boundary, so get the next cluster */
1121 cluster_t cluster_num_next = fat_get_next_cluster(fd->fs, cluster_num);
1122 if(!cluster_num_next && buffer_left > 0)
1123 /* we reached the last cluster, append a new one */
1124 cluster_num_next = fat_append_clusters(fd->fs, cluster_num, 1);
1125 if(!cluster_num_next)
1127 fd->pos_cluster = 0;
1131 cluster_num = cluster_num_next;
1132 first_cluster_offset = 0;
1135 fd->pos_cluster = cluster_num;
1137 } while(buffer_left > 0); /* check if we are done */
1139 /* update directory entry */
1140 if(fd->pos > fd->dir_entry.file_size)
1142 uint32_t size_old = fd->dir_entry.file_size;
1144 /* update file size */
1145 fd->dir_entry.file_size = fd->pos;
1146 /* write directory entry */
1147 if(!fat_write_dir_entry(fd->fs, &fd->dir_entry))
1149 /* We do not return an error here since we actually wrote
1150 * some data to disk. So we calculate the amount of data
1151 * we wrote to disk and which lies within the old file size.
1153 buffer_left = fd->pos - size_old;
1158 return buffer_len - buffer_left;
1163 * Repositions the read/write file offset.
1165 * Changes the file offset where the next call to fat_read_file()
1166 * or fat_write_file() starts reading/writing.
1168 * If the new offset is beyond the end of the file, fat_resize_file()
1169 * is implicitly called, i.e. the file is expanded.
1171 * The new offset can be given in different ways determined by
1172 * the \c whence parameter:
1173 * - \b FAT_SEEK_SET: \c *offset is relative to the beginning of the file.
1174 * - \b FAT_SEEK_CUR: \c *offset is relative to the current file position.
1175 * - \b FAT_SEEK_END: \c *offset is relative to the end of the file.
1177 * The resulting absolute offset is written to the location the \c offset
1178 * parameter points to.
1180 * \param[in] fd The file decriptor of the file on which to seek.
1181 * \param[in,out] offset A pointer to the new offset, as affected by the \c whence
1182 * parameter. The function writes the new absolute offset
1183 * to this location before it returns.
1184 * \param[in] whence Affects the way \c offset is interpreted, see above.
1185 * \returns 0 on failure, 1 on success.
1187 uint8_t fat_seek_file(struct fat_file_struct* fd, int32_t* offset, uint8_t whence)
1192 uint32_t new_pos = fd->pos;
1202 new_pos = fd->dir_entry.file_size + *offset;
1208 if(new_pos > fd->dir_entry.file_size
1209 #if FAT_WRITE_SUPPORT
1210 && !fat_resize_file(fd, new_pos)
1216 fd->pos_cluster = 0;
1218 *offset = (int32_t) new_pos;
1222 #if FAT_WRITE_SUPPORT
1225 * Resizes a file to have a specific size.
1227 * Enlarges or shrinks the file pointed to by the file descriptor to have
1228 * exactly the specified size.
1230 * If the file is truncated, all bytes having an equal or larger offset
1231 * than the given size are lost. If the file is expanded, the additional
1232 * bytes are allocated.
1234 * \note Please be aware that this function just allocates or deallocates disk
1235 * space, it does not explicitely clear it. To avoid data leakage, this
1236 * must be done manually.
1238 * \param[in] fd The file decriptor of the file which to resize.
1239 * \param[in] size The new size of the file.
1240 * \returns 0 on failure, 1 on success.
1242 uint8_t fat_resize_file(struct fat_file_struct* fd, uint32_t size)
1247 cluster_t cluster_num = fd->dir_entry.cluster;
1248 uint16_t cluster_size = fd->fs->header.cluster_size;
1249 uint32_t size_new = size;
1253 if(cluster_num == 0 && size_new == 0)
1254 /* the file stays empty */
1257 /* seek to the next cluster as long as we need the space */
1258 while(size_new > cluster_size)
1260 /* get next cluster of file */
1261 cluster_t cluster_num_next = fat_get_next_cluster(fd->fs, cluster_num);
1262 if(cluster_num_next)
1264 cluster_num = cluster_num_next;
1265 size_new -= cluster_size;
1273 if(size_new > cluster_size || cluster_num == 0)
1275 /* Allocate new cluster chain and append
1276 * it to the existing one, if available.
1278 cluster_t cluster_count = (size_new + cluster_size - 1) / cluster_size;
1279 cluster_t cluster_new_chain = fat_append_clusters(fd->fs, cluster_num, cluster_count);
1280 if(!cluster_new_chain)
1285 cluster_num = cluster_new_chain;
1286 fd->dir_entry.cluster = cluster_num;
1290 /* write new directory entry */
1291 fd->dir_entry.file_size = size;
1293 fd->dir_entry.cluster = 0;
1294 if(!fat_write_dir_entry(fd->fs, &fd->dir_entry))
1299 /* free all clusters of file */
1300 fat_free_clusters(fd->fs, cluster_num);
1302 else if(size_new <= cluster_size)
1304 /* free all clusters no longer needed */
1305 fat_terminate_clusters(fd->fs, cluster_num);
1310 /* correct file position */
1314 fd->pos_cluster = 0;
1323 * Opens a directory.
1325 * \param[in] fs The filesystem on which the directory to open resides.
1326 * \param[in] dir_entry The directory entry which stands for the directory to open.
1327 * \returns An opaque directory descriptor on success, 0 on failure.
1328 * \see fat_close_dir
1330 struct fat_dir_struct* fat_open_dir(struct fat_fs_struct* fs, const struct fat_dir_entry_struct* dir_entry)
1332 if(!fs || !dir_entry || !(dir_entry->attributes & FAT_ATTRIB_DIR))
1335 #if USE_DYNAMIC_MEMORY
1336 struct fat_dir_struct* dd = malloc(sizeof(*dd));
1340 struct fat_dir_struct* dd = fat_dir_handles;
1342 for(i = 0; i < FAT_DIR_COUNT; ++i)
1349 if(i >= FAT_DIR_COUNT)
1353 memcpy(&dd->dir_entry, dir_entry, sizeof(*dir_entry));
1355 dd->entry_cluster = dir_entry->cluster;
1356 dd->entry_offset = 0;
1363 * Closes a directory descriptor.
1365 * This function destroys a directory descriptor which was
1366 * previously obtained by calling fat_open_dir(). When this
1367 * function returns, the given descriptor will be invalid.
1369 * \param[in] dd The directory descriptor to close.
1372 void fat_close_dir(struct fat_dir_struct* dd)
1375 #if USE_DYNAMIC_MEMORY
1384 * Reads the next directory entry contained within a parent directory.
1386 * \param[in] dd The descriptor of the parent directory from which to read the entry.
1387 * \param[out] dir_entry Pointer to a buffer into which to write the directory entry information.
1388 * \returns 0 on failure, 1 on success.
1389 * \see fat_reset_dir
1391 uint8_t fat_read_dir(struct fat_dir_struct* dd, struct fat_dir_entry_struct* dir_entry)
1393 if(!dd || !dir_entry)
1396 /* get current position of directory handle */
1397 struct fat_fs_struct* fs = dd->fs;
1398 const struct fat_header_struct* header = &fs->header;
1399 uint16_t cluster_size = header->cluster_size;
1400 cluster_t cluster_num = dd->entry_cluster;
1401 uint16_t cluster_offset = dd->entry_offset;
1402 struct fat_read_dir_callback_arg arg;
1404 /* reset directory entry */
1405 memset(dir_entry, 0, sizeof(*dir_entry));
1407 /* reset callback arguments */
1408 memset(&arg, 0, sizeof(arg));
1409 arg.dir_entry = dir_entry;
1411 /* check if we read from the root directory */
1412 if(cluster_num == 0)
1414 #if FAT_FAT32_SUPPORT
1415 if(fs->partition->type == PARTITION_TYPE_FAT32)
1416 cluster_num = header->root_dir_cluster;
1419 cluster_size = header->cluster_zero_offset - header->root_dir_offset;
1424 while(!arg.finished)
1426 /* read directory entries up to the cluster border */
1427 uint16_t cluster_left = cluster_size - cluster_offset;
1428 uint32_t pos = cluster_offset;
1429 if(cluster_num == 0)
1430 pos += header->root_dir_offset;
1432 pos += fat_cluster_offset(fs, cluster_num);
1435 if(!fs->partition->device_read_interval(pos,
1439 fat_dir_entry_read_callback,
1444 cluster_offset += arg.bytes_read;
1446 if(cluster_offset >= cluster_size)
1448 /* we reached the cluster border and switch to the next cluster */
1451 /* get number of next cluster */
1452 if(!(cluster_num = fat_get_next_cluster(fs, cluster_num)))
1454 /* directory entry not found, reset directory handle */
1455 cluster_num = dd->dir_entry.cluster;
1461 dd->entry_cluster = cluster_num;
1462 dd->entry_offset = cluster_offset;
1464 return dir_entry->long_name[0] != '\0' ? 1 : 0;
1469 * Resets a directory handle.
1471 * Resets the directory handle such that reading restarts
1472 * with the first directory entry.
1474 * \param[in] dd The directory handle to reset.
1475 * \returns 0 on failure, 1 on success.
1478 uint8_t fat_reset_dir(struct fat_dir_struct* dd)
1483 dd->entry_cluster = dd->dir_entry.cluster;
1484 dd->entry_offset = 0;
1490 * Callback function for reading a directory entry.
1492 uint8_t fat_dir_entry_read_callback(uint8_t* buffer, offset_t offset, void* p)
1494 struct fat_read_dir_callback_arg* arg = p;
1495 struct fat_dir_entry_struct* dir_entry = arg->dir_entry;
1497 arg->bytes_read += 32;
1499 /* skip deleted or empty entries */
1500 if(buffer[0] == FAT_DIRENTRY_DELETED || !buffer[0])
1503 if(!dir_entry->entry_offset)
1504 dir_entry->entry_offset = offset;
1506 switch(fat_interpret_dir_entry(dir_entry, buffer))
1508 case 0: /* failure */
1512 case 1: /* buffer successfully parsed, continue */
1516 case 2: /* directory entry complete, finish */
1528 * Interprets a raw directory entry and puts the contained
1529 * information into the directory entry.
1531 * For a single file there may exist multiple directory
1532 * entries. All except the last one are lfn entries, which
1533 * contain parts of the long filename. The last directory
1534 * entry is a traditional 8.3 style one. It contains all
1535 * other information like size, cluster, date and time.
1537 * \param[in,out] dir_entry The directory entry to fill.
1538 * \param[in] raw_entry A pointer to 32 bytes of raw data.
1539 * \returns 0 on failure, 1 on success and 2 if the
1540 * directory entry is complete.
1542 uint8_t fat_interpret_dir_entry(struct fat_dir_entry_struct* dir_entry, const uint8_t* raw_entry)
1544 if(!dir_entry || !raw_entry || !raw_entry[0])
1547 char* long_name = dir_entry->long_name;
1548 if(raw_entry[11] == 0x0f)
1550 /* Lfn supports unicode, but we do not, for now.
1551 * So we assume pure ascii and read only every
1554 uint16_t char_offset = ((raw_entry[0] & 0x3f) - 1) * 13;
1555 const uint8_t char_mapping[] = { 1, 3, 5, 7, 9, 14, 16, 18, 20, 22, 24, 28, 30 };
1556 for(i = 0; i <= 12 && char_offset + i < sizeof(dir_entry->long_name) - 1; ++i)
1557 long_name[char_offset + i] = raw_entry[char_mapping[i]];
1563 /* if we do not have a long name, take the short one */
1564 if(long_name[0] == '\0')
1567 for(i = 0; i < 8; ++i)
1569 if(raw_entry[i] == ' ')
1571 long_name[i] = raw_entry[i];
1573 /* Windows NT and later versions do not store LFN entries
1574 * for 8.3 names which have a lowercase basename, extension
1575 * or both when everything else is uppercase. They use two
1576 * extra bits to signal a lowercase basename or extension.
1578 if((raw_entry[12] & 0x08) && raw_entry[i] >= 'A' && raw_entry[i] <= 'Z')
1579 long_name[i] += 'a' - 'A';
1581 if(long_name[0] == 0x05)
1582 long_name[0] = (char) FAT_DIRENTRY_DELETED;
1584 if(raw_entry[8] != ' ')
1586 long_name[i++] = '.';
1591 if(raw_entry[j] == ' ')
1593 long_name[i] = raw_entry[j];
1595 /* See above for the lowercase 8.3 name handling of
1596 * Windows NT and later.
1598 if((raw_entry[12] & 0x10) && raw_entry[j] >= 'A' && raw_entry[j] <= 'Z')
1599 long_name[i] += 'a' - 'A';
1605 long_name[i] = '\0';
1608 /* extract properties of file and store them within the structure */
1609 dir_entry->attributes = raw_entry[11];
1610 dir_entry->cluster = ltoh16(*((uint16_t*) &raw_entry[26]));
1611 #if FAT_FAT32_SUPPORT
1612 dir_entry->cluster |= ((cluster_t) ltoh16(*((uint16_t*) &raw_entry[20]))) << 16;
1614 dir_entry->file_size = ltoh32(*((uint32_t*) &raw_entry[28]));
1616 #if FAT_DATETIME_SUPPORT
1617 dir_entry->modification_time = ltoh16(*((uint16_t*) &raw_entry[22]));
1618 dir_entry->modification_date = ltoh16(*((uint16_t*) &raw_entry[24]));
1625 #if FAT_WRITE_SUPPORT
1628 * Searches for space where to store a directory entry.
1630 * \param[in] fs The filesystem on which to operate.
1631 * \param[in] parent The directory in which to search.
1632 * \param[in] dir_entry The directory entry for which to search space.
1633 * \returns 0 on failure, a device offset on success.
1635 offset_t fat_find_offset_for_dir_entry(const struct fat_fs_struct* fs, const struct fat_dir_struct* parent, const struct fat_dir_entry_struct* dir_entry)
1637 if(!fs || !dir_entry)
1640 /* search for a place where to write the directory entry to disk */
1641 uint8_t free_dir_entries_needed = (strlen(dir_entry->long_name) + 12) / 13 + 1;
1642 uint8_t free_dir_entries_found = 0;
1643 cluster_t cluster_num = parent->dir_entry.cluster;
1644 offset_t dir_entry_offset = 0;
1645 offset_t offset = 0;
1646 offset_t offset_to = 0;
1647 #if FAT_FAT32_SUPPORT
1648 uint8_t is_fat32 = (fs->partition->type == PARTITION_TYPE_FAT32);
1651 if(cluster_num == 0)
1653 #if FAT_FAT32_SUPPORT
1656 cluster_num = fs->header.root_dir_cluster;
1661 /* we read/write from the root directory entry */
1662 offset = fs->header.root_dir_offset;
1663 offset_to = fs->header.cluster_zero_offset;
1664 dir_entry_offset = offset;
1670 if(offset == offset_to)
1672 if(cluster_num == 0)
1673 /* We iterated through the whole root directory and
1674 * could not find enough space for the directory entry.
1680 /* We reached a cluster boundary and have to
1681 * switch to the next cluster.
1684 cluster_t cluster_next = fat_get_next_cluster(fs, cluster_num);
1687 cluster_next = fat_append_clusters(fs, cluster_num, 1);
1691 /* we appended a new cluster and know it is free */
1692 dir_entry_offset = fs->header.cluster_zero_offset +
1693 (offset_t) (cluster_next - 2) * fs->header.cluster_size;
1695 /* clear cluster to avoid garbage directory entries */
1696 fat_clear_cluster(fs, cluster_next);
1700 cluster_num = cluster_next;
1703 offset = fat_cluster_offset(fs, cluster_num);
1704 offset_to = offset + fs->header.cluster_size;
1705 dir_entry_offset = offset;
1706 free_dir_entries_found = 0;
1709 /* read next lfn or 8.3 entry */
1711 if(!fs->partition->device_read(offset, &first_char, sizeof(first_char)))
1714 /* check if we found a free directory entry */
1715 if(first_char == FAT_DIRENTRY_DELETED || !first_char)
1717 /* check if we have the needed number of available entries */
1718 ++free_dir_entries_found;
1719 if(free_dir_entries_found >= free_dir_entries_needed)
1727 dir_entry_offset = offset;
1728 free_dir_entries_found = 0;
1732 return dir_entry_offset;
1736 #if FAT_WRITE_SUPPORT
1739 * Writes a directory entry to disk.
1741 * \note The file name is not checked for invalid characters.
1743 * \note The generation of the short 8.3 file name is quite
1744 * simple. The first eight characters are used for the filename.
1745 * The extension, if any, is made up of the first three characters
1746 * following the last dot within the long filename. If the
1747 * filename (without the extension) is longer than eight characters,
1748 * the lower byte of the cluster number replaces the last two
1749 * characters to avoid name clashes. In any other case, it is your
1750 * responsibility to avoid name clashes.
1752 * \param[in] fs The filesystem on which to operate.
1753 * \param[in] dir_entry The directory entry to write.
1754 * \returns 0 on failure, 1 on success.
1756 uint8_t fat_write_dir_entry(const struct fat_fs_struct* fs, struct fat_dir_entry_struct* dir_entry)
1758 if(!fs || !dir_entry)
1761 #if FAT_DATETIME_SUPPORT
1770 fat_get_datetime(&year, &month, &day, &hour, &min, &sec);
1771 fat_set_file_modification_date(dir_entry, year, month, day);
1772 fat_set_file_modification_time(dir_entry, hour, min, sec);
1776 device_write_t device_write = fs->partition->device_write;
1777 offset_t offset = dir_entry->entry_offset;
1778 const char* name = dir_entry->long_name;
1779 uint8_t name_len = strlen(name);
1780 uint8_t lfn_entry_count = (name_len + 12) / 13;
1783 /* write 8.3 entry */
1785 /* generate 8.3 file name */
1786 memset(&buffer[0], ' ', 11);
1787 char* name_ext = strrchr(name, '.');
1788 if(name_ext && *++name_ext)
1790 uint8_t name_ext_len = strlen(name_ext);
1791 name_len -= name_ext_len + 1;
1793 if(name_ext_len > 3)
1796 memcpy(&buffer[8], name_ext, name_ext_len);
1801 memcpy(buffer, name, name_len);
1803 /* For now, we create lfn entries for all files,
1804 * except the "." and ".." directory references.
1805 * This is to avoid difficulties with capitalization,
1806 * as 8.3 filenames allow uppercase letters only.
1808 * Theoretically it would be possible to leave
1809 * the 8.3 entry alone if the basename and the
1810 * extension have no mixed capitalization.
1812 if(name[0] == '.' &&
1813 ((name[1] == '.' && name[2] == '\0') ||
1816 lfn_entry_count = 0;
1820 memcpy(buffer, name, 8);
1822 /* Minimize 8.3 name clashes by appending
1823 * the lower byte of the cluster number.
1825 uint8_t num = dir_entry->cluster & 0xff;
1827 buffer[6] = (num < 0xa0) ? ('0' + (num >> 4)) : ('a' + (num >> 4));
1829 buffer[7] = (num < 0x0a) ? ('0' + num) : ('a' + num);
1831 if(buffer[0] == FAT_DIRENTRY_DELETED)
1834 /* fill directory entry buffer */
1835 memset(&buffer[11], 0, sizeof(buffer) - 11);
1836 buffer[0x0b] = dir_entry->attributes;
1837 #if FAT_DATETIME_SUPPORT
1838 *((uint16_t*) &buffer[0x16]) = htol16(dir_entry->modification_time);
1839 *((uint16_t*) &buffer[0x18]) = htol16(dir_entry->modification_date);
1841 #if FAT_FAT32_SUPPORT
1842 *((uint16_t*) &buffer[0x14]) = htol16((uint16_t) (dir_entry->cluster >> 16));
1844 *((uint16_t*) &buffer[0x1a]) = htol16(dir_entry->cluster);
1845 *((uint32_t*) &buffer[0x1c]) = htol32(dir_entry->file_size);
1848 if(!device_write(offset + (uint16_t) lfn_entry_count * 32, buffer, sizeof(buffer)))
1851 /* calculate checksum of 8.3 name */
1852 uint8_t checksum = buffer[0];
1853 for(i = 1; i < 11; ++i)
1854 checksum = ((checksum >> 1) | (checksum << 7)) + buffer[i];
1856 /* write lfn entries */
1857 uint8_t lfn_entry=0;
1858 for(lfn_entry = lfn_entry_count; lfn_entry > 0; --lfn_entry)
1860 memset(buffer, 0xff, sizeof(buffer));
1863 const char* long_name_curr = name + (lfn_entry - 1) * 13;
1867 buffer[i++] = *long_name_curr;
1880 if(!*long_name_curr++)
1884 /* set index of lfn entry */
1885 buffer[0x00] = lfn_entry;
1886 if(lfn_entry == lfn_entry_count)
1887 buffer[0x00] |= FAT_DIRENTRY_LFNLAST;
1889 /* mark as lfn entry */
1890 buffer[0x0b] = 0x0f;
1892 /* set 8.3 checksum */
1893 buffer[0x0d] = checksum;
1895 /* clear reserved bytes */
1901 device_write(offset, buffer, sizeof(buffer));
1903 offset += sizeof(buffer);
1914 * Creates a file and obtains the directory entry of the
1915 * new file. If the file to create already exists, the
1916 * directory entry of the existing file will be returned
1917 * within the dir_entry parameter.
1919 * \note The file name is not checked for invalid characters.
1921 * \note The generation of the short 8.3 file name is quite
1922 * simple. The first eight characters are used for the filename.
1923 * The extension, if any, is made up of the first three characters
1924 * following the last dot within the long filename. If the
1925 * filename (without the extension) is longer than eight characters,
1926 * the lower byte of the cluster number replaces the last two
1927 * characters to avoid name clashes. In any other case, it is your
1928 * responsibility to avoid name clashes.
1930 * \param[in] parent The handle of the directory in which to create the file.
1931 * \param[in] file The name of the file to create.
1932 * \param[out] dir_entry The directory entry to fill for the new file.
1933 * \returns 0 on failure, 1 on success.
1934 * \see fat_delete_file
1936 uint8_t fat_create_file(struct fat_dir_struct* parent, const char* file, struct fat_dir_entry_struct* dir_entry)
1938 if(!parent || !file || !file[0] || !dir_entry)
1941 /* check if the file already exists */
1944 if(!fat_read_dir(parent, dir_entry))
1947 if(strcmp(file, dir_entry->long_name) == 0)
1949 fat_reset_dir(parent);
1954 struct fat_fs_struct* fs = parent->fs;
1956 /* prepare directory entry with values already known */
1957 memset(dir_entry, 0, sizeof(*dir_entry));
1958 strncpy(dir_entry->long_name, file, sizeof(dir_entry->long_name) - 1);
1960 /* find place where to store directory entry */
1961 if(!(dir_entry->entry_offset = fat_find_offset_for_dir_entry(fs, parent, dir_entry)))
1964 /* write directory entry to disk */
1965 if(!fat_write_dir_entry(fs, dir_entry))
1973 * Deletes a file or directory.
1975 * If a directory is deleted without first deleting its
1976 * subdirectories and files, disk space occupied by these
1977 * files will get wasted as there is no chance to release
1978 * it and mark it as free.
1980 * \param[in] fs The filesystem on which to operate.
1981 * \param[in] dir_entry The directory entry of the file to delete.
1982 * \returns 0 on failure, 1 on success.
1983 * \see fat_create_file
1985 uint8_t fat_delete_file(struct fat_fs_struct* fs, struct fat_dir_entry_struct* dir_entry)
1987 if(!fs || !dir_entry)
1990 /* get offset of the file's directory entry */
1991 offset_t dir_entry_offset = dir_entry->entry_offset;
1992 if(!dir_entry_offset)
1998 /* read directory entry */
1999 if(!fs->partition->device_read(dir_entry_offset, buffer, sizeof(buffer)))
2002 /* mark the directory entry as deleted */
2003 buffer[0] = FAT_DIRENTRY_DELETED;
2005 /* write back entry */
2006 if(!fs->partition->device_write(dir_entry_offset, buffer, sizeof(buffer)))
2009 /* check if we deleted the whole entry */
2010 if(buffer[11] != 0x0f)
2013 dir_entry_offset += 32;
2016 /* We deleted the directory entry. The next thing to do is
2017 * marking all occupied clusters as free.
2019 return (dir_entry->cluster == 0 || fat_free_clusters(fs, dir_entry->cluster));
2024 * Creates a directory.
2026 * Creates a directory and obtains its directory entry.
2027 * If the directory to create already exists, its
2028 * directory entry will be returned within the dir_entry
2031 * \note The notes which apply to fat_create_file also
2032 * apply to this function.
2034 * \param[in] parent The handle of the parent directory of the new directory.
2035 * \param[in] dir The name of the directory to create.
2036 * \param[out] dir_entry The directory entry to fill for the new directory.
2037 * \returns 0 on failure, 1 on success.
2038 * \see fat_delete_dir
2040 uint8_t fat_create_dir(struct fat_dir_struct* parent, const char* dir, struct fat_dir_entry_struct* dir_entry)
2042 if(!parent || !dir || !dir[0] || !dir_entry)
2045 /* check if the file or directory already exists */
2046 while(fat_read_dir(parent, dir_entry))
2048 if(strcmp(dir, dir_entry->long_name) == 0)
2050 fat_reset_dir(parent);
2055 struct fat_fs_struct* fs = parent->fs;
2057 /* allocate cluster which will hold directory entries */
2058 cluster_t dir_cluster = fat_append_clusters(fs, 0, 1);
2062 /* clear cluster to prevent bogus directory entries */
2063 fat_clear_cluster(fs, dir_cluster);
2065 memset(dir_entry, 0, sizeof(*dir_entry));
2066 dir_entry->attributes = FAT_ATTRIB_DIR;
2068 /* create "." directory self reference */
2069 dir_entry->entry_offset = fs->header.cluster_zero_offset +
2070 (offset_t) (dir_cluster - 2) * fs->header.cluster_size;
2071 dir_entry->long_name[0] = '.';
2072 dir_entry->cluster = dir_cluster;
2073 if(!fat_write_dir_entry(fs, dir_entry))
2075 fat_free_clusters(fs, dir_cluster);
2079 /* create ".." parent directory reference */
2080 dir_entry->entry_offset += 32;
2081 dir_entry->long_name[1] = '.';
2082 dir_entry->cluster = parent->dir_entry.cluster;
2083 if(!fat_write_dir_entry(fs, dir_entry))
2085 fat_free_clusters(fs, dir_cluster);
2089 /* fill directory entry */
2090 strncpy(dir_entry->long_name, dir, sizeof(dir_entry->long_name) - 1);
2091 dir_entry->cluster = dir_cluster;
2093 /* find place where to store directory entry */
2094 if(!(dir_entry->entry_offset = fat_find_offset_for_dir_entry(fs, parent, dir_entry)))
2096 fat_free_clusters(fs, dir_cluster);
2100 /* write directory to disk */
2101 if(!fat_write_dir_entry(fs, dir_entry))
2103 fat_free_clusters(fs, dir_cluster);
2112 * Deletes a directory.
2114 * This is just a synonym for fat_delete_file().
2115 * If a directory is deleted without first deleting its
2116 * subdirectories and files, disk space occupied by these
2117 * files will get wasted as there is no chance to release
2118 * it and mark it as free.
2120 * \param[in] fs The filesystem on which to operate.
2121 * \param[in] dir_entry The directory entry of the directory to delete.
2122 * \returns 0 on failure, 1 on success.
2123 * \see fat_create_dir
2126 uint8_t fat_delete_dir(struct fat_fs_struct* fs, struct fat_dir_entry_struct* dir_entry);
2129 #if FAT_DATETIME_SUPPORT
2132 * Returns the modification date of a file.
2134 * \param[in] dir_entry The directory entry of which to return the modification date.
2135 * \param[out] year The year the file was last modified.
2136 * \param[out] month The month the file was last modified.
2137 * \param[out] day The day the file was last modified.
2139 void fat_get_file_modification_date(const struct fat_dir_entry_struct* dir_entry, uint16_t* year, uint8_t* month, uint8_t* day)
2144 *year = 1980 + ((dir_entry->modification_date >> 9) & 0x7f);
2145 *month = (dir_entry->modification_date >> 5) & 0x0f;
2146 *day = (dir_entry->modification_date >> 0) & 0x1f;
2150 #if FAT_DATETIME_SUPPORT
2153 * Returns the modification time of a file.
2155 * \param[in] dir_entry The directory entry of which to return the modification time.
2156 * \param[out] hour The hour the file was last modified.
2157 * \param[out] min The min the file was last modified.
2158 * \param[out] sec The sec the file was last modified.
2160 void fat_get_file_modification_time(const struct fat_dir_entry_struct* dir_entry, uint8_t* hour, uint8_t* min, uint8_t* sec)
2165 *hour = (dir_entry->modification_time >> 11) & 0x1f;
2166 *min = (dir_entry->modification_time >> 5) & 0x3f;
2167 *sec = ((dir_entry->modification_time >> 0) & 0x1f) * 2;
2171 #if (FAT_WRITE_SUPPORT && FAT_DATETIME_SUPPORT)
2174 * Sets the modification time of a date.
2176 * \param[in] dir_entry The directory entry for which to set the modification date.
2177 * \param[in] year The year the file was last modified.
2178 * \param[in] month The month the file was last modified.
2179 * \param[in] day The day the file was last modified.
2181 void fat_set_file_modification_date(struct fat_dir_entry_struct* dir_entry, uint16_t year, uint8_t month, uint8_t day)
2186 dir_entry->modification_date =
2187 ((year - 1980) << 9) |
2188 ((uint16_t) month << 5) |
2189 ((uint16_t) day << 0);
2193 #if (FAT_WRITE_SUPPORT && FAT_DATETIME_SUPPORT)
2196 * Sets the modification time of a file.
2198 * \param[in] dir_entry The directory entry for which to set the modification time.
2199 * \param[in] hour The year the file was last modified.
2200 * \param[in] min The month the file was last modified.
2201 * \param[in] sec The day the file was last modified.
2203 void fat_set_file_modification_time(struct fat_dir_entry_struct* dir_entry, uint8_t hour, uint8_t min, uint8_t sec)
2208 dir_entry->modification_time =
2209 ((uint16_t) hour << 11) |
2210 ((uint16_t) min << 5) |
2211 ((uint16_t) sec >> 1) ;
2217 * Returns the amount of total storage capacity of the filesystem in bytes.
2219 * \param[in] fs The filesystem on which to operate.
2220 * \returns 0 on failure, the filesystem size in bytes otherwise.
2222 offset_t fat_get_fs_size(const struct fat_fs_struct* fs)
2227 #if FAT_FAT32_SUPPORT
2228 if(fs->partition->type == PARTITION_TYPE_FAT32)
2229 return (offset_t) (fs->header.fat_size / 4 - 2) * fs->header.cluster_size;
2232 return (offset_t) (fs->header.fat_size / 2 - 2) * fs->header.cluster_size;
2237 * Returns the amount of free storage capacity on the filesystem in bytes.
2239 * \note As the FAT filesystem is cluster based, this function does not
2240 * return continuous values but multiples of the cluster size.
2242 * \param[in] fs The filesystem on which to operate.
2243 * \returns 0 on failure, the free filesystem space in bytes otherwise.
2245 offset_t fat_get_fs_free(const struct fat_fs_struct* fs)
2251 struct fat_usage_count_callback_arg count_arg;
2252 count_arg.cluster_count = 0;
2253 count_arg.buffer_size = sizeof(fat);
2255 offset_t fat_offset = fs->header.fat_offset;
2256 uint32_t fat_size = fs->header.fat_size;
2259 uintptr_t length = UINTPTR_MAX - 1;
2260 if(fat_size < length)
2263 if(!fs->partition->device_read_interval(fat_offset,
2267 #if FAT_FAT32_SUPPORT
2268 (fs->partition->type == PARTITION_TYPE_FAT16) ?
2269 fat_get_fs_free_16_callback :
2270 fat_get_fs_free_32_callback,
2272 fat_get_fs_free_16_callback,
2279 fat_offset += length;
2283 return (offset_t) count_arg.cluster_count * fs->header.cluster_size;
2288 * Callback function used for counting free clusters in a FAT.
2290 uint8_t fat_get_fs_free_16_callback(uint8_t* buffer, offset_t offset, void* p)
2292 struct fat_usage_count_callback_arg* count_arg = (struct fat_usage_count_callback_arg*) p;
2293 uintptr_t buffer_size = count_arg->buffer_size;
2296 for(j = 0; i < buffer_size; j += 2, buffer += 2)
2298 uint16_t cluster = *((uint16_t*) &buffer[0]);
2299 if(cluster == HTOL16(FAT16_CLUSTER_FREE))
2300 ++(count_arg->cluster_count);
2306 #if FAT_FAT32_SUPPORT
2309 * Callback function used for counting free clusters in a FAT32.
2311 uint8_t fat_get_fs_free_32_callback(uint8_t* buffer, offset_t offset, void* p)
2313 struct fat_usage_count_callback_arg* count_arg = (struct fat_usage_count_callback_arg*) p;
2314 uintptr_t buffer_size = count_arg->buffer_size;
2316 for(i = 0; i < buffer_size; i += 4, buffer += 4)
2318 uint32_t cluster = *((uint32_t*) &buffer[0]);
2319 if(cluster == HTOL32(FAT32_CLUSTER_FREE))
2320 ++(count_arg->cluster_count);