/*\r
- * Acess2\r
+ * Acess 2\r
* FAT12/16/32 Driver Version (Incl LFN)\r
*/\r
-//INCLUDES\r
+#define DEBUG 0\r
#include <common.h>\r
#include <modules.h>\r
#include <vfs.h>\r
#include "fs_fat.h"\r
\r
-#define DEBUG 0\r
#define VERBOSE 1\r
\r
-#if DEBUG\r
-# define DEBUGS(v...) Log(v)\r
-#else\r
-# define DEBUGS(v...)\r
-# undef ENTER\r
-# undef LOG\r
-# undef LEAVE\r
-# define ENTER(...)\r
-# define LOG(...)\r
-# define LEAVE(...)\r
-#endif\r
-\r
#define CACHE_FAT 1 //!< Caches the FAT in memory\r
#define USE_LFN 1 //!< Enables the use of Long File Names\r
\r
\r
// === PROTOTYPES ===\r
int FAT_Install(char **Arguments);\r
-tVFS_Node *FAT_InitDevice(char *device, char *options);\r
-void FAT_CloseDevice(tVFS_Node *node);\r
+tVFS_Node *FAT_InitDevice(char *device, char **options);\r
+void FAT_Unmount(tVFS_Node *Node);\r
Uint64 FAT_Read(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer);\r
Uint64 FAT_Write(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer);\r
char *FAT_ReadDir(tVFS_Node *dirNode, int dirpos);\r
void FAT_CloseFile(tVFS_Node *node);\r
\r
// === SEMI-GLOBALS ===\r
-MODULE_DEFINE(0, 0x5B /*v0.90*/, FAT32, FAT_Install, NULL);\r
+MODULE_DEFINE(0, 0x51 /*v0.80*/, FAT32, FAT_Install, NULL);\r
tFAT_VolInfo gFAT_Disks[8];\r
int giFAT_PartCount = 0;\r
#if CACHE_FAT\r
t_lfncache *fat_lfncache;\r
#endif\r
tVFS_Driver gFAT_FSInfo = {\r
- "fat", 0, FAT_InitDevice, NULL\r
+ "fat", 0, FAT_InitDevice, FAT_Unmount, NULL\r
};\r
\r
// === CODE ===\r
return 0;\r
}\r
\r
-/* Reads the boot sector of a disk and prepares the structures for it\r
+/**\r
+ * \fn tVFS_Node *FAT_InitDevice(char *Device, char **options)\r
+ * \brief Reads the boot sector of a disk and prepares the structures for it\r
*/\r
-tVFS_Node *FAT_InitDevice(char *Device, char *options)\r
+tVFS_Node *FAT_InitDevice(char *Device, char **options)\r
{\r
fat_bootsect *bs;\r
int i;\r
#endif\r
\r
//Get Name\r
- //puts(" Name: ");\r
if(diskInfo->type == FAT32) {\r
for(i=0;i<11;i++)\r
diskInfo->name[i] = (bs->spec.fat32.label[i] == ' ' ? '\0' : bs->spec.fat32.label[i]);\r
diskInfo->name[i] = (bs->spec.fat16.label[i] == ' ' ? '\0' : bs->spec.fat16.label[i]);\r
}\r
diskInfo->name[11] = '\0';\r
- //puts(diskInfo->name); putch('\n');\r
\r
//Compute Root directory offset\r
if(diskInfo->type == FAT32)\r
fat_cache[giFAT_PartCount][i] = buf[i&127];\r
}\r
}\r
- DEBUGS(" FAT_InitDisk: FAT Fully Cached\n");\r
+ LOG("FAT Fully Cached");\r
}\r
#endif /*CACHE_FAT*/\r
\r
//Initalise inode cache for FAT\r
gFAT_Disks[giFAT_PartCount].inodeHandle = Inode_GetHandle();\r
+ LOG("Inode Cache handle is %i", gFAT_Disks[giFAT_PartCount].inodeHandle);\r
\r
- #if DEBUG\r
- Log(" FAT_InitDisk: Inode Cache handle is %i\n", gFAT_Disks[giFAT_PartCount].inodeHandle);\r
- #endif\r
- \r
- //== VFS Interface\r
+ // == VFS Interface\r
node = &gFAT_Disks[giFAT_PartCount].rootNode;\r
- //node->Name = gFAT_Disks[giFAT_PartCount].name;\r
node->Inode = diskInfo->rootOffset;\r
- node->Size = bs->files_in_root; //Unknown - To be set on readdir\r
+ node->Size = bs->files_in_root; // Unknown - To be set on readdir\r
node->ImplInt = giFAT_PartCount;\r
\r
node->ReferenceCount = 1;\r
\r
- node->UID = 0; node->GID= 0;\r
+ node->UID = 0; node->GID = 0;\r
node->NumACLs = 1;\r
node->ACLs = &gVFS_ACL_EveryoneRWX;\r
node->Flags = VFS_FFLAG_DIRECTORY;\r
node->FindDir = FAT_FindDir;\r
node->Relink = FAT_Relink;\r
node->MkNod = FAT_Mknod;\r
- node->Close = FAT_CloseDevice;\r
+ //node->Close = FAT_CloseDevice;\r
\r
giFAT_PartCount ++;\r
return node;\r
}\r
\r
/**\r
- * \fn void FAT_CloseDevice(tVFS_Node *node)\r
+ * \fn void FAT_Unmount(tVFS_Node *Node)\r
* \brief Closes a mount and marks it as free\r
*/\r
-void FAT_CloseDevice(tVFS_Node *node)\r
+void FAT_Unmount(tVFS_Node *Node)\r
{\r
- node->ReferenceCount --;\r
- \r
- if(node->ReferenceCount > 0) return;\r
- \r
// Close Disk Handle\r
- VFS_Close( gFAT_Disks[node->ImplInt].fileHandle );\r
- Inode_ClearCache(gFAT_Disks[node->ImplInt].inodeHandle);\r
- gFAT_Disks[node->ImplInt].fileHandle = -2;\r
+ VFS_Close( gFAT_Disks[Node->ImplInt].fileHandle );\r
+ // Clear Node Cache\r
+ Inode_ClearCache(gFAT_Disks[Node->ImplInt].inodeHandle);\r
+ // Mark as unused\r
+ gFAT_Disks[Node->ImplInt].fileHandle = -2;\r
return;\r
}\r
\r
*/\r
static void FAT_int_ReadCluster(int Handle, Uint32 Cluster, int Length, void *Buffer)\r
{\r
- #if DEBUG\r
ENTER("iHandle xCluster iLength pBuffer", Handle, Cluster, Length, Buffer);\r
- #endif\r
VFS_ReadAt(\r
gFAT_Disks[Handle].fileHandle,\r
(gFAT_Disks[Handle].firstDataSect + (Cluster-2)*gFAT_Disks[Handle].bootsect.spc )\r
Length,\r
Buffer\r
);\r
- #if DEBUG\r
LEAVE('-');\r
- #endif\r
}\r
\r
/**\r
return 0;\r
}\r
\r
+ // Sanity Check offset\r
+ if(offset > node->Size) {\r
+ //Log("FAT_Read: Reading past EOF (%i > %i)", offset, node->Size);\r
+ return 0;\r
+ }\r
+ // Clamp Size\r
+ if(offset + length > node->Size) {\r
+ //Log("FAT_Read: Reading past EOF (%lli + %lli > %lli), clamped to %lli",\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
{\r
memcpy( buffer, (void*)( tmpBuf + offset%bpc ), length );\r
free(tmpBuf);\r
LEAVE('i', 1);\r
- return 1;\r
+ return length;\r
}\r
\r
preSkip = offset / bpc;\r
if (count == 1) {\r
free(tmpBuf);\r
LEAVE('i', 1);\r
- return 1;\r
+ return length;\r
}\r
\r
cluster = FAT_int_GetFatValue(handle, cluster);\r
\r
ENTER("pParent pFT sLongFileName", parent, ft, LongFileName);\r
\r
- // Get Name\r
- //node.Name = FAT_int_CreateName(parent, ft, LongFileName);\r
// Set Other Data\r
node.Inode = ft->cluster | (ft->clusterHi<<16);\r
node.Size = ft->size;\r
node.ReadDir = FAT_ReadDir;\r
node.FindDir = FAT_FindDir;\r
node.MkNod = FAT_Mknod;\r
+ node.Size = -1;\r
} else {\r
node.Read = FAT_Read;\r
node.Write = FAT_Write;\r
// Offset in sector\r
a = dirpos & 0xF;\r
\r
- LOG("offset=%i, a=%i\n", (Uint)offset, a);\r
+ LOG("offset=%i, a=%i", (Uint)offset, a);\r
\r
// Read Sector\r
VFS_ReadAt(disk->fileHandle, offset*512, 512, fileinfo); // Read Dir Data\r
\r
- LOG("name[0] = 0x%x\n", (Uint8)fileinfo[a].name[0]);\r
+ LOG("name[0] = 0x%x", (Uint8)fileinfo[a].name[0]);\r
//Check if this is the last entry\r
if(fileinfo[a].name[0] == '\0') {\r
dirNode->Size = dirpos;\r
- LOG("End of list\n");\r
+ LOG("End of list");\r
LEAVE('n');\r
return NULL; // break\r
}\r
// Get the current length\r
len = strlen(lfn);\r
\r
- // Sanity Check (FAT implementations do not allow >255 bytes)\r
+ // Sanity Check (FAT implementations should not allow >255 bytes)\r
if(len + 13 > 255) return VFS_SKIP;\r
// Rebase all bytes\r
for(a=len+1;a--;) lfn[a+13] = lfn[a];\r