Don't read high 16 bits of start cluster from a directory entry on non-FAT32 partititions, in case it contains non-zero data

This commit is contained in:
Michael Chisholm 2008-09-08 08:28:17 +00:00
parent 783ea08837
commit bfb4d60d1f
4 changed files with 26 additions and 13 deletions

View File

@ -62,6 +62,10 @@
2008-08-02 - Chishm 2008-08-02 - Chishm
* Correct cluster given on FAT32 when .. entry is included in path to subdirectory * 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 * 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 <string.h> #include <string.h>
@ -272,8 +276,13 @@ static bool _FAT_directory_entryGetAlias (const u8* entryData, char* destName) {
return (destName[0] != '\0'); return (destName[0] != '\0');
} }
u32 _FAT_directory_entryGetCluster (const u8* entryData) { 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); 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) { 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 // Check that we reached the end of the path
found = true; found = true;
} else if (entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR) { } else if (entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR) {
dirCluster = _FAT_directory_entryGetCluster (entry->entryData); dirCluster = _FAT_directory_entryGetCluster (partition, entry->entryData);
pathPosition = nextPathPosition; pathPosition = nextPathPosition;
// Consume separator(s) // Consume separator(s)
while (pathPosition[0] == DIR_SEPARATOR) { while (pathPosition[0] == DIR_SEPARATOR) {
@ -637,7 +646,7 @@ bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const
if (found && !notFound) { if (found && !notFound) {
if (partition->filesysType == FS_FAT32 && (entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR) && 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, // On FAT32 it should specify an actual cluster for the root entry,
// not cluster 0 as on FAT16 // not cluster 0 as on FAT16
@ -1090,7 +1099,7 @@ bool _FAT_directory_chdir (PARTITION* partition, const char* path) {
return false; return false;
} }
partition->cwdCluster = _FAT_directory_entryGetCluster (entry.entryData); partition->cwdCluster = _FAT_directory_entryGetCluster (partition, entry.entryData);
return true; return true;
} }
@ -1099,7 +1108,7 @@ void _FAT_directory_entryStat (PARTITION* partition, DIR_ENTRY* entry, struct st
// Fill in the stat struct // Fill in the stat struct
// Some of the values are faked for the sake of compatibility // 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_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) | st->st_mode = (_FAT_directory_isDirectory(entry) ? S_IFDIR : S_IFREG) |
(S_IRUSR | S_IRGRP | S_IROTH) | (S_IRUSR | S_IRGRP | S_IROTH) |
(_FAT_directory_isWritable (entry) ? (S_IWUSR | S_IWGRP | S_IWOTH) : 0); // Mode bits based on dirEntry ATTRIB byte (_FAT_directory_isWritable (entry) ? (S_IWUSR | S_IWGRP | S_IWOTH) : 0); // Mode bits based on dirEntry ATTRIB byte

View File

@ -31,6 +31,10 @@
2007-11-01 - Chishm 2007-11-01 - Chishm
* Added unicode support * 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 #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 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. Fill in the file name and entry data of DIR_ENTRY* entry.

View File

@ -151,7 +151,7 @@ int _FAT_unlink_r (struct _reent *r, const char *path) {
return -1; 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 // 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; r->_errno = ENOTDIR;
return -1; return -1;
} }
dirCluster = _FAT_directory_entryGetCluster (newDirEntry.entryData); dirCluster = _FAT_directory_entryGetCluster (partition, newDirEntry.entryData);
// Move the pathEnd past the last DIR_SEPARATOR // Move the pathEnd past the last DIR_SEPARATOR
pathEnd += 1; pathEnd += 1;
} }
@ -414,7 +414,7 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
r->_errno = ENOTDIR; r->_errno = ENOTDIR;
return -1; return -1;
} }
parentCluster = _FAT_directory_entryGetCluster (dirEntry.entryData); parentCluster = _FAT_directory_entryGetCluster (partition, dirEntry.entryData);
// Move the pathEnd past the last DIR_SEPARATOR // Move the pathEnd past the last DIR_SEPARATOR
pathEnd += 1; 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 // 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 // Get the first entry for use with a call to dirnext
state->validEntry = state->validEntry =

View File

@ -170,7 +170,7 @@ int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
r->_errno = ENOTDIR; r->_errno = ENOTDIR;
return -1; return -1;
} }
dirCluster = _FAT_directory_entryGetCluster (dirEntry.entryData); dirCluster = _FAT_directory_entryGetCluster (partition, dirEntry.entryData);
// Move the pathEnd past the last DIR_SEPARATOR // Move the pathEnd past the last DIR_SEPARATOR
pathEnd += 1; 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 // Associate this file with a particular partition
file->partition = partition; file->partition = partition;
file->startCluster = _FAT_directory_entryGetCluster (dirEntry.entryData); file->startCluster = _FAT_directory_entryGetCluster (partition, dirEntry.entryData);
// Truncate the file if requested // Truncate the file if requested
if ((flags & O_TRUNC) && file->write && (file->startCluster != 0)) { if ((flags & O_TRUNC) && file->write && (file->startCluster != 0)) {