From 051a7f3451fec22fcadee2190fa25fd9560c55c9 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Sat, 19 Sep 2015 18:39:45 +0200 Subject: [PATCH] FolderMemoryCard: Handle empty files on load and write --- pcsx2/gui/MemoryCardFolder.cpp | 47 +++++++++++++++++++++++----------- pcsx2/gui/MemoryCardFolder.h | 3 +++ 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/pcsx2/gui/MemoryCardFolder.cpp b/pcsx2/gui/MemoryCardFolder.cpp index 6205d07dc9..f9acb749d0 100644 --- a/pcsx2/gui/MemoryCardFolder.cpp +++ b/pcsx2/gui/MemoryCardFolder.cpp @@ -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 const u32 clusterSize = m_superBlock.data.pages_per_cluster * m_superBlock.data.page_len; 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 newNeededClusters = ( dirEntry->entry.data.length % 2 ) == 0 ? countClusters + 1 : countClusters; if ( newNeededClusters > GetAmountFreeDataClusters() ) { @@ -450,17 +445,21 @@ bool FolderMemoryCard::AddFile( MemoryCardFileEntry* const dirEntry, const wxStr } newFileEntry->entry.data.length = filesize; - u32 fileDataStartingCluster = GetFreeDataCluster(); - newFileEntry->entry.data.cluster = fileDataStartingCluster; + if ( filesize != 0 ) { + u32 fileDataStartingCluster = GetFreeDataCluster(); + newFileEntry->entry.data.cluster = fileDataStartingCluster; - // mark the appropriate amount of clusters as used - u32 dataCluster = fileDataStartingCluster; - m_fat.data[0][0][dataCluster] = LastDataCluster | DataClusterInUseMask; - for ( unsigned int i = 0; i < countClusters - 1; ++i ) { - u32 newCluster = GetFreeDataCluster(); - m_fat.data[0][0][dataCluster] = newCluster | DataClusterInUseMask; - m_fat.data[0][0][newCluster] = LastDataCluster | DataClusterInUseMask; - dataCluster = newCluster; + // mark the appropriate amount of clusters as used + u32 dataCluster = fileDataStartingCluster; + m_fat.data[0][0][dataCluster] = LastDataCluster | DataClusterInUseMask; + for ( unsigned int i = 0; i < countClusters - 1; ++i ) { + u32 newCluster = GetFreeDataCluster(); + m_fat.data[0][0][dataCluster] = newCluster | DataClusterInUseMask; + m_fat.data[0][0][newCluster] = LastDataCluster | DataClusterInUseMask; + dataCluster = newCluster; + } + } else { + newFileEntry->entry.data.cluster = MemoryCardFileEntry::EmptyFileCluster; } file.Close(); @@ -990,6 +989,24 @@ void FolderMemoryCard::FlushFileEntries( const u32 dirCluster, const u32 remaini } } else if ( entry->IsValid() && entry->IsUsed() && entry->IsFile() ) { 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(); + } + } + } } } diff --git a/pcsx2/gui/MemoryCardFolder.h b/pcsx2/gui/MemoryCardFolder.h index 0072584df7..feded636ac 100644 --- a/pcsx2/gui/MemoryCardFolder.h +++ b/pcsx2/gui/MemoryCardFolder.h @@ -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 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)