I am trying to make a file watcher that watches multiple directories simultaneously and i found a function that watches one directory and it works well. So I tried to create multiple threads with the same function and just give them the different paths of the directories as parameters. And it still works, but not perfectly. It does provide me with the first change in one directory, but then it gets stuck for that one and in the other directories the changes i make are printed as if they wore made in the first directory. I think the threads are getting messed up and I don`t know why. Here is the function
void watch_directory(LPCSTR path, int i)
{
char buf[2048];
DWORD nRet;
BOOL result = TRUE;
char filename[MAX_PATH];
DirInfo[0].hDir = CreateFile(path, GENERIC_READ | FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
NULL);
if (DirInfo[0].hDir == INVALID_HANDLE_VALUE)
{
return; //cannot open folder
}
lstrcpy(DirInfo[0].lpszDirName, path);
OVERLAPPED PollingOverlap;
FILE_NOTIFY_INFORMATION* pNotify;
int offset;
PollingOverlap.OffsetHigh = 0;
PollingOverlap.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
while (result)
{
result = ReadDirectoryChangesW(
DirInfo[0].hDir,// handle to the directory to be watched
&buf,// pointer to the buffer to receive the read results
sizeof(buf),// length of lpBuffer
TRUE,// flag for monitoring directory or directory tree
FILE_NOTIFY_CHANGE_FILE_NAME |
FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_SIZE,
&nRet,// number of bytes returned
&PollingOverlap,// pointer to structure needed for overlapped I/O
NULL);
WaitForSingleObject(PollingOverlap.hEvent, INFINITE);
offset = 0;
int rename = 0;
char oldName[260];
char newName[260];
do
{
pNotify = (FILE_NOTIFY_INFORMATION*)((char*)buf + offset);
strcpy(filename, "");
int filenamelen = WideCharToMultiByte(CP_ACP, 0, pNotify->FileName, pNotify->FileNameLength / 2, filename, sizeof(filename), NULL, NULL);
filename[pNotify->FileNameLength / 2] = '\0';
cout << pNotify->Action << i << filename << endl;
offset += pNotify->NextEntryOffset;
} while (pNotify->NextEntryOffset); //(offset != 0);
}
/*label:*/ CloseHandle(DirInfo[0].hDir);
}
And here is the way I create the threads:
vector <string> dirs;
vector <thread> threads;
dirs.push_back("F:\\Arhitecturi\\test0");
dirs.push_back("F:\\Arhitecturi\\test1");
for (int i = 0; i < dirs.size(); i++)
{
threads.push_back(thread(watch_directory, dirs[i].c_str(), i));
}
for (int i = 0; i < threads.size(); i++)
{
threads[i].join();
}