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 );
|
fileInfo.GetTimes( NULL, &modificationTime, &creationTime );
|
||||||
|
|
||||||
// set file entry metadata
|
// 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 );
|
wxFileName metaFileName( dirPath, fileName );
|
||||||
metaFileName.AppendDir( L"_pcsx2_meta" );
|
metaFileName.AppendDir( L"_pcsx2_meta" );
|
||||||
wxFFile metaFile;
|
wxFFile metaFile;
|
||||||
if ( metaFileName.FileExists() && metaFile.Open( metaFileName.GetFullPath(), L"rb" ) ) {
|
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();
|
metaFile.Close();
|
||||||
|
if ( bytesRead < 0x60 ) {
|
||||||
|
strcpy( (char*)&newFileEntry->entry.data.name[0], fileName.mbc_str() );
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
newFileEntry->entry.data.mode = MemoryCardFileEntry::DefaultFileMode;
|
newFileEntry->entry.data.mode = MemoryCardFileEntry::DefaultFileMode;
|
||||||
newFileEntry->entry.data.timeCreated = MemoryCardFileEntryDateTime::FromWxDateTime( creationTime );
|
newFileEntry->entry.data.timeCreated = MemoryCardFileEntryDateTime::FromWxDateTime( creationTime );
|
||||||
newFileEntry->entry.data.timeModified = MemoryCardFileEntryDateTime::FromWxDateTime( modificationTime );
|
newFileEntry->entry.data.timeModified = MemoryCardFileEntryDateTime::FromWxDateTime( modificationTime );
|
||||||
|
strcpy( (char*)&newFileEntry->entry.data.name[0], fileName.mbc_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
newFileEntry->entry.data.length = filesize;
|
newFileEntry->entry.data.length = filesize;
|
||||||
u32 fileDataStartingCluster = GetFreeDataCluster();
|
u32 fileDataStartingCluster = GetFreeDataCluster();
|
||||||
newFileEntry->entry.data.cluster = fileDataStartingCluster;
|
newFileEntry->entry.data.cluster = fileDataStartingCluster;
|
||||||
strcpy( (char*)&newFileEntry->entry.data.name[0], fileName.mbc_str() );
|
|
||||||
|
|
||||||
// mark the appropriate amount of clusters as used
|
// mark the appropriate amount of clusters as used
|
||||||
u32 dataCluster = fileDataStartingCluster;
|
u32 dataCluster = fileDataStartingCluster;
|
||||||
|
@ -478,18 +481,6 @@ void FolderMemoryCard::AddFileEntryToMetadataQuickAccess( MemoryCardFileEntry* c
|
||||||
} while ( ( fileCluster = m_fat.data[0][0][fileCluster] ) != 0xFFFFFFFFu );
|
} 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() {
|
s32 FolderMemoryCard::IsPresent() {
|
||||||
return m_isEnabled;
|
return m_isEnabled;
|
||||||
}
|
}
|
||||||
|
@ -1116,7 +1107,7 @@ wxFFile* FileAccessHelper::Open( const wxFileName& folderName, MemoryCardFileMet
|
||||||
this->Close();
|
this->Close();
|
||||||
|
|
||||||
wxFileName fn( folderName );
|
wxFileName fn( folderName );
|
||||||
fileRef->GetPath( &fn );
|
bool cleanedFilename = fileRef->GetPath( &fn );
|
||||||
wxString filename( fn.GetFullPath() );
|
wxString filename( fn.GetFullPath() );
|
||||||
|
|
||||||
if ( !fn.FileExists() ) {
|
if ( !fn.FileExists() ) {
|
||||||
|
@ -1136,13 +1127,13 @@ wxFFile* FileAccessHelper::Open( const wxFileName& folderName, MemoryCardFileMet
|
||||||
|
|
||||||
// write metadata of file if it's nonstandard
|
// write metadata of file if it's nonstandard
|
||||||
fn.AppendDir( L"_pcsx2_meta" );
|
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() ) {
|
if ( !fn.DirExists() ) {
|
||||||
fn.Mkdir();
|
fn.Mkdir();
|
||||||
}
|
}
|
||||||
wxFFile metaFile( fn.GetFullPath(), L"wb" );
|
wxFFile metaFile( fn.GetFullPath(), L"wb" );
|
||||||
if ( metaFile.IsOpened() ) {
|
if ( metaFile.IsOpened() ) {
|
||||||
metaFile.Write( entry->entry.raw, 0x40 );
|
metaFile.Write( entry->entry.raw, sizeof( entry->entry.raw ) );
|
||||||
metaFile.Close();
|
metaFile.Close();
|
||||||
}
|
}
|
||||||
} else {
|
} 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() {
|
FolderMemoryCardAggregator::FolderMemoryCardAggregator() {
|
||||||
for ( uint i = 0; i < TotalCardSlots; ++i ) {
|
for ( uint i = 0; i < TotalCardSlots; ++i ) {
|
||||||
|
|
|
@ -140,7 +140,8 @@ struct MemoryCardFileMetadataReference {
|
||||||
MemoryCardFileEntry* entry;
|
MemoryCardFileEntry* entry;
|
||||||
u32 consecutiveCluster;
|
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
|
// Close an open file, if any
|
||||||
void Close();
|
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:
|
protected:
|
||||||
// Open a new file and remember it for later
|
// Open a new file and remember it for later
|
||||||
wxFFile* Open( const wxFileName& folderName, MemoryCardFileMetadataReference* fileRef, const wxString& mode, bool writeMetadata = false );
|
wxFFile* Open( const wxFileName& folderName, MemoryCardFileMetadataReference* fileRef, const wxString& mode, bool writeMetadata = false );
|
||||||
|
|
Loading…
Reference in New Issue