From a31ff1f434b6c07859fb03dba2fd7ed8c814ea00 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Fri, 5 Dec 2003 00:07:18 +0000 Subject: [PATCH] FileManager-based profile mounts --- stepmania/src/ProfileManager.cpp | 86 ++++++-------------------- stepmania/src/RageFileDriver.h | 1 + stepmania/src/RageFileDriverDirect.cpp | 51 +++++++++++++++ stepmania/src/RageFileDriverDirect.h | 1 + stepmania/src/RageFileManager.cpp | 56 ++++++++++++----- stepmania/src/RageFileManager.h | 4 +- 6 files changed, 115 insertions(+), 84 deletions(-) diff --git a/stepmania/src/ProfileManager.cpp b/stepmania/src/ProfileManager.cpp index 32eeffd8ab..54cee5656b 100644 --- a/stepmania/src/ProfileManager.cpp +++ b/stepmania/src/ProfileManager.cpp @@ -15,6 +15,8 @@ #include "arch/arch.h" #include "PrefsManager.h" #include "RageLog.h" +#include "RageFile.h" +#include "RageFileManager.h" #include "IniFile.h" #include "GameConstantsAndTypes.h" #include "SongManager.h" @@ -34,10 +36,22 @@ ProfileManager* PROFILEMAN = NULL; // global and accessable from anywhere in our #define NEW_MEM_CARD_NAME "NewCard" #define NEW_PROFILE_NAME "NewProfile" +static const char *MemCardDirs[NUM_PLAYERS] = +{ + /* @ is important; see RageFileManager LoadedDriver::GetPath */ + "@mc1" SLASH, + "@mc2" SLASH, +}; + ProfileManager::ProfileManager() { for( int p=0; pm_sMemoryCardDir[p] != "" ) + FILEMAN->Mount( "dir", PREFSMAN->m_sMemoryCardDir[p], MemCardDirs[p] ); + } } ProfileManager::~ProfileManager() @@ -125,79 +139,15 @@ bool ProfileManager::LoadDefaultProfileFromMachine( PlayerNumber pn ) return LoadProfile( pn, sDir, false ); } -CString GetMemCardDir( PlayerNumber pn ) -{ - CString sDir = PREFSMAN->m_sMemoryCardDir[pn]; - if( sDir.empty() ) - return sDir; - if( sDir.Right(1) != SLASH ) - sDir += SLASH; - return sDir; -} - bool ProfileManager::IsMemoryCardInserted( PlayerNumber pn ) { - CString sDir = GetMemCardDir( pn ); - if( sDir.empty() ) - return false; - -#ifdef _WINDOWS - // Windows will throw up a message box if we try to write to a - // removable drive with no disk inserted. Find out whether there's a - // disk in the drive w/o writing a file. - - // find drive letter - vector matches; - static Regex parse("^([A-Za-z]+):"); - parse.Compare(sDir, matches); - if( matches.size() != 1 ) - { - return false; - } - else - { - CString sDrive = matches[0]; - TCHAR szVolumeNameBuffer[MAX_PATH]; - DWORD dwVolumeSerialNumber; - DWORD dwMaximumComponentLength; - DWORD lpFileSystemFlags; - TCHAR szFileSystemNameBuffer[MAX_PATH]; - BOOL bResult = GetVolumeInformation( - sDrive + ":", - szVolumeNameBuffer, - sizeof(szVolumeNameBuffer), - &dwVolumeSerialNumber, - &dwMaximumComponentLength, - &lpFileSystemFlags, - szFileSystemNameBuffer, - sizeof(szFileSystemNameBuffer) ); - return !!bResult; - } -#else - - // Try to create directory before writing a temp file. - CreateDirectories( sDir ); - - // Test whether a memory card is usable by trying to write a file. - CString sFile = sDir + "temp"; - FILE* fp = fopen( sFile, "w" ); - if( fp ) - { - fclose( fp ); - remove( sFile ); - return true; - } - else - { - return false; - } -#endif + return FILEMAN->MountpointIsReady( MemCardDirs[pn] ); } bool ProfileManager::LoadProfileFromMemoryCard( PlayerNumber pn ) { - CString sDir = GetMemCardDir( pn ); - if( sDir.empty() ) + CString sDir = MemCardDirs[pn]; + if( !FILEMAN->IsMounted(sDir) ) return false; m_bUsingMemoryCard[pn] = true; @@ -218,7 +168,7 @@ bool ProfileManager::LoadFirstAvailableProfile( PlayerNumber pn ) if( LoadProfileFromMemoryCard(pn) ) return true; - CString sDir = GetMemCardDir( pn ); + CString sDir = MemCardDirs[pn]; CreateProfile( sDir, NEW_MEM_CARD_NAME ); if( LoadProfileFromMemoryCard(pn) ) return true; diff --git a/stepmania/src/RageFileDriver.h b/stepmania/src/RageFileDriver.h index bf2275ee49..301cf69386 100644 --- a/stepmania/src/RageFileDriver.h +++ b/stepmania/src/RageFileDriver.h @@ -12,6 +12,7 @@ public: virtual RageFileManager::FileType GetFileType( CString sPath ) = 0; virtual int GetFileSizeInBytes( CString sFilePath ) = 0; virtual int GetFileModTime( CString sPath ) = 0; + virtual bool Ready() { return true; } /* see RageFileManager::MountpointIsReady */ }; class RageFileObj diff --git a/stepmania/src/RageFileDriverDirect.cpp b/stepmania/src/RageFileDriverDirect.cpp index 3237fd38cc..3c222eb504 100644 --- a/stepmania/src/RageFileDriverDirect.cpp +++ b/stepmania/src/RageFileDriverDirect.cpp @@ -99,6 +99,56 @@ int RageFileDriverDirect::GetFileModTime( CString sPath ) return st.st_mtime; } +#ifdef _WINDOWS +#include "windows.h" +#endif +bool RageFileDriverDirect::Ready() +{ +#ifdef _WINDOWS + // Windows will throw up a message box if we try to write to a + // removable drive with no disk inserted. Find out whether there's a + // disk in the drive w/o writing a file. + + // find drive letter + vector matches; + static Regex parse("^([A-Za-z]+):"); + parse.Compare( root, matches ); + if( matches.size() != 1 ) + return false; + + CString sDrive = matches[0]; + TCHAR szVolumeNameBuffer[MAX_PATH]; + DWORD dwVolumeSerialNumber; + DWORD dwMaximumComponentLength; + DWORD lpFileSystemFlags; + TCHAR szFileSystemNameBuffer[MAX_PATH]; + BOOL bResult = GetVolumeInformation( + sDrive + ":\\", + szVolumeNameBuffer, + sizeof(szVolumeNameBuffer), + &dwVolumeSerialNumber, + &dwMaximumComponentLength, + &lpFileSystemFlags, + szFileSystemNameBuffer, + sizeof(szFileSystemNameBuffer) ); + return !!bResult; +#else + + // Try to create directory before writing a temp file. + CreateDirectories( sDir ); // XXX + + // Try to write a file. + CString sFile = sDir + "temp"; + RageFile f; + if( !f.Open( sFile, RageFile::WRITE ) ) + return false; + + f.Close(); + remove( sFile ); + return true; +#endif +} + RageFileObjDirect::RageFileObjDirect( int fd_, RageFile &p ): RageFileObj( p ) { @@ -162,5 +212,6 @@ int RageFileObjDirect::GetFileSize() /* * Copyright (c) 2003 by the person(s) listed below. All rights reserved. * Glenn Maynard + * Chris Danford */ diff --git a/stepmania/src/RageFileDriverDirect.h b/stepmania/src/RageFileDriverDirect.h index 5fb35a2ba8..4d22dd9815 100644 --- a/stepmania/src/RageFileDriverDirect.h +++ b/stepmania/src/RageFileDriverDirect.h @@ -13,6 +13,7 @@ public: RageFileManager::FileType GetFileType( CString sPath ); int GetFileSizeInBytes( CString sFilePath ); int GetFileModTime( CString sPath ); + bool Ready(); private: CString root; diff --git a/stepmania/src/RageFileManager.cpp b/stepmania/src/RageFileManager.cpp index 6e6254e86d..2261d7dce0 100644 --- a/stepmania/src/RageFileManager.cpp +++ b/stepmania/src/RageFileManager.cpp @@ -14,7 +14,7 @@ struct LoadedDriver * only send "Foo/Bar". The path "Themes/Foo" is out of the scope * of the driver, and GetPath returns false. */ RageFileDriver *driver; - CString base; + CString MountPoint; CString GetPath( CString path ); }; @@ -25,15 +25,15 @@ static vector g_Drivers; RageFileManager::RageFileManager() { #if defined(XBOX) - RageFileManager::AddFS( "dir", ".", "" ); + RageFileManager::Mount( "dir", ".", "" ); /* XXX: drop BASE_PATH and do this instead */ -// RageFileManager::AddFS( "dir", "D:\\", "" ); +// RageFileManager::Mount( "dir", "D:\\", "" ); #else /* Paths relative to the CWD: */ - RageFileManager::AddFS( "dir", ".", "" ); + RageFileManager::Mount( "dir", ".", "" ); /* Absolute paths. This is rarely used, eg. by Alsa9Buf::GetSoundCardDebugInfo(). */ - RageFileManager::AddFS( "dir", "/", "/" ); + RageFileManager::Mount( "dir", "/", "/" ); #endif #if defined(WIN32) @@ -41,7 +41,7 @@ RageFileManager::RageFileManager() for( char c = 'A'; c <= 'Z'; ++c ) { const CString path = ssprintf( "%c:/", c ); - RageFileManager::AddFS( "dir", path, path ); + RageFileManager::Mount( "dir", path, path ); } #endif } @@ -56,24 +56,26 @@ RageFileManager::~RageFileManager() CString LoadedDriver::GetPath( CString path ) { - if( base.size() == 0 ) - return path; + /* If the path begins with @, default mount points don't count. */ + const bool Dedicated = ( path.size() && path[0] == '@' ); + if( MountPoint.size() == 0 ) + return Dedicated? "":path; /* Map all slashes to forward slash. */ path.Replace( "\\", "/" ); - if( path.Left( base.size() ).CompareNoCase( base ) ) + if( path.Left( MountPoint.size() ).CompareNoCase( MountPoint ) ) return ""; /* no match */ - return path.Right( path.size() - base.size() ); + return path.Right( path.size() - MountPoint.size() ); } #include "RageFileDriverDirect.h" -void RageFileManager::AddFS( CString Type, CString Root, CString Base ) +void RageFileManager::Mount( CString Type, CString Root, CString MountPoint ) { - if( Base.size() && Base.Right(1) != "/" ) - Base += '/'; + if( MountPoint.size() && MountPoint.Right(1) != "/" ) + MountPoint += '/'; ASSERT( Root != "" ); if( Root.Right(1) != "/" ) Root += '/'; @@ -88,10 +90,34 @@ void RageFileManager::AddFS( CString Type, CString Root, CString Base ) return; LoadedDriver ld; ld.driver = driver; - ld.base = Base; + ld.MountPoint = MountPoint; g_Drivers.push_back( ld ); } - + +bool RageFileManager::IsMounted( CString MountPoint ) +{ + for( unsigned i = 0; i < g_Drivers.size(); ++i ) + if( !g_Drivers[i].MountPoint.CompareNoCase( MountPoint ) ) + return true; + + return false; +} + +/* Return true if the driver with the given root path is ready (eg. CD or memory card + * inserted). */ +bool RageFileManager::MountpointIsReady( CString MountPoint ) +{ + for( unsigned i = 0; i < g_Drivers.size(); ++i ) + { + if( g_Drivers[i].MountPoint.CompareNoCase( MountPoint ) ) + continue; + + return g_Drivers[i].driver->Ready(); + } + + return false; +} + RageFileManager::FileType RageFileManager::GetFileType( const CString &sPath ) { for( unsigned i = 0; i < g_Drivers.size(); ++i ) diff --git a/stepmania/src/RageFileManager.h b/stepmania/src/RageFileManager.h index 1f0454aab7..cca23d22f1 100644 --- a/stepmania/src/RageFileManager.h +++ b/stepmania/src/RageFileManager.h @@ -20,7 +20,9 @@ public: int GetFileSizeInBytes( const CString &sPath ); int GetFileModTime( const CString &sPath ); - void AddFS( CString Type, CString RealPath, CString Root ); + void Mount( CString Type, CString RealPath, CString MountPoint ); + bool IsMounted( CString MountPoint ); + bool MountpointIsReady( CString MountPoint ); /* Used only by RageFile: */ RageFileObj *Open( const CString &sPath, RageFile::OpenMode mode, RageFile &p, int &err );