* 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.
This commit is contained in:
Corinna Vinschen 2004-04-06 10:19:31 +00:00
parent cffd8968e3
commit b8eac1dee4
3 changed files with 42 additions and 28 deletions

View File

@ -1,3 +1,13 @@
2004-04-03 Corinna Vinschen <corinna@vinschen.de>
* 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.
2004-04-03 Corinna Vinschen <corinna@vinschen.de> 2004-04-03 Corinna Vinschen <corinna@vinschen.de>
* fhandler_raw.cc (fhandler_dev_raw::open): Actually use "options". * fhandler_raw.cc (fhandler_dev_raw::open): Actually use "options".

View File

@ -23,6 +23,8 @@ details. */
#include "cygheap.h" #include "cygheap.h"
#include "shared_info.h" #include "shared_info.h"
#include "pinfo.h" #include "pinfo.h"
#include <ntdef.h>
#include "ntdll.h"
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
@ -94,24 +96,12 @@ path_conv::ndisk_links (DWORD nNumberOfLinks)
int __stdcall int __stdcall
fhandler_base::fstat_by_handle (struct __stat64 *buf) fhandler_base::fstat_by_handle (struct __stat64 *buf)
{ {
int res = 0;
BY_HANDLE_FILE_INFORMATION local; BY_HANDLE_FILE_INFORMATION local;
BOOL res = GetFileInformationByHandle (get_handle (), &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;
}
debug_printf ("%d = GetFileInformationByHandle (%s, %d)", debug_printf ("%d = GetFileInformationByHandle (%s, %d)",
res, get_win32_name (), get_handle ()); res, get_win32_name (), get_handle ());
if (res == 0) /* GetFileInformationByHandle will fail if it's given stdio handle or pipe*/
/* GetFileInformationByHandle will fail if it's given stdin/out/err if (!res)
or a pipe*/
{ {
memset (&local, 0, sizeof (local)); memset (&local, 0, sizeof (local));
local.nFileSizeLow = GetFileSize (get_handle (), &local.nFileSizeHigh); local.nFileSizeLow = GetFileSize (get_handle (), &local.nFileSizeHigh);
@ -231,6 +221,9 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
DWORD nFileIndexLow, DWORD nFileIndexLow,
DWORD nNumberOfLinks) DWORD nNumberOfLinks)
{ {
IO_STATUS_BLOCK st;
FILE_COMPRESSION_INFORMATION fci;
/* This is for FAT filesystems, which don't support atime/ctime */ /* This is for FAT filesystems, which don't support atime/ctime */
if (ftLastAccessTime.dwLowDateTime == 0 if (ftLastAccessTime.dwLowDateTime == 0
&& ftLastAccessTime.dwHighDateTime == 0) && ftLastAccessTime.dwHighDateTime == 0)
@ -276,16 +269,13 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
buf->st_blksize = S_BLKSIZE; buf->st_blksize = S_BLKSIZE;
/* GetCompressedFileSize() gets autoloaded. It returns INVALID_FILE_SIZE /* On compressed and sparsed files, we request the actual amount of bytes
if it doesn't exist. Since that's also a valid return value on 64bit allocated on disk. */
capable file systems, we must additionally check for the win32 error. */ if (pc.has_attribute (FILE_ATTRIBUTE_COMPRESSED | FILE_ATTRIBUTE_SPARSE_FILE)
nFileSizeLow = GetCompressedFileSizeA (pc, &nFileSizeHigh); && get_io_handle ()
if (nFileSizeLow != INVALID_FILE_SIZE || GetLastError () == NO_ERROR) && !NtQueryInformationFile (get_io_handle (), &st, (PVOID) &fci,
/* On systems supporting compressed (and sparsed) files, sizeof fci, FileCompressionInformation))
GetCompressedFileSize() returns the actual amount of buf->st_blocks = (fci.CompressedSize.QuadPart + S_BLKSIZE - 1) / S_BLKSIZE;
bytes allocated on disk. */
buf->st_blocks = (((_off64_t)nFileSizeHigh << 32)
+ nFileSizeLow + S_BLKSIZE - 1) / S_BLKSIZE;
else else
/* Just compute no. of blocks from file size. */ /* Just compute no. of blocks from file size. */
buf->st_blocks = (buf->st_size + S_BLKSIZE - 1) / S_BLKSIZE; buf->st_blocks = (buf->st_size + S_BLKSIZE - 1) / S_BLKSIZE;

View File

@ -357,6 +357,20 @@ typedef struct _FILE_NAME_INFORMATION
WCHAR FileName[MAX_PATH + 100]; WCHAR FileName[MAX_PATH + 100];
} FILE_NAME_INFORMATION; } FILE_NAME_INFORMATION;
typedef struct _FILE_COMPRESSION_INFORMATION
{
LARGE_INTEGER CompressedSize;
USHORT CompressionFormat;
UCHAR CompressionUnitShift;
UCHAR Unknown;
UCHAR ClusterSizeShift;
} FILE_COMPRESSION_INFORMATION, *PFILE_COMPRESSION_INFORMATION;
typedef enum _FILE_INFORMATION_CLASS
{
FileCompressionInformation = 28
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
typedef enum _OBJECT_INFORMATION_CLASS typedef enum _OBJECT_INFORMATION_CLASS
{ {
ObjectBasicInformation = 0, ObjectBasicInformation = 0,