mssf_core/runtime/
config.rs

1// ------------------------------------------------------------
2// Copyright (c) Microsoft Corporation.  All rights reserved.
3// Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4// ------------------------------------------------------------
5
6use crate::{WString, error::ErrorCode};
7use mssf_com::{
8    FabricRuntime::IFabricConfigurationPackage,
9    FabricTypes::{
10        FABRIC_CONFIGURATION_PARAMETER, FABRIC_CONFIGURATION_PARAMETER_EX1,
11        FABRIC_CONFIGURATION_PARAMETER_LIST, FABRIC_CONFIGURATION_SECTION,
12        FABRIC_CONFIGURATION_SECTION_LIST,
13    },
14};
15
16use crate::{
17    iter::{FabricIter, FabricListAccessor},
18    strings::WStringWrap,
19};
20
21#[derive(Debug, Clone)]
22pub struct ConfigurationPackage {
23    com: IFabricConfigurationPackage,
24}
25
26pub struct ConfigurationPackageDesc {
27    pub name: WString,
28    pub service_manifest_name: WString,
29    pub service_manifest_version: WString,
30    pub version: WString,
31}
32
33pub struct ConfigurationSettings {
34    pub sections: ConfigurationSectionList,
35}
36
37// FABRIC_CONFIGURATION_SECTION_LIST
38pub struct ConfigurationSectionList {
39    com: IFabricConfigurationPackage,
40}
41
42type ConfigurationSectionListIter<'a> =
43    FabricIter<'a, FABRIC_CONFIGURATION_SECTION, ConfigurationSection, ConfigurationSectionList>;
44
45impl ConfigurationSectionList {
46    fn get_section_list_ref(&self) -> &FABRIC_CONFIGURATION_SECTION_LIST {
47        let raw = unsafe { self.com.get_Settings().as_ref().unwrap() };
48        unsafe { raw.Sections.as_ref().unwrap() }
49    }
50    pub fn iter(&self) -> ConfigurationSectionListIter<'_> {
51        ConfigurationSectionListIter::new(self, self)
52    }
53}
54
55impl FabricListAccessor<FABRIC_CONFIGURATION_SECTION> for ConfigurationSectionList {
56    fn get_count(&self) -> u32 {
57        self.get_section_list_ref().Count
58    }
59
60    fn get_first_item(&self) -> *const FABRIC_CONFIGURATION_SECTION {
61        self.get_section_list_ref().Items
62    }
63}
64
65impl From<IFabricConfigurationPackage> for ConfigurationPackage {
66    fn from(com: IFabricConfigurationPackage) -> Self {
67        Self { com }
68    }
69}
70
71impl From<ConfigurationPackage> for IFabricConfigurationPackage {
72    fn from(value: ConfigurationPackage) -> Self {
73        value.com
74    }
75}
76
77impl ConfigurationPackage {
78    pub fn get_description(&self) -> ConfigurationPackageDesc {
79        let raw = unsafe { self.com.get_Description().as_ref().unwrap() };
80
81        ConfigurationPackageDesc {
82            name: WStringWrap::from(raw.Name).into(),
83            service_manifest_name: WStringWrap::from(raw.ServiceManifestName).into(),
84            service_manifest_version: WStringWrap::from(raw.ServiceManifestVersion).into(),
85            version: WStringWrap::from(raw.Version).into(),
86        }
87    }
88
89    pub fn get_settings(&self) -> ConfigurationSettings {
90        ConfigurationSettings {
91            sections: ConfigurationSectionList {
92                com: self.com.clone(),
93            },
94        }
95    }
96
97    pub fn get_path(&self) -> WString {
98        let raw = unsafe { self.com.get_Path() };
99        WStringWrap::from(raw).into()
100    }
101
102    pub fn get_section(&self, section_name: &WString) -> crate::Result<ConfigurationSection> {
103        let raw = unsafe { self.com.GetSection(section_name.as_pcwstr()) }?;
104        let raw_ref = unsafe { raw.as_ref() };
105        match raw_ref {
106            Some(c) => {
107                let mut res = ConfigurationSection::from(c);
108                res.owner = Some(self.com.clone());
109                Ok(res)
110            }
111            None => Err(ErrorCode::E_POINTER.into()),
112        }
113    }
114
115    pub fn get_value(
116        &self,
117        section_name: &WString,
118        parameter_name: &WString,
119    ) -> crate::Result<(WString, bool)> {
120        let mut is_encrypted: u8 = Default::default();
121        let raw = unsafe {
122            self.com.GetValue(
123                section_name.as_pcwstr(),
124                parameter_name.as_pcwstr(),
125                std::ptr::addr_of_mut!(is_encrypted),
126            )
127        }?;
128        Ok((WStringWrap::from(raw).into(), is_encrypted != 0))
129    }
130
131    pub fn decrypt_value(&self, encryptedvalue: &WString) -> crate::Result<WString> {
132        let s = unsafe { self.com.DecryptValue(encryptedvalue.as_pcwstr()) }?;
133        Ok(WStringWrap::from(&s).into())
134    }
135}
136
137// Note: parameter has ptr to raw memory into
138// Com obj, but this relationship is not tracked by lifetime,
139// So when using config section and parameter list,
140// make sure the com obj is still in scope.
141// TODO: find a way to make lifetime work.
142pub struct ConfigurationSection {
143    owner: Option<IFabricConfigurationPackage>,
144    pub name: WString,
145    pub parameters: ConfigurationParameterList, // Note: the list has no lifetime tracking
146}
147
148impl From<&FABRIC_CONFIGURATION_SECTION> for ConfigurationSection {
149    fn from(value: &FABRIC_CONFIGURATION_SECTION) -> Self {
150        Self {
151            owner: None,
152            name: WStringWrap::from(value.Name).into(),
153            parameters: ConfigurationParameterList {
154                list: value.Parameters, // TODO: ownership/lifetime escaped here.
155            },
156        }
157    }
158}
159
160// FABRIC_CONFIGURATION_PARAMETER_LIST
161// TODO: the owner is not accessible.
162type ConfigurationParameterListIter<'a> = FabricIter<
163    'a,
164    FABRIC_CONFIGURATION_PARAMETER,
165    ConfigurationParameter,
166    ConfigurationParameterList,
167>;
168
169pub struct ConfigurationParameterList {
170    list: *const FABRIC_CONFIGURATION_PARAMETER_LIST,
171}
172
173impl ConfigurationParameterList {
174    pub fn iter(&self) -> ConfigurationParameterListIter<'_> {
175        ConfigurationParameterListIter::new(self, self)
176    }
177}
178
179impl FabricListAccessor<FABRIC_CONFIGURATION_PARAMETER> for ConfigurationParameterList {
180    fn get_count(&self) -> u32 {
181        unsafe { self.list.as_ref().unwrap().Count }
182    }
183
184    fn get_first_item(&self) -> *const FABRIC_CONFIGURATION_PARAMETER {
185        unsafe { self.list.as_ref().unwrap().Items }
186    }
187}
188
189#[derive(Debug)]
190pub struct ConfigurationParameter {
191    pub is_encrypted: bool,
192    pub must_overrride: bool,
193    pub name: WString,
194    pub value: WString,
195    pub r#type: WString,
196}
197
198impl From<&FABRIC_CONFIGURATION_PARAMETER> for ConfigurationParameter {
199    fn from(value: &FABRIC_CONFIGURATION_PARAMETER) -> Self {
200        let raw1 = unsafe {
201            (value.Reserved as *const FABRIC_CONFIGURATION_PARAMETER_EX1)
202                .as_ref()
203                .unwrap()
204        };
205        Self {
206            name: WStringWrap::from(value.Name).into(),
207            is_encrypted: value.IsEncrypted,
208            must_overrride: value.MustOverride,
209            value: WStringWrap::from(value.Value).into(),
210            r#type: WStringWrap::from(raw1.Type).into(),
211        }
212    }
213}