f00abaad051b36000681d588a009fce01a2e4fe6
[reactos.git] / reactos / win32ss / printing / base / spoolsv / main.c
1 /*
2 * PROJECT: ReactOS Print Spooler Service
3 * LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
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)RpcThreadProc, 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 }