ferrisetw 1.2.0

Basically a KrabsETW rip-off written in Rust
Documentation
use core::ffi::c_void;
use std::str::Utf8Error;
use windows::core::PSTR;
use windows::Win32::Foundation::{LocalFree, HLOCAL, PSID};
use windows::Win32::Security::Authorization::ConvertSidToStringSidA;

/// SDDL native error
#[derive(Debug)]
pub enum SddlNativeError {
    /// Represents an error parsing the SID into a String
    SidParseError(Utf8Error),
    /// Represents an standard IO Error
    IoError(std::io::Error),
}

impl From<Utf8Error> for SddlNativeError {
    fn from(err: Utf8Error) -> Self {
        SddlNativeError::SidParseError(err)
    }
}

impl std::fmt::Display for SddlNativeError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::SidParseError(e) => write!(f, "sid parse error {}", e),
            Self::IoError(e) => write!(f, "i/o error {}", e),
        }
    }
}

pub(crate) type SddlResult<T> = Result<T, SddlNativeError>;

pub fn convert_sid_to_string(sid: *const c_void) -> SddlResult<String> {
    let mut tmp = PSTR::null();
    unsafe {
        let not_really_mut_sid = sid.cast_mut(); // That's OK to widely change the constness here, because it will be given as an _input_ of ConvertSidToStringSidA and will not be modified
        if ConvertSidToStringSidA(PSID(not_really_mut_sid), &mut tmp).is_err() {
            return Err(SddlNativeError::IoError(std::io::Error::last_os_error()));
        }

        let sid_string = std::ffi::CStr::from_ptr(tmp.0.cast()).to_str()?.to_owned();

        if LocalFree(HLOCAL(tmp.0.cast())) != HLOCAL(std::ptr::null_mut()) {
            return Err(SddlNativeError::IoError(std::io::Error::last_os_error()));
        }

        Ok(sid_string)
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_convert_string_to_sid() {
        let sid: Vec<u8> = vec![1, 2, 0, 0, 0, 0, 0, 5, 0x20, 0, 0, 0, 0x20, 2, 0, 0];
        if let Ok(string_sid) = convert_sid_to_string(sid.as_ptr() as *const c_void) {
            assert_eq!(string_sid, "S-1-5-32-544");
        }
    }
}