1use crate::pipe::{server_run, PipeStream};
15use log::error;
16use serde::{Deserialize, Serialize};
17use tokio::{
18 net::windows::named_pipe::ClientOptions,
19 time::{sleep, Duration},
20};
21use win_wrap::{
22 common::close_handle,
23 threading::{
24 get_current_process_id, open_process, wait_for_single_object, PROCESS_SYNCHRONIZE,
25 },
26};
27
28const PIPE_NAME: &str = r"\\.\PIPE\RIGELA_KILLER";
29
30#[derive(Deserialize, Serialize)]
31enum KillSignal {
32 Request,
33 Response(u32),
34}
35
36pub async fn wait_until_killed() {
37 let mut stream = server_run::<KillSignal>(PIPE_NAME).await;
38 while let Ok(_) = stream.recv().await {
39 break;
40 }
41 stream
42 .send(&KillSignal::Response(get_current_process_id()))
43 .await
44 .unwrap_or(());
45}
46
47pub async fn kill() {
48 let mut stream = match ClientOptions::new().open(PIPE_NAME) {
49 Ok(x) => PipeStream::new(x),
50 Err(_) => return,
51 };
52
53 if let Err(e) = stream.send(&KillSignal::Request).await {
54 error!("{}", e);
55 }
56 if let Ok(KillSignal::Response(pid)) = stream.recv().await {
57 if let Ok(handle) = open_process(PROCESS_SYNCHRONIZE, false, pid) {
58 wait_for_single_object(handle, 5000);
59 close_handle(handle);
60 }
61 }
62
63 sleep(Duration::from_millis(1000)).await;
64}