modified: myjupyterlab.sh
[GalaxyCodeBases.git] / etc / Windows / vlmcsd_old_vancepym / ntservice.c
blob6eb021ead126cf00cae0565263764ff9d5ecdc04
1 #ifndef CONFIG
2 #define CONFIG "config.h"
3 #endif // CONFIG
4 #include CONFIG
6 #include "ntservice.h"
7 #include "shared_globals.h"
8 #include "vlmcsd.h"
9 #include "output.h"
10 #include "helpers.h"
12 #ifdef _NTSERVICE
14 SERVICE_STATUS gSvcStatus;
15 SERVICE_STATUS_HANDLE gSvcStatusHandle;
17 static VOID WINAPI ServiceCtrlHandler(const DWORD dwCtrl)
19 // Handle the requested control code.
21 switch(dwCtrl)
23 case SERVICE_CONTROL_STOP:
24 case SERVICE_CONTROL_SHUTDOWN:
26 ServiceShutdown = TRUE;
27 ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
29 // Remove PID file and free ressources
30 cleanup();
31 # ifdef USE_MSRPC
32 ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0);
33 # endif // !USE_MSRPC
34 return;
36 /*case SERVICE_CONTROL_INTERROGATE:
37 break;*/
39 default:
40 break;
44 static VOID WINAPI ServiceMain(const int argc_unused, CARGV argv_unused)
46 // Register the handler function for the service
48 gSvcStatusHandle = RegisterServiceCtrlHandler(
49 NT_SERVICE_NAME,
50 ServiceCtrlHandler
53 if(!gSvcStatusHandle)
55 //ServiceReportEvent(RegisterServiceCtrlHandler);
56 return;
59 // These SERVICE_STATUS members remain as set here
61 gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
62 gSvcStatus.dwServiceSpecificExitCode = 0;
64 // Run the actual program
65 ReportServiceStatus(SERVICE_STOPPED, newmain(), 3000);
68 SERVICE_TABLE_ENTRY NTServiceDispatchTable[] = {
70 (LPSTR)NT_SERVICE_NAME,
71 (LPSERVICE_MAIN_FUNCTION) ServiceMain
74 NULL,
75 NULL
79 VOID ReportServiceStatus(const DWORD dwCurrentState, const DWORD dwWin32ExitCode, const DWORD dwWaitHint)
81 static DWORD dwCheckPoint = 1;
83 // Fill in the SERVICE_STATUS structure.
85 gSvcStatus.dwCurrentState = dwCurrentState;
86 gSvcStatus.dwWin32ExitCode = dwWin32ExitCode;
87 gSvcStatus.dwWaitHint = dwWaitHint;
89 if (dwCurrentState == SERVICE_START_PENDING)
90 gSvcStatus.dwControlsAccepted = 0;
91 else
92 gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
94 if ( (dwCurrentState == SERVICE_RUNNING) ||
95 (dwCurrentState == SERVICE_STOPPED) )
96 gSvcStatus.dwCheckPoint = 0;
97 else
98 gSvcStatus.dwCheckPoint = dwCheckPoint++;
100 // Report the status of the service to the SCM.
101 SetServiceStatus(gSvcStatusHandle, &gSvcStatus);
104 /*VOID ServiceReportEvent(char *szFunction)
106 HANDLE hEventSource;
107 const char *eventStrings[2];
108 TCHAR Buffer[80];
110 hEventSource = RegisterEventSource(NULL, NT_SERVICE_NAME);
112 if (hEventSource)
114 snprintf(Buffer, 80, "%s failed with %d", szFunction, GetLastError());
116 eventStrings[0] = NT_SERVICE_NAME;
117 eventStrings[1] = Buffer;
119 ReportEvent(hEventSource, // event log handle
120 EVENTLOG_ERROR_TYPE, // event type
121 0, // event category
122 00, // event identifier
123 NULL, // no security identifier
124 2, // size of lpszStrings array
125 0, // no binary data
126 eventStrings, // array of strings
127 NULL); // no binary data
129 DeregisterEventSource(hEventSource);
133 //Returns 0=Error, 1=Success, 2=Doesn't exist
136 static uint_fast8_t OpenAndRemoveService(DWORD *dwPreviousState, SC_HANDLE *schSCManager)
138 SERVICE_STATUS status;
139 uint_fast8_t i;
140 SC_HANDLE installedService;
141 uint_fast8_t result = 1;
142 BOOL closeManager = FALSE;
144 // Allow NULL for both Arguments
145 if (!dwPreviousState) dwPreviousState = (DWORD*)alloca(sizeof(*dwPreviousState));
146 if (!schSCManager)
148 schSCManager = (SC_HANDLE*)alloca(sizeof(*schSCManager));
149 closeManager = TRUE;
152 *schSCManager = OpenSCManager(
153 NULL, // local computer
154 NULL, // ServicesActive database
155 SC_MANAGER_ALL_ACCESS); // full access rights
157 if (!*schSCManager) return 0;
159 if (!(installedService = OpenService(*schSCManager, NT_SERVICE_NAME, SERVICE_ALL_ACCESS)))
161 result = 2;
163 else
165 *dwPreviousState = SERVICE_STOPPED;
166 if (QueryServiceStatus(installedService, &status)) *dwPreviousState = status.dwCurrentState;
168 ControlService(installedService, SERVICE_CONTROL_STOP, &status);
170 for (i = 0; i < 10; i++)
172 QueryServiceStatus(installedService, &status);
173 // Give it 100 ms after it reported SERVICE_STOPPED. Subsequent CreateService will fail otherwise
174 Sleep(100);
175 if (status.dwCurrentState == SERVICE_STOPPED) break;
178 if (!DeleteService(installedService)) result = 0;
179 CloseServiceHandle(installedService);
182 if (closeManager) CloseServiceHandle(*schSCManager);
183 return result;
186 static VOID ServiceInstaller(const char *restrict ServiceUser, const char *const ServicePassword)
188 SC_HANDLE schSCManager;
189 SC_HANDLE schService;
190 char szPath[MAX_PATH] = "\"";
192 if (!GetModuleFileName(NULL, szPath + sizeof(char), MAX_PATH - 1))
194 errorout("Cannot install service (%d)\n", (uint32_t)GetLastError());
195 return;
198 strcat(szPath,"\"");
200 int i;
201 for (i = 1; i < global_argc; i ++)
203 // Strip unneccessary parameters, especially the password
204 if (!strcmp(global_argv[i], "-s")) continue;
206 if (!strcmp(global_argv[i], "-W") ||
207 !strcmp(global_argv[i], "-U"))
209 i++;
210 continue;
213 strcat(szPath, " ");
215 if (strchr(global_argv[i], ' '))
217 strcat(szPath, "\"");
218 strcat(szPath, global_argv[i]);
219 strcat(szPath, "\"");
221 else
222 strcat(szPath, global_argv[i]);
225 // Get a handle to the SCM database.
227 SERVICE_STATUS status;
228 DWORD dwPreviousState;
230 if (!OpenAndRemoveService(&dwPreviousState, &schSCManager))
232 errorout("Service removal failed (%d)\n", (uint32_t)GetLastError());
233 return;
236 char *tempUser = NULL;
238 if (ServiceUser)
240 // Shortcuts for some well known users
241 if (!strcasecmp(ServiceUser, "/l")) ServiceUser="NT AUTHORITY\\LocalService";
242 if (!strcasecmp(ServiceUser, "/n")) ServiceUser="NT AUTHORITY\\NetworkService";
244 // Allow Local Users without .\ , e.g. "johndoe" instead of ".\johndoe"
245 if (!strchr(ServiceUser, '\\'))
247 tempUser = (char*)vlmcsd_malloc(strlen(ServiceUser) + 3);
248 strcpy(tempUser, ".\\");
249 strcat(tempUser, ServiceUser);
250 ServiceUser = tempUser;
254 schService = CreateService(
255 schSCManager, // SCM database
256 NT_SERVICE_NAME, // name of service
257 NT_SERVICE_DISPLAY_NAME, // service name to display
258 SERVICE_ALL_ACCESS, // desired access
259 SERVICE_WIN32_OWN_PROCESS, // service type
260 SERVICE_AUTO_START, // start type
261 SERVICE_ERROR_NORMAL, // error control type
262 szPath, // path to service's binary
263 NULL, // no load ordering group
264 NULL, // no tag identifier
265 "tcpip\0", // depends on TCP/IP
266 ServiceUser, // LocalSystem account
267 ServicePassword); // no password
269 # if __clang__ && (__CYGWIN__ || __MINGW64__ )
270 // Workaround for clang not understanding some GCC asm syntax used in <w32api/psdk_inc/intrin-impl.h>
271 ZeroMemory((char*)ServicePassword, strlen(ServicePassword));
272 # else
273 SecureZeroMemory((char*)ServicePassword, strlen(ServicePassword));
274 # endif
275 if (tempUser) free(tempUser);
277 if (schService == NULL)
279 errorout("CreateService failed (%u)\n", (uint32_t)GetLastError());
280 CloseServiceHandle(schSCManager);
281 return;
283 else
285 errorout("Service installed successfully\n");
287 if (dwPreviousState == SERVICE_RUNNING)
289 printf("Restarting " NT_SERVICE_NAME " service => ");
290 status.dwCurrentState = SERVICE_STOPPED;
292 if (StartService(schService, 0, NULL))
294 for (i = 0; i < 10; i++)
296 if (!QueryServiceStatus(schService, &status) || status.dwCurrentState != SERVICE_START_PENDING) break;
297 Sleep(100);
300 if (status.dwCurrentState == SERVICE_RUNNING)
301 printf("Success\n");
302 else if (status.dwCurrentState == SERVICE_START_PENDING)
303 printf("Not ready within a second\n");
304 else
305 errorout("Error\n");
307 else
308 errorout("Error %u\n", (uint32_t)GetLastError());
312 CloseServiceHandle(schService);
313 CloseServiceHandle(schSCManager);
316 int NtServiceInstallation(const int_fast8_t installService, const char *restrict ServiceUser, const char *const ServicePassword)
318 if (IsNTService) return 0;
320 if (installService == 1) // Install
322 ServiceInstaller(ServiceUser, ServicePassword);
323 return(0);
326 if (installService == 2) // Remove
328 switch(OpenAndRemoveService(NULL, NULL))
330 case 0:
331 errorout("Error removing service %s\n", NT_SERVICE_NAME);
332 return(!0);
333 case 1:
334 printf("Service %s removed successfully\n", NT_SERVICE_NAME);
335 return(0);
336 default:
337 errorout("Service %s does not exist.\n", NT_SERVICE_NAME);
338 return(!0);
342 // Do nothing
344 return(0);
346 #endif // _NTSERVICE