Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Goffart <olivier@woboq.com>2014-11-17 11:43:29 +0300
committerOlivier Goffart <olivier@woboq.com>2014-11-17 11:43:29 +0300
commite529bbed907409fc454427b48f6f033763b42114 (patch)
treeec53b033df0e5e557e34398fd7cb5f2cd3a78d0d /src/mirall
parent39e97779ec1136fc93379f049248b6894ee27a87 (diff)
parent7c034b427ed6b144a0d0e9a10d04ce1e2037d3f0 (diff)
Merge pull request #2454 from owncloud/fswatcher_readdirectorychanges_port
switch to ReadDirectoryChangesW
Diffstat (limited to 'src/mirall')
-rw-r--r--src/mirall/folderwatcher_win.cpp83
1 files changed, 57 insertions, 26 deletions
diff --git a/src/mirall/folderwatcher_win.cpp b/src/mirall/folderwatcher_win.cpp
index c6c8242fa..76f687709 100644
--- a/src/mirall/folderwatcher_win.cpp
+++ b/src/mirall/folderwatcher_win.cpp
@@ -25,42 +25,73 @@ namespace Mirall {
void WatcherThread::run()
{
- _handle = FindFirstChangeNotification((wchar_t*)_path.utf16(),
- true, // recursive watch
- FILE_NOTIFY_CHANGE_FILE_NAME |
- FILE_NOTIFY_CHANGE_DIR_NAME |
- FILE_NOTIFY_CHANGE_LAST_WRITE);
+ _handle = CreateFileW(
+ (wchar_t*)_path.utf16(),
+ FILE_LIST_DIRECTORY,
+ FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL
+ );
if (_handle == INVALID_HANDLE_VALUE)
{
- qDebug() << Q_FUNC_INFO << "FindFirstChangeNotification function failed, stopping watcher!";
- FindCloseChangeNotification(_handle);
- _handle = 0;
- return;
- }
-
- if (_handle == NULL)
- {
- qDebug() << Q_FUNC_INFO << "FindFirstChangeNotification returned null, stopping watcher!";
+ qDebug() << Q_FUNC_INFO << "Failed to set up a watch for" << _path << ", stopping watcher!";
FindCloseChangeNotification(_handle);
_handle = 0;
return;
}
+ size_t bufsize = 4096;
+ size_t maxlen = 4096;
while(true) {
- switch(WaitForSingleObject(_handle, /*wait*/ INFINITE)) {
- case WAIT_OBJECT_0:
- if (FindNextChangeNotification(_handle) == false) {
- qDebug() << Q_FUNC_INFO << "FindFirstChangeNotification returned FALSE, stopping watcher!";
- FindCloseChangeNotification(_handle);
- _handle = 0;
- return;
+ char fileNotify[bufsize];
+ FILE_NOTIFY_INFORMATION *pFileNotify =
+ (FILE_NOTIFY_INFORMATION*)fileNotify;
+ DWORD dwBytesReturned = 0;
+ SecureZeroMemory(pFileNotify, bufsize);
+ if(ReadDirectoryChangesW( _handle, (LPVOID)pFileNotify,
+ bufsize, true,
+ FILE_NOTIFY_CHANGE_FILE_NAME |
+ FILE_NOTIFY_CHANGE_DIR_NAME |
+ FILE_NOTIFY_CHANGE_LAST_WRITE,
+ &dwBytesReturned, NULL, NULL))
+ {
+ FILE_NOTIFY_INFORMATION *curEntry = pFileNotify;
+ while(true) {
+ size_t len = pFileNotify->FileNameLength / 2;
+ QString file = _path + "\\" + QString::fromWCharArray(pFileNotify->FileName, len);
+
+ QString longfile;
+ QScopedArrayPointer<TCHAR> buffer(new TCHAR[maxlen]);
+ if (GetLongPathNameW(reinterpret_cast<LPCWSTR>(file.utf16()), buffer.data(), maxlen) == 0) {
+ qDebug() << Q_FUNC_INFO << "Error converting file name to full length, resorting to original name.";
+ longfile = file;
+ } else {
+ longfile = QString::fromUtf16(reinterpret_cast<const ushort *>(buffer.data()), maxlen-1);
+ }
+
+ qDebug() << Q_FUNC_INFO << "Found change in" << file;
+ emit changed(longfile);
+ if (curEntry->NextEntryOffset == 0) {
+ break;
+ }
+ curEntry = (FILE_NOTIFY_INFORMATION*)
+ (char*)curEntry + curEntry->NextEntryOffset;
+ }
+ } else {
+ switch(GetLastError()) {
+ case ERROR_NOTIFY_ENUM_DIR:
+ qDebug() << Q_FUNC_INFO << "Too many events for buffer, resizing";
+ bufsize *= 2;
+ break;
+ default:
+ qDebug() << Q_FUNC_INFO << "General error while watching. Exiting.";
+ CloseHandle(_handle);
+ _handle = NULL;
+ break;
}
- // qDebug() << Q_FUNC_INFO << "Change detected in" << _path << "from" << QThread::currentThread ();
- emit changed(_path);
- break;
- default:
- qDebug() << Q_FUNC_INFO << "Error while watching";
}
}
}