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