FolderMemoryCard: Handle empty files on load and write

This commit is contained in:
Admiral H. Curtiss 2015-09-19 18:39:45 +02:00 committed by Avi Halachmi (:avih)
parent 56452481e2
commit 051a7f3451
2 changed files with 35 additions and 15 deletions

View File

@ -413,11 +413,6 @@ bool FolderMemoryCard::AddFile( MemoryCardFileEntry* const dirEntry, const wxStr
// make sure we have enough space on the memcard to hold the data // make sure we have enough space on the memcard to hold the data
const u32 clusterSize = m_superBlock.data.pages_per_cluster * m_superBlock.data.page_len; const u32 clusterSize = m_superBlock.data.pages_per_cluster * m_superBlock.data.page_len;
const u32 filesize = file.Length(); const u32 filesize = file.Length();
if (!filesize) {
Console.Error(L"(MCDF) Empty file. Aborting.");
file.Close();
return false;
}
const u32 countClusters = ( filesize % clusterSize ) != 0 ? ( filesize / clusterSize + 1 ) : ( filesize / clusterSize ); const u32 countClusters = ( filesize % clusterSize ) != 0 ? ( filesize / clusterSize + 1 ) : ( filesize / clusterSize );
const u32 newNeededClusters = ( dirEntry->entry.data.length % 2 ) == 0 ? countClusters + 1 : countClusters; const u32 newNeededClusters = ( dirEntry->entry.data.length % 2 ) == 0 ? countClusters + 1 : countClusters;
if ( newNeededClusters > GetAmountFreeDataClusters() ) { if ( newNeededClusters > GetAmountFreeDataClusters() ) {
@ -450,17 +445,21 @@ bool FolderMemoryCard::AddFile( MemoryCardFileEntry* const dirEntry, const wxStr
} }
newFileEntry->entry.data.length = filesize; newFileEntry->entry.data.length = filesize;
u32 fileDataStartingCluster = GetFreeDataCluster(); if ( filesize != 0 ) {
newFileEntry->entry.data.cluster = fileDataStartingCluster; u32 fileDataStartingCluster = GetFreeDataCluster();
newFileEntry->entry.data.cluster = fileDataStartingCluster;
// mark the appropriate amount of clusters as used // mark the appropriate amount of clusters as used
u32 dataCluster = fileDataStartingCluster; u32 dataCluster = fileDataStartingCluster;
m_fat.data[0][0][dataCluster] = LastDataCluster | DataClusterInUseMask; m_fat.data[0][0][dataCluster] = LastDataCluster | DataClusterInUseMask;
for ( unsigned int i = 0; i < countClusters - 1; ++i ) { for ( unsigned int i = 0; i < countClusters - 1; ++i ) {
u32 newCluster = GetFreeDataCluster(); u32 newCluster = GetFreeDataCluster();
m_fat.data[0][0][dataCluster] = newCluster | DataClusterInUseMask; m_fat.data[0][0][dataCluster] = newCluster | DataClusterInUseMask;
m_fat.data[0][0][newCluster] = LastDataCluster | DataClusterInUseMask; m_fat.data[0][0][newCluster] = LastDataCluster | DataClusterInUseMask;
dataCluster = newCluster; dataCluster = newCluster;
}
} else {
newFileEntry->entry.data.cluster = MemoryCardFileEntry::EmptyFileCluster;
} }
file.Close(); file.Close();
@ -990,6 +989,24 @@ void FolderMemoryCard::FlushFileEntries( const u32 dirCluster, const u32 remaini
} }
} else if ( entry->IsValid() && entry->IsUsed() && entry->IsFile() ) { } else if ( entry->IsValid() && entry->IsUsed() && entry->IsFile() ) {
AddFileEntryToMetadataQuickAccess( entry, parent ); AddFileEntryToMetadataQuickAccess( entry, parent );
if ( entry->entry.data.length == 0 ) {
// empty files need to be explicitly created, as there will be no data cluster referencing it later
char cleanName[sizeof( entry->entry.data.name )];
memcpy( cleanName, (const char*)entry->entry.data.name, sizeof( cleanName ) );
bool filenameCleaned = FileAccessHelper::CleanMemcardFilename( cleanName );
const wxString filePath = dirPath + L"/" + wxString::FromAscii( (const char*)cleanName );
if ( m_performFileWrites ) {
wxFileName fn( m_folderName.GetFullPath() + filePath );
if ( !fn.FileExists() ) {
if ( !fn.DirExists() ) {
fn.Mkdir( 0777, wxPATH_MKDIR_FULL );
}
wxFFile createEmptyFile( fn.GetFullPath(), L"wb" );
createEmptyFile.Close();
}
}
}
} }
} }

View File

@ -158,6 +158,9 @@ struct MemoryCardFileEntry {
static const u32 DefaultDirMode = Mode_Read | Mode_Write | Mode_Execute | Mode_Directory | Mode_Unknown0x0400 | Mode_Used; static const u32 DefaultDirMode = Mode_Read | Mode_Write | Mode_Execute | Mode_Directory | Mode_Unknown0x0400 | Mode_Used;
static const u32 DefaultFileMode = Mode_Read | Mode_Write | Mode_Execute | Mode_File | Mode_Unknown0x0080 | Mode_Unknown0x0400 | Mode_Used; static const u32 DefaultFileMode = Mode_Read | Mode_Write | Mode_Execute | Mode_File | Mode_Unknown0x0080 | Mode_Unknown0x0400 | Mode_Used;
// used in the cluster entry of empty files on real memory cards, as far as we know
static const u32 EmptyFileCluster = 0xFFFFFFFFu;
}; };
#pragma pack(pop) #pragma pack(pop)