use alloc::vec::Vec;
use wdk_sys::{
ntddk::{IoCreateSymbolicLink, IoDeleteSymbolicLink, RtlInitUnicodeString},
NT_SUCCESS, UNICODE_STRING,
};
pub struct SymbolicLink {
name: Vec<u16>,
}
impl SymbolicLink {
pub fn new(name: &str, target: &str) -> Result<Self, &'static str> {
let name_utf16: Vec<u16> = name.encode_utf16().chain(core::iter::once(0)).collect();
Self::create(&name_utf16, target)?;
Ok(Self { name: name_utf16 })
}
pub fn create(name: &Vec<u16>, target: &str) -> Result<(), &'static str> {
let mut name_us: UNICODE_STRING = unsafe { core::mem::zeroed() };
let mut target_us: UNICODE_STRING = unsafe { core::mem::zeroed() };
let target_utf16: Vec<u16> = target.encode_utf16().chain(core::iter::once(0)).collect();
unsafe {
RtlInitUnicodeString(&mut name_us, name.as_ptr());
RtlInitUnicodeString(&mut target_us, target_utf16.as_ptr());
}
let status = unsafe { IoCreateSymbolicLink(&mut name_us, &mut target_us) };
if !NT_SUCCESS(status) {
return Err("CreateSymbolicLink error");
}
Ok(())
}
fn delete(name: &Vec<u16>) {
let mut name_us: UNICODE_STRING = unsafe { core::mem::zeroed() };
unsafe {
RtlInitUnicodeString(&mut name_us, name.as_ptr());
let _ = IoDeleteSymbolicLink(&mut name_us);
}
}
}
impl Drop for SymbolicLink {
fn drop(&mut self) {
Self::delete(&self.name);
}
}