use std::{
fs,
path::PathBuf,
process::exit,
sync::{
Arc,
atomic::{AtomicBool, Ordering},
},
thread,
time::Duration,
};
use clap::Parser;
use ib_shell::{
app,
hook::{HookConfig, inject::ShellInjector},
item::hook::{
display_name::DisplayNameHookConfig, inject::ShellItemHooks, prop::PropertyHookConfig,
},
};
use tracing::{error, info};
#[derive(Parser)]
#[command(name = "inject-hook")]
#[command(about = "Inject shell hooks into the process", long_about = None)]
struct Args {
#[arg(short, long)]
profile: String,
}
fn main() {
tracing_subscriber::fmt::init();
let args = Args::parse();
let dll_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent()
.unwrap()
.join("target")
.join(&args.profile)
.join("examples")
.join("hook.dll");
let log_path = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("hook.log");
dbg!(&log_path);
_ = fs::remove_file(&log_path);
let config = HookConfig::builder()
.item(
ib_shell::item::hook::HookConfig::builder()
.enabled(true)
.display_name(
DisplayNameHookConfig::builder()
.display_prefix(widestring::u16str!("ðŸ˜").as_slice())
.edit_prefix(widestring::u16str!("ðŸ˜").as_slice())
.build(),
)
.property({
let property = PropertyHookConfig::builder()
.str_prefix(widestring::u16str!("💢").as_slice());
#[cfg(feature = "everything")]
let property = property.size_from_everything(true);
property.build()
})
.log(log_path)
.build(),
)
.build();
let mut hooks = match ShellInjector::builder()
.dll_path(dll_path)
.config(config)
.apps(vec![app::EXPLORER])
.build()
{
Ok(hooks) => hooks,
Err(e) => {
error!("Error: {}", e);
exit(1);
}
};
info!("Press Ctrl+C to eject and exit...");
let running = Arc::new(AtomicBool::new(true));
let r = Arc::clone(&running);
ctrlc::set_handler(move || {
r.store(false, Ordering::SeqCst);
})
.expect("Error setting Ctrl-C handler");
while running.load(Ordering::SeqCst) {
thread::sleep(Duration::from_secs(1));
}
info!("Disabling hooks and ejecting DLL...");
hooks.eject();
}