From 2a24463d0bfef5d94e0918583cfffcf3a949f0df Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 12 Apr 2005 14:26:31 +0000 Subject: [PATCH] * autoload.cc (NtQueryVolumeInformationFile): Add. * fhandler.cc (fhandler_base::raw_write): Don't touch has_changed flag. * fhandler.h (enum change_state): Remove. (fhandler_base::status): Revert has_changed to a simple bit. (fhandler_base::fstat_helper): Add nAllocSize parameter. Rename ftCreationTime to ftChangeTime. * fhandler_disk_file.cc: Call fstat_helper with additional allocation size throughout. (fhandler_base::fstat_by_handle): Use NT native functions to get full file information on NT. Call fstat_helper with LastWriteTime as ctime, if ChangeTime is not available. (fhandler_base::fstat_by_name): Call fstat_helper with LastWriteTime as ctime. (fhandler_base::fstat_helper): Add comment. Drop special FAT handling since it's useless. Use nAllocSize for st_blocks if available. (fhandler_disk_file::touch_ctime): Only touch LastWriteTime. (fhandler_disk_file::fchmod): Set has_changed on 9x only. (fhandler_disk_file::fchown): Don't set has_changed. (fhandler_disk_file::facl): Ditto. (fhandler_disk_file::ftruncate): Ditto. (fhandler_disk_file::link): Set has_changed on 9x only and on original file only. (fhandler_base::open_fs): Don't set has_changed in O_TRUNC case. * ntdll.h (FILE_BASIC_INFORMATION): Define. (FILE_STANDARD_INFORMATION): Define. (FILE_INTERNAL_INFORMATION): Define. (FILE_EA_INFORMATION): Define. (FILE_ACCESS_INFORMATION): Define. (FILE_POSITION_INFORMATION): Define. (FILE_MODE_INFORMATION): Define. (FILE_ALIGNMENT_INFORMATION): Define. (FILE_NAME_INFORMATION): Don't define with arbitrary FileName size. (FILE_ALL_INFORMATION): Define. (FILE_INFORMATION_CLASS): Add FileAllInformation. (FILE_FS_VOLUME_INFORMATION): Define. (FS_INFORMATION_CLASS): Define. (NtQueryVolumeInformationFile): Define. --- winsup/cygwin/ChangeLog | 41 +++++++++ winsup/cygwin/autoload.cc | 1 + winsup/cygwin/fhandler.cc | 1 - winsup/cygwin/fhandler.h | 15 ++-- winsup/cygwin/fhandler_disk_file.cc | 129 +++++++++++++++++----------- winsup/cygwin/ntdll.h | 81 +++++++++++++++-- 6 files changed, 202 insertions(+), 66 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index d330c5cfa..958941efe 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,44 @@ +2005-04-12 Corinna Vinschen + + * autoload.cc (NtQueryVolumeInformationFile): Add. + * fhandler.cc (fhandler_base::raw_write): Don't touch has_changed flag. + * fhandler.h (enum change_state): Remove. + (fhandler_base::status): Revert has_changed to a simple bit. + (fhandler_base::fstat_helper): Add nAllocSize parameter. Rename + ftCreationTime to ftChangeTime. + * fhandler_disk_file.cc: + Call fstat_helper with additional + allocation size throughout. + (fhandler_base::fstat_by_handle): Use NT native functions to get + full file information on NT. Call fstat_helper with LastWriteTime + as ctime, if ChangeTime is not available. + (fhandler_base::fstat_by_name): Call fstat_helper with LastWriteTime + as ctime. + (fhandler_base::fstat_helper): Add comment. Drop special FAT + handling since it's useless. Use nAllocSize for st_blocks if available. + (fhandler_disk_file::touch_ctime): Only touch LastWriteTime. + (fhandler_disk_file::fchmod): Set has_changed on 9x only. + (fhandler_disk_file::fchown): Don't set has_changed. + (fhandler_disk_file::facl): Ditto. + (fhandler_disk_file::ftruncate): Ditto. + (fhandler_disk_file::link): Set has_changed on 9x only and on original + file only. + (fhandler_base::open_fs): Don't set has_changed in O_TRUNC case. + * ntdll.h (FILE_BASIC_INFORMATION): Define. + (FILE_STANDARD_INFORMATION): Define. + (FILE_INTERNAL_INFORMATION): Define. + (FILE_EA_INFORMATION): Define. + (FILE_ACCESS_INFORMATION): Define. + (FILE_POSITION_INFORMATION): Define. + (FILE_MODE_INFORMATION): Define. + (FILE_ALIGNMENT_INFORMATION): Define. + (FILE_NAME_INFORMATION): Don't define with arbitrary FileName size. + (FILE_ALL_INFORMATION): Define. + (FILE_INFORMATION_CLASS): Add FileAllInformation. + (FILE_FS_VOLUME_INFORMATION): Define. + (FS_INFORMATION_CLASS): Define. + (NtQueryVolumeInformationFile): Define. + 2005-04-11 Corinna Vinschen Revert previous patch. diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index f0180160b..8986c7924 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -394,6 +394,7 @@ LoadDLLfuncEx2 (NtQueryObject, 20, ntdll, 1, 1) LoadDLLfuncEx (NtQuerySystemInformation, 16, ntdll, 1) LoadDLLfuncEx (NtQuerySecurityObject, 20, ntdll, 1) LoadDLLfuncEx (NtQueryVirtualMemory, 24, ntdll, 1) +LoadDLLfuncEx (NtQueryVolumeInformationFile, 20, ntdll, 1) LoadDLLfuncEx (NtSetSecurityObject, 12, ntdll, 1) LoadDLLfuncEx (NtUnmapViewOfSection, 8, ntdll, 1) LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1) diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index dc7485a79..1e7efc7d7 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -295,7 +295,6 @@ fhandler_base::raw_write (const void *ptr, size_t len) return -1; } written: - has_changed (data_changed); return bytes_written; } diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index e1ad64aa2..12c5b6445 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -78,12 +78,6 @@ enum query_state { query_write_attributes = 4 }; -enum change_state { - no_change = 0, - inode_changed = 1, - data_changed = 2 -}; - class fhandler_base { friend class dtable; @@ -106,14 +100,14 @@ class fhandler_base read or write access */ unsigned close_on_exec : 1; /* close-on-exec */ unsigned need_fork_fixup : 1; /* Set if need to fixup after fork. */ - unsigned has_changed : 2; /* Flag used to set ctime on close. */ + unsigned has_changed : 1; /* Flag used to set ctime on close. */ public: status_flags () : rbinary (0), rbinset (0), wbinary (0), wbinset (0), nohandle (0), uninterruptible_io (0), append_mode (0), did_lseek (0), query_open (no_query), close_on_exec (0), need_fork_fixup (0), - has_changed (no_change) + has_changed (0) {} } status, open_status; @@ -194,7 +188,7 @@ class fhandler_base IMPLEMENT_STATUS_FLAG (query_state, query_open) IMPLEMENT_STATUS_FLAG (bool, close_on_exec) IMPLEMENT_STATUS_FLAG (bool, need_fork_fixup) - IMPLEMENT_STATUS_FLAG (change_state, has_changed) + IMPLEMENT_STATUS_FLAG (bool, has_changed) int get_default_fmode (int flags); @@ -264,12 +258,13 @@ class fhandler_base virtual int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); int __stdcall fstat_fs (struct __stat64 *buf) __attribute__ ((regparm (2))); int __stdcall fstat_helper (struct __stat64 *buf, - FILETIME ftCreationTime, + FILETIME ftChangeTime, FILETIME ftLastAccessTime, FILETIME ftLastWriteTime, DWORD dwVolumeSerialNumber, DWORD nFileSizeHigh, DWORD nFileSizeLow, + LONGLONG nAllocSize, DWORD nFileIndexHigh, DWORD nFileIndexLow, DWORD nNumberOfLinks) diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 0cf1e1fb0..118308ab4 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -100,6 +100,51 @@ int __stdcall fhandler_base::fstat_by_handle (struct __stat64 *buf) { BY_HANDLE_FILE_INFORMATION local; + + if (wincap.is_winnt ()) + { + NTSTATUS status; + IO_STATUS_BLOCK io; + /* The entries potentially contain a name of MAX_PATH wide characters. */ + DWORD fvi_size = 2 * CYG_MAX_PATH + sizeof (FILE_FS_VOLUME_INFORMATION); + DWORD fai_size = 2 * CYG_MAX_PATH + sizeof (FILE_ALL_INFORMATION); + + PFILE_FS_VOLUME_INFORMATION pfvi = (PFILE_FS_VOLUME_INFORMATION) + alloca (fvi_size); + PFILE_ALL_INFORMATION pfai = (PFILE_ALL_INFORMATION) alloca (fai_size); + + status = NtQueryVolumeInformationFile (get_handle (), &io, pfvi, fvi_size, + FileFsVolumeInformation); + if (!NT_SUCCESS (status)) + { + debug_printf ("%u = NtQueryVolumeInformationFile)", + RtlNtStatusToDosError (status)); + pfvi->VolumeSerialNumber = 0; /* Set to pc.volser () in helper. */ + } + status = NtQueryInformationFile (get_handle (), &io, pfai, fai_size, + FileAllInformation); + if (NT_SUCCESS (status)) + /* If the change time is 0, it's a file system which doesn't + support a change timestamp. In that case use the LastWriteTime + entry, as in other calls to fstat_helper. */ + return fstat_helper (buf, + pfai->BasicInformation.ChangeTime.QuadPart ? + *(FILETIME *) &pfai->BasicInformation.ChangeTime : + *(FILETIME *) &pfai->BasicInformation.LastWriteTime, + *(FILETIME *) &pfai->BasicInformation.LastAccessTime, + *(FILETIME *) &pfai->BasicInformation.LastWriteTime, + pfvi->VolumeSerialNumber, + pfai->StandardInformation.EndOfFile.HighPart, + pfai->StandardInformation.EndOfFile.LowPart, + pfai->StandardInformation.AllocationSize.QuadPart, + pfai->InternalInformation.IndexNumber.HighPart, + pfai->InternalInformation.IndexNumber.LowPart, + pfai->StandardInformation.NumberOfLinks); + + debug_printf ("%u = NtQuerynformationFile)", + RtlNtStatusToDosError (status)); + } + BOOL res = GetFileInformationByHandle (get_handle (), &local); debug_printf ("%d = GetFileInformationByHandle (%s, %d)", res, get_win32_name (), get_handle ()); @@ -111,12 +156,13 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf) } return fstat_helper (buf, - local.ftCreationTime, + local.ftLastWriteTime, /* see fstat_helper comment */ local.ftLastAccessTime, local.ftLastWriteTime, local.dwVolumeSerialNumber, local.nFileSizeHigh, local.nFileSizeLow, + -1LL, local.nFileIndexHigh, local.nFileIndexLow, local.nNumberOfLinks); @@ -139,12 +185,13 @@ fhandler_base::fstat_by_name (struct __stat64 *buf) { FindClose (handle); res = fstat_helper (buf, - local.ftCreationTime, + local.ftLastWriteTime, /* see fstat_helper comment */ local.ftLastAccessTime, local.ftLastWriteTime, pc.volser (), local.nFileSizeHigh, local.nFileSizeLow, + -1LL, 0, 0, 1); @@ -152,7 +199,7 @@ fhandler_base::fstat_by_name (struct __stat64 *buf) else if (pc.isdir ()) { FILETIME ft = {}; - res = fstat_helper (buf, ft, ft, ft, pc.volser (), 0, 0, 0, 0, 1); + res = fstat_helper (buf, ft, ft, ft, pc.volser (), 0, 0, -1LL, 0, 0, 1); } else { @@ -213,14 +260,21 @@ fhandler_base::fstat_fs (struct __stat64 *buf) return res; } +/* The ftChangeTime is taken from the NTFS ChangeTime entry, if reading + the file information using NtQueryInformationFile succeeded. If not, + it's faked using the LastWriteTime entry from GetFileInformationByHandle + or FindFirstFile. We're deliberatly not using the creation time anymore + to simplify interaction with native Windows applications which choke on + creation times >= access or write times. */ int __stdcall fhandler_base::fstat_helper (struct __stat64 *buf, - FILETIME ftCreationTime, + FILETIME ftChangeTime, FILETIME ftLastAccessTime, FILETIME ftLastWriteTime, DWORD dwVolumeSerialNumber, DWORD nFileSizeHigh, DWORD nFileSizeLow, + LONGLONG nAllocSize, DWORD nFileIndexHigh, DWORD nFileIndexLow, DWORD nNumberOfLinks) @@ -228,17 +282,9 @@ fhandler_base::fstat_helper (struct __stat64 *buf, 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) - ftLastAccessTime = ftLastWriteTime; - if (ftCreationTime.dwLowDateTime == 0 - && ftCreationTime.dwHighDateTime == 0) - ftCreationTime = ftLastWriteTime; - to_timestruc_t (&ftLastAccessTime, &buf->st_atim); to_timestruc_t (&ftLastWriteTime, &buf->st_mtim); - to_timestruc_t (&ftCreationTime, &buf->st_ctim); + to_timestruc_t (&ftChangeTime, &buf->st_ctim); buf->st_dev = dwVolumeSerialNumber ?: pc.volser (); buf->st_size = ((_off64_t) nFileSizeHigh << 32) + nFileSizeLow; /* The number of links to a directory includes the @@ -273,15 +319,20 @@ fhandler_base::fstat_helper (struct __stat64 *buf, buf->st_blksize = 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) + if (nAllocSize >= 0LL) + /* A successful NtQueryInformationFile returns the allocation size + correctly for compressed and sparse files as well. */ + buf->st_blocks = (nAllocSize + S_BLKSIZE - 1) / S_BLKSIZE; + else if (pc.has_attribute (FILE_ATTRIBUTE_COMPRESSED + | FILE_ATTRIBUTE_SPARSE_FILE) && get_io_handle () && !NtQueryInformationFile (get_io_handle (), &st, (PVOID) &fci, sizeof fci, FileCompressionInformation)) + /* Otherwise we request the actual amount of bytes allocated for + compressed and sparsed files. */ buf->st_blocks = (fci.CompressedSize.QuadPart + S_BLKSIZE - 1) / S_BLKSIZE; else - /* Just compute no. of blocks from file size. */ + /* Otherwise compute no. of blocks from file size. */ buf->st_blocks = (buf->st_size + S_BLKSIZE - 1) / S_BLKSIZE; buf->st_mode = 0; @@ -380,6 +431,7 @@ fhandler_base::fstat_helper (struct __stat64 *buf, int __stdcall fhandler_disk_file::fstat (struct __stat64 *buf) { + /* Changing inode data requires setting ctime (only 9x). */ if (has_changed ()) touch_ctime (); return fstat_fs (buf); @@ -393,11 +445,10 @@ fhandler_disk_file::touch_ctime (void) GetSystemTimeAsFileTime (&ft); /* Modification time is touched if the file data has changed as well. This happens for instance on write() or ftruncate(). */ - if (!SetFileTime (get_io_handle (), &ft, NULL, - has_changed () == data_changed ? &ft : NULL)) + if (!SetFileTime (get_io_handle (), NULL, NULL, &ft)) debug_printf ("SetFileTime (%s) failed, %E", get_win32_name ()); else - has_changed (no_change); + has_changed (false); } int __stdcall @@ -443,8 +494,8 @@ fhandler_disk_file::fchmod (mode_t mode) res = 0; /* Set ctime on success. */ - if (!res) - has_changed (inode_changed); + if (!res && !wincap.is_winnt ()) + has_changed (true); if (oret) close (); @@ -476,13 +527,8 @@ fhandler_disk_file::fchown (__uid32_t uid, __gid32_t gid) attrib |= S_IFDIR; int res = get_file_attribute (pc.has_acls (), get_io_handle (), pc, &attrib); if (!res) - { - res = set_file_attribute (pc.has_acls (), get_io_handle (), pc, - uid, gid, attrib); - /* Set ctime on success. */ - if (!res) - has_changed (inode_changed); - } + res = set_file_attribute (pc.has_acls (), get_io_handle (), pc, + uid, gid, attrib); if (oret) close (); @@ -576,10 +622,6 @@ fhandler_disk_file::facl (int cmd, int nentries, __aclent32_t *aclbufp) } } - /* Set ctime on success. */ - if (!res && cmd == SETACL) - has_changed (inode_changed); - if (oret) close (); @@ -626,9 +668,6 @@ fhandler_disk_file::ftruncate (_off64_t length) res = res_bug; /* restore original file pointer location */ lseek (prev_loc, SEEK_SET); - /* Set ctime on success. */ - if (!res) - has_changed (data_changed); } } return res; @@ -760,8 +799,6 @@ fhandler_disk_file::link (const char *newpath) } success: - /* Set ctime on success. */ - has_changed (inode_changed); close (); if (!allow_winsymlinks && pc.is_lnk_symlink ()) SetFileAttributes (newpc, (DWORD) pc @@ -776,16 +813,14 @@ docopy: __seterrno (); return -1; } - /* Set ctime on success, also on the copy. */ - has_changed (inode_changed); + /* Set ctime on success (copy gets it automatically). */ + if (!wincap.is_winnt ()) + has_changed (true); close (); fhandler_disk_file fh (newpc); fh.query_open (query_write_attributes); if (fh.open (O_BINARY, 0)) - { - fh.has_changed (inode_changed); - fh.close (); - } + fh.close (); return 0; } @@ -897,10 +932,6 @@ fhandler_base::open_fs (int flags, mode_t mode) && !allow_ntsec && allow_ntea) set_file_attribute (false, NULL, get_win32_name (), mode); - /* O_TRUNC on existing file requires setting ctime. */ - if ((flags & (O_CREAT | O_TRUNC)) == O_TRUNC) - has_changed (data_changed); - set_fs_flags (pc.fs_flags ()); out: @@ -912,7 +943,7 @@ out: int fhandler_disk_file::close () { - /* Changing file data requires setting ctime. */ + /* Changing inode data requires setting ctime (only 9x). */ if (has_changed ()) touch_ctime (); return close_fs (); diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h index 844a131b5..dfebe77d1 100644 --- a/winsup/cygwin/ntdll.h +++ b/winsup/cygwin/ntdll.h @@ -354,11 +354,62 @@ typedef struct _MEMORY_WORKING_SET_LIST ULONG WorkingSetList[1]; } MEMORY_WORKING_SET_LIST, *PMEMORY_WORKING_SET_LIST; -typedef struct _FILE_NAME_INFORMATION -{ - DWORD FileNameLength; - WCHAR FileName[MAX_PATH + 100]; -} FILE_NAME_INFORMATION; +typedef struct _FILE_BASIC_INFORMATION { + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + ULONG FileAttributes; +} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; + +typedef struct _FILE_STANDARD_INFORMATION { + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG NumberOfLinks; + BOOLEAN DeletePending; + BOOLEAN Directory; +} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION; + +typedef struct _FILE_INTERNAL_INFORMATION { + LARGE_INTEGER IndexNumber; +} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION; + +typedef struct _FILE_EA_INFORMATION { + ULONG EaSize; +} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION; + +typedef struct _FILE_ACCESS_INFORMATION { + ACCESS_MASK AccessFlags; +} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION; + +typedef struct _FILE_POSITION_INFORMATION { + LARGE_INTEGER CurrentByteOffset; +} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION; + +typedef struct _FILE_MODE_INFORMATION { + ULONG Mode; +} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION; + +typedef struct _FILE_ALIGNMENT_INFORMATION { + ULONG AlignmentRequirement; +} FILE_ALIGNMENT_INFORMATION; + +typedef struct _FILE_NAME_INFORMATION { + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; + +typedef struct _FILE_ALL_INFORMATION { + FILE_BASIC_INFORMATION BasicInformation; + FILE_STANDARD_INFORMATION StandardInformation; + FILE_INTERNAL_INFORMATION InternalInformation; + FILE_EA_INFORMATION EaInformation; + FILE_ACCESS_INFORMATION AccessInformation; + FILE_POSITION_INFORMATION PositionInformation; + FILE_MODE_INFORMATION ModeInformation; + FILE_ALIGNMENT_INFORMATION AlignmentInformation; + FILE_NAME_INFORMATION NameInformation; +} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION; typedef struct _FILE_PIPE_LOCAL_INFORMATION { @@ -385,10 +436,25 @@ typedef struct _FILE_COMPRESSION_INFORMATION typedef enum _FILE_INFORMATION_CLASS { + FileAllInformation = 18, FilePipeLocalInformation = 24, FileCompressionInformation = 28 } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; +typedef struct _FILE_FS_VOLUME_INFORMATION +{ + LARGE_INTEGER VolumeCreationTime; + ULONG VolumeSerialNumber; + ULONG VolumeLabelLength; + BOOLEAN SupportsObjects; + WCHAR VolumeLabel[1]; +} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION; + +typedef enum _FSINFOCLASS +{ + FileFsVolumeInformation = 1 +} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS; + typedef enum _OBJECT_INFORMATION_CLASS { ObjectBasicInformation = 0, @@ -420,7 +486,7 @@ extern "C" NTSTATUS NTAPI NtOpenFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG); NTSTATUS NTAPI NtOpenSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES); - NTSTATUS NTAPI NtQueryInformationFile (HANDLE, IO_STATUS_BLOCK *, VOID *, + NTSTATUS NTAPI NtQueryInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS); NTSTATUS NTAPI NtQueryInformationProcess (HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG); @@ -432,6 +498,9 @@ extern "C" PSECURITY_DESCRIPTOR, ULONG, PULONG); NTSTATUS NTAPI NtQueryVirtualMemory (HANDLE, PVOID, MEMORY_INFORMATION_CLASS, PVOID, ULONG, PULONG); + NTSTATUS NTAPI NtQueryVolumeInformationFile (HANDLE, IO_STATUS_BLOCK *, + VOID *, ULONG, + FS_INFORMATION_CLASS); NTSTATUS NTAPI NtSetSecurityObject (HANDLE, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR); NTSTATUS NTAPI NtUnmapViewOfSection (HANDLE, PVOID);