1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
use crate::utilities;
use crate::Sid;
use std::ffi::OsString;
use std::io;
use std::ptr::null_mut;

/// Wraps [`ConvertSidToStringSidW`](https://docs.microsoft.com/en-us/windows/win32/api/sddl/nf-sddl-convertsidtostringsidw).
///
/// ```
/// use windows_permissions::{LocalBox, Sid, wrappers::ConvertSidToStringSid};
///
/// let string_sid = "S-1-5-123-456-789";
/// let sid: LocalBox<Sid> = string_sid.parse().unwrap();
/// let string_sid2 = ConvertSidToStringSid(&sid).unwrap();
///
/// assert_eq!(string_sid, string_sid2);
/// ```
#[allow(non_snake_case)]
pub fn ConvertSidToStringSid(sid: &Sid) -> io::Result<OsString> {
    let mut buf_ptr: *mut u16 = null_mut();
    let result = unsafe {
        winapi::shared::sddl::ConvertSidToStringSidW(sid as *const _ as *mut _, &mut buf_ptr)
    };

    if result == 0 {
        // Failed! No need to clean up
        Err(io::Error::last_os_error())
    } else {
        // Success! Copy the string into an OsString and free the original buffer
        let nul_pos = unsafe { utilities::search_buffer(&0x00, buf_ptr) };
        let slice_with_nul = unsafe { std::slice::from_raw_parts(buf_ptr, nul_pos + 1) };

        let os_string = utilities::os_from_buf(slice_with_nul);

        unsafe { winapi::um::winbase::LocalFree(buf_ptr as *mut _) };

        Ok(os_string)
    }
}