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);
121 return ERROR_SUCCESS
;
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);
127 return ERROR_SUCCESS
;
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);
133 return ERROR_SUCCESS
;
135 case SERVICE_CONTROL_INTERROGATE
:
136 return ERROR_SUCCESS
;
139 if (dwControl
>= 128 && dwControl
<= 255) /* User defined */
141 LogEvent(_T("User defined control code"), 0, 0, LOG_FILE
);
142 return ERROR_SUCCESS
;
146 LogEvent(_T("ERROR: Bad control code"), 0, 0, LOG_FILE
);
147 return ERROR_INVALID_SERVICE_CONTROL
;
154 ServiceMain(DWORD argc
, LPTSTR argv
[])
156 SERVICEINFO servInfo
;
158 LogEvent(_T("Entering ServiceMain"), 0, 0, LOG_FILE
);
160 servInfo
.servStatus
.dwServiceType
= SERVICE_WIN32_OWN_PROCESS
;
161 servInfo
.servStatus
.dwCurrentState
= SERVICE_STOPPED
;
162 servInfo
.servStatus
.dwControlsAccepted
= SERVICE_ACCEPT_STOP
| SERVICE_ACCEPT_SHUTDOWN
| SERVICE_ACCEPT_PAUSE_CONTINUE
;
163 servInfo
.servStatus
.dwWin32ExitCode
= ERROR_SERVICE_SPECIFIC_ERROR
;
164 servInfo
.servStatus
.dwServiceSpecificExitCode
= 0;
165 servInfo
.servStatus
.dwCheckPoint
= 0;
166 servInfo
.servStatus
.dwWaitHint
= 1000;
168 LogEvent(_T("Registering service control handler"), 0, 0, LOG_FILE
);
169 servInfo
.hStatus
= RegisterServiceCtrlHandlerEx(ServiceName
, ServerCtrlHandler
, &servInfo
);
170 if (!servInfo
.hStatus
)
171 LogEvent(_T("Failed to register service"), GetLastError(), 100, LOG_ALL
);
173 UpdateStatus(&servInfo
, SERVICE_START_PENDING
, 1);
175 if (!CreateServiceThread(&servInfo
))
177 servInfo
.servStatus
.dwServiceSpecificExitCode
= 1;
178 UpdateStatus(&servInfo
, SERVICE_STOPPED
, 0);
182 LogEvent(_T("Service thread shut down. Set SERVICE_STOPPED status"), 0, 0, LOG_FILE
);
183 UpdateStatus(&servInfo
, SERVICE_STOPPED
, 0);
185 LogEvent(_T("Leaving ServiceMain"), 0, 0, LOG_FILE
);
189 int _tmain(int argc
, LPTSTR argv
[])
191 SERVICE_TABLE_ENTRY ServiceTable
[] =
193 {ServiceName
, ServiceMain
},
199 if (!StartServiceCtrlDispatcher(ServiceTable
))
200 LogEvent(_T("failed to start the service control dispatcher"), GetLastError(), 101, LOG_ALL
);