mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
dll: FspFileSystemInitialize, FspFileSystemFinalize
This commit is contained in:
parent
5b917c4566
commit
ef5b664dcc
@ -125,6 +125,7 @@ typedef struct _FSP_FILE_SYSTEM
|
||||
ULONG DispatcherThreadCount;
|
||||
NTSTATUS DispatcherResult;
|
||||
PWSTR MountPoint;
|
||||
LIST_ENTRY MountEntry;
|
||||
} FSP_FILE_SYSTEM;
|
||||
FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
|
||||
const FSP_FSCTL_VOLUME_PARAMS *VolumeParams,
|
||||
|
@ -13,6 +13,62 @@ enum
|
||||
|
||||
static FSP_FILE_SYSTEM_INTERFACE FspFileSystemNullInterface;
|
||||
|
||||
static CRITICAL_SECTION FspFileSystemMountListGuard;
|
||||
static LIST_ENTRY FspFileSystemMountList = { &FspFileSystemMountList, &FspFileSystemMountList };
|
||||
|
||||
VOID FspFileSystemInitialize(VOID)
|
||||
{
|
||||
/*
|
||||
* This function is called during DLL_PROCESS_ATTACH. We must therefore keep initialization
|
||||
* tasks to a minimum.
|
||||
*
|
||||
* Initialization of synchronization objects is allowed! See:
|
||||
* https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx
|
||||
*/
|
||||
|
||||
InitializeCriticalSection(&FspFileSystemMountListGuard);
|
||||
}
|
||||
|
||||
VOID FspFileSystemFinalize(VOID)
|
||||
{
|
||||
/*
|
||||
* This function is called during DLL_PROCESS_DETACH. We must therefore keep finalization
|
||||
* tasks to a minimum.
|
||||
*
|
||||
* Very few things can be safely done during DLL_PROCESS_DETACH. See:
|
||||
* https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx
|
||||
* https://blogs.msdn.microsoft.com/oldnewthing/20070503-00/?p=27003/
|
||||
* https://blogs.msdn.microsoft.com/oldnewthing/20100122-00/?p=15193/
|
||||
*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
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);
|
||||
|
||||
DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
|
||||
FileSystem->MountPoint, FileSystem->VolumeName);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&FspFileSystemMountListGuard);
|
||||
}
|
||||
|
||||
FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
|
||||
const FSP_FSCTL_VOLUME_PARAMS *VolumeParams,
|
||||
const FSP_FILE_SYSTEM_INTERFACE *Interface,
|
||||
@ -74,6 +130,8 @@ FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR M
|
||||
if (0 != FileSystem->MountPoint)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
NTSTATUS Result;
|
||||
|
||||
if (0 == MountPoint)
|
||||
{
|
||||
DWORD Drives;
|
||||
@ -94,17 +152,14 @@ FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR M
|
||||
MountPoint[0] = Drive;
|
||||
if (DefineDosDeviceW(DDD_RAW_TARGET_PATH, MountPoint, FileSystem->VolumeName))
|
||||
{
|
||||
FileSystem->MountPoint = MountPoint;
|
||||
return STATUS_SUCCESS;
|
||||
Result = STATUS_SUCCESS;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
Result = STATUS_NO_SUCH_DEVICE;
|
||||
}
|
||||
|
||||
MemFree(MountPoint);
|
||||
|
||||
return FspNtStatusFromWin32(GetLastError());
|
||||
else
|
||||
Result = FspNtStatusFromWin32(GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -122,15 +177,24 @@ FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR M
|
||||
MountPoint = P;
|
||||
|
||||
if (DefineDosDeviceW(DDD_RAW_TARGET_PATH, MountPoint, FileSystem->VolumeName))
|
||||
Result = STATUS_SUCCESS;
|
||||
else
|
||||
Result = FspNtStatusFromWin32(GetLastError());
|
||||
}
|
||||
|
||||
exit:
|
||||
if (NT_SUCCESS(Result))
|
||||
{
|
||||
FileSystem->MountPoint = MountPoint;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&FspFileSystemMountListGuard);
|
||||
InsertTailList(&FspFileSystemMountList, &FileSystem->MountEntry);
|
||||
LeaveCriticalSection(&FspFileSystemMountListGuard);
|
||||
}
|
||||
else
|
||||
MemFree(MountPoint);
|
||||
|
||||
return FspNtStatusFromWin32(GetLastError());
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
FSP_API VOID FspFileSystemRemoveMountPoint(FSP_FILE_SYSTEM *FileSystem)
|
||||
@ -138,6 +202,10 @@ FSP_API VOID FspFileSystemRemoveMountPoint(FSP_FILE_SYSTEM *FileSystem)
|
||||
if (0 == FileSystem->MountPoint)
|
||||
return;
|
||||
|
||||
EnterCriticalSection(&FspFileSystemMountListGuard);
|
||||
RemoveEntryList(&FileSystem->MountEntry);
|
||||
LeaveCriticalSection(&FspFileSystemMountListGuard);
|
||||
|
||||
DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
|
||||
FileSystem->MountPoint, FileSystem->VolumeName);
|
||||
|
||||
|
@ -16,6 +16,10 @@ BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved)
|
||||
ProcessHeap = GetProcessHeap();
|
||||
if (0 == ProcessHeap)
|
||||
return FALSE;
|
||||
FspFileSystemInitialize();
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
FspFileSystemFinalize();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -68,4 +68,31 @@ void *memset(void *dst, int val, size_t siz)
|
||||
}
|
||||
#endif
|
||||
|
||||
static FORCEINLINE
|
||||
VOID InsertTailList(PLIST_ENTRY ListHead, PLIST_ENTRY Entry)
|
||||
{
|
||||
PLIST_ENTRY Blink;
|
||||
|
||||
Blink = ListHead->Blink;
|
||||
Entry->Flink = ListHead;
|
||||
Entry->Blink = Blink;
|
||||
Blink->Flink = Entry;
|
||||
ListHead->Blink = Entry;
|
||||
}
|
||||
static FORCEINLINE
|
||||
BOOLEAN RemoveEntryList(PLIST_ENTRY Entry)
|
||||
{
|
||||
PLIST_ENTRY Blink;
|
||||
PLIST_ENTRY Flink;
|
||||
|
||||
Flink = Entry->Flink;
|
||||
Blink = Entry->Blink;
|
||||
Blink->Flink = Flink;
|
||||
Flink->Blink = Blink;
|
||||
return Flink == Blink;
|
||||
}
|
||||
|
||||
VOID FspFileSystemInitialize(VOID);
|
||||
VOID FspFileSystemFinalize(VOID);
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user