use core::{ffi::c_void, mem::ManuallyDrop};
use moon_instructions::sidt;
use wdk::println;
#[repr(packed(2))]
struct IdtInfo {
limit: u16,
base: u64,
}
#[repr(C)]
union KIDTENTRY64 {
alignment: u64,
fields: ManuallyDrop<KIDTENTRY64Fields>,
}
#[repr(C)]
struct KIDTENTRY64Fields {
offset_low: u16,
selector: u16,
ist_index: u16,
offset_middle: u16,
offset_high: u32,
reserved1: u32,
}
#[repr(C)]
union TrapAddr {
all: u64,
fields: ManuallyDrop<TrapAddrFields>,
}
#[repr(C)]
struct TrapAddrFields {
low: u16,
mid: u16,
hig: u32,
}
#[derive(Debug)]
pub struct GetIdtFunctionAddressError {}
pub fn get_idt_function_address(index: u32) -> Result<*mut c_void, GetIdtFunctionAddressError> {
unsafe {
let mut idt_info: IdtInfo = core::mem::zeroed();
sidt(&mut idt_info as *mut _ as *mut _);
let base = idt_info.base as *mut u64;
let limit = idt_info.limit;
println!("idt base:{:p},limit:{:X}", base, limit);
let entry_ptr = base as *const KIDTENTRY64;
let entry = &*entry_ptr.add(index as _);
let trap = TrapAddr {
fields: ManuallyDrop::new(TrapAddrFields {
low: (*entry).fields.offset_low,
mid: (*entry).fields.offset_middle,
hig: (*entry).fields.offset_high,
}),
};
Ok(trap.all as _)
}
}