From 671c0c12ab7adf593df0bf6d6c5f449a6c1ca2ea Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Thu, 15 Dec 2016 16:15:22 -0800 Subject: [PATCH] sys: FSCTL_QUERY_PERSISTENT_VOLUME_STATE --- src/sys/fsctl.c | 36 ++++++++++++++++++++++++++++++++++++ tst/winfsp-tests/info-test.c | 24 ++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/sys/fsctl.c b/src/sys/fsctl.c index f1a7f5d0..86303ea1 100644 --- a/src/sys/fsctl.c +++ b/src/sys/fsctl.c @@ -29,6 +29,8 @@ static NTSTATUS FspFsvolFileSystemControlOplock( PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); static IO_COMPLETION_ROUTINE FspFsvolFileSystemControlOplockCompletion; static WORKER_THREAD_ROUTINE FspFsvolFileSystemControlOplockCompletionWork; +static NTSTATUS FspFsvolFileSystemControlQueryPersistentVolumeState( + PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); static NTSTATUS FspFsvolFileSystemControl( PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); FSP_IOCMPL_DISPATCH FspFsvolFileSystemControlComplete; @@ -42,6 +44,7 @@ FSP_DRIVER_DISPATCH FspFileSystemControl; #pragma alloc_text(PAGE, FspFsvolFileSystemControlOplock) // !#pragma alloc_text(PAGE, FspFsvolFileSystemControlOplockCompletion) #pragma alloc_text(PAGE, FspFsvolFileSystemControlOplockCompletionWork) +#pragma alloc_text(PAGE, FspFsvolFileSystemControlQueryPersistentVolumeState) #pragma alloc_text(PAGE, FspFsvolFileSystemControl) #pragma alloc_text(PAGE, FspFsvolFileSystemControlComplete) #pragma alloc_text(PAGE, FspFsvolFileSystemControlRequestFini) @@ -473,6 +476,36 @@ static VOID FspFsvolFileSystemControlOplockCompletionWork(PVOID Context) FspFree(CompletionContext); } +static NTSTATUS FspFsvolFileSystemControlQueryPersistentVolumeState( + PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) +{ + PAGED_CODE(); + + PVOID Buffer = Irp->AssociatedIrp.SystemBuffer; + ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength; + ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength; + PFILE_FS_PERSISTENT_VOLUME_INFORMATION Info; + + if (0 == Buffer) + return STATUS_INVALID_PARAMETER; + + if (sizeof(FILE_FS_PERSISTENT_VOLUME_INFORMATION) > InputBufferLength || + sizeof(FILE_FS_PERSISTENT_VOLUME_INFORMATION) > OutputBufferLength) + return STATUS_BUFFER_TOO_SMALL; + + Info = Buffer; + if (1 != Info->Version || + !FlagOn(Info->FlagMask, PERSISTENT_VOLUME_STATE_SHORT_NAME_CREATION_DISABLED)) + return STATUS_INVALID_PARAMETER; + + RtlZeroMemory(Info, sizeof(FILE_FS_PERSISTENT_VOLUME_INFORMATION)); + Info->VolumeFlags = PERSISTENT_VOLUME_STATE_SHORT_NAME_CREATION_DISABLED; + + Irp->IoStatus.Information = sizeof(FILE_FS_PERSISTENT_VOLUME_INFORMATION); + + return STATUS_SUCCESS; +} + static NTSTATUS FspFsvolFileSystemControl( PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { @@ -506,6 +539,9 @@ static NTSTATUS FspFsvolFileSystemControl( case FSCTL_REQUEST_OPLOCK: Result = FspFsvolFileSystemControlOplock(FsvolDeviceObject, Irp, IrpSp); break; + case FSCTL_QUERY_PERSISTENT_VOLUME_STATE: + Result = FspFsvolFileSystemControlQueryPersistentVolumeState(FsvolDeviceObject, Irp, IrpSp); + break; } break; } diff --git a/tst/winfsp-tests/info-test.c b/tst/winfsp-tests/info-test.c index dc25ac78..3ee03bd0 100644 --- a/tst/winfsp-tests/info-test.c +++ b/tst/winfsp-tests/info-test.c @@ -1039,6 +1039,8 @@ void getvolinfo_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) ULARGE_INTEGER TotalBytes; ULARGE_INTEGER FreeBytes; HANDLE Handle; + FILE_FS_PERSISTENT_VOLUME_INFORMATION PersistentVolumeInfo, PersistentVolumeInfoOut; + DWORD BytesTransferred; StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); @@ -1078,6 +1080,28 @@ void getvolinfo_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) ASSERT(FILE_TYPE_DISK == FileType); CloseHandle(Handle); + StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s%s", + -1 == Flags ? L"\\\\.\\" : L"", + Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); + + Handle = CreateFileW(FilePath, + FILE_READ_DATA, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, 0); + ASSERT(INVALID_HANDLE_VALUE != Handle); + memset(&PersistentVolumeInfo, 0, sizeof PersistentVolumeInfo); + PersistentVolumeInfo.FlagMask = PERSISTENT_VOLUME_STATE_SHORT_NAME_CREATION_DISABLED; + PersistentVolumeInfo.Version = 1; + Success = DeviceIoControl(Handle, FSCTL_QUERY_PERSISTENT_VOLUME_STATE, + &PersistentVolumeInfo, sizeof PersistentVolumeInfo, + &PersistentVolumeInfoOut, sizeof PersistentVolumeInfoOut, + &BytesTransferred, + 0); + ASSERT(Success); + ASSERT(sizeof PersistentVolumeInfoOut == BytesTransferred); + if (-1 != Flags) + ASSERT(PERSISTENT_VOLUME_STATE_SHORT_NAME_CREATION_DISABLED == PersistentVolumeInfoOut.VolumeFlags); + CloseHandle(Handle); + memfs_stop(memfs); }