From 7a229db6544c207fda7a3cf535da96dda6954f8e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 23 Oct 2006 15:13:55 +0000 Subject: [PATCH] * fhandler_disk_file.cc (fhandler_disk_file::rewinddir): Accomodate buggy RestartScan behaviour of Windows 2000. * wincap.h: Define has_buggy_restart_scan throughout. * wincap.cc: Ditto. --- winsup/cygwin/ChangeLog | 7 ++++++ winsup/cygwin/fhandler_disk_file.cc | 33 ++++++++++++++++++++++++++++- winsup/cygwin/wincap.cc | 23 +++++++++++++++----- winsup/cygwin/wincap.h | 2 ++ 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index c89a434b1..d76219164 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,10 @@ +2006-10-23 Corinna Vinschen + + * fhandler_disk_file.cc (fhandler_disk_file::rewinddir): Accomodate + buggy RestartScan behaviour of Windows 2000. + * wincap.h: Define has_buggy_restart_scan throughout. + * wincap.cc: Ditto. + 2006-10-22 Corinna Vinschen * fhandler_disk_file.cc (fhandler_disk_file::facl): Fix whitespace. diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 26a97f602..ed67bc78e 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -1975,7 +1975,38 @@ void fhandler_disk_file::rewinddir (DIR *dir) { if (wincap.is_winnt ()) - d_cachepos (dir) = 0; + { + d_cachepos (dir) = 0; + if (wincap.has_buggy_restart_scan () && isremote ()) + { + /* This works around a W2K bug. The RestartScan parameter in calls + to NtQueryDiretoryFile on remote shares is ignored, thus resulting + in not being able to rewind on remote shares. By reopening the + directory, we get a fresh new directory pointers. w*/ + UNICODE_STRING fname = {0, CYG_MAX_PATH * 2, (WCHAR *) L""}; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + IO_STATUS_BLOCK io; + HANDLE new_dir; + + InitializeObjectAttributes (&attr, &fname, OBJ_CASE_INSENSITIVE, + dir->__handle, NULL); + status = NtOpenFile (&new_dir, SYNCHRONIZE | FILE_LIST_DIRECTORY, + &attr, &io, wincap.shared (), + FILE_SYNCHRONOUS_IO_NONALERT + | FILE_OPEN_FOR_BACKUP_INTENT + | FILE_DIRECTORY_FILE); + if (!NT_SUCCESS (stat)) + debug_printf ("Unable to reopen dir %s, NT error: 0x%08x, " + "win32: %lu", get_name (), status, + RtlNtStatusToDosError (status)); + else + { + CloseHandle (dir->__handle); + dir->__handle = new_dir; + } + } + } else if (dir->__handle != INVALID_HANDLE_VALUE) { if (dir->__handle) diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index caef37873..9c82e45a7 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -66,6 +66,7 @@ static NO_COPY wincaps wincap_unknown = { has_disabled_user_tos_setting:false, has_fileid_dirinfo:false, has_exclusiveaddruse:false, + has_buggy_restart_scan:false, }; static NO_COPY wincaps wincap_95 = { @@ -123,6 +124,7 @@ static NO_COPY wincaps wincap_95 = { has_disabled_user_tos_setting:false, has_fileid_dirinfo:false, has_exclusiveaddruse:false, + has_buggy_restart_scan:false, }; static NO_COPY wincaps wincap_95osr2 = { @@ -180,6 +182,7 @@ static NO_COPY wincaps wincap_95osr2 = { has_disabled_user_tos_setting:false, has_fileid_dirinfo:false, has_exclusiveaddruse:false, + has_buggy_restart_scan:false, }; static NO_COPY wincaps wincap_98 = { @@ -237,6 +240,7 @@ static NO_COPY wincaps wincap_98 = { has_disabled_user_tos_setting:false, has_fileid_dirinfo:false, has_exclusiveaddruse:false, + has_buggy_restart_scan:false, }; static NO_COPY wincaps wincap_98se = { @@ -294,6 +298,7 @@ static NO_COPY wincaps wincap_98se = { has_disabled_user_tos_setting:false, has_fileid_dirinfo:false, has_exclusiveaddruse:false, + has_buggy_restart_scan:false, }; static NO_COPY wincaps wincap_me = { @@ -351,6 +356,7 @@ static NO_COPY wincaps wincap_me = { has_disabled_user_tos_setting:false, has_fileid_dirinfo:false, has_exclusiveaddruse:false, + has_buggy_restart_scan:false, }; static NO_COPY wincaps wincap_nt3 = { @@ -408,6 +414,7 @@ static NO_COPY wincaps wincap_nt3 = { has_disabled_user_tos_setting:false, has_fileid_dirinfo:false, has_exclusiveaddruse:false, + has_buggy_restart_scan:false, }; static NO_COPY wincaps wincap_nt4 = { @@ -465,6 +472,7 @@ static NO_COPY wincaps wincap_nt4 = { has_disabled_user_tos_setting:false, has_fileid_dirinfo:false, has_exclusiveaddruse:false, + has_buggy_restart_scan:false, }; static NO_COPY wincaps wincap_nt4sp4 = { @@ -521,7 +529,8 @@ static NO_COPY wincaps wincap_nt4sp4 = { has_working_virtual_lock:true, has_disabled_user_tos_setting:false, has_fileid_dirinfo:false, - has_exclusiveaddruse:true + has_exclusiveaddruse:true, + has_buggy_restart_scan:false, }; static NO_COPY wincaps wincap_2000 = { @@ -578,7 +587,8 @@ static NO_COPY wincaps wincap_2000 = { has_working_virtual_lock:true, has_disabled_user_tos_setting:true, has_fileid_dirinfo:true, - has_exclusiveaddruse:true + has_exclusiveaddruse:true, + has_buggy_restart_scan:true, }; static NO_COPY wincaps wincap_xp = { @@ -635,7 +645,8 @@ static NO_COPY wincaps wincap_xp = { has_working_virtual_lock:true, has_disabled_user_tos_setting:true, has_fileid_dirinfo:true, - has_exclusiveaddruse:true + has_exclusiveaddruse:true, + has_buggy_restart_scan:false, }; static NO_COPY wincaps wincap_2003 = { @@ -692,7 +703,8 @@ static NO_COPY wincaps wincap_2003 = { has_working_virtual_lock:true, has_disabled_user_tos_setting:true, has_fileid_dirinfo:true, - has_exclusiveaddruse:true + has_exclusiveaddruse:true, + has_buggy_restart_scan:false, }; static NO_COPY wincaps wincap_vista = { @@ -749,7 +761,8 @@ static NO_COPY wincaps wincap_vista = { has_working_virtual_lock:true, has_disabled_user_tos_setting:true, has_fileid_dirinfo:true, - has_exclusiveaddruse:true + has_exclusiveaddruse:true, + has_buggy_restart_scan:false, }; wincapc wincap __attribute__((section (".cygwin_dll_common"), shared)); diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index d4edfd3da..0f1b95a15 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -67,6 +67,7 @@ struct wincaps unsigned has_disabled_user_tos_setting : 1; unsigned has_fileid_dirinfo : 1; unsigned has_exclusiveaddruse : 1; + unsigned has_buggy_restart_scan : 1; }; class wincapc @@ -140,6 +141,7 @@ public: bool IMPLEMENT (has_disabled_user_tos_setting) bool IMPLEMENT (has_fileid_dirinfo) bool IMPLEMENT (has_exclusiveaddruse) + bool IMPLEMENT (has_buggy_restart_scan) #undef IMPLEMENT };