use crate::{WString, error::ErrorCode};
use mssf_com::{
FabricRuntime::IFabricConfigurationPackage,
FabricTypes::{
FABRIC_CONFIGURATION_PARAMETER, FABRIC_CONFIGURATION_PARAMETER_EX1,
FABRIC_CONFIGURATION_PARAMETER_LIST, FABRIC_CONFIGURATION_SECTION,
FABRIC_CONFIGURATION_SECTION_LIST,
},
};
use crate::{
iter::{FabricIter, FabricListAccessor},
strings::WStringWrap,
};
#[derive(Debug, Clone)]
pub struct ConfigurationPackage {
com: IFabricConfigurationPackage,
}
pub struct ConfigurationPackageDesc {
pub name: WString,
pub service_manifest_name: WString,
pub service_manifest_version: WString,
pub version: WString,
}
pub struct ConfigurationSettings {
pub sections: ConfigurationSectionList,
}
pub struct ConfigurationSectionList {
com: IFabricConfigurationPackage,
}
type ConfigurationSectionListIter<'a> =
FabricIter<'a, FABRIC_CONFIGURATION_SECTION, ConfigurationSection, ConfigurationSectionList>;
impl ConfigurationSectionList {
fn get_section_list_ref(&self) -> &FABRIC_CONFIGURATION_SECTION_LIST {
let raw = unsafe { self.com.get_Settings().as_ref().unwrap() };
unsafe { raw.Sections.as_ref().unwrap() }
}
pub fn iter(&self) -> ConfigurationSectionListIter<'_> {
ConfigurationSectionListIter::new(self, self)
}
}
impl FabricListAccessor<FABRIC_CONFIGURATION_SECTION> for ConfigurationSectionList {
fn get_count(&self) -> u32 {
self.get_section_list_ref().Count
}
fn get_first_item(&self) -> *const FABRIC_CONFIGURATION_SECTION {
self.get_section_list_ref().Items
}
}
impl From<IFabricConfigurationPackage> for ConfigurationPackage {
fn from(com: IFabricConfigurationPackage) -> Self {
Self { com }
}
}
impl From<ConfigurationPackage> for IFabricConfigurationPackage {
fn from(value: ConfigurationPackage) -> Self {
value.com
}
}
impl ConfigurationPackage {
pub fn get_description(&self) -> ConfigurationPackageDesc {
let raw = unsafe { self.com.get_Description().as_ref().unwrap() };
ConfigurationPackageDesc {
name: WStringWrap::from(raw.Name).into(),
service_manifest_name: WStringWrap::from(raw.ServiceManifestName).into(),
service_manifest_version: WStringWrap::from(raw.ServiceManifestVersion).into(),
version: WStringWrap::from(raw.Version).into(),
}
}
pub fn get_settings(&self) -> ConfigurationSettings {
ConfigurationSettings {
sections: ConfigurationSectionList {
com: self.com.clone(),
},
}
}
pub fn get_path(&self) -> WString {
let raw = unsafe { self.com.get_Path() };
WStringWrap::from(raw).into()
}
pub fn get_section(&self, section_name: &WString) -> crate::Result<ConfigurationSection> {
let raw = unsafe { self.com.GetSection(section_name.as_pcwstr()) }?;
let raw_ref = unsafe { raw.as_ref() };
match raw_ref {
Some(c) => {
let mut res = ConfigurationSection::from(c);
res.owner = Some(self.com.clone());
Ok(res)
}
None => Err(ErrorCode::E_POINTER.into()),
}
}
pub fn get_value(
&self,
section_name: &WString,
parameter_name: &WString,
) -> crate::Result<(WString, bool)> {
let mut is_encrypted: u8 = Default::default();
let raw = unsafe {
self.com.GetValue(
section_name.as_pcwstr(),
parameter_name.as_pcwstr(),
std::ptr::addr_of_mut!(is_encrypted),
)
}?;
Ok((WStringWrap::from(raw).into(), is_encrypted != 0))
}
pub fn decrypt_value(&self, encryptedvalue: &WString) -> crate::Result<WString> {
let s = unsafe { self.com.DecryptValue(encryptedvalue.as_pcwstr()) }?;
Ok(WStringWrap::from(&s).into())
}
}
pub struct ConfigurationSection {
owner: Option<IFabricConfigurationPackage>,
pub name: WString,
pub parameters: ConfigurationParameterList, }
impl From<&FABRIC_CONFIGURATION_SECTION> for ConfigurationSection {
fn from(value: &FABRIC_CONFIGURATION_SECTION) -> Self {
Self {
owner: None,
name: WStringWrap::from(value.Name).into(),
parameters: ConfigurationParameterList {
list: value.Parameters, },
}
}
}
type ConfigurationParameterListIter<'a> = FabricIter<
'a,
FABRIC_CONFIGURATION_PARAMETER,
ConfigurationParameter,
ConfigurationParameterList,
>;
pub struct ConfigurationParameterList {
list: *const FABRIC_CONFIGURATION_PARAMETER_LIST,
}
impl ConfigurationParameterList {
pub fn iter(&self) -> ConfigurationParameterListIter<'_> {
ConfigurationParameterListIter::new(self, self)
}
}
impl FabricListAccessor<FABRIC_CONFIGURATION_PARAMETER> for ConfigurationParameterList {
fn get_count(&self) -> u32 {
unsafe { self.list.as_ref().unwrap().Count }
}
fn get_first_item(&self) -> *const FABRIC_CONFIGURATION_PARAMETER {
unsafe { self.list.as_ref().unwrap().Items }
}
}
#[derive(Debug)]
pub struct ConfigurationParameter {
pub is_encrypted: bool,
pub must_overrride: bool,
pub name: WString,
pub value: WString,
pub r#type: WString,
}
impl From<&FABRIC_CONFIGURATION_PARAMETER> for ConfigurationParameter {
fn from(value: &FABRIC_CONFIGURATION_PARAMETER) -> Self {
let raw1 = unsafe {
(value.Reserved as *const FABRIC_CONFIGURATION_PARAMETER_EX1)
.as_ref()
.unwrap()
};
Self {
name: WStringWrap::from(value.Name).into(),
is_encrypted: value.IsEncrypted,
must_overrride: value.MustOverride,
value: WStringWrap::from(value.Value).into(),
r#type: WStringWrap::from(raw1.Type).into(),
}
}
}