Fixes for crashes if firstblock or numblocks is > 2049

Fixes some memory leaks, removes duplicate function
some information about hdr added

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1311 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
LPFaint99 2008-11-27 05:30:18 +00:00
parent 69e978f9e2
commit af46362f34
3 changed files with 62 additions and 45 deletions

View File

@ -664,9 +664,11 @@ bool CMemcardManager::ReloadMemcard(const char *fileName, int card, int page)
m_MemcardList[card]->SetItem(index, COLUMN_BANNER, wxEmptyString);
m_MemcardList[card]->SetItem(index, COLUMN_TITLE, wxString::FromAscii(title));
m_MemcardList[card]->SetItem(index, COLUMN_COMMENT, wxString::FromAscii(comment));
if (!memoryCard[card]->GetNumBlocks(j, &blocks)) blocks = 0;
blocks = memoryCard[card]->GetFileSize(j);
if (blocks == 0xFFFF) blocks = 0;
wxBlock.Printf(wxT("%10d"), blocks);
if (!memoryCard[card]->GetFirstBlock(j,&firstblock)) firstblock = 0;
firstblock = memoryCard[card]->GetFirstBlock(j);
if (firstblock == 0xFFFF) firstblock = 3; // to make firstblock -1
wxFirstBlock.Printf(wxT("%10d"), firstblock-4);
m_MemcardList[card]->SetItem(index,COLUMN_BLOCKS, wxBlock);
m_MemcardList[card]->SetItem(index,COLUMN_FIRSTBLOCK, wxFirstBlock);

View File

