yalishandar / tasklist-rs

Get the process name or process id on windows
19 stars 3 forks source link

Correctly Decode from Windows-1252 to UTF8 #3

Closed FrostyCoolSlug closed 11 months ago

FrostyCoolSlug commented 11 months ago

This fixes an issue with process names being assumed to be UTF-8.

An issue came up when using the library from a user who was running a process that had the Trade Mark symbol (™) in the process name. The issue was the that character was ASCII 153, and not UTF-8, causing the code to panic.

This change adds the 'encoding' crate, and correctly converts Windows-1252 encoded Strings from the process name into UTF-8 encoded strings.

FrostyCoolSlug commented 11 months ago

There might be a way to convert it inside the Windows API itself (or get the value as a wchar_t, which can be parsed as utf16), but I couldn't see anything obvious.

yalishandar commented 11 months ago

I‘m trying to change PROCESSENTRY32 struct as PROCESSENTRY32W and then use the OsString::from_wide() function to convert [u16; 260] as string.

fn get_proc_name(name: [u16; 260]) -> String {
    use std::os::windows::ffi::OsStringExt;
    let s = std::ffi::OsString::from_wide(&name);
    s.into_string().unwrap()
}
pub unsafe fn tasklist() -> HashMap<String, u32> {
    use std::mem::size_of;
    use std::mem::zeroed;
    use windows::Win32::Foundation::CloseHandle;
    use windows::Win32::System::Diagnostics::ToolHelp::{
        CreateToolhelp32Snapshot, Process32FirstW, Process32NextW, PROCESSENTRY32W,
        TH32CS_SNAPPROCESS,
    };

    let mut temp: HashMap<String, u32> = HashMap::new();

    let h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0).unwrap();

    let mut process = zeroed::<PROCESSENTRY32W>();
    process.dwSize = size_of::<PROCESSENTRY32W>() as u32;

    if Process32FirstW(h, &mut process).as_bool() {
        loop {
            if Process32NextW(h, &mut process).as_bool() {
                temp.insert(
                    get_proc_name(process.szExeFile),
                    process.th32ProcessID.try_into().unwrap(),
                );
            } else {
                break;
            }
        }
    }

    CloseHandle(h);
    temp
}

Does this code work correctly in your environment?

yalishandar commented 11 months ago

It looks like the problem has been solved by doing this. Now: image Before: image