1use std::fmt::Display;
8use std::sync::Mutex;
9use lazy_static::lazy_static;
10use sysinfo::{Signal, System};
11
12#[cfg(target_os = "windows")]
13use sysinfo::{Pid};
14
15#[cfg(target_os = "windows")]
16use winreg::RegKey;
17#[cfg(target_os = "windows")]
18use winreg::enums::{KEY_READ, HKEY_USERS};
19pub type ProcResult<T> = crate::PisPasResult<T>;
20
21#[derive(Debug, Default, Clone)]
22pub struct UserInfo {
23 pub pid: u32,
24 pub sesion_id: u32,
25 pub sid: String,
26 pub username: String,
27 pub userprofile: String,
28 pub desktop: String,
29 pub path: String,
30 pub tmp_path: String,
31}
32impl Display for UserInfo {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 write!(f, "pid: {}, sid: {}, username: {}, userprofile: {}, desktop: {}, path: {}", self.pid, self.sid, self.username, self.userprofile, self.desktop, self.path)
35 }
36}
37
38pub fn kill_process_by_name(name: &str) {
41 let mut system = System::new_all();
42 system.refresh_processes();
43
44 for process in system.processes_by_name(name) {
47 tracing::info!("{} {}", process.pid(), process.name());
48 if process.kill_with(Signal::Kill).is_none() {
49 tracing::error!("This signal isn't supported on this platform");
50 }
51 }
52}
53
54#[cfg(target_os = "windows")]
55fn get_user_desktop(sid: &str) -> ProcResult<String> {
56 let pispas_users = RegKey::predef(HKEY_USERS);
57 let full_key_path = format!(r"{}\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders", sid);
58
59 match pispas_users.open_subkey_with_flags(&full_key_path, KEY_READ) {
60 Ok(profiles_key) => {
61 if let Ok(desktop_path) = profiles_key.get_value("Desktop") {
62 return Ok(desktop_path);
63 }
64 }
65 Err(e) => {
66 tracing::error!("Error opening user's Shell Folders key: {}", e);
67 return Err(e.into());
68 }
69 }
70 Err(anyhow::anyhow!("Error getting user's desktop path"))
71}
72
73#[cfg(target_os = "windows")]
74pub fn get_temp(sid: &str, userprofile: &str) -> ProcResult<String> {
75 let pispas_users = RegKey::predef(HKEY_USERS);
76 match pispas_users.open_subkey_with_flags(&format!(r"{}\{}", sid, crate::ENVIRONMENT), KEY_READ) {
77 Ok(enviroment_key) => {
78 if let Ok(temp_path) = enviroment_key.get_value::<String, &str>(crate::TMP_KEY) {
79 let temp_path = temp_path.replace(format!("%{}%", crate::USER_PROFILE_KEY).as_str(), userprofile);
80 tracing::info!("temp_path: {}", temp_path);
81 return Ok(temp_path);
82 }
83 }
84 Err(e) => {
85 tracing::error!("Error opening user's Shell Folders key: {}", e);
86 return Err(e.into());
87 }
88 }
89 Err(anyhow::anyhow!("Error getting user's temp path"))
90}
91
92#[cfg(target_os = "windows")]
93pub fn get_user_profile(sid: &str) -> ProcResult<String> {
94 let pispas_users = RegKey::predef(HKEY_USERS);
95
96 match pispas_users.open_subkey_with_flags(&format!(r"{}\{}", sid, crate::VOLATILE_ENVIRONMENT), KEY_READ) {
97 Ok(profiles_key) => {
98 if let Ok(userprofile) = profiles_key.get_value::<String, &str>(crate::USER_PROFILE_KEY) {
99 return Ok(userprofile);
100 }
101 }
102 Err(e) => {
103 tracing::error!("Error opening user's Volatile Environment key: {}", e);
104 return Err(e.into());
105 }
106 }
107 Err(anyhow::anyhow!("Error getting user's userprofile path"))
108}
109
110#[cfg(target_os = "windows")]
111pub fn get_parent_pid(pid: u32) -> Pid {
112 let system = System::new_all();
113 if let Some(process) = system.process(Pid::from_u32(pid)) {
114 process.parent().map_or(Pid::from_u32(0) , |parent| parent)
115 } else {
116 Pid::from_u32(0)
117 }
118}
119#[cfg(target_os = "windows")]
120pub fn get_parent_info(pid: u32) -> ProcResult<UserInfo> {
121 let system = System::new_all();
122 let mut user_info = UserInfo::default();
123 let parent_pid = get_parent_pid(pid);
124 tracing::info!("tray get_parent_info: {}", parent_pid);
125 match system.process(parent_pid) {
126 Some(pparent) => {
127 if let Some(sid) = pparent.user_id() {
128 user_info.sid = sid.to_string();
129 }
130 if let Some(sesion_id) = pparent.session_id() {
131 user_info.sesion_id = sesion_id.as_u32();
132 }
133 tracing::info!("tray get_parent_info: {}", pparent.name());
134 match pparent.user_id() {
135 Some(sid) => {
136 let sid = sid.to_string();
137 user_info.pid = pparent.pid().as_u32();
138 if let Ok(user_profile) = get_user_profile(sid.as_str()) {
139 user_info.username = get_username_from_path(&user_profile).unwrap_or_default();
140 user_info.userprofile = user_profile.clone();
141 if let Ok(desktop) = get_user_desktop(sid.as_str()) {
142 user_info.desktop = desktop.clone();
143 }
144 if let Ok(tmp_path) = get_temp(sid.as_str(), &user_profile) {
145 user_info.tmp_path = tmp_path.clone();
146 } else{
147 user_info.tmp_path = std::env::temp_dir().to_str().unwrap_or_default().to_string();
148 }
149 }
150 if let Ok(path) = get_process_path(user_info.pid) {
151 tracing::info!("parent path => {}", path);
152 user_info.path = path.clone();
153 }
154 tracing::info!("parent info => {:?}", user_info);
155 }
156 None => {
157 tracing::error!("SID pparent not found");
158 }
159 }
160 }
161 None => {
162 tracing::error!("parent process not found");
163 }
164 }
165 tracing::info!("parent user_info => {:?}", user_info);
166 Ok(user_info)
167}
168
169#[cfg(target_os = "windows")]
170pub fn get_process_path(pid: u32) -> ProcResult<String>{
171 let system = System::new_all();
172 if let Some(process) = system.process(Pid::from_u32(pid)) {
173 if let Some(path) = process.exe().expect("Can't get process path").to_str().map(|s| s.to_string()) {
174 return Ok(path);
175 }
176 else{
177 return Err(anyhow::anyhow!("Error getting process path"));
178 }
179 } else {
180 Err(anyhow::anyhow!("Process not found"))
181 }
182}
183
184#[cfg(target_os = "windows")]
185pub fn get_username_from_path(path: &str) -> ProcResult<String> {
186 let username= std::path::Path::new(&path).file_name().unwrap().to_string_lossy().to_string();
187 return Ok(username);
188}
189lazy_static! {
190 static ref GRAND_FATHER_INFO: Mutex<Option<UserInfo>> = Mutex::new(None);
191}
192
193#[cfg(target_os = "windows")]
194pub fn get_gran_father_info() -> ProcResult<UserInfo> {
195 tracing::info!("call get_gran_father_info");
196 let mut info = GRAND_FATHER_INFO.lock().unwrap(); if let Some(grand_father_info) = info.as_ref() {
199 return Ok(grand_father_info.clone());
201 }
202
203 let mut pid = std::process::id();
204 tracing::info!("pid => {}", pid);
205
206 loop {
207 match get_parent_info(pid) {
208 Ok(parent_info) => {
209 if parent_info.pid != 0 {
210 pid = parent_info.pid;
211
212 if parent_info.path.contains("explorer.exe")
214 || parent_info.path.contains("SystemSettings.exe")
215 || parent_info.path.contains("services.exe")
216 {
217 *info = Some(parent_info.clone());
219 return Ok(parent_info);
220 } else {
221 tracing::info!("Parent Info => {:?}", parent_info);
222 }
223 } else {
224 return Err(anyhow::anyhow!("No parent process found"));
226 }
227 }
228 Err(e) => {
229 tracing::error!("Error getting parent info: {}", e);
230 return Err(e);
231 }
232 }
233 }
234}