diff --git a/src/win/fs-event.c b/src/win/fs-event.c index 95f843ad..14c9af9a 100644 --- a/src/win/fs-event.c +++ b/src/win/fs-event.c @@ -69,6 +69,7 @@ static void uv_relative_path(const WCHAR* filename, size_t relpathlen; size_t filenamelen = wcslen(filename); size_t dirlen = wcslen(dir); + assert(!_wcsnicmp(filename, dir, dirlen)); if (dirlen > 0 && dir[dirlen - 1] == '\\') dirlen--; relpathlen = filenamelen - dirlen - 1; @@ -151,11 +152,11 @@ int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* path, unsigned int flags) { - int name_size, is_path_dir; + int name_size, is_path_dir, size; DWORD attr, last_error; WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL; WCHAR short_path_buffer[MAX_PATH]; - WCHAR* short_path; + WCHAR* short_path, *long_path; if (uv__is_active(handle)) return UV_EINVAL; @@ -197,6 +198,30 @@ int uv_fs_event_start(uv_fs_event_t* handle, if (is_path_dir) { /* path is a directory, so that's the directory that we will watch. */ + + /* Convert to long path. */ + size = GetLongPathNameW(pathw, NULL, 0); + + if (size) { + long_path = (WCHAR*)uv__malloc(size * sizeof(WCHAR)); + if (!long_path) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + + size = GetLongPathNameW(pathw, long_path, size); + if (size) { + long_path[size] = '\0'; + } else { + uv__free(long_path); + long_path = NULL; + } + } + + if (long_path) { + uv__free(pathw); + pathw = long_path; + } + dir_to_watch = pathw; } else { /* diff --git a/test/test-fs-event.c b/test/test-fs-event.c index 39d73300..5ddccffd 100644 --- a/test/test-fs-event.c +++ b/test/test-fs-event.c @@ -129,7 +129,7 @@ static void fs_event_cb_dir(uv_fs_event_t* handle, const char* filename, ++fs_event_cb_called; ASSERT(handle == &fs_event); ASSERT(status == 0); - ASSERT(events == UV_RENAME); + ASSERT(events == UV_CHANGE); #if defined(__APPLE__) || defined(_WIN32) || defined(__linux__) ASSERT(strcmp(filename, "file1") == 0); #else @@ -477,6 +477,42 @@ TEST_IMPL(fs_event_watch_dir_recursive) { #endif } +#ifdef _WIN32 +TEST_IMPL(fs_event_watch_dir_short_path) { + uv_loop_t* loop; + int r; + + /* Setup */ + loop = uv_default_loop(); + remove("watch_dir/file1"); + remove("watch_dir/"); + create_dir("watch_dir"); + create_file("watch_dir/file1"); + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, fs_event_cb_dir, "watch_~1", 0); + ASSERT(r == 0); + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + r = uv_timer_start(&timer, timer_cb_file, 100, 0); + ASSERT(r == 0); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(fs_event_cb_called == 1); + ASSERT(timer_cb_called == 1); + ASSERT(close_cb_called == 1); + + /* Cleanup */ + remove("watch_dir/file1"); + remove("watch_dir/"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif + TEST_IMPL(fs_event_watch_file) { #if defined(NO_FS_EVENTS) diff --git a/test/test-list.h b/test/test-list.h index a5ace534..f7641871 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -301,6 +301,9 @@ TEST_DECLARE (fs_stat_missing_path) TEST_DECLARE (fs_read_file_eof) TEST_DECLARE (fs_event_watch_dir) TEST_DECLARE (fs_event_watch_dir_recursive) +#ifdef _WIN32 +TEST_DECLARE (fs_event_watch_dir_short_path) +#endif TEST_DECLARE (fs_event_watch_file) TEST_DECLARE (fs_event_watch_file_exact_path) TEST_DECLARE (fs_event_watch_file_twice) @@ -828,6 +831,9 @@ TASK_LIST_START TEST_ENTRY (fs_file_open_append) TEST_ENTRY (fs_event_watch_dir) TEST_ENTRY (fs_event_watch_dir_recursive) +#ifdef _WIN32 + TEST_ENTRY (fs_event_watch_dir_short_path) +#endif TEST_ENTRY (fs_event_watch_file) TEST_ENTRY (fs_event_watch_file_exact_path) TEST_ENTRY (fs_event_watch_file_twice)