spoolsv: Improve the service stub so that it can be started and stopped.
[wine] / programs / spoolsv / main.c
1 /*
2  * Copyright 2007 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #define WIN32_LEAN_AND_MEAN
20
21 #include <windows.h>
22
23 #include "wine/debug.h"
24
25 WINE_DEFAULT_DEBUG_CHANNEL(spoolsv);
26
27 static WCHAR spoolerW[] = {'S','p','o','o','l','e','r',0};
28
29 static SERVICE_STATUS_HANDLE service_handle;
30 static HANDLE stop_event;
31
32 static DWORD WINAPI service_handler( DWORD ctrl, DWORD event_type, LPVOID event_data, LPVOID context )
33 {
34     SERVICE_STATUS status;
35
36     status.dwServiceType             = SERVICE_WIN32;
37     status.dwControlsAccepted        = SERVICE_ACCEPT_STOP;
38     status.dwWin32ExitCode           = 0;
39     status.dwServiceSpecificExitCode = 0;
40     status.dwCheckPoint              = 0;
41     status.dwWaitHint                = 0;
42
43     switch(ctrl)
44     {
45     case SERVICE_CONTROL_STOP:
46     case SERVICE_CONTROL_SHUTDOWN:
47         WINE_TRACE( "shutting down\n" );
48         status.dwCurrentState     = SERVICE_STOP_PENDING;
49         status.dwControlsAccepted = 0;
50         SetServiceStatus( service_handle, &status );
51         SetEvent( stop_event );
52         return NO_ERROR;
53     default:
54         WINE_FIXME( "got service ctrl %x\n", ctrl );
55         status.dwCurrentState = SERVICE_RUNNING;
56         SetServiceStatus( service_handle, &status );
57         return NO_ERROR;
58     }
59 }
60
61 static void WINAPI serv_main(DWORD argc, LPWSTR *argv)
62 {
63     SERVICE_STATUS status;
64
65     WINE_TRACE( "starting service\n" );
66
67     stop_event = CreateEventW( NULL, TRUE, FALSE, NULL );
68
69     service_handle = RegisterServiceCtrlHandlerExW( spoolerW, service_handler, NULL );
70     if (!service_handle)
71         return;
72
73     status.dwServiceType             = SERVICE_WIN32;
74     status.dwCurrentState            = SERVICE_RUNNING;
75     status.dwControlsAccepted        = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
76     status.dwWin32ExitCode           = 0;
77     status.dwServiceSpecificExitCode = 0;
78     status.dwCheckPoint              = 0;
79     status.dwWaitHint                = 10000;
80     SetServiceStatus( service_handle, &status );
81
82     WaitForSingleObject( stop_event, INFINITE );
83
84     status.dwCurrentState     = SERVICE_STOPPED;
85     status.dwControlsAccepted = 0;
86     SetServiceStatus( service_handle, &status );
87     WINE_TRACE( "service stopped\n" );
88 }
89
90 int main(int argc, char **argv)
91 {
92     static const SERVICE_TABLE_ENTRYW servtbl[] = {
93         {spoolerW, serv_main},
94         {NULL, NULL}
95     };
96
97     WINE_TRACE("(%d %p)\n", argc, argv);
98
99     StartServiceCtrlDispatcherW(servtbl);
100     return 0;
101 }