From bfb4d60d1fc77ac6287dcd914a280ef920843b45 Mon Sep 17 00:00:00 2001 From: Michael Chisholm Date: Mon, 8 Sep 2008 08:28:17 +0000 Subject: [PATCH] Don't read high 16 bits of start cluster from a directory entry on non-FAT32 partititions, in case it contains non-zero data --- source/directory.c | 21 +++++++++++++++------ source/directory.h | 6 +++++- source/fatdir.c | 8 ++++---- source/fatfile.c | 4 ++-- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/source/directory.c b/source/directory.c index 74f5c8a..4d6e008 100644 --- a/source/directory.c +++ b/source/directory.c @@ -62,6 +62,10 @@ 2008-08-02 - Chishm * Correct cluster given on FAT32 when .. entry is included in path to subdirectory * Fixed creation of long filename entry for all-caps filenames longer than 8 characters + + 2008-09-07 - Chishm + * Don't read high 16 bits of start cluster from a directory entry on non-FAT32 partititions, in case it contains non-zero data + * Thanks to Chris Liu */ #include @@ -272,8 +276,13 @@ static bool _FAT_directory_entryGetAlias (const u8* entryData, char* destName) { return (destName[0] != '\0'); } -u32 _FAT_directory_entryGetCluster (const u8* entryData) { - return u8array_to_u16(entryData,DIR_ENTRY_cluster) | (u8array_to_u16(entryData, DIR_ENTRY_clusterHigh) << 16); +u32 _FAT_directory_entryGetCluster (PARTITION* partition, const u8* entryData) { + if (partition->filesysType == FS_FAT32) { + // Only use high 16 bits of start cluster when we are certain they are correctly defined + return u8array_to_u16(entryData,DIR_ENTRY_cluster) | (u8array_to_u16(entryData, DIR_ENTRY_clusterHigh) << 16); + } else { + return u8array_to_u16(entryData,DIR_ENTRY_cluster); + } } static bool _FAT_directory_incrementDirEntryPosition (PARTITION* partition, DIR_ENTRY_POSITION* entryPosition, bool extendDirectory) { @@ -620,7 +629,7 @@ bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const // Check that we reached the end of the path found = true; } else if (entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR) { - dirCluster = _FAT_directory_entryGetCluster (entry->entryData); + dirCluster = _FAT_directory_entryGetCluster (partition, entry->entryData); pathPosition = nextPathPosition; // Consume separator(s) while (pathPosition[0] == DIR_SEPARATOR) { @@ -637,7 +646,7 @@ bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const if (found && !notFound) { if (partition->filesysType == FS_FAT32 && (entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR) && - _FAT_directory_entryGetCluster (entry->entryData) == CLUSTER_ROOT) + _FAT_directory_entryGetCluster (partition, entry->entryData) == CLUSTER_ROOT) { // On FAT32 it should specify an actual cluster for the root entry, // not cluster 0 as on FAT16 @@ -1090,7 +1099,7 @@ bool _FAT_directory_chdir (PARTITION* partition, const char* path) { return false; } - partition->cwdCluster = _FAT_directory_entryGetCluster (entry.entryData); + partition->cwdCluster = _FAT_directory_entryGetCluster (partition, entry.entryData); return true; } @@ -1099,7 +1108,7 @@ void _FAT_directory_entryStat (PARTITION* partition, DIR_ENTRY* entry, struct st // Fill in the stat struct // Some of the values are faked for the sake of compatibility st->st_dev = _FAT_disc_hostType(partition->disc); // The device is the 32bit ioType value - st->st_ino = (ino_t)(_FAT_directory_entryGetCluster(entry->entryData)); // The file serial number is the start cluster + st->st_ino = (ino_t)(_FAT_directory_entryGetCluster(partition, entry->entryData)); // The file serial number is the start cluster st->st_mode = (_FAT_directory_isDirectory(entry) ? S_IFDIR : S_IFREG) | (S_IRUSR | S_IRGRP | S_IROTH) | (_FAT_directory_isWritable (entry) ? (S_IWUSR | S_IWGRP | S_IWOTH) : 0); // Mode bits based on dirEntry ATTRIB byte diff --git a/source/directory.h b/source/directory.h index 4e63583..5e34e8d 100644 --- a/source/directory.h +++ b/source/directory.h @@ -31,6 +31,10 @@ 2007-11-01 - Chishm * Added unicode support + + 2008-09-07 - Chishm + * Don't read high 16 bits of start cluster from a directory entry on non-FAT32 partititions, in case it contains non-zero data + * Thanks to Chris Liu */ #ifndef _DIRECTORY_H @@ -162,7 +166,7 @@ bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, u32 dirClu /* Get the start cluster of a file from it's entry data */ -u32 _FAT_directory_entryGetCluster (const u8* entryData); +u32 _FAT_directory_entryGetCluster (PARTITION* partition, const u8* entryData); /* Fill in the file name and entry data of DIR_ENTRY* entry. diff --git a/source/fatdir.c b/source/fatdir.c index 293006b..c27f6e1 100644 --- a/source/fatdir.c +++ b/source/fatdir.c @@ -151,7 +151,7 @@ int _FAT_unlink_r (struct _reent *r, const char *path) { return -1; } - cluster = _FAT_directory_entryGetCluster (dirEntry.entryData); + cluster = _FAT_directory_entryGetCluster (partition, dirEntry.entryData); // If this is a directory, make sure it is empty @@ -319,7 +319,7 @@ int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) { r->_errno = ENOTDIR; return -1; } - dirCluster = _FAT_directory_entryGetCluster (newDirEntry.entryData); + dirCluster = _FAT_directory_entryGetCluster (partition, newDirEntry.entryData); // Move the pathEnd past the last DIR_SEPARATOR pathEnd += 1; } @@ -414,7 +414,7 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) { r->_errno = ENOTDIR; return -1; } - parentCluster = _FAT_directory_entryGetCluster (dirEntry.entryData); + parentCluster = _FAT_directory_entryGetCluster (partition, dirEntry.entryData); // Move the pathEnd past the last DIR_SEPARATOR pathEnd += 1; } @@ -564,7 +564,7 @@ DIR_ITER* _FAT_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path) } // Save the start cluster for use when resetting the directory data - state->startCluster = _FAT_directory_entryGetCluster (dirEntry.entryData); + state->startCluster = _FAT_directory_entryGetCluster (state->partition, dirEntry.entryData); // Get the first entry for use with a call to dirnext state->validEntry = diff --git a/source/fatfile.c b/source/fatfile.c index d411de7..4bc4278 100644 --- a/source/fatfile.c +++ b/source/fatfile.c @@ -170,7 +170,7 @@ int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags r->_errno = ENOTDIR; return -1; } - dirCluster = _FAT_directory_entryGetCluster (dirEntry.entryData); + dirCluster = _FAT_directory_entryGetCluster (partition, dirEntry.entryData); // Move the pathEnd past the last DIR_SEPARATOR pathEnd += 1; } @@ -216,7 +216,7 @@ int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags // Associate this file with a particular partition file->partition = partition; - file->startCluster = _FAT_directory_entryGetCluster (dirEntry.entryData); + file->startCluster = _FAT_directory_entryGetCluster (partition, dirEntry.entryData); // Truncate the file if requested if ((flags & O_TRUNC) && file->write && (file->startCluster != 0)) {