* \r
* Known Bugs:\r
* - LFN Is buggy in FAT_ReadDir\r
+ * \r
+ * Notes:\r
+ * - There's hard-coded 512 byte sectors everywhere, that needs to be\r
+ * cleaned.\r
+ * - Thread safety is out the window with the write and LFN code\r
*/\r
/**\r
* \todo Implement changing of the parent directory when a file is written to\r
#define DEBUG 0\r
#define VERBOSE 1\r
\r
-#define CACHE_FAT 1 //!< Caches the FAT in memory\r
+#define CACHE_FAT 0 //!< Caches the FAT in memory\r
#define USE_LFN 1 //!< Enables the use of Long File Names\r
-#define SUPPORT_WRITE 0\r
+#define SUPPORT_WRITE 0 //!< Enables write support\r
\r
#include <acess.h>\r
#include <modules.h>\r
\r
// === TYPES ===\r
#if USE_LFN\r
-typedef struct s_lfncache\r
+/**\r
+ * \brief Long-Filename cache entry\r
+ */\r
+typedef struct sFAT_LFNCacheEnt\r
+{\r
+ int ID;\r
+ char Data[256];\r
+} tFAT_LFNCacheEnt;\r
+/**\r
+ * \brief Long-Filename cache\r
+ */\r
+typedef struct sFAT_LFNCache\r
{\r
- Uint Inode;\r
- tFAT_VolInfo *Disk;\r
- int id;\r
- char Name[256];\r
- struct s_lfncache *Next;\r
-} t_lfncache;\r
+ int NumEntries;\r
+ tFAT_LFNCacheEnt Entries[];\r
+} tFAT_LFNCache;\r
#endif\r
\r
// === PROTOTYPES ===\r
+// --- Driver Core\r
int FAT_Install(char **Arguments);\r
tVFS_Node *FAT_InitDevice(char *device, char **options);\r
void FAT_Unmount(tVFS_Node *Node);\r
-\r
+// --- Helpers\r
+ int FAT_int_GetAddress(tVFS_Node *Node, Uint64 Offset, Uint64 *Addr, Uint32 *Cluster);\r
Uint32 FAT_int_GetFatValue(tFAT_VolInfo *Disk, Uint32 Cluster);\r
+#if SUPPORT_WRITE\r
Uint32 FAT_int_AllocateCluster(tFAT_VolInfo *Disk, Uint32 Previous);\r
-\r
+Uint32 FAT_int_FreeCluster(tFAT_VolInfo *Disk, Uint32 Cluster);\r
+#endif\r
void FAT_int_ReadCluster(tFAT_VolInfo *Disk, Uint32 Cluster, int Length, void *Buffer);\r
+// --- File IO\r
Uint64 FAT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);\r
#if SUPPORT_WRITE\r
void FAT_int_WriteCluster(tFAT_VolInfo *Disk, Uint32 Cluster, void *Buffer);\r
Uint64 FAT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);\r
#endif\r
-\r
+// --- Directory IO\r
char *FAT_ReadDir(tVFS_Node *Node, int ID);\r
tVFS_Node *FAT_FindDir(tVFS_Node *Node, char *Name);\r
+#if SUPPORT_WRITE\r
int FAT_Mknod(tVFS_Node *Node, char *Name, Uint Flags);\r
int FAT_Relink(tVFS_Node *node, char *OldName, char *NewName);\r
+#endif\r
void FAT_CloseFile(tVFS_Node *node);\r
\r
// === Options ===\r
MODULE_DEFINE(0, (0<<8)|50 /*v0.50*/, VFAT, FAT_Install, NULL, NULL);\r
tFAT_VolInfo gFAT_Disks[8];\r
int giFAT_PartCount = 0;\r
-#if USE_LFN\r
-t_lfncache *fat_lfncache;\r
-#endif\r
tVFS_Driver gFAT_FSInfo = {"fat", 0, FAT_InitDevice, FAT_Unmount, NULL};\r
\r
// === CODE ===\r
/**\r
* \fn int FAT_Install(char **Arguments)\r
- * \brief \r
+ * \brief Install the FAT Driver\r
*/\r
int FAT_Install(char **Arguments)\r
{\r
// Temporary Pointer\r
bs = &diskInfo->bootsect;\r
\r
- //Open device and read boot sector\r
+ // Open device and read boot sector\r
diskInfo->fileHandle = VFS_Open(Device, VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE);\r
if(diskInfo->fileHandle == -1) {\r
Log_Notice("FAT", "Unable to open device '%s'", Device);\r
}\r
if(Cluster) *Cluster = cluster;\r
}\r
+ else {\r
+ // Increment by clusters in offset\r
+ cluster += Offset / disk->BytesPerCluster;\r
+ }\r
\r
LOG("cluster = %08x", cluster);\r
\r
addr = disk->firstDataSect * disk->bootsect.bps;\r
addr += (cluster - 2) * disk->BytesPerCluster;\r
}\r
+ // In-cluster offset\r
addr += Offset % disk->BytesPerCluster;\r
\r
LOG("addr = 0x%08x", addr);\r
#endif\r
ofs = Disk->bootsect.resvSectCount*512;\r
if(Disk->type == FAT12) {\r
- VFS_ReadAt(Disk->fileHandle, ofs+(cluster>>1)*3, 3, &val);\r
- val = (cluster&1 ? val&0xFFF : val>>12);\r
+ VFS_ReadAt(Disk->fileHandle, ofs+(cluster/2)*3, 3, &val);\r
+ val = (cluster & 1 ? val>>12 : val & 0xFFF);\r
if(val == EOC_FAT12) val = -1;\r
} else if(Disk->type == FAT16) {\r
VFS_ReadAt(Disk->fileHandle, ofs+cluster*2, 2, &val);\r
*/\r
/**\r
* \brief Read a cluster\r
+ * \param Disk Disk (Volume) to read from\r
+ * \param Length Length to read\r
+ * \param Buffer Destination for read data\r
*/\r
void FAT_int_ReadCluster(tFAT_VolInfo *Disk, Uint32 Cluster, int Length, void *Buffer)\r
{\r
ENTER("pDisk xCluster iLength pBuffer", Disk, Cluster, Length, Buffer);\r
- //Log("Cluster = %i (0x%x)", Cluster, Cluster);\r
VFS_ReadAt(\r
Disk->fileHandle,\r
(Disk->firstDataSect + (Cluster-2)*Disk->bootsect.spc )\r
* \fn Uint64 FAT_Read(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer)\r
* \brief Reads data from a specified file\r
*/\r
-Uint64 FAT_Read(tVFS_Node *Node, Uint64 offset, Uint64 length, void *buffer)\r
+Uint64 FAT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
{\r
int preSkip, count;\r
int i, cluster, pos;\r
void *tmpBuf;\r
tFAT_VolInfo *disk = Node->ImplPtr;\r
\r
- ENTER("pNode Xoffset Xlength pbuffer", Node, offset, length, buffer);\r
+ ENTER("pNode Xoffset Xlength pbuffer", Node, Offset, Length, Buffer);\r
+ \r
+ // Sanity Check offset\r
+ if(Offset > Node->Size) {\r
+ LOG("Reading past EOF (%i > %i)", Offset, Node->Size);\r
+ LEAVE('i', 0);\r
+ return 0;\r
+ }\r
\r
// Calculate and Allocate Bytes Per Cluster\r
bpc = disk->BytesPerCluster;\r
tmpBuf = (void*) malloc(bpc);\r
if( !tmpBuf ) return 0;\r
\r
- // Cluster is stored in Inode Field\r
+ // Cluster is stored in the low 32-bits of the Inode field\r
cluster = Node->Inode & 0xFFFFFFFF;\r
\r
- // Sanity Check offset\r
- if(offset > Node->Size) {\r
- LOG("Reading past EOF (%i > %i)", offset, Node->Size);\r
- LEAVE('i', 0);\r
- return 0;\r
- }\r
// Clamp Size\r
- if(offset + length > Node->Size) {\r
+ if(Offset + Length > Node->Size) {\r
LOG("Reading past EOF (%lli + %lli > %lli), clamped to %lli",\r
- offset, length, Node->Size, Node->Size - offset);\r
- length = Node->Size - offset;\r
+ Offset, Length, Node->Size, Node->Size - Offset);\r
+ Length = Node->Size - Offset;\r
}\r
\r
- // Single Cluster including offset\r
- if(length + offset < bpc)\r
+ // Reading from within the first cluster only?\r
+ if(Offset + Length < bpc)\r
{\r
+ LOG("First cluster only");\r
FAT_int_ReadCluster(disk, cluster, bpc, tmpBuf);\r
- memcpy( buffer, (void*)( tmpBuf + offset%bpc ), length );\r
+ memcpy( Buffer, (void*)( tmpBuf + Offset%bpc ), Length );\r
free(tmpBuf);\r
+ #if DEBUG\r
+ //Debug_HexDump("FAT_Read", Buffer, Length);\r
+ #endif\r
LEAVE('i', 1);\r
- return length;\r
- }\r
- \r
- #if 0\r
- if( FAT_int_GetAddress(Node, offset, &addr) )\r
- {\r
- Log_Warning("FAT", "Offset is past end of cluster chain mark");\r
- LEAVE('i', 0);\r
- return 0;\r
+ return Length;\r
}\r
- #endif\r
- \r
- preSkip = offset / bpc;\r
\r
- //Skip previous clusters\r
- for(i=preSkip;i--;) {\r
+ // Skip previous clusters\r
+ preSkip = Offset / bpc;\r
+ for(i = preSkip; i--; ) {\r
cluster = FAT_int_GetFatValue(disk, cluster);\r
if(cluster == -1) {\r
Log_Warning("FAT", "Offset is past end of cluster chain mark");\r
+ free(tmpBuf);\r
LEAVE('i', 0);\r
return 0;\r
}\r
}\r
\r
// Get Count of Clusters to read\r
- count = ((offset%bpc+length) / bpc) + 1;\r
+ count = ((Offset%bpc + Length) / bpc) + 1;\r
\r
// Get buffer Position after 1st cluster\r
- pos = bpc - offset%bpc;\r
- \r
- // Read 1st Cluster\r
- FAT_int_ReadCluster(disk, cluster, bpc, tmpBuf);\r
- memcpy(\r
- buffer,\r
- (void*)( tmpBuf + (bpc-pos) ),\r
- (pos < length ? pos : length)\r
- );\r
+ pos = bpc - Offset%bpc;\r
\r
- if (count == 1) {\r
+ // Read 1st Cluster (performs alignment for us)\r
+ if( pos == bpc && Length >= bpc ) {\r
+ FAT_int_ReadCluster(disk, cluster, bpc, Buffer);\r
+ }\r
+ else {\r
+ FAT_int_ReadCluster(disk, cluster, bpc, tmpBuf);\r
+ memcpy(\r
+ Buffer,\r
+ (void*)( tmpBuf + (bpc-pos) ),\r
+ (pos < Length ? pos : Length)\r
+ );\r
+ }\r
+ \r
+ // Simple return\r
+ if( count == 1 ) {\r
+ #if DEBUG\r
+ //Debug_HexDump("FAT_Read", Buffer, Length);\r
+ #endif\r
free(tmpBuf);\r
LEAVE('i', 1);\r
- return length;\r
+ return Length;\r
}\r
\r
- cluster = FAT_int_GetFatValue(disk, cluster);\r
- \r
#if DEBUG\r
LOG("pos = %i", pos);\r
LOG("Reading the rest of the clusters");\r
#endif\r
\r
- \r
// Read the rest of the cluster data\r
for( i = 1; i < count-1; i++ )\r
{\r
- FAT_int_ReadCluster(disk, cluster, bpc, tmpBuf);\r
- memcpy((void*)(buffer+pos), tmpBuf, bpc);\r
- pos += bpc;\r
+ // Get next cluster in the chain\r
cluster = FAT_int_GetFatValue(disk, cluster);\r
if(cluster == -1) {\r
Warning("FAT_Read - Read past End of Cluster Chain");\r
LEAVE('i', 0);\r
return 0;\r
}\r
+ // Read cluster\r
+ FAT_int_ReadCluster(disk, cluster, bpc, (void*)(Buffer+pos));\r
+ pos += bpc;\r
}\r
\r
- FAT_int_ReadCluster(disk, cluster, bpc, tmpBuf);\r
- memcpy((void*)(buffer+pos), tmpBuf, length-pos);\r
+ // Get next cluster in the chain\r
+ cluster = FAT_int_GetFatValue(disk, cluster);\r
+ if(cluster == -1) {\r
+ Warning("FAT_Read - Read past End of Cluster Chain");\r
+ free(tmpBuf);\r
+ LEAVE('i', 0);\r
+ return 0;\r
+ }\r
+ \r
+ // Read final cluster\r
+ if( Length - pos == bpc )\r
+ {\r
+ FAT_int_ReadCluster( disk, cluster, bpc, (void*)(Buffer+pos) );\r
+ }\r
+ else {\r
+ FAT_int_ReadCluster( disk, cluster, bpc, tmpBuf );\r
+ memcpy( (void*)(Buffer+pos), tmpBuf, Length-pos );\r
+ }\r
\r
#if DEBUG\r
LOG("Free tmpBuf(0x%x) and Return", tmpBuf);\r
+ //Debug_HexDump("FAT_Read", Buffer, Length);\r
#endif\r
\r
free(tmpBuf);\r
- LEAVE('X', length);\r
- return length;\r
+ LEAVE('X', Length);\r
+ return Length;\r
}\r
\r
#if SUPPORT_WRITE\r
* ====================\r
*/\r
/**\r
- * \fn void FAT_int_ProperFilename(char *dest, char *src)\r
* \brief Converts a FAT directory entry name into a proper filename\r
+ * \param dest Destination array (must be at least 13 bytes in size)\r
+ * \param src 8.3 filename (concatenated, e.g 'FILE1 TXT')\r
*/\r
-void FAT_int_ProperFilename(char *dest, char *src)\r
+void FAT_int_ProperFilename(char *dest, const char *src)\r
{\r
- int a, b;\r
+ int inpos, outpos;\r
\r
- for( a = 0; a < 8; a++) {\r
- if(src[a] == ' ') break;\r
- dest[a] = src[a];\r
+ // Name\r
+ outpos = 0;\r
+ for( inpos = 0; inpos < 8; inpos++ ) {\r
+ if(src[inpos] == ' ') break;\r
+ dest[outpos++] = src[inpos];\r
}\r
- b = a;\r
- a = 8;\r
+ inpos = 8;\r
+ // Check for empty extensions\r
if(src[8] != ' ')\r
- dest[b++] = '.';\r
- for( ; a < 11; a++, b++) {\r
- if(src[a] == ' ') break;\r
- dest[b] = src[a];\r
+ {\r
+ dest[outpos++] = '.';\r
+ for( ; inpos < 11; inpos++) {\r
+ if(src[inpos] == ' ') break;\r
+ dest[outpos++] = src[inpos];\r
+ }\r
}\r
- dest[b] = '\0';\r
- #if DEBUG\r
+ dest[outpos++] = '\0';\r
+ \r
//LOG("dest='%s'", dest);\r
- #endif\r
}\r
\r
/**\r
* \fn char *FAT_int_CreateName(fat_filetable *ft, char *LongFileName)\r
* \brief Converts either a LFN or a 8.3 Name into a proper name\r
+ * \param ft Pointer to the file's entry in the parent directory\r
+ * \param LongFileName Long file name pointer\r
+ * \return Filename as a heap string\r
*/\r
char *FAT_int_CreateName(fat_filetable *ft, char *LongFileName)\r
{\r
{\r
#endif\r
ret = (char*) malloc(13);\r
- memset(ret, 13, '\0');\r
FAT_int_ProperFilename(ret, ft->name);\r
#if USE_LFN\r
}\r
}\r
\r
/**\r
- * \fn tVFS_Node *FAT_int_CreateNode(tVFS_Node *parent, fat_filetable *ft)\r
* \brief Creates a tVFS_Node structure for a given file entry\r
+ * \param Parent Parent directory VFS node\r
+ * \param Entry File table entry for the new node\r
+ * \param Pos Position in the parent of the new node\r
*/\r
tVFS_Node *FAT_int_CreateNode(tVFS_Node *Parent, fat_filetable *Entry, int Pos)\r
{\r
ENTER("pParent pFT", Parent, Entry);\r
\r
// Set Other Data\r
+ // 0-31: Cluster, 32-63: Parent Cluster\r
node.Inode = Entry->cluster | (Entry->clusterHi<<16) | (Parent->Inode << 32);\r
LOG("node.Inode = %llx", node.Inode);\r
+ // Position in parent directory\r
node.ImplInt = Pos & 0xFFFF;\r
+ // Disk Pointer\r
node.ImplPtr = disk;\r
node.Size = Entry->size;\r
LOG("Entry->size = %i", Entry->size);\r
+ // root:root\r
node.UID = 0; node.GID = 0;\r
node.NumACLs = 1;\r
\r
node.ACLs = &gVFS_ACL_EveryoneRWX; // RWXRWXRWX\r
}\r
\r
+ // Create timestamps\r
node.ATime = timestamp(0,0,0,\r
((Entry->adate&0x1F) - 1), // Days\r
((Entry->adate&0x1E0) - 1), // Months\r
1980+((Entry->mdate&0xFF00)>>8) // Years\r
);\r
\r
+ // Set pointers\r
if(node.Flags & VFS_FFLAG_DIRECTORY) {\r
//Log_Debug("FAT", "Directory %08x has size 0x%x", node.Inode, node.Size);\r
node.ReadDir = FAT_ReadDir;\r
node.Relink = FAT_Relink;\r
#endif\r
node.Size = -1;\r
- } else {\r
+ }\r
+ else {\r
node.Read = FAT_Read;\r
#if SUPPORT_WRITE\r
node.Write = FAT_Write;\r
return ret;\r
}\r
\r
-/* ====================\r
+/* \r
+ * ====================\r
* Directory IO\r
* ====================\r
*/\r
\r
/**\r
* \brief Reads a sector from the disk\r
+ * \param Node Directory node to read\r
+ * \param Sector Sector number in the directory to read\r
+ * \param Buffer Destination buffer for the read data\r
*/\r
int FAT_int_ReadDirSector(tVFS_Node *Node, int Sector, fat_filetable *Buffer)\r
{\r
\r
ENTER("pNode iSector pEntry", Node, Sector, Buffer);\r
\r
+ // Parse address\r
if(FAT_int_GetAddress(Node, Sector * 512, &addr, NULL))\r
{\r
LEAVE('i', 1);\r
/**\r
* \brief Writes an entry to the disk\r
* \todo Support expanding a directory\r
+ * \param Node Directory node\r
+ * \param ID ID of entry to update\r
+ * \param Entry Entry data\r
* \return Zero on success, non-zero on error\r
*/\r
int FAT_int_WriteDirEntry(tVFS_Node *Node, int ID, fat_filetable *Entry)\r
/**\r
* \fn char *FAT_int_GetLFN(tVFS_Node *node)\r
* \brief Return pointer to LFN cache entry\r
+ * \param Node Directory node\r
+ * \param ID ID of the short name\r
+ * \return Pointer to the LFN cache entry\r
*/\r
-char *FAT_int_GetLFN(tVFS_Node *node)\r
+char *FAT_int_GetLFN(tVFS_Node *Node, int ID)\r
{\r
- t_lfncache *tmp;\r
- tmp = fat_lfncache;\r
- while(tmp)\r
+ tFAT_LFNCache *cache;\r
+ int i, firstFree;\r
+ \r
+ // TODO: Thread Safety (Lock things)\r
+ cache = Node->Data;\r
+ \r
+ // Create a cache if it isn't there\r
+ if(!cache) {\r
+ cache = Node->Data = malloc( sizeof(tFAT_LFNCache) + sizeof(tFAT_LFNCacheEnt) );\r
+ cache->NumEntries = 1;\r
+ cache->Entries[0].ID = ID;\r
+ cache->Entries[0].Data[0] = '\0';\r
+ return cache->Entries[0].Data;\r
+ }\r
+ \r
+ // Scan for a current entry\r
+ firstFree = -1;\r
+ for( i = 0; i < cache->NumEntries; i++ )\r
{\r
- if(tmp->Inode == node->Inode && tmp->Disk == node->ImplPtr)\r
- return tmp->Name;\r
- tmp = tmp->Next;\r
+ if( cache->Entries[i].ID == ID )\r
+ return cache->Entries[i].Data;\r
+ if( cache->Entries[i].ID == -1 && firstFree == -1 )\r
+ firstFree = i;\r
+ }\r
+ \r
+ if(firstFree == -1) {\r
+ // Use `i` for temp length\r
+ i = sizeof(tFAT_LFNCache) + (cache->NumEntries+1)*sizeof(tFAT_LFNCacheEnt);\r
+ Node->Data = realloc( Node->Data, i );\r
+ if( !Node->Data ) {\r
+ Log_Error("FAT", "malloc() fail, unable to allocate %i for LFN cache", i);\r
+ return NULL;\r
+ }\r
+ cache = Node->Data;\r
+ i = cache->NumEntries;\r
+ cache->NumEntries ++;\r
+ }\r
+ else {\r
+ i = firstFree;\r
}\r
- tmp = malloc(sizeof(t_lfncache));\r
- tmp->Inode = node->Inode;\r
- tmp->Disk = node->ImplPtr;\r
- memset(tmp->Name, 0, 256);\r
\r
- tmp->Next = fat_lfncache;\r
- fat_lfncache = tmp;\r
+ // Create new entry\r
+ cache->Entries[ i ].ID = ID;\r
+ cache->Entries[ i ].Data[0] = '\0';\r
\r
- return tmp->Name;\r
+ //TODO: Unlock\r
+ return cache->Entries[ i ].Data;\r
}\r
\r
/**\r
* \fn void FAT_int_DelLFN(tVFS_Node *node)\r
* \brief Delete a LFN cache entry\r
+ * \param Node Directory node\r
+ * \param ID File Entry ID\r
*/\r
-void FAT_int_DelLFN(tVFS_Node *node)\r
+void FAT_int_DelLFN(tVFS_Node *Node, int ID)\r
{\r
- t_lfncache *tmp;\r
+ tFAT_LFNCache *cache = Node->Data;\r
+ int i;\r
\r
- if(!fat_lfncache) return;\r
+ // Fast return\r
+ if(!cache) return;\r
\r
- if(!fat_lfncache->Next)\r
+ // Scan for a current entry\r
+ for( i = 0; i < cache->NumEntries; i++ )\r
{\r
- tmp = fat_lfncache;\r
- fat_lfncache = tmp->Next;\r
- free(tmp);\r
- return;\r
- }\r
- tmp = fat_lfncache;\r
- while(tmp && tmp->Next)\r
- {\r
- if(tmp->Inode == node->Inode && tmp->Disk == node->ImplPtr)\r
- {\r
- free(tmp->Next);\r
- tmp->Next = tmp->Next->Next;\r
- return;\r
- }\r
- tmp = tmp->Next;\r
+ if( cache->Entries[i].ID == ID )\r
+ cache->Entries[i].ID = -1;\r
}\r
+ return ;\r
}\r
#endif\r
\r
* \fn char *FAT_ReadDir(tVFS_Node *Node, int ID)\r
* \param Node Node structure of directory\r
* \param ID Directory position\r
+ * \return Filename as a heap string, NULL or VFS_SKIP\r
*/\r
char *FAT_ReadDir(tVFS_Node *Node, int ID)\r
{\r
- fat_filetable fileinfo[16]; //Sizeof=32, 16 per sector\r
- int a=0;\r
+ fat_filetable fileinfo[16]; // sizeof(fat_filetable)=32, so 16 per sector\r
+ int a = 0;\r
char *ret;\r
#if USE_LFN\r
char *lfn = NULL;\r
\r
#if USE_LFN\r
// Get Long File Name Cache\r
- lfn = FAT_int_GetLFN(Node);\r
if(fileinfo[a].attrib == ATTR_LFN)\r
{\r
fat_longfilename *lfnInfo;\r
int len;\r
\r
lfnInfo = (fat_longfilename *) &fileinfo[a];\r
+ \r
+ // Get cache for corresponding file\r
+ lfn = FAT_int_GetLFN( Node, ID + (lfnInfo->id & 0x3F) );\r
+ \r
+ // Bit 6 indicates the start of an entry\r
if(lfnInfo->id & 0x40) memset(lfn, 0, 256);\r
+ \r
// Get the current length\r
len = strlen(lfn);\r
\r
- // Sanity Check (FAT implementations should not allow >255 bytes)\r
+ // Sanity Check (FAT implementations should not allow >255 character names)\r
if(len + 13 > 255) return VFS_SKIP;\r
// Rebase all bytes\r
for(a=len+1;a--;) lfn[a+13] = lfn[a];\r
}\r
#endif\r
\r
- //Check if it is a volume entry\r
+ // Check if it is a volume entry\r
if(fileinfo[a].attrib & 0x08) {\r
LEAVE('p', VFS_SKIP);\r
return VFS_SKIP;\r
fileinfo[a].name[8], fileinfo[a].name[9], fileinfo[a].name[10] );\r
\r
#if USE_LFN\r
+ lfn = FAT_int_GetLFN(Node, ID);\r
ret = FAT_int_CreateName(&fileinfo[a], lfn);\r
- lfn[0] = '\0';\r
#else\r
ret = FAT_int_CreateName(&fileinfo[a], NULL);\r
#endif\r
\r
#if USE_LFN\r
// Long File Name Entry\r
- if(fileinfo[i&0xF].attrib == ATTR_LFN)\r
+ if(fileinfo[i & 0xF].attrib == ATTR_LFN)\r
{\r
lfnInfo = (fat_longfilename *) &fileinfo[i&0xF];\r
if(lfnInfo->id & 0x40) {\r
#if SUPPORT_WRITE\r
// Update the node if it's dirty (don't bother if it's marked for\r
// deletion)\r
- if( Node->ImplInt & FAT_FLAG_DIRTY && !(Node->ImplInt & FAT_FLAG_DELETE) )\r
+ if( (Node->ImplInt & FAT_FLAG_DIRTY) && !(Node->ImplInt & FAT_FLAG_DELETE) )\r
{\r
tFAT_VolInfo buf[16];\r
tFAT_VolInfo *ft = &buf[ (Node->ImplInt & 0xFFFF) % 16 ];\r
// TODO: Make this more thread safe somehow, probably by moving the\r
// Inode_UncacheNode higher up and saving the cluster value somewhere\r
if( Node->ReferenceCount == 1 )\r
- {\r
- // Delete LFN Cache\r
- #if USE_LFN\r
- if( Node->Flags & VFS_FFLAG_DIRECTORY)\r
- FAT_int_DelLFN(Node);\r
- #endif\r
- \r
+ { \r
#if SUPPORT_WRITE\r
// Delete File\r
if( Node->ImplInt & FAT_FLAG_DELETE ) {\r