]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - win/win32service.cpp
zap the evil externs, and comment the lot
[user/henk/code/inspircd.git] / win / win32service.cpp
index ca44019c05205c9c42973630962259d7ce368cd0..d364cd6ce9f05a78828df70bdb1c4fa847dbbd21 100644 (file)
  *
  * ---------------------------------------------------
  */\r
-\r
+#include "inspircd_config.h"\r
+#include "inspircd.h"\r
 #include <windows.h>\r
 #include <stdlib.h>\r
 #include <string.h>\r
 #include <stdio.h>\r
 \r
-extern int smain(int argc, char** argv);\r
-extern const char* dlerror();\r
-\r
 static SERVICE_STATUS_HANDLE serviceStatusHandle;\r
 static HANDLE hThreadEvent;\r
 static HANDLE killServiceEvent;\r
 static int serviceCurrentStatus;\r
 \r
-// This is used to define ChangeServiceConf2() as we can't link\r
-// directly against this symbol (see below where it is used)\r
+/** This is used to define ChangeServiceConf2() as we can't link\r
+ * directly against this symbol (see below where it is used)\r
+ */\r
 typedef BOOL (CALLBACK* SETSERVDESC)(SC_HANDLE,DWORD,LPVOID);\r
+\r
+/* A commandline parameter handler for service specific commandline parameters */\r
 typedef void (*CommandlineParameterHandler)(void);\r
 \r
-SETSERVDESC ChangeServiceConf;         // A function pointer for dynamic linking tricks\r
+/* Represents a commandline and its handler */\r
+struct Commandline\r
+{\r
+       const char* Switch;\r
+       CommandlineParameterHandler Handler;\r
+};\r
 \r
+/* A function pointer for dynamic linking tricks */\r
+SETSERVDESC ChangeServiceConf;\r
 \r
+/* Kills the service by setting an event which the other thread picks up and exits */\r
 void KillService()\r
 {\r
-       /* FIXME: This should set a flag in the mainloop for shutting down */\r
        SetEvent(hThreadEvent);\r
        Sleep(2000);\r
        SetEvent(killServiceEvent);\r
 }\r
 \r
+/** The main part of inspircd runs within this thread function. This allows the service part to run\r
+ * seperately on its own and to be able to kill the worker thread when its time to quit.\r
+ */\r
 DWORD WINAPI WorkerThread(LPDWORD param)\r
 {\r
        // *** REAL MAIN HERE ***\r
@@ -51,13 +62,16 @@ DWORD WINAPI WorkerThread(LPDWORD param)
        return 0;\r
 }\r
 \r
+/** Starts the worker thread above */\r
 void StartServiceThread()\r
 {\r
        DWORD dwd;\r
        CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)WorkerThread,NULL,0,&dwd);\r
 }\r
 \r
-\r
+/** This function updates the status of the service in the SCM\r
+ * (service control manager, the services.msc applet)\r
+ */\r
 BOOL UpdateSCMStatus (DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint)\r
 {\r
        BOOL success;\r
@@ -94,14 +108,14 @@ BOOL UpdateSCMStatus (DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServi
        return success;\r
 }\r
 \r
-\r
+/** This function is called by us when the service is being shut down or when it can't be started */\r
 void terminateService (int code, int wincode)\r
 {\r
        UpdateSCMStatus(SERVICE_STOPPED,wincode?wincode:ERROR_SERVICE_SPECIFIC_ERROR,(wincode)?0:code,0,0);\r
        return;\r
 }\r
 \r
-\r
+/** This callback is called by windows when the state of the service has been changed */\r
 VOID ServiceCtrlHandler (DWORD controlCode)\r
 {\r
        switch(controlCode)\r
@@ -121,7 +135,7 @@ VOID ServiceCtrlHandler (DWORD controlCode)
        UpdateSCMStatus(serviceCurrentStatus, NO_ERROR, 0, 0, 0);\r
 }\r
 \r
-\r
+/** This callback is called by windows when the service is started */\r
 VOID ServiceMain(DWORD argc, LPTSTR *argv)\r
 {\r
        BOOL success;\r
@@ -141,8 +155,8 @@ VOID ServiceMain(DWORD argc, LPTSTR *argv)
                return;\r
        }\r
 \r
-       killServiceEvent = CreateEvent(NULL,true,false,NULL);\r
-       hThreadEvent = CreateEvent(NULL,true,false,NULL);\r
+       killServiceEvent = CreateEvent(NULL, true, false, NULL);\r
+       hThreadEvent = CreateEvent(NULL, true, false, NULL);\r
 \r
        if (!killServiceEvent || !hThreadEvent)\r
        {\r
@@ -168,6 +182,7 @@ VOID ServiceMain(DWORD argc, LPTSTR *argv)
        WaitForSingleObject (killServiceEvent, INFINITE);\r
 }\r
 \r
+/** Install the windows service. This requires administrator privileges. */\r
 void InstallService()\r
 {\r
        SC_HANDLE myService, scm;\r
@@ -224,6 +239,7 @@ void InstallService()
        CloseServiceHandle(scm);\r
 }\r
 \r
+/** Remove the windows service. This requires administrator privileges. */\r
 void RemoveService()\r
 {\r
        SC_HANDLE myService, scm;\r
@@ -256,16 +272,10 @@ void RemoveService()
        CloseServiceHandle(scm);\r
 }\r
 \r
-struct Commandline\r
-{\r
-       const char* Switch;\r
-       CommandlineParameterHandler Handler;\r
-};\r
-\r
 /* In windows, our main() flows through here, before calling the 'real' main, smain() in inspircd.cpp */\r
 int main(int argc, char** argv)\r
 {\r
-\r
+       /* List of parameters and handlers */\r
        Commandline params[] = {\r
                { "--installservice", InstallService },\r
                { "--removeservice", RemoveService },\r
@@ -299,18 +309,29 @@ int main(int argc, char** argv)
                {\r
                        /* Service not installed or no permission to modify it */\r
                        CloseServiceHandle(scm);\r
-                       smain(argc, argv);\r
+                       return smain(argc, argv);\r
                }\r
        }\r
        else\r
        {\r
                /* Not enough privileges to open the SCM */\r
-               smain(argc, argv);\r
+               return smain(argc, argv);\r
        }\r
 \r
        CloseServiceHandle(myService);\r
        CloseServiceHandle(scm);\r
 \r
+       /* Check if the process is running interactively. InspIRCd does not run interactively\r
+        * as a service so if this is true, we just run the non-service inspircd.\r
+        */\r
+       USEROBJECTFLAGS uoflags;\r
+       HWINSTA winstation = GetProcessWindowStation();\r
+       if (GetUserObjectInformation(winstation, UOI_FLAGS, &uoflags, sizeof(uoflags), NULL))\r
+       {\r
+               if (uoflags.dwFlags == WSF_VISIBLE)\r
+                       return smain(argc, argv);\r
+       }\r
+\r
        /* If we get here, we know the service is installed so we can start it */\r
 \r
        SERVICE_TABLE_ENTRY serviceTable[] =\r