use std::ffi::{c_char, c_int, c_uint, c_void};
use std::mem::{offset_of, size_of};
pub type HookId = u32;
pub type HookRemovalFn = unsafe extern "C" fn(id: HookId, context: *mut c_void);
const _: () = {
const SLOT: usize = size_of::<*const ()>();
macro_rules! assert_slot {
($field:ident, $slot:expr) => {
assert!(offset_of!(IKHookVtable, $field) == $slot * SLOT);
};
}
assert!(size_of::<Action>() == 1);
assert!(size_of::<IKHook>() == SLOT);
assert_slot!(setup_hook, 0);
assert_slot!(setup_virtual_hook, 1);
assert_slot!(remove_hook, 2);
assert_slot!(get_context_ptr, 3);
assert_slot!(get_original_function, 4);
assert_slot!(get_original_value_ptr, 5);
assert_slot!(get_override_value_ptr, 6);
assert_slot!(get_current_value_ptr, 7);
assert_slot!(destroy_return_value, 8);
assert_slot!(find_original, 9);
assert_slot!(find_original_virtual, 10);
assert_slot!(do_recall, 11);
assert_slot!(save_return_value, 12);
assert_slot!(lookup_signature, 13);
assert_slot!(was_original_function_skipped, 14);
assert!(size_of::<IKHookVtable>() == 15 * SLOT);
};
pub const INVALID_HOOK: HookId = HookId::MAX;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct Action(pub u8);
impl Action {
pub const IGNORE: Self = Self(0);
pub const OVERRIDE: Self = Self(1);
pub const SUPERSEDE: Self = Self(2);
}
#[repr(C)]
pub struct IKHook {
pub vtable: *const IKHookVtable,
}
#[repr(C)]
pub struct IKHookVtable {
pub setup_hook: unsafe extern "C" fn(
*mut IKHook,
function: *mut c_void,
context: *mut c_void,
removed_function: *mut c_void,
pre: *mut c_void,
post: *mut c_void,
make_return: *mut c_void,
make_call_original: *mut c_void,
stack_size: c_uint,
async_: bool,
) -> HookId,
pub setup_virtual_hook: unsafe extern "C" fn(
*mut IKHook,
vtable: *mut *mut c_void,
index: c_int,
context: *mut c_void,
removed_function: *mut c_void,
pre: *mut c_void,
post: *mut c_void,
make_return: *mut c_void,
make_call_original: *mut c_void,
stack_size: c_uint,
async_: bool,
) -> HookId,
pub remove_hook: unsafe extern "C" fn(
*mut IKHook,
id: HookId,
async_: bool,
hook_removal_fn: Option<HookRemovalFn>,
context: *mut c_void,
),
pub get_context_ptr: unsafe extern "C" fn(*mut IKHook) -> *mut c_void,
pub get_original_function: unsafe extern "C" fn(*mut IKHook) -> *mut c_void,
pub get_original_value_ptr: unsafe extern "C" fn(*mut IKHook) -> *mut c_void,
pub get_override_value_ptr: unsafe extern "C" fn(*mut IKHook) -> *mut c_void,
pub get_current_value_ptr: unsafe extern "C" fn(*mut IKHook, pop: bool) -> *mut c_void,
pub destroy_return_value: unsafe extern "C" fn(*mut IKHook),
pub find_original: unsafe extern "C" fn(*mut IKHook, function: *mut c_void) -> *mut c_void,
pub find_original_virtual:
unsafe extern "C" fn(*mut IKHook, vtable: *mut *mut c_void, index: c_int) -> *mut c_void,
pub do_recall: unsafe extern "C" fn(
*mut IKHook,
action: Action,
ptr_to_return: *mut c_void,
return_size: usize,
init_op: *mut c_void,
deinit_op: *mut c_void,
) -> *mut c_void,
pub save_return_value: unsafe extern "C" fn(
*mut IKHook,
action: Action,
ptr_to_return: *mut c_void,
return_size: usize,
init_op: *mut c_void,
deinit_op: *mut c_void,
original: bool,
),
pub lookup_signature: unsafe extern "C" fn(
*mut IKHook,
start: *mut c_void,
size: usize,
signature: *const c_char,
) -> *mut c_void,
pub was_original_function_skipped: unsafe extern "C" fn(*mut IKHook) -> bool,
}