xref: /reactos/base/services/wuauserv/wuauserv.c (revision 50cf16b3)
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 exitEvent = 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     SetServiceStatus(ServiceStatusHandle,
41                      &ServiceStatus);
42     DPRINT1("WU UpdateServiceStatus() called\n");
43 }
44 
45 static DWORD WINAPI
46 ServiceControlHandler(DWORD dwControl,
47                       DWORD dwEventType,
48                       LPVOID lpEventData,
49                       LPVOID lpContext)
50 {
51     switch (dwControl)
52     {
53         case SERVICE_CONTROL_STOP:
54             DPRINT1("WU ServiceControlHandler()  SERVICE_CONTROL_STOP received\n");
55             UpdateServiceStatus(SERVICE_STOPPED);
56             SetEvent(exitEvent);
57             return ERROR_SUCCESS;
58 
59         case SERVICE_CONTROL_PAUSE:
60             DPRINT1("WU ServiceControlHandler()  SERVICE_CONTROL_PAUSE received\n");
61             UpdateServiceStatus(SERVICE_PAUSED);
62             return ERROR_SUCCESS;
63 
64         case SERVICE_CONTROL_CONTINUE:
65             DPRINT1("WU ServiceControlHandler()  SERVICE_CONTROL_CONTINUE received\n");
66             UpdateServiceStatus(SERVICE_RUNNING);
67             return ERROR_SUCCESS;
68 
69         case SERVICE_CONTROL_INTERROGATE:
70             DPRINT1("WU ServiceControlHandler()  SERVICE_CONTROL_INTERROGATE received\n");
71             SetServiceStatus(ServiceStatusHandle,
72                              &ServiceStatus);
73             return ERROR_SUCCESS;
74 
75         case SERVICE_CONTROL_SHUTDOWN:
76             DPRINT1("WU ServiceControlHandler()  SERVICE_CONTROL_SHUTDOWN received\n");
77             UpdateServiceStatus(SERVICE_STOPPED);
78             return ERROR_SUCCESS;
79 
80         default :
81             DPRINT1("WU ServiceControlHandler()  Control %lu received\n");
82             return ERROR_CALL_NOT_IMPLEMENTED;
83     }
84 }
85 
86 VOID WINAPI
87 ServiceMain(DWORD argc, LPTSTR *argv)
88 {
89     UNREFERENCED_PARAMETER(argc);
90     UNREFERENCED_PARAMETER(argv);
91 
92     DPRINT("WU ServiceMain() called\n");
93 
94     ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName,
95                                                         ServiceControlHandler,
96                                                         NULL);
97     if (!ServiceStatusHandle)
98     {
99         DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
100         return;
101     }
102 
103     UpdateServiceStatus(SERVICE_RUNNING);
104 
105     exitEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
106     WaitForSingleObject(exitEvent, INFINITE);
107     CloseHandle(exitEvent);
108 
109     UpdateServiceStatus(SERVICE_STOPPED);
110 }
111 
112 BOOL WINAPI
113 DllMain(HINSTANCE hinstDLL,
114         DWORD fdwReason,
115         LPVOID lpvReserved)
116 {
117     switch (fdwReason)
118     {
119         case DLL_PROCESS_ATTACH:
120             DisableThreadLibraryCalls(hinstDLL);
121             break;
122 
123         case DLL_PROCESS_DETACH:
124             break;
125     }
126 
127     return TRUE;
128 }
129