]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - win/win32service.cpp
Merge pull request #320 from ChrisTX/insp20+cleanupwin
[user/henk/code/inspircd.git] / win / win32service.cpp
index 62d75178c803df88f67a78f82ebbe80c523ffe60..b677b6662e5d28cf6296a0683028f976a3b42569 100644 (file)
@@ -1,17 +1,25 @@
-/*       +------------------------------------+
- *       | Inspire Internet Relay Chat Daemon |
- *       +------------------------------------+
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
  *
- *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
- * See: http://www.inspircd.org/wiki/index.php/Credits
+ *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
  *
- * This program is free but copyrighted software; see
- *         the file COPYING for details.
+ * This file is part of InspIRCd.  InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
  *
- * ---------------------------------------------------
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+
+
 #include "inspircd_config.h"
 #include "inspircd.h"
+#include "exitcodes.h"
 #include <windows.h>
 #include <stdlib.h>
 #include <string.h>
@@ -27,8 +35,8 @@ static int serviceCurrentStatus;
  */
 typedef BOOL (CALLBACK* SETSERVDESC)(SC_HANDLE,DWORD,LPVOID);
 
-BOOL UpdateSCMStatus (DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint);
-void terminateService (int code, int wincode);
+BOOL UpdateSCMStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint);
+void terminateService(int code, int wincode);
 
 /* A commandline parameter handler for service specific commandline parameters */
 typedef void (*CommandlineParameterHandler)(void);
@@ -43,6 +51,15 @@ struct Commandline
 /* A function pointer for dynamic linking tricks */
 SETSERVDESC ChangeServiceConf;
 
+LPCSTR RetrieveLastError()
+{
+       static char err[100];
+       FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)err, sizeof(err), 0);
+       SetLastError(ERROR_SUCCESS);
+       return err;
+}
+
+/* Returns true if this program is running as a service, false if it is running interactive */
 bool IsAService()
 {
        USEROBJECTFLAGS uoflags;
@@ -67,9 +84,9 @@ void KillService()
 DWORD WINAPI WorkerThread(LPDWORD param)
 {
        char modname[MAX_PATH];
-       GetModuleFileName(NULL, modname, sizeof(modname));
-       char* argv[] = { modname, "--nofork", "--debug" };
-       smain(3, argv);
+       GetModuleFileNameA(NULL, modname, sizeof(modname));
+       char* argv[] = { modname, "--nofork" };
+       smain(2, argv);
        KillService();
        return 0;
 }
@@ -84,7 +101,7 @@ void SetServiceRunning()
        BOOL success = UpdateSCMStatus(SERVICE_RUNNING, NO_ERROR, 0, 0, 0);
        if (!success)
        {
-               terminateService(18, GetLastError());
+               terminateService(EXIT_STATUS_UPDATESCM_FAILED, GetLastError());
                return;
        }
 }
@@ -100,7 +117,7 @@ void StartServiceThread()
 /** This function updates the status of the service in the SCM
  * (service control manager, the services.msc applet)
  */
