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