feat: finish cdylib ffi and improve ffi C header
This commit is contained in:
66
wfassoc-cdylib/src/ffi_types.rs
Normal file
66
wfassoc-cdylib/src/ffi_types.rs
Normal file
@@ -0,0 +1,66 @@
|
||||
//! The module including all FFI types used by this crate.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use num_enum::TryFromPrimitive;
|
||||
|
||||
// region: HICON
|
||||
|
||||
/// The type representing Win32 HICON handle.
|
||||
///
|
||||
/// In theory, we can fetch HICON type from "windows_sys" crate.
|
||||
/// However, I don't want to add it as this crate's dependency,
|
||||
/// because I don't use anything within it except this type.
|
||||
/// So I check Microsoft document, re-define it in there for this crate.
|
||||
/// Reference: https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types
|
||||
pub type HICON = *mut c_void;
|
||||
|
||||
/// The invalid value of Win32 HICON handle.
|
||||
///
|
||||
/// The same reason like [HICON] to re-define it in there.
|
||||
pub const INVALID_ICON: HICON = std::ptr::null_mut();
|
||||
|
||||
// endregion
|
||||
|
||||
// region: Scope
|
||||
|
||||
/// The FFI wrapper for [wfassoc::Scope].
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone, TryFromPrimitive)]
|
||||
pub enum Scope {
|
||||
User = 0,
|
||||
System = 1,
|
||||
}
|
||||
|
||||
impl From<Scope> for wfassoc::Scope {
|
||||
fn from(value: Scope) -> Self {
|
||||
match value {
|
||||
Scope::User => wfassoc::Scope::User,
|
||||
Scope::System => wfassoc::Scope::System,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region: View
|
||||
|
||||
/// The FFI wrapper for [wfassoc::View].
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone, TryFromPrimitive)]
|
||||
pub enum View {
|
||||
User = 0,
|
||||
System = 1,
|
||||
Hybrid = 2,
|
||||
}
|
||||
|
||||
impl From<View> for wfassoc::View {
|
||||
fn from(value: View) -> Self {
|
||||
match value {
|
||||
View::User => wfassoc::View::User,
|
||||
View::System => wfassoc::View::System,
|
||||
View::Hybrid => wfassoc::View::Hybrid,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
@@ -1,16 +1,13 @@
|
||||
mod cstr_ffi;
|
||||
mod last_error;
|
||||
mod object_pool;
|
||||
mod ffi_types;
|
||||
|
||||
use num_enum::TryFromPrimitive;
|
||||
use object_pool::ObjectPool;
|
||||
use std::sync::{LazyLock, RwLock};
|
||||
use thiserror::Error as TeError;
|
||||
use wfassoc::highlevel::{Program, Schema};
|
||||
|
||||
pub use cstr_ffi::CStyleString;
|
||||
pub use object_pool::Token;
|
||||
|
||||
// region: Error
|
||||
|
||||
/// Error occurs in this crate.
|
||||
@@ -198,39 +195,9 @@ static EXT_STATUE_POOL: LazyLock<RwLock<ObjectPool<wfassoc::highlevel::ProgramEx
|
||||
|
||||
// region: Exposed Types
|
||||
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone, TryFromPrimitive)]
|
||||
pub enum Scope {
|
||||
User = 0,
|
||||
System = 1,
|
||||
}
|
||||
|
||||
impl From<Scope> for wfassoc::Scope {
|
||||
fn from(value: Scope) -> Self {
|
||||
match value {
|
||||
Scope::User => wfassoc::Scope::User,
|
||||
Scope::System => wfassoc::Scope::System,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone, TryFromPrimitive)]
|
||||
pub enum View {
|
||||
User = 0,
|
||||
System = 1,
|
||||
Hybrid = 2,
|
||||
}
|
||||
|
||||
impl From<View> for wfassoc::View {
|
||||
fn from(value: View) -> Self {
|
||||
match value {
|
||||
View::User => wfassoc::View::User,
|
||||
View::System => wfassoc::View::System,
|
||||
View::Hybrid => wfassoc::View::Hybrid,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub use cstr_ffi::CStyleString;
|
||||
pub use object_pool::Token;
|
||||
pub use ffi_types::{HICON, Scope, View};
|
||||
|
||||
// endregion
|
||||
|
||||
@@ -273,6 +240,11 @@ pub extern "C" fn WFHasPrivilege() -> bool {
|
||||
wfassoc::win32::utilities::has_privilege()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn WFInvalidToken() -> Token {
|
||||
object_pool::invalid_token()
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region: Schema
|
||||
@@ -581,11 +553,16 @@ pub extern "C" fn WFProgramQueryExt(
|
||||
let pool = pull_reader!(PROGRAM_POOL)?;
|
||||
let program = pool.get(in_program)?;
|
||||
let view = resolve_enum!(View, in_view)?;
|
||||
|
||||
|
||||
let ext_status = program.query_ext(view.into(), in_index)?;
|
||||
todo!();
|
||||
let mut pool = pull_writer!(EXT_STATUE_POOL)?;
|
||||
Ok(pool.allocate(ext_status)?)
|
||||
let token = match ext_status {
|
||||
Some(ext_status) => {
|
||||
let mut pool = pull_writer!(EXT_STATUE_POOL)?;
|
||||
pool.allocate(ext_status)?
|
||||
},
|
||||
None => object_pool::invalid_token(),
|
||||
};
|
||||
Ok(token)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -600,22 +577,33 @@ pub extern "C" fn WFExtStatusDestroy(in_ext_status: in_param_ty!(Token)) -> bool
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn WFExtStatuGetName(in_ext_status: in_param_ty!(Token), out_name: out_param_ty!(CStyleString)) -> bool {
|
||||
pub extern "C" fn WFExtStatuGetName(
|
||||
in_ext_status: in_param_ty!(Token),
|
||||
out_name: out_param_ty!(CStyleString),
|
||||
) -> bool {
|
||||
cffi_wrapper!(|in_ext_status: Token| -> (out_name: CStyleString) {
|
||||
let pool = pull_reader!(EXT_STATUE_POOL)?;
|
||||
let ext_status = pool.get(in_ext_status)?;
|
||||
|
||||
|
||||
cstr_ffi::set_ffi_string(ext_status.get_name())?;
|
||||
Ok(cstr_ffi::get_ffi_string())
|
||||
})
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn WFExtStatuGetIcon(in_ext_status: in_param_ty!(Token), out_icon: out_param_ty!(HICON)) -> bool {
|
||||
pub extern "C" fn WFExtStatuGetIcon(
|
||||
in_ext_status: in_param_ty!(Token),
|
||||
out_icon: out_param_ty!(HICON),
|
||||
) -> bool {
|
||||
cffi_wrapper!(|in_ext_status: Token| -> (out_icon: HICON) {
|
||||
let pool = pull_reader!(EXT_STATUE_POOL)?;
|
||||
let ext_status = pool.get(in_ext_status)?;
|
||||
Ok(ext_status.get_icon())
|
||||
|
||||
let icon = match ext_status.get_icon() {
|
||||
Some(icon) => icon.get_icon(),
|
||||
None => ffi_types::INVALID_ICON,
|
||||
};
|
||||
Ok(icon)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,14 @@ pub enum Error {
|
||||
/// The token for fetching object in [ObjectPool].
|
||||
pub type Token = u64;
|
||||
|
||||
/// Get the invalid token.
|
||||
///
|
||||
/// Invalid token is always invalid for fetching object in pool,
|
||||
/// And can be useful in FFI scenario.
|
||||
pub fn invalid_token() -> Token {
|
||||
DefaultKey::null().data().as_ffi()
|
||||
}
|
||||
|
||||
/// A pool for managing objects with unique tokens.
|
||||
///
|
||||
/// It is highly suggested to use this pool with [std::sync::RwLock] guard.
|
||||
|
||||
Reference in New Issue
Block a user