-BOOL UpdateSCMStatus (DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint)
+BOOL UpdateSCMStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint)
 {
        BOOL success;
        SERVICE_STATUS serviceStatus;
@@ -137,13 +154,13 @@ BOOL UpdateSCMStatus (DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServi
 }
 
 /** This function is called by us when the service is being shut down or when it can't be started */
-void terminateService (int code, int wincode)
+void terminateService(int code, int wincode)
 {
        UpdateSCMStatus(SERVICE_STOPPED, wincode ? wincode : ERROR_SERVICE_SPECIFIC_ERROR, wincode ? 0 : code, 0, 0);
        return;
 }
 
-/* In windows we hook this to exit() */
+/* In windows we hook this to InspIRCd::Exit() */
 void SetServiceStopped(int status)
 {
        if (!IsAService())
@@ -156,7 +173,7 @@ void SetServiceStopped(int status)
 }
 
 /** This callback is called by windows when the state of the service has been changed */
-VOID ServiceCtrlHandler (DWORD controlCode)
+VOID ServiceCtrlHandler(DWORD controlCode)
 {
        switch(controlCode)
        {
@@ -179,19 +196,18 @@ VOID ServiceCtrlHandler (DWORD controlCode)
 VOID ServiceMain(DWORD argc, LPTSTR *argv)
 {
        BOOL success;
-       DWORD type=0, size=0;
 
-       serviceStatusHandle = RegisterServiceCtrlHandler("InspIRCd", (LPHANDLER_FUNCTION)ServiceCtrlHandler);
+       serviceStatusHandle = RegisterServiceCtrlHandler(TEXT("InspIRCd"), (LPHANDLER_FUNCTION)ServiceCtrlHandler);
        if (!serviceStatusHandle)
        {
-               terminateService(17, GetLastError());
+               terminateService(EXIT_STATUS_RSCH_FAILED, GetLastError());
                return;
        }
 
        success = UpdateSCMStatus(SERVICE_START_PENDING, NO_ERROR, 0, 1, 1000);
        if (!success)
        {
-               terminateService(18, GetLastError());
+               terminateService(EXIT_STATUS_UPDATESCM_FAILED, GetLastError());
                return;
        }
 
@@ -200,14 +216,14 @@ VOID ServiceMain(DWORD argc, LPTSTR *argv)
 
        if (!killServiceEvent || !hThreadEvent)
        {
-               terminateService(19, GetLastError());
+               terminateService(EXIT_STATUS_CREATE_EVENT_FAILED, GetLastError());
                return;
        }
 
        success = UpdateSCMStatus(SERVICE_START_PENDING, NO_ERROR, 0, 2, 1000);
        if (!success)
        {
-               terminateService(18, GetLastError());
+               terminateService(EXIT_STATUS_UPDATESCM_FAILED, GetLastError());
                return;
        }
 
@@ -222,22 +238,22 @@ void InstallService()
        SERVICE_DESCRIPTION svDesc;
        HINSTANCE advapi32;
 
-       char modname[MAX_PATH];
+       TCHAR modname[MAX_PATH];
        GetModuleFileName(NULL, modname, sizeof(modname));
 
        scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE);
        if (!scm)
        {
-               printf("Unable to open service control manager: %s\n", dlerror());
+               printf("Unable to open service control manager: %s\n", RetrieveLastError());
                return;
        }
 
-       myService = CreateService(scm,"InspIRCd","Inspire IRC Daemon", SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
+       myService = CreateService(scm,TEXT("InspIRCd"),TEXT("Inspire IRC Daemon"), SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
                SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, modname, 0, 0, 0, NULL, NULL);
 
        if (!myService)
        {
-               printf("Unable to create service: %s\n", dlerror());
+               printf("Unable to create service: %s\n", RetrieveLastError());
                CloseServiceHandle(scm);
                return;
        }
@@ -246,19 +262,19 @@ void InstallService()
        // this is supported from 5.0 (win2k) onwards only, so we can't link to the definition of
        // this function in advapi32.lib, otherwise the program will not run on windows NT 4. We
        // must use LoadLibrary and GetProcAddress to export the function name from advapi32.dll
-       advapi32 = LoadLibrary("advapi32.dll");
+       advapi32 = LoadLibrary(TEXT("advapi32.dll"));
        if (advapi32)
        {
                ChangeServiceConf = (SETSERVDESC)GetProcAddress(advapi32,"ChangeServiceConfig2A");
                if (ChangeServiceConf)
                {
-                       char desc[] = "The Inspire Internet Relay Chat Daemon hosts IRC channels and conversations.\
- If this service is stopped, the IRC server will not run.";
+                       TCHAR desc[] = TEXT("The Inspire Internet Relay Chat Daemon hosts IRC channels and conversations.\
+ If this service is stopped, the IRC server will not run.");
                        svDesc.lpDescription = desc;
                        BOOL success = ChangeServiceConf(myService,SERVICE_CONFIG_DESCRIPTION, &svDesc);
                        if (!success)
                        {
-                               printf("Unable to set service description: %s\n", dlerror());
+                               printf("Unable to set service description: %s\n", RetrieveLastError());
                                CloseServiceHandle(myService);
                                CloseServiceHandle(scm);
                                return;
@@ -280,21 +296,21 @@ void RemoveService()
        scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE);
        if (!scm)
        {
-               printf("Unable to open service control manager: %s\n", dlerror());
+               printf("Unable to open service control manager: %s\n", RetrieveLastError());
                return;
        }
 
-       myService = OpenService(scm,"InspIRCd",SERVICE_ALL_ACCESS);
+       myService = OpenService(scm,TEXT("InspIRCd"),SERVICE_ALL_ACCESS);
        if (!myService)
        {
-               printf("Unable to open service: %s\n", dlerror());
+               printf("Unable to open service: %s\n", RetrieveLastError());
                CloseServiceHandle(scm);
                return;
        }
 
        if (!DeleteService(myService))
        {
-               printf("Unable to delete service: %s\n", dlerror());
+               printf("Unable to delete service: %s\n", RetrieveLastError());
                CloseServiceHandle(myService);
                CloseServiceHandle(scm);
                return;
@@ -337,7 +353,7 @@ int main(int argc, char** argv)
        scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE);
        if (scm)
        {
-               myService = OpenService(scm,"InspIRCd",SERVICE_ALL_ACCESS);
+               myService = OpenService(scm,TEXT("InspIRCd"),SERVICE_ALL_ACCESS);
                if (!myService)
                {
                        /* Service not installed or no permission to modify it */
@@ -364,7 +380,7 @@ int main(int argc, char** argv)
 
        SERVICE_TABLE_ENTRY serviceTable[] =
        {
-               {"InspIRCd", (LPSERVICE_MAIN_FUNCTION) ServiceMain },
+               {TEXT("InspIRCd"), (LPSERVICE_MAIN_FUNCTION) ServiceMain },
                {NULL, NULL}
        };