]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - win/win32service.cpp
detect if the process has an interactive session (if its started as a service, the...
[user/henk/code/inspircd.git] / win / win32service.cpp
index 0eb9d0c1ac2cef919ea4f5b9a13b4090ac476215..0f8a2010806f8eac9edaf137c79d31a1412b4691 100644 (file)
@@ -17,6 +17,7 @@
 #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
@@ -27,6 +28,17 @@ static int serviceCurrentStatus;
 // directly against this symbol (see below where it is used)\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
+/* Represents a commandline and its handler */\r
+struct Commandline\r
+{\r
+       const char* Switch;\r
+       CommandlineParameterHandler Handler;\r
+};\r
+\r
+\r
 SETSERVDESC ChangeServiceConf;         // A function pointer for dynamic linking tricks\r
 \r
 \r
@@ -128,14 +140,14 @@ VOID ServiceMain(DWORD argc, LPTSTR *argv)
        serviceStatusHandle = RegisterServiceCtrlHandler("InspIRCd", (LPHANDLER_FUNCTION)ServiceCtrlHandler);\r
        if (!serviceStatusHandle)\r
        {\r
-               terminateService(1,GetLastError());\r
+               terminateService(1, GetLastError());\r
                return;\r
        }\r
 \r
        success = UpdateSCMStatus(SERVICE_START_PENDING, NO_ERROR, 0, 1, 1000);\r
        if (!success)\r
        {\r
-               terminateService(2,GetLastError());\r
+               terminateService(2, GetLastError());\r
                return;\r
        }\r
 \r
@@ -144,14 +156,14 @@ VOID ServiceMain(DWORD argc, LPTSTR *argv)
 \r
        if (!killServiceEvent || !hThreadEvent)\r
        {\r
-               terminateService(99,GetLastError());\r
+               terminateService(99, GetLastError());\r
                return;\r
        }\r
 \r
        success = UpdateSCMStatus(SERVICE_START_PENDING, NO_ERROR, 0, 2, 1000);\r
        if (!success)\r
        {\r
-               terminateService(2,GetLastError());\r
+               terminateService(2, GetLastError());\r
                return;\r
        }\r
 \r
@@ -160,13 +172,13 @@ VOID ServiceMain(DWORD argc, LPTSTR *argv)
        success = UpdateSCMStatus(SERVICE_RUNNING, NO_ERROR, 0, 0, 0);\r
        if (!success)\r
        {\r
-               terminateService(6,GetLastError());\r
+               terminateService(6, GetLastError());\r
                return;\r
        }\r
        WaitForSingleObject (killServiceEvent, INFINITE);\r
 }\r
 \r
-void InstallService(void)\r
+void InstallService()\r
 {\r
        SC_HANDLE myService, scm;\r
        SERVICE_DESCRIPTION svDesc;\r
@@ -178,16 +190,16 @@ void InstallService(void)
        scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE);\r
        if (!scm)\r
        {\r
-               printf("Unable to open service control manager: %d\n", GetLastError());\r
+               printf("Unable to open service control manager: %s\n", dlerror());\r
                return;\r
        }\r
 \r
        myService = CreateService(scm,"InspIRCd","Inspire IRC Daemon", SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,\r
-               SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, modname, 0, 0, 0, NULL, NULL);\r
+               SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, modname, 0, 0, 0, NULL, NULL);\r
 \r
        if (!myService)\r
        {\r
-               printf("Unable to create service: %d\n", GetLastError());\r
+               printf("Unable to create service: %s\n", dlerror());\r
                CloseServiceHandle(scm);\r
                return;\r
        }\r
@@ -202,13 +214,13 @@ void InstallService(void)
                ChangeServiceConf = (SETSERVDESC)GetProcAddress(advapi32,"ChangeServiceConfig2A");\r
                if (ChangeServiceConf)\r
                {\r
-                       char desc[] = "The Inspire Internet Relay Chat Daemon hosts IRC channels and conversations. \\r
                                    If this service is stopped, the IRC server will not run.";\r
+                       char desc[] = "The Inspire Internet Relay Chat Daemon hosts IRC channels and conversations.\\r
+ If this service is stopped, the IRC server will not run.";\r
                        svDesc.lpDescription = desc;\r
                        BOOL success = ChangeServiceConf(myService,SERVICE_CONFIG_DESCRIPTION, &svDesc);\r
                        if (!success)\r
                        {\r
-                               printf("Unable to set service description: %d\n", GetLastError());\r
+                               printf("Unable to set service description: %s\n", dlerror());\r
                                CloseServiceHandle(myService);\r
                                CloseServiceHandle(scm);\r
                                return;\r
@@ -222,28 +234,28 @@ void InstallService(void)
        CloseServiceHandle(scm);\r
 }\r
 \r
-void RemoveService(void)\r
+void RemoveService()\r
 {\r
        SC_HANDLE myService, scm;\r
 \r
        scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE);\r
        if (!scm)\r
        {\r
-               printf("Unable to open service control manager: %d\n", GetLastError());\r
+               printf("Unable to open service control manager: %s\n", dlerror());\r
                return;\r
        }\r
 \r
        myService = OpenService(scm,"InspIRCd",SERVICE_ALL_ACCESS);\r
        if (!myService)\r
        {\r
-               printf("Unable to open service: %d\n", GetLastError());\r
+               printf("Unable to open service: %s\n", dlerror());\r
                CloseServiceHandle(scm);\r
                return;\r
        }\r
 \r
        if (!DeleteService(myService))\r
        {\r
-               printf("Unable to delete service: %d\n", GetLastError());\r
+               printf("Unable to delete service: %s\n", dlerror());\r
                CloseServiceHandle(myService);\r
                CloseServiceHandle(scm);\r
                return;\r
@@ -257,18 +269,23 @@ void RemoveService(void)
 /* 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
+       Commandline params[] = {\r
+               { "--installservice", InstallService },\r
+               { "--removeservice", RemoveService },\r
+               { NULL }\r
+       };\r
+\r
        /* Check for parameters */\r
        if (argc > 1)\r
        {\r
-               if (!_stricmp(argv[1], "--installservice"))\r
+               for (int z = 0; params[z].Switch; ++z)\r
                {\r
-                       InstallService();\r
-                       return 0;\r
-               }\r
-               else if (!_stricmp(argv[1], "--removeservice"))\r
-               {\r
-                       RemoveService();\r
-                       return 0;\r
+                       if (!_stricmp(argv[1], params[z].Switch))\r
+                       {\r
+                               params[z].Handler();\r
+                               return 0;\r
+                       }\r
                }\r
        }\r
 \r
@@ -286,18 +303,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