From e82b06ae499c70787fb71a4079b46c79d188623b Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Wed, 11 May 2016 11:29:36 -0700 Subject: [PATCH] dll: FspServiceStop: early exit if service is already being stopped --- inc/winfsp/winfsp.h | 3 ++- src/dll/service.c | 13 ++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index 78696a67..65934799 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -857,8 +857,9 @@ typedef struct _FSP_SERVICE ULONG AcceptControl; ULONG ExitCode; SERVICE_STATUS_HANDLE StatusHandle; - CRITICAL_SECTION ServiceStatusGuard; SERVICE_STATUS ServiceStatus; + CRITICAL_SECTION ServiceStatusGuard; + CRITICAL_SECTION ServiceStopGuard; BOOLEAN AllowConsoleMode; WCHAR ServiceName[]; } FSP_SERVICE; diff --git a/src/dll/service.c b/src/dll/service.c index 63272c95..ccafb0aa 100644 --- a/src/dll/service.c +++ b/src/dll/service.c @@ -126,6 +126,7 @@ FSP_API NTSTATUS FspServiceCreate(PWSTR ServiceName, Service->AcceptControl = OnStop ? SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN : 0; InitializeCriticalSection(&Service->ServiceStatusGuard); + InitializeCriticalSection(&Service->ServiceStopGuard); *PService = Service; @@ -134,6 +135,7 @@ FSP_API NTSTATUS FspServiceCreate(PWSTR ServiceName, FSP_API VOID FspServiceDelete(FSP_SERVICE *Service) { + DeleteCriticalSection(&Service->ServiceStopGuard); DeleteCriticalSection(&Service->ServiceStatusGuard); MemFree(Service); } @@ -335,11 +337,16 @@ exit: FSP_API VOID FspServiceStop(FSP_SERVICE *Service) { SERVICE_STATUS ServiceStatus; + BOOLEAN Stopped; NTSTATUS Result; - EnterCriticalSection(&Service->ServiceStatusGuard); + if (!TryEnterCriticalSection(&Service->ServiceStopGuard)) + return; /* the service is already being stopped! */ - if (SERVICE_STOPPED == Service->ServiceStatus.dwCurrentState) + EnterCriticalSection(&Service->ServiceStatusGuard); + Stopped = SERVICE_STOPPED == Service->ServiceStatus.dwCurrentState; + LeaveCriticalSection(&Service->ServiceStatusGuard); + if (Stopped) goto exit; ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; @@ -376,7 +383,7 @@ FSP_API VOID FspServiceStop(FSP_SERVICE *Service) } exit: - LeaveCriticalSection(&Service->ServiceStatusGuard); + LeaveCriticalSection(&Service->ServiceStopGuard); } static VOID WINAPI FspServiceEntry(DWORD Argc, PWSTR *Argv)