From 95c0c8a7078f6deb495cbfee4e5a433cbaae56b4 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Fri, 28 Oct 2022 21:46:44 -0300 Subject: [PATCH] Improve windows running-as-a-service detection works Get rid of the --win32-daemon hack (which was removed from the service itself earlier in this PR, by mistake) and replace it with detection of the error code for "not running as a service" that windows gives us back if we try to set up service controller dispatching but aren't a service. --- daemon/lokinet.cpp | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/daemon/lokinet.cpp b/daemon/lokinet.cpp index 5d50500db..3b576f504 100644 --- a/daemon/lokinet.cpp +++ b/daemon/lokinet.cpp @@ -344,15 +344,26 @@ main(int argc, char* argv[]) #else SERVICE_TABLE_ENTRY DispatchTable[] = { {strdup("lokinet"), (LPSERVICE_MAIN_FUNCTION)win32_daemon_entry}, {NULL, NULL}}; - if (std::string{argv[1]} == "--win32-daemon") - { - return StartServiceCtrlDispatcher(DispatchTable); - } - else + + // Try first to run as a service; if this works it fires off to win32_daemon_entry and doesn't + // return until the service enters STOPPED state. + if (StartServiceCtrlDispatcher(DispatchTable)) + return 0; + + auto error = GetLastError(); + + // We'll get this error if not invoked as a service, which is fine: we can just run directly + if (error == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { llarp::sys::service_manager->disable(); return lokinet_main(argc, argv); } + else + { + llarp::log::critical( + logcat, "Error launching service: {}", std::system_category().message(error)); + return 1; + } #endif } @@ -605,9 +616,8 @@ SvcCtrlHandler(DWORD dwCtrl) } } -// The win32 daemon entry point is just a trampoline that returns control -// to the original lokinet entry -// and only gets called if we get --win32-daemon in the command line +// The win32 daemon entry point is where we go when invoked as a windows service; we do the required +// service dance and then pretend we were invoked via main(). VOID FAR PASCAL win32_daemon_entry(DWORD, LPTSTR* argv) {