sys,dll: only user mode sends MountManager IOCTL's

(except for cleanup in FspMountdevFini)
This commit is contained in:
Bill Zissimopoulos 2019-09-08 17:45:00 -07:00
parent 1d15c9546b
commit 05b37c744b
No known key found for this signature in database
GPG Key ID: 3D4F95D52C7B3EA3
3 changed files with 159 additions and 55 deletions

View File

@ -447,6 +447,24 @@ static NTSTATUS FspFileSystemSetMountPoint_Mountmgr(PWSTR MountPoint, PWSTR Volu
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
/* mountmgr.h */ /* 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 typedef struct
{ {
USHORT SymbolicLinkNameOffset; USHORT SymbolicLinkNameOffset;
@ -456,8 +474,11 @@ static NTSTATUS FspFileSystemSetMountPoint_Mountmgr(PWSTR MountPoint, PWSTR Volu
} MOUNTMGR_CREATE_POINT_INPUT; } MOUNTMGR_CREATE_POINT_INPUT;
GUID UniqueId; GUID UniqueId;
MOUNTMGR_CREATE_POINT_INPUT *Input = 0; MOUNTMGR_QUERY_AUTO_MOUNT QueryAutoMount;
ULONG VolumeNameSize, InputSize; MOUNTMGR_SET_AUTO_MOUNT SetAutoMount;
MOUNTMGR_TARGET_NAME *TargetName = 0;
MOUNTMGR_CREATE_POINT_INPUT *CreatePointInput = 0;
ULONG VolumeNameSize, QueryAutoMountSize, TargetNameSize, CreatePointInputSize;
HKEY RegKey; HKEY RegKey;
LONG RegResult; LONG RegResult;
WCHAR RegValueName[MAX_PATH]; WCHAR RegValueName[MAX_PATH];
@ -472,31 +493,83 @@ static NTSTATUS FspFileSystemSetMountPoint_Mountmgr(PWSTR MountPoint, PWSTR Volu
goto exit; goto exit;
VolumeNameSize = lstrlenW(VolumeName) * sizeof(WCHAR); 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); TargetName = MemAlloc(TargetNameSize);
if (0 == Input) if (0 == TargetName)
{ {
Result = STATUS_INSUFFICIENT_RESOURCES; Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit; goto exit;
} }
memset(Input, 0, sizeof *Input); CreatePointInput = MemAlloc(CreatePointInputSize);
Input->SymbolicLinkNameOffset = sizeof *Input; if (0 == CreatePointInput)
Input->SymbolicLinkNameLength = sizeof L"\\DosDevices\\X:" - sizeof(WCHAR); {
Input->DeviceNameOffset = Input->SymbolicLinkNameOffset + Input->SymbolicLinkNameLength; Result = STATUS_INSUFFICIENT_RESOURCES;
Input->DeviceNameLength = (USHORT)VolumeNameSize; goto exit;
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);
/* 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( Result = FspFileSystemMountmgrControl(
CTL_CODE('m', 0, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS), CTL_CODE('m', 0, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
/* IOCTL_MOUNTMGR_CREATE_POINT */ /* IOCTL_MOUNTMGR_CREATE_POINT */
Input, InputSize, 0, 0); CreatePointInput, CreatePointInputSize, 0, 0);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
@ -533,7 +606,8 @@ static NTSTATUS FspFileSystemSetMountPoint_Mountmgr(PWSTR MountPoint, PWSTR Volu
Result = STATUS_SUCCESS; Result = STATUS_SUCCESS;
exit: exit:
MemFree(Input); MemFree(CreatePointInput);
MemFree(TargetName);
return Result; return Result;
} }
@ -692,7 +766,6 @@ static VOID FspFileSystemRemoveMountPoint_Mountmgr(PWSTR MountPoint)
L"\\DosDevices\\X:", Input->SymbolicLinkNameLength); L"\\DosDevices\\X:", Input->SymbolicLinkNameLength);
((PWCHAR)((PUINT8)Input + Input->SymbolicLinkNameOffset))[12] = MountPoint[4] & ~0x20; ((PWCHAR)((PUINT8)Input + Input->SymbolicLinkNameOffset))[12] = MountPoint[4] & ~0x20;
/* convert to uppercase */ /* convert to uppercase */
Result = FspFileSystemMountmgrControl( Result = FspFileSystemMountmgrControl(
CTL_CODE('m', 1, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS), CTL_CODE('m', 1, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
/* IOCTL_MOUNTMGR_DELETE_POINTS */ /* IOCTL_MOUNTMGR_DELETE_POINTS */

View File

@ -578,14 +578,6 @@ NTSTATUS FspVolumeMakeMountdev(
ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength; ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength;
ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength; ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
BOOLEAN Persistent = 0 < InputBufferLength ? !!*(PBOOLEAN)Irp->AssociatedIrp.SystemBuffer : FALSE; 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; NTSTATUS Result;
if (0 == FsvrtDeviceObject) if (0 == FsvrtDeviceObject)
@ -596,34 +588,11 @@ NTSTATUS FspVolumeMakeMountdev(
FspDeviceGlobalLock(); FspDeviceGlobalLock();
Result = FspMountdevMake(FsvrtDeviceObject, FsvolDeviceObject, Persistent); 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)) if (!NT_SUCCESS(Result))
goto exit; {
if (STATUS_TOO_LATE != Result)
goto exit;
}
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
&FspFsvrtDeviceExtension(FsvrtDeviceObject)->UniqueId, sizeof(GUID)); &FspFsvrtDeviceExtension(FsvrtDeviceObject)->UniqueId, sizeof(GUID));

View File

@ -159,7 +159,67 @@ static void volpath_mount_dotest(ULONG Flags, PWSTR Prefix, PWSTR MountPoint)
FspFileSystemRemoveMountPoint(MemfsFileSystem(memfs)); 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[0]);
ASSERT(VolumePathNameSuccess[1]); ASSERT(VolumePathNameSuccess[1]);
@ -171,6 +231,8 @@ static void volpath_mount_dotest(ULONG Flags, PWSTR Prefix, PWSTR MountPoint)
ASSERT(VolumePathNameSuccess[5]); ASSERT(VolumePathNameSuccess[5]);
ASSERT(VolumePathNameSuccess[6]); ASSERT(VolumePathNameSuccess[6]);
} }
memfs_stop(memfs);
} }
static void volpath_mount_test(void) static void volpath_mount_test(void)