2 * PROJECT: ReactOS services
3 * LICENSE: GPL - See COPYING in the top level directory
5 * PURPOSE: skeleton service
6 * COPYRIGHT: Copyright 2008 Ged Murphy <gedmurphy@reactos.org>
10 #include "myservice.h"
12 volatile BOOL bShutDown
= FALSE
;
13 volatile BOOL bPause
= FALSE
;
15 LPTSTR ServiceName
= _T("skel_service");
17 typedef struct _ServiceInfo
19 SERVICE_STATUS servStatus
;
20 SERVICE_STATUS_HANDLE hStatus
;
21 } SERVICEINFO
, *PSERVICEINFO
;
23 /********* To be moved to new file **********/
24 typedef struct _ServiceData
28 } SERVICEDATA
, *PSERVICEDATA
;
30 DWORD WINAPI
ThreadProc(LPVOID lpParam
)
37 /*******************************************/
41 UpdateStatus(PSERVICEINFO pServInfo
,
48 pServInfo
->servStatus
.dwCheckPoint
+= Check
;
50 pServInfo
->servStatus
.dwCheckPoint
= Check
;
53 pServInfo
->servStatus
.dwCurrentState
= NewStatus
;
57 _T("Service state 0x%lu, CheckPoint %lu"),
58 pServInfo
->servStatus
.dwCurrentState
,
59 pServInfo
->servStatus
.dwCheckPoint
);
60 LogEvent(szSet
, 0, 0, LOG_FILE
);
62 if (!SetServiceStatus(pServInfo
->hStatus
, &pServInfo
->servStatus
))
63 LogEvent(_T("Cannot set service status"), GetLastError(), 0, LOG_ALL
);
67 CreateServiceThread(PSERVICEINFO pServInfo
)
70 PSERVICEDATA servData
;
72 UpdateStatus(pServInfo
, 0, 1);
74 LogEvent(_T("Creating service thread"), 0, 0, LOG_FILE
);
76 hThread
= CreateThread(NULL
,
85 LogEvent(_T("Failed to start service thread"), GetLastError(), 101, LOG_ALL
);
89 UpdateStatus(pServInfo
, 0, 1);
91 LogEvent(_T("setting service status to running"), 0, 0, LOG_FILE
);
92 UpdateStatus(pServInfo
, SERVICE_RUNNING
, 0);
94 WaitForSingleObject(hThread
, INFINITE
);
104 ServerCtrlHandler(DWORD dwControl
,
110 PSERVICEINFO pServInfo
= (PSERVICEINFO
)lpContext
;
114 case SERVICE_CONTROL_SHUTDOWN
:
115 case SERVICE_CONTROL_STOP
:
116 LogEvent(_T("\nSetting the service to SERVICE_STOP_PENDING"), 0, 0, LOG_FILE
);
117 InterlockedExchange((LONG
*)&bShutDown
, TRUE
);
118 pServInfo
->servStatus
.dwWin32ExitCode
= 0;
119 pServInfo
->servStatus
.dwWaitHint
= 0;
120 UpdateStatus(pServInfo
, SERVICE_STOP_PENDING
, 1);
123 case SERVICE_CONTROL_PAUSE
:
124 LogEvent(_T("Setting the service to SERVICE_PAUSED"), 0, 0, LOG_FILE
);
125 InterlockedExchange((LONG
*)&bPause
, TRUE
);
126 UpdateStatus(pServInfo
, SERVICE_PAUSED
, 0);
129 case SERVICE_CONTROL_CONTINUE
:
130 LogEvent(_T("Setting the service to SERVICE_RUNNING"), 0, 0, LOG_FILE
);
131 InterlockedExchange((LONG
*)&bPause
, FALSE
);
132 UpdateStatus(pServInfo
, SERVICE_RUNNING
, 0);
135 case SERVICE_CONTROL_INTERROGATE
:
139 if (dwControl
> 127 && dwControl
< 256) /* user defined */
140 LogEvent(_T("User defined control code"), 0, 0, LOG_FILE
);
142 LogEvent(_T("ERROR: Bad control code"), 0, 0, LOG_FILE
);
149 ServiceMain(DWORD argc
, LPTSTR argv
[])
151 SERVICEINFO servInfo
;
153 LogEvent(_T("Entering ServiceMain"), 0, 0, LOG_FILE
);
155 servInfo
.servStatus
.dwServiceType
= SERVICE_WIN32_OWN_PROCESS
;
156 servInfo
.servStatus
.dwCurrentState
= SERVICE_STOPPED
;
157 servInfo
.servStatus
.dwControlsAccepted
= SERVICE_ACCEPT_STOP
| SERVICE_ACCEPT_SHUTDOWN
| SERVICE_ACCEPT_PAUSE_CONTINUE
;
158 servInfo
.servStatus
.dwWin32ExitCode
= ERROR_SERVICE_SPECIFIC_ERROR
;
159 servInfo
.servStatus
.dwServiceSpecificExitCode
= 0;
160 servInfo
.servStatus
.dwCheckPoint
= 0;
161 servInfo
.servStatus
.dwWaitHint
= 1000;
163 LogEvent(_T("Registering service control handler"), 0, 0, LOG_FILE
);
164 servInfo
.hStatus
= RegisterServiceCtrlHandlerEx(ServiceName
, ServerCtrlHandler
, &servInfo
);
165 if (!servInfo
.hStatus
)
166 LogEvent(_T("Failed to register service"), GetLastError(), 100, LOG_ALL
);
168 UpdateStatus(&servInfo
, SERVICE_START_PENDING
, 1);
170 if (!CreateServiceThread(&servInfo
))
172 servInfo
.servStatus
.dwServiceSpecificExitCode
= 1;
173 UpdateStatus(&servInfo
, SERVICE_STOPPED
, 0);
177 LogEvent(_T("Service thread shut down. Set SERVICE_STOPPED status"), 0, 0, LOG_FILE
);
178 UpdateStatus(&servInfo
, SERVICE_STOPPED
, 0);
180 LogEvent(_T("Leaving ServiceMain"), 0, 0, LOG_FILE
);
184 int _tmain(int argc
, LPTSTR argv
[])
186 SERVICE_TABLE_ENTRY ServiceTable
[] =
188 {ServiceName
, ServiceMain
},
194 if (!StartServiceCtrlDispatcher(ServiceTable
))
195 LogEvent(_T("failed to start the service control dispatcher"), GetLastError(), 101, LOG_ALL
);