From 509f33ba272947f16b2da0ade584b7b6bf935fd5 Mon Sep 17 00:00:00 2001 From: emoose Date: Sat, 17 Apr 2021 13:59:28 +0100 Subject: [PATCH] [VFS/STFS] Fix BlockToOffsetSTFS for non-read_only_format (CON) packages Previous code would give wrong results for those types of packages as the block_shift would cancel itself out, moving it to happen afterward let it give the right result though, probably a mistake while reversing it. (eg. block 0 would give 0xB000, but that's wrong for non-read_only packages as 0xA000 and 0xB000 are reserved for the first hash-table there, fixed code returns the correct 0xC000 offset) Also changed it to a multiply & renamed it to blocks_per_hash_table to make it more obvious what the purpose is. --- src/xenia/vfs/devices/stfs_container_device.cc | 15 ++++++--------- src/xenia/vfs/devices/stfs_container_device.h | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/xenia/vfs/devices/stfs_container_device.cc b/src/xenia/vfs/devices/stfs_container_device.cc index 7160ddd4f..e3ecdedff 100644 --- a/src/xenia/vfs/devices/stfs_container_device.cc +++ b/src/xenia/vfs/devices/stfs_container_device.cc @@ -561,13 +561,10 @@ StfsContainerDevice::Error StfsContainerDevice::ReadSTFS() { return Error::kSuccess; } -size_t StfsContainerDevice::BlockToOffsetSTFS(uint64_t block_index) { - uint64_t block; - uint32_t block_shift = 0; - if (((header_.header.header_size + 0x0FFF) & 0xB000) == 0xB000 || - !header_.metadata.stfs_volume_descriptor.flags.read_only_format) { - block_shift = - header_.header.magic == XContentPackageType::kPackageTypeCon ? 1 : 0; +size_t StfsContainerDevice::BlockToOffsetSTFS(uint64_t block_index) const { + uint32_t blocks_per_hash_table = 1; + if (!header_.metadata.stfs_volume_descriptor.flags.read_only_format) { + blocks_per_hash_table = 2; } // For every level there is a hash table @@ -576,9 +573,9 @@ size_t StfsContainerDevice::BlockToOffsetSTFS(uint64_t block_index) { // Level 2: hash table of next 170 level 1 hash tables // And so on... uint64_t base = kBlocksPerHashLevel[0]; - block = block_index; + uint64_t block = block_index; for (uint32_t i = 0; i < 3; i++) { - block += (block_index + (base << block_shift)) / (base << block_shift); + block += ((block_index + base) / base) * blocks_per_hash_table; if (block_index < base) { break; } diff --git a/src/xenia/vfs/devices/stfs_container_device.h b/src/xenia/vfs/devices/stfs_container_device.h index 500b1ab21..29d12cfa0 100644 --- a/src/xenia/vfs/devices/stfs_container_device.h +++ b/src/xenia/vfs/devices/stfs_container_device.h @@ -462,7 +462,7 @@ class StfsContainerDevice : public Device { void BlockToOffsetSVOD(size_t sector, size_t* address, size_t* file_index); Error ReadSTFS(); - size_t BlockToOffsetSTFS(uint64_t block); + size_t BlockToOffsetSTFS(uint64_t block_index) const; StfsHashEntry GetBlockHash(const uint8_t* map_ptr, uint32_t block_index, uint32_t table_offset);