From ad4866e0cb1f7ddefbe1e31a890741e4cbc50181 Mon Sep 17 00:00:00 2001 From: aliaspider Date: Tue, 28 Oct 2014 06:47:04 +0100 Subject: remove unused files --- sdk-modifications/libsrc/fs/directory.c | 1035 ------------------------------- 1 file changed, 1035 deletions(-) delete mode 100755 sdk-modifications/libsrc/fs/directory.c (limited to 'sdk-modifications/libsrc/fs/directory.c') diff --git a/sdk-modifications/libsrc/fs/directory.c b/sdk-modifications/libsrc/fs/directory.c deleted file mode 100755 index 124daf8..0000000 --- a/sdk-modifications/libsrc/fs/directory.c +++ /dev/null @@ -1,1035 +0,0 @@ -/* - directory.c - Reading, writing and manipulation of the directory structure on - a FAT partition - - Copyright (c) 2006 Michael "Chishm" Chisholm - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - 2006-08-14 - Chishm - * entryFromPath correctly finds "" and "." now - - 2006-08-17 - Chishm - * entryFromPath doesn't look for "" anymore - use "." to refer to the current directory - - 2006-08-19 - Chishm - * Fixed entryFromPath bug when looking for "." in root directory - - 2006-10-01 - Chishm - * Now clears the whole new cluster when linking in more clusters for a directory - - 2006-10-28 - Chishm - * stat returns the hostType for the st_dev value -*/ -//version 1.1 -//Note: fix bug in _FAT_directory_isValidAlias() - -#include -#include - -#include "directory.h" -#include "fs_common.h" -#include "partition.h" -#include "file_allocation_table.h" -#include "bit_ops.h" -#include "filetime.h" -#include "fs_unicode.h" - -// Directory entry codes -#define DIR_ENTRY_LAST 0x00 -#define DIR_ENTRY_FREE 0xE5 - - -// Long file name directory entry -enum LFN_offset { - LFN_offset_ordinal = 0x00, // Position within LFN - LFN_offset_char0 = 0x01, - LFN_offset_char1 = 0x03, - LFN_offset_char2 = 0x05, - LFN_offset_char3 = 0x07, - LFN_offset_char4 = 0x09, - LFN_offset_flag = 0x0B, // Should be equal to ATTRIB_LFN - LFN_offset_reserved1 = 0x0C, // Always 0x00 - LFN_offset_checkSum = 0x0D, // Checksum of short file name (alias) - LFN_offset_char5 = 0x0E, - LFN_offset_char6 = 0x10, - LFN_offset_char7 = 0x12, - LFN_offset_char8 = 0x14, - LFN_offset_char9 = 0x16, - LFN_offset_char10 = 0x18, - LFN_offset_reserved2 = 0x1A, // Always 0x0000 - LFN_offset_char11 = 0x1C, - LFN_offset_char12 = 0x1E -}; -const int LFN_offset_table[13]={0x01,0x03,0x05,0x07,0x09,0x0E,0x10,0x12,0x14,0x16,0x18,0x1C,0x1E}; - -#define LFN_END 0x40 -#define LFN_DEL 0x80 - -static char* strupr(char* a) -{ - char *str; - - str = a; - while(*str) - { - if(*str >= 'a' && *str <= 'z') *str -= 0x20; - str += 1; - } - - return a; -} - -static char* strlwr(char *a){ - char *str; - - str = a; - while(*str) - { - if((*str) >= 'A' && (*str) <= 'Z') (*str) = ((*str) -'A' + 'a'); - str++; - } - return a; -} - -bool _FAT_directory_isValidLfn (const char* name) { - u32 i; - u32 nameLength; - // Make sure the name is short enough to be valid - if ( strnlen(name, MAX_FILENAME_LENGTH) >= MAX_FILENAME_LENGTH) { - return false; - } - // Make sure it doesn't contain any invalid characters - if (strpbrk (name, "\\/:*?\"<>|") != NULL) { - return false; - } - - nameLength = strnlen(name, MAX_FILENAME_LENGTH); - // Make sure the name doesn't contain any control codes - for (i = 0; i < nameLength; i++) { - if ((unsigned char)name[i] < 0x20) { - return false; - } - } - // Otherwise it is valid - return true; -} -bool _FAT_directory_isValidAlias (const char* name) { - //return false;//disables this function to preserve file name casing - - u32 i; - u32 nameLength; - const char* dot; - - // Make sure the name is short enough to be valid - if ( strnlen(name, MAX_ALIAS_LENGTH) >= MAX_ALIAS_LENGTH) { - return false; - } - // Make sure it doesn't contain any invalid characters - if (strpbrk (name, "\\/:;*?\"<>|&+,=[]") != NULL) { - return false; - } - - // - if (strpbrk (name, " ") != NULL) { - return false; - } - - nameLength = strnlen(name, MAX_ALIAS_LENGTH); - // Make sure the name doesn't contain any control codes - //if name isn't all capitals, then it is not a valid short name - for (i = 0; i < nameLength; i++) { - if (name[i] > 0x5A && name[i]!= 0x20) { - return false; - } - } - - dot = strchr ( name, '.'); - // Make sure there is only one '.' - if ((dot != NULL) && (strrchr ( name, '.') != dot)) { - return false; - } - // If there is a '.': - if (dot != NULL) { - // Make sure the filename portion is 1-8 characters long - if (((dot - 1 - name) > 8) || ((dot - 1 - name) < 1)) { - return false; - } - // Make sure the extension is 1-3 characters long, if it exists - if ((strnlen(dot + 1, MAX_ALIAS_LENGTH) > 3) || (strnlen(dot + 1, MAX_ALIAS_LENGTH) < 1)) { - return false; - } - } else { - // Make sure the entire file name is 1-8 characters long - if ((nameLength > 8) || (nameLength < 1)) { - return false; - } - } - - // Since we made it through all those tests, it must be valid - return true; -} - -static bool _FAT_directory_entryGetAlias (const u8* entryData, char* destName) { - int i=0; - int j=0; - - destName[0] = '\0'; - if (entryData[0] != DIR_ENTRY_FREE) { - if (entryData[0] == '.') { - destName[0] = '.'; - if (entryData[1] == '.') { - destName[1] = '.'; - destName[2] = '\0'; - } else { - destName[1] = '\0'; - } - } else { - // Copy the filename from the dirEntry to the string - for (i = 0; (i < 8) && (entryData[DIR_ENTRY_name + i] != ' '); i++) { - destName[i] = entryData[DIR_ENTRY_name + i]; - } - // Copy the extension from the dirEntry to the string - if (entryData[DIR_ENTRY_extension] != ' ') { - destName[i++] = '.'; - for ( j = 0; (j < 3) && (entryData[DIR_ENTRY_extension + j] != ' '); j++) { - destName[i++] = entryData[DIR_ENTRY_extension + j]; - } - } - destName[i] = '\0'; - } - } - - 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); -} - -static bool _FAT_directory_incrementDirEntryPosition (PARTITION* partition, DIR_ENTRY_POSITION* entryPosition, bool extendDirectory) { - DIR_ENTRY_POSITION position; - position = *entryPosition; - u32 tempCluster; - - // Increment offset, wrapping at the end of a sector - ++ position.offset; - if (position.offset == BYTES_PER_READ / DIR_ENTRY_DATA_SIZE) { - position.offset = 0; - // Increment sector when wrapping - ++ position.sector; - // But wrap at the end of a cluster - if ((position.sector == partition->sectorsPerCluster) && (position.cluster != FAT16_ROOT_DIR_CLUSTER)) { - position.sector = 0; - // Move onto the next cluster, making sure there is another cluster to go to - tempCluster = _FAT_fat_nextCluster(partition, position.cluster); - if (tempCluster == CLUSTER_EOF) { - if (extendDirectory) { - tempCluster = _FAT_fat_linkFreeClusterCleared (partition, position.cluster); - if (tempCluster == CLUSTER_FREE) { - return false; // This will only happen if the disc is full - } - } else { - return false; // Got to the end of the directory, not extending it - } - } - position.cluster = tempCluster; - } else if ((position.cluster == FAT16_ROOT_DIR_CLUSTER) && (position.sector == (partition->dataStart - partition->rootDirStart))) { - return false; // Got to end of root directory, can't extend it - } - } - *entryPosition = position; - return true; -} - -bool _FAT_directory_getNextEntry (PARTITION* partition, DIR_ENTRY* entry) { - DIR_ENTRY_POSITION entryStart; - DIR_ENTRY_POSITION entryEnd; - - u8 entryData[0x20]; - - bool notFound, found; - u32 maxSectors; - int lfnPos; - u8 lfnChkSum, chkSum; - char* filename; - u16 unicodeFilename[256]; - bool lfnExists; - - int i; - - lfnChkSum = 0; - - entryStart = entry->dataEnd; - - // Make sure we are using the correct root directory, in case of FAT32 - if (entryStart.cluster == FAT16_ROOT_DIR_CLUSTER) { - entryStart.cluster = partition->rootDirCluster; - } - - entryEnd = entryStart; - filename = entry->d_name; - //unicodeFilename = entry->unicodeFilename; - memset( unicodeFilename, 0, 512 ); - - // Can only be FAT16_ROOT_DIR_CLUSTER if it is the root directory on a FAT12 or FAT16 partition - if (entryStart.cluster == FAT16_ROOT_DIR_CLUSTER) { - maxSectors = partition->dataStart - partition->rootDirStart; - } else { - maxSectors = partition->sectorsPerCluster; - } - - lfnExists = false; - - found = false; - notFound = false; - - while (!found && !notFound) { - if (_FAT_directory_incrementDirEntryPosition (partition, &entryEnd, false) == false) { - notFound = true; - } - - _FAT_cache_readPartialSector (partition->cache, entryData, _FAT_fat_clusterToSector(partition, entryEnd.cluster) + entryEnd.sector, entryEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - - if (entryData[DIR_ENTRY_attributes] == ATTRIB_LFN) { - // It's an LFN - if (entryData[LFN_offset_ordinal] & LFN_DEL) { - lfnExists = false; - } else if (entryData[LFN_offset_ordinal] & LFN_END) { - // Last part of LFN, make sure it isn't deleted using previous if(Thanks MoonLight) - entryStart = entryEnd; // This is the start of a directory entry - lfnExists = true; - //filename[(entryData[LFN_offset_ordinal] & ~LFN_END) * 13] = '\0'; // Set end of lfn to null character - unicodeFilename[(entryData[LFN_offset_ordinal] & ~LFN_END) * 13] = 0x0000; - lfnChkSum = entryData[LFN_offset_checkSum]; - } if (lfnChkSum != entryData[LFN_offset_checkSum]) { - lfnExists = false; - } - //unicodeFilename[0] = 0x0000; - if (lfnExists) { - lfnPos = ((entryData[LFN_offset_ordinal] & ~LFN_END) - 1) * 13; - for (i = 0; i < 13; i++) { - unicodeFilename[lfnPos + i] = u8array_to_u16( entryData, LFN_offset_table[i]); - // | entryData[LFN_offset_table[i]+1]<<8; // modify this for unicode support; - } - } - } else if (entryData[DIR_ENTRY_attributes] & ATTRIB_VOL) { - // This is a volume name, don't bother with it - } else if (entryData[0] == DIR_ENTRY_LAST) { - notFound = true; - } else if ((entryData[0] != DIR_ENTRY_FREE) && (entryData[0] > 0x20) && !(entryData[DIR_ENTRY_attributes] & ATTRIB_VOL)) { - if (lfnExists) { - // Calculate file checksum - chkSum = 0; - for (i=0; i < 11; i++) { - // NOTE: The operation is an unsigned char rotate right - chkSum = ((chkSum & 1) ? 0x80 : 0) + (chkSum >> 1) + entryData[i]; - } - if (chkSum != lfnChkSum) { - lfnExists = false; - //filename[0] = '\0'; - //unicodeFilename[0] = 0x0000; // move this line to below(1) - } - } - //short name - if (!lfnExists) { - entryStart = entryEnd; - unicodeFilename[0] = 0x0000; // (1)make sure clear previous search junk - // get alias anyway - _FAT_directory_entryGetAlias (entryData, filename); - strlwr(filename);//convert to lowercase characters - } - //long name - else - { - _FAT_unicode16_to_utf8 (unicodeFilename, filename); - } - - found = true; - } - } - - // If no file is found, return false - if (notFound) { - return false; - } else { - // Fill in the directory entry struct - entry->dataStart = entryStart; - entry->dataEnd = entryEnd; - memcpy (entry->entryData, entryData, DIR_ENTRY_DATA_SIZE); - return true; - } -} - -bool _FAT_directory_getFirstEntry (PARTITION* partition, DIR_ENTRY* entry, u32 dirCluster) { - entry->dataStart.cluster = dirCluster; - entry->dataStart.sector = 0; - entry->dataStart.offset = -1; // Start before the beginning of the directory - - entry->dataEnd = entry->dataStart; - - return _FAT_directory_getNextEntry (partition, entry); -} - -bool _FAT_directory_getRootEntry (PARTITION* partition, DIR_ENTRY* entry) { - entry->dataStart.cluster = 0; - entry->dataStart.sector = 0; - entry->dataStart.offset = 0; - - entry->dataEnd = entry->dataStart; - - memset (entry->d_name, '\0', MAX_FILENAME_LENGTH); - entry->d_name[0] = '.'; - - memset (entry->entryData, 0, DIR_ENTRY_DATA_SIZE); - memset (entry->entryData, ' ', 11); - entry->entryData[0] = '.'; - - entry->entryData[DIR_ENTRY_attributes] = ATTRIB_DIR; - - u16_to_u8array (entry->entryData, DIR_ENTRY_cluster, partition->rootDirCluster); - u16_to_u8array (entry->entryData, DIR_ENTRY_clusterHigh, partition->rootDirCluster >> 16); - - return true; -} - -bool _FAT_directory_entryFromPosition (PARTITION* partition, DIR_ENTRY* entry) { - DIR_ENTRY_POSITION entryStart; - DIR_ENTRY_POSITION entryEnd; - entryStart = entry->dataStart; - entryEnd = entry->dataEnd; - bool entryStillValid; - bool finished; - - int i; - int lfnPos; - - u8 entryData[DIR_ENTRY_DATA_SIZE]; - - memset (entry->d_name, '\0', MAX_FILENAME_LENGTH); - - // Create an empty directory entry to overwrite the old ones with - for ( entryStillValid = true, finished = false; - entryStillValid && !finished; - entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &entryStart, false)) - { - _FAT_cache_readPartialSector (partition->cache, entryData, - _FAT_fat_clusterToSector(partition, entryStart.cluster) + entryStart.sector, - entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - - if ((entryStart.cluster == entryEnd.cluster) - && (entryStart.sector == entryEnd.sector) - && (entryStart.offset == entryEnd.offset)) { - // Copy the entry data and stop, since this is the last section of the directory entry - memcpy (entry->entryData, entryData, DIR_ENTRY_DATA_SIZE); - finished = true; - } else { - // Copy the long file name data - lfnPos = ((entryData[LFN_offset_ordinal] & ~LFN_END) - 1) * 13; - for (i = 0; i < 13; i++) { - entry->d_name[lfnPos + i] = entryData[LFN_offset_table[i]]; // modify this for unicode support; - } - } - } - - if (!entryStillValid) { - return false; - } - - if ((entryStart.cluster == entryEnd.cluster) - && (entryStart.sector == entryEnd.sector) - && (entryStart.offset == entryEnd.offset)) { - // Since the entry doesn't have a long file name, extract the short filename - if (!_FAT_directory_entryGetAlias (entry->entryData, entry->d_name)) { - return false; - } - } - - return true; -} - -bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const char* path, const char* pathEnd) { - size_t dirnameLength; - const char* pathPosition; - const char* nextPathPosition; - - //size_t uniDirnameLength; - //u16 uniPath[MAX_FILENAME_LENGTH]; - //const u16 * uniPathPosition; - //const u16 * uniNextPathPosition; - - u32 dirCluster; - bool foundFile; - - //char alias[MAX_ALIAS_LENGTH]; - - bool found, notFound; - - //_FAT_utf8_to_unicode16( path, uniPath ); - pathPosition = path; - //uniPathPosition = uniPath; - - found = false; - notFound = false; - - if (pathEnd == NULL) { - // Set pathEnd to the end of the path string - pathEnd = strchr (path, '\0'); - } - - if (pathPosition[0] == DIR_SEPARATOR) { - // Start at root directory - dirCluster = partition->rootDirCluster; - // Consume separator(s) - while (pathPosition[0] == DIR_SEPARATOR) { - pathPosition++; - } - - //while (uniPathPosition[0] == (unsigned short)DIR_SEPARATOR) { - // uniPathPosition++; - //} - - if (pathPosition >= pathEnd) { - _FAT_directory_getRootEntry (partition, entry); - found = true; - } - } else { - // Start in current working directory - dirCluster = partition->cwdCluster; - } - - // If the path is only specifying a directory in the form "." - // and this is the root directory, return it - //if ((dirCluster == partition->rootDirCluster) && (strncasecmp(".", pathPosition, 2) == 0)) { - if ((dirCluster == partition->rootDirCluster) && strlen(pathPosition) == 1 && (strcasecmp(".", pathPosition) == 0)) { - _FAT_directory_getRootEntry (partition, entry); - found = true; - } - - while (!found && !notFound) { - // Get the name of the next required subdirectory within the path - nextPathPosition = strchr (pathPosition, DIR_SEPARATOR); - //uniNextPathPosition = _unistrchr( uniPathPosition, (unsigned short)DIR_SEPARATOR ); - if (nextPathPosition != NULL) { - dirnameLength = nextPathPosition - pathPosition; - } else { - dirnameLength = strlen(pathPosition); - } - //if (uniNextPathPosition != 0x0000) { - // uniDirnameLength = uniNextPathPosition - uniPathPosition; - //} else { - // uniDirnameLength = _unistrnlen(uniPathPosition, MAX_FILENAME_LENGTH); - //} - - if (dirnameLength > MAX_FILENAME_LENGTH) { - // The path is too long to bother with - return false; - } - //if( uniDirnameLength > MAX_FILENAME_LENGTH ) { - // return false; - //} - - // Look for the directory within the path - foundFile = _FAT_directory_getFirstEntry (partition, entry, dirCluster); - - while (foundFile && !found && !notFound) { // It hasn't already found the file - // Check if the filename matches - //if ((uniDirnameLength == _unistrnlen(entry->unicodeFilename, MAX_FILENAME_LENGTH)) - // && (_unistrncmp(entry->unicodeFilename, uniPathPosition, uniDirnameLength) == 0)) { - // found = true; - //} - - //if(!strncasecmp(entry->d_name, pathPosition, dirnameLength)) - if(strlen(entry->d_name) == dirnameLength && !strncasecmp(entry->d_name, pathPosition, dirnameLength)) - found = true; - - // Check if the alias matches - //_FAT_directory_entryGetAlias (entry->entryData, alias); - //if ((dirnameLength == strnlen(alias, MAX_ALIAS_LENGTH)) - // && (strncasecmp(alias, pathPosition, dirnameLength) == 0)) { - // found = true; - //} - - if (found && !(entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR) && (nextPathPosition != NULL)) { - // Make sure that we aren't trying to follow a file instead of a directory in the path - found = false; - } - - if (!found) { - foundFile = _FAT_directory_getNextEntry (partition, entry); - } - } - - if (!foundFile) { - // Check that the search didn't get to the end of the directory - notFound = true; - found = false; - } else if ((nextPathPosition == NULL) || (nextPathPosition >= pathEnd)) { - // 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); - pathPosition = nextPathPosition; - //uniPathPosition = uniNextPathPosition; - // Consume separator(s) - while (pathPosition[0] == DIR_SEPARATOR) { - pathPosition++; - } - //while (uniPathPosition[0] == (unsigned short)DIR_SEPARATOR) { - // uniPathPosition++; - //} - // The requested directory was found - if (pathPosition >= pathEnd) { - found = true; - } else { - found = false; - } - } - } - - if (found && !notFound) { - return true; - } else { - return false; - } -} - -bool _FAT_directory_removeEntry (PARTITION* partition, DIR_ENTRY* entry) { - DIR_ENTRY_POSITION entryStart; - DIR_ENTRY_POSITION entryEnd; - entryStart = entry->dataStart; - entryEnd = entry->dataEnd; - bool entryStillValid; - bool finished; - - u8 entryData[DIR_ENTRY_DATA_SIZE]; - - // Create an empty directory entry to overwrite the old ones with - for ( entryStillValid = true, finished = false; - entryStillValid && !finished; - entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &entryStart, false)) - { - _FAT_cache_readPartialSector (partition->cache, entryData, _FAT_fat_clusterToSector(partition, entryStart.cluster) + entryStart.sector, entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - entryData[0] = DIR_ENTRY_FREE; - _FAT_cache_writePartialSector (partition->cache, entryData, _FAT_fat_clusterToSector(partition, entryStart.cluster) + entryStart.sector, entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - if ((entryStart.cluster == entryEnd.cluster) && (entryStart.sector == entryEnd.sector) && (entryStart.offset == entryEnd.offset)) { - finished = true; - } - } - - if (!entryStillValid) { - return false; - } - - return true; -} - -static bool _FAT_directory_findEntryGap (PARTITION* partition, DIR_ENTRY* entry, u32 dirCluster, u32 size) { - DIR_ENTRY_POSITION gapStart; - DIR_ENTRY_POSITION gapEnd; - - u8 entryData[DIR_ENTRY_DATA_SIZE]; - - u32 dirEntryRemain; - - bool endOfDirectory, entryStillValid; - - // Scan Dir for free entry - gapEnd.offset = 0; - gapEnd.sector = 0; - gapEnd.cluster = dirCluster; - - gapStart = gapEnd; - - entryStillValid = true; - dirEntryRemain = size; - endOfDirectory = false; - - while (entryStillValid && !endOfDirectory && (dirEntryRemain > 0)) { - _FAT_cache_readPartialSector (partition->cache, entryData, _FAT_fat_clusterToSector(partition, gapEnd.cluster) + gapEnd.sector, gapEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - if (entryData[0] == DIR_ENTRY_LAST) { - gapStart = gapEnd; - -- dirEntryRemain; - endOfDirectory = true; - } else if (entryData[0] == DIR_ENTRY_FREE) { - if (dirEntryRemain == size) { - gapStart = gapEnd; - } - -- dirEntryRemain; - } else { - dirEntryRemain = size; - } - - if (!endOfDirectory && (dirEntryRemain > 0)) { - entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &gapEnd, true); - } - } - - // Make sure the scanning didn't fail - if (!entryStillValid) { - return false; - } - - // Save the start entry, since we know it is valid - entry->dataStart = gapStart; - - if (endOfDirectory) { - memset (entryData, DIR_ENTRY_LAST, DIR_ENTRY_DATA_SIZE); - dirEntryRemain += 1; // Increase by one to take account of End Of Directory Marker - while ((dirEntryRemain > 0) && entryStillValid) { - // Get the gapEnd before incrementing it, so the second to last one is saved - entry->dataEnd = gapEnd; - // Increment gapEnd, moving onto the next entry - entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &gapEnd, true); - -- dirEntryRemain; - // Fill the entry with blanks - _FAT_cache_writePartialSector (partition->cache, entryData, _FAT_fat_clusterToSector(partition, gapEnd.cluster) + gapEnd.sector, gapEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - } - if (!entryStillValid) { - return false; - } - } else { - entry->dataEnd = gapEnd; - } - - return true; -} - -static bool _FAT_directory_entryExists (PARTITION* partition, const char* name, u32 dirCluster) { - DIR_ENTRY tempEntry; - bool foundFile; - //char alias[MAX_ALIAS_LENGTH]; - u32 dirnameLength; - //u16 unicodeName[MAX_FILENAME_LENGTH]; - - dirnameLength = strnlen(name, MAX_FILENAME_LENGTH); - - if (dirnameLength >= MAX_FILENAME_LENGTH) { - return false; - } - - //_FAT_utf8_to_unicode16( name, unicodeName ); - - // Make sure the entry doesn't already exist - foundFile = _FAT_directory_getFirstEntry (partition, &tempEntry, dirCluster); - - while (foundFile) { // It hasn't already found the file - // Check if the filename matches - //if (/*(dirnameLength == _unistrnlen(tempEntry.unicodeFilename, MAX_FILENAME_LENGTH))*/ - // //&& (strcasecmp(tempEntry.filename, name) == 0)) { - // /*&&*/ (_unistrncmp( unicodeName, tempEntry.unicodeFilename, MAX_FILENAME_LENGTH ) == 0 )) - //{ - // return true; - //} - //if(!strncasecmp(name, tempEntry.d_name, dirnameLength)) - if(!strcasecmp(name, tempEntry.d_name)) - return true; - - // Check if the alias matches - //_FAT_directory_entryGetAlias (tempEntry.entryData, alias); - //if ((dirnameLength == strnlen(alias, MAX_ALIAS_LENGTH)) - // && (strcasecmp(alias, name) == 0)) { - // return true; - //} - foundFile = _FAT_directory_getNextEntry (partition, &tempEntry); - } - return false; -} - -//a fix for checking if a short file name is already in use. -static bool _FAT_directory_entryExistsSFN (PARTITION* partition, const char* name, u32 dirCluster) { - DIR_ENTRY tempEntry; - bool foundFile; - char alias[MAX_ALIAS_LENGTH]; - u32 dirnameLength; - - dirnameLength = strnlen(name, MAX_FILENAME_LENGTH); - - if (dirnameLength >= MAX_FILENAME_LENGTH) { - return false; - } - - - // Make sure the entry doesn't already exist - foundFile = _FAT_directory_getFirstEntry (partition, &tempEntry, dirCluster); - - while (foundFile) { // It hasn't already found the file - if(!strcasecmp(name, tempEntry.d_name)) - return true; - - // Check if the alias matches - _FAT_directory_entryGetAlias (tempEntry.entryData, alias); - if ((dirnameLength == strnlen(alias, MAX_ALIAS_LENGTH)) - && (strcasecmp(alias, name) == 0)) { - return true; - } - foundFile = _FAT_directory_getNextEntry (partition, &tempEntry); - } - return false; -} - -bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, u32 dirCluster) { - u32 entrySize; - u8 lfnEntry[DIR_ENTRY_DATA_SIZE]; - s32 i,j; // Must be signed for use when decrementing in for loop - char *tmpCharPtr; - DIR_ENTRY_POSITION curEntryPos; - bool entryStillValid; - u8 aliasCheckSum = 0; - char alias [MAX_ALIAS_LENGTH]; - u16 unicodeFilename[256]; - - // Make sure the filename is not 0 length - if (strnlen (entry->d_name, MAX_FILENAME_LENGTH) < 1) { - return false; - } - // Make sure the filename is at least a valid LFN - if ( !(_FAT_directory_isValidLfn (entry->d_name))) { - return false; - } - - // Remove trailing spaces - for (i = strlen (entry->d_name) - 1; (i > 0) && (entry->d_name[i] == ' '); --i) { - entry->d_name[i] = '\0'; - } - // Remove leading spaces - for (i = 0; (i < strlen (entry->d_name)) && (entry->d_name[i] == ' '); ++i) ; - if (i > 0) { - memmove (entry->d_name, entry->d_name + i, strlen (entry->d_name + i)); - } - - // Remove junk in filename - i = strlen (entry->d_name); - memset (entry->d_name + i, '\0', MAX_FILENAME_LENGTH - i); - - // Make sure the entry doesn't already exist - if (_FAT_directory_entryExists (partition, entry->d_name, dirCluster)) { - return false; - } - - // Clear out alias, so we can generate a new one - memset (entry->entryData, ' ', 11); - - if ( strncmp(entry->d_name, ".", MAX_FILENAME_LENGTH) == 0) { - // "." entry - entry->entryData[0] = '.'; - entrySize = 1; - } else if ( strncmp(entry->d_name, "..", MAX_FILENAME_LENGTH) == 0) { - // ".." entry - entry->entryData[0] = '.'; - entry->entryData[1] = '.'; - entrySize = 1; - }else if (_FAT_directory_isValidAlias (entry->d_name)) { - entrySize = 1; - // Copy into alias - for (i = 0, j = 0; (j < 8) && (entry->d_name[i] != '.') && (entry->d_name[i] != '\0'); i++, j++) { - entry->entryData[j] = entry->d_name[i]; - } - while (j < 8) { - entry->entryData[j] = ' '; - ++ j; - } - if (entry->d_name[i] == '.') { - // Copy extension - ++ i; - while ((entry->d_name[i] != '\0') && (j < 11)) { - entry->entryData[j] = entry->d_name[i]; - ++ i; - ++ j; - } - } - while (j < 11) { - entry->entryData[j] = ' '; - ++ j; - } - // Short filename - strupr (entry->entryData); - }else { - // Long filename needed - //memset( entry->unicodeFilename, 0, 512 ); - //_FAT_utf8_to_unicode16( (const char*)entry->d_name, entry->unicodeFilename ); - memset( unicodeFilename, 0, 512 ); - _FAT_utf8_to_unicode16( (const char*)entry->d_name, unicodeFilename ); - - //entrySize = ((strnlen (entry->filename, MAX_FILENAME_LENGTH) + LFN_ENTRY_LENGTH - 1) / LFN_ENTRY_LENGTH) + 1; - //entrySize = ((_unistrnlen( entry->unicodeFilename, MAX_FILENAME_LENGTH ) + LFN_ENTRY_LENGTH - 1) / LFN_ENTRY_LENGTH) + 1; - entrySize = ((_unistrnlen( unicodeFilename, MAX_FILENAME_LENGTH ) + LFN_ENTRY_LENGTH - 1) / LFN_ENTRY_LENGTH) + 1; - - // Generate alias - tmpCharPtr = strrchr (entry->d_name, '.'); - if (tmpCharPtr == NULL) { - tmpCharPtr = strrchr (entry->d_name, '\0'); - } - for (i = 0, j = 0; (j < 6) && (entry->d_name + i < tmpCharPtr); i++) { - if ( _uniisalnum((u8)(entry->d_name[i]))) { - alias[j] = entry->d_name[i]; - ++ j; - } - } - while (j < 8) { - alias[j] = '_'; - ++ j; - } - tmpCharPtr = strrchr (entry->d_name, '.'); - if (tmpCharPtr != NULL) { - alias[8] = '.'; - // Copy extension - while ((tmpCharPtr != '\0') && (j < 12)) { - alias[j] = tmpCharPtr[0]; - ++ tmpCharPtr; - ++ j; - } - alias[j] = '\0'; - } else { - for (j = 8; j < MAX_ALIAS_LENGTH; j++) { - alias[j] = '\0'; - } - } - - // Get a valid tail number - alias[5] = '~'; - i = 0; - do { - i++; - alias[6] = '0' + ((i / 10) % 10); // 10's digit - alias[7] = '0' + (i % 10); // 1's digit - } while (_FAT_directory_entryExistsSFN (partition, alias, dirCluster) && (i < 100)); - if (i == 100) { - // Couldn't get a tail number - return false; - } - - // Make it upper case - strupr (alias); - - // Now copy it into the directory entry data - memcpy (entry->entryData, alias, 8); - memcpy (entry->entryData + 8, alias + 9, 3); - for (i = 0; i < 10; i++) { - if (entry->entryData[i] < 0x20) { - // Replace null and control characters with spaces - entry->entryData[i] = 0x20; - } - } - // Generate alias checksum - for (i=0; i < 11; i++) - { - // NOTE: The operation is an unsigned char rotate right - aliasCheckSum = ((aliasCheckSum & 1) ? 0x80 : 0) + (aliasCheckSum >> 1) + entry->entryData[i]; - } - - } - - // Find or create space for the entry - if (_FAT_directory_findEntryGap (partition, entry, dirCluster, entrySize) == false) { - return false; - } - - // Write out directory entry - curEntryPos = entry->dataStart; - - for (entryStillValid = true, i = entrySize; entryStillValid && i > 0; - entryStillValid = _FAT_directory_incrementDirEntryPosition (partition, &curEntryPos, false), -- i ) - { - if (i > 1) { - // Long filename entry - lfnEntry[LFN_offset_ordinal] = (i - 1) | (i == entrySize ? LFN_END : 0); - for (j = 0; j < 13; j++) { - //if (entry->unicodeFilename[(i - 2) * 13 + j] == '\0') { - if (unicodeFilename[(i - 2) * 13 + j] == '\0') { - //if ((j > 1) && (entry->unicodeFilename[(i - 2) * 13 + (j-1)] == '\0')) { - if ((j > 1) && (unicodeFilename[(i - 2) * 13 + (j-1)] == '\0')) { - u16_to_u8array (lfnEntry, LFN_offset_table[j], 0xffff); // Padding - } else { - u16_to_u8array (lfnEntry, LFN_offset_table[j], 0x0000); // Terminating null character - } - } else { - //u16_to_u8array (lfnEntry, LFN_offset_table[j], entry->unicodeFilename[(i - 2) * 13 + j]); - u16_to_u8array (lfnEntry, LFN_offset_table[j], unicodeFilename[(i - 2) * 13 + j]); - } - } - - lfnEntry[LFN_offset_checkSum] = aliasCheckSum; - lfnEntry[LFN_offset_flag] = ATTRIB_LFN; - lfnEntry[LFN_offset_reserved1] = 0; - u16_to_u8array (lfnEntry, LFN_offset_reserved2, 0); - _FAT_cache_writePartialSector (partition->cache, lfnEntry, _FAT_fat_clusterToSector(partition, curEntryPos.cluster) + curEntryPos.sector, curEntryPos.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - } else { - // Alias & file data - _FAT_cache_writePartialSector (partition->cache, entry->entryData, _FAT_fat_clusterToSector(partition, curEntryPos.cluster) + curEntryPos.sector, curEntryPos.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE); - } - } - - return true; -} - -bool _FAT_directory_chdir (PARTITION* partition, const char* path) { - DIR_ENTRY entry; - - if (!_FAT_directory_entryFromPath (partition, &entry, path, NULL)) { - return false; - } - - if (!(entry.entryData[DIR_ENTRY_attributes] & ATTRIB_DIR)) { - return false; - } - - partition->cwdCluster = _FAT_directory_entryGetCluster (entry.entryData); - - return true; -} - -void _FAT_directory_entryStat (PARTITION* partition, DIR_ENTRY* entry, struct stat *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_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) | - (_FAT_directory_isHidden (entry) ? S_IHIDDEN : 0); // Mode bits based on dirEntry ATTRIB byte - st->st_nlink = 1; // Always one hard link on a FAT file - st->st_uid = 1; // Faked for FAT - st->st_gid = 2; // Faked for FAT - st->st_rdev = st->st_dev; - st->st_size = u8array_to_u32 (entry->entryData, DIR_ENTRY_fileSize); // File size - st->st_atime = _FAT_filetime_to_time_t ( - 0, - u8array_to_u16 (entry->entryData, DIR_ENTRY_aDate) - ); - //st->st_spare1 = _FAT_directory_isHidden (entry); - st->st_mtime = _FAT_filetime_to_time_t ( - u8array_to_u16 (entry->entryData, DIR_ENTRY_mTime), - u8array_to_u16 (entry->entryData, DIR_ENTRY_mDate) - ); - //st->st_spare2 = 0; - st->st_ctime = _FAT_filetime_to_time_t ( - u8array_to_u16 (entry->entryData, DIR_ENTRY_cTime), - u8array_to_u16 (entry->entryData, DIR_ENTRY_cDate) - ); - //st->st_spare3 = 0; - st->st_blksize = BYTES_PER_READ; // Prefered file I/O block size - st->st_blocks = (st->st_size + BYTES_PER_READ - 1) / BYTES_PER_READ; // File size in blocks -// st->st_spare4[0] = 0; -// st->st_spare4[1] = 0; -} -- cgit v1.2.3