tIntroduction of -N flag to support functioning as an NT Service - vaccinewars - be a doctor and try to vaccinate the world
(HTM) git clone git://src.adamsgaard.dk/vaccinewars
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit f62a9d1e6315c24677fea70fd7727e348c861ddc
(DIR) parent 38f976f2b148003c9a5ee01061093b831d42d1bf
(HTM) Author: Ben Webb <ben@salilab.org>
Date: Mon, 5 Nov 2001 19:06:27 +0000
Introduction of -N flag to support functioning as an NT Service
Diffstat:
M src/dopewars.c | 4 ++--
M src/serverside.c | 79 +++++++++++++++++++++++++++++--
M src/serverside.h | 2 +-
M src/winmain.c | 58 ++++++++++++++++++++++---------
4 files changed, 118 insertions(+), 25 deletions(-)
---
(DIR) diff --git a/src/dopewars.c b/src/dopewars.c
t@@ -1948,7 +1948,7 @@ Report bugs to the author at ben@bellatrix.pcl.ox.ac.uk\n"),DATADIR);
void HandleCmdLine(int argc,char *argv[]) {
int c;
- static const gchar *options = "anbchvf:o:sSp:g:r:wtC:l:";
+ static const gchar *options = "anbchvf:o:sSp:g:r:wtC:l:N";
#ifdef HAVE_GETOPT_LONG
static const struct option long_options[] = {
{ "no-color", no_argument, NULL, 'b' },
t@@ -2074,7 +2074,7 @@ int main(int argc,char *argv[]) {
#ifdef GUI_SERVER
gtk_set_locale();
gtk_init(&argc,&argv);
- GuiServerLoop();
+ GuiServerLoop(FALSE);
#else
/* Deal with dopelog() stuff nicely */
logfp = fopen(Log.File,"a");
(DIR) diff --git a/src/serverside.c b/src/serverside.c
t@@ -1257,10 +1257,73 @@ static gint GuiRequestDelete(GtkWidget *widget,GdkEvent *event,gpointer data) {
#ifdef CYGWIN
static HWND mainhwnd=NULL;
+static SERVICE_STATUS_HANDLE scHandle;
+
+static BOOL RegisterStatus(DWORD state) {
+ SERVICE_STATUS status;
+ status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ status.dwCurrentState = state;
+ status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+ status.dwWin32ExitCode = NO_ERROR;
+ status.dwCheckPoint = 0;
+ status.dwWaitHint = 5000;
+ return SetServiceStatus(scHandle,&status);
+}
+
+static VOID WINAPI ServiceHandler(DWORD control) {
+ DWORD state=SERVICE_RUNNING;
+ switch(control) {
+ case SERVICE_CONTROL_STOP:
+ state=SERVICE_STOP_PENDING;
+ break;
+ }
+ if (!RegisterStatus(state)) {
+ dopelog(0,_("Failed to set NT Service status"));
+ return;
+ }
+
+ if (mainhwnd && !PostMessage(mainhwnd,MYWM_SERVICE,0,(LPARAM)control)) {
+ dopelog(0,_("Failed to post service notification message"));
+ return;
+ }
+}
+
+static VOID WINAPI ServiceInit(DWORD argc,LPTSTR *argv) {
+ scHandle = RegisterServiceCtrlHandler("dopewars-server",ServiceHandler);
+ if (!scHandle) {
+ dopelog(0,_("Failed to register service handler")); return;
+ }
+ if (!RegisterStatus(SERVICE_START_PENDING)) {
+ dopelog(0,_("Failed to set NT Service status"));
+ return;
+ }
+
+ GuiServerLoop(TRUE);
+
+ if (!RegisterStatus(SERVICE_STOPPED)) {
+ dopelog(0,_("Failed to set NT Service status"));
+ return;
+ }
+}
+
+void ServiceMain(void) {
+ SERVICE_TABLE_ENTRY services[] = {
+ { "dopewars-server",ServiceInit },
+ { NULL,NULL }
+ };
+ if (!StartServiceCtrlDispatcher(services)) {
+ dopelog(0,_("Failed to start NT Service"));
+ }
+}
static LRESULT CALLBACK GuiServerWndProc(HWND hwnd,UINT msg,WPARAM wparam,
LPARAM lparam) {
if (hwnd==mainhwnd) switch(msg) {
+ case MYWM_SERVICE:
+ if (lparam==SERVICE_CONTROL_STOP) {
+ GuiQuitServer();
+ }
+ break;
case MYWM_TASKBAR:
if ((UINT)lparam==WM_LBUTTONDOWN) ShowWindow(mainhwnd,SW_SHOW);
break;
t@@ -1281,7 +1344,6 @@ static void SetupTaskBarIcon(GtkWidget *widget) {
if (widget && !widget->hWnd) return;
if (!widget && !mainhwnd) return;
- if (widget) mainhwnd = widget->hWnd;
nid.hWnd = mainhwnd;
if (widget) {
nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
t@@ -1296,7 +1358,7 @@ static void SetupTaskBarIcon(GtkWidget *widget) {
}
#endif /* CYGWIN */
-void GuiServerLoop() {
+void GuiServerLoop(gboolean is_service) {
GtkWidget *window,*text,*hbox,*vbox,*entry,*label;
GtkAdjustment *adj;
t@@ -1329,14 +1391,21 @@ void GuiServerLoop() {
gtk_container_add(GTK_CONTAINER(window),vbox);
gtk_widget_show_all(window);
- g_set_print_handler(GuiServerPrintFunc);
- g_log_set_handler(NULL,LogMask()|G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_WARNING,
- GuiServerLogMessage,NULL);
+ if (!is_service) {
+ g_set_print_handler(GuiServerPrintFunc);
+ g_log_set_handler(NULL,LogMask()|G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_WARNING,
+ GuiServerLogMessage,NULL);
+ }
StartServer();
ListenTag=gdk_input_add(ListenSock,GDK_INPUT_READ,GuiNewConnect,NULL);
#ifdef CYGWIN
+ mainhwnd=window->hWnd;
SetupTaskBarIcon(window);
+ if (is_service && !RegisterStatus(SERVICE_RUNNING)) {
+ dopelog(0,_("Failed to set NT Service status"));
+ return;
+ }
#endif
gtk_main();
#ifdef CYGWIN
(DIR) diff --git a/src/serverside.h b/src/serverside.h
t@@ -71,7 +71,7 @@ gboolean CanPlayerFire(Player *Play);
gboolean CanRunHere(Player *Play);
Player *GetNextShooter(Player *Play);
#ifdef GUI_SERVER
-void GuiServerLoop(void);
+void GuiServerLoop(gboolean is_service);
#endif
#endif
(DIR) diff --git a/src/winmain.c b/src/winmain.c
t@@ -47,8 +47,9 @@ static void ServerLogMessage(const gchar *log_domain,GLogLevelFlags log_level,
text=GetLogString(log_level,message);
if (text) {
g_string_append(text,"\n");
- WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),text->str,strlen(text->str),
- &NumChar,NULL);
+ g_print(text->str);
+/* WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),text->str,strlen(text->str),
+ &NumChar,NULL);*/
g_string_free(text,TRUE);
}
}
t@@ -146,15 +147,30 @@ int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpszCmdParam,int nCmdShow) {
gchar **split;
int argc;
+ gboolean is_service;
+ gchar modpath[300],*lastslash;
#ifdef ENABLE_NLS
gchar *winlocale;
#endif
- g_log_set_handler(NULL,LogMask()|G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_WARNING|
- G_LOG_LEVEL_CRITICAL,LogMessage,NULL);
+/* Are we running as an NT service? */
+ is_service = (lpszCmdParam && strncmp(lpszCmdParam,"-N",2)==0);
+
+ if (is_service) {
+ modpath[0]='\0';
+ GetModuleFileName(NULL,modpath,300);
+ lastslash=strrchr(modpath,'\\');
+ if (lastslash) *lastslash='\0';
+ SetCurrentDirectory(modpath);
+ }
+
LogFileStart();
g_set_print_handler(LogFilePrintFunc);
+ g_log_set_handler(NULL,LogMask()|G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_WARNING|
+ G_LOG_LEVEL_CRITICAL,
+ ServerLogMessage,NULL);
+
#ifdef ENABLE_NLS
winlocale=GetWindowsLocale();
if (winlocale) putenv(winlocale);
t@@ -176,25 +192,33 @@ int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
while (split[argc] && split[argc][0]) argc++;
if (GeneralStartup(argc,split)==0) {
- if (WantVersion || WantHelp) {
- WindowPrintStart();
- g_set_print_handler(WindowPrintFunc);
- HandleHelpTexts();
- WindowPrintEnd();
- } else if (WantConvert) {
- WindowPrintStart();
- g_set_print_handler(WindowPrintFunc);
- ConvertHighScoreFile();
- WindowPrintEnd();
- } else {
+ if (WantVersion || WantHelp) {
+ WindowPrintStart();
+ g_set_print_handler(WindowPrintFunc);
+ HandleHelpTexts();
+ WindowPrintEnd();
+#ifdef NETWORKING
+ } else if (is_service) {
+ StartNetworking();
+Network=Server=TRUE;
+ win32_init(hInstance,hPrevInstance,"mainicon");
+ ServiceMain();
+ StopNetworking();
+#endif
+ } else if (WantConvert) {
+ WindowPrintStart();
+ g_set_print_handler(WindowPrintFunc);
+ ConvertHighScoreFile();
+ WindowPrintEnd();
+ } else {
#ifdef NETWORKING
- StartNetworking();
+ StartNetworking();
#endif
if (Server) {
#ifdef NETWORKING
#ifdef GUI_SERVER
win32_init(hInstance,hPrevInstance,"mainicon");
- GuiServerLoop();
+ GuiServerLoop(FALSE);
#else
AllocConsole();
SetConsoleTitle(_("dopewars server"));