use std::ffi::OsStr;
use std::io;
use std::iter;
use std::os::windows::ffi::OsStrExt;
use std::os::windows::io::AsRawHandle;
use std::ptr;
use windows_sys::Win32::Foundation::ERROR_SUCCESS;
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FWPM_SUBLAYER0;
use windows_sys::Win32::NetworkManagement::WindowsFilteringPlatform::FwpmSubLayerAdd0;
use windows_sys::core::GUID;
use crate::transaction::Transaction;
#[derive(Clone)]
pub struct SubLayerBuilder<Name> {
sublayer: FWPM_SUBLAYER0,
display_data_name_buffer: Vec<u16>,
display_data_desc_buffer: Vec<u16>,
_pd: std::marker::PhantomData<Name>,
}
#[doc(hidden)]
#[derive(Default)]
pub struct SubLayerBuilderMissingName;
#[doc(hidden)]
pub struct SubLayerBuilderHasName;
impl Default for SubLayerBuilder<SubLayerBuilderMissingName> {
fn default() -> SubLayerBuilder<SubLayerBuilderMissingName> {
SubLayerBuilder {
sublayer: Default::default(),
display_data_name_buffer: Default::default(),
display_data_desc_buffer: Default::default(),
_pd: Default::default(),
}
}
}
impl<Name> SubLayerBuilder<Name> {
pub fn name(mut self, name: impl AsRef<OsStr>) -> SubLayerBuilder<SubLayerBuilderHasName> {
self.display_data_name_buffer = name
.as_ref()
.encode_wide()
.chain(iter::once(0u16))
.collect();
self.sublayer.displayData.name = self.display_data_name_buffer.as_mut_ptr();
SubLayerBuilder {
sublayer: self.sublayer,
display_data_name_buffer: self.display_data_name_buffer,
display_data_desc_buffer: self.display_data_desc_buffer,
_pd: std::marker::PhantomData,
}
}
pub fn description(mut self, desc: impl AsRef<OsStr>) -> SubLayerBuilder<Name> {
self.display_data_desc_buffer = desc
.as_ref()
.encode_wide()
.chain(iter::once(0u16))
.collect();
self.sublayer.displayData.description = self.display_data_desc_buffer.as_mut_ptr();
SubLayerBuilder {
sublayer: self.sublayer,
display_data_name_buffer: self.display_data_name_buffer,
display_data_desc_buffer: self.display_data_desc_buffer,
_pd: std::marker::PhantomData,
}
}
pub fn weight(mut self, weight: u16) -> SubLayerBuilder<Name> {
self.sublayer.weight = weight;
self
}
pub fn guid(mut self, guid: GUID) -> SubLayerBuilder<Name> {
self.sublayer.subLayerKey = guid;
self
}
}
impl SubLayerBuilder<SubLayerBuilderHasName> {
pub fn add<'a>(&self, transaction: &Transaction<'a>) -> io::Result<()> {
let status = unsafe {
FwpmSubLayerAdd0(
transaction.engine.as_raw_handle(),
&self.sublayer,
ptr::null_mut(),
)
};
if status != ERROR_SUCCESS {
return Err(io::Error::from_raw_os_error(status as i32));
}
Ok(())
}
}