xref: /reactos/base/services/wuauserv/wuauserv.c (revision 9393fc32)
1 /*
2 * PROJECT:          ReactOS Update Service
3 * LICENSE:          GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE:          Automatic Updates service stub.
5 *                   Stub is required for some application at the installation phase.
6 * COPYRIGHT:        Copyright 2018 Denis Malikov (filedem@gmail.com)
7 */
8 
9 #include "wuauserv.h"
10 
11 /* GLOBALS ******************************************************************/
12 
13 static WCHAR ServiceName[] = L"wuauserv";
14 
15 static SERVICE_STATUS_HANDLE ServiceStatusHandle;
16 static SERVICE_STATUS ServiceStatus;
17 
18 static HANDLE hStopEvent = NULL;
19 
20 /* FUNCTIONS *****************************************************************/
21 
22 static VOID
23 UpdateServiceStatus(DWORD dwState)
24 {
25     ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
26     ServiceStatus.dwCurrentState = dwState;
27     ServiceStatus.dwControlsAccepted = 0;
28     ServiceStatus.dwWin32ExitCode = 0;
29     ServiceStatus.dwServiceSpecificExitCode = 0;
30     ServiceStatus.dwCheckPoint = 0;
31 
32     if (dwState == SERVICE_START_PENDING ||
33         dwState == SERVICE_STOP_PENDING ||
34         dwState == SERVICE_PAUSE_PENDING ||
35         dwState == SERVICE_CONTINUE_PENDING)
36         ServiceStatus.dwWaitHint = 1000;
37     else
38         ServiceStatus.dwWaitHint = 0;
39 
40     if (dwState == SERVICE_RUNNING)
41         ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
42 
43     SetServiceStatus(ServiceStatusHandle,
44                      &ServiceStatus);
45     DPRINT1("WU UpdateServiceStatus() called\n");
46 }
47 
48 static DWORD WINAPI
49 ServiceControlHandler(DWORD dwControl,
50                       DWORD dwEventType,
51                       LPVOID lpEventData,
52                       LPVOID lpContext)
53 {
54     switch (dwControl)
55     {
56         case SERVICE_CONTROL_STOP:
57             DPRINT1("WU ServiceControlHandler()  SERVICE_CONTROL_STOP received\n");
58             SetEvent(hStopEvent);
59             UpdateServiceStatus(SERVICE_STOP_PENDING);
60             return ERROR_SUCCESS;
61 
62         case SERVICE_CONTROL_PAUSE:
63             DPRINT1("WU ServiceControlHandler()  SERVICE_CONTROL_PAUSE received\n");
64             UpdateServiceStatus(SERVICE_PAUSED);
65             return ERROR_SUCCESS;
66 
67         case SERVICE_CONTROL_CONTINUE:
68             DPRINT1("WU ServiceControlHandler()  SERVICE_CONTROL_CONTINUE received\n");
69             UpdateServiceStatus(SERVICE_RUNNING);
70             return ERROR_SUCCESS;
71 
72         case SERVICE_CONTROL_INTERROGATE:
73             DPRINT1("WU ServiceControlHandler()  SERVICE_CONTROL_INTERROGATE received\n");
74             SetServiceStatus(ServiceStatusHandle,
75                              &ServiceStatus);
76             return ERROR_SUCCESS;
77 
78         case SERVICE_CONTROL_SHUTDOWN:
79             DPRINT1("WU ServiceControlHandler()  SERVICE_CONTROL_SHUTDOWN received\n");
80             SetEvent(hStopEvent);
81             UpdateServiceStatus(SERVICE_STOP_PENDING);
82             return ERROR_SUCCESS;
83 
84         default :
85             DPRINT1("WU ServiceControlHandler()  Control %lu received\n");
86             return ERROR_CALL_NOT_IMPLEMENTED;
87     }
88 }
89 
90 VOID WINAPI
91 ServiceMain(DWORD argc, LPTSTR *argv)
92 {
93     UNREFERENCED_PARAMETER(argc);
94     UNREFERENCED_PARAMETER(argv);
95 
96     DPRINT("WU ServiceMain() called\n");
97 
98     ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName,
99                                                         ServiceControlHandler,
100                                                         NULL);
101     if (!ServiceStatusHandle)
102     {
103         DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
104         return;
105     }
106 
107     hStopEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
108     if (hStopEvent == NULL)
109     {
110         DPRINT1("CreateEvent() failed! (Error %lu)\n", GetLastError());
111         goto done;
112     }
113 
114     UpdateServiceStatus(SERVICE_RUNNING);
115 
116     WaitForSingleObject(hStopEvent, INFINITE);
117     CloseHandle(hStopEvent);
118 
119 done:
120     UpdateServiceStatus(SERVICE_STOPPED);
121 }
122 
123 BOOL WINAPI
124 DllMain(HINSTANCE hinstDLL,
125         DWORD fdwReason,
126         LPVOID lpvReserved)
127 {
128     switch (fdwReason)
129     {
130         case DLL_PROCESS_ATTACH:
131             DisableThreadLibraryCalls(hinstDLL);
132             break;
133 
134         case DLL_PROCESS_DETACH:
135             break;
136     }
137 
138     return TRUE;
139 }
140