common entry point whether invoked as service or as app
| 17 | |
| 18 | // common entry point whether invoked as service or as app |
| 19 | int CommonEntry(DWORD argc, LPTSTR* argv, bool asApp) |
| 20 | { |
| 21 | util::log::IdentificationTable::AddThisProcess("service"); |
| 22 | util::log::IdentificationTable::AddThisThread("main"); |
| 23 | logsetup::LogChannelManager logMan_; |
| 24 | // parse command line, return with error code from CLI11 if running as app |
| 25 | if (auto e = clio::Options::Init(argc, argv); e && asApp) { |
| 26 | return *e; |
| 27 | } |
| 28 | // configure windows registry access |
| 29 | Reg::SetReadonly(asApp); |
| 30 | // configure logging based on CLI arguments and registry settings |
| 31 | logsetup::ConfigureLogging(asApp); |
| 32 | // place middleware dll discovery path into registry |
| 33 | if (!asApp) { |
| 34 | char path[MAX_PATH]; |
| 35 | if (GetModuleFileNameA(nullptr, path, (DWORD)std::size(path)) == 0) { |
| 36 | pmlog_error("Failure to get path to service executable").no_trace().hr(); |
| 37 | } |
| 38 | else { |
| 39 | const auto middlewarePath = std::filesystem::path{ path }.parent_path() / "PresentMonAPI2.dll"; |
| 40 | Reg::Get().middlewarePath = middlewarePath.string(); |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | // annouce versioning etc. |
| 45 | pmlog_info(std::format("Starting service, build #{} ({}) [{}], logging @{} (log build @{})", |
| 46 | bid::BuildIdShortHash(), bid::BuildIdDirtyFlag() ? "dirty" : "clean", |
| 47 | bid::BuildIdTimestamp(), |
| 48 | log::GetLevelName(log::GlobalPolicy::Get().GetLogLevel()), |
| 49 | log::GetLevelName(PMLOG_BUILD_LEVEL_))); |
| 50 | |
| 51 | if (asApp) { |
| 52 | auto& svc = ConsoleDebugMockService::Get(); |
| 53 | svc.Run(); |
| 54 | return svc.GetErrorCode().value_or(0); |
| 55 | } |
| 56 | else { |
| 57 | ConcreteService svc{ serviceName }; |
| 58 | svc.ServiceMain(); |
| 59 | const auto exitCode = svc.GetErrorCode().value_or(0); |
| 60 | svc.ReportServiceStatus(SERVICE_STOPPED, exitCode, 0); |
| 61 | // this return code is not actually effectual, but we need to return something |
| 62 | return exitCode; |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | // callback registered with and called by the Service Control Manager |
| 67 | VOID WINAPI ServiceMainCallback(DWORD argc, LPTSTR* argv) |
no test coverage detected