Translation update done using Pootle.
[gammu.git] / smsd / winservice.c
blobbe18fcec34bc4dbe98f631e8b1d67757c43391ed
1 /**
2 * SMSD Windows Service
3 */
4 /* Copyright (c) 2009 Michal Cihar <michal@cihar.com> */
5 /* Licensend under GNU GPL 2 */
7 #include <stdio.h>
8 #include <windows.h>
9 #include <winsvc.h>
10 #include <time.h>
11 #include <gammu-smsd.h>
13 #include "winservice.h"
14 #include "log.h"
16 char smsd_service_name[SERVICE_NAME_LENGTH] = "GammuSMSD";
18 /* Defined in main.c */
19 extern GSM_SMSDConfig *config;
21 SERVICE_STATUS m_ServiceStatus;
23 SERVICE_STATUS_HANDLE m_ServiceStatusHandle;
25 void service_print_error(const char *info)
27 char *lpMsgBuf;
29 FormatMessage(
30 FORMAT_MESSAGE_ALLOCATE_BUFFER |
31 FORMAT_MESSAGE_FROM_SYSTEM |
32 FORMAT_MESSAGE_IGNORE_INSERTS,
33 NULL,
34 GetLastError(),
35 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
36 (LPTSTR) &lpMsgBuf,
38 NULL
40 fprintf(stderr, "Error %d: %s (%s)\n", (int)GetLastError(), lpMsgBuf, info);
42 LocalFree(lpMsgBuf);
45 void WINAPI SMSDServiceCtrlHandler(DWORD Opcode)
47 switch (Opcode) {
48 case SERVICE_CONTROL_PAUSE:
49 m_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
50 break;
51 case SERVICE_CONTROL_CONTINUE:
52 m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
53 break;
54 case SERVICE_CONTROL_STOP:
55 m_ServiceStatus.dwWin32ExitCode = 0;
56 m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
57 m_ServiceStatus.dwCheckPoint = 0;
58 m_ServiceStatus.dwWaitHint = 0;
60 SetServiceStatus(m_ServiceStatusHandle,
61 &m_ServiceStatus);
62 SMSD_Shutdown(config);
63 break;
64 case SERVICE_CONTROL_INTERROGATE:
65 break;
67 return;
70 BOOL report_service_status(DWORD CurrentState,
71 DWORD Win32ExitCode,
72 DWORD WaitHint)
74 static DWORD CheckPoint = 1;
76 m_ServiceStatus.dwServiceType = SERVICE_WIN32;
77 m_ServiceStatus.dwCurrentState = CurrentState;
78 m_ServiceStatus.dwWin32ExitCode = Win32ExitCode;
79 m_ServiceStatus.dwServiceSpecificExitCode = 0;
80 m_ServiceStatus.dwWaitHint = WaitHint;
82 if (CurrentState == SERVICE_START_PENDING) {
83 m_ServiceStatus.dwControlsAccepted = 0;
84 } else {
85 m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
88 if ( (CurrentState == SERVICE_RUNNING) ||
89 (CurrentState == SERVICE_STOPPED) ) {
90 m_ServiceStatus.dwCheckPoint = 0;
91 } else {
92 m_ServiceStatus.dwCheckPoint = CheckPoint++;
95 // Report the status of the service to the SCM.
96 return SetServiceStatus( m_ServiceStatusHandle, &m_ServiceStatus );
99 void WINAPI ServiceMain(DWORD argc, LPTSTR * argv)
101 GSM_Error error;
104 m_ServiceStatusHandle = RegisterServiceCtrlHandler(smsd_service_name,
105 SMSDServiceCtrlHandler);
106 if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE) 0) {
107 service_print_error("Failed to initiate service");
108 SMSD_LogErrno(config, "Failed to initiate service");
109 return;
112 if (!report_service_status(SERVICE_START_PENDING, NO_ERROR, 3000)) {
113 service_print_error("Failed to report state pending");
116 if (!report_service_status(SERVICE_RUNNING, NO_ERROR, 0)) {
117 service_print_error("Failed to report state started");
120 error = SMSD_MainLoop(config, FALSE, 0);
121 if (error != ERR_NONE) {
122 report_service_status(SERVICE_STOPPED, error, 0);
123 SMSD_LogErrno(config, "Failed to start SMSD");
124 return;
125 } else {
126 report_service_status(SERVICE_STOPPED, NO_ERROR, 0);
128 return;
131 gboolean install_smsd_service(SMSD_Parameters * params)
133 char config_name[MAX_PATH], program_name[MAX_PATH], commandline[3 * MAX_PATH];
134 char service_display_name[MAX_PATH];
136 HANDLE schSCManager, schService;
137 char description[] = "Gammu SMS Daemon service";
138 SERVICE_DESCRIPTION service_description;
140 if (GetModuleFileName(NULL, program_name, sizeof(program_name)) == 0)
141 return FALSE;
143 if (GetFullPathName(params->config_file, sizeof(config_name), config_name, NULL) == 0)
144 return FALSE;
146 sprintf(commandline, "\"%s\" -S -c \"%s\" -n \"%s\" -f %d",
147 program_name, config_name, smsd_service_name, params->max_failures);
149 sprintf(service_display_name, "Gammu SMSD Service (%s)", smsd_service_name);
151 schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
153 if (schSCManager == NULL) {
154 return FALSE;
157 schService = CreateService(schSCManager,
158 smsd_service_name,
159 service_display_name, // service name to display
160 SERVICE_ALL_ACCESS, // desired access
161 SERVICE_WIN32_OWN_PROCESS, // service type
162 SERVICE_AUTO_START, // start type
163 SERVICE_ERROR_NORMAL, // error control type
164 commandline, // service's binarygammu-smsd
165 NULL, // no load ordering group
166 NULL, // no tag identifier
167 NULL, // no dependencies
168 NULL, // LocalSystem account
169 NULL); // no password
171 if (schService == NULL) {
172 return FALSE;
175 service_description.lpDescription = description;
176 if (ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &service_description) == 0) {
177 return FALSE;
180 CloseServiceHandle(schService);
181 return TRUE;
184 gboolean uninstall_smsd_service(void)
186 HANDLE schSCManager;
188 SC_HANDLE hService;
190 schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
192 if (schSCManager == NULL) {
193 return FALSE;
196 hService = OpenService(schSCManager, smsd_service_name, SERVICE_ALL_ACCESS);
198 if (hService == NULL) {
199 return FALSE;
201 if (DeleteService(hService) == 0) {
202 return FALSE;
204 if (CloseServiceHandle(hService) == 0) {
205 return FALSE;
208 return TRUE;
211 gboolean stop_smsd_service(void)
213 HANDLE schSCManager;
215 SC_HANDLE hService;
216 SERVICE_STATUS sstatus;
218 schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
220 if (schSCManager == NULL)
221 return FALSE;
222 hService =
223 OpenService(schSCManager, smsd_service_name, SERVICE_ALL_ACCESS);
224 if (hService == NULL)
225 return FALSE;
226 if (ControlService(hService, SERVICE_CONTROL_STOP, &sstatus) == 0)
227 return FALSE;
228 if (CloseServiceHandle(hService) == 0)
229 return FALSE;
231 return TRUE;
234 gboolean start_smsd_service(void)
236 HANDLE schSCManager;
238 SC_HANDLE hService;
240 schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
242 if (schSCManager == NULL) {
243 return FALSE;
246 hService = OpenService(schSCManager, smsd_service_name, SERVICE_ALL_ACCESS);
248 if (hService == NULL) {
249 return FALSE;
251 if (StartService(hService, 0, NULL) == 0) {
252 return FALSE;
254 if (CloseServiceHandle(hService) == 0) {
255 return FALSE;
258 return TRUE;
261 gboolean start_smsd_service_dispatcher(void)
263 SERVICE_TABLE_ENTRY DispatchTable[] = {
264 {smsd_service_name, ServiceMain},
265 {NULL, NULL}
268 return StartServiceCtrlDispatcher(DispatchTable);
271 /* How should editor hadle tabs in this file? Add editor commands here.
272 * vim: noexpandtab sw=8 ts=8 sts=8: