Link to home
Start Free TrialLog in
Avatar of Trancos
TrancosFlag for United States of America

asked on

<Todo: File Description> Message when Norton AV intercepts process


Hi experts,

This is a two part question (each part is worth half the total points offered).
This question might sound a bit difficult but I think is not that difficult, it's maybe a problem with naming my processes.Well, here is the description.
I have a MFC dialog application (VS.NET 2003) that copies files from source to target. The copy routine is a recursive function that basically "clones" the tree within source (files and sub-directories) into the target directory.
To do this, I create a working thread with AfxBeginThread(...) and I launch a Modal dialog from the main dialog (this is only to display a progress bar and a "Cancel" button). When large files being copied Norton AV displays its typical msg saying that a file is waiting to be scanned. The funny bit is that instead of showing the process name it says:
TODO: <File Description> is waiting for a virus scan of 'FILE.CAB'

Hence my question, where is "TODO: <File Description>" declared? How can I change that to my Apps name?
I'm using CopyFileEx to copy the files.
Another CopyFileEx related issue, when I cancel the copy process by pressing "cancel" on the modal dialog, the thread is finished with:

dwError=GetLastError();
AfxEndThread(dwError);
which in this case dwError == ERROR_REQUEST_ABORTED
on My main dialog thread, I retrieve this value with GetExitCodeThread and everything works fine. However, if I have my windows explorer open and pointing to the destination directory, it won't let me delete everything. I assume that the problem is that the CopyFileEx thread didn't release the last folder it was working on and that's why I cannot delete all? Any ideas and/or comments on this will be greatly appreciated.



ASKER CERTIFIED SOLUTION
Avatar of nonubik
nonubik

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of mactep13
mactep13

The AfxEndThread function must be called from within a thread to terminate the thread. If you're calling from outside the thread, your thread will not terminate. I will NOT recommend calling TerminateThread(). This function is unsafe and will not release any allocations of your thread. What you really want to do is to create some kind of syncronization object that tells your thread to end by calling AfxEndThread from within itself. Setting a bool and checking for value inside the thread is simplest, but if you want to have nice code, try creating an Event object that will signal to the thread to die.
As far as the TODO, what nonubik said is correct. Change the info in your resource view under VERSION for the File Description.

Hope this helps.

mactep
Avatar of Trancos

ASKER

Nonubik,

Thanks a lot, that's help me. I therefore consider this part of the question as answered.

Mactep13, thanks for your comments, however that's not the problem. I finish the working thread where CopyFileEx is working with AfxEndThread(dwError);
This is ofcourse done withing the same thread, so everything is done according to "msdn rules", however, somehow the process doesn't unlock the last folder it was working on. I have tried ExitProcess(dwError) but this will end the whole application (which make sense, since I just managing different thread, not different processes). As for the synchronization objects, I tried to use CEvent, and then WaitforSingleObject(...), but it didn't work. After reading a bit more about CEvent, CSyncObject, and CSingleLock, I didn't really get the mechanism, so I decided to create a new message in my application. After all, I don't really need synchronizing, since I'm not accessing the same resource at anytime.
>This is ofcourse done withing the same thread, so everything is done according to "msdn rules",

As you described, I see that when pressing 'Cancel' you somehow tell the worker thread to call AfxEndThread. Can you post some code?
However, call AfxEndThread is not a clean solution and you can use, as mactep13 suggested, a bool variable that will be set on pressing 'Cancel' and will be read in the working thread loop and terminate the loop.
Avatar of Trancos

ASKER

Hi nonubik,

I seem to have found the problem. Just to give you an idea of what was going on, here is a bit of code of my program and some comments to show the solution.

OnBnClickedOK
{
   ....
_copyfiles_thread=AfxBeginThread(CopyFilesThread,
                    (LPVOID)this,
                    THREAD_PRIORITY_BELOW_NORMAL,
                    CREATE_SUSPENDED);

      _copyfiles_thread->m_bAutoDelete=FALSE;
      _copyfiles_thread->BeginWaitCursor();
      dlg_Progress=new CProgressDlg(this,&g_bCancelOp);      

      //dlg_Progress->Create(IDD_PROGRESSDLG,this);  // Creates the dialog that will display a progress indicator and a Cancel Button
      //dlg_Progress->ShowWindow(SW_SHOW);
      dlg_Progress->DoModal();                            //This is a Modal dialog that doesn't close on "Cancel" clicked
      _copyfiles_thread->ResumeThread();
}

CopyFilesThread(LPVOID lpParam)    //The main function of the working thread
{
      CopySourceFiles(      csSourceDirectory,         // This function calls CopyFileEx with a CopyProgressRoutine
            csTargetDirectory,         // g_bCancelOp is checked inside CopyProgressRoutine, so that whenever
            gigabytes,                    // the use clicks on "Cancel" inside dlg_Progress, g_bCancelOp is updated and
            ResultCopyOp,             // CopyProgressRoutine sends a cancel message.
            pThis->dlg_Progress,
            (LPVOID*)pbProgress );

      if( ResultCopyOp.bError )      //Error detected
      {
      AfxGetMainWnd()->PostMessage(WM_COPYFINISHED,(WPARAM)ResultCopyOp.dwErrorCode,ResultCopyOp.bError);
      g_bCancelOp=FALSE;
      //AfxEndThread(ResultCopyOp.dwErrorCode);
      return ResultCopyOp.dwErrorCode;      // Thread aborted or interrupted
      } else {
      SetCurrentDirectory(csSourceDirectory);     // Change directory to root
      AfxGetMainWnd()->PostMessage(WM_COPYFINISHED,0,0);
      return 0x259; // Thread Successful
     }
}

The problem I had is that as you can see from here, when the thread was interrupted by "g_bCancel", the CopySourceFile function didn't change directory and the "CopyFilesThread" function didn't either, so basically I just had to add "SetCurrentDirectory" the "Error detected" branch.

finally, the main thread's catches the message with:
OnCopyFinished(WPARAM wParam, LPARAM lParam)
{
   CloseHandle(_copyfiles_thread->m_hThread);
   _copyfiles_thread->Delete();

   if( dwExitCode == ERROR_REQUEST_ABORTED || wParam || lParam )
   {
      AfxMessageBox("Copying system files aborted");
      m_sbProgress.SetPos64(0);
      ShowHideStatusBar(TRUE);
   }
   else{ ... }
}

Thanks a lot anyway.