Module: wine Branch: master Commit: ded68372a29eecc057718137a35f668f9d26d497 URL: http://source.winehq.org/git/wine.git/?a=commit;h=ded68372a29eecc057718137a3...
Author: Michael Moss mmoss@google.com Date: Thu Mar 20 11:29:58 2008 -0700
kernel32/tests: Test notifications for overlapping directory watches.
---
dlls/kernel32/tests/change.c | 87 ++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 87 insertions(+), 0 deletions(-)
diff --git a/dlls/kernel32/tests/change.c b/dlls/kernel32/tests/change.c index b698eaa..7c90ccd 100644 --- a/dlls/kernel32/tests/change.c +++ b/dlls/kernel32/tests/change.c @@ -776,6 +776,92 @@ static void test_readdirectorychanges_filedir(void) ok( r == TRUE, "failed to remove directory\n"); }
+static void test_ffcn_directory_overlap(void) +{ + HANDLE parent_watch, child_watch, parent_thread, child_thread; + char workdir[MAX_PATH], parentdir[MAX_PATH], childdir[MAX_PATH]; + char tempfile[MAX_PATH]; + DWORD threadId; + BOOL ret; + + /* Setup directory hierarchy */ + ret = GetTempPathA(MAX_PATH, workdir); + ok((ret > 0) && (ret <= MAX_PATH), + "GetTempPathA error: %d\n", GetLastError()); + + ret = GetTempFileNameA(workdir, "fcn", 0, tempfile); + ok(ret, "GetTempFileNameA error: %d\n", GetLastError()); + ret = DeleteFileA(tempfile); + ok(ret, "DeleteFileA error: %d\n", GetLastError()); + + lstrcpyA(parentdir, tempfile); + ret = CreateDirectoryA(parentdir, NULL); + ok(ret, "CreateDirectoryA error: %d\n", GetLastError()); + + lstrcpyA(childdir, parentdir); + lstrcatA(childdir, "\c"); + ret = CreateDirectoryA(childdir, NULL); + ok(ret, "CreateDirectoryA error: %d\n", GetLastError()); + + + /* When recursively watching overlapping directories, changes in child + * should trigger notifications for both child and parent */ + parent_thread = StartNotificationThread(parentdir, TRUE, + FILE_NOTIFY_CHANGE_FILE_NAME); + child_thread = StartNotificationThread(childdir, TRUE, + FILE_NOTIFY_CHANGE_FILE_NAME); + + /* Create a file in child */ + ret = GetTempFileNameA(childdir, "fcn", 0, tempfile); + ok(ret, "GetTempFileNameA error: %d\n", GetLastError()); + + /* Both watches should trigger */ + ret = FinishNotificationThread(parent_thread); + ok(ret, "Missed parent notification\n"); + ret = FinishNotificationThread(child_thread); + ok(ret, "Missed child notification\n"); + + ret = DeleteFileA(tempfile); + ok(ret, "DeleteFileA error: %d\n", GetLastError()); + + + /* Removing a recursive parent watch should not affect child watches. Doing + * so used to crash wineserver. */ + parent_watch = FindFirstChangeNotificationA(parentdir, TRUE, + FILE_NOTIFY_CHANGE_FILE_NAME); + ok(parent_watch != INVALID_HANDLE_VALUE, + "FindFirstChangeNotification error: %d\n", GetLastError()); + child_watch = FindFirstChangeNotificationA(childdir, TRUE, + FILE_NOTIFY_CHANGE_FILE_NAME); + ok(child_watch != INVALID_HANDLE_VALUE, + "FindFirstChangeNotification error: %d\n", GetLastError()); + + ret = FindCloseChangeNotification(parent_watch); + ok(ret, "FindCloseChangeNotification error: %d\n", GetLastError()); + + child_thread = CreateThread(NULL, 0, NotificationThread, + (LPVOID)child_watch, 0, &threadId); + ok(child_thread != NULL, "CreateThread error: %d\n", GetLastError()); + + /* Create a file in child */ + ret = GetTempFileNameA(childdir, "fcn", 0, tempfile); + ok(ret, "GetTempFileNameA error: %d\n", GetLastError()); + + /* Child watch should trigger */ + ret = FinishNotificationThread(child_thread); + ok(ret, "Missed child notification\n"); + + /* clean up */ + ret = DeleteFileA(tempfile); + ok(ret, "DeleteFileA error: %d\n", GetLastError()); + + ret = RemoveDirectoryA(childdir); + ok(ret, "RemoveDirectoryA error: %d\n", GetLastError()); + + ret = RemoveDirectoryA(parentdir); + ok(ret, "RemoveDirectoryA error: %d\n", GetLastError()); +} + START_TEST(change) { HMODULE hkernel32 = GetModuleHandle("kernel32"); @@ -791,4 +877,5 @@ START_TEST(change) test_readdirectorychanges(); test_readdirectorychanges_null(); test_readdirectorychanges_filedir(); + test_ffcn_directory_overlap(); }