mirror of
https://github.com/winfsp/winfsp.git
synced 2025-07-03 09:22:57 -05:00
sys,dll: FspFileSystemSetMountPoint: mount manager support
This commit is contained in:
183
src/dll/fs.c
183
src/dll/fs.c
@ -93,7 +93,9 @@ FSP_API NTSTATUS FspFileSystemPreflight(PWSTR DevicePath,
|
||||
Result = STATUS_SUCCESS;
|
||||
else
|
||||
{
|
||||
if (FspPathIsDrive(MountPoint))
|
||||
if (FspPathIsMountmgrMountPoint(MountPoint))
|
||||
Result = STATUS_SUCCESS; /* cannot check with the mount manager, assume success */
|
||||
else if (FspPathIsDrive(MountPoint))
|
||||
Result = QueryDosDeviceW(MountPoint, TargetPath, MAX_PATH) ?
|
||||
STATUS_OBJECT_NAME_COLLISION : STATUS_SUCCESS;
|
||||
else
|
||||
@ -220,6 +222,48 @@ static NTSTATUS FspFileSystemLauncherDefineDosDevice(
|
||||
return !NT_SUCCESS(Result) ? Result : FspNtStatusFromWin32(ErrorCode);
|
||||
}
|
||||
|
||||
static NTSTATUS FspFileSystemMountmgrControl(ULONG IoControlCode,
|
||||
PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, PULONG POutputBufferLength)
|
||||
{
|
||||
HANDLE MgrHandle = INVALID_HANDLE_VALUE;
|
||||
DWORD Bytes = 0;
|
||||
NTSTATUS Result;
|
||||
|
||||
if (0 == POutputBufferLength)
|
||||
POutputBufferLength = &Bytes;
|
||||
|
||||
MgrHandle = CreateFileW(L"\\\\.\\MountPointManager",
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
0,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
0);
|
||||
if (INVALID_HANDLE_VALUE == MgrHandle)
|
||||
{
|
||||
Result = FspNtStatusFromWin32(GetLastError());
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!DeviceIoControl(MgrHandle,
|
||||
IoControlCode,
|
||||
InputBuffer, InputBufferLength, OutputBuffer, *POutputBufferLength,
|
||||
&Bytes, 0))
|
||||
{
|
||||
Result = FspNtStatusFromWin32(GetLastError());
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*POutputBufferLength = Bytes;
|
||||
Result = STATUS_SUCCESS;
|
||||
|
||||
exit:
|
||||
if (INVALID_HANDLE_VALUE != MgrHandle)
|
||||
CloseHandle(MgrHandle);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
static NTSTATUS FspFileSystemSetMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName,
|
||||
PHANDLE PMountHandle)
|
||||
{
|
||||
@ -395,6 +439,68 @@ exit:
|
||||
return Result;
|
||||
}
|
||||
|
||||
static NTSTATUS FspFileSystemSetMountPoint_Mountmgr(PWSTR MountPoint, PWSTR VolumeName,
|
||||
HANDLE VolumeHandle)
|
||||
{
|
||||
/* only support drives for now! (format: \\.\X:) */
|
||||
if (L'\0' != MountPoint[6])
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
/* mountmgr.h */
|
||||
typedef struct
|
||||
{
|
||||
USHORT SymbolicLinkNameOffset;
|
||||
USHORT SymbolicLinkNameLength;
|
||||
USHORT DeviceNameOffset;
|
||||
USHORT DeviceNameLength;
|
||||
} MOUNTMGR_CREATE_POINT_INPUT;
|
||||
|
||||
MOUNTMGR_CREATE_POINT_INPUT *Input = 0;
|
||||
ULONG VolumeNameSize, InputSize;
|
||||
NTSTATUS Result;
|
||||
|
||||
/* transform our volume into one that can be used by the MountManager */
|
||||
Result = FspFsctlMakeMountdev(VolumeHandle, FALSE);
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
|
||||
VolumeNameSize = lstrlenW(VolumeName) * sizeof(WCHAR);
|
||||
InputSize = sizeof *Input + sizeof L"\\DosDevices\\X:" - sizeof(WCHAR) + VolumeNameSize;
|
||||
|
||||
Input = MemAlloc(InputSize);
|
||||
if (0 == Input)
|
||||
{
|
||||
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);
|
||||
|
||||
Result = FspFileSystemMountmgrControl(
|
||||
CTL_CODE('m', 0, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
||||
/* IOCTL_MOUNTMGR_CREATE_POINT */
|
||||
Input, InputSize, 0, 0);
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
|
||||
Result = STATUS_SUCCESS;
|
||||
|
||||
exit:
|
||||
MemFree(Input);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR MountPoint)
|
||||
{
|
||||
return FspFileSystemSetMountPointEx(FileSystem, MountPoint, 0);
|
||||
@ -450,7 +556,10 @@ FSP_API NTSTATUS FspFileSystemSetMountPointEx(FSP_FILE_SYSTEM *FileSystem, PWSTR
|
||||
memcpy(P, MountPoint, L);
|
||||
MountPoint = P;
|
||||
|
||||
if (FspPathIsDrive(MountPoint))
|
||||
if (FspPathIsMountmgrMountPoint(MountPoint))
|
||||
Result = FspFileSystemSetMountPoint_Mountmgr(MountPoint, FileSystem->VolumeName,
|
||||
FileSystem->VolumeHandle);
|
||||
else if (FspPathIsDrive(MountPoint))
|
||||
Result = FspFileSystemSetMountPoint_Drive(MountPoint, FileSystem->VolumeName,
|
||||
&MountHandle);
|
||||
else
|
||||
@ -495,12 +604,80 @@ static VOID FspFileSystemRemoveMountPoint_Directory(HANDLE MountHandle)
|
||||
CloseHandle(MountHandle);
|
||||
}
|
||||
|
||||
static VOID FspFileSystemRemoveMountPoint_Mountmgr(PWSTR MountPoint)
|
||||
{
|
||||
/* mountmgr.h */
|
||||
typedef struct
|
||||
{
|
||||
ULONG SymbolicLinkNameOffset;
|
||||
USHORT SymbolicLinkNameLength;
|
||||
USHORT Reserved1;
|
||||
ULONG UniqueIdOffset;
|
||||
USHORT UniqueIdLength;
|
||||
USHORT Reserved2;
|
||||
ULONG DeviceNameOffset;
|
||||
USHORT DeviceNameLength;
|
||||
USHORT Reserved3;
|
||||
} MOUNTMGR_MOUNT_POINT;
|
||||
typedef struct
|
||||
{
|
||||
ULONG Size;
|
||||
ULONG NumberOfMountPoints;
|
||||
MOUNTMGR_MOUNT_POINT MountPoints[1];
|
||||
} MOUNTMGR_MOUNT_POINTS;
|
||||
|
||||
MOUNTMGR_MOUNT_POINT *Input = 0;
|
||||
MOUNTMGR_MOUNT_POINTS *Output = 0;
|
||||
ULONG InputSize, OutputSize;
|
||||
NTSTATUS Result;
|
||||
|
||||
InputSize = sizeof *Input + sizeof L"\\DosDevices\\X:" - sizeof(WCHAR);
|
||||
OutputSize = 4096;
|
||||
|
||||
Input = MemAlloc(InputSize);
|
||||
if (0 == Input)
|
||||
{
|
||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
Output = MemAlloc(OutputSize);
|
||||
if (0 == Output)
|
||||
{
|
||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memset(Input, 0, sizeof *Input);
|
||||
Input->SymbolicLinkNameOffset = sizeof *Input;
|
||||
Input->SymbolicLinkNameLength = sizeof L"\\DosDevices\\X:" - sizeof(WCHAR);
|
||||
memcpy((PUINT8)Input + Input->SymbolicLinkNameOffset,
|
||||
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 */
|
||||
Input, InputSize, Output, &OutputSize);
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
|
||||
Result = STATUS_SUCCESS;
|
||||
|
||||
exit:
|
||||
MemFree(Output);
|
||||
MemFree(Input);
|
||||
}
|
||||
|
||||
FSP_API VOID FspFileSystemRemoveMountPoint(FSP_FILE_SYSTEM *FileSystem)
|
||||
{
|
||||
if (0 == FileSystem->MountPoint)
|
||||
return;
|
||||
|
||||
if (FspPathIsDrive(FileSystem->MountPoint))
|
||||
if (FspPathIsMountmgrMountPoint(FileSystem->MountPoint))
|
||||
FspFileSystemRemoveMountPoint_Mountmgr(FileSystem->MountPoint);
|
||||
else if (FspPathIsDrive(FileSystem->MountPoint))
|
||||
FspFileSystemRemoveMountPoint_Drive(FileSystem->MountPoint, FileSystem->VolumeName,
|
||||
FileSystem->MountHandle);
|
||||
else
|
||||
|
Reference in New Issue
Block a user