use std::{fs, path::Path, process::Command, time::Instant};
fn main() {
if !wininskit::is_elevated() {
println!("run this elevated - the grant needs it");
return;
}
let root = std::env::temp_dir().join("wininskit-acl-timing");
println!("{:>9} {:>9} {:>9}", "files", "first", "again");
for count in [0usize, 1_000, 10_000, 40_000] {
let _ = fs::remove_dir_all(&root);
fill(&root, count);
let started = Instant::now();
let first = wininskit::grant_users_full_access(&root);
let first_seconds = started.elapsed().as_secs_f64();
let started = Instant::now();
let again = wininskit::grant_users_full_access(&root);
let again_seconds = started.elapsed().as_secs_f64();
match (first, again) {
(Ok(()), Ok(())) => {
println!("{count:>9} {first_seconds:>9.3} {again_seconds:>9.3}")
}
(first, again) => println!("{count:>9} {first:?} {again:?}"),
}
}
let child = root.join("created-after-the-grant.txt");
fs::write(&child, b"x").expect("write child");
println!("\ninherited entries on a file created after the grant:");
match Command::new("icacls").arg(&child).output() {
Ok(output) => {
let text = String::from_utf8_lossy(&output.stdout);
for line in text.lines().filter(|l| l.contains("(I)")) {
println!(" {}", line.trim());
}
println!(
" -> BUILTIN\\Users present: {}",
text.contains("BUILTIN\\Users")
);
}
Err(error) => println!(" could not run icacls: {error}"),
}
let _ = fs::remove_dir_all(&root);
}
fn fill(root: &Path, count: usize) {
fs::create_dir_all(root).expect("create root");
const PER_DIRECTORY: usize = 200;
for index in 0..count {
let directory = root.join(format!("d{:04}", index / PER_DIRECTORY));
if index.is_multiple_of(PER_DIRECTORY) {
fs::create_dir_all(&directory).expect("create directory");
}
fs::write(directory.join(format!("f{index:06}.bin")), b"x").expect("write file");
}
}