mirror of
https://github.com/winfsp/winfsp.git
synced 2025-07-03 17:32:57 -05:00
dll: FspFileSystemStopServiceIfNecessary
This commit is contained in:
@ -1883,3 +1883,12 @@ FSP_API BOOLEAN FspFileSystemAddNotifyInfo(FSP_FSCTL_NOTIFY_INFO *NotifyInfo,
|
||||
{
|
||||
return FspFileSystemAddXxxInfo(NotifyInfo, Buffer, Length, PBytesTransferred);
|
||||
}
|
||||
|
||||
FSP_API VOID FspFileSystemStopServiceIfNecessary(FSP_FILE_SYSTEM *FileSystem,
|
||||
BOOLEAN Normally)
|
||||
{
|
||||
/* NOTE: .NET calls us with a zero FileSystem pointer! */
|
||||
if (Normally)
|
||||
return;
|
||||
FspServiceStopLoop();
|
||||
}
|
||||
|
@ -2635,6 +2635,17 @@ static NTSTATUS fsp_fuse_intf_SetEa(FSP_FILE_SYSTEM *FileSystem,
|
||||
&Uid, &Gid, &Mode, FileInfo);
|
||||
}
|
||||
|
||||
static VOID fsp_fuse_intf_DispatcherStopped(FSP_FILE_SYSTEM *FileSystem,
|
||||
BOOLEAN Normally)
|
||||
{
|
||||
if (Normally)
|
||||
return;
|
||||
|
||||
struct fuse *f = FileSystem->UserContext;
|
||||
|
||||
fsp_fuse_exit(f->env, f);
|
||||
}
|
||||
|
||||
FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf =
|
||||
{
|
||||
fsp_fuse_intf_GetVolumeInfo,
|
||||
@ -2668,6 +2679,8 @@ FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf =
|
||||
fsp_fuse_intf_Overwrite,
|
||||
fsp_fuse_intf_GetEa,
|
||||
fsp_fuse_intf_SetEa,
|
||||
0,
|
||||
fsp_fuse_intf_DispatcherStopped,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -110,6 +110,7 @@ NTSTATUS FspGetModuleFileName(
|
||||
VOID FspFileSystemPeekInDirectoryBuffer(PVOID *PDirBuffer,
|
||||
PUINT8 *PBuffer, PULONG *PIndex, PULONG PCount);
|
||||
|
||||
VOID FspServiceStopLoop(VOID);
|
||||
BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType);
|
||||
|
||||
static inline ULONG FspPathSuffixIndex(PWSTR FileName)
|
||||
|
@ -40,6 +40,8 @@ enum
|
||||
GetStatus_WaitHint = 0x4000,
|
||||
};
|
||||
|
||||
static SRWLOCK FspServiceLoopLock = SRWLOCK_INIT;
|
||||
static SRWLOCK FspServiceTableLock = SRWLOCK_INIT;
|
||||
static SERVICE_TABLE_ENTRYW *FspServiceTable;
|
||||
static HANDLE FspServiceConsoleModeEvent;
|
||||
static UINT32 FspServiceConsoleCtrlHandlerDisabled;
|
||||
@ -220,6 +222,14 @@ FSP_API ULONG FspServiceGetExitCode(FSP_SERVICE *Service)
|
||||
|
||||
FSP_API NTSTATUS FspServiceLoop(FSP_SERVICE *Service)
|
||||
{
|
||||
/*
|
||||
* FspServiceLoop can only be called once per process, because of StartServiceCtrlDispatcherW
|
||||
* (which returns ERROR_SERVICE_ALREADY_RUNNING if called more than once). Unfortunately this
|
||||
* limitation was never documented and there may be users of FspServiceLoop out there that call
|
||||
* it more than once per process.
|
||||
*/
|
||||
AcquireSRWLockExclusive(&FspServiceLoopLock);
|
||||
|
||||
NTSTATUS Result;
|
||||
SERVICE_TABLE_ENTRYW ServiceTable[2];
|
||||
|
||||
@ -236,7 +246,9 @@ FSP_API NTSTATUS FspServiceLoop(FSP_SERVICE *Service)
|
||||
ServiceTable[0].lpServiceProc = FspServiceEntry;
|
||||
ServiceTable[1].lpServiceName = 0;
|
||||
ServiceTable[1].lpServiceProc = 0;
|
||||
AcquireSRWLockExclusive(&FspServiceTableLock);
|
||||
FspServiceTable = ServiceTable;
|
||||
ReleaseSRWLockExclusive(&FspServiceTableLock);
|
||||
|
||||
if (!StartServiceCtrlDispatcherW(ServiceTable))
|
||||
{
|
||||
@ -331,11 +343,42 @@ FSP_API NTSTATUS FspServiceLoop(FSP_SERVICE *Service)
|
||||
Result = STATUS_SUCCESS;
|
||||
|
||||
exit:
|
||||
AcquireSRWLockExclusive(&FspServiceTableLock);
|
||||
FspServiceTable = 0;
|
||||
ReleaseSRWLockExclusive(&FspServiceTableLock);
|
||||
|
||||
ReleaseSRWLockExclusive(&FspServiceLoopLock);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
static DWORD WINAPI FspServiceStopLoopThread(PVOID Context);
|
||||
VOID FspServiceStopLoop(VOID)
|
||||
{
|
||||
BOOLEAN HasService;
|
||||
HANDLE Thread;
|
||||
|
||||
AcquireSRWLockShared(&FspServiceTableLock);
|
||||
HasService = 0 != FspServiceFromTable();
|
||||
ReleaseSRWLockShared(&FspServiceTableLock);
|
||||
|
||||
if (HasService)
|
||||
{
|
||||
Thread = CreateThread(0, 0, FspServiceStopLoopThread, 0, 0, 0);
|
||||
if (0 != Thread)
|
||||
CloseHandle(Thread);
|
||||
}
|
||||
}
|
||||
static DWORD WINAPI FspServiceStopLoopThread(PVOID Context)
|
||||
{
|
||||
AcquireSRWLockShared(&FspServiceTableLock);
|
||||
FSP_SERVICE *Service = FspServiceFromTable();
|
||||
if (0 != Service)
|
||||
FspServiceStop(Service);
|
||||
ReleaseSRWLockShared(&FspServiceTableLock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
FSP_API VOID FspServiceStop(FSP_SERVICE *Service)
|
||||
{
|
||||
SERVICE_STATUS ServiceStatus;
|
||||
@ -393,6 +436,7 @@ static VOID WINAPI FspServiceEntry(DWORD Argc, PWSTR *Argv)
|
||||
FSP_SERVICE *Service;
|
||||
|
||||
Service = FspServiceFromTable();
|
||||
/* we are subordinate to FspServiceLoop; no need to protect this access with FspServiceTableLock */
|
||||
if (0 == Service)
|
||||
{
|
||||
FspServiceLog(EVENTLOG_ERROR_TYPE,
|
||||
@ -501,6 +545,7 @@ static DWORD WINAPI FspServiceConsoleModeThread(PVOID Context)
|
||||
;
|
||||
|
||||
Service = FspServiceFromTable();
|
||||
/* we are subordinate to FspServiceLoop; no need to protect this access with FspServiceTableLock */
|
||||
if (0 == Service)
|
||||
FspServiceLog(EVENTLOG_ERROR_TYPE,
|
||||
L"" __FUNCTION__ ": internal error: FspServiceFromTable = 0");
|
||||
|
Reference in New Issue
Block a user