X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2FFilesystems%2FFAT%2Ffat.c;h=936ca4a6f183f310f9a6780f5969e810e9b7caec;hb=fe2794b4f932c0755674493b6a6da4b60a5c2433;hp=a63bac016e2ba22b5794f90e06fde35a0e9b9dca;hpb=b0ab9997c3256041087483c0840247821bfa55c8;p=tpg%2Facess2.git diff --git a/Modules/Filesystems/FAT/fat.c b/Modules/Filesystems/FAT/fat.c index a63bac01..936ca4a6 100644 --- a/Modules/Filesystems/FAT/fat.c +++ b/Modules/Filesystems/FAT/fat.c @@ -17,7 +17,7 @@ * \todo Implement changing of the parent directory when a file is written to * \todo Implement file creation / deletion */ -#define DEBUG 1 +#define DEBUG 0 #define VERBOSE 1 #define CACHE_FAT 0 //!< Caches the FAT in memory @@ -40,6 +40,7 @@ typedef struct sFAT_LFNCacheEnt { int ID; + // TODO: Handle UTF16 names correctly char Data[256]; } tFAT_LFNCacheEnt; /** @@ -55,7 +56,7 @@ typedef struct sFAT_LFNCache // === PROTOTYPES === // --- Driver Core int FAT_Install(char **Arguments); -tVFS_Node *FAT_InitDevice(char *device, char **options); +tVFS_Node *FAT_InitDevice(const char *device, const char **options); void FAT_Unmount(tVFS_Node *Node); // --- Helpers int FAT_int_GetAddress(tVFS_Node *Node, Uint64 Offset, Uint64 *Addr, Uint32 *Cluster); @@ -101,10 +102,9 @@ int FAT_Install(char **Arguments) } /** - * \fn tVFS_Node *FAT_InitDevice(char *Device, char **Options) * \brief Reads the boot sector of a disk and prepares the structures for it */ -tVFS_Node *FAT_InitDevice(char *Device, char **Options) +tVFS_Node *FAT_InitDevice(const char *Device, const char **Options) { fat_bootsect *bs; int i; @@ -911,6 +911,7 @@ char *FAT_int_CreateName(fat_filetable *ft, char *LongFileName) { char *ret; ENTER("pft sLongFileName", ft, LongFileName); + //Log_Debug("FAT", "FAT_int_CreateName(ft=%p, LongFileName=%p'%s')", ft, LongFileName); #if USE_LFN if(LongFileName && LongFileName[0] != '\0') { @@ -920,6 +921,10 @@ char *FAT_int_CreateName(fat_filetable *ft, char *LongFileName) { #endif ret = (char*) malloc(13); + if( !ret ) { + Log_Warning("FAT", "FAT_int_CreateName: malloc(13) failed"); + return NULL; + } FAT_int_ProperFilename(ret, ft->name); #if USE_LFN } @@ -941,7 +946,7 @@ tVFS_Node *FAT_int_CreateNode(tVFS_Node *Parent, fat_filetable *Entry, int Pos) tFAT_VolInfo *disk = Parent->ImplPtr; ENTER("pParent pFT", Parent, Entry); - LOG("disk = %p\n", disk); + LOG("disk = %p", disk); memset(&node, 0, sizeof(tVFS_Node)); @@ -1099,12 +1104,7 @@ int FAT_int_WriteDirEntry(tVFS_Node *Node, int ID, fat_filetable *Entry) } #endif -#if USE_LFN -// I should probably more tightly associate the LFN cache with the node -// somehow, maybe by adding a field to tVFS_Node before locking it -// Maybe .Cache or something like that (something that is free'd by the -// Inode_UncacheNode function) - +#if USE_LFN /** * \fn char *FAT_int_GetLFN(tVFS_Node *node) * \brief Return pointer to LFN cache entry @@ -1117,6 +1117,8 @@ char *FAT_int_GetLFN(tVFS_Node *Node, int ID) tFAT_LFNCache *cache; int i, firstFree; + Mutex_Acquire( &Node->Lock ); + // TODO: Thread Safety (Lock things) cache = Node->Data; @@ -1126,15 +1128,20 @@ char *FAT_int_GetLFN(tVFS_Node *Node, int ID) cache->NumEntries = 1; cache->Entries[0].ID = ID; cache->Entries[0].Data[0] = '\0'; + Mutex_Release( &Node->Lock ); + //Log_Debug("FAT", "Return = %p (new)", cache->Entries[0].Data); return cache->Entries[0].Data; } - // Scan for a current entry + // Scan for this entry firstFree = -1; for( i = 0; i < cache->NumEntries; i++ ) { - if( cache->Entries[i].ID == ID ) + if( cache->Entries[i].ID == ID ) { + Mutex_Release( &Node->Lock ); + //Log_Debug("FAT", "Return = %p (match)", cache->Entries[i].Data); return cache->Entries[i].Data; + } if( cache->Entries[i].ID == -1 && firstFree == -1 ) firstFree = i; } @@ -1144,9 +1151,11 @@ char *FAT_int_GetLFN(tVFS_Node *Node, int ID) i = sizeof(tFAT_LFNCache) + (cache->NumEntries+1)*sizeof(tFAT_LFNCacheEnt); Node->Data = realloc( Node->Data, i ); if( !Node->Data ) { - Log_Error("FAT", "malloc() fail, unable to allocate %i for LFN cache", i); + Log_Error("FAT", "realloc() fail, unable to allocate %i for LFN cache", i); + Mutex_Release( &Node->Lock ); return NULL; } + //Log_Debug("FAT", "Realloc (%i)\n", i); cache = Node->Data; i = cache->NumEntries; cache->NumEntries ++; @@ -1159,7 +1168,8 @@ char *FAT_int_GetLFN(tVFS_Node *Node, int ID) cache->Entries[ i ].ID = ID; cache->Entries[ i ].Data[0] = '\0'; - //TODO: Unlock + Mutex_Release( &Node->Lock ); + //Log_Debug("FAT", "Return = %p (firstFree, i = %i)", cache->Entries[i].Data, i); return cache->Entries[ i ].Data; } @@ -1241,33 +1251,32 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID) if(fileinfo[a].attrib == ATTR_LFN) { fat_longfilename *lfnInfo; - int len; lfnInfo = (fat_longfilename *) &fileinfo[a]; // Get cache for corresponding file + // > ID + Index gets the corresponding short node lfn = FAT_int_GetLFN( Node, ID + (lfnInfo->id & 0x3F) ); // Bit 6 indicates the start of an entry if(lfnInfo->id & 0x40) memset(lfn, 0, 256); - // Get the current length - len = strlen(lfn); + a = ((lfnInfo->id & 0x3F) - 1) * 13; + //Log_Debug("FAT", "ID = 0x%02x, a = %i", lfnInfo->id, a); // Sanity Check (FAT implementations should not allow >255 character names) - if(len + 13 > 255) return VFS_SKIP; - // Rebase all bytes - for(a=len+1;a--;) lfn[a+13] = lfn[a]; + if(a > 255) return VFS_SKIP; // Append new bytes - lfn[ 0] = lfnInfo->name1[0]; lfn[ 1] = lfnInfo->name1[1]; - lfn[ 2] = lfnInfo->name1[2]; lfn[ 3] = lfnInfo->name1[3]; - lfn[ 4] = lfnInfo->name1[4]; - lfn[ 5] = lfnInfo->name2[0]; lfn[ 6] = lfnInfo->name2[1]; - lfn[ 7] = lfnInfo->name2[2]; lfn[ 8] = lfnInfo->name2[3]; - lfn[ 9] = lfnInfo->name2[4]; lfn[10] = lfnInfo->name2[5]; - lfn[11] = lfnInfo->name3[0]; lfn[12] = lfnInfo->name3[1]; + lfn[a+ 0] = lfnInfo->name1[0]; lfn[a+ 1] = lfnInfo->name1[1]; + lfn[a+ 2] = lfnInfo->name1[2]; lfn[a+ 3] = lfnInfo->name1[3]; + lfn[a+ 4] = lfnInfo->name1[4]; + lfn[a+ 5] = lfnInfo->name2[0]; lfn[a+ 6] = lfnInfo->name2[1]; + lfn[a+ 7] = lfnInfo->name2[2]; lfn[a+ 8] = lfnInfo->name2[3]; + lfn[a+ 9] = lfnInfo->name2[4]; lfn[a+10] = lfnInfo->name2[5]; + lfn[a+11] = lfnInfo->name3[0]; lfn[a+12] = lfnInfo->name3[1]; LOG("lfn = '%s'", lfn); + //Log_Debug("FAT", "lfn = '%s'", lfn); LEAVE('p', VFS_SKIP); return VFS_SKIP; } @@ -1278,11 +1287,16 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID) LEAVE('p', VFS_SKIP); return VFS_SKIP; } - // Ignore . and .. - if(fileinfo[a].name[0] == '.') { + // Ignore . + if(fileinfo[a].name[0] == '.' && fileinfo[a].name[1] == ' ') { + LEAVE('p', VFS_SKIP); + return VFS_SKIP; + } + // and .. + if(fileinfo[a].name[0] == '.' && fileinfo[a].name[1] == '.' && fileinfo[a].name[2] == ' ') { LEAVE('p', VFS_SKIP); return VFS_SKIP; - } + } LOG("name='%c%c%c%c%c%c%c%c.%c%c%c'", fileinfo[a].name[0], fileinfo[a].name[1], fileinfo[a].name[2], fileinfo[a].name[3], @@ -1291,6 +1305,7 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID) #if USE_LFN lfn = FAT_int_GetLFN(Node, ID); + //Log_Debug("FAT", "lfn = %p'%s'", lfn, lfn); ret = FAT_int_CreateName(&fileinfo[a], lfn); #else ret = FAT_int_CreateName(&fileinfo[a], NULL);