version 0.1.10
[fms.git] / src / fmsservice.cpp
1 #include "../include/fmsservice.h"\r
2 #include "../include/global.h"\r
3 \r
4 #include <string>\r
5 \r
6 #ifdef _WIN32\r
7 \r
8 #include <direct.h>\r
9 \r
10 #ifdef XMEM\r
11         #include <xmem.h>\r
12 #endif\r
13 \r
14 SERVICE_STATUS ServiceStatus; \r
15 SERVICE_STATUS_HANDLE hStatus; \r
16 \r
17 void ControlHandler(DWORD request) \r
18\r
19     switch(request) \r
20     { \r
21         case SERVICE_CONTROL_STOP: \r
22         case SERVICE_CONTROL_SHUTDOWN: \r
23             ServiceStatus.dwWin32ExitCode = 0; \r
24             ServiceStatus.dwCurrentState  = SERVICE_STOP_PENDING; \r
25                         wantshutdown=true;\r
26             break; \r
27         \r
28         default:\r
29             break;\r
30     } \r
31  \r
32     /* Report current status */\r
33     SetServiceStatus (hStatus, &ServiceStatus);\r
34  \r
35     return; \r
36 }\r
37 \r
38 BOOL ServiceInstall()\r
39 {\r
40     SC_HANDLE hSCM, hService;\r
41     char szFilePath[FILENAME_MAX], szKey[256];\r
42     HKEY hKey;\r
43     DWORD dwData;\r
44     \r
45     hSCM = OpenSCManager(NULL, /* local machine */\r
46                          NULL, /* ServicesActive database */\r
47                          SC_MANAGER_ALL_ACCESS); /* full access */\r
48 \r
49     if (!hSCM) return FALSE;\r
50 \r
51     GetModuleFileName(NULL, szFilePath, sizeof(szFilePath));\r
52         std::string commandline(szFilePath);\r
53         commandline+=" -s";\r
54 \r
55     hService = CreateService(hSCM,\r
56                              FMS_SERVICE_NAME,\r
57                              FMS_SERVICE_NAME,\r
58                              SERVICE_ALL_ACCESS,\r
59                              SERVICE_WIN32_OWN_PROCESS,\r
60                              SERVICE_AUTO_START, /* start condition */\r
61                              SERVICE_ERROR_NORMAL,\r
62                              commandline.c_str(),\r
63                              NULL,\r
64                              NULL,\r
65                              NULL,\r
66                              NULL,\r
67                              NULL);\r
68 \r
69     if (!hService) {\r
70         CloseServiceHandle(hSCM);\r
71         return FALSE;\r
72     }\r
73 \r
74     hKey = NULL;\r
75     strcpy(szKey, "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\");\r
76     strcat(szKey, FMS_SERVICE_NAME);\r
77     if (RegCreateKey(HKEY_LOCAL_MACHINE, szKey, &hKey) != ERROR_SUCCESS) {\r
78         CloseServiceHandle(hService);\r
79         CloseServiceHandle(hSCM);\r
80         return FALSE;\r
81     }\r
82 \r
83     RegSetValueEx(hKey,\r
84                   "EventMessageFile",\r
85                   0,\r
86                   REG_EXPAND_SZ, \r
87                   (CONST BYTE*)szFilePath,\r
88                   (int) strlen(szFilePath) + 1);     \r
89 \r
90     dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;\r
91     RegSetValueEx(hKey,\r
92                   "TypesSupported",\r
93                   0,\r
94                   REG_DWORD,\r
95                   (CONST BYTE*)&dwData,\r
96                   sizeof(DWORD));\r
97     RegCloseKey(hKey);\r
98 \r
99     CloseServiceHandle(hService);\r
100     CloseServiceHandle(hSCM);\r
101 \r
102     return TRUE;\r
103 }\r
104 \r
105 BOOL ServiceIsInstalled()\r
106 {\r
107     BOOL bResult;\r
108     SC_HANDLE hSCM, hService;\r
109     \r
110     hSCM = OpenSCManager(NULL, /* local machine */\r
111                          NULL, /* ServicesActive database */\r
112                          SC_MANAGER_ALL_ACCESS); /* full access */\r
113 \r
114     bResult = FALSE;\r
115 \r
116     if (hSCM) {\r
117         hService = OpenService(hSCM,\r
118                                FMS_SERVICE_NAME,\r
119                                SERVICE_QUERY_CONFIG);\r
120 \r
121         if (hService) {\r
122             bResult = TRUE;\r
123             CloseServiceHandle(hService);\r
124         }\r
125         CloseServiceHandle(hSCM);\r
126     }\r
127 \r
128     return bResult;\r
129 }\r
130 \r
131 void ServiceMain(int argc, char** argv) \r
132\r
133     char szDocumentRoot[MAX_PATH];\r
134 \r
135     ServiceStatus.dwServiceType        = SERVICE_WIN32; \r
136     ServiceStatus.dwCurrentState       = SERVICE_START_PENDING; \r
137     ServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;\r
138     ServiceStatus.dwWin32ExitCode      = 0; \r
139     ServiceStatus.dwServiceSpecificExitCode = 0; \r
140     ServiceStatus.dwCheckPoint         = 0; \r
141     ServiceStatus.dwWaitHint           = 0; \r
142 \r
143     hStatus = RegisterServiceCtrlHandler(FMS_SERVICE_NAME, (LPHANDLER_FUNCTION)ControlHandler);\r
144 \r
145     if (hStatus == (SERVICE_STATUS_HANDLE)0) { \r
146         /* Registering Control Handler failed */\r
147         return; \r
148     }\r
149 \r
150     /* Initialize Service */\r
151 \r
152     /*\r
153      Construct default paths & filenames and make sure we serve documents from the folder containing the executable.\r
154      If left without a default value, we will be serving from C:\WINDOWS\SYSTEM32 (we start there as a service)!\r
155     */\r
156     GetModuleFileName(NULL, szDocumentRoot, MAX_PATH);\r
157         std::string path(szDocumentRoot);\r
158         std::string::size_type slashpos=path.rfind("\\");\r
159         if(slashpos==std::string::npos)\r
160         {\r
161                 slashpos=path.rfind("/");\r
162         }\r
163         if(slashpos!=std::string::npos)\r
164         {\r
165                 path.erase(slashpos);\r
166         }\r
167         chdir(path.c_str());\r
168 \r
169     /* We report the running status to SCM. */\r
170     ServiceStatus.dwCurrentState = SERVICE_RUNNING;\r
171     SetServiceStatus (hStatus, &ServiceStatus);\r
172 \r
173         MainFunction();\r
174 \r
175         ServiceStatus.dwCurrentState=SERVICE_STOPPED;\r
176         SetServiceStatus(hStatus,&ServiceStatus);\r
177 \r
178     return; \r
179 }\r
180 \r
181 BOOL ServiceStart()\r
182 {\r
183     SERVICE_TABLE_ENTRY ServiceTable[2];\r
184 \r
185     ServiceTable[0].lpServiceName = FMS_SERVICE_NAME;\r
186     ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;\r
187 \r
188     ServiceTable[1].lpServiceName = NULL;\r
189     ServiceTable[1].lpServiceProc = NULL;\r
190 \r
191     /* Start the control dispatcher thread for our service */\r
192     return StartServiceCtrlDispatcher(ServiceTable);\r
193 }\r
194 \r
195 BOOL ServiceUninstall()\r
196 {\r
197     SC_HANDLE hSCM, hService;\r
198     BOOL bResult;\r
199     \r
200     hSCM = OpenSCManager(NULL, /* local machine */\r
201                          NULL, /* ServicesActive database */\r
202                          SC_MANAGER_ALL_ACCESS); /* full access */\r
203 \r
204     if (!hSCM) return 0;\r
205 \r
206     bResult = FALSE;\r
207 \r
208     hService = OpenService(hSCM,\r
209                            FMS_SERVICE_NAME,\r
210                            DELETE);\r
211 \r
212     if (hService) {\r
213         if (DeleteService(hService)) bResult = TRUE;\r
214         CloseServiceHandle(hService);\r
215     }\r
216 \r
217     CloseServiceHandle(hSCM);\r
218 \r
219     return bResult;\r
220 }\r
221 \r
222 #endif  // _WIN32\r