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
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