reman3/Rayman_X/cpa/Appli/WinS2B/Process.cpp

493 lines
14 KiB
C++

//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// FILE : Process.cpp
// AUTHOR : Catalin Cocos
//__________________________________________________________________________________________________
#include "stdinc.h"
#include "process.h"
#include "app.h"
#include "Tree.h"
#include "resource.h"
BOOL volatile Stop;
HANDLE hProcessSemaphore, hStopSemaphore;
HANDLE hLogFile = INVALID_HANDLE_VALUE;
void SetTxtProp( COLORREF clr/* = RGB(0, 255, 0)*/, DWORD effects /*= 0*/)
{
CHARFORMAT cf= { sizeof(CHARFORMAT) };
cf.dwMask = CFM_BOLD|CFM_FACE|CFM_COLOR|CFM_SIZE;
cf.dwEffects = effects;
cf.yHeight = -10;
cf.crTextColor = clr;
cf.bCharSet = DEFAULT_CHARSET;
cf.bPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
strcpy(cf.szFaceName, "Arial");
SendMessage(hWOut, EM_SETCHARFORMAT, SCF_SELECTION , (LPARAM) &cf ); // set the character format
}
void AddTxt( const char* text)
{
CHARRANGE cr = { -1, -1};
SendMessage(hWOut,EM_EXSETSEL, 0, (LPARAM) &cr );
SendMessage(hWOut,EM_REPLACESEL, FALSE, (LPARAM) text);
if(hLogFile != INVALID_HANDLE_VALUE)
{
DWORD bw;
WriteFile(hLogFile, text, strlen(text), &bw, NULL );
}
}
void AddItemChildren(CSTPArray<CDirInfo>* pData, HTREEITEM hChild)
{
TV_ITEM ti = { TVIF_HANDLE|TVIF_STATE|TVIF_PARAM, hChild, 0, ~0 };
TreeView_GetItem( hWTree, &ti);
ti.state &= TVIS_STATEIMAGEMASK;
CDirInfo* pDi = ((CDirInfo*)ti.lParam);
if(pDi->GetSize() ||
ti.state == TI_STATE_FILES ||
ti.state == TI_STATE_RECURSE)
{
// add this item
CDirInfo* pNewD = new CDirInfo((char*)pDi->FileName());
if(ti.state == TI_STATE_FILES) pNewD->m_Flags = CDIR_ALL;
if(ti.state == TI_STATE_RECURSE) pNewD->m_Flags = CDIR_RECURSE;
if(!pNewD->m_Flags)
{
// add the file list
pNewD->SetSize(pDi->GetSize());
for(int i = pNewD->GetUpperBound(); i>=0; i-- )
pNewD->SetAt(i, new CFileName( (char*)(*pDi)[i]->FileName() ));
}
BOOL NA;
pData->SAdd(pNewD, NA, FALSE);
}
for( HTREEITEM hNext = TreeView_GetChild( hWTree, hChild); hNext; hNext = TreeView_GetNextSibling( hWTree, hNext))
AddItemChildren( pData, hNext);
}
void AddFile( CSTPArray<CDirInfo>* pData, char* filename )
{
if(!CnvEng.IsFileSupported(filename))
return;
char Dir[_MAX_PATH];
char Fname[_MAX_FNAME];
_splitpath(filename, Dir, NULL, Fname, NULL);
_splitpath(filename, NULL, Dir+strlen(Dir), NULL, Fname+strlen(Fname));
Dir[strlen(Dir) - 1] = 0;
CDirInfo* pDi = new CDirInfo(Dir);
int idx, ins;
idx = pData->Index( pDi, &ins);
if(idx>=0)
{
delete pDi; // we have a match
if((*pData)[idx]->m_Flags) return;
BOOL NA;
CFileName * pName = new CFileName(Fname);
(*pData)[idx]->SAdd(pName, NA, FALSE);
if(NA) delete pName;
return;
}
if(ins>0 && strlen((*pData)[ins-1]->FileName()) <= strlen(Dir) &&
!_strnicmp((*pData)[ins-1]->FileName(), Dir, strlen((*pData)[ins-1]->FileName())) &&
(*pData)[ins-1]->m_Flags == CDIR_RECURSE)
{
delete pDi; // this is a sub-folder of a recursive folder, we need no info on it
return;
}
// we need to add the folder
pDi->Add(new CFileName(Fname)); // add its first file...
pData->InsertAt(ins, pDi, 1); // and add it in the list
}
void AddTextCollection( CSTPArray<CDirInfo>* pData, char* filename )
{
CTextParser P; // the file parser object
if(!P.AccessFile(filename)) // try to acces the txt file
return;
P.SetType( "\\._-", CTP_TEXT);
P.SetType( "^", CTP_LINE_COMMENT);
char Dir[_MAX_PATH];
_splitpath(filename, Dir, NULL, NULL, NULL);
_splitpath(filename, NULL, Dir+strlen(Dir), NULL, NULL);
Dir[strlen(Dir) - 1] = 0;
char* bksl = strrchr( Dir, '\\');
if(bksl) bksl[1] = 0;
else *Dir = 0;
char* Word = NULL, *NextWord;
DWORD i = P.Advance();
while(!(i & CTP_EOF ))
{
Word = P.Word();
char* Begin = strchr( Word, ')');
if(Begin) Word = Begin+1;
char FullName[_MAX_PATH+_MAX_FNAME];
strcpy( FullName, Dir);
strcat( FullName, Word );
AddFile( pData, FullName);
do
{
i = P.Advance();
NextWord = P.Word();
if(Begin = strchr( NextWord, ')')) NextWord = Begin+1;
}
while( !(i & CTP_EOF ) && !strcmpi(Word, NextWord));
}
}
void AddLogCollection( CSTPArray<CDirInfo>* pData, char* filename )
{
CTextParser P; // the file parser object
if(!P.AccessFile(filename)) // try to acces the log file
return;
P.SetType( "\\._-", CTP_TEXT);
P.SetType( "*", CTP_LINE_COMMENT);
DWORD i = P.Advance();
while(!(i & CTP_EOF ))
{
if(!strcmp(P.Word(), "Obtaining"))
{
i = P.Advance();
if( !(i & CTP_EOF ) )
AddFile( pData, P.Word());
}
i = P.Advance();
}
}
unsigned long Lines, Files, Directories, TotalFiles, Errors;
float Length, Output;
SYSTEMTIME systime;
BOOL DirectoryNotDisplayed;
CDirInfo* pCrtDir;
void ProcessFile( char* szFile)
{
char OutputName[_MAX_PATH +10];
strcpy(OutputName, szFile);
strcat(OutputName, BINEXTENSION);
switch(OperatingMode)
{
case ID_MODE_CLEAN:
{
char Ext[_MAX_EXT];
char fName[_MAX_FNAME];
_splitpath(szFile, NULL, NULL, fName, Ext );
if(!strcmp (Ext, BINEXTENSION) && (!CnvEng.IsFilteringActive() || CnvEng.IsFileSupported( fName )))
{
if(DirectoryNotDisplayed)
{
AddTxt("\r\n");//Processing ");
AddTxt( pCrtDir->FileName());
AddTxt( " ...\r\n");
DirectoryNotDisplayed = FALSE;
}
Files ++;
AddTxt("\t");
AddTxt(fName);
AddTxt(Ext);
if(!DeleteFile(szFile)) AddTxt(" Error: Deletion failed!");
AddTxt("\r\n");
}
}
break;
case ID_MODE_NORMAL:
{
HANDLE hOut = CreateFile( OutputName, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hOut != INVALID_HANDLE_VALUE)
{
HANDLE hIn = CreateFile( szFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if( hIn != INVALID_HANDLE_VALUE )
{
BY_HANDLE_FILE_INFORMATION iIn, iOut;
GetFileInformationByHandle( hIn, &iIn);
GetFileInformationByHandle( hOut, &iOut);
CloseHandle(hIn);
if(CompareFileTime(&iIn.ftLastWriteTime, &iOut.ftLastWriteTime) <= 0 )
{
// the file is up to date
CloseHandle(hOut);
break;
}
}
CloseHandle(hOut);
}
}
case ID_MODE_FORCED:
{
DWORD len, Outlen;
unsigned line;
char Ext[_MAX_EXT];
char fName[_MAX_FNAME];
_splitpath(szFile, NULL, NULL, fName, Ext );
if(DirectoryNotDisplayed)
{
AddTxt("\r\n");//Processing ");
AddTxt( pCrtDir->FileName());
AddTxt( " ...\r\n");
DirectoryNotDisplayed = FALSE;
}
AddTxt("\t");
AddTxt(fName);
AddTxt(Ext);
Files ++;
SetTxtProp( RGB(255, 0, 0), CFE_BOLD );
int TheERROR = CnvEng.Convert( szFile, OutputName, &line, &len, &Outlen );
switch(TheERROR )
{
case SB_ERR_OUTPUT_FILEOPEN: AddTxt(" Error! Unable to create the output file."); break;
case SB_ERR_FILEOPEN: AddTxt(" Error! Unable to open the file."); break;
case SB_ERR_BAD_FILE_EXTENSION: AddTxt(" Error! This file type is not currently supported."); break;
case SB_ERR_PARAMETER_MISSING:
AddTxt(" Error (line ");
itoa( line, OutputName, 10);
AddTxt( OutputName );
AddTxt( ")! Parameter Missing.");
break;
case SB_ERR_UNKNOWN_DIRECTIVE:
AddTxt(" Error (line ");
itoa( line, OutputName, 10);
AddTxt( OutputName );
AddTxt( ")! Unknown Directive.");
break;
case SB_ERR_UNKNOWN_SECTION:
AddTxt(" Error (line ");
itoa( line, OutputName, 10);
AddTxt( OutputName );
AddTxt( ")! Unknown Section Type.");
break;
case SB_ERR_UNKNOWN_ENTRY:
AddTxt(" Error (line ");
itoa( line, OutputName, 10);
AddTxt( OutputName );
AddTxt( ")! Unknown Entry Type.");
break;
case SB_ERR_UNEXPECTED_EOF:
AddTxt(" Error (line ");
itoa( line, OutputName, 10);
AddTxt( OutputName );
AddTxt( ")! Unexpected End of File.");
break;
}
SetTxtProp();
AddTxt("\r\n");
Lines += line;
Length += ((float)len)/1024/1024;
Output += ((float)Outlen)/1024/1024;
if(TheERROR)
Errors++;
}
break;
}
}
void ProcessDirectory( CDirInfo* pDi )
{
char buffer[_MAX_PATH];
DirectoryNotDisplayed = TRUE;
pCrtDir = pDi;
// AddTxt("\r\n");//Processing ");
// AddTxt( pDi->FileName());
// AddTxt( " ...\r\n");
Directories ++;
if(pDi->m_Flags)
{
CTypedPtrArray<CDirInfo*> arRecFolders;
arRecFolders.SetGranularity(5);
strcpy(buffer, pDi->FileName());
strcat(buffer, "\\*.*");
WIN32_FIND_DATA fd;
HANDLE hSearch = FindFirstFile( buffer, &fd );
for(BOOL Found = (hSearch != INVALID_HANDLE_VALUE); Found && !Stop; Found = FindNextFile( hSearch, &fd))
{
if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
//we found a sub-directory
if(pDi->m_Flags == CDIR_RECURSE && *fd.cFileName != '.')
{
strcpy( buffer, pDi->FileName());
strcat( buffer, "\\");
strcat( buffer, fd.cFileName);
//create the new structure
CDirInfo* pNewDir = new CDirInfo( buffer );
pNewDir->m_Flags = CDIR_RECURSE;
arRecFolders.Add(pNewDir);
}
}
else
{
//we found a file
TotalFiles++;
if(OperatingMode == ID_MODE_CLEAN || CnvEng.IsFileSupported(fd.cFileName))
{
strcpy( buffer, pDi->FileName());
strcat( buffer, "\\");
strcat( buffer, fd.cFileName);
ProcessFile( buffer ); // convert the file
}
}
if(WaitForSingleObject(hStopSemaphore, 0) == WAIT_OBJECT_0) Stop = TRUE;
}
if(hSearch != INVALID_HANDLE_VALUE) FindClose(hSearch);
for( int i = 0, k = arRecFolders.GetSize(); i<k && !Stop; i++) // process the subdirectories
{
ProcessDirectory(arRecFolders[i]);
if(WaitForSingleObject(hStopSemaphore, 0) == WAIT_OBJECT_0) Stop = TRUE;
}
arRecFolders.DeleteAll();
}
else for(int i = 0, k = pDi->GetSize(); i<k && !Stop; i++)
{
TotalFiles++;
//process the selected files
strcpy( buffer, pDi->FileName());
strcat( buffer, "\\");
strcat( buffer, (*pDi)[i]->FileName());
if(OperatingMode == ID_MODE_CLEAN)
strcat( buffer,BINEXTENSION );
ProcessFile( buffer ); // convert the file
if(WaitForSingleObject(hStopSemaphore, 0) == WAIT_OBJECT_0) Stop = TRUE;
}
}
void __cdecl ProcessThread(void* pParam)
{
char buffer[_MAX_PATH];
strcpy(buffer, CrtCfg);
char* ext = strrchr(buffer, '.');
if(ext) strcpy(ext, ".log");
else strcat(buffer, ".log");
hLogFile = CreateFile( buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
SetWindowText(hWOut, "");
AddTxt("------------ Configuration: ");
AddTxt( CrtCfg );
AddTxt(" ------------\r\n");
Output = Length = 0.f;
Errors = TotalFiles = Lines = Files = Directories = 0;
GetSystemTime( &systime );
CSTPArray<CDirInfo>* pData = (CSTPArray<CDirInfo>*) pParam;
//--------------------------------------------------------
for(int i = 0, k = pData->GetSize(); i<k && !Stop; i++)
{
ProcessDirectory( (*pData)[i] );
if(WaitForSingleObject(hStopSemaphore, 0) == WAIT_OBJECT_0) Stop = TRUE;
}
//--------------------------------------------------------
pData->DeleteAll();
delete pData;
// compute the elapsed time
SYSTEMTIME finalTime;
GetSystemTime( &finalTime );
AddTxt("\r\n");
if(Stop) AddTxt( "Processing canceled by user.\r\n" );
AddTxt("--------------------------------------\r\n");
AddTxt("Processing Mode:\t");
switch(OperatingMode)
{
case ID_MODE_NORMAL: AddTxt(" NORMAL\r\n"); break;
case ID_MODE_FORCED: AddTxt(" FORCED\r\n"); break;
case ID_MODE_CLEAN: AddTxt(" CLEAN-UP\r\n"); break;
}
sprintf( buffer,"Total Directories :\t%u\r\n", Directories);
AddTxt( buffer );
sprintf( buffer,"Total Files :\t\t%u\r\n", TotalFiles);
AddTxt( buffer );
sprintf( buffer,"Processed Files :\t%u\r\n",Files);
AddTxt( buffer );
sprintf( buffer,"Processed Lines :\t%u\r\n",Lines);
AddTxt( buffer );
sprintf( buffer,"Read Data (MB) :\t%.3f\r\n",Length);
AddTxt( buffer );
sprintf( buffer,"Output Data (MB) :\t%.3f\r\n",Output);
AddTxt( buffer );
int hour = finalTime.wHour - systime.wHour;
int minute = finalTime.wMinute - systime.wMinute + hour*60;
int second = finalTime.wSecond - systime.wSecond;
if( second<0)
{
minute--;
second+=60;
}
sprintf( buffer,"Processing Time :\t%i:%02i\r\n",minute,second);
AddTxt( buffer );
AddTxt("--------------------------------------\r\n");
if(Errors)
{
SetTxtProp( RGB(255, 0, 0), CFE_BOLD );
sprintf( buffer,"\t%u Error%s.\r\n",Errors, Errors>1?"s":"");
AddTxt( buffer );
SetTxtProp();
AddTxt("--------------------------------------\r\n");
}
if(hLogFile != INVALID_HANDLE_VALUE) CloseHandle(hLogFile);
PlaySound( "SystemAsterisk", NULL, SND_ALIAS|SND_NOWAIT|SND_ASYNC);
Processing = FALSE;
ReleaseSemaphore( hProcessSemaphore, 1, NULL);
OnIdle();
}
void Process( int What )
{
// initializing data...
HCURSOR hOldCursor = SetCursor( LoadCursor(NULL, IDC_WAIT));
SetWindowText( hWStatusbar, "Initializing, please wait...");
CSTPArray<CDirInfo>* pData = new CSTPArray<CDirInfo>;
pData->SetGranularity(20);
if(What & PROCESS_SELECTION)
// set the tree selection
for(HTREEITEM hChild = TreeView_GetRoot(hWTree); hChild; hChild = TreeView_GetNextSibling(hWTree, hChild))
AddItemChildren( pData, hChild);
if(What & PROCESS_COLLECTIONS)
for( int i = ListView_GetItemCount( hWList ) -1 ; i>=0; i-- )
{
LV_ITEM it = {LVIF_STATE|LVIF_PARAM, i, 0, 0, ~0};
ListView_GetItem( hWList, &it);
if(it.state & LSTATE_CHECKED)
{
char Ext[_MAX_EXT];
_splitpath((char*)it.lParam, NULL, NULL, NULL, Ext);
if(!strcmpi(Ext+1, "txt"))
AddTextCollection( pData, (char*)it.lParam);
else if(!strcmpi(Ext+1, "log"))
AddLogCollection( pData, (char*)it.lParam);
}
}
SetCursor( hOldCursor );
SetWindowText( hWStatusbar, "Ready");
Processing = TRUE;
Stop = FALSE;
WaitForSingleObject(hStopSemaphore, 0);
WaitForSingleObject(hProcessSemaphore, 0); // reset the semaphores state
OnIdle();
_beginthread(ProcessThread, 0, pData); // launch the processing
// SetFocus( hWOut );
}
void StopProcessing()
{
if(!Processing) return;
ReleaseSemaphore( hStopSemaphore, 1, NULL);
}