rigela_utils/
killer.rs

1/*
2 * Copyright (c) 2024. The RigelA open source project team and
3 * its contributors reserve all rights.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and limitations under the License.
12 */
13
14use 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}