//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ // 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* 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* 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* 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* 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 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(); iGetSize(); iFileName()); 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* pData = (CSTPArray*) pParam; //-------------------------------------------------------- for(int i = 0, k = pData->GetSize(); iDeleteAll(); 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* pData = new CSTPArray; 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); }