tFAT_VolInfo gFAT_Disks[8];\r
int giFAT_PartCount = 0;\r
tVFS_Driver gFAT_FSInfo = {"fat", 0, FAT_InitDevice, FAT_Unmount, FAT_GetNodeFromINode, NULL};\r
+tVFS_NodeType gFAT_DirType = {\r
+ .TypeName = "FAT-Dir",\r
+ .ReadDir = FAT_ReadDir,\r
+ .FindDir = FAT_FindDir,\r
+ #if SUPPORT_WRITE\r
+ .MkNod = FAT_Mknod,\r
+ .Relink = FAT_Relink,\r
+ #endif\r
+ .Close = FAT_CloseFile\r
+ };\r
+tVFS_NodeType gFAT_FileType = {\r
+ .TypeName = "FAT-File",\r
+ .Read = FAT_Read,\r
+ #if SUPPORT_WRITE\r
+ .Write = FAT_Write,\r
+ #endif\r
+ .Close = FAT_CloseFile\r
+ };\r
\r
// === CODE ===\r
/**\r
node->ACLs = &gVFS_ACL_EveryoneRWX;\r
node->Flags = VFS_FFLAG_DIRECTORY;\r
node->CTime = node->MTime = node->ATime = now();\r
- \r
- node->Read = node->Write = NULL;\r
- node->ReadDir = FAT_ReadDir;\r
- node->FindDir = FAT_FindDir;\r
- #if SUPPORT_WRITE\r
- node->Relink = FAT_Relink;\r
- node->MkNod = FAT_Mknod;\r
- #else\r
- node->Relink = NULL;\r
- node->MkNod = NULL;\r
- #endif\r
- //node->Close = FAT_Unmount;\r
+\r
+ node->Type = &gFAT_DirType; \r
\r
giFAT_PartCount ++;\r
return node;\r
Uint64 FAT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
{\r
int preSkip, count;\r
+ Uint64 final_bytes;\r
int i, cluster, pos;\r
tFAT_VolInfo *disk = Node->ImplPtr;\r
char tmpBuf[disk->BytesPerCluster];\r
\r
// Sanity Check offset\r
if(Offset > Node->Size) {\r
- LOG("Reading past EOF (%i > %i)", Offset, Node->Size);\r
+ LOG("Seek past EOF (%i > %i)", Offset, Node->Size);\r
LEAVE('i', 0);\r
return 0;\r
}\r
cluster = Node->Inode & 0xFFFFFFFF;\r
\r
// Clamp Size\r
- if(Offset >= Node->Size || 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
}\r
\r
- // Reading from within the first cluster only?\r
- if((int)Offset + (int)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
- #if DEBUG\r
- //Debug_HexDump("FAT_Read", Buffer, Length);\r
- #endif\r
- LEAVE('i', 1);\r
- return Length;\r
- }\r
- \r
// Skip previous clusters\r
preSkip = Offset / bpc;\r
- for(i = preSkip; i--; ) {\r
+ Offset %= bpc;\r
+ LOG("preSkip = %i, Offset = %i", preSkip, (int)Offset);\r
+ for(i = preSkip; i--; )\r
+ {\r
cluster = FAT_int_GetFatValue(disk, cluster);\r
if(cluster == -1) {\r
Log_Warning("FAT", "Offset is past end of cluster chain mark");\r
return 0;\r
}\r
}\r
- \r
- // Get Count of Clusters to read\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 (performs alignment for us)\r
- if( pos == bpc && (int)Length >= bpc ) {\r
- FAT_int_ReadCluster(disk, cluster, bpc, Buffer);\r
- }\r
- else {\r
+\r
+ // Reading from within one cluster\r
+ if((int)Offset + (int)Length <= bpc)\r
+ {\r
+ LOG("single cluster only");\r
FAT_int_ReadCluster(disk, cluster, bpc, tmpBuf);\r
- memcpy(\r
- Buffer,\r
- (void*)( tmpBuf + (bpc-pos) ),\r
- (pos < (int)Length ? (Uint)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
- LEAVE('i', 1);\r
+ memcpy( Buffer, (void*)( tmpBuf + Offset%bpc ), Length );\r
+ LEAVE('X', Length);\r
return Length;\r
}\r
\r
- #if DEBUG\r
- LOG("pos = %i", pos);\r
- LOG("Reading the rest of the clusters");\r
- #endif\r
- \r
- // Read the rest of the cluster data\r
- for( i = 1; i < count-1; i++ )\r
+ // Align read to a cluster\r
+ if( Offset > 0 )\r
{\r
+ pos = bpc - Offset;\r
+ FAT_int_ReadCluster(disk, cluster, bpc, tmpBuf);\r
+ memcpy( Buffer, (void*)( tmpBuf + Offset ), pos );\r
+ LOG("pos = %i, Reading the rest of the clusters");\r
// Get next cluster in the chain\r
cluster = FAT_int_GetFatValue(disk, cluster);\r
if(cluster == -1) {\r
- Log_Warning("FAT", "FAT_Read: Read past End of Cluster Chain");\r
- LEAVE('i', 0);\r
- return 0;\r
+ Log_Warning("FAT", "Read past End of Cluster Chain (Align)");\r
+ LEAVE('X', pos);\r
+ return pos;\r
+ }\r
+ }\r
+ else\r
+ pos = 0;\r
+\r
+ // Get Count of Clusters to read\r
+// count = DivMod64U(Length - pos, bpc, &final_bytes);\r
+ count = (Length - pos) / bpc;\r
+ final_bytes = (Length - pos) % bpc;\r
+ LOG("Offset = %i, Length = %i, count = %i, final_bytes = %i", (int)Offset, (int)Length, count, final_bytes);\r
+ \r
+ // Read the rest of the cluster data\r
+ for( ; count; count -- )\r
+ {\r
+ if(cluster == -1) {\r
+ Log_Warning("FAT", "Read past End of Cluster Chain (Bulk)");\r
+ LEAVE('X', pos);\r
+ return pos;\r
}\r
// Read cluster\r
FAT_int_ReadCluster(disk, cluster, bpc, (void*)(Buffer+pos));\r
pos += bpc;\r
+ // Get next cluster in the chain\r
+ cluster = FAT_int_GetFatValue(disk, cluster);\r
}\r
- \r
- // Get next cluster in the chain\r
- cluster = FAT_int_GetFatValue(disk, cluster);\r
- if(cluster == -1) {\r
- Log_Warning("FAT", "FAT_Read: Read past End of Cluster Chain");\r
- LEAVE('i', 0);\r
- return 0;\r
- }\r
- \r
- // Read final cluster\r
- if( (int)Length - pos == bpc )\r
+\r
+ if( final_bytes > 0 )\r
{\r
- FAT_int_ReadCluster( disk, cluster, bpc, (void*)(Buffer+pos) );\r
- }\r
- else {\r
+ if(cluster == -1) {\r
+ Log_Warning("FAT", "Read past End of Cluster Chain (Final)");\r
+ LEAVE('X', pos);\r
+ return pos;\r
+ }\r
+ // Read final cluster\r
FAT_int_ReadCluster( disk, cluster, bpc, tmpBuf );\r
memcpy( (void*)(Buffer+pos), tmpBuf, Length-pos );\r
}\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
// 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.FindDir = FAT_FindDir;\r
- #if SUPPORT_WRITE\r
- node.MkNod = FAT_Mknod;\r
- node.Relink = FAT_Relink;\r
- #endif\r
+ node.Type = &gFAT_DirType; \r
node.Size = -1;\r
}\r
else {\r
- node.Read = FAT_Read;\r
- #if SUPPORT_WRITE\r
- node.Write = FAT_Write;\r
- #endif\r
+ node.Type = &gFAT_FileType;\r
}\r
- node.Close = FAT_CloseFile;\r
\r
ret = Inode_CacheNode(disk->inodeHandle, &node);\r
LEAVE('p', ret);\r
tFAT_VolInfo *disk = Node->ImplPtr;\r
Uint32 cluster;\r
\r
- ENTER("pNode sname", Node, Name);\r
- \r
+ ENTER("pNode sname", Node, Name); \r
+\r
// Fast Returns\r
if(!Name || Name[0] == '\0') {\r
LEAVE('n');\r