/* * Copyright (c) 2025 Proton AG * * This file is part of ProtonVPN. * * ProtonVPN is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ProtonVPN is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ProtonVPN. If not, see . */ using System; using System.Collections.Generic; using System.IO; using System.ServiceProcess; using Autofac; using ProtonVPN.Api.Installers; using ProtonVPN.Common.Core.Networking; using ProtonVPN.Common.Installers.Extensions; using ProtonVPN.Common.Legacy.OS.Processes; using ProtonVPN.Configurations.Contracts; using ProtonVPN.Configurations.Installers; using ProtonVPN.Crypto.Installers; using ProtonVPN.IPv6.Installers; using ProtonVPN.IssueReporting.Static; using ProtonVPN.Logging.Contracts; using ProtonVPN.Logging.Contracts.Events.AppServiceLogs; using ProtonVPN.Logging.Events; using ProtonVPN.Logging.Installers; using ProtonVPN.Native.PInvoke; using ProtonVPN.OperatingSystems.Network.Installers; using ProtonVPN.Service.Settings; using ProtonVPN.Service.StateMachine; using ProtonVPN.Update.Installers; using ProtonVPN.Vpn.OpenVpn; namespace ProtonVPN.Service.Start; internal class Bootstrapper { private IContainer _container; private T Resolve() => _container.Resolve(); public Bootstrapper() { GlobalExceptionHandler.Initialize(); IssueReportingInitializer.Run(); } public void Initialize() { SetDllDirectories(); Configure(); PrepareDirectories(); Start(); } private void Configure() { ContainerBuilder builder = new(); builder.RegisterLoggerConfiguration(c => c.ServiceLogsFilePath) .RegisterModule() .RegisterModule() .RegisterModule() .RegisterModule() .RegisterModule() .RegisterAssemblyModule() .RegisterAssemblyModule() .RegisterAssemblyModule(); _container = builder.Build(); } private void PrepareDirectories() { IStaticConfiguration staticConfig = Resolve(); Directory.CreateDirectory(staticConfig.ServiceLogsFolder); Directory.CreateDirectory(staticConfig.OpenVpn.TlsExportCertFolder); } private void Start() { AppDomain.CurrentDomain.UnhandledException += OnUnhandledExceptionOccurredAsync; RegisterEvents(); Resolve().Clean(Resolve().ServiceLogsFolder, 10); VpnService vpnService = Resolve(); ServiceBase.Run(vpnService); vpnService.CancellationToken.WaitHandle.WaitOne(); Resolve().Info("=== Proton VPN Service has exited ==="); } private void RegisterEvents() { Resolve().SettingsChanged += (_, e) => { IEnumerable instances = Resolve>(); foreach (IServiceSettingsAware instance in instances) { instance.OnServiceSettingsChanged(e); } IssueReportingInitializer.SetEnabled(e.IsShareCrashReportsEnabled); }; } private async void OnUnhandledExceptionOccurredAsync(object sender, UnhandledExceptionEventArgs e) { IStaticConfiguration config = Resolve(); IOsProcesses processes = Resolve(); Resolve().Disconnect(); Resolve().Stop(); processes.KillProcesses(config.ClientName); } private static void SetDllDirectories() { Kernel32.SetDefaultDllDirectories(Kernel32.SetDefaultDllDirectoriesFlags.LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); } }