diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index a88c92bfb..1b1938bcb 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,13 @@ +2011-12-13 Corinna Vinschen + + * fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Call + file_get_fnoi instead of NtQueryInformationFile. + * path.cc (file_get_fnoi): New helper function to collect a + FILE_NETWORK_OPEN_INFORMATION block. + (symlink_info::check): Call file_get_fnoi rather than + NtQueryInformationFile to collect a FILE_NETWORK_OPEN_INFORMATION block. + * path.h (file_get_fnoi): Declare. + 2011-12-13 Dave Korn * times.cc (hires_ns::resolution): Don't return less than 1. diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 7f92e8e28..37040fbd5 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -347,9 +347,7 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf) on the information stored in pc.fnoi. So we overwrite them here. */ if (get_io_handle ()) { - PFILE_NETWORK_OPEN_INFORMATION pfnoi = pc.fnoi (); - status = NtQueryInformationFile (h, &io, pfnoi, sizeof *pfnoi, - FileNetworkOpenInformation); + status = file_get_fnoi (h, pc.fs_is_netapp (), pc.fnoi ()); if (!NT_SUCCESS (status)) { debug_printf ("%p = NtQueryInformationFile(%S, " diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 56b219485..09874327d 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -1180,6 +1180,48 @@ path_conv::is_binary () && (bin == SCS_32BIT_BINARY || bin == SCS_64BIT_BINARY); } +/* Helper function to fill the fnoi datastructure for a file. */ +NTSTATUS +file_get_fnoi (HANDLE h, bool skip_network_open_inf, + PFILE_NETWORK_OPEN_INFORMATION pfnoi) +{ + NTSTATUS status; + IO_STATUS_BLOCK io; + + /* Some FSes (Netapps) don't implement FileNetworkOpenInformation. */ + status = skip_network_open_inf ? STATUS_INVALID_PARAMETER + : NtQueryInformationFile (h, &io, pfnoi, sizeof *pfnoi, + FileNetworkOpenInformation); + if (status == STATUS_INVALID_PARAMETER || status == STATUS_NOT_IMPLEMENTED) + { + /* Apart from accessing Netapps, this also occurs when accessing SMB + share root dirs hosted on NT4 (STATUS_INVALID_PARAMETER), or when + accessing SMB share root dirs from NT4 (STATUS_NOT_IMPLEMENTED). */ + FILE_BASIC_INFORMATION fbi; + FILE_STANDARD_INFORMATION fsi; + + status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi, + FileBasicInformation); + if (NT_SUCCESS (status)) + { + memcpy (pfnoi, &fbi, 4 * sizeof (LARGE_INTEGER)); + if (NT_SUCCESS (NtQueryInformationFile (h, &io, &fsi, + sizeof fsi, + FileStandardInformation))) + { + pfnoi->EndOfFile.QuadPart = fsi.EndOfFile.QuadPart; + pfnoi->AllocationSize.QuadPart + = fsi.AllocationSize.QuadPart; + } + else + pfnoi->EndOfFile.QuadPart + = pfnoi->AllocationSize.QuadPart = 0; + pfnoi->FileAttributes = fbi.FileAttributes; + } + } + return status; +} + /* Normalize a Win32 path. /'s are converted to \'s in the process. All duplicate \'s, except for 2 leading \'s, are deleted. @@ -2422,44 +2464,9 @@ restart: } else { - PFILE_NETWORK_OPEN_INFORMATION pfnoi = conv_hdl.fnoi (); - - /* Netapps don't implement FileNetworkOpenInformation. */ - status = fs.is_netapp () - ? STATUS_INVALID_PARAMETER - : NtQueryInformationFile (h, &io, pfnoi, sizeof *pfnoi, - FileNetworkOpenInformation); - if (status == STATUS_INVALID_PARAMETER - || status == STATUS_NOT_IMPLEMENTED) - { - /* Apart from accessing Netapps, this also occurs when - accessing SMB share root dirs hosted on NT4 - (STATUS_INVALID_PARAMETER), or when trying to access - SMB share root dirs from NT4 (STATUS_NOT_IMPLEMENTED). */ - FILE_BASIC_INFORMATION fbi; - FILE_STANDARD_INFORMATION fsi; - - status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi, - FileBasicInformation); - if (NT_SUCCESS (status)) - { - memcpy (pfnoi, &fbi, 4 * sizeof (LARGE_INTEGER)); - if (NT_SUCCESS (NtQueryInformationFile (h, &io, &fsi, - sizeof fsi, - FileStandardInformation))) - { - pfnoi->EndOfFile.QuadPart = fsi.EndOfFile.QuadPart; - pfnoi->AllocationSize.QuadPart - = fsi.AllocationSize.QuadPart; - } - else - pfnoi->EndOfFile.QuadPart - = pfnoi->AllocationSize.QuadPart = 0; - pfnoi->FileAttributes = fbi.FileAttributes; - } - } + status = file_get_fnoi (h, fs.is_netapp (), conv_hdl.fnoi ()); if (NT_SUCCESS (status)) - fileattr = pfnoi->FileAttributes; + fileattr = conv_hdl.fnoi ()->FileAttributes; } } if (!NT_SUCCESS (status)) diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 9dce9178e..3ef857a89 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -425,6 +425,7 @@ int path_prefix_p (const char *path1, const char *path2, int len1, bool caseinsensitive) __attribute__ ((regparm (3))); bool is_floppy (const char *); +NTSTATUS file_get_fnoi (HANDLE, bool, struct _FILE_NETWORK_OPEN_INFORMATION *); int normalize_win32_path (const char *, char *, char *&); int normalize_posix_path (const char *, char *, char *&); PUNICODE_STRING get_nt_native_path (const char *, UNICODE_STRING&, bool) __attribute__ ((regparm (3)));