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 | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/daemon/lokinet.cpp b/daemon/lokinet.cpp index 5d50500db..3b576f504 100644 --- a/daemon/lokinet.cpp +++ b/daemon/lokinet.cpp @@ -344,14 +344,25 @@ 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") + + // 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) { - return StartServiceCtrlDispatcher(DispatchTable); + llarp::sys::service_manager->disable(); + return lokinet_main(argc, argv); } else { - llarp::sys::service_manager->disable(); - return lokinet_main(argc, argv); + 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) {