4 /* Copyright (c) 2009 Michal Cihar <michal@cihar.com> */
5 /* Licensend under GNU GPL 2 */
11 #include <gammu-smsd.h>
13 #include "winservice.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
)
30 FORMAT_MESSAGE_ALLOCATE_BUFFER
|
31 FORMAT_MESSAGE_FROM_SYSTEM
|
32 FORMAT_MESSAGE_IGNORE_INSERTS
,
35 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), /* Default language */
40 fprintf(stderr
, "Error %d: %s (%s)\n", (int)GetLastError(), lpMsgBuf
, info
);
45 void WINAPI
SMSDServiceCtrlHandler(DWORD Opcode
)
48 case SERVICE_CONTROL_PAUSE
:
49 m_ServiceStatus
.dwCurrentState
= SERVICE_PAUSED
;
51 case SERVICE_CONTROL_CONTINUE
:
52 m_ServiceStatus
.dwCurrentState
= SERVICE_RUNNING
;
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
,
62 SMSD_Shutdown(config
);
64 case SERVICE_CONTROL_INTERROGATE
:
70 BOOL
report_service_status(DWORD CurrentState
,
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;
85 m_ServiceStatus
.dwControlsAccepted
= SERVICE_ACCEPT_STOP
;
88 if ( (CurrentState
== SERVICE_RUNNING
) ||
89 (CurrentState
== SERVICE_STOPPED
) ) {
90 m_ServiceStatus
.dwCheckPoint
= 0;
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
)
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");
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");
126 report_service_status(SERVICE_STOPPED
, NO_ERROR
, 0);
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)
143 if (GetFullPathName(params
->config_file
, sizeof(config_name
), config_name
, NULL
) == 0)
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
) {
157 schService
= CreateService(schSCManager
,
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
) {
175 service_description
.lpDescription
= description
;
176 if (ChangeServiceConfig2(schService
, SERVICE_CONFIG_DESCRIPTION
, &service_description
) == 0) {
180 CloseServiceHandle(schService
);
184 gboolean
uninstall_smsd_service(void)
190 schSCManager
= OpenSCManager(NULL
, NULL
, SC_MANAGER_ALL_ACCESS
);
192 if (schSCManager
== NULL
) {
196 hService
= OpenService(schSCManager
, smsd_service_name
, SERVICE_ALL_ACCESS
);
198 if (hService
== NULL
) {
201 if (DeleteService(hService
) == 0) {
204 if (CloseServiceHandle(hService
) == 0) {
211 gboolean
stop_smsd_service(void)
216 SERVICE_STATUS sstatus
;
218 schSCManager
= OpenSCManager(NULL
, NULL
, SC_MANAGER_ALL_ACCESS
);
220 if (schSCManager
== NULL
)
223 OpenService(schSCManager
, smsd_service_name
, SERVICE_ALL_ACCESS
);
224 if (hService
== NULL
)
226 if (ControlService(hService
, SERVICE_CONTROL_STOP
, &sstatus
) == 0)
228 if (CloseServiceHandle(hService
) == 0)
234 gboolean
start_smsd_service(void)
240 schSCManager
= OpenSCManager(NULL
, NULL
, SC_MANAGER_ALL_ACCESS
);
242 if (schSCManager
== NULL
) {
246 hService
= OpenService(schSCManager
, smsd_service_name
, SERVICE_ALL_ACCESS
);
248 if (hService
== NULL
) {
251 if (StartService(hService
, 0, NULL
) == 0) {
254 if (CloseServiceHandle(hService
) == 0) {
261 gboolean
start_smsd_service_dispatcher(void)
263 SERVICE_TABLE_ENTRY DispatchTable
[] = {
264 {smsd_service_name
, ServiceMain
},
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: