1 /* 2 * PROJECT: ReactOS Print Spooler Service 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Main functions 5 * COPYRIGHT: Copyright 2015 Colin Finck (colin@reactos.org) 6 */ 7 8 #include "precomp.h" 9 10 SERVICE_STATUS_HANDLE hServiceStatus; 11 SERVICE_STATUS ServiceStatus; 12 WCHAR wszServiceName[] = L"Spooler"; 13 14 static void 15 _UpdateServiceStatus(DWORD dwNewStatus, DWORD dwCheckPoint) 16 { 17 ServiceStatus.dwCheckPoint = dwCheckPoint; 18 ServiceStatus.dwCurrentState = dwNewStatus; 19 SetServiceStatus(hServiceStatus, &ServiceStatus); 20 } 21 22 static DWORD WINAPI 23 _ServiceControlHandlerEx(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext) 24 { 25 switch (dwControl) 26 { 27 case SERVICE_CONTROL_SHUTDOWN: 28 case SERVICE_CONTROL_STOP: 29 _UpdateServiceStatus(SERVICE_STOP_PENDING, 1); 30 RpcMgmtStopServerListening(NULL); 31 _UpdateServiceStatus(SERVICE_STOPPED, 0); 32 return NO_ERROR; 33 34 case SERVICE_CONTROL_INTERROGATE: 35 return NO_ERROR; 36 37 default: 38 return ERROR_CALL_NOT_IMPLEMENTED; 39 } 40 } 41 42 static VOID WINAPI 43 _ServiceMain(DWORD dwArgc, LPWSTR* lpszArgv) 44 { 45 HANDLE hThread; 46 47 UNREFERENCED_PARAMETER(dwArgc); 48 UNREFERENCED_PARAMETER(lpszArgv); 49 50 // Register our service for control 51 hServiceStatus = RegisterServiceCtrlHandlerExW(wszServiceName, _ServiceControlHandlerEx, NULL); 52 53 // Report initial SERVICE_START_PENDING status 54 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; 55 ServiceStatus.dwServiceSpecificExitCode = 0; 56 ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 57 ServiceStatus.dwWaitHint = 4000; 58 ServiceStatus.dwWin32ExitCode = NO_ERROR; 59 _UpdateServiceStatus(SERVICE_START_PENDING, 0); 60 61 // Create a thread for serving RPC requests 62 hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)LrpcThreadProc, NULL, 0, NULL); 63 if (!hThread) 64 { 65 ERR("CreateThread failed with error %u!\n", GetLastError()); 66 _UpdateServiceStatus(SERVICE_STOPPED, 0); 67 return; 68 } 69 70 // We don't need the thread handle. Keeping it open blocks the thread from terminating. 71 CloseHandle(hThread); 72 73 // Initialize the routing layer in spoolss.dll 74 if (!InitializeRouter(hServiceStatus)) 75 { 76 ERR("InitializeRouter failed with error %lu!\n", GetLastError()); 77 _UpdateServiceStatus(SERVICE_STOPPED, 0); 78 return; 79 } 80 81 // We're alive! 82 _UpdateServiceStatus(SERVICE_RUNNING, 0); 83 } 84 85 int 86 wmain(int argc, WCHAR* argv[]) 87 { 88 SERVICE_TABLE_ENTRYW ServiceTable[] = 89 { 90 {wszServiceName, _ServiceMain}, 91 {NULL, NULL} 92 }; 93 94 UNREFERENCED_PARAMETER(argc); 95 UNREFERENCED_PARAMETER(argv); 96 97 StartServiceCtrlDispatcherW(ServiceTable); 98 99 return 0; 100 } 101