mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -05:00
dll: FspFileSystemSetMountPoint, FspFileSystemRemoveMountPoint
Ensure that mapped drives get cleaned up even if file system dies
This commit is contained in:
parent
3db09be764
commit
b8b15e8035
@ -595,7 +595,7 @@ typedef struct _FSP_FILE_SYSTEM
|
|||||||
ULONG DispatcherThreadCount;
|
ULONG DispatcherThreadCount;
|
||||||
NTSTATUS DispatcherResult;
|
NTSTATUS DispatcherResult;
|
||||||
PWSTR MountPoint;
|
PWSTR MountPoint;
|
||||||
LIST_ENTRY MountEntry;
|
HANDLE MountHandle;
|
||||||
UINT32 DebugLog;
|
UINT32 DebugLog;
|
||||||
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY OpGuardStrategy;
|
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY OpGuardStrategy;
|
||||||
SRWLOCK OpGuardLock;
|
SRWLOCK OpGuardLock;
|
||||||
|
114
src/dll/fs.c
114
src/dll/fs.c
@ -25,60 +25,34 @@ enum
|
|||||||
static FSP_FILE_SYSTEM_INTERFACE FspFileSystemNullInterface;
|
static FSP_FILE_SYSTEM_INTERFACE FspFileSystemNullInterface;
|
||||||
|
|
||||||
static INIT_ONCE FspFileSystemInitOnce = INIT_ONCE_STATIC_INIT;
|
static INIT_ONCE FspFileSystemInitOnce = INIT_ONCE_STATIC_INIT;
|
||||||
static BOOLEAN FspFileSystemInitialized;
|
static NTSTATUS (NTAPI *FspNtOpenSymbolicLinkObject)(
|
||||||
static CRITICAL_SECTION FspFileSystemMountListGuard;
|
PHANDLE LinkHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes);
|
||||||
static LIST_ENTRY FspFileSystemMountList = { &FspFileSystemMountList, &FspFileSystemMountList };
|
static NTSTATUS (NTAPI *FspNtMakeTemporaryObject)(
|
||||||
|
HANDLE Handle);
|
||||||
|
static NTSTATUS (NTAPI *FspNtClose)(
|
||||||
|
HANDLE Handle);
|
||||||
|
|
||||||
static BOOL WINAPI FspFileSystemInitialize(
|
static BOOL WINAPI FspFileSystemInitialize(
|
||||||
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
|
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
|
||||||
{
|
{
|
||||||
InitializeCriticalSection(&FspFileSystemMountListGuard);
|
HANDLE Handle;
|
||||||
return FspFileSystemInitialized = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID FspFileSystemFinalize(BOOLEAN Dynamic)
|
Handle = GetModuleHandleW(L"ntdll.dll");
|
||||||
{
|
if (0 != Handle)
|
||||||
/*
|
|
||||||
* This function is called during DLL_PROCESS_DETACH. We must therefore keep
|
|
||||||
* finalization tasks to a minimum.
|
|
||||||
*
|
|
||||||
* We enter our FspFileSystemMountListGuard critical section here and then attempt to cleanup
|
|
||||||
* our mount points using DefineDosDeviceW. On Vista and later orphaned critical sections
|
|
||||||
* become "electrified", so our process will be forcefully terminated if one of its threads
|
|
||||||
* was already modifying the list when the ExitProcess happened. This is a good thing!
|
|
||||||
*
|
|
||||||
* The use of DefineDosDeviceW is rather suspect and probably unsafe. DefineDosDeviceW reaches
|
|
||||||
* out to CSRSS, which is probably not the safest thing to do when in DllMain! There is also
|
|
||||||
* some evidence that it may attempt to load DLL's under some circumstances, which is a
|
|
||||||
* definite no-no as we are under the loader lock!
|
|
||||||
*
|
|
||||||
* We only delete the criticaly section when being dynamically unloaded. On process exit the
|
|
||||||
* OS will clean it up for us.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!FspFileSystemInitialized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
FSP_FILE_SYSTEM *FileSystem;
|
|
||||||
PLIST_ENTRY MountEntry;
|
|
||||||
|
|
||||||
EnterCriticalSection(&FspFileSystemMountListGuard);
|
|
||||||
|
|
||||||
for (MountEntry = FspFileSystemMountList.Flink;
|
|
||||||
&FspFileSystemMountList != MountEntry;
|
|
||||||
MountEntry = MountEntry->Flink)
|
|
||||||
{
|
{
|
||||||
FileSystem = CONTAINING_RECORD(MountEntry, FSP_FILE_SYSTEM, MountEntry);
|
FspNtOpenSymbolicLinkObject = (PVOID)GetProcAddress(Handle, "NtOpenSymbolicLinkObject");
|
||||||
|
FspNtMakeTemporaryObject = (PVOID)GetProcAddress(Handle, "NtMakeTemporaryObject");
|
||||||
|
FspNtClose = (PVOID)GetProcAddress(Handle, "NtClose");
|
||||||
|
|
||||||
DefineDosDeviceW(
|
if (0 == FspNtOpenSymbolicLinkObject || 0 == FspNtMakeTemporaryObject || 0 == FspNtClose)
|
||||||
DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
|
{
|
||||||
FileSystem->MountPoint, FileSystem->VolumeName);
|
FspNtOpenSymbolicLinkObject = 0;
|
||||||
|
FspNtMakeTemporaryObject = 0;
|
||||||
|
FspNtClose = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LeaveCriticalSection(&FspFileSystemMountListGuard);
|
return TRUE;
|
||||||
|
|
||||||
if (Dynamic)
|
|
||||||
DeleteCriticalSection(&FspFileSystemMountListGuard);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
|
FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
|
||||||
@ -95,8 +69,6 @@ FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
|
|||||||
Interface = &FspFileSystemNullInterface;
|
Interface = &FspFileSystemNullInterface;
|
||||||
|
|
||||||
InitOnceExecuteOnce(&FspFileSystemInitOnce, FspFileSystemInitialize, 0, 0);
|
InitOnceExecuteOnce(&FspFileSystemInitOnce, FspFileSystemInitialize, 0, 0);
|
||||||
if (!FspFileSystemInitialized)
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
|
|
||||||
FileSystem = MemAlloc(sizeof *FileSystem);
|
FileSystem = MemAlloc(sizeof *FileSystem);
|
||||||
if (0 == FileSystem)
|
if (0 == FileSystem)
|
||||||
@ -151,6 +123,7 @@ FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR M
|
|||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
HANDLE MountHandle = 0;
|
||||||
|
|
||||||
if (0 == MountPoint)
|
if (0 == MountPoint)
|
||||||
{
|
{
|
||||||
@ -203,13 +176,41 @@ FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR M
|
|||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
if (NT_SUCCESS(Result) && 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this path always considered successful regardless if we made symlink temporary */
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (NT_SUCCESS(Result))
|
if (NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
FileSystem->MountPoint = MountPoint;
|
FileSystem->MountPoint = MountPoint;
|
||||||
|
FileSystem->MountHandle = MountHandle;
|
||||||
EnterCriticalSection(&FspFileSystemMountListGuard);
|
|
||||||
InsertTailList(&FspFileSystemMountList, &FileSystem->MountEntry);
|
|
||||||
LeaveCriticalSection(&FspFileSystemMountListGuard);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
MemFree(MountPoint);
|
MemFree(MountPoint);
|
||||||
@ -222,15 +223,16 @@ FSP_API VOID FspFileSystemRemoveMountPoint(FSP_FILE_SYSTEM *FileSystem)
|
|||||||
if (0 == FileSystem->MountPoint)
|
if (0 == FileSystem->MountPoint)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EnterCriticalSection(&FspFileSystemMountListGuard);
|
|
||||||
RemoveEntryList(&FileSystem->MountEntry);
|
|
||||||
LeaveCriticalSection(&FspFileSystemMountListGuard);
|
|
||||||
|
|
||||||
DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
|
DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
|
||||||
FileSystem->MountPoint, FileSystem->VolumeName);
|
FileSystem->MountPoint, FileSystem->VolumeName);
|
||||||
|
|
||||||
MemFree(FileSystem->MountPoint);
|
MemFree(FileSystem->MountPoint);
|
||||||
FileSystem->MountPoint = 0;
|
FileSystem->MountPoint = 0;
|
||||||
|
|
||||||
|
if (0 != FileSystem->MountHandle)
|
||||||
|
{
|
||||||
|
FspNtClose(FileSystem->MountHandle);
|
||||||
|
FileSystem->MountHandle = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD WINAPI FspFileSystemDispatcherThread(PVOID FileSystem0)
|
static DWORD WINAPI FspFileSystemDispatcherThread(PVOID FileSystem0)
|
||||||
|
@ -42,7 +42,6 @@ BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved)
|
|||||||
Dynamic = 0 == Reserved;
|
Dynamic = 0 == Reserved;
|
||||||
fsp_fuse_finalize(Dynamic);
|
fsp_fuse_finalize(Dynamic);
|
||||||
FspServiceFinalize(Dynamic);
|
FspServiceFinalize(Dynamic);
|
||||||
FspFileSystemFinalize(Dynamic);
|
|
||||||
FspEventLogFinalize(Dynamic);
|
FspEventLogFinalize(Dynamic);
|
||||||
FspPosixFinalize(Dynamic);
|
FspPosixFinalize(Dynamic);
|
||||||
break;
|
break;
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
|
|
||||||
VOID FspPosixFinalize(BOOLEAN Dynamic);
|
VOID FspPosixFinalize(BOOLEAN Dynamic);
|
||||||
VOID FspEventLogFinalize(BOOLEAN Dynamic);
|
VOID FspEventLogFinalize(BOOLEAN Dynamic);
|
||||||
VOID FspFileSystemFinalize(BOOLEAN Dynamic);
|
|
||||||
VOID FspServiceFinalize(BOOLEAN Dynamic);
|
VOID FspServiceFinalize(BOOLEAN Dynamic);
|
||||||
VOID fsp_fuse_finalize(BOOLEAN Dynamic);
|
VOID fsp_fuse_finalize(BOOLEAN Dynamic);
|
||||||
VOID fsp_fuse_finalize_thread(VOID);
|
VOID fsp_fuse_finalize_thread(VOID);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user