mirror of https://github.com/PCSX2/pcsx2.git
FolderMemoryCard: Clean PS2 filenames that would be illegal in Windows and write the actual names into the metadata files.
This fixes issues with game such as Rayman Revolution, http://forums.pcsx2.net/Thread-New-feature-Needs-testing-Automatically-managed-Folder-Memory-Card-Public-Test?pid=463482#pid463482
This commit is contained in:
parent
92c794f03b
commit
50ad3a8bf5
|
@ -409,24 +409,27 @@ bool FolderMemoryCard::AddFile( MemoryCardFileEntry* const dirEntry, const wxStr
|
|||
fileInfo.GetTimes( NULL, &modificationTime, &creationTime );
|
||||
|
||||
// set file entry metadata
|
||||
memset( &newFileEntry->entry.raw[0], 0x00, 0x200 );
|
||||
memset( &newFileEntry->entry.raw[0], 0x00, sizeof( newFileEntry->entry.raw ) );
|
||||
|
||||
wxFileName metaFileName( dirPath, fileName );
|
||||
metaFileName.AppendDir( L"_pcsx2_meta" );
|
||||
wxFFile metaFile;
|
||||
if ( metaFileName.FileExists() && metaFile.Open( metaFileName.GetFullPath(), L"rb" ) ) {
|
||||
metaFile.Read( &newFileEntry->entry.raw, 0x40 );
|
||||
size_t bytesRead = metaFile.Read( &newFileEntry->entry.raw, sizeof( newFileEntry->entry.raw ) );
|
||||
metaFile.Close();
|
||||
if ( bytesRead < 0x60 ) {
|
||||
strcpy( (char*)&newFileEntry->entry.data.name[0], fileName.mbc_str() );
|
||||
}
|
||||
} else {
|
||||
newFileEntry->entry.data.mode = MemoryCardFileEntry::DefaultFileMode;
|
||||
newFileEntry->entry.data.timeCreated = MemoryCardFileEntryDateTime::FromWxDateTime( creationTime );
|
||||
newFileEntry->entry.data.timeModified = MemoryCardFileEntryDateTime::FromWxDateTime( modificationTime );
|
||||
strcpy( (char*)&newFileEntry->entry.data.name[0], fileName.mbc_str() );
|
||||
}
|
||||
|
||||
newFileEntry->entry.data.length = filesize;
|
||||
u32 fileDataStartingCluster = GetFreeDataCluster();
|
||||
newFileEntry->entry.data.cluster = fileDataStartingCluster;
|
||||
strcpy( (char*)&newFileEntry->entry.data.name[0], fileName.mbc_str() );
|
||||
|
||||
// mark the appropriate amount of clusters as used
|
||||
u32 dataCluster = fileDataStartingCluster;
|
||||
|
@ -478,18 +481,6 @@ void FolderMemoryCard::AddFileEntryToMetadataQuickAccess( MemoryCardFileEntry* c
|
|||
} while ( ( fileCluster = m_fat.data[0][0][fileCluster] ) != 0xFFFFFFFFu );
|
||||
}
|
||||
|
||||
void MemoryCardFileMetadataReference::GetPath( wxFileName* fileName ) {
|
||||
if ( parent ) {
|
||||
parent->GetPath( fileName );
|
||||
}
|
||||
|
||||
if ( entry->IsDir() ) {
|
||||
fileName->AppendDir( wxString::FromAscii( (const char*)entry->entry.data.name ) );
|
||||
} else if ( entry->IsFile() ) {
|
||||
fileName->SetName( wxString::FromAscii( (const char*)entry->entry.data.name ) );
|
||||
}
|
||||
}
|
||||
|
||||
s32 FolderMemoryCard::IsPresent() {
|
||||
return m_isEnabled;
|
||||
}
|
||||
|
@ -1116,7 +1107,7 @@ wxFFile* FileAccessHelper::Open( const wxFileName& folderName, MemoryCardFileMet
|
|||
this->Close();
|
||||
|
||||
wxFileName fn( folderName );
|
||||
fileRef->GetPath( &fn );
|
||||
bool cleanedFilename = fileRef->GetPath( &fn );
|
||||
wxString filename( fn.GetFullPath() );
|
||||
|
||||
if ( !fn.FileExists() ) {
|
||||
|
@ -1136,13 +1127,13 @@ wxFFile* FileAccessHelper::Open( const wxFileName& folderName, MemoryCardFileMet
|
|||
|
||||
// write metadata of file if it's nonstandard
|
||||
fn.AppendDir( L"_pcsx2_meta" );
|
||||
if ( entry->entry.data.mode != MemoryCardFileEntry::DefaultFileMode || entry->entry.data.attr != 0 ) {
|
||||
if ( cleanedFilename || entry->entry.data.mode != MemoryCardFileEntry::DefaultFileMode || entry->entry.data.attr != 0 ) {
|
||||
if ( !fn.DirExists() ) {
|
||||
fn.Mkdir();
|
||||
}
|
||||
wxFFile metaFile( fn.GetFullPath(), L"wb" );
|
||||
if ( metaFile.IsOpened() ) {
|
||||
metaFile.Write( entry->entry.raw, 0x40 );
|
||||
metaFile.Write( entry->entry.raw, sizeof( entry->entry.raw ) );
|
||||
metaFile.Close();
|
||||
}
|
||||
} else {
|
||||
|
@ -1178,6 +1169,46 @@ void FileAccessHelper::Close() {
|
|||
}
|
||||
}
|
||||
|
||||
bool FileAccessHelper::CleanMemcardFilename( char* name ) {
|
||||
// invalid characters for filenames in the PS2 file system: { '/', '?', '*' }
|
||||
// the following characters are valid in a PS2 memcard file system but invalid in Windows
|
||||
// there's less restrictions on Linux but by cleaning them always we keep the folders cross-compatible
|
||||
const char illegalChars[] = { '\\', '%', ':', '|', '"', '<', '>' };
|
||||
bool cleaned = false;
|
||||
|
||||
for ( int i = 0; i < sizeof( illegalChars ); ++i ) {
|
||||
// this sizeof looks really odd but I couldn't get MemoryCardFileEntry::entry.data.name (or variants) working, feel free to replace with something equivalent but nicer looking
|
||||
for ( int j = 0; j < sizeof( ( (MemoryCardFileEntry*)0 )->entry.data.name ); ++j ) {
|
||||
if ( name[j] == illegalChars[i] ) {
|
||||
name[j] = '_';
|
||||
cleaned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cleaned;
|
||||
}
|
||||
|
||||
|
||||
bool MemoryCardFileMetadataReference::GetPath( wxFileName* fileName ) {
|
||||
bool parentCleaned = false;
|
||||
if ( parent ) {
|
||||
parentCleaned = parent->GetPath( fileName );
|
||||
}
|
||||
|
||||
char cleanName[sizeof( entry->entry.data.name )];
|
||||
memcpy( cleanName, (const char*)entry->entry.data.name, sizeof( cleanName ) );
|
||||
bool localCleaned = FileAccessHelper::CleanMemcardFilename( cleanName );
|
||||
|
||||
if ( entry->IsDir() ) {
|
||||
fileName->AppendDir( wxString::FromAscii( cleanName ) );
|
||||
} else if ( entry->IsFile() ) {
|
||||
fileName->SetName( wxString::FromAscii( cleanName ) );
|
||||
}
|
||||
|
||||
return parentCleaned || localCleaned;
|
||||
}
|
||||
|
||||
|
||||
FolderMemoryCardAggregator::FolderMemoryCardAggregator() {
|
||||
for ( uint i = 0; i < TotalCardSlots; ++i ) {
|
||||
|
|
|
@ -140,7 +140,8 @@ struct MemoryCardFileMetadataReference {
|
|||
MemoryCardFileEntry* entry;
|
||||
u32 consecutiveCluster;
|
||||
|
||||
void GetPath( wxFileName* fileName );
|
||||
// returns true if filename was modified and metadata containing the actual filename should be written
|
||||
bool GetPath( wxFileName* fileName );
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -162,6 +163,10 @@ public:
|
|||
// Close an open file, if any
|
||||
void Close();
|
||||
|
||||
// removes characters from a PS2 file name that would be illegal in a Windows file system
|
||||
// returns true if any changes were made
|
||||
static bool CleanMemcardFilename( char* name );
|
||||
|
||||
protected:
|
||||
// Open a new file and remember it for later
|
||||
wxFFile* Open( const wxFileName& folderName, MemoryCardFileMetadataReference* fileRef, const wxString& mode, bool writeMetadata = false );
|
||||
|
|
Loading…
Reference in New Issue