i2pd-launch 0.5.0-beta.12

Launches i2pd with clean state
#![allow(unsafe_code)]

use std::path::{Path, PathBuf};

use once_cell::sync::OnceCell;

use windows_sys::Win32::Foundation::BOOL;
use windows_sys::Win32::Foundation::{FALSE, TRUE};
use windows_sys::Win32::System::Console::SetConsoleCtrlHandler;
use windows_sys::Win32::System::Console::{CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, CTRL_SHUTDOWN_EVENT};

type DWORD = u32;

static HANDLER_DATA: OnceCell<PathBuf> = OnceCell::new();

/// Nastav cestu do OnceCell a zaregistruj Ctrl+Break handler
/// Volat přesně jednou před spuštěním vláken.
pub fn setup(path: &Path) {
   // Attempt to Init data
   match HANDLER_DATA.set(path.to_path_buf()) {
      Ok(()) =>
      // Set handler
      unsafe {
         SetConsoleCtrlHandler(Some(win32_handler), TRUE /* TRUE = add handler */);
      },
      Err(_) => eprintln!("warning: handler::setup() already called."),
   };
}

/// Win32 callback — signature přesně dle PHANDLER_ROUTINE.
/// BOOL WINAPI HandlerRoutine(DWORD dwCtrlType)
unsafe extern "system" fn win32_handler(ctrl_type: DWORD) -> BOOL {
   match ctrl_type {
      CTRL_CLOSE_EVENT | CTRL_LOGOFF_EVENT | CTRL_SHUTDOWN_EVENT => {
         // get() je lock-free, volitelně panickuj pokud setup nebyl zavolán
         if let Some(path) = HANDLER_DATA.get() {
            super::wipe_files(path);
         }
         TRUE // TRUE = zprávu jsme zpracovali, další handlery nevolat
      }
      _ => FALSE, // FALSE = předej dál
   }
}