Partial implementation of NtQueryVolumeInformationFile.
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 60c1cbe..d293b42 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -30,6 +30,23 @@
#ifdef HAVE_SYS_ERRNO_H
#include <sys/errno.h>
#endif
+#ifdef HAVE_SYS_STATVFS_H
+# include <sys/statvfs.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+#ifdef STATFS_DEFINED_BY_SYS_VFS
+# include <sys/vfs.h>
+#else
+# ifdef STATFS_DEFINED_BY_SYS_MOUNT
+# include <sys/mount.h>
+# else
+# ifdef STATFS_DEFINED_BY_SYS_STATFS
+# include <sys/statfs.h>
+# endif
+# endif
+#endif
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
@@ -923,6 +940,7 @@
return status;
}
+
/******************************************************************************
* NtQueryVolumeInformationFile [NTDLL.@]
* ZwQueryVolumeInformationFile [NTDLL.@]
@@ -930,106 +948,133 @@
* Get volume information for an open file handle.
*
* PARAMS
- * FileHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile()
- * IoStatusBlock [O] Receives information about the operation on return
- * FsInformation [O] Destination for volume information
- * Length [I] Size of FsInformation
- * FsInformationClass [I] Type of volume information to set
+ * handle [I] Handle returned from ZwOpenFile() or ZwCreateFile()
+ * io [O] Receives information about the operation on return
+ * buffer [O] Destination for volume information
+ * length [I] Size of FsInformation
+ * info_class [I] Type of volume information to set
*
* RETURNS
- * Success: 0. IoStatusBlock and FsInformation are updated.
+ * Success: 0. io and buffer are updated.
* Failure: An NTSTATUS error code describing the error.
*/
-NTSTATUS WINAPI NtQueryVolumeInformationFile (
- IN HANDLE FileHandle,
- OUT PIO_STATUS_BLOCK IoStatusBlock,
- OUT PVOID FSInformation,
- IN ULONG Length,
- IN FS_INFORMATION_CLASS FSInformationClass)
+NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io,
+ PVOID buffer, ULONG length,
+ FS_INFORMATION_CLASS info_class )
{
- ULONG len = 0;
+ int fd;
- FIXME("(%p %p %p 0x%08lx 0x%08x) stub!\n",
- FileHandle, IoStatusBlock, FSInformation, Length, FSInformationClass);
+ if ((io->u.Status = wine_server_handle_to_fd( handle, GENERIC_READ,
+ &fd, NULL, NULL )) != STATUS_SUCCESS)
+ return io->u.Status;
- switch ( FSInformationClass )
- {
- case FileFsVolumeInformation:
- len = sizeof( FILE_FS_VOLUME_INFORMATION );
- break;
- case FileFsLabelInformation:
- len = 0;
- break;
+ io->u.Status = STATUS_NOT_IMPLEMENTED;
+ io->Information = 0;
- case FileFsSizeInformation:
- len = sizeof( FILE_FS_SIZE_INFORMATION );
- break;
+ switch( info_class )
+ {
+ case FileFsVolumeInformation:
+ FIXME( "%p: volume info not supported\n", handle );
+ break;
+ case FileFsLabelInformation:
+ FIXME( "%p: label info not supported\n", handle );
+ break;
+ case FileFsSizeInformation:
+ if (length < sizeof(FILE_FS_SIZE_INFORMATION))
+ io->u.Status = STATUS_BUFFER_TOO_SMALL;
+ else
+ {
+ FILE_FS_SIZE_INFORMATION *info = buffer;
+ struct statvfs st;
- case FileFsDeviceInformation:
- len = sizeof( FILE_FS_DEVICE_INFORMATION );
- break;
- case FileFsAttributeInformation:
- len = sizeof( FILE_FS_ATTRIBUTE_INFORMATION );
- break;
+ if (fstatvfs( fd, &st ) < 0) io->u.Status = FILE_GetNtStatus();
+ else
+ {
+ info->TotalAllocationUnits.QuadPart = st.f_blocks;
+ info->AvailableAllocationUnits.QuadPart = st.f_bavail;
+ info->SectorsPerAllocationUnit = 1;
+ info->BytesPerSector = st.f_frsize;
+ io->Information = sizeof(*info);
+ io->u.Status = STATUS_SUCCESS;
+ }
+ }
+ break;
+ case FileFsDeviceInformation:
+ if (length < sizeof(FILE_FS_DEVICE_INFORMATION))
+ io->u.Status = STATUS_BUFFER_TOO_SMALL;
+ else
+ {
+ FILE_FS_DEVICE_INFORMATION *info = buffer;
- case FileFsControlInformation:
- len = 0;
- break;
+#if defined(linux) && defined(HAVE_FSTATFS)
+ struct stat st;
+ struct statfs stfs;
- case FileFsFullSizeInformation:
- len = 0;
- break;
-
- case FileFsObjectIdInformation:
- len = 0;
- break;
-
- case FileFsMaximumInformation:
- len = 0;
- break;
- }
-
- if (Length < len)
- return STATUS_BUFFER_TOO_SMALL;
-
- switch ( FSInformationClass )
- {
- case FileFsVolumeInformation:
- break;
- case FileFsLabelInformation:
- break;
-
- case FileFsSizeInformation:
- break;
-
- case FileFsDeviceInformation:
- if (FSInformation)
- {
- FILE_FS_DEVICE_INFORMATION * DeviceInfo = FSInformation;
- DeviceInfo->DeviceType = FILE_DEVICE_DISK;
- DeviceInfo->Characteristics = 0;
- break;
- };
- case FileFsAttributeInformation:
- break;
-
- case FileFsControlInformation:
- break;
-
- case FileFsFullSizeInformation:
- break;
-
- case FileFsObjectIdInformation:
- break;
-
- case FileFsMaximumInformation:
- break;
- }
- IoStatusBlock->u.Status = STATUS_SUCCESS;
- IoStatusBlock->Information = len;
- return STATUS_SUCCESS;
+ info->DeviceType = FILE_DEVICE_DISK;
+ info->Characteristics = 0;
+ if (fstatfs( fd, &stfs ) < 0) stfs.f_type = 0;
+ switch (stfs.f_type)
+ {
+ case 0x9660: /* iso9660 */
+ case 0x15013346: /* udf */
+ info->DeviceType = FILE_DEVICE_CD_ROM_FILE_SYSTEM;
+ info->Characteristics = FILE_REMOVABLE_MEDIA|FILE_READ_ONLY_DEVICE;
+ break;
+ case 0x6969: /* nfs */
+ case 0x517B: /* smbfs */
+ case 0x564c: /* ncpfs */
+ info->DeviceType = FILE_DEVICE_NETWORK_FILE_SYSTEM;
+ info->Characteristics = FILE_REMOTE_DEVICE;
+ break;
+ case 0x01021994: /* tmpfs */
+ case 0x28cd3d45: /* cramfs */
+ case 0x1373: /* devfs */
+ case 0x9fa0: /* procfs */
+ info->DeviceType = FILE_DEVICE_VIRTUAL_DISK;
+ info->Characteristics = 0;
+ break;
+ default:
+ info->DeviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
+ info->Characteristics = 0;
+ break;
+ }
+ /* check for floppy disk */
+ if (!fstat( fd, &st ) && major(st.st_dev) == 2 /*FLOPPY_MAJOR*/)
+ info->Characteristics |= FILE_REMOVABLE_MEDIA;
+#else
+ static int warned;
+ if (!warned++) FIXME( "device info not supported on this platform\n" );
+ info->DeviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
+ info->Characteristics = 0;
+#endif
+ io->Information = sizeof(*info);
+ io->u.Status = STATUS_SUCCESS;
+ }
+ break;
+ case FileFsAttributeInformation:
+ FIXME( "%p: attribute info not supported\n", handle );
+ break;
+ case FileFsControlInformation:
+ FIXME( "%p: control info not supported\n", handle );
+ break;
+ case FileFsFullSizeInformation:
+ FIXME( "%p: full size info not supported\n", handle );
+ break;
+ case FileFsObjectIdInformation:
+ FIXME( "%p: object id info not supported\n", handle );
+ break;
+ case FileFsMaximumInformation:
+ FIXME( "%p: maximum info not supported\n", handle );
+ break;
+ default:
+ io->u.Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ wine_server_release_fd( handle, fd );
+ return io->u.Status;
}
+
/******************************************************************
* NtFlushBuffersFile (NTDLL.@)
*