/* ======================================================================================= Name :SaveMngr.cpp Author :Vincent Lhullier Date :11/07/97 Description :manage save of data before modification Create a copy of GameData tree with all file that would be modified. That will allow someone to recuperate previous version if save generate some problem in data. ======================================================================================= Modification -> Author : Date : Description : ======================================================================================= */ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #include "stdafx.h" #include #include #include "SaveMngr.h" #include "IniData.h" /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* ======================================================================================= CONSTANTS ======================================================================================= */ #define C_szGameDataDir "GameData" #define C_szOldGameDataDir "GameDat_" /* ======================================================================================= GLOBALS ======================================================================================= */ static char SAVE_g_szDirName[ _MAX_PATH ]; /* ======================================================================================= ======================================================================================= FUNCTIONS ======================================================================================= ======================================================================================= */ /* ======================================================================================= Directory Functions ======================================================================================= */ /* ---------------------------------------------------------------------------------------- Don't call this function directly, it is used by SAVE_fn_bDeleteTree Description : delete recursively a directory Returns (BOOL ) true if success ---------------------------------------------------------------------------------------- */ BOOL fn_bDeleteTree( void ) { WIN32_FIND_DATA stFindData; HANDLE hFind; char *p_szEndDirName; p_szEndDirName = SAVE_g_szDirName + strlen( SAVE_g_szDirName ); strcpy( p_szEndDirName, "\\*.*" ); if( (hFind = FindFirstFile(SAVE_g_szDirName, &stFindData )) == INVALID_HANDLE_VALUE) return TRUE; *p_szEndDirName = 0; do { *p_szEndDirName = '\\'; strcpy( p_szEndDirName + 1, stFindData.cFileName ); if ( stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { if ( *stFindData.cFileName != '.') { if ( !fn_bDeleteTree() ) return FALSE; } } else { if (_access( SAVE_g_szDirName, 2) == -1 ) _chmod( SAVE_g_szDirName, _S_IWRITE ); if ( !DeleteFile( SAVE_g_szDirName ) ) return FALSE; } *p_szEndDirName = 0; } while(FindNextFile( hFind, &stFindData )); FindClose( hFind ); return RemoveDirectory( SAVE_g_szDirName ); } /* ---------------------------------------------------------------------------------------- Description : delete completely a directory szDirName -> name of dir to delete Returns (BOOL ) true if success ---------------------------------------------------------------------------------------- */ BOOL SAVE_fn_bDeleteTree( char *szDirName ) { strcpy( SAVE_g_szDirName, szDirName ); return fn_bDeleteTree(); } /* ======================================================================================= Error functions ======================================================================================= */ /* ---------------------------------------------------------------------------------------- Description : display an error message _szMessage -> message to display ---------------------------------------------------------------------------------------- */ void SAVE_fn_vErrorMessage( char *_szMessage ) { char szError[1024]; char *p_szError = szError; p_szError += sprintf( p_szError, "Error deleting all existing version of saved data\n" ); p_szError += sprintf( p_szError, "Data in %s.XXX directory will not be correct\n" ); p_szError += sprintf( p_szError, "---------------------------------------------------\n" ); p_szError += sprintf( p_szError, "%s\n\n", _szMessage ); AfxMessageBox( szError, MB_ICONSTOP | MB_OK ); } /* ======================================================================================= Version functions ======================================================================================= */ /* ---------------------------------------------------------------------------------------- Description : _szSavedDirectoryName -> name of directory from which function extract version number Returns (long ) version number if it's a valid directory, -1 else ---------------------------------------------------------------------------------------- */ long SAVE_fn_lGetVersionNumberFromDirExt( char *_szSavedDirectoryName ) { char *p_szExt; long lVersionNumber = -1; p_szExt = strchr( _szSavedDirectoryName, '.' ); if (p_szExt != NULL) { if ( strlen( ++p_szExt ) == 3) { lVersionNumber = 0; while (*p_szExt != 0) { if ( !isdigit (*p_szExt) ) return -1; lVersionNumber = lVersionNumber * 10 + (*p_szExt++ - '0'); } } } return lVersionNumber; } /* ---------------------------------------------------------------------------------------- Description : return name of directory used to store data for a given version lVersion -> version number szVersionDirName -> to put dir name (assumed to be long enough ) ---------------------------------------------------------------------------------------- */ void SAVE_fn_vGetVersionDirName( long _lVersion, char *_szVersionDirName, BOOL _bOld ) { sprintf( _szVersionDirName, "%s\\..\\%s.%03d", g_stIniData.szLocalPath, _bOld ? C_szOldGameDataDir : C_szGameDataDir, _lVersion ); } /* ---------------------------------------------------------------------------------------- Description : delete a version directory _lVersion -> number of version Returns (BOOL ) true if success ---------------------------------------------------------------------------------------- */ BOOL SAVE_fn_bDeleteVersion( long _lVersion, BOOL _bOld ) { char szVersionName[ _MAX_PATH ]; SAVE_fn_vGetVersionDirName( _lVersion, szVersionName, _bOld); if (!SAVE_fn_bDeleteTree( szVersionName )) { char szMessage[100]; sprintf( szMessage, "Can't delete old %s version directory", szVersionName ); SAVE_fn_vErrorMessage( szMessage ); return FALSE; } return TRUE; } /* ---------------------------------------------------------------------------------------- Description : analyse the current version that are on disk a_cVersion -> array of 1000 char that will be filled each case is a flag that indicate if a version number is used or not return (long) number of used version ---------------------------------------------------------------------------------------- */ long SAVE_fn_lGetUsedVersion( char *a_cVersion, BOOL _bOld ) { WIN32_FIND_DATA stFindData; HANDLE hFind; char szFilter[ _MAX_PATH ]; long lNumberOfVersions = 0; long lVersion; /* * set all version as unused */ memset ( a_cVersion , 0, 1000 ); sprintf( szFilter, "%s\\..\\%s.*", g_stIniData.szLocalPath, _bOld ? C_szOldGameDataDir : C_szGameDataDir ); if( (hFind = FindFirstFile(szFilter, &stFindData )) == INVALID_HANDLE_VALUE) return 0; do { if ( stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { lVersion = SAVE_fn_lGetVersionNumberFromDirExt( stFindData.cFileName ); if (lVersion != -1) { a_cVersion[ lVersion ] = 1; lNumberOfVersions++ ; } } } while(FindNextFile( hFind, &stFindData )); FindClose( hFind ); return lNumberOfVersions; } /* ---------------------------------------------------------------------------------------- Description : rename a version _lOldVersion -> old version number _lNewVersion -> new version number Returns (BOOL ) ---------------------------------------------------------------------------------------- */ BOOL SAVE_fn_bRenameVersionToOldVersion( long _lVersion ) { char szOldVersion[ _MAX_PATH ]; char szVersion[ _MAX_PATH ]; SAVE_fn_vGetVersionDirName( _lVersion, szVersion, FALSE ); SAVE_fn_vGetVersionDirName( _lVersion, szOldVersion, TRUE ); if ( !MoveFile( szVersion, szOldVersion) ) { char szMessage[100]; sprintf( szMessage, "Can't rename %s version to old version %s ", szVersion, szOldVersion ); SAVE_fn_vErrorMessage( szMessage ); return FALSE; } return TRUE; } /* ======================================================================================= principal function ======================================================================================= */ /* ---------------------------------------------------------------------------------------- Description : delete all old versions and rename recent version ---------------------------------------------------------------------------------------- */ BOOL SAVE_fn_bDeleteAllVersions( void ) { char a_cVersion[1000]; long lNumberOfVersions; long lVersion; long lVersionIndex; /* * get old used versions */ lNumberOfVersions = SAVE_fn_lGetUsedVersion( a_cVersion, TRUE ); /* * remove all old versions */ for (lVersion = 0, lVersionIndex = 0; lVersion < lNumberOfVersions; lVersionIndex ++) { if (a_cVersion[ lVersionIndex ]) { lVersion ++; if (!SAVE_fn_bDeleteVersion( lVersionIndex, TRUE )) return FALSE; } } /* * get used versions */ lNumberOfVersions = SAVE_fn_lGetUsedVersion( a_cVersion, FALSE ); if (lNumberOfVersions == 0) return TRUE; /* * check for hole in version number */ for (lVersion = 0, lVersionIndex = 0; lVersion < lNumberOfVersions; lVersionIndex ++) { if (a_cVersion[ lVersionIndex ]) { lVersion ++; if (!SAVE_fn_bRenameVersionToOldVersion( lVersionIndex )) return FALSE; } } return TRUE; }