FAT directory functions
[FAT support]

Collaboration diagram for FAT directory functions:

Functions

struct fat_dir_structfat_open_dir (struct fat_fs_struct *fs, const struct fat_dir_entry_struct *dir_entry)
void fat_close_dir (struct fat_dir_struct *dd)
uint8_t fat_read_dir (struct fat_dir_struct *dd, struct fat_dir_entry_struct *dir_entry)
uint8_t fat_reset_dir (struct fat_dir_struct *dd)
uint8_t fat_create_dir (struct fat_dir_struct *parent, const char *dir, struct fat_dir_entry_struct *dir_entry)

Detailed Description

Functions for managing directories.

Function Documentation

void fat_close_dir ( struct fat_dir_struct dd  ) 

Closes a directory descriptor.

This function destroys a directory descriptor which was previously obtained by calling fat_open_dir(). When this function returns, the given descriptor will be invalid.

Parameters:
[in] dd The directory descriptor to close.
See also:
fat_open_dir

Definition at line 1418 of file fat.c.

References fat_dir_struct::fs.

Referenced by WaspSD::cd(), WaspSD::close(), and fat_get_dir_entry_of_path().

01419 {
01420     if(dd)
01421 #if USE_DYNAMIC_MEMORY
01422         free(dd);
01423 #else
01424         dd->fs = 0;
01425 #endif
01426 }

Here is the caller graph for this function:

uint8_t fat_create_dir ( struct fat_dir_struct parent,
const char *  dir,
struct fat_dir_entry_struct dir_entry 
)

Creates a directory.

Creates a directory and obtains its directory entry. If the directory to create already exists, its directory entry will be returned within the dir_entry parameter.

Note:
The notes which apply to fat_create_file also apply to this function.
Parameters:
[in] parent The handle of the parent directory of the new directory.
[in] dir The name of the directory to create.
[out] dir_entry The directory entry to fill for the new directory.
Returns:
0 on failure, 1 on success.
See also:
fat_delete_dir

Definition at line 2170 of file fat.c.

References fat_dir_entry_struct::attributes, fat_dir_entry_struct::cluster, fat_header_struct::cluster_size, fat_header_struct::cluster_zero_offset, fat_dir_struct::dir_entry, fat_dir_entry_struct::entry_offset, fat_append_clusters(), FAT_ATTRIB_DIR, fat_clear_cluster(), fat_find_offset_for_dir_entry(), fat_free_clusters(), fat_read_dir(), fat_reset_dir(), fat_write_dir_entry(), fat_dir_struct::fs, fat_fs_struct::header, and fat_dir_entry_struct::long_name.

Referenced by WaspSD::mkdir().

02171 {
02172     if(!parent || !dir || !dir[0] || !dir_entry)
02173         return 0;
02174 
02175     /* check if the file or directory already exists */
02176     while(fat_read_dir(parent, dir_entry))
02177     {
02178         if(strcmp(dir, dir_entry->long_name) == 0)
02179         {
02180             fat_reset_dir(parent);
02181             return 0;
02182         }
02183     }
02184 
02185     struct fat_fs_struct* fs = parent->fs;
02186 
02187     /* allocate cluster which will hold directory entries */
02188     cluster_t dir_cluster = fat_append_clusters(fs, 0, 1);
02189     if(!dir_cluster)
02190         return 0;
02191 
02192     /* clear cluster to prevent bogus directory entries */
02193     fat_clear_cluster(fs, dir_cluster);
02194     
02195     memset(dir_entry, 0, sizeof(*dir_entry));
02196     dir_entry->attributes = FAT_ATTRIB_DIR;
02197 
02198     /* create "." directory self reference */
02199     dir_entry->entry_offset = fs->header.cluster_zero_offset +
02200                               (offset_t) (dir_cluster - 2) * fs->header.cluster_size;
02201     dir_entry->long_name[0] = '.';
02202     dir_entry->cluster = dir_cluster;
02203     if(!fat_write_dir_entry(fs, dir_entry))
02204     {
02205         fat_free_clusters(fs, dir_cluster);
02206         return 0;
02207     }
02208 
02209     /* create ".." parent directory reference */
02210     dir_entry->entry_offset += 32;
02211     dir_entry->long_name[1] = '.';
02212     dir_entry->cluster = parent->dir_entry.cluster;
02213     if(!fat_write_dir_entry(fs, dir_entry))
02214     {
02215         fat_free_clusters(fs, dir_cluster);
02216         return 0;
02217     }
02218 
02219     /* fill directory entry */
02220     strncpy(dir_entry->long_name, dir, sizeof(dir_entry->long_name) - 1);
02221     dir_entry->cluster = dir_cluster;
02222 
02223     /* find place where to store directory entry */
02224     if(!(dir_entry->entry_offset = fat_find_offset_for_dir_entry(fs, parent, dir_entry)))
02225     {
02226         fat_free_clusters(fs, dir_cluster);
02227         return 0;
02228     }
02229 
02230     /* write directory to disk */
02231     if(!fat_write_dir_entry(fs, dir_entry))
02232     {
02233         fat_free_clusters(fs, dir_cluster);
02234         return 0;
02235     }
02236 
02237     return 1;
02238 }

