diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 754892a1a..df3efaa25 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,12 @@ +2007-07-19 Corinna Vinschen + + * fhandler_disk_file.cc (fhandler_base::fstat_by_name): Use + NtQueryFullAttributesFile instead of FindFirstFile. + (fhandler_base::fstat_fs): Drop check for exec_state. Drop check for + invalid characters. + * ntdll.h (struct _FILE_NETWORK_OPEN_INFORMATION): Define. + (NtQueryFullAttributesFile): Declare. + 2007-07-19 Corinna Vinschen * fhandler.cc (fhandler_base::open): Drop local wpath and upath diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index a2b2bf093..5d37d04d5 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -272,34 +272,35 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf) int __stdcall fhandler_base::fstat_by_name (struct __stat64 *buf) { - int res; - HANDLE handle; - WIN32_FIND_DATA local; + int res = -1; + NTSTATUS status; + OBJECT_ATTRIBUTES attr; + FILE_NETWORK_OPEN_INFORMATION fnoi; if (!pc.exists ()) { debug_printf ("already determined that pc does not exist"); set_errno (ENOENT); - res = -1; } - else if ((handle = FindFirstFile (pc, &local)) != INVALID_HANDLE_VALUE) + else if (NT_SUCCESS (status = NtQueryFullAttributesFile ( + pc.get_object_attr (attr, sec_none_nih), &fnoi))) { - FindClose (handle); if (pc.is_rep_symlink ()) - local.dwFileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY; - pc.file_attributes (local.dwFileAttributes); + fnoi.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY; + pc.file_attributes (fnoi.FileAttributes); res = fstat_helper (buf, - local.ftLastWriteTime, /* see fstat_helper comment */ - local.ftLastAccessTime, - local.ftLastWriteTime, - local.ftCreationTime, - pc.volser (), - (ULONGLONG) local.nFileSizeHigh << 32 - | local.nFileSizeLow, - -1LL, - 0ULL, - 1, - local.dwFileAttributes); + *(FILETIME *) (fnoi.ChangeTime.QuadPart + ? &fnoi.ChangeTime + : &fnoi.LastWriteTime), + *(FILETIME *) &fnoi.LastAccessTime, + *(FILETIME *) &fnoi.LastWriteTime, + *(FILETIME *) &fnoi.CreationTime, + pc.volser (), + fnoi.EndOfFile.QuadPart, + fnoi.AllocationSize.QuadPart, + 0ULL, + 1, + fnoi.FileAttributes); } else if (pc.isdir ()) { @@ -309,8 +310,7 @@ fhandler_base::fstat_by_name (struct __stat64 *buf) } else { - debug_printf ("FindFirstFile failed for '%s', %E", (char *) pc); - __seterrno (); + __seterrno_from_nt_status (status); res = -1; } return res; @@ -330,14 +330,7 @@ fhandler_base::fstat_fs (struct __stat64 *buf) else return fstat_by_handle (buf); } - /* If we don't care if the file is executable or we already know if it is, - then just do a "query open" as it is apparently much faster. */ - if (pc.exec_state () != dont_know_if_executable) - { - if (pc.fs_is_fat () && !strpbrk (get_win32_name (), "?*|<>")) - return fstat_by_name (buf); - query_open (query_stat_control); - } + query_open (query_stat_control); if (!(oret = open_fs (open_flags, 0)) && get_errno () == EACCES) { /* If we couldn't open the file, try a query open with no permissions. diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h index a509f1fce..973d48ee6 100644 --- a/winsup/cygwin/ntdll.h +++ b/winsup/cygwin/ntdll.h @@ -520,6 +520,16 @@ typedef struct _FILE_STANDARD_INFORMATION { BOOLEAN Directory; } FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION; +typedef struct _FILE_NETWORK_OPEN_INFORMATION { + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG FileAttributes; +} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION; + typedef struct _FILE_INTERNAL_INFORMATION { LARGE_INTEGER FileId; } FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION; @@ -716,6 +726,8 @@ extern "C" BOOLEAN, PULONG, PULONG); NTSTATUS NTAPI NtQueryEaFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, BOOLEAN, PVOID, ULONG, PULONG, BOOLEAN); + NTSTATUS NTAPI NtQueryFullAttributesFile (POBJECT_ATTRIBUTES, + PFILE_NETWORK_OPEN_INFORMATION); NTSTATUS NTAPI NtQueryInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS); NTSTATUS NTAPI NtQueryInformationProcess (HANDLE, PROCESSINFOCLASS,