HTML Code:
Platform : Windows2000, XP,
Microsoft Visual C++ .NET (Version 7.1),

Hello,

I need to process the files in a directory immediately the moment it gets
deposited in a directory.
I am trying to achieve this by using WaitForMultipleObjects ,
FindFirstChangeNotification, FindNextChangeNotification in a While loop
in the Run() of one of my worker threads of my multithread application.
I get the events for the files that were deposited after the
WaitForMultipleObjects was invoked in the while loop.
However those files that get deposited in the folder in the split of second
before the WaitForMultipleObjects is invoked are not getting reported i.e. I
am not getting their handles.
Is there any other API or code that can help me achieve the same without
losing the notification of the files deposited in between?
Any evident problem that you see as to why this should happen?

Any pointers would be of great help
Thanks and Regards
Ganga
(Please see excerpts of code below
Code:
int CABIEventWorkThread::Run()

{

ASSERT_VALID(GetWork());

CDirEventReceiverWork* dirWrk =
dynamic_cast<CDirEventReceiverWork*>(GetWork());


try

{

COMMINFOCON con;

dirWrk->GetEventDirectoryList(con);

dirWrk->RunOnce();

HANDLE* dwChangeHandles;


DWORD timeout = GetCycleTime();

BOOL waitAll = FALSE;

DWORD dwWaitStatus;

while (TRUE)

{

try

{

dirWrk->GetEventDirectoryList(con);

m_pDirEventServer.WatchDirectories(con);

dwChangeHandles = GetHandleList();


int nHandles = m_pDirEventServer.GetHandleMap().size()+ 2;

dwWaitStatus = WaitForMultipleObjects(nHandles, dwChangeHandles,

waitAll, timeout);

if(dwWaitStatus == WAIT_TIMEOUT )

{

//Refresh receiver list

continue;

}

if((dwWaitStatus == WAIT_OBJECT_0 + 0) || (dwWaitStatus == WAIT_OBJECT_0 +
1) )

{

//signalled kill event

break;

}

if((dwWaitStatus <= (WAIT_OBJECT_0 +1)) || (dwWaitStatus >= nHandles))

{

ASSERT(false);

ostringstream ost;

ost << "Invalid wait return value [" << dwWaitStatus << "]";

CABIException(PROGRAM_ERROR, ost.str(), __FILE__, __LINE__);

continue;

}


if(dwWaitStatus == m_pDirEventServer.GetHandleMap().size())

{

//signalled kill event

break;

}


try

{

CCommInfo ci = m_pDirEventServer.SetNextChangeNotification

(dwWaitStatus , dwChangeHandles);

dirWrk->SetCommInfo(ci);

//Process the directory

dirWrk->DoWork(GetWork());

}

catch(CABIException e)

{

ostringstream ost;

ost << e.ReportError();

CABIException(PROGRAM_ERROR, ost.str(), __FILE__, __LINE__);

continue;

}

}

catch(CABIException e)

{

ostringstream ost;

ost << e.ReportError();

CABIException(PROGRAM_ERROR, ost.str(), __FILE__, __LINE__);

continue;

}

}

}

catch(...)

{

ostringstream ost;

ost << "Caught Unknown Exception while doing Directory receiver Work";

CABIException(PROGRAM_ERROR, ost.str(), __FILE__, __LINE__);

}

try

{

//signalled externally for killing myself

EndWork(); //do derived shutdown

}

catch(CABIException& e)

{

ASSERT(false);

}

catch(CException* e)

{

ASSERT(false);

char szErr[1024];

e->GetErrorMessage(szErr, 1024);

e->Delete();

ostringstream ost;

ost << "Caught CException while executing EndWork(), with error [" << szErr
<< "]. Rebulidng ABI Exception";

CABIException(PROGRAM_ERROR, ost.str(), __FILE__, __LINE__);

}

catch(exception& e)

{

ASSERT(false);

ostringstream ost;

ost << "Caught exception while executing EndWork(), with error [" <<
e.what() << "]. Rebulidng ABI Exception";

CABIException(PROGRAM_ERROR, ost.str(), __FILE__, __LINE__);

}

catch(...)

{

//this should never happen unless there is problem destroying

//work object (bad pointer)

ASSERT(false);

ostringstream ost;

ost << "Caught unknown exception while executing EndWork(). Rebulidng ABI
Exception";

CABIException(PROGRAM_ERROR, ost.str(), __FILE__, __LINE__);

}

SetEvent(GetEventDead()); //signal to calling thread that i am done

SetEvent(GetEventAnotherDead()); //signal to calling thread that i am done

AfxEndThread(0,m_bAutoDelete);

return 0;

}

void CDirEventServer::WatchDirectories(const COMMINFOCON& con)

{

HANDLE dwChangeHandle;

TCHAR lpDrive[4];

TCHAR lpFile[_MAX_FNAME];

TCHAR lpExt[_MAX_EXT];

StopWatch();

for(COMMINFOCON::const_iterator It = con.begin(); It != con.end(); It++)

{

const CCommInfo& ci =(*It);


string strPath = ci.GetRemoteDir();

const TCHAR* lpDir = strPath.c_str();

bool subDirState = ci.IsSubDirectory();

_tsplitpath(lpDir, lpDrive, NULL, lpFile, lpExt);

lpDrive[2] = (TCHAR)'\\';

lpDrive[3] = (TCHAR)'\0';


// Watch the directory for file creation and deletion.


dwChangeHandle= FindFirstChangeNotification(

lpDir, // directory to watch

subDirState, // do not watch subtree

FILE_NOTIFY_CHANGE_CREATION |

FILE_NOTIFY_CHANGE_LAST_WRITE); // watch file name changes


if (dwChangeHandle == INVALID_HANDLE_VALUE)

{

ostringstream ost;

ost << "FindFirstChangeNotification returned an INVALID_HANDLE_VALUE";

throw CABIException(PROGRAM_ERROR,ost.str(),__FILE__,__LINE__);

}


AddToHandleMap(dwChangeHandle, &ci);

}

}

CCommInfo CDirEventServer::SetNextChangeNotification(long lWait, HANDLE*
dwChangeHandles)

{


HANDLECOMMINFOMAP::iterator It =
GetHandleMap().find(dwChangeHandles[lWait]);

if (lWait >= 0 && It != GetHandleMap().end())

{

const CCommInfo* ci = (*It).second;


ASSERT(lWait < GetHandleMap().size()+2);

if (FindNextChangeNotification(

dwChangeHandles[lWait]) == FALSE)

{

ostringstream ost;

ost << "FindNextChangeNotification returned an INVALID_HANDLE_VALUE";

throw CABIException(PROGRAM_ERROR,ost.str(),__FILE__,__LINE__);

}

return *ci;

}

else

{

ostringstream ost;

ost << "Invalid Handle Wait state";

throw CABIException(PROGRAM_ERROR, ost.str(), __FILE__, __LINE__);

}

}