Project

General

Profile

« Previous | Next » 

Revision 368d31d4

Added by Hamish Coleman over 13 years ago

  • ID 368d31d4816d2b3a346918bb426efce8ba716283

Update win-scm with new learnings, also add a service test helper program

View differences:

.gitignore
# Ignore the built binaries
wconsd.exe
portenum.exe
svctest.exe
# Ignore the object files
*.o
Makefile
all: wconsd.exe portenum.exe
all: wconsd.exe portenum.exe svctest.exe
get:
pscp 192.168.1.1:s/src/wconsd/*.c ./
......
wconsd.exe: wconsd.o $(MODULES) $(LIBCLI)
$(CC) -o $@ $^ -lws2_32
svctest.exe: svctest.o win-scm.c
$(CC) -o $@ $^
portenum.exe: portenum.c
$(CC) $(CFLAGS) -o $@ portenum.c -lwinspool -lsetupapi
......
/usr/lib/wine/wine.bin wconsd.exe.so -p 9600
clean:
rm -f *.o wconsd.exe portenum.exe
rm -f *.o wconsd.exe portenum.exe svctest.exe
svctest.c
/*
* Test framework for win-svc
*
*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include "scm.h"
/*
* log a debug message
*/
int dprintf_level = 1;
int dprintf_to_stdout = 0;
int dprintf(unsigned char severity, const char *fmt, ...) {
va_list args;
char buf[1024];
int i;
if (severity > dprintf_level)
return 0;
va_start(args,fmt);
i=vsnprintf(buf,sizeof(buf),fmt,args);
va_end(args);
if (dprintf_to_stdout) {
printf("%s",buf);
} else {
OutputDebugStringA(buf);
}
return i;
}
#define trace(s) \
dprintf(1,"%s:%i(%s) %s\n",__FILE__,__LINE__,__FUNCTION__,s)
int svctest_init(int argc, char **argv);
int svctest_main(int param1);
int svctest_stop(int param1);
struct SCM_def sd = {
.name = "svctest",
.desc = "svctest - test win-scm",
.init = svctest_init,
.main = svctest_main,
.stop = svctest_stop,
};
static int do_getopt(const int argc, char **argv) {
static struct option long_options[] = {
{"install", 1, 0, 'i'},
{"remove", 0, 0, 'r'},
{"debug", 2, 0, 'd'},
{0,0,0,0}
};
while(1) {
int c = getopt_long(argc,argv, "ird::",
long_options,NULL);
if (c==-1)
break;
switch(c) {
case 'i': {
/* request service installation */
char *path = SCM_Install(&sd,optarg);
if (!path) {
printf("Service installation failed\n");
return 2;
}
printf("Service '%s' installed, binary path '%s'\n",sd.name,path);
printf("You should now start the service using the service manager.\n");
return 1;
}
case 'r':
// request service removal
if (SCM_Remove(&sd)==0) {
printf("Deleted service '%s'\n",sd.name);
} else {
printf("Service removal failed\n");
}
return 1;
}
}
return 0;
}
int svctest_init(int argc, char **argv) {
dprintf(1,"%s:%i(%s) argc==%i\n",__FILE__,__LINE__,__FUNCTION__,argc);
int i;
for (i=0;i<argc;i++) {
dprintf(1,"%s:%i: argv==%s\n",__FILE__,__LINE__,argv[i]);
}
dprintf(1,"%s:%i(%s) sd.mode==%i\n",__FILE__,__LINE__,__FUNCTION__,sd.mode);
if (do_getopt(argc,argv)) {
/* do_getopt returns nonzero if we should not continue */
return 1;
}
trace("return 0");
return 0;
}
int run = 1;
int svctest_main(int param1) {
while(run) {
1;
/* FIXME - sleep */
}
trace("return 0");
return 0;
}
int svctest_stop(int param1) {
run = 0;
trace("return 0");
return 0;
}
int main(int argc, char **argv)
{
dprintf(1,"%s:%i: argc==%i\n",__FILE__,__LINE__,argc);
char **arg = argv;
while(*arg) {
dprintf(1,"%s:%i: argv==%s\n",__FILE__,__LINE__,*arg);
arg++;
}
if (SCM_Start(&sd,argc,argv)!=SVC_OK) {
dprintf(1,"%s:%i: SCM_Start!=SVC_OK\n",__FILE__,__LINE__);
return 1;
}
trace("return 0");
return 0;
}
wconsd.c
switch(c) {
case 'i': {
/* request service installation */
char *path = SCM_Install(&sd);
char *path = SCM_Install(&sd,NULL);
if (!path) {
printf("Service installation failed\n");
return 2;
win-scm.c
SetServiceStatus( svcHandle, &svcStatus );
sd->mode=SVC_OK;
/* TODO - use either saved cmdline args or scm args here */
if ((err=sd->init(argc,argv))!=0) {
svcStatus.dwCurrentState = SERVICE_STOPPED;
svcStatus.dwWin32ExitCode = err;
......
return;
}
int SCM_Start_Console(int argc, char **argv) {
int SCM_Start_Console(struct SCM_def *sd) {
global_sd->mode=SVC_CONSOLE;
int err = global_sd->init(argc,argv);
sd->mode=SVC_CONSOLE;
int err = sd->init(sd->argc,sd->argv);
if (err!=0) {
return SVC_FAIL;
}
global_sd->main(0);
sd->main(0);
return SVC_OK;
}
......
{ NULL, NULL }
};
/* save the cmdline for possible use later */
sd->argc=argc;
sd->argv=argv;
global_sd = sd;
#if 0
/* turns out to be untrue! */
/* If we have commandline args, then we cannot have been started
* by the Windows SCM
*/
if (argc>1) {
return SCM_Start_Console(argc,argv);
return SCM_Start_Console(sd);
}
#endif
/* try to run as a service */
if (StartServiceCtrlDispatcher(ServiceTable)==0) {
int err = GetLastError();
if (err == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) {
return SCM_Start_Console(argc,argv);
return SCM_Start_Console(sd);
}
/* any other error, assume fatal */
......
return SVC_OK;
}
char *SCM_Install(struct SCM_def *sd) {
char *SCM_Install(struct SCM_def *sd, char *args) {
SC_HANDLE schSCManager, schService;
static char path[MAX_PATH];
......
return NULL;
}
/*
* Note - the above path calculation does not work for paths containing
* spaces. This is because Windows is stupid, mosttly due to bad
* design - see the next below.
*/
static char cmdline[MAX_PATH+10];
if (args) {
/*
* The "BinaryPathName" can also have cmdline params
* embedded into it. Stupid windows
*/
snprintf(cmdline,sizeof(cmdline),"\"%s\" %s",path,args);
} else {
snprintf(cmdline,sizeof(cmdline),"\"%s\"",path);
}
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
schService = CreateService(
......
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
path,
cmdline,
NULL, NULL, NULL, NULL, NULL);
if (schService == NULL) {

Also available in: Unified diff