@ -70,7 +70,7 @@ void GCMemcard::calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2)
}
}
u16 GCMemcard::GetFreeBlocks(void)
u16 GCMemcard::GetFreeBlocks()
{
if (!mcdFile) return 0;
return BE16(bat.FreeBlocks);
@ -119,18 +119,12 @@ bool GCMemcard::TitlePresent(DEntry d)
return false;
}
bool GCMemcard::GetNumBlocks(u32 index, u16* buffer)
u16 GCMemcard::GetFirstBlock(u32 index)
{
if (!mcdFile) return false;
*buffer = BE16(dir.Dir[index].BlockCount);
return true;
}
bool GCMemcard::GetFirstBlock(u32 index, u16* buffer)
{
if (!mcdFile) return false;
*buffer = BE16(dir.Dir[index].FirstBlock);
return true;
if (!mcdFile) return 0xFFFF;
u16 block = BE16(dir.Dir[index].FirstBlock);
if (block > MAXBLOCK) return 0xFFFF;
return block;
}
u32 GCMemcard::RemoveFile(u32 index) //index in the directory array
@ -161,15 +155,21 @@ u32 GCMemcard::RemoveFile(u32 index) //index in the directory array
u16 freeBlock= BE16(bat.FreeBlocks) - BE16(d->BlockCount);
bat.FreeBlocks[0] = u8(freeBlock >> 8);
bat.FreeBlocks[1] = u8(freeBlock);
t = new u8[GetFileSize(i) * 0x2000];
switch (GetFileData(i, t, true))
u16 size = GetFileSize(i);
if (size != 0xFFFF)
{
case NOMEMCARD:
delete[] t;
break;
case FAIL:
return FAIL;
break;
t = new u8[size * 0x2000];
switch (GetFileData(i, t, true))
{
case NOMEMCARD:
delete[] t;
break;
case FAIL:
delete[] t;
return FAIL;
break;
}
}
}
memset(&(dir.Dir[i]), 0xFF, 0x40);
@ -308,7 +308,7 @@ u32 GCMemcard::ImportFile(DEntry& direntry, u8* contents, int remove)
return fileBlocks;
}
u32 GCMemcard::GetFileData(u32 index, u8*dest, bool old) //index in the directory array
u32 GCMemcard::GetFileData(u32 index, u8* dest, bool old) //index in the directory array
{
if (!mcdFile) return NOMEMCARD;
@ -316,7 +316,8 @@ u32 GCMemcard::GetFileData(u32 index, u8*dest, bool old) //index in the director
u16 saveLength = BE16(dir.Dir[index].BlockCount);
u16 memcardSize = BE16(hdr.Size) * 0x0010;
if (block + saveLength > memcardSize)
if ((block == 0xFFFF) || (saveLength == 0xFFFF)
|| (block + saveLength > memcardSize))
{
return FAIL;
}
@ -344,11 +345,13 @@ u32 GCMemcard::GetFileData(u32 index, u8*dest, bool old) //index in the director
return SUCCESS;
}
u32 GCMemcard::GetFileSize(u32 index) //index in the directory array
u16 GCMemcard::GetFileSize(u32 index) //index in the directory array
{
if (!mcdFile) return 0;
if (!mcdFile) return 0xFFFF;
return BE16(dir.Dir[index].BlockCount);
u16 blocks = BE16(dir.Dir[index].BlockCount);
if (blocks > (u16) MAXBLOCK) return 0xFFFF;
return blocks;
}
bool GCMemcard::GetFileInfo(u32 index, GCMemcard::DEntry& info) //index in the directory array
@ -374,7 +377,7 @@ bool GCMemcard::GetComment1(u32 index, char *fn) //index in the directory array
u32 Comment1 = BE32(dir.Dir[index].CommentsAddr);
u32 DataBlock = BE16(dir.Dir[index].FirstBlock) - 5;
if (Comment1 == 0xFFFFFFFF)
if ((DataBlock > MAXBLOCK) || (Comment1 == 0xFFFFFFFF))
{
fn[0] = 0;
return false;
@ -391,7 +394,7 @@ bool GCMemcard::GetComment2(u32 index, char *fn) //index in the directory array
u32 Comment1 = BE32(dir.Dir[index].CommentsAddr);
u32 Comment2 = Comment1 + 32;
u32 DataBlock = BE16(dir.Dir[index].FirstBlock) - 5;
if (Comment1 == 0xFFFFFFFF)
if ((DataBlock > MAXBLOCK) || (Comment1 == 0xFFFFFFFF))
{
fn[0] = 0;
return false;
@ -479,7 +482,7 @@ bool GCMemcard::ReadBannerRGBA8(u32 index, u32* buffer)
u32 DataOffset = BE32(dir.Dir[index].ImageOffset);
u32 DataBlock = BE16(dir.Dir[index].FirstBlock) - 5;
if (DataOffset == 0xFFFFFFFF)
if ((DataBlock > MAXBLOCK) || (DataOffset == 0xFFFFFFFF))
{
return false;
}
@ -516,7 +519,7 @@ u32 GCMemcard::ReadAnimRGBA8(u32 index, u32* buffer, u8 *delays)
u32 DataOffset = BE32(dir.Dir[index].ImageOffset);
u32 DataBlock = BE16(dir.Dir[index].FirstBlock) - 5;
if (DataOffset == 0xFFFFFFFF)
if ((DataBlock > MAXBLOCK) || (DataOffset == 0xFFFFFFFF))
{
return 0;
}
@ -663,14 +666,18 @@ u32 GCMemcard::CopyFrom(GCMemcard& source, u32 index)
DEntry d;
if (!source.GetFileInfo(index, d)) return 0;
u8 *t = new u8[source.GetFileSize(index) * 0x2000];
u32 size = source.GetFileSize(index);
if (size == 0xFFFF) return 0;
u8 *t = new u8[size * 0x2000];
switch (source.GetFileData(index, t, true))
{
case FAIL:
delete[] t;
return FAIL;
case NOMEMCARD:
delete[] t;
return NOMEMCARD;
default:
break;
@ -806,16 +813,22 @@ u32 GCMemcard::ExportGci(u32 index, const char *fileName)
fseek(gci, 0, SEEK_SET);
DEntry d;
if (!this->GetFileInfo(index, d)) return NOMEMCARD;
if (!GetFileInfo(index, d)) return NOMEMCARD;
assert(fwrite(&d, 1, 0x40, gci) == 0x40);
u8 *t = new u8[this->GetFileSize(index) * 0x2000];
u32 size = GetFileSize(index);
if (size == 0xFFFF)return FAIL;
u8 *t = new u8[size * 0x2000];
switch(GetFileData(index, t, true))
{
case FAIL:
fclose(gci);
delete []t;
return FAIL;
case NOMEMCARD:
fclose(gci);
delete []t;
return NOMEMCARD;
default:
break;

View File

@ -46,7 +46,8 @@ enum
NOFILE,
TITLEPRESENT,
SUCCESS = 0x2000,
FAIL
FAIL,
MAXBLOCK = 0x2049
};
class GCMemcard
@ -66,9 +67,10 @@ private:
};
struct Header { //Offset Size Description
u8 Unk[12]; //0x0000 12 ?
u8 Unk1[12]; //0x0000 12 ?
OSTime fmtTime; //0x000c 8 time of format (OSTime value)
u8 UID[12]; //0x0014 12 unique card id (?)
u8 SramBias[4]; //0x0014 4 sram bias at time of format
u8 Unk2[8]; //0x0018 8 ? almost always 0 or 1
u8 Pad1[2]; //0x0020 2 padding zeroes
u8 Size[2]; //0x0022 2 size of memcard in Mbits
u8 Encoding[2]; //0x0024 2 encoding (ASCII or japanese)
@ -168,21 +170,21 @@ public:
// buffer needs to be a char[32] or bigger
bool GetFileName(u32 index, char* buffer);
bool GetNumBlocks(u32 index, u16* buffer);
// get file length in blocks
u16 GetFileSize(u32 index);
// get first block for file
u16 GetFirstBlock(u32 index);
// get the free blocks from bat
u16 GetFreeBlocks(void);
bool GetFirstBlock(u32 index, u16* buffer);
// buffer needs to be a char[32] or bigger
bool GetComment1(u32 index, char* buffer);
// buffer needs to be a char[32] or bigger
bool GetComment2(u32 index, char* buffer);
// get file length un bytes
u32 GetFileSize(u32 index);
// assumes there's enough space in buffer
// old determines if function uses old or new method of copying data
// some functions only work with old way, some only work with new way