MCPcopy Create free account
hub / github.com/apache/nifi-minifi-cpp / CreateServiceTerminationThread

Function CreateServiceTerminationThread

main/MiNiFiWindowsService.cpp:260–376  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

258}
259
260bool CreateServiceTerminationThread(std::shared_ptr<logging::Logger> logger, HANDLE terminationEventHandle) {
261 // Get hService and monitor it - if service is terminated, then terminate current exe, otherwise the exe becomes unmanageable when service is restarted.
262 auto hService = [&logger]() -> HANDLE {
263 auto hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
264 if (INVALID_HANDLE_VALUE == hSnapShot) {
265 logger->log_error("!CreateToolhelp32Snapshot lastError %x", GetLastError());
266 return 0;
267 }
268
269 auto getProcessInfo = [&logger, &hSnapShot](DWORD processId, DWORD& parentProcessId, std::string& parentProcessName) {
270 parentProcessId = 0;
271 parentProcessName.clear();
272
273 PROCESSENTRY32 procentry{};
274 procentry.dwSize = sizeof(procentry);
275
276 if (!Process32First(hSnapShot, &procentry)) {
277 logger->log_error("!Process32First lastError %x", GetLastError());
278 return;
279 }
280
281 do {
282 if (processId == procentry.th32ProcessID) {
283 parentProcessId = procentry.th32ParentProcessID;
284 parentProcessName = procentry.szExeFile;
285 return;
286 }
287 } while (Process32Next(hSnapShot, &procentry));
288 };
289
290 // Find current process info, which contains parentProcessId.
291 DWORD parentProcessId{};
292 std::string parentProcessName;
293 getProcessInfo(GetCurrentProcessId(), parentProcessId, parentProcessName);
294
295 // Find parent process info (the service which started current process), which contains service name.
296 DWORD parentParentProcessId{};
297 getProcessInfo(parentProcessId, parentParentProcessId, parentProcessName);
298
299 CloseHandle(hSnapShot);
300
301 // Just in case check that service name == current process name.
302 char filePath[MAX_PATH];
303 if (!GetModuleFileName(0, filePath, _countof(filePath))) {
304 logger->log_error("!GetModuleFileName lastError %x", GetLastError());
305 return 0;
306 }
307
308 const auto pSlash = strrchr(filePath, '\\');
309 if (!pSlash) {
310 logger->log_error("Invalid filePath %s", filePath);
311 return 0;
312 }
313 const std::string fileName = pSlash + 1;
314
315 if (_stricmp(fileName.c_str(), parentProcessName.c_str())) {
316 logger->log_error("Parent process %s != current process %s", parentProcessName.c_str(), fileName.c_str());
317 return 0;

Callers 1

mainFunction · 0.85

Calls 5

SignalExitProcessFunction · 0.85
log_errorMethod · 0.80
c_strMethod · 0.80
log_infoMethod · 0.80
clearMethod · 0.45

Tested by

no test coverage detected