38 SERVICE_STATUS_HANDLE gSvcStatusHandle;
39 SERVICE_STATUS gSvcStatus;
57 s->gSvcStatusHandle = 0;
63 static void parse_args(
yaz_sc_t s,
int *argc_p,
char ***argv_p)
71 for (i = 1; i < *argc_p; i++)
73 const char *
opt = (*argv_p)[i];
74 if (!strcmp(
opt,
"-install"))
80 else if (!strcmp(
opt,
"-installa"))
87 else if (!strcmp(
opt,
"-remove"))
93 else if (!strcmp(
opt,
"-run") && i < *argc_p-1)
96 const char *dir = (*argv_p)[i+1];
103 *argc_p = *argc_p - skip_opt;
104 for (; i < *argc_p; i++)
105 (*argv_p)[i] = (*argv_p)[i + skip_opt];
110 for (i = 1; i < *argc_p; i++)
112 const char *
opt = (*argv_p)[i];
113 if (
opt[0] ==
'-' &&
opt[1] ==
'l')
121 else if (i < *argc_p - 1)
141 *argc_p = *argc_p - skip_opt;
142 for (; i < *argc_p; i++)
143 (*argv_p)[i] = (*argv_p)[i + skip_opt];
149 DWORD dwCurrentState,
150 DWORD dwWin32ExitCode,
153 if (s->gSvcStatusHandle)
155 static DWORD dwCheckPoint = 1;
159 s->gSvcStatus.dwCurrentState = dwCurrentState;
160 s->gSvcStatus.dwWin32ExitCode = dwWin32ExitCode;
161 s->gSvcStatus.dwWaitHint = dwWaitHint;
163 if (dwCurrentState == SERVICE_START_PENDING)
164 s->gSvcStatus.dwControlsAccepted = 0;
166 s->gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
168 if ( (dwCurrentState == SERVICE_RUNNING) ||
169 (dwCurrentState == SERVICE_STOPPED) )
170 s->gSvcStatus.dwCheckPoint = 0;
172 s->gSvcStatus.dwCheckPoint = dwCheckPoint++;
175 SetServiceStatus(s->gSvcStatusHandle, &s->gSvcStatus );
181 VOID WINAPI sc_SvcCtrlHandler(DWORD dwCtrl)
185 case SERVICE_CONTROL_STOP:
187 sc_ReportSvcStatus(global_sc, SERVICE_STOP_PENDING, NO_ERROR, 0);
189 sc_ReportSvcStatus(global_sc, SERVICE_STOPPED, NO_ERROR, 0);
191 case SERVICE_CONTROL_INTERROGATE:
198 static void WINAPI sc_service_main(DWORD argc,
char **argv)
205 s->gSvcStatusHandle = RegisterServiceCtrlHandler(
208 if (!s->gSvcStatusHandle)
214 s->gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
215 s->gSvcStatus.dwServiceSpecificExitCode = 0;
217 sc_ReportSvcStatus(s, SERVICE_START_PENDING, NO_ERROR, 3000);
221 sc_ReportSvcStatus(s, SERVICE_STOPPED,
222 ret_code ? ERROR_SERVICE_SPECIFIC_ERROR : NO_ERROR, ret_code);
229 sc_ReportSvcStatus(s, SERVICE_RUNNING, NO_ERROR, 0);
234 int (*sc_main)(
yaz_sc_t s,
int argc,
char **argv),
241 parse_args(s, &argc, &argv);
245 SC_HANDLE manager = OpenSCManager(NULL ,
247 SC_MANAGER_ALL_ACCESS);
255 SC_HANDLE schService = 0;
259 char cwdstr[_MAX_PATH];
261 if (!_getcwd(cwdstr,
sizeof(cwdstr)))
262 strcpy (cwdstr,
".");
264 if (GetModuleFileName(NULL, szPath, 2048) == 0)
270 for (i = 1; i < argc; i++)
273 if (strchr(argv[i],
' '))
276 if (strchr(argv[i],
' '))
290 SERVICE_WIN32_OWN_PROCESS,
292 SERVICE_AUTO_START : SERVICE_DEMAND_START,
293 SERVICE_ERROR_NORMAL,
300 if (schService == NULL)
304 CloseServiceHandle(manager);
308 CloseServiceHandle(schService);
313 SC_HANDLE schService = 0;
314 SERVICE_STATUS serviceStatus;
316 schService = OpenService(manager, TEXT(s->
service_name), SERVICE_ALL_ACCESS);
317 if (schService == NULL)
321 CloseServiceHandle(manager);
325 if (ControlService(schService, SERVICE_CONTROL_STOP, &serviceStatus))
329 while (QueryServiceStatus(schService, &serviceStatus))
331 if (serviceStatus.dwCurrentState != SERVICE_STOP_PENDING)
335 if (serviceStatus.dwCurrentState != SERVICE_STOPPED)
338 if (DeleteService(schService))
342 CloseServiceHandle(schService);
344 CloseServiceHandle(manager);
350 SERVICE_TABLE_ENTRY dt[2];
353 dt[0].lpServiceProc = sc_service_main;
354 dt[1].lpServiceName = 0;
355 dt[1].lpServiceProc = 0;
359 if (!StartServiceCtrlDispatcher(dt))
368 return s->
sc_main(s, argc, argv);
373 xfree((*s)->service_name);
374 xfree((*s)->display_name);
void yaz_log(int level, const char *fmt,...)
Writes log message.
void yaz_log_init_file(const char *fname)
sets log file
#define YLOG_FATAL
log level: fatal
#define YLOG_ERRNO
log level: append system error message
#define YLOG_LOG
log level: log (regular)
void yaz_sc_destroy(yaz_sc_t *s)
frees service control handle
int yaz_sc_program(yaz_sc_t s, int argc, char **argv, int(*sc_main)(yaz_sc_t s, int argc, char **argv), void(*sc_stop)(yaz_sc_t s))
registers service controlled program
yaz_sc_t yaz_sc_create(const char *service_name, const char *display_name)
creates service handle
void yaz_sc_running(yaz_sc_t s)
signals that sc_main applicatio starts running
Header for Windows Service Control utility.
void(* sc_stop)(yaz_sc_t s)
int(* sc_main)(yaz_sc_t s, int argc, char **argv)
void wrbuf_destroy(WRBUF b)
destroy WRBUF and its buffer
WRBUF wrbuf_alloc(void)
construct WRBUF
const char * wrbuf_cstr(WRBUF b)
returns WRBUF content as C-string
void wrbuf_puts(WRBUF b, const char *buf)
appends C-string to WRBUF
Header for WRBUF (growing buffer)
Header for memory handling functions.
#define xstrdup(s)
utility macro which calls xstrdup_f
#define xfree(x)
utility macro which calls xfree_f
#define xmalloc(x)
utility macro which calls malloc_f