xref: /reactos/base/services/wuauserv/wuauserv.c (revision 016e7bb9)
155368bacSDenis Malikov /*
255368bacSDenis Malikov * PROJECT:          ReactOS Update Service
355368bacSDenis Malikov * LICENSE:          GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
455368bacSDenis Malikov * PURPOSE:          Automatic Updates service stub.
555368bacSDenis Malikov *                   Stub is required for some application at the installation phase.
655368bacSDenis Malikov * COPYRIGHT:        Copyright 2018 Denis Malikov (filedem@gmail.com)
755368bacSDenis Malikov */
855368bacSDenis Malikov 
955368bacSDenis Malikov #include "wuauserv.h"
1055368bacSDenis Malikov 
1155368bacSDenis Malikov /* GLOBALS ******************************************************************/
1255368bacSDenis Malikov 
1355368bacSDenis Malikov static WCHAR ServiceName[] = L"wuauserv";
1455368bacSDenis Malikov 
1555368bacSDenis Malikov static SERVICE_STATUS_HANDLE ServiceStatusHandle;
1655368bacSDenis Malikov static SERVICE_STATUS ServiceStatus;
1755368bacSDenis Malikov 
181f082eccSEric Kohl static HANDLE hStopEvent = NULL;
1955368bacSDenis Malikov 
2055368bacSDenis Malikov /* FUNCTIONS *****************************************************************/
2155368bacSDenis Malikov 
2255368bacSDenis Malikov static VOID
UpdateServiceStatus(DWORD dwState)2355368bacSDenis Malikov UpdateServiceStatus(DWORD dwState)
2455368bacSDenis Malikov {
2555368bacSDenis Malikov     ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
2655368bacSDenis Malikov     ServiceStatus.dwCurrentState = dwState;
2755368bacSDenis Malikov     ServiceStatus.dwControlsAccepted = 0;
2855368bacSDenis Malikov     ServiceStatus.dwWin32ExitCode = 0;
2955368bacSDenis Malikov     ServiceStatus.dwServiceSpecificExitCode = 0;
3055368bacSDenis Malikov     ServiceStatus.dwCheckPoint = 0;
3155368bacSDenis Malikov 
3255368bacSDenis Malikov     if (dwState == SERVICE_START_PENDING ||
3355368bacSDenis Malikov         dwState == SERVICE_STOP_PENDING ||
3455368bacSDenis Malikov         dwState == SERVICE_PAUSE_PENDING ||
3555368bacSDenis Malikov         dwState == SERVICE_CONTINUE_PENDING)
3655368bacSDenis Malikov         ServiceStatus.dwWaitHint = 1000;
3755368bacSDenis Malikov     else
3855368bacSDenis Malikov         ServiceStatus.dwWaitHint = 0;
3955368bacSDenis Malikov 
408a631c84SEric Kohl     if (dwState == SERVICE_RUNNING)
418a631c84SEric Kohl         ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
428a631c84SEric Kohl 
43*016e7bb9SHermès Bélusca-Maïto     SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
44*016e7bb9SHermès Bélusca-Maïto     DPRINT1("WU UpdateServiceStatus(%lu) called\n", dwState);
4555368bacSDenis Malikov }
4655368bacSDenis Malikov 
4755368bacSDenis Malikov static DWORD WINAPI
ServiceControlHandler(DWORD dwControl,DWORD dwEventType,LPVOID lpEventData,LPVOID lpContext)4855368bacSDenis Malikov ServiceControlHandler(DWORD dwControl,
4955368bacSDenis Malikov                       DWORD dwEventType,
5055368bacSDenis Malikov                       LPVOID lpEventData,
5155368bacSDenis Malikov                       LPVOID lpContext)
5255368bacSDenis Malikov {
5355368bacSDenis Malikov     switch (dwControl)
5455368bacSDenis Malikov     {
5555368bacSDenis Malikov         case SERVICE_CONTROL_STOP:
56*016e7bb9SHermès Bélusca-Maïto             DPRINT1("WU ServiceControlHandler(SERVICE_CONTROL_STOP) received\n");
571f082eccSEric Kohl             SetEvent(hStopEvent);
588a631c84SEric Kohl             UpdateServiceStatus(SERVICE_STOP_PENDING);
5955368bacSDenis Malikov             return ERROR_SUCCESS;
6055368bacSDenis Malikov 
6155368bacSDenis Malikov         case SERVICE_CONTROL_PAUSE:
62*016e7bb9SHermès Bélusca-Maïto             DPRINT1("WU ServiceControlHandler(SERVICE_CONTROL_PAUSE) received\n");
6355368bacSDenis Malikov             UpdateServiceStatus(SERVICE_PAUSED);
6455368bacSDenis Malikov             return ERROR_SUCCESS;
6555368bacSDenis Malikov 
6655368bacSDenis Malikov         case SERVICE_CONTROL_CONTINUE:
67*016e7bb9SHermès Bélusca-Maïto             DPRINT1("WU ServiceControlHandler(SERVICE_CONTROL_CONTINUE) received\n");
6855368bacSDenis Malikov             UpdateServiceStatus(SERVICE_RUNNING);
6955368bacSDenis Malikov             return ERROR_SUCCESS;
7055368bacSDenis Malikov 
7155368bacSDenis Malikov         case SERVICE_CONTROL_INTERROGATE:
72*016e7bb9SHermès Bélusca-Maïto             DPRINT1("WU ServiceControlHandler(SERVICE_CONTROL_INTERROGATE) received\n");
73*016e7bb9SHermès Bélusca-Maïto             SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
7455368bacSDenis Malikov             return ERROR_SUCCESS;
7555368bacSDenis Malikov 
7655368bacSDenis Malikov         case SERVICE_CONTROL_SHUTDOWN:
77*016e7bb9SHermès Bélusca-Maïto             DPRINT1("WU ServiceControlHandler(SERVICE_CONTROL_SHUTDOWN) received\n");
781f082eccSEric Kohl             SetEvent(hStopEvent);
798a631c84SEric Kohl             UpdateServiceStatus(SERVICE_STOP_PENDING);
8055368bacSDenis Malikov             return ERROR_SUCCESS;
8155368bacSDenis Malikov 
8255368bacSDenis Malikov         default :
83*016e7bb9SHermès Bélusca-Maïto             DPRINT1("WU ServiceControlHandler(Control %lu) received\n", dwControl);
8455368bacSDenis Malikov             return ERROR_CALL_NOT_IMPLEMENTED;
8555368bacSDenis Malikov     }
8655368bacSDenis Malikov }
8755368bacSDenis Malikov 
8855368bacSDenis Malikov VOID WINAPI
ServiceMain(DWORD argc,LPTSTR * argv)8955368bacSDenis Malikov ServiceMain(DWORD argc, LPTSTR *argv)
9055368bacSDenis Malikov {
9155368bacSDenis Malikov     UNREFERENCED_PARAMETER(argc);
9255368bacSDenis Malikov     UNREFERENCED_PARAMETER(argv);
9355368bacSDenis Malikov 
9455368bacSDenis Malikov     DPRINT("WU ServiceMain() called\n");
9555368bacSDenis Malikov 
9655368bacSDenis Malikov     ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName,
9755368bacSDenis Malikov                                                         ServiceControlHandler,
9855368bacSDenis Malikov                                                         NULL);
9955368bacSDenis Malikov     if (!ServiceStatusHandle)
10055368bacSDenis Malikov     {
101*016e7bb9SHermès Bélusca-Maïto         DPRINT1("RegisterServiceCtrlHandlerExW() failed (Error %lu)\n", GetLastError());
10255368bacSDenis Malikov         return;
10355368bacSDenis Malikov     }
10455368bacSDenis Malikov 
1051f082eccSEric Kohl     hStopEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
1061f082eccSEric Kohl     if (hStopEvent == NULL)
1071f082eccSEric Kohl     {
108*016e7bb9SHermès Bélusca-Maïto         DPRINT1("CreateEvent() failed (Error %lu)\n", GetLastError());
1091f082eccSEric Kohl         goto done;
1101f082eccSEric Kohl     }
1118a631c84SEric Kohl 
11255368bacSDenis Malikov     UpdateServiceStatus(SERVICE_RUNNING);
11355368bacSDenis Malikov 
1141f082eccSEric Kohl     WaitForSingleObject(hStopEvent, INFINITE);
1151f082eccSEric Kohl     CloseHandle(hStopEvent);
11655368bacSDenis Malikov 
1171f082eccSEric Kohl done:
11855368bacSDenis Malikov     UpdateServiceStatus(SERVICE_STOPPED);
11955368bacSDenis Malikov }
12055368bacSDenis Malikov 
12155368bacSDenis Malikov BOOL WINAPI
DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)12255368bacSDenis Malikov DllMain(HINSTANCE hinstDLL,
12355368bacSDenis Malikov         DWORD fdwReason,
12455368bacSDenis Malikov         LPVOID lpvReserved)
12555368bacSDenis Malikov {
12655368bacSDenis Malikov     switch (fdwReason)
12755368bacSDenis Malikov     {
12855368bacSDenis Malikov         case DLL_PROCESS_ATTACH:
12955368bacSDenis Malikov             DisableThreadLibraryCalls(hinstDLL);
13055368bacSDenis Malikov             break;
13155368bacSDenis Malikov 
13255368bacSDenis Malikov         case DLL_PROCESS_DETACH:
13355368bacSDenis Malikov             break;
13455368bacSDenis Malikov     }
13555368bacSDenis Malikov 
13655368bacSDenis Malikov     return TRUE;
13755368bacSDenis Malikov }
138