use crate::WSL_DISTRIBUTION_FLAGS;
use winapi::shared::ntdef::{PSTR, ULONG};
use winapi::um::combaseapi::CoTaskMemFree;
use std::ops::Drop;
use std::ptr::null_mut;
#[derive(Default)]
pub struct Configuration {
pub version: ULONG,
pub default_uid: ULONG,
pub flags: WSL_DISTRIBUTION_FLAGS,
pub default_environment_variables: EnvironmentVariables,
}
pub struct EnvironmentVariables {
pub(crate) array: *mut PSTR,
pub(crate) count: usize,
}
impl EnvironmentVariables {
pub fn new() -> Self { Self { array: null_mut(), count: 0 } }
pub fn len(&self) -> usize { self.count }
pub fn get(&self, index: usize) -> Option<(&[u8], &[u8])> {
if index >= self.count {
None
} else {
let st = unsafe { *self.array.add(index) };
for i in 0.. {
match unsafe { *st.add(i) } as _ {
b'\0' => return Some((unsafe { std::slice::from_raw_parts(st.cast(), i) }, &[])),
b'=' => for k in i.. {
if unsafe { *st.add(k) } != 0 { continue }
let all = unsafe { std::slice::from_raw_parts(st.cast(), k) };
let (k, v) = all.split_at(i);
return Some((k, &v[1..]));
},
_ => {},
}
}
None }
}
pub fn iter(&self) -> impl Iterator<Item = (&[u8], &[u8])> {
EnvironmentVariablesIter { vars: self, index: 0 }
}
}
impl Default for EnvironmentVariables {
fn default() -> Self { Self::new() }
}
impl Drop for EnvironmentVariables {
fn drop(&mut self) {
if !self.array.is_null() {
for i in 0..self.count {
unsafe { CoTaskMemFree((*self.array.add(i)).cast()) };
}
unsafe { CoTaskMemFree(self.array.cast()) }
}
self.array = null_mut();
self.count = 0;
}
}
impl<'e> IntoIterator for &'e EnvironmentVariables {
type Item = (&'e [u8], &'e [u8]);
type IntoIter = EnvironmentVariablesIter<'e>;
fn into_iter(self) -> Self::IntoIter {
EnvironmentVariablesIter { vars: self, index: 0 }
}
}
pub struct EnvironmentVariablesIter<'e> {
vars: &'e EnvironmentVariables,
index: usize,
}
impl<'e> Iterator for EnvironmentVariablesIter<'e> {
type Item = (&'e [u8], &'e [u8]);
fn next(&mut self) -> Option<Self::Item> {
let kv = self.vars.get(self.index)?;
self.index += 1;
Some(kv)
}
}