mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -05:00
dll: FspFileSystemSetMountPointEx and related refactoring
This commit is contained in:
parent
186f7cd9ee
commit
12704a3a4a
@ -893,6 +893,8 @@ FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem);
|
|||||||
* STATUS_SUCCESS or error code.
|
* STATUS_SUCCESS or error code.
|
||||||
*/
|
*/
|
||||||
FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR MountPoint);
|
FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR MountPoint);
|
||||||
|
FSP_API NTSTATUS FspFileSystemSetMountPointEx(FSP_FILE_SYSTEM *FileSystem, PWSTR MountPoint,
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor);
|
||||||
/**
|
/**
|
||||||
* Remove the mount point for a file system.
|
* Remove the mount point for a file system.
|
||||||
*
|
*
|
||||||
|
216
src/dll/fs.c
216
src/dll/fs.c
@ -187,20 +187,63 @@ FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem)
|
|||||||
MemFree(FileSystem);
|
MemFree(FileSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFileSystemSetMountPoint_CreateDirectory(PWSTR MountPoint, PWSTR VolumeName)
|
static NTSTATUS FspFileSystemSetMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName,
|
||||||
|
PHANDLE PMountHandle)
|
||||||
|
{
|
||||||
|
*PMountHandle = 0;
|
||||||
|
|
||||||
|
if (!DefineDosDeviceW(DDD_RAW_TARGET_PATH, MountPoint, VolumeName))
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
if (0 != FspNtOpenSymbolicLinkObject)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
HANDLE DirHandle;
|
WCHAR SymlinkBuf[6];
|
||||||
BOOL Success;
|
UNICODE_STRING Symlink;
|
||||||
|
OBJECT_ATTRIBUTES Obja;
|
||||||
|
|
||||||
|
memcpy(SymlinkBuf, L"\\??\\X:", sizeof SymlinkBuf);
|
||||||
|
SymlinkBuf[4] = MountPoint[0];
|
||||||
|
Symlink.Length = Symlink.MaximumLength = sizeof SymlinkBuf;
|
||||||
|
Symlink.Buffer = SymlinkBuf;
|
||||||
|
|
||||||
|
memset(&Obja, 0, sizeof Obja);
|
||||||
|
Obja.Length = sizeof Obja;
|
||||||
|
Obja.ObjectName = &Symlink;
|
||||||
|
Obja.Attributes = OBJ_CASE_INSENSITIVE;
|
||||||
|
|
||||||
|
Result = FspNtOpenSymbolicLinkObject(PMountHandle, DELETE, &Obja);
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
Result = FspNtMakeTemporaryObject(*PMountHandle);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
FspNtClose(*PMountHandle);
|
||||||
|
*PMountHandle = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspFileSystemSetMountPoint_Directory(PWSTR MountPoint, PWSTR VolumeName,
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor, PHANDLE PMountHandle)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
SECURITY_ATTRIBUTES SecurityAttributes;
|
||||||
|
HANDLE MountHandle = INVALID_HANDLE_VALUE;
|
||||||
DWORD Backslashes, Bytes;
|
DWORD Backslashes, Bytes;
|
||||||
USHORT VolumeNameLength, BackslashLength, ReparseDataLength;
|
USHORT VolumeNameLength, BackslashLength, ReparseDataLength;
|
||||||
PREPARSE_DATA_BUFFER ReparseData = 0;
|
PREPARSE_DATA_BUFFER ReparseData = 0;
|
||||||
PWSTR P, PathBuffer;
|
PWSTR P, PathBuffer;
|
||||||
|
|
||||||
|
*PMountHandle = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Windows does not allow mount points (junctions) to point to network file systems.
|
* Windows does not allow mount points (junctions) to point to network file systems.
|
||||||
*
|
*
|
||||||
* Count how many backslashes our VolumeName. If it is 3 or more this is a network
|
* Count how many backslashes our VolumeName has. If it is 3 or more this is a network
|
||||||
* file system. Preemptively return STATUS_NETWORK_ACCESS_DENIED.
|
* file system. Preemptively return STATUS_NETWORK_ACCESS_DENIED.
|
||||||
*/
|
*/
|
||||||
for (P = VolumeName, Backslashes = 0; *P; P++)
|
for (P = VolumeName, Backslashes = 0; *P; P++)
|
||||||
@ -211,25 +254,24 @@ static NTSTATUS FspFileSystemSetMountPoint_CreateDirectory(PWSTR MountPoint, PWS
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CreateDirectoryW(MountPoint, 0))
|
memset(&SecurityAttributes, 0, sizeof SecurityAttributes);
|
||||||
|
SecurityAttributes.nLength = sizeof SecurityAttributes;
|
||||||
|
SecurityAttributes.lpSecurityDescriptor = SecurityDescriptor;
|
||||||
|
|
||||||
|
MountHandle = CreateFileW(MountPoint,
|
||||||
|
FILE_WRITE_ATTRIBUTES,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
|
&SecurityAttributes,
|
||||||
|
CREATE_NEW,
|
||||||
|
FILE_ATTRIBUTE_DIRECTORY |
|
||||||
|
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_POSIX_SEMANTICS | FILE_FLAG_DELETE_ON_CLOSE,
|
||||||
|
0);
|
||||||
|
if (INVALID_HANDLE_VALUE == MountHandle)
|
||||||
{
|
{
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
DirHandle = CreateFileW(MountPoint,
|
|
||||||
FILE_WRITE_ATTRIBUTES,
|
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
|
||||||
0,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
|
|
||||||
0);
|
|
||||||
if (INVALID_HANDLE_VALUE == DirHandle)
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto rmdir_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
VolumeNameLength = (USHORT)lstrlenW(VolumeName);
|
VolumeNameLength = (USHORT)lstrlenW(VolumeName);
|
||||||
BackslashLength = 0 == VolumeNameLength || L'\\' != VolumeName[VolumeNameLength - 1];
|
BackslashLength = 0 == VolumeNameLength || L'\\' != VolumeName[VolumeNameLength - 1];
|
||||||
VolumeNameLength *= sizeof(WCHAR);
|
VolumeNameLength *= sizeof(WCHAR);
|
||||||
@ -243,7 +285,7 @@ static NTSTATUS FspFileSystemSetMountPoint_CreateDirectory(PWSTR MountPoint, PWS
|
|||||||
if (0 == ReparseData)
|
if (0 == ReparseData)
|
||||||
{
|
{
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto rmdir_and_exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReparseData->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
|
ReparseData->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
|
||||||
@ -270,86 +312,35 @@ static NTSTATUS FspFileSystemSetMountPoint_CreateDirectory(PWSTR MountPoint, PWS
|
|||||||
PathBuffer[VolumeNameLength / sizeof(WCHAR)] = L'\\';
|
PathBuffer[VolumeNameLength / sizeof(WCHAR)] = L'\\';
|
||||||
PathBuffer[(VolumeNameLength + BackslashLength) / sizeof(WCHAR)] = L'\0';
|
PathBuffer[(VolumeNameLength + BackslashLength) / sizeof(WCHAR)] = L'\0';
|
||||||
|
|
||||||
Success = DeviceIoControl(DirHandle, FSCTL_SET_REPARSE_POINT,
|
if (!DeviceIoControl(MountHandle, FSCTL_SET_REPARSE_POINT,
|
||||||
ReparseData, REPARSE_DATA_BUFFER_HEADER_SIZE + ReparseData->ReparseDataLength,
|
ReparseData, REPARSE_DATA_BUFFER_HEADER_SIZE + ReparseData->ReparseDataLength,
|
||||||
0, 0,
|
0, 0,
|
||||||
&Bytes, 0);
|
&Bytes, 0))
|
||||||
CloseHandle(DirHandle);
|
|
||||||
if (!Success)
|
|
||||||
{
|
{
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
goto rmdir_and_exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*PMountHandle = MountHandle;
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
if (!NT_SUCCESS(Result) && INVALID_HANDLE_VALUE != MountHandle)
|
||||||
|
CloseHandle(MountHandle);
|
||||||
|
|
||||||
MemFree(ReparseData);
|
MemFree(ReparseData);
|
||||||
return Result;
|
|
||||||
|
|
||||||
rmdir_and_exit:
|
|
||||||
RemoveDirectoryW(MountPoint);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS FspFileSystemSetMountPoint_MakeTemporary(PWSTR MountPoint, PHANDLE PMountHandle)
|
|
||||||
{
|
|
||||||
NTSTATUS Result = STATUS_SUCCESS;
|
|
||||||
HANDLE MountHandle = 0;
|
|
||||||
|
|
||||||
if (FspPathIsDrive(MountPoint))
|
|
||||||
{
|
|
||||||
if (0 != FspNtOpenSymbolicLinkObject)
|
|
||||||
{
|
|
||||||
WCHAR SymlinkBuf[6];
|
|
||||||
UNICODE_STRING Symlink;
|
|
||||||
OBJECT_ATTRIBUTES Obja;
|
|
||||||
|
|
||||||
memcpy(SymlinkBuf, L"\\??\\X:", sizeof SymlinkBuf);
|
|
||||||
SymlinkBuf[4] = MountPoint[0];
|
|
||||||
Symlink.Length = Symlink.MaximumLength = sizeof SymlinkBuf;
|
|
||||||
Symlink.Buffer = SymlinkBuf;
|
|
||||||
|
|
||||||
memset(&Obja, 0, sizeof Obja);
|
|
||||||
Obja.Length = sizeof Obja;
|
|
||||||
Obja.ObjectName = &Symlink;
|
|
||||||
Obja.Attributes = OBJ_CASE_INSENSITIVE;
|
|
||||||
|
|
||||||
Result = FspNtOpenSymbolicLinkObject(&MountHandle, DELETE, &Obja);
|
|
||||||
if (NT_SUCCESS(Result))
|
|
||||||
{
|
|
||||||
Result = FspNtMakeTemporaryObject(MountHandle);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
{
|
|
||||||
FspNtClose(MountHandle);
|
|
||||||
MountHandle = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* open the directory for DELETE_ON_CLOSE; closing it will remove the directory */
|
|
||||||
MountHandle = CreateFileW(MountPoint,
|
|
||||||
FILE_READ_ATTRIBUTES,
|
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
|
||||||
0,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_DELETE_ON_CLOSE,
|
|
||||||
0);
|
|
||||||
if (INVALID_HANDLE_VALUE == MountHandle)
|
|
||||||
{
|
|
||||||
MountHandle = 0;
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*PMountHandle = MountHandle;
|
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR MountPoint)
|
FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR MountPoint)
|
||||||
|
{
|
||||||
|
return FspFileSystemSetMountPointEx(FileSystem, MountPoint, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspFileSystemSetMountPointEx(FSP_FILE_SYSTEM *FileSystem, PWSTR MountPoint,
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor)
|
||||||
{
|
{
|
||||||
if (0 != FileSystem->MountPoint)
|
if (0 != FileSystem->MountPoint)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
@ -375,12 +366,11 @@ FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR M
|
|||||||
if (0 == (Drives & (1 << (Drive - 'A'))))
|
if (0 == (Drives & (1 << (Drive - 'A'))))
|
||||||
{
|
{
|
||||||
MountPoint[0] = Drive;
|
MountPoint[0] = Drive;
|
||||||
if (DefineDosDeviceW(DDD_RAW_TARGET_PATH, MountPoint, FileSystem->VolumeName))
|
Result = FspFileSystemSetMountPoint_Drive(MountPoint, FileSystem->VolumeName,
|
||||||
{
|
&MountHandle);
|
||||||
Result = STATUS_SUCCESS;
|
if (NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Result = STATUS_NO_SUCH_DEVICE;
|
Result = STATUS_NO_SUCH_DEVICE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -400,22 +390,16 @@ FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR M
|
|||||||
MountPoint = P;
|
MountPoint = P;
|
||||||
|
|
||||||
if (FspPathIsDrive(MountPoint))
|
if (FspPathIsDrive(MountPoint))
|
||||||
{
|
Result = FspFileSystemSetMountPoint_Drive(MountPoint, FileSystem->VolumeName,
|
||||||
if (DefineDosDeviceW(DDD_RAW_TARGET_PATH, MountPoint, FileSystem->VolumeName))
|
&MountHandle);
|
||||||
Result = STATUS_SUCCESS;
|
|
||||||
else
|
else
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
Result = FspFileSystemSetMountPoint_Directory(MountPoint, FileSystem->VolumeName,
|
||||||
}
|
SecurityDescriptor, &MountHandle);
|
||||||
else
|
|
||||||
Result = FspFileSystemSetMountPoint_CreateDirectory(MountPoint, FileSystem->VolumeName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (NT_SUCCESS(Result))
|
if (NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
FspFileSystemSetMountPoint_MakeTemporary(MountPoint, &MountHandle);
|
|
||||||
/* ignore result; this path always considered successful */
|
|
||||||
|
|
||||||
FileSystem->MountPoint = MountPoint;
|
FileSystem->MountPoint = MountPoint;
|
||||||
FileSystem->MountHandle = MountHandle;
|
FileSystem->MountHandle = MountHandle;
|
||||||
}
|
}
|
||||||
@ -425,34 +409,36 @@ exit:
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VOID FspFileSystemRemoveMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName, HANDLE MountHandle)
|
||||||
|
{
|
||||||
|
DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
|
||||||
|
MountPoint, VolumeName);
|
||||||
|
|
||||||
|
if (0 != MountHandle)
|
||||||
|
FspNtClose(MountHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID FspFileSystemRemoveMountPoint_Directory(HANDLE MountHandle)
|
||||||
|
{
|
||||||
|
/* directory is marked DELETE_ON_CLOSE */
|
||||||
|
CloseHandle(MountHandle);
|
||||||
|
}
|
||||||
|
|
||||||
FSP_API VOID FspFileSystemRemoveMountPoint(FSP_FILE_SYSTEM *FileSystem)
|
FSP_API VOID FspFileSystemRemoveMountPoint(FSP_FILE_SYSTEM *FileSystem)
|
||||||
{
|
{
|
||||||
BOOLEAN IsDrive;
|
|
||||||
|
|
||||||
if (0 == FileSystem->MountPoint)
|
if (0 == FileSystem->MountPoint)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IsDrive = FspPathIsDrive(FileSystem->MountPoint);
|
if (FspPathIsDrive(FileSystem->MountPoint))
|
||||||
if (IsDrive)
|
FspFileSystemRemoveMountPoint_Drive(FileSystem->MountPoint, FileSystem->VolumeName,
|
||||||
DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
|
FileSystem->MountHandle);
|
||||||
FileSystem->MountPoint, FileSystem->VolumeName);
|
|
||||||
else
|
else
|
||||||
/* nothing to do! directory will be deleted when the MountHandle is closed */;
|
FspFileSystemRemoveMountPoint_Directory(FileSystem->MountHandle);
|
||||||
|
|
||||||
MemFree(FileSystem->MountPoint);
|
MemFree(FileSystem->MountPoint);
|
||||||
FileSystem->MountPoint = 0;
|
FileSystem->MountPoint = 0;
|
||||||
|
|
||||||
if (0 != FileSystem->MountHandle)
|
|
||||||
{
|
|
||||||
if (IsDrive)
|
|
||||||
FspNtClose(FileSystem->MountHandle);
|
|
||||||
else
|
|
||||||
/* CloseHandle really calls NtClose, but I like being defensive when programming */
|
|
||||||
CloseHandle(FileSystem->MountHandle);
|
|
||||||
|
|
||||||
FileSystem->MountHandle = 0;
|
FileSystem->MountHandle = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static DWORD WINAPI FspFileSystemDispatcherThread(PVOID FileSystem0)
|
static DWORD WINAPI FspFileSystemDispatcherThread(PVOID FileSystem0)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user