version 0.1.10
[fms.git] / src / fmsservice.cpp
diff --git a/src/fmsservice.cpp b/src/fmsservice.cpp
new file mode 100644 (file)
index 0000000..e24a53f
--- /dev/null
@@ -0,0 +1,222 @@
+#include "../include/fmsservice.h"\r
+#include "../include/global.h"\r
+\r
+#include <string>\r
+\r
+#ifdef _WIN32\r
+\r
+#include <direct.h>\r
+\r
+#ifdef XMEM\r
+       #include <xmem.h>\r
+#endif\r
+\r
+SERVICE_STATUS ServiceStatus; \r
+SERVICE_STATUS_HANDLE hStatus; \r
+\r
+void ControlHandler(DWORD request) \r
+{ \r
+    switch(request) \r
+    { \r
+        case SERVICE_CONTROL_STOP: \r
+        case SERVICE_CONTROL_SHUTDOWN: \r
+            ServiceStatus.dwWin32ExitCode = 0; \r
+            ServiceStatus.dwCurrentState  = SERVICE_STOP_PENDING; \r
+                       wantshutdown=true;\r
+            break; \r
+        \r
+        default:\r
+            break;\r
+    } \r
\r
+    /* Report current status */\r
+    SetServiceStatus (hStatus, &ServiceStatus);\r
\r
+    return; \r
+}\r
+\r
+BOOL ServiceInstall()\r
+{\r
+    SC_HANDLE hSCM, hService;\r
+    char szFilePath[FILENAME_MAX], szKey[256];\r
+    HKEY hKey;\r
+    DWORD dwData;\r
+    \r
+    hSCM = OpenSCManager(NULL, /* local machine */\r
+                         NULL, /* ServicesActive database */\r
+                         SC_MANAGER_ALL_ACCESS); /* full access */\r
+\r
+    if (!hSCM) return FALSE;\r
+\r
+    GetModuleFileName(NULL, szFilePath, sizeof(szFilePath));\r
+       std::string commandline(szFilePath);\r
+       commandline+=" -s";\r
+\r
+    hService = CreateService(hSCM,\r
+                             FMS_SERVICE_NAME,\r
+                             FMS_SERVICE_NAME,\r
+                             SERVICE_ALL_ACCESS,\r
+                             SERVICE_WIN32_OWN_PROCESS,\r
+                             SERVICE_AUTO_START, /* start condition */\r
+                             SERVICE_ERROR_NORMAL,\r
+                             commandline.c_str(),\r
+                             NULL,\r
+                             NULL,\r
+                             NULL,\r
+                             NULL,\r
+                             NULL);\r
+\r
+    if (!hService) {\r
+        CloseServiceHandle(hSCM);\r
+        return FALSE;\r
+    }\r
+\r
+    hKey = NULL;\r
+    strcpy(szKey, "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\");\r
+    strcat(szKey, FMS_SERVICE_NAME);\r
+    if (RegCreateKey(HKEY_LOCAL_MACHINE, szKey, &hKey) != ERROR_SUCCESS) {\r
+        CloseServiceHandle(hService);\r
+        CloseServiceHandle(hSCM);\r
+        return FALSE;\r
+    }\r
+\r
+    RegSetValueEx(hKey,\r
+                  "EventMessageFile",\r
+                  0,\r
+                  REG_EXPAND_SZ, \r
+                  (CONST BYTE*)szFilePath,\r
+                  (int) strlen(szFilePath) + 1);     \r
+\r
+    dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;\r
+    RegSetValueEx(hKey,\r
+                  "TypesSupported",\r
+                  0,\r
+                  REG_DWORD,\r
+                  (CONST BYTE*)&dwData,\r
+                  sizeof(DWORD));\r
+    RegCloseKey(hKey);\r
+\r
+    CloseServiceHandle(hService);\r
+    CloseServiceHandle(hSCM);\r
+\r
+    return TRUE;\r
+}\r
+\r
+BOOL ServiceIsInstalled()\r
+{\r
+    BOOL bResult;\r
+    SC_HANDLE hSCM, hService;\r
+    \r
+    hSCM = OpenSCManager(NULL, /* local machine */\r
+                         NULL, /* ServicesActive database */\r
+                         SC_MANAGER_ALL_ACCESS); /* full access */\r
+\r
+    bResult = FALSE;\r
+\r
+    if (hSCM) {\r
+        hService = OpenService(hSCM,\r
+                               FMS_SERVICE_NAME,\r
+                               SERVICE_QUERY_CONFIG);\r
+\r
+        if (hService) {\r
+            bResult = TRUE;\r
+            CloseServiceHandle(hService);\r
+        }\r
+        CloseServiceHandle(hSCM);\r
+    }\r
+\r
+    return bResult;\r
+}\r
+\r
+void ServiceMain(int argc, char** argv) \r
+{ \r
+    char szDocumentRoot[MAX_PATH];\r
+\r
+    ServiceStatus.dwServiceType        = SERVICE_WIN32; \r
+    ServiceStatus.dwCurrentState       = SERVICE_START_PENDING; \r
+    ServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;\r
+    ServiceStatus.dwWin32ExitCode      = 0; \r
+    ServiceStatus.dwServiceSpecificExitCode = 0; \r
+    ServiceStatus.dwCheckPoint         = 0; \r
+    ServiceStatus.dwWaitHint           = 0; \r
+\r
+    hStatus = RegisterServiceCtrlHandler(FMS_SERVICE_NAME, (LPHANDLER_FUNCTION)ControlHandler);\r
+\r
+    if (hStatus == (SERVICE_STATUS_HANDLE)0) { \r
+        /* Registering Control Handler failed */\r
+        return; \r
+    }\r
+\r
+    /* Initialize Service */\r
+\r
+    /*\r
+     Construct default paths & filenames and make sure we serve documents from the folder containing the executable.\r
+     If left without a default value, we will be serving from C:\WINDOWS\SYSTEM32 (we start there as a service)!\r
+    */\r
+    GetModuleFileName(NULL, szDocumentRoot, MAX_PATH);\r
+       std::string path(szDocumentRoot);\r
+       std::string::size_type slashpos=path.rfind("\\");\r
+       if(slashpos==std::string::npos)\r
+       {\r
+               slashpos=path.rfind("/");\r
+       }\r
+       if(slashpos!=std::string::npos)\r
+       {\r
+               path.erase(slashpos);\r
+       }\r
+       chdir(path.c_str());\r
+\r
+    /* We report the running status to SCM. */\r
+    ServiceStatus.dwCurrentState = SERVICE_RUNNING;\r
+    SetServiceStatus (hStatus, &ServiceStatus);\r
+\r
+       MainFunction();\r
+\r
+       ServiceStatus.dwCurrentState=SERVICE_STOPPED;\r
+       SetServiceStatus(hStatus,&ServiceStatus);\r
+\r
+    return; \r
+}\r
+\r
+BOOL ServiceStart()\r
+{\r
+    SERVICE_TABLE_ENTRY ServiceTable[2];\r
+\r
+    ServiceTable[0].lpServiceName = FMS_SERVICE_NAME;\r
+    ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;\r
+\r
+    ServiceTable[1].lpServiceName = NULL;\r
+    ServiceTable[1].lpServiceProc = NULL;\r
+\r
+    /* Start the control dispatcher thread for our service */\r
+    return StartServiceCtrlDispatcher(ServiceTable);\r
+}\r
+\r
+BOOL ServiceUninstall()\r
+{\r
+    SC_HANDLE hSCM, hService;\r
+    BOOL bResult;\r
+    \r
+    hSCM = OpenSCManager(NULL, /* local machine */\r
+                         NULL, /* ServicesActive database */\r
+                         SC_MANAGER_ALL_ACCESS); /* full access */\r
+\r
+    if (!hSCM) return 0;\r
+\r
+    bResult = FALSE;\r
+\r
+    hService = OpenService(hSCM,\r
+                           FMS_SERVICE_NAME,\r
+                           DELETE);\r
+\r
+    if (hService) {\r
+        if (DeleteService(hService)) bResult = TRUE;\r
+        CloseServiceHandle(hService);\r
+    }\r
+\r
+    CloseServiceHandle(hSCM);\r
+\r
+    return bResult;\r
+}\r
+\r
+#endif // _WIN32\r