Here is the call graph for this function:

Here is the caller graph for this function:

struct fat_dir_struct* fat_open_dir ( struct fat_fs_struct fs,
const struct fat_dir_entry_struct dir_entry 
) [read]

Opens a directory.

Parameters:
[in] fs The filesystem on which the directory to open resides.
[in] dir_entry The directory entry which stands for the directory to open.
Returns:
An opaque directory descriptor on success, 0 on failure.
See also:
fat_close_dir

Definition at line 1376 of file fat.c.

References fat_dir_entry_struct::attributes, fat_dir_entry_struct::cluster, fat_dir_struct::dir_entry, fat_dir_struct::entry_cluster, fat_dir_struct::entry_offset, FAT_ATTRIB_DIR, FAT_DIR_COUNT, fat_dir_handles, and fat_dir_struct::fs.

Referenced by WaspSD::cd(), fat_get_dir_entry_of_path(), and WaspSD::init().

01377 {
01378     if(!fs || !dir_entry || !(dir_entry->attributes & FAT_ATTRIB_DIR))
01379         return 0;
01380 
01381 #if USE_DYNAMIC_MEMORY
01382     struct fat_dir_struct* dd = malloc(sizeof(*dd));
01383     if(!dd)
01384         return 0;
01385 #else
01386     struct fat_dir_struct* dd = fat_dir_handles;
01387     uint8_t i;
01388     for(i = 0; i < FAT_DIR_COUNT; ++i)
01389     {
01390         if(!dd->fs)
01391             break;
01392 
01393         ++dd;
01394     }
01395     if(i >= FAT_DIR_COUNT)
01396         return 0;
01397 #endif
01398     
01399     memcpy(&dd->dir_entry, dir_entry, sizeof(*dir_entry));
01400     dd->fs = fs;
01401     dd->entry_cluster = dir_entry->cluster;
01402     dd->entry_offset = 0;
01403 
01404     return dd;
01405 }

Here is the caller graph for this function:

uint8_t fat_read_dir ( struct fat_dir_struct dd,
struct fat_dir_entry_struct dir_entry 
)

Reads the next directory entry contained within a parent directory.

Parameters:
[in] dd The descriptor of the parent directory from which to read the entry.
[out] dir_entry Pointer to a buffer into which to write the directory entry information.
Returns:
0 on failure, 1 on success.
See also:
fat_reset_dir

Definition at line 1437 of file fat.c.

References fat_read_dir_callback_arg::bytes_read, fat_header_struct::cluster_size, fat_header_struct::cluster_zero_offset, partition_struct::device_read_interval, fat_read_dir_callback_arg::dir_entry, fat_dir_struct::entry_cluster, fat_dir_struct::entry_offset, fat_cluster_offset(), fat_dir_entry_read_callback(), fat_get_next_cluster(), fat_reset_dir(), fat_read_dir_callback_arg::finished, fat_dir_struct::fs, fat_fs_struct::header, fat_fs_struct::partition, PARTITION_TYPE_FAT32, fat_header_struct::root_dir_offset, and partition_struct::type.

Referenced by WaspSD::delDir(), fat_create_dir(), fat_create_file(), fat_get_dir_entry_of_path(), WaspSD::find_file_in_dir(), WaspSD::ls(), and WaspSD::numFiles().

