3 HANDLE killServiceEvent = NULL;
4 static SERVICE_STATUS ssStatus; // current status of the service
5 static SERVICE_STATUS_HANDLE sshStatusHandle;
6 static DWORD dwErr = 0;
7 static char szErr[1024] = "";
9 char *name_service="ortemanager";
10 char *name_service_disp="ortemanager";
12 int managerInit(void); //forward declaration
13 int managerStart(void); //forward declaration
14 int managerStop(void); //forward declaration
16 static void AddToMessageLog(char *lpszMsg) {
19 char * lpszStrings[2];
21 dwErr = GetLastError();
22 hEventSource = RegisterEventSource(NULL, name_service);
23 sprintf(szMsg, "%s error: %li", name_service, dwErr);
24 lpszStrings[0] = szMsg;
25 lpszStrings[1] = lpszMsg;
26 if(hEventSource != NULL) {
27 ReportEvent(hEventSource, // handle of event source
28 EVENTLOG_ERROR_TYPE, // event type
31 NULL, // current user's SID
32 2, // strings in lpszStrings
33 0, // no bytes of raw data
34 (LPCSTR*)lpszStrings, // array of error strings
36 DeregisterEventSource(hEventSource);
40 BOOL ReportStatusToSCMgr(DWORD dwCurrentState,DWORD dwWin32ExitCode,
42 static DWORD dwCheckPoint = 1;
45 if(dwCurrentState == SERVICE_START_PENDING) ssStatus.dwControlsAccepted = 0;
46 else ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
47 ssStatus.dwCurrentState = dwCurrentState;
48 ssStatus.dwWin32ExitCode = dwWin32ExitCode;
49 ssStatus.dwWaitHint = dwWaitHint;
50 if((dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED)) ssStatus.dwCheckPoint = 0;
51 else ssStatus.dwCheckPoint = dwCheckPoint++;
52 if(!(fResult = SetServiceStatus(sshStatusHandle, &ssStatus))) {
53 AddToMessageLog("SetServiceStatus");
58 void WINAPI service_ctrl(DWORD dwCtrlCode) {
60 case SERVICE_CONTROL_STOP:
61 ssStatus.dwCurrentState = SERVICE_STOP_PENDING;
63 SetEvent(killServiceEvent);
65 case SERVICE_CONTROL_INTERROGATE:
70 ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
73 void WINAPI service_main(DWORD dwArgc, char **lpszArgv) {
75 sshStatusHandle = RegisterServiceCtrlHandler(name_service, service_ctrl);
77 ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
78 ssStatus.dwServiceSpecificExitCode = 0;
79 killServiceEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
80 if (!killServiceEvent) goto cleanup;
81 if(!ReportStatusToSCMgr(SERVICE_START_PENDING,NO_ERROR,3000)) goto cleanup;
84 AddToMessageLog("Starting communication");
89 if(!ReportStatusToSCMgr(SERVICE_RUNNING,NO_ERROR, 0 )) goto cleanup;
90 WaitForSingleObject(killServiceEvent,INFINITE);
91 CloseHandle(killServiceEvent);
95 ReportStatusToSCMgr(SERVICE_STOP_PENDING,dwErr,0);
96 ReportStatusToSCMgr(SERVICE_STOPPED,dwErr,0);
100 void serviceDispatchTable(void) {
101 SERVICE_TABLE_ENTRY dispatchTable[] = {
102 { name_service, (LPSERVICE_MAIN_FUNCTION)service_main },
105 if(!StartServiceCtrlDispatcher(dispatchTable)) {
106 AddToMessageLog("StartServiceCtrlDispatcher failed.");
110 char *GetLastErrorText( char *lpszBuf, DWORD dwSize ) {
112 char *lpszTemp = NULL;
114 dwRet = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
121 // supplied buffer is not long enough
122 if(!dwRet || ((long)dwSize < (long)dwRet+14)) {
125 lpszTemp[lstrlen(lpszTemp)-2] = '\0'; //remove cr and newline character
126 sprintf(lpszBuf, "%s (%li)", lpszTemp, GetLastError());
128 if(lpszTemp) LocalFree((HLOCAL) lpszTemp );
132 void installService(void) {
133 SC_HANDLE schService;
134 SC_HANDLE schSCManager;
137 if(GetModuleFileName( NULL, szPath, sizeof(szPath) - 1) == 0) {
138 printf("Unable to install %s - %s\n",
140 GetLastErrorText(szErr, sizeof(szErr)));
143 strcat(szPath," -s");
144 schSCManager = OpenSCManager(NULL, // machine (NULL == local)
145 NULL, // database (NULL == default)
146 SC_MANAGER_ALL_ACCESS); // access required
148 schService = CreateService(schSCManager, // SCManager database
149 name_service, // name of service
150 name_service_disp, // name to display
151 SERVICE_ALL_ACCESS, // desired access
152 SERVICE_WIN32_OWN_PROCESS, // service type
153 SERVICE_AUTO_START, // start type
154 SERVICE_ERROR_NORMAL, // error control type
155 szPath, // service's binary
156 NULL, // no load ordering group
157 NULL, // no tag identifier
158 NULL, // dependencies
159 NULL, // LocalSystem account
160 NULL); // no password
162 CloseServiceHandle(schSCManager);
163 printf("Service name (%s) instaled!\n",name_service);
165 printf("OpenSCManager failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
170 void removeService(void) {
171 SC_HANDLE schService;
172 SC_HANDLE schSCManager;
174 schSCManager = OpenSCManager(NULL, // machine (NULL == local)
175 NULL, // database (NULL == default)
176 SC_MANAGER_ALL_ACCESS ); // access required
178 schService = OpenService(schSCManager, name_service, SERVICE_ALL_ACCESS);
180 // try to stop the service
181 if(ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus )) {
182 printf("Stopping %s.", name_service);
184 while(QueryServiceStatus(schService, &ssStatus )) {
185 if(ssStatus.dwCurrentState == SERVICE_STOP_PENDING) {
192 if(ssStatus.dwCurrentState == SERVICE_STOPPED) {
193 printf("\n%s stopped.\n", name_service);
195 printf("\n%s failed to stop.\n", name_service);
198 // now remove the service
199 if(DeleteService(schService)) {
200 printf("%s removed.\n", name_service);
202 printf("DeleteService failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
204 CloseServiceHandle(schService);
206 printf("OpenService failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
208 CloseServiceHandle(schSCManager);
210 printf("OpenSCManager failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));