tIntroduction of -N flag to support functioning as an NT Service - vaccinewars … | |
git clone git://src.adamsgaard.dk/vaccinewars | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit f62a9d1e6315c24677fea70fd7727e348c861ddc | |
parent 38f976f2b148003c9a5ee01061093b831d42d1bf | |
Author: Ben Webb <[email protected]> | |
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(-) | |
--- | |
diff --git a/src/dopewars.c b/src/dopewars.c | |
t@@ -1948,7 +1948,7 @@ Report bugs to the author at [email protected]\… | |
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"); | |
diff --git a/src/serverside.c b/src/serverside.c | |
t@@ -1257,10 +1257,73 @@ static gint GuiRequestDelete(GtkWidget *widget,GdkEven… | |
#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 | |
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 | |
diff --git a/src/winmain.c b/src/winmain.c | |
t@@ -47,8 +47,9 @@ static void ServerLogMessage(const gchar *log_domain,GLogLev… | |
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 hPrev… | |
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 hPrev… | |
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")); |