windows-permissions 0.2.4

Safe Rust bindings to Windows permissions APIs
Documentation
use crate::constants::SecurityInformation;
use crate::utilities;
use crate::SecurityDescriptor;
use std::ffi::OsString;
use std::io;
use std::ptr::null_mut;
use std::slice;

/// Wraps [`ConvertSecurityDescriptorToStringSecurityDescriptorW`](https://docs.microsoft.com/en-us/windows/win32/api/sddl/nf-sddl-convertsecuritydescriptortostringsecuritydescriptorw)
///
/// This always uses `SDDL_REVISION_1` as the SDDL revision.
///
/// It may be more convenient to use [`SecurityDescriptor::as_sddl`] when all
/// security information is needed.
///
/// ```
/// use windows_permissions::wrappers::ConvertSecurityDescriptorToStringSecurityDescriptor;
/// use windows_permissions::{constants::SecurityInformation, LocalBox, SecurityDescriptor};
///
/// let string_sd = "G:S-1-5-10-20";
/// let sd: LocalBox<SecurityDescriptor> = string_sd.parse().unwrap();
///
/// let string_sd2 = ConvertSecurityDescriptorToStringSecurityDescriptor(
///     &sd,
///     SecurityInformation::all()
/// ).unwrap();
///
/// assert_eq!(string_sd, &string_sd2);
/// ```
#[allow(non_snake_case)]
pub fn ConvertSecurityDescriptorToStringSecurityDescriptor(
    sd: &SecurityDescriptor,
    info: SecurityInformation,
) -> io::Result<OsString> {
    let mut buf_ptr: *mut u16 = null_mut();
    let mut buf_len: u32 = 0;

    // If success, buf_ptr must be LocalFree'd
    let result = unsafe {
        winapi::shared::sddl::ConvertSecurityDescriptorToStringSecurityDescriptorW(
            sd as *const _ as *mut _,
            winapi::shared::sddl::SDDL_REVISION_1.into(),
            info.bits(),
            &mut buf_ptr,
            &mut buf_len,
        )
    };

    if result == 0 {
        // Failed, no need to free
        return Err(io::Error::last_os_error());
    }

    let slice = unsafe { slice::from_raw_parts(buf_ptr, buf_len as usize) };

    let string = utilities::os_from_buf(slice);

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

    Ok(string)
}