typedef struct sFAT_LFNCacheEnt\r
{\r
int ID;\r
+ // TODO: Handle UTF16 names correctly\r
char Data[256];\r
} tFAT_LFNCacheEnt;\r
/**\r
{\r
char *ret;\r
ENTER("pft sLongFileName", ft, LongFileName);\r
+ //Log_Debug("FAT", "FAT_int_CreateName(ft=%p, LongFileName=%p'%s')", ft, LongFileName);\r
#if USE_LFN\r
if(LongFileName && LongFileName[0] != '\0')\r
{ \r
{\r
#endif\r
ret = (char*) malloc(13);\r
+ if( !ret ) {\r
+ Log_Warning("FAT", "FAT_int_CreateName: malloc(13) failed");\r
+ return NULL;\r
+ }\r
FAT_int_ProperFilename(ret, ft->name);\r
#if USE_LFN\r
}\r
tFAT_VolInfo *disk = Parent->ImplPtr;\r
\r
ENTER("pParent pFT", Parent, Entry);\r
+ LOG("disk = %p", disk);\r
\r
memset(&node, 0, sizeof(tVFS_Node));\r
\r
}\r
#endif\r
\r
-#if USE_LFN\r
-// I should probably more tightly associate the LFN cache with the node\r
-// somehow, maybe by adding a field to tVFS_Node before locking it\r
-// Maybe .Cache or something like that (something that is free'd by the\r
-// Inode_UncacheNode function)\r
- \r
+#if USE_LFN \r
/**\r
* \fn char *FAT_int_GetLFN(tVFS_Node *node)\r
* \brief Return pointer to LFN cache entry\r
tFAT_LFNCache *cache;\r
int i, firstFree;\r
\r
+ Mutex_Acquire( &Node->Lock );\r
+ \r
// TODO: Thread Safety (Lock things)\r
cache = Node->Data;\r
\r
cache->NumEntries = 1;\r
cache->Entries[0].ID = ID;\r
cache->Entries[0].Data[0] = '\0';\r
+ Mutex_Release( &Node->Lock );\r
+ //Log_Debug("FAT", "Return = %p (new)", cache->Entries[0].Data);\r
return cache->Entries[0].Data;\r
}\r
\r
- // Scan for a current entry\r
+ // Scan for this entry\r
firstFree = -1;\r
for( i = 0; i < cache->NumEntries; i++ )\r
{\r
- if( cache->Entries[i].ID == ID )\r
+ if( cache->Entries[i].ID == ID ) {\r
+ Mutex_Release( &Node->Lock );\r
+ //Log_Debug("FAT", "Return = %p (match)", cache->Entries[i].Data);\r
return cache->Entries[i].Data;\r
+ }\r
if( cache->Entries[i].ID == -1 && firstFree == -1 )\r
firstFree = i;\r
}\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
+ Log_Error("FAT", "realloc() fail, unable to allocate %i for LFN cache", i);\r
+ Mutex_Release( &Node->Lock );\r
return NULL;\r
}\r
+ //Log_Debug("FAT", "Realloc (%i)\n", i);\r
cache = Node->Data;\r
i = cache->NumEntries;\r
cache->NumEntries ++;\r
cache->Entries[ i ].ID = ID;\r
cache->Entries[ i ].Data[0] = '\0';\r
\r
- //TODO: Unlock\r
+ Mutex_Release( &Node->Lock );\r
+ //Log_Debug("FAT", "Return = %p (firstFree, i = %i)", cache->Entries[i].Data, i);\r
return cache->Entries[ i ].Data;\r
}\r
\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
+ // > ID + Index gets the corresponding short node\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
+ a = (lfnInfo->id & 0x3F) * 13;\r
\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
+ if(a > 255) return VFS_SKIP;\r
\r
// Append new bytes\r
- lfn[ 0] = lfnInfo->name1[0]; lfn[ 1] = lfnInfo->name1[1];\r
- lfn[ 2] = lfnInfo->name1[2]; lfn[ 3] = lfnInfo->name1[3];\r
- lfn[ 4] = lfnInfo->name1[4]; \r
- lfn[ 5] = lfnInfo->name2[0]; lfn[ 6] = lfnInfo->name2[1];\r
- lfn[ 7] = lfnInfo->name2[2]; lfn[ 8] = lfnInfo->name2[3];\r
- lfn[ 9] = lfnInfo->name2[4]; lfn[10] = lfnInfo->name2[5];\r
- lfn[11] = lfnInfo->name3[0]; lfn[12] = lfnInfo->name3[1];\r
+ lfn[a+ 0] = lfnInfo->name1[0]; lfn[a+ 1] = lfnInfo->name1[1];\r
+ lfn[a+ 2] = lfnInfo->name1[2]; lfn[a+ 3] = lfnInfo->name1[3];\r
+ lfn[a+ 4] = lfnInfo->name1[4]; \r
+ lfn[a+ 5] = lfnInfo->name2[0]; lfn[a+ 6] = lfnInfo->name2[1];\r
+ lfn[a+ 7] = lfnInfo->name2[2]; lfn[a+ 8] = lfnInfo->name2[3];\r
+ lfn[a+ 9] = lfnInfo->name2[4]; lfn[a+10] = lfnInfo->name2[5];\r
+ lfn[a+11] = lfnInfo->name3[0]; lfn[a+12] = lfnInfo->name3[1];\r
LOG("lfn = '%s'", lfn);\r
LEAVE('p', VFS_SKIP);\r
return VFS_SKIP;\r
LEAVE('p', VFS_SKIP);\r
return VFS_SKIP;\r
}\r
- // Ignore . and ..\r
- if(fileinfo[a].name[0] == '.') {\r
+ // Ignore .\r
+ if(fileinfo[a].name[0] == '.' && fileinfo[a].name[1] == ' ') {\r
+ LEAVE('p', VFS_SKIP);\r
+ return VFS_SKIP;\r
+ }\r
+ // and ..\r
+ if(fileinfo[a].name[0] == '.' && fileinfo[a].name[1] == '.' && fileinfo[a].name[2] == ' ') {\r
LEAVE('p', VFS_SKIP);\r
return VFS_SKIP;\r
- } \r
+ }\r
\r
LOG("name='%c%c%c%c%c%c%c%c.%c%c%c'",\r
fileinfo[a].name[0], fileinfo[a].name[1], fileinfo[a].name[2], fileinfo[a].name[3],\r