FileManager-based profile mounts
This commit is contained in:
@@ -15,6 +15,8 @@
|
|||||||
#include "arch/arch.h"
|
#include "arch/arch.h"
|
||||||
#include "PrefsManager.h"
|
#include "PrefsManager.h"
|
||||||
#include "RageLog.h"
|
#include "RageLog.h"
|
||||||
|
#include "RageFile.h"
|
||||||
|
#include "RageFileManager.h"
|
||||||
#include "IniFile.h"
|
#include "IniFile.h"
|
||||||
#include "GameConstantsAndTypes.h"
|
#include "GameConstantsAndTypes.h"
|
||||||
#include "SongManager.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_MEM_CARD_NAME "NewCard"
|
||||||
#define NEW_PROFILE_NAME "NewProfile"
|
#define NEW_PROFILE_NAME "NewProfile"
|
||||||
|
|
||||||
|
static const char *MemCardDirs[NUM_PLAYERS] =
|
||||||
|
{
|
||||||
|
/* @ is important; see RageFileManager LoadedDriver::GetPath */
|
||||||
|
"@mc1" SLASH,
|
||||||
|
"@mc2" SLASH,
|
||||||
|
};
|
||||||
|
|
||||||
ProfileManager::ProfileManager()
|
ProfileManager::ProfileManager()
|
||||||
{
|
{
|
||||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||||
|
{
|
||||||
m_bUsingMemoryCard[p] = false;
|
m_bUsingMemoryCard[p] = false;
|
||||||
|
|
||||||
|
if( PREFSMAN->m_sMemoryCardDir[p] != "" )
|
||||||
|
FILEMAN->Mount( "dir", PREFSMAN->m_sMemoryCardDir[p], MemCardDirs[p] );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileManager::~ProfileManager()
|
ProfileManager::~ProfileManager()
|
||||||
@@ -125,79 +139,15 @@ bool ProfileManager::LoadDefaultProfileFromMachine( PlayerNumber pn )
|
|||||||
return LoadProfile( pn, sDir, false );
|
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 )
|
bool ProfileManager::IsMemoryCardInserted( PlayerNumber pn )
|
||||||
{
|
{
|
||||||
CString sDir = GetMemCardDir( pn );
|
return FILEMAN->MountpointIsReady( MemCardDirs[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<CString> 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProfileManager::LoadProfileFromMemoryCard( PlayerNumber pn )
|
bool ProfileManager::LoadProfileFromMemoryCard( PlayerNumber pn )
|
||||||
{
|
{
|
||||||
CString sDir = GetMemCardDir( pn );
|
CString sDir = MemCardDirs[pn];
|
||||||
if( sDir.empty() )
|
if( !FILEMAN->IsMounted(sDir) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_bUsingMemoryCard[pn] = true;
|
m_bUsingMemoryCard[pn] = true;
|
||||||
@@ -218,7 +168,7 @@ bool ProfileManager::LoadFirstAvailableProfile( PlayerNumber pn )
|
|||||||
if( LoadProfileFromMemoryCard(pn) )
|
if( LoadProfileFromMemoryCard(pn) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
CString sDir = GetMemCardDir( pn );
|
CString sDir = MemCardDirs[pn];
|
||||||
CreateProfile( sDir, NEW_MEM_CARD_NAME );
|
CreateProfile( sDir, NEW_MEM_CARD_NAME );
|
||||||
if( LoadProfileFromMemoryCard(pn) )
|
if( LoadProfileFromMemoryCard(pn) )
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ public:
|
|||||||
virtual RageFileManager::FileType GetFileType( CString sPath ) = 0;
|
virtual RageFileManager::FileType GetFileType( CString sPath ) = 0;
|
||||||
virtual int GetFileSizeInBytes( CString sFilePath ) = 0;
|
virtual int GetFileSizeInBytes( CString sFilePath ) = 0;
|
||||||
virtual int GetFileModTime( CString sPath ) = 0;
|
virtual int GetFileModTime( CString sPath ) = 0;
|
||||||
|
virtual bool Ready() { return true; } /* see RageFileManager::MountpointIsReady */
|
||||||
};
|
};
|
||||||
|
|
||||||
class RageFileObj
|
class RageFileObj
|
||||||
|
|||||||
@@ -99,6 +99,56 @@ int RageFileDriverDirect::GetFileModTime( CString sPath )
|
|||||||
return st.st_mtime;
|
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<CString> 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 ):
|
RageFileObjDirect::RageFileObjDirect( int fd_, RageFile &p ):
|
||||||
RageFileObj( p )
|
RageFileObj( p )
|
||||||
{
|
{
|
||||||
@@ -162,5 +212,6 @@ int RageFileObjDirect::GetFileSize()
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003 by the person(s) listed below. All rights reserved.
|
* Copyright (c) 2003 by the person(s) listed below. All rights reserved.
|
||||||
* Glenn Maynard
|
* Glenn Maynard
|
||||||
|
* Chris Danford
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ public:
|
|||||||
RageFileManager::FileType GetFileType( CString sPath );
|
RageFileManager::FileType GetFileType( CString sPath );
|
||||||
int GetFileSizeInBytes( CString sFilePath );
|
int GetFileSizeInBytes( CString sFilePath );
|
||||||
int GetFileModTime( CString sPath );
|
int GetFileModTime( CString sPath );
|
||||||
|
bool Ready();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CString root;
|
CString root;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ struct LoadedDriver
|
|||||||
* only send "Foo/Bar". The path "Themes/Foo" is out of the scope
|
* only send "Foo/Bar". The path "Themes/Foo" is out of the scope
|
||||||
* of the driver, and GetPath returns false. */
|
* of the driver, and GetPath returns false. */
|
||||||
RageFileDriver *driver;
|
RageFileDriver *driver;
|
||||||
CString base;
|
CString MountPoint;
|
||||||
|
|
||||||
CString GetPath( CString path );
|
CString GetPath( CString path );
|
||||||
};
|
};
|
||||||
@@ -25,15 +25,15 @@ static vector<LoadedDriver> g_Drivers;
|
|||||||
RageFileManager::RageFileManager()
|
RageFileManager::RageFileManager()
|
||||||
{
|
{
|
||||||
#if defined(XBOX)
|
#if defined(XBOX)
|
||||||
RageFileManager::AddFS( "dir", ".", "" );
|
RageFileManager::Mount( "dir", ".", "" );
|
||||||
/* XXX: drop BASE_PATH and do this instead */
|
/* XXX: drop BASE_PATH and do this instead */
|
||||||
// RageFileManager::AddFS( "dir", "D:\\", "" );
|
// RageFileManager::Mount( "dir", "D:\\", "" );
|
||||||
#else
|
#else
|
||||||
/* Paths relative to the CWD: */
|
/* Paths relative to the CWD: */
|
||||||
RageFileManager::AddFS( "dir", ".", "" );
|
RageFileManager::Mount( "dir", ".", "" );
|
||||||
|
|
||||||
/* Absolute paths. This is rarely used, eg. by Alsa9Buf::GetSoundCardDebugInfo(). */
|
/* Absolute paths. This is rarely used, eg. by Alsa9Buf::GetSoundCardDebugInfo(). */
|
||||||
RageFileManager::AddFS( "dir", "/", "/" );
|
RageFileManager::Mount( "dir", "/", "/" );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
@@ -41,7 +41,7 @@ RageFileManager::RageFileManager()
|
|||||||
for( char c = 'A'; c <= 'Z'; ++c )
|
for( char c = 'A'; c <= 'Z'; ++c )
|
||||||
{
|
{
|
||||||
const CString path = ssprintf( "%c:/", c );
|
const CString path = ssprintf( "%c:/", c );
|
||||||
RageFileManager::AddFS( "dir", path, path );
|
RageFileManager::Mount( "dir", path, path );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -56,24 +56,26 @@ RageFileManager::~RageFileManager()
|
|||||||
|
|
||||||
CString LoadedDriver::GetPath( CString path )
|
CString LoadedDriver::GetPath( CString path )
|
||||||
{
|
{
|
||||||
if( base.size() == 0 )
|
/* If the path begins with @, default mount points don't count. */
|
||||||
return path;
|
const bool Dedicated = ( path.size() && path[0] == '@' );
|
||||||
|
if( MountPoint.size() == 0 )
|
||||||
|
return Dedicated? "":path;
|
||||||
|
|
||||||
/* Map all slashes to forward slash. */
|
/* Map all slashes to forward slash. */
|
||||||
path.Replace( "\\", "/" );
|
path.Replace( "\\", "/" );
|
||||||
|
|
||||||
if( path.Left( base.size() ).CompareNoCase( base ) )
|
if( path.Left( MountPoint.size() ).CompareNoCase( MountPoint ) )
|
||||||
return ""; /* no match */
|
return ""; /* no match */
|
||||||
|
|
||||||
return path.Right( path.size() - base.size() );
|
return path.Right( path.size() - MountPoint.size() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#include "RageFileDriverDirect.h"
|
#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) != "/" )
|
if( MountPoint.size() && MountPoint.Right(1) != "/" )
|
||||||
Base += '/';
|
MountPoint += '/';
|
||||||
ASSERT( Root != "" );
|
ASSERT( Root != "" );
|
||||||
if( Root.Right(1) != "/" )
|
if( Root.Right(1) != "/" )
|
||||||
Root += '/';
|
Root += '/';
|
||||||
@@ -88,10 +90,34 @@ void RageFileManager::AddFS( CString Type, CString Root, CString Base )
|
|||||||
return;
|
return;
|
||||||
LoadedDriver ld;
|
LoadedDriver ld;
|
||||||
ld.driver = driver;
|
ld.driver = driver;
|
||||||
ld.base = Base;
|
ld.MountPoint = MountPoint;
|
||||||
g_Drivers.push_back( ld );
|
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 )
|
RageFileManager::FileType RageFileManager::GetFileType( const CString &sPath )
|
||||||
{
|
{
|
||||||
for( unsigned i = 0; i < g_Drivers.size(); ++i )
|
for( unsigned i = 0; i < g_Drivers.size(); ++i )
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ public:
|
|||||||
int GetFileSizeInBytes( const CString &sPath );
|
int GetFileSizeInBytes( const CString &sPath );
|
||||||
int GetFileModTime( 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: */
|
/* Used only by RageFile: */
|
||||||
RageFileObj *Open( const CString &sPath, RageFile::OpenMode mode, RageFile &p, int &err );
|
RageFileObj *Open( const CString &sPath, RageFile::OpenMode mode, RageFile &p, int &err );
|
||||||
|
|||||||
Reference in New Issue
Block a user