From 6b15e72206a5511ea1cd3a734ce3155e3668d084 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 28 Jul 2019 22:37:17 +0200 Subject: [PATCH] [W32TIME] Use an event to stop the service CORE-16180 --- base/services/w32time/w32time.c | 52 ++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/base/services/w32time/w32time.c b/base/services/w32time/w32time.c index d6a6828b637..590396fc771 100644 --- a/base/services/w32time/w32time.c +++ b/base/services/w32time/w32time.c @@ -12,6 +12,7 @@ SERVICE_STATUS ServiceStatus; SERVICE_STATUS_HANDLE hStatus; +HANDLE hStopEvent = NULL; static WCHAR ServiceName[] = L"W32Time"; int InitService(VOID); @@ -208,28 +209,21 @@ ControlHandler(DWORD request) switch (request) { case SERVICE_CONTROL_STOP: - DPRINT("W32Time Service stopped.\n"); - - ServiceStatus.dwWin32ExitCode = 0; - ServiceStatus.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus(hStatus, &ServiceStatus); - return; - case SERVICE_CONTROL_SHUTDOWN: - DPRINT("W32Time Service stopped.\n"); + DPRINT("Stopping W32Time Service\n"); ServiceStatus.dwWin32ExitCode = 0; - ServiceStatus.dwCurrentState = SERVICE_STOPPED; + ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; SetServiceStatus(hStatus, &ServiceStatus); + + if (hStopEvent) + SetEvent(hStopEvent); return; default: break; } - /* Report current status */ - SetServiceStatus(hStatus, &ServiceStatus); - return; } @@ -239,7 +233,7 @@ WINAPI ServiceMain(DWORD argc, LPWSTR *argv) { int result; - DWORD dwPollInterval; + DWORD dwInterval; UNREFERENCED_PARAMETER(argc); UNREFERENCED_PARAMETER(argv); @@ -260,14 +254,27 @@ ServiceMain(DWORD argc, LPWSTR *argv) return; } + /* Create the stop event */ + hStopEvent = CreateEventW(NULL, FALSE, FALSE, NULL); + if (hStopEvent == NULL) + { + ServiceStatus.dwCurrentState = SERVICE_STOPPED; + ServiceStatus.dwWin32ExitCode = GetLastError(); + ServiceStatus.dwControlsAccepted = 0; + SetServiceStatus(hStatus, &ServiceStatus); + return; + } + + /* Get the interval */ + dwInterval = GetIntervalSetting(); + /* We report the running status to SCM. */ ServiceStatus.dwCurrentState = SERVICE_RUNNING; SetServiceStatus(hStatus, &ServiceStatus); /* The worker loop of a service */ - while (ServiceStatus.dwCurrentState == SERVICE_RUNNING) + for (;;) { - dwPollInterval = GetIntervalSetting(); result = SetTime(); if (result) @@ -284,13 +291,24 @@ ServiceMain(DWORD argc, LPWSTR *argv) * service when the correct conditions can be determined, but it * is left commented out. ServiceStatus.dwCurrentState = SERVICE_STOPPED; - ServiceStatus.dwWin32ExitCode = -1; + ServiceStatus.dwWin32ExitCode = result; SetServiceStatus(hStatus, &ServiceStatus); return; */ } - Sleep(dwPollInterval * 1000); + if (WaitForSingleObject(hStopEvent, dwInterval) == WAIT_OBJECT_0) + { + CloseHandle(hStopEvent); + hStopEvent = NULL; + + ServiceStatus.dwCurrentState = SERVICE_STOPPED; + ServiceStatus.dwWin32ExitCode = ERROR_SUCCESS; + ServiceStatus.dwControlsAccepted = 0; + SetServiceStatus(hStatus, &ServiceStatus); + DPRINT("Stopped W32Time Service\n"); + return; + } } return; }