Skip to main content

edlcodegen_core/
edl_core_ffi.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use crate::edl_core_types::{AbiError, BOOL, S_OK, WIN32_TRUE};
5use core::ffi::c_void;
6
7// The consuming crate will link these in based on which side of the trust boundary the crate exists
8// in. Either Kernel32 for the host or vertdll for the enclave.
9unsafe extern "system" {
10    pub fn CallEnclave(
11        lproutine: isize,
12        lpparameter: *const c_void,
13        fwaitforthread: i32,
14        lpreturnvalue: *mut *mut c_void,
15    ) -> i32;
16    pub fn GetLastError() -> u32;
17    pub fn GetProcessHeap() -> *mut c_void;
18    pub fn HeapAlloc(hheap: *mut c_void, dwflags: u32, dwbytes: usize) -> *mut c_void;
19    pub fn HeapFree(hheap: *mut c_void, dwflags: u32, lpmem: *const c_void) -> i32;
20}
21
22pub struct CallEnclaveInput {
23    func: isize,
24    in_params_ptr: *const c_void,
25}
26
27impl CallEnclaveInput {
28    pub const fn new(func: isize, ptr: *const c_void) -> Self {
29        Self {
30            func,
31            in_params_ptr: ptr,
32        }
33    }
34}
35pub fn call_enclave<T>(input: CallEnclaveInput) -> Result<T, AbiError>
36where
37    T: CallEnclaveReturn,
38{
39    let mut out: *mut c_void = core::ptr::null_mut();
40    let out_ptr: *mut *mut c_void = &mut out;
41    let func_res = unsafe {
42        BOOL(CallEnclave(
43            input.func,
44            input.in_params_ptr,
45            WIN32_TRUE.0,
46            out_ptr,
47        ))
48    };
49
50    if !func_res.as_bool() {
51        let last_err = unsafe { GetLastError() };
52        return Err(AbiError::Win32Error(last_err));
53    }
54
55    T::from_edl_framework(out)
56}
57
58pub trait CallEnclaveReturn: Sized {
59    fn from_edl_framework(ptr: *mut c_void) -> Result<Self, AbiError>;
60}
61
62impl CallEnclaveReturn for *mut c_void {
63    fn from_edl_framework(ptr: *mut c_void) -> Result<Self, AbiError> {
64        Ok(ptr)
65    }
66}
67impl CallEnclaveReturn for () {
68    fn from_edl_framework(ptr: *mut c_void) -> Result<Self, AbiError> {
69        let hr = crate::helpers::pvoid_to_hresult(ptr);
70
71        if hr == S_OK {
72            return Ok(());
73        }
74
75        Err(AbiError::Hresult(hr))
76    }
77}