diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2004-04-06 10:19:31 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2004-04-06 10:19:31 +0000 |
commit | b8eac1dee4591c199ed330c0108255782526cb0a (patch) | |
tree | 96bfa86ff7ed6e51a0eb687c2474b6cf94f36fa6 /winsup/cygwin/fhandler_disk_file.cc | |
parent | cffd8968e3b761caed180bc883944853afcf488c (diff) | |
download | cygnal-b8eac1dee4591c199ed330c0108255782526cb0a.tar.gz cygnal-b8eac1dee4591c199ed330c0108255782526cb0a.tar.bz2 cygnal-b8eac1dee4591c199ed330c0108255782526cb0a.zip |
* fhandler_disk_file.cc (fhandler_base::fstat_helper): Request
compressed size only if the matching attributes are set. Use
NtQueryInformationFile instead of GetCompressedFileSize.
(fhandler_base::fstat_by_handle): Remove NT 3.5 cruft since
local.dwVolumeSerialNumber isn't used subsequently.
* ntdll.h: Add typedefs for FILE_COMPRESSION_INFORMATION and
FILE_INFORMATION_CLASS.
Diffstat (limited to 'winsup/cygwin/fhandler_disk_file.cc')
-rw-r--r-- | winsup/cygwin/fhandler_disk_file.cc | 40 |
1 files changed, 15 insertions, 25 deletions
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 8661445a1..62e133f76 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -23,6 +23,8 @@ details. */ #include "cygheap.h" #include "shared_info.h" #include "pinfo.h" +#include <ntdef.h> +#include "ntdll.h" #include <assert.h> #include <ctype.h> @@ -94,24 +96,12 @@ path_conv::ndisk_links (DWORD nNumberOfLinks) int __stdcall fhandler_base::fstat_by_handle (struct __stat64 *buf) { - int res = 0; BY_HANDLE_FILE_INFORMATION local; - - /* NT 3.51 seems to have a bug when attempting to get vol serial - numbers. This loop gets around this. */ - for (int i = 0; i < 2; i++) - { - if (!(res = GetFileInformationByHandle (get_handle (), &local))) - break; - if (local.dwVolumeSerialNumber && (long) local.dwVolumeSerialNumber != -1) - break; - } - + BOOL res = GetFileInformationByHandle (get_handle (), &local); debug_printf ("%d = GetFileInformationByHandle (%s, %d)", res, get_win32_name (), get_handle ()); - if (res == 0) - /* GetFileInformationByHandle will fail if it's given stdin/out/err - or a pipe*/ + /* GetFileInformationByHandle will fail if it's given stdio handle or pipe*/ + if (!res) { memset (&local, 0, sizeof (local)); local.nFileSizeLow = GetFileSize (get_handle (), &local.nFileSizeHigh); @@ -231,6 +221,9 @@ fhandler_base::fstat_helper (struct __stat64 *buf, DWORD nFileIndexLow, DWORD nNumberOfLinks) { + IO_STATUS_BLOCK st; + FILE_COMPRESSION_INFORMATION fci; + /* This is for FAT filesystems, which don't support atime/ctime */ if (ftLastAccessTime.dwLowDateTime == 0 && ftLastAccessTime.dwHighDateTime == 0) @@ -276,16 +269,13 @@ fhandler_base::fstat_helper (struct __stat64 *buf, buf->st_blksize = S_BLKSIZE; - /* GetCompressedFileSize() gets autoloaded. It returns INVALID_FILE_SIZE - if it doesn't exist. Since that's also a valid return value on 64bit - capable file systems, we must additionally check for the win32 error. */ - nFileSizeLow = GetCompressedFileSizeA (pc, &nFileSizeHigh); - if (nFileSizeLow != INVALID_FILE_SIZE || GetLastError () == NO_ERROR) - /* On systems supporting compressed (and sparsed) files, - GetCompressedFileSize() returns the actual amount of - bytes allocated on disk. */ - buf->st_blocks = (((_off64_t)nFileSizeHigh << 32) - + nFileSizeLow + S_BLKSIZE - 1) / S_BLKSIZE; + /* On compressed and sparsed files, we request the actual amount of bytes + allocated on disk. */ + if (pc.has_attribute (FILE_ATTRIBUTE_COMPRESSED | FILE_ATTRIBUTE_SPARSE_FILE) + && get_io_handle () + && !NtQueryInformationFile (get_io_handle (), &st, (PVOID) &fci, + sizeof fci, FileCompressionInformation)) + buf->st_blocks = (fci.CompressedSize.QuadPart + S_BLKSIZE - 1) / S_BLKSIZE; else /* Just compute no. of blocks from file size. */ buf->st_blocks = (buf->st_size + S_BLKSIZE - 1) / S_BLKSIZE; |