From b549ec70b4d008635da3e262a28ffea88334ad83 Mon Sep 17 00:00:00 2001 From: LPFaint99 Date: Thu, 1 May 2014 12:21:48 -0700 Subject: [PATCH] GCMemcard: fix edge case of adding to a fragmented memcard. allocates last block of memcard, and then wraps around, instead of attempting to write past the end of the card --- Source/Core/Core/HW/GCMemcard.cpp | 9 +++++---- Source/Core/Core/HW/GCMemcard.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Source/Core/Core/HW/GCMemcard.cpp b/Source/Core/Core/HW/GCMemcard.cpp index 6731f8e3cc..738e3c93c3 100644 --- a/Source/Core/Core/HW/GCMemcard.cpp +++ b/Source/Core/Core/HW/GCMemcard.cpp @@ -554,11 +554,12 @@ u16 GCMemcard::BlockAlloc::GetNextBlock(u16 Block) const return Common::swap16(Map[Block-MC_FST_BLOCKS]); } -u16 GCMemcard::BlockAlloc::NextFreeBlock(u16 StartingBlock) const +u16 GCMemcard::BlockAlloc::NextFreeBlock(u16 MaxBlock, u16 StartingBlock) const { if (FreeBlocks) { - for (u16 i = StartingBlock; i < BAT_SIZE; ++i) + MaxBlock = std::min(MaxBlock, BAT_SIZE); + for (u16 i = StartingBlock; i < MaxBlock; ++i) if (Map[i-MC_FST_BLOCKS] == 0) return i; @@ -638,7 +639,7 @@ u32 GCMemcard::ImportFile(DEntry& direntry, std::vector &saveBlocks) } // find first free data block - u16 firstBlock = CurrentBat->NextFreeBlock(BE16(CurrentBat->LastAllocated)); + u16 firstBlock = CurrentBat->NextFreeBlock(maxBlock - MC_FST_BLOCKS, BE16(CurrentBat->LastAllocated)); if (firstBlock == 0xFFFF) return OUTOFBLOCKS; Directory UpdatedDir = *CurrentDir; @@ -683,7 +684,7 @@ u32 GCMemcard::ImportFile(DEntry& direntry, std::vector &saveBlocks) if (i == fileBlocks-1) nextBlock = 0xFFFF; else - nextBlock = UpdatedBat.NextFreeBlock(firstBlock+1); + nextBlock = UpdatedBat.NextFreeBlock(maxBlock - MC_FST_BLOCKS, firstBlock + 1); UpdatedBat.Map[firstBlock - MC_FST_BLOCKS] = BE16(nextBlock); UpdatedBat.LastAllocated = BE16(firstBlock); firstBlock = nextBlock; diff --git a/Source/Core/Core/HW/GCMemcard.h b/Source/Core/Core/HW/GCMemcard.h index 584db1856e..081f1ca5e3 100644 --- a/Source/Core/Core/HW/GCMemcard.h +++ b/Source/Core/Core/HW/GCMemcard.h @@ -158,7 +158,7 @@ private: u16 LastAllocated; //0x0008 2 Last allocated Block u16 Map[BAT_SIZE]; //0x000a 0x1ff8 Map of allocated Blocks u16 GetNextBlock(u16 Block) const; - u16 NextFreeBlock(u16 StartingBlock=MC_FST_BLOCKS) const; + u16 NextFreeBlock(u16 MaxBlock, u16 StartingBlock = MC_FST_BLOCKS) const; bool ClearBlocks(u16 StartingBlock, u16 Length); } bat,bat_backup;