+/**\r
+ * \brief Converts an offset in a file into a disk address\r
+ * \param Node File (or directory) node\r
+ * \param Offset Offset in the file\r
+ * \param Addr Return Address\r
+ * \param Cluster Set to the current cluster (or the last one if \a Offset\r
+ * is past EOC) - Not touched if the node is the root\r
+ * directory.\r
+ * \return Zero on success, non-zero on error\r
+ */\r
+int FAT_int_GetAddress(tVFS_Node *Node, Uint64 Offset, Uint64 *Addr, Uint32 *Cluster)\r
+{\r
+ Uint32 cluster;\r
+ Uint64 addr;\r
+ int skip;\r
+ tFAT_VolInfo *disk = Node->ImplPtr;\r
+ \r
+ ENTER("pNode XOffset", Node, Offset);\r
+ \r
+ cluster = Node->Inode & 0xFFFFFFFF; // Cluster ID\r
+ \r
+ // Do Cluster Skip\r
+ // - Pre FAT32 had a reserved area for the root.\r
+ if( disk->type == FAT32 || cluster != disk->rootOffset )\r
+ {\r
+ skip = Offset / disk->BytesPerCluster;\r
+ // Skip previous clusters\r
+ for(; skip-- ; )\r
+ {\r
+ if(Cluster) *Cluster = cluster;\r
+ cluster = FAT_int_GetFatValue(disk, cluster);\r
+ // Check for end of cluster chain\r
+ if(cluster == -1) { LEAVE('i', 1); return 1;}\r
+ }\r
+ if(Cluster) *Cluster = cluster;\r
+ }\r
+ \r
+ // Bounds Checking (Used to spot corruption)\r
+ if(cluster > disk->ClusterCount + 2)\r
+ {\r
+ Log_Warning("FAT", "Cluster ID is over cluster count (0x%x>0x%x)",\r
+ cluster, disk->ClusterCount+2);\r
+ LEAVE('i', 1);\r
+ return 1;\r
+ }\r
+ \r
+ // Compute Offsets\r
+ // - Pre FAT32 cluster base (in sectors)\r
+ if( cluster == disk->rootOffset && disk->type != FAT32 ) {\r
+ addr = disk->bootsect.resvSectCount * disk->bootsect.bps;\r
+ addr += cluster * disk->BytesPerCluster;\r
+ }\r
+ else {\r
+ addr = disk->firstDataSect;\r
+ addr += (cluster - 2) * disk->BytesPerCluster;\r
+ }\r
+ addr += Offset % disk->BytesPerCluster;\r
+ \r
+ *Addr = addr;\r
+ LEAVE('i', 0);\r
+ return 0;\r
+}\r
+\r