- Merge from trunk up to r45543
[reactos.git] / base / services / spoolsv / spoolsv.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: services/spoolsv/spoolsv.c
5 * PURPOSE: Printer spooler
6 * PROGRAMMER: Eric Kohl
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #define WIN32_NO_STATUS
12 #include <windows.h>
13
14 #include "wine/debug.h"
15
16 WINE_DEFAULT_DEBUG_CHANNEL(spoolsv);
17
18
19 /* GLOBALS ******************************************************************/
20
21 #define SERVICE_NAME TEXT("Spooler")
22
23 SERVICE_STATUS_HANDLE ServiceStatusHandle;
24 SERVICE_STATUS ServiceStatus;
25
26
27 /* FUNCTIONS *****************************************************************/
28
29 static VOID
30 UpdateServiceStatus(DWORD dwState)
31 {
32 ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
33 ServiceStatus.dwCurrentState = dwState;
34
35 if (dwState == SERVICE_RUNNING)
36 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
37 else if (dwState == SERVICE_PAUSED)
38 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_PAUSE_CONTINUE;
39 else
40 ServiceStatus.dwControlsAccepted = 0;
41
42 ServiceStatus.dwWin32ExitCode = 0;
43 ServiceStatus.dwServiceSpecificExitCode = 0;
44 ServiceStatus.dwCheckPoint = 0;
45
46 if (dwState == SERVICE_START_PENDING ||
47 dwState == SERVICE_STOP_PENDING ||
48 dwState == SERVICE_PAUSE_PENDING ||
49 dwState == SERVICE_CONTINUE_PENDING)
50 ServiceStatus.dwWaitHint = 10000;
51 else
52 ServiceStatus.dwWaitHint = 0;
53
54 SetServiceStatus(ServiceStatusHandle,
55 &ServiceStatus);
56 }
57
58
59 static DWORD WINAPI
60 ServiceControlHandler(DWORD dwControl,
61 DWORD dwEventType,
62 LPVOID lpEventData,
63 LPVOID lpContext)
64 {
65 TRACE("ServiceControlHandler() called\n");
66
67 switch (dwControl)
68 {
69 case SERVICE_CONTROL_STOP:
70 TRACE(" SERVICE_CONTROL_STOP received\n");
71 UpdateServiceStatus(SERVICE_STOPPED);
72 return ERROR_SUCCESS;
73
74 case SERVICE_CONTROL_PAUSE:
75 TRACE(" SERVICE_CONTROL_PAUSE received\n");
76 UpdateServiceStatus(SERVICE_PAUSED);
77 return ERROR_SUCCESS;
78
79 case SERVICE_CONTROL_CONTINUE:
80 TRACE(" SERVICE_CONTROL_CONTINUE received\n");
81 UpdateServiceStatus(SERVICE_RUNNING);
82 return ERROR_SUCCESS;
83
84 case SERVICE_CONTROL_INTERROGATE:
85 TRACE(" SERVICE_CONTROL_INTERROGATE received\n");
86 SetServiceStatus(ServiceStatusHandle,
87 &ServiceStatus);
88 return ERROR_SUCCESS;
89
90 case SERVICE_CONTROL_SHUTDOWN:
91 TRACE(" SERVICE_CONTROL_SHUTDOWN received\n");
92 UpdateServiceStatus(SERVICE_STOPPED);
93 return ERROR_SUCCESS;
94
95 default :
96 TRACE(" Control %lu received\n");
97 return ERROR_CALL_NOT_IMPLEMENTED;
98 }
99 }
100
101
102 static VOID CALLBACK
103 ServiceMain(DWORD argc, LPTSTR *argv)
104 {
105 UNREFERENCED_PARAMETER(argc);
106 UNREFERENCED_PARAMETER(argv);
107
108 TRACE("ServiceMain() called\n");
109
110 ServiceStatusHandle = RegisterServiceCtrlHandlerExW(SERVICE_NAME,
111 ServiceControlHandler,
112 NULL);
113
114 TRACE("Calling SetServiceStatus()\n");
115 UpdateServiceStatus(SERVICE_RUNNING);
116 TRACE("SetServiceStatus() called\n");
117
118
119 TRACE("ServiceMain() done\n");
120 }
121
122
123 int
124 wmain(int argc, WCHAR *argv[])
125 {
126 SERVICE_TABLE_ENTRY ServiceTable[2] =
127 {
128 {SERVICE_NAME, ServiceMain},
129 {NULL, NULL}
130 };
131
132 UNREFERENCED_PARAMETER(argc);
133 UNREFERENCED_PARAMETER(argv);
134
135 TRACE("Spoolsv: main() started\n");
136
137 StartServiceCtrlDispatcher(ServiceTable);
138
139 TRACE("Spoolsv: main() done\n");
140
141 ExitThread(0);
142
143 return 0;
144 }
145
146 /* EOF */