reman3/Rayman_X/cpa/Appli/BinaryTool2/src/file.cpp

545 lines
16 KiB
C++

#include "stdafx.h"
#include "file.h"
#include "globaldata.h"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
tdeStatus fn_eCreateDirectory( const char *_szDirectory )
{
if ( (!CreateDirectory( _szDirectory, NULL )) && (GetLastError() != ERROR_ALREADY_EXISTS) )
{
char *p_szCur;
p_szCur = strchr( _szDirectory, '\\');
while (p_szCur != NULL)
{
*p_szCur = 0;
if ((!CreateDirectory (_szDirectory, NULL)) && (GetLastError() != ERROR_ALREADY_EXISTS) )
{
char szMessage[ 512 ];
sprintf( szMessage, "Can't create local path '%s'", _szDirectory );
AfxMessageBox( szMessage, MB_OK | MB_ICONSTOP );
return STATUS_C_Error;
}
*p_szCur++ = '\\';
p_szCur = strchr( p_szCur, '\\');
};
if ((!CreateDirectory (_szDirectory, NULL)) && (GetLastError() != ERROR_ALREADY_EXISTS) )
{
char szMessage[ 512 ];
sprintf( szMessage, "Can't create local path '%s'", _szDirectory );
AfxMessageBox( szMessage, MB_OK | MB_ICONSTOP );
return STATUS_C_Error;
}
}
return STATUS_C_OK;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Copy a file or a directory (no '\' at end of directory name !)
// Source may contain wilcards. Dest must be a path to a directory !
// If source is a directory, the copy is recursive
tdeStatus fn_eCopyFileOrDirectory( const char *_szSource, const char *_szDest )
{
HANDLE hCopyhandle;
WIN32_FIND_DATA stFindData;
int iNbCharactersForSourcePath;
char szSource[512];
char szDest[512];
tdeStatus eStatus;
if( (eStatus = fn_eCreateDirectory( _szDest )) != STATUS_C_OK )
return eStatus;
// No file to copy, nothing to do...
if( (hCopyhandle = FindFirstFile( _szSource, &stFindData )) == INVALID_HANDLE_VALUE )
return STATUS_C_OK;
iNbCharactersForSourcePath = (strrchr( _szSource, '\\' ) - _szSource);
do
{
// Skip . and ..
if( (stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
&& ( (strcmp( stFindData.cFileName, ".") == 0)
|| strcmp( stFindData.cFileName, "..") == 0) )
continue;
strncpy( szSource, _szSource, iNbCharactersForSourcePath+1 );
szSource[iNbCharactersForSourcePath+1] = 0;
strcat( szSource, stFindData.cFileName );
sprintf( szDest, "%s\\%s", _szDest, stFindData.cFileName );
// If file is a directory
if( (stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
{
strcat( szSource, "\\*.*" );
if( (eStatus = fn_eCopyFileOrDirectory( szSource, szDest )) != STATUS_C_OK )
return eStatus;
}
else
{
if( ! CopyFile( szSource, szDest, FALSE ) )
{
char szMessage[1024];
sprintf( szMessage, "Copy failed: '%s' to '%s", szSource, szDest );
AfxMessageBox( szMessage, MB_OK | MB_ICONSTOP );
return STATUS_C_Error;
}
}
// Test for end of work.
if( g_stTheGlobalData.bStopWork )
return STATUS_C_UserBreak;
} while( FindNextFile( hCopyhandle, &stFindData ) );
FindClose( hCopyhandle );
return STATUS_C_OK;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Copy some files to a directory. Function will also seach for files in sub-dirs of source.
// Source may contain wilcards. Dest must be a path to a directory !
tdeStatus fn_eRecursiveFileCopy( const char *_szSource, const char *_szDest )
{
HANDLE hDirectoryHandle;
WIN32_FIND_DATA stFindData;
int iNbCharactersForSourcePath;
char szSource[512];
char szDest[512];
tdeStatus eStatus;
// Copy this level of directory
if( (eStatus = fn_eCopyFileOrDirectory( _szSource, _szDest )) != STATUS_C_OK )
return eStatus;
// Now we are going to check for subdirs.
iNbCharactersForSourcePath = (strrchr( _szSource, '\\' ) - _szSource);
strncpy( szSource, _szSource, iNbCharactersForSourcePath+1 );
szSource[iNbCharactersForSourcePath+1] = 0;
strcat( szSource, "*.*" );
// No files in directory, nothing to do...
if( (hDirectoryHandle = FindFirstFile( szSource, &stFindData )) == INVALID_HANDLE_VALUE )
return STATUS_C_OK;
do
{
// Skip . and ..
if( (stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
&& ( (strcmp( stFindData.cFileName, ".") == 0)
|| strcmp( stFindData.cFileName, "..") == 0) )
continue;
// We treat only directories
if( (stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
{
strncpy( szSource, _szSource, iNbCharactersForSourcePath+1 );
szSource[iNbCharactersForSourcePath+1] = 0;
strcat( szSource, stFindData.cFileName );
strcat( szSource, _szSource+iNbCharactersForSourcePath );
sprintf( szDest, "%s\\%s", _szDest, stFindData.cFileName );
if( (eStatus = fn_eRecursiveFileCopy( szSource, szDest )) != STATUS_C_OK )
return eStatus;
}
// Test for end of work.
if( g_stTheGlobalData.bStopWork )
return STATUS_C_UserBreak;
} while( FindNextFile( hDirectoryHandle, &stFindData ) );
FindClose( hDirectoryHandle );
return STATUS_C_OK;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Moves file(s) or a directory (no '\' at end of directory name !)
// Source may contain wilcards. Dest must be a path to a directory !
tdeStatus fn_eMoveFileOrDirectory( const char *_szSource, const char *_szDest )
{
HANDLE hCopyhandle;
WIN32_FIND_DATA stFindData;
int iNbCharactersForSourcePath;
char szSource[512], szDest[512];
tdeStatus eStatus;
if( (eStatus = fn_eCreateDirectory( _szDest )) != STATUS_C_OK )
return eStatus;
// No file to copy, nothing to do...
if( (hCopyhandle = FindFirstFile( _szSource, &stFindData )) == INVALID_HANDLE_VALUE )
return STATUS_C_OK;
iNbCharactersForSourcePath = (strrchr( _szSource, '\\' ) - _szSource);
do
{
// Skip . and ..
if( (stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
&& ( (strcmp( stFindData.cFileName, ".") == 0)
|| strcmp( stFindData.cFileName, "..") == 0) )
continue;
strncpy( szSource, _szSource, iNbCharactersForSourcePath+1 );
szSource[iNbCharactersForSourcePath+1] = 0;
strcat( szSource, stFindData.cFileName );
sprintf( szDest, "%s\\%s", _szDest, stFindData.cFileName );
if( ! MoveFile( szSource, szDest ) )
{
char szMessage[1024];
sprintf( szMessage, "Move failed: '%s' to '%s", szSource, szDest );
AfxMessageBox( szMessage, MB_OK | MB_ICONSTOP );
return STATUS_C_Error;
}
// Test for end of work.
if( g_stTheGlobalData.bStopWork )
return STATUS_C_UserBreak;
} while( FindNextFile( hCopyhandle, &stFindData ) );
FindClose( hCopyhandle );
return STATUS_C_OK;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Deletes file(s) or directory (no '\' at end of directory name !)
// Source may contain wilcards.
// If source is a directory, the delete is recursive.
tdeStatus fn_eDeleteFileOrDirectory( const char *_szSource )
{
HANDLE hDeletehandle;
WIN32_FIND_DATA stFindData;
int iNbCharactersForSourcePath;
char szSource[512];
tdeStatus eStatus;
// No file to delete, nothing to do...
if( (hDeletehandle = FindFirstFile( _szSource, &stFindData )) == INVALID_HANDLE_VALUE )
return STATUS_C_OK;
iNbCharactersForSourcePath = (strrchr( _szSource, '\\' ) - _szSource);
do
{
// Skip . and ..
if( (stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
&& ( (strcmp( stFindData.cFileName, ".") == 0)
|| strcmp( stFindData.cFileName, "..") == 0) )
continue;
strncpy( szSource, _szSource, iNbCharactersForSourcePath+1 );
szSource[iNbCharactersForSourcePath+1] = 0;
strcat( szSource, stFindData.cFileName );
// If file is a directory
if( (stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
{
strcat( szSource, "\\*.*" );
if( (eStatus = fn_eDeleteFileOrDirectory( szSource )) != STATUS_C_OK )
return eStatus;
*strrchr( szSource, '\\' ) = 0;
if( ! RemoveDirectory( szSource ) )
{
char szMessage[1024];
sprintf( szMessage, "Delete failed on '%s'", szSource );
AfxMessageBox( szMessage, MB_OK | MB_ICONSTOP );
return STATUS_C_Error;
}
}
else if( ! DeleteFile( szSource ) )
{
char szMessage[1024];
sprintf( szMessage, "Delete failed on '%s'", szSource );
AfxMessageBox( szMessage, MB_OK | MB_ICONSTOP );
return STATUS_C_Error;
}
// Test for end of work.
if( g_stTheGlobalData.bStopWork )
return STATUS_C_UserBreak;
} while( FindNextFile( hDeletehandle, &stFindData ) );
FindClose( hDeletehandle );
return STATUS_C_OK;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// This part deals with batch copy/move of files :
// Common files for all binarised maps (no files generated by binarisation nor sound or textures)
// files relative to main directory
char *g_a_szCommonFiles[] =
{
"Copy", "Gamedata\\Options\\current.cfg", "%bin%\\Options",
"End"
};
char *g_a_szFilesBeforeBinarize[] =
{
// Make sure main directory is clean
"Delete", "fix*.sna",
"Delete", "fix*.snd",
"Delete", "fix*.ptx",
"Delete", "fix*.gpt",
"Delete", "fix.rt?",
"Delete", "%level%*.sna",
"Delete", "%level%*.snd",
"Delete", "%level%*.ptx",
"Delete", "%level%*.gpt",
"Delete", "%level%.rt?",
"End"
};
char *g_a_szFilesAfterFirstPass[] =
{
// Get fix files from gamedata\world\levels
"Move", "Gamedata\\World\\Levels\\fix*", "",
"Rename", "Fix.sna", "Fix0.sna",
"Rename", "Fix.snd", "Fix0.snd",
"Rename", "Fix.ptx", "Fix0.ptx",
"Rename", "Fix.gpt", "Fix0.gpt",
// Get level files from gamedata\world\levels\<LevelName>
"Rename", "Gamedata\\World\\Levels\\%level%\\%level%.sna", "%level%0.sna",
"Rename", "Gamedata\\World\\Levels\\%level%\\%level%.snd", "%level%0.snd",
"Rename", "Gamedata\\World\\Levels\\%level%\\%level%.ptx", "%level%0.ptx",
"Rename", "Gamedata\\World\\Levels\\%level%\\%level%.gpt", "%level%0.gpt",
"End"
};
char *g_a_szFilesAfterSecondPass[] =
{
// Get fix files from gamedata\world\levels
"Move", "Gamedata\\World\\Levels\\fix*", "",
"Rename", "Fix.sna", "Fix1.sna",
"Rename", "Fix.snd", "Fix1.snd",
"Rename", "Fix.ptx", "Fix1.ptx",
"Rename", "Fix.gpt", "Fix1.gpt",
// Get level files from gamedata\world\levels\<LevelName>
"Rename", "Gamedata\\World\\Levels\\%level%\\%level%.sna", "%level%1.sna",
"Rename", "Gamedata\\World\\Levels\\%level%\\%level%.snd", "%level%1.snd",
"Rename", "Gamedata\\World\\Levels\\%level%\\%level%.ptx", "%level%1.ptx",
"Rename", "Gamedata\\World\\Levels\\%level%\\%level%.gpt", "%level%1.gpt",
"End"
};
char *g_a_szFixFilesAfterCRB[] =
{
// Delete previous fix files
"Delete", "%bin%\\World\\Levels\\fix*",
"Delete", "%bin%\\Game.dsb",
// Delete files from second pass
"Delete", "Fix1.*",
// We will use files from first pass.
"Rename", "Fix0.sna", "Fix.sna",
"Rename", "Fix0.snd", "Fix.snd",
"Rename", "Fix0.ptx", "Fix.ptx",
"Rename", "Fix0.gpt", "Fix.gpt",
"Move", "Fix.*", "%bin%\\World\\Levels",
// "Move", "Fix.rt?", "%bin%\\World\\Levels",
"Move", "Gamedata\\Game.dsb", "%bin%",
"End"
};
char *g_a_szDeleteFixFilesAfterCRB[] =
{
// Delete fix files
"Delete", "fix*.sna",
"Delete", "fix*.snd",
"Delete", "fix*.ptx",
"Delete", "fix*.gpt",
"Delete", "fix.rt?",
"End"
};
char *g_a_szLevelFilesAfterCRB[] =
{
// Delete files from second pass
"Delete", "%level%1.*",
// We will use files from first pass.
"Rename", "%level%0.sna", "%level%.sna",
"Rename", "%level%0.snd", "%level%.snd",
"Rename", "%level%0.ptx", "%level%.ptx",
"Rename", "%level%0.gpt", "%level%.gpt",
// Delete bin level directory
"Delete", "%bin%\\World\\Levels\\%level%\\*.*",
// Move all files to destination directory
"Move", "%level%*", "%bin%\\World\\Levels\\%level%",
"Move", "Gamedata\\World\\Levels\\%level%\\%level%.dsb", "%bin%\\World\\Levels\\%level%",
"End"
};
char *g_a_szDeleteFilesAfterBinarize[] =
{
// Delete all remaining files in main directory
"Delete", "fix*.sna",
"Delete", "fix*.snd",
"Delete", "fix*.ptx",
"Delete", "fix*.gpt",
"Delete", "fix.rt?",
"Delete", "%level%*.sna",
"Delete", "%level%*.snd",
"Delete", "%level%*.ptx",
"Delete", "%level%*.gpt",
"Delete", "%level%.rt?",
// Also delete files in level
"Delete", "Gamedata\\Game.dsb",
"Delete", "Gamedata\\World\\Levels\\%level%\\%level%.dsb",
"End"
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Analyse keyword
// Used by fn_eTreatArrayOfFiles
int fn_iGetKeyword( char *_szKeyword )
{
if( stricmp( _szKeyword, "Copy" )==0 )
return 0;
else if( stricmp( _szKeyword, "Move" )==0 )
return 1;
else if( stricmp( _szKeyword, "Rename" )==0 )
return 2;
else if( stricmp( _szKeyword, "Delete" )==0 )
return 3;
else if( stricmp( _szKeyword, "End" )==0 )
return 4;
return -1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Analyse parameter
// Used by fn_eTreatArrayOfFiles
void fn_vGetParameter( char *_szResult, char *_szParam, tdstCopyFileContext *_p_stContext )
{
char *p_cSource = _szParam, *p_cDest = _szResult;
// hack: if no %bin%, assume path is main directory
if( strnicmp( p_cSource, "%bin%", 5 ) == 0 )
{
strcpy( p_cDest, _p_stContext->csBinDirectory );
p_cDest += strlen( p_cDest );
p_cSource += 5;
}
else
{
strcpy( p_cDest, _p_stContext->csMainDirectory );
p_cDest += strlen( p_cDest );
if( *p_cSource ) *p_cDest++ = '\\';
}
while( *p_cSource )
{
if( strnicmp( p_cSource, "%level%", 7 ) == 0 )
{
strcpy( p_cDest, _p_stContext->csLevelName );
p_cDest += strlen( p_cDest );
p_cSource += 7;
}
else
{
*p_cDest++ = *p_cSource++;
}
}
*p_cDest = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Execute copy/move/deletes/rename commands in given array
// See above for exemples.
// stContext contains strings used when replacing %bin%, %level%....
tdeStatus fn_eTreatArrayOfFiles( char *_a_szFileCommands[], tdstCopyFileContext *_p_stContext )
{
char szSource[512], szDest[512];
int iKeyWord;
tdeStatus eCommandOK;
char **p_szCommand = _a_szFileCommands;
do
{
switch( fn_iGetKeyword( *p_szCommand++ ) )
{
case 0: // Copy
fn_vGetParameter( szSource, *p_szCommand++, _p_stContext );
fn_vGetParameter( szDest, *p_szCommand++, _p_stContext );
eCommandOK = fn_eCopyFileOrDirectory( szSource, szDest );
break;
case 1: // Move
fn_vGetParameter( szSource, *p_szCommand++, _p_stContext );
fn_vGetParameter( szDest, *p_szCommand++, _p_stContext );
eCommandOK = fn_eMoveFileOrDirectory( szSource, szDest );
break;
case 2: // Rename
fn_vGetParameter( szSource, *p_szCommand++, _p_stContext );
fn_vGetParameter( szDest, *p_szCommand++, _p_stContext );
eCommandOK = STATUS_C_OK;
if( ! MoveFile( szSource, szDest ) )
{
char szMessage[1024];
sprintf( szMessage, "Move failed: '%s' to '%s", szSource, szDest );
AfxMessageBox( szMessage, MB_OK | MB_ICONSTOP );
eCommandOK = STATUS_C_Error;
}
break;
case 3: // Delete
fn_vGetParameter( szSource, *p_szCommand++, _p_stContext );
eCommandOK = fn_eDeleteFileOrDirectory( szSource );
break;
case 4: // End
return STATUS_C_OK;
break;
default: // Error in array !
ASSERT(0);
iKeyWord = -1;
eCommandOK = STATUS_C_Error;
break;
}
} while( eCommandOK == STATUS_C_OK );
return eCommandOK;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -