From 05b37c744b746889b529551aef566ceff1f23e28 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Sun, 8 Sep 2019 17:45:00 -0700 Subject: [PATCH] sys,dll: only user mode sends MountManager IOCTL's (except for cleanup in FspMountdevFini) --- src/dll/fs.c | 111 ++++++++++++++++++++++++++------ src/sys/volume.c | 39 ++--------- tst/winfsp-tests/volpath-test.c | 64 +++++++++++++++++- 3 files changed, 159 insertions(+), 55 deletions(-) diff --git a/src/dll/fs.c b/src/dll/fs.c index 8e717dc4..fb23f25e 100644 --- a/src/dll/fs.c +++ b/src/dll/fs.c @@ -447,6 +447,24 @@ static NTSTATUS FspFileSystemSetMountPoint_Mountmgr(PWSTR MountPoint, PWSTR Volu return STATUS_INVALID_PARAMETER; /* mountmgr.h */ + typedef enum + { + Disabled = 0, + Enabled, + } MOUNTMGR_AUTO_MOUNT_STATE; + typedef struct + { + MOUNTMGR_AUTO_MOUNT_STATE CurrentState; + } MOUNTMGR_QUERY_AUTO_MOUNT; + typedef struct + { + MOUNTMGR_AUTO_MOUNT_STATE NewState; + } MOUNTMGR_SET_AUTO_MOUNT; + typedef struct + { + USHORT DeviceNameLength; + WCHAR DeviceName[1]; + } MOUNTMGR_TARGET_NAME; typedef struct { USHORT SymbolicLinkNameOffset; @@ -456,8 +474,11 @@ static NTSTATUS FspFileSystemSetMountPoint_Mountmgr(PWSTR MountPoint, PWSTR Volu } MOUNTMGR_CREATE_POINT_INPUT; GUID UniqueId; - MOUNTMGR_CREATE_POINT_INPUT *Input = 0; - ULONG VolumeNameSize, InputSize; + MOUNTMGR_QUERY_AUTO_MOUNT QueryAutoMount; + MOUNTMGR_SET_AUTO_MOUNT SetAutoMount; + MOUNTMGR_TARGET_NAME *TargetName = 0; + MOUNTMGR_CREATE_POINT_INPUT *CreatePointInput = 0; + ULONG VolumeNameSize, QueryAutoMountSize, TargetNameSize, CreatePointInputSize; HKEY RegKey; LONG RegResult; WCHAR RegValueName[MAX_PATH]; @@ -472,31 +493,83 @@ static NTSTATUS FspFileSystemSetMountPoint_Mountmgr(PWSTR MountPoint, PWSTR Volu goto exit; VolumeNameSize = lstrlenW(VolumeName) * sizeof(WCHAR); - InputSize = sizeof *Input + sizeof L"\\DosDevices\\X:" - sizeof(WCHAR) + VolumeNameSize; + QueryAutoMountSize = sizeof QueryAutoMount; + TargetNameSize = FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + VolumeNameSize; + CreatePointInputSize = sizeof *CreatePointInput + + sizeof L"\\DosDevices\\X:" - sizeof(WCHAR) + VolumeNameSize; - Input = MemAlloc(InputSize); - if (0 == Input) + TargetName = MemAlloc(TargetNameSize); + if (0 == TargetName) { Result = STATUS_INSUFFICIENT_RESOURCES; goto exit; } - memset(Input, 0, sizeof *Input); - Input->SymbolicLinkNameOffset = sizeof *Input; - Input->SymbolicLinkNameLength = sizeof L"\\DosDevices\\X:" - sizeof(WCHAR); - Input->DeviceNameOffset = Input->SymbolicLinkNameOffset + Input->SymbolicLinkNameLength; - Input->DeviceNameLength = (USHORT)VolumeNameSize; - memcpy((PUINT8)Input + Input->SymbolicLinkNameOffset, - L"\\DosDevices\\X:", Input->SymbolicLinkNameLength); - ((PWCHAR)((PUINT8)Input + Input->SymbolicLinkNameOffset))[12] = MountPoint[4] & ~0x20; - /* convert to uppercase */ - memcpy((PUINT8)Input + Input->DeviceNameOffset, - VolumeName, Input->DeviceNameLength); + CreatePointInput = MemAlloc(CreatePointInputSize); + if (0 == CreatePointInput) + { + Result = STATUS_INSUFFICIENT_RESOURCES; + goto exit; + } + /* query the current AutoMount value and save it */ + Result = FspFileSystemMountmgrControl( + CTL_CODE('m', 15, METHOD_BUFFERED, FILE_ANY_ACCESS), + /* IOCTL_MOUNTMGR_QUERY_AUTO_MOUNT */ + 0, 0, &QueryAutoMount, &QueryAutoMountSize); + if (!NT_SUCCESS(Result)) + goto exit; + + /* disable AutoMount */ + SetAutoMount.NewState = 0; + Result = FspFileSystemMountmgrControl( + CTL_CODE('m', 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS), + /* IOCTL_MOUNTMGR_SET_AUTO_MOUNT */ + &SetAutoMount, sizeof SetAutoMount, 0, 0); + if (!NT_SUCCESS(Result)) + goto exit; + + /* announce volume arrival */ + memset(TargetName, 0, sizeof *TargetName); + TargetName->DeviceNameLength = (USHORT)VolumeNameSize; + memcpy(TargetName->DeviceName, + VolumeName, TargetName->DeviceNameLength); + Result = FspFileSystemMountmgrControl( + CTL_CODE('m', 11, METHOD_BUFFERED, FILE_READ_ACCESS), + /* IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION */ + TargetName, TargetNameSize, 0, 0); + if (!NT_SUCCESS(Result)) + goto exit; + + /* reset the AutoMount value to the saved one */ + SetAutoMount.NewState = QueryAutoMount.CurrentState; + FspFileSystemMountmgrControl( + CTL_CODE('m', 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS), + /* IOCTL_MOUNTMGR_SET_AUTO_MOUNT */ + &SetAutoMount, sizeof SetAutoMount, 0, 0); +#if 0 + if (!NT_SUCCESS(Result)) + goto exit; +#endif + + /* create mount point */ + memset(CreatePointInput, 0, sizeof *CreatePointInput); + CreatePointInput->SymbolicLinkNameOffset = sizeof *CreatePointInput; + CreatePointInput->SymbolicLinkNameLength = sizeof L"\\DosDevices\\X:" - sizeof(WCHAR); + CreatePointInput->DeviceNameOffset = + CreatePointInput->SymbolicLinkNameOffset + CreatePointInput->SymbolicLinkNameLength; + CreatePointInput->DeviceNameLength = (USHORT)VolumeNameSize; + memcpy((PUINT8)CreatePointInput + CreatePointInput->SymbolicLinkNameOffset, + L"\\DosDevices\\X:", CreatePointInput->SymbolicLinkNameLength); + ((PWCHAR)((PUINT8)CreatePointInput + CreatePointInput->SymbolicLinkNameOffset))[12] = + MountPoint[4] & ~0x20; + /* convert to uppercase */ + memcpy((PUINT8)CreatePointInput + CreatePointInput->DeviceNameOffset, + VolumeName, CreatePointInput->DeviceNameLength); Result = FspFileSystemMountmgrControl( CTL_CODE('m', 0, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS), /* IOCTL_MOUNTMGR_CREATE_POINT */ - Input, InputSize, 0, 0); + CreatePointInput, CreatePointInputSize, 0, 0); if (!NT_SUCCESS(Result)) goto exit; @@ -533,7 +606,8 @@ static NTSTATUS FspFileSystemSetMountPoint_Mountmgr(PWSTR MountPoint, PWSTR Volu Result = STATUS_SUCCESS; exit: - MemFree(Input); + MemFree(CreatePointInput); + MemFree(TargetName); return Result; } @@ -692,7 +766,6 @@ static VOID FspFileSystemRemoveMountPoint_Mountmgr(PWSTR MountPoint) L"\\DosDevices\\X:", Input->SymbolicLinkNameLength); ((PWCHAR)((PUINT8)Input + Input->SymbolicLinkNameOffset))[12] = MountPoint[4] & ~0x20; /* convert to uppercase */ - Result = FspFileSystemMountmgrControl( CTL_CODE('m', 1, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS), /* IOCTL_MOUNTMGR_DELETE_POINTS */ diff --git a/src/sys/volume.c b/src/sys/volume.c index f17114f2..3292d35c 100644 --- a/src/sys/volume.c +++ b/src/sys/volume.c @@ -578,14 +578,6 @@ NTSTATUS FspVolumeMakeMountdev( ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength; ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength; BOOLEAN Persistent = 0 < InputBufferLength ? !!*(PBOOLEAN)Irp->AssociatedIrp.SystemBuffer : FALSE; - MOUNTMGR_QUERY_AUTO_MOUNT QueryAutoMount; - MOUNTMGR_SET_AUTO_MOUNT SetAutoMount; - union - { - MOUNTMGR_TARGET_NAME V; - UINT8 B[FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + FSP_FSCTL_VOLUME_NAME_SIZEMAX]; - } TargetName; - ULONG Length; NTSTATUS Result; if (0 == FsvrtDeviceObject) @@ -596,34 +588,11 @@ NTSTATUS FspVolumeMakeMountdev( FspDeviceGlobalLock(); Result = FspMountdevMake(FsvrtDeviceObject, FsvolDeviceObject, Persistent); - if (NT_SUCCESS(Result)) - { - Length = sizeof QueryAutoMount; - Result = FspSendMountmgrDeviceControlIrp(IOCTL_MOUNTMGR_QUERY_AUTO_MOUNT, - &QueryAutoMount, 0, &Length); - if (!NT_SUCCESS(Result)) - goto exit; - - SetAutoMount.NewState = 0; - Result = FspSendMountmgrDeviceControlIrp(IOCTL_MOUNTMGR_SET_AUTO_MOUNT, - &SetAutoMount, sizeof SetAutoMount, 0); - if (!NT_SUCCESS(Result)) - goto exit; - - TargetName.V.DeviceNameLength = FsvolDeviceExtension->VolumeName.Length; - RtlCopyMemory(TargetName.V.DeviceName, - FsvolDeviceExtension->VolumeName.Buffer, FsvolDeviceExtension->VolumeName.Length); - Result = FspSendMountmgrDeviceControlIrp(IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION, - &TargetName.V, FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + TargetName.V.DeviceNameLength, 0); - - SetAutoMount.NewState = QueryAutoMount.CurrentState; - FspSendMountmgrDeviceControlIrp(IOCTL_MOUNTMGR_SET_AUTO_MOUNT, - &SetAutoMount, sizeof SetAutoMount, 0); - } - else if (STATUS_TOO_LATE == Result) - Result = STATUS_SUCCESS; if (!NT_SUCCESS(Result)) - goto exit; + { + if (STATUS_TOO_LATE != Result) + goto exit; + } RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &FspFsvrtDeviceExtension(FsvrtDeviceObject)->UniqueId, sizeof(GUID)); diff --git a/tst/winfsp-tests/volpath-test.c b/tst/winfsp-tests/volpath-test.c index e26603dc..34cb45ca 100644 --- a/tst/winfsp-tests/volpath-test.c +++ b/tst/winfsp-tests/volpath-test.c @@ -159,7 +159,67 @@ static void volpath_mount_dotest(ULONG Flags, PWSTR Prefix, PWSTR MountPoint) FspFileSystemRemoveMountPoint(MemfsFileSystem(memfs)); - memfs_stop(memfs); + ASSERT(VolumePathNameSuccess[0]); + ASSERT(VolumePathNameSuccess[1]); + ASSERT(VolumePathNameSuccess[2]); + + if (MemfsNet != Flags) + { + ASSERT(VolumePathNameSuccess[4]); + ASSERT(VolumePathNameSuccess[5]); + ASSERT(VolumePathNameSuccess[6]); + } + + Result = FspFileSystemSetMountPoint(MemfsFileSystem(memfs), MountPoint); + ASSERT(NT_SUCCESS(Result)); + + Prefix = FspFileSystemMountPoint(MemfsFileSystem(memfs)); + + StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1", + Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); + + Success = CreateDirectoryW(FilePath, 0); + ASSERT(Success); + + StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1\\file2", + Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); + + Handle = CreateFileW(FilePath, + GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); + ASSERT(INVALID_HANDLE_VALUE != Handle); + CloseHandle(Handle); + + StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\", + Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); + + VolumePathNameSuccess[0] = GetVolumePathNameW(FilePath, VolumePathName, MAX_PATH); + VolumePathNameSuccess[4] = GetVolumeNameForVolumeMountPointW(VolumePathName, VolumeName, MAX_PATH); + + StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1", + Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); + + VolumePathNameSuccess[1] = GetVolumePathNameW(FilePath, VolumePathName, MAX_PATH); + VolumePathNameSuccess[5] = GetVolumeNameForVolumeMountPointW(VolumePathName, VolumeName, MAX_PATH); + + StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1\\file2", + Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); + + VolumePathNameSuccess[2] = GetVolumePathNameW(FilePath, VolumePathName, MAX_PATH); + VolumePathNameSuccess[6] = GetVolumeNameForVolumeMountPointW(VolumePathName, VolumeName, MAX_PATH); + + StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1\\file2", + Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); + + Success = DeleteFileW(FilePath); + ASSERT(Success); + + StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1", + Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); + + Success = RemoveDirectoryW(FilePath); + ASSERT(Success); + + FspFileSystemRemoveMountPoint(MemfsFileSystem(memfs)); ASSERT(VolumePathNameSuccess[0]); ASSERT(VolumePathNameSuccess[1]); @@ -171,6 +231,8 @@ static void volpath_mount_dotest(ULONG Flags, PWSTR Prefix, PWSTR MountPoint) ASSERT(VolumePathNameSuccess[5]); ASSERT(VolumePathNameSuccess[6]); } + + memfs_stop(memfs); } static void volpath_mount_test(void)