01438 {
01439     if(!dd || !dir_entry)
01440         return 0;
01441 
01442     /* get current position of directory handle */
01443     struct fat_fs_struct* fs = dd->fs;
01444     const struct fat_header_struct* header = &fs->header;
01445     uint16_t cluster_size = header->cluster_size;
01446     cluster_t cluster_num = dd->entry_cluster;
01447     uint16_t cluster_offset = dd->entry_offset;
01448     struct fat_read_dir_callback_arg arg;
01449 
01450     if(cluster_offset >= cluster_size)
01451     {
01452         /* The latest call hit the border of the last cluster in
01453          * the chain, but it still returned a directory entry.
01454          * So we now reset the handle and signal the caller the
01455          * end of the listing.
01456          */
01457         fat_reset_dir(dd);
01458         return 0;
01459     }
01460 
01461     /* reset callback arguments */
01462     memset(&arg, 0, sizeof(arg));
01463     memset(dir_entry, 0, sizeof(*dir_entry));
01464     arg.dir_entry = dir_entry;
01465 
01466     /* check if we read from the root directory */
01467     if(cluster_num == 0)
01468     {
01469 #if FAT_FAT32_SUPPORT
01470         if(fs->partition->type == PARTITION_TYPE_FAT32)
01471             cluster_num = header->root_dir_cluster;
01472         else
01473 #endif
01474             cluster_size = header->cluster_zero_offset - header->root_dir_offset;
01475     }
01476 
01477     /* read entries */
01478     uint8_t buffer[32];
01479     while(!arg.finished)
01480     {
01481         /* read directory entries up to the cluster border */
01482         uint16_t cluster_left = cluster_size - cluster_offset;
01483         offset_t pos = cluster_offset;
01484         if(cluster_num == 0)
01485             pos += header->root_dir_offset;
01486         else
01487             pos += fat_cluster_offset(fs, cluster_num);
01488 
01489         arg.bytes_read = 0;
01490         if(!fs->partition->device_read_interval(pos,
01491                                                 buffer,
01492                                                 sizeof(buffer),
01493                                                 cluster_left,
01494                                                 fat_dir_entry_read_callback,
01495                                                 &arg)
01496           )
01497             return 0;
01498 
01499         cluster_offset += arg.bytes_read;
01500 
01501         if(cluster_offset >= cluster_size)
01502         {
01503             /* we reached the cluster border and switch to the next cluster */
01504 
01505             /* get number of next cluster */
01506             if((cluster_num = fat_get_next_cluster(fs, cluster_num)) != 0)
01507             {
01508                 cluster_offset = 0;
01509                 continue;
01510             }
01511 
01512             /* we are at the end of the cluster chain */
01513             if(!arg.finished)
01514             {
01515                 /* directory entry not found, reset directory handle */
01516                 fat_reset_dir(dd);
01517                 return 0;
01518             }
01519             else
01520             {
01521                 /* The current execution of the function has been successful,
01522                  * so we can not signal an end of the directory listing to
01523                  * the caller, but must wait for the next call. So we keep an
01524                  * invalid cluster offset to mark this directory handle's
01525                  * traversal as finished.
01526                  */
01527             }
01528 
01529             break;
01530         }
01531     }
01532 
01533     dd->entry_cluster = cluster_num;
01534     dd->entry_offset = cluster_offset;
01535 
01536     return arg.finished;
01537 }

Here is the call graph for this function:

Here is the caller graph for this function:

uint8_t fat_reset_dir ( struct fat_dir_struct dd  ) 

Resets a directory handle.

Resets the directory handle such that reading restarts with the first directory entry.

Parameters:
[in] dd The directory handle to reset.
Returns:
0 on failure, 1 on success.
See also:
fat_read_dir

Definition at line 1550 of file fat.c.

References fat_dir_entry_struct::cluster, fat_dir_struct::dir_entry, fat_dir_struct::entry_cluster, and fat_dir_struct::entry_offset.

Referenced by fat_create_dir(), fat_create_file(), fat_read_dir(), and WaspSD::find_file_in_dir().

01551 {
01552     if(!dd)
01553         return 0;
01554 
01555     dd->entry_cluster = dd->dir_entry.cluster;
01556     dd->entry_offset = 0;
01557     return 1;
01558 }

Here is the caller graph for this function:


Generated on Tue Jul 20 09:31:00 2010 for WaspmoteAPI by  doxygen 1.5.6