edlcodegen_core/
helpers.rs1use crate::{
5 edl_core_ffi::{GetProcessHeap, HeapAlloc, HeapFree},
6 edl_core_types::{AbiError, BOOL, E_FAIL, E_INVALIDARG, HEAP_ZERO_MEMORY, HRESULT, S_OK},
7};
8use core::ffi::c_void;
9
10pub fn abi_func_to_address(func_ptr: extern "system" fn(*mut c_void) -> *mut c_void) -> u64 {
11 func_ptr as *const () as u64
12}
13
14pub fn proc_address_to_isize(
15 func_ptr: unsafe extern "system" fn(*mut c_void) -> *mut c_void,
16) -> isize {
17 func_ptr as *const () as isize
18}
19
20#[inline(always)]
21pub fn hresult_to_pvoid(hr: i32) -> *mut c_void {
22 ((hr as u64) & 0x0000_0000_FFFF_FFFF) as usize as *mut c_void
23}
24
25#[inline(always)]
26pub fn pvoid_to_hresult(ptr: *mut c_void) -> i32 {
27 ((ptr as u64) & 0x0000_0000_FFFF_FFFF) as i32
28}
29
30pub fn allocate_memory(size: usize) -> *mut c_void {
31 unsafe { HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size) }
32}
33
34pub fn deallocate_memory(mem: *mut c_void) -> HRESULT {
35 if mem.is_null() {
36 return HRESULT(S_OK);
37 }
38
39 let res = unsafe { BOOL(HeapFree(GetProcessHeap(), 0, mem as *const c_void)) };
40
41 if !res.as_bool() {
42 return HRESULT(E_FAIL);
43 }
44
45 HRESULT(S_OK)
46}
47
48#[unsafe(no_mangle)]
50pub extern "system" fn allocate_memory_ffi(context: *mut c_void) -> *mut c_void {
51 allocate_memory(context as usize)
52}
53
54#[unsafe(no_mangle)]
56pub extern "system" fn deallocate_memory_ffi(memory: *mut c_void) -> *mut c_void {
57 let hr = deallocate_memory(memory);
58 hr.0 as *mut c_void
59}
60
61pub fn copy_slice_to_buffer<T>(buffer: *mut c_void, data: &[T]) -> Result<(), AbiError> {
63 if buffer.is_null() {
64 return Err(AbiError::Hresult(E_INVALIDARG));
65 }
66
67 unsafe {
69 core::ptr::copy_nonoverlapping(data.as_ptr(), buffer as *mut T, data.len());
70 }
71
72 Ok(())
73}
74
75#[macro_export]
76macro_rules! return_hr_as_pvoid {
77 ($result:expr) => {{
78 if let Some(err) = $result.err() {
79 return $crate::helpers::hresult_to_pvoid(err.to_hresult().0);
80 }
81
82 return $crate::edl_core_types::S_OK as *mut core::ffi::c_void;
83 }};
84}
85
86pub fn assign_if_some<T>(dst: Option<&mut T>, src: Option<T>) {
87 if let (Some(dst_obj), Some(src_obj)) = (dst, src) {
88 *dst_obj = src_obj;
89 }
90}