Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Rearrange Runtime #136

Merged
merged 7 commits into from
Apr 3, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Deny missing docs
  • Loading branch information
rylev committed Apr 2, 2020
commit da99a225cbc8c2a61ea579d759f267602d5750a2
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub trait IUnknown {

#[com_interface("EFF8970E-C50F-45E0-9284-291CE5A6F771")]
pub trait IAnimal: IUnknown {
fn eat(&self) -> HRESULT;
unsafe fn eat(&self) -> HRESULT;
}

```
Expand Down Expand Up @@ -85,21 +85,21 @@ pub struct BritishShortHairCat {

```rust
impl IDomesticAnimal for BritishShortHairCat {
fn train(&self) -> HRESULT {
unsafe fn train(&self) -> HRESULT {
println!("Training...");
NOERROR
}
}

impl ICat for BritishShortHairCat {
fn ignore_humans(&self) -> HRESULT {
unsafe fn ignore_humans(&self) -> HRESULT {
println!("Ignoring Humans...");
NOERROR
}
}

impl IAnimal for BritishShortHairCat {
fn eat(&self) -> HRESULT {
unsafe fn eat(&self) -> HRESULT {
println!("Eating...");
NOERROR
}
Expand Down
2 changes: 1 addition & 1 deletion macros/support/src/com_interface/iid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ pub fn generate(macro_attr: &TokenStream, interface_ident: &Ident) -> HelperToke
let data4_8 = LitInt::new(format!("0x{}", data4_8).as_str(), Span::call_site());

quote!(
#[allow(non_upper_case_globals)]
#[allow(non_upper_case_globals, missing_docs)]
pub const #iid_ident: com::sys::IID = com::sys::IID {
data1: #data1,
data2: #data2,
Expand Down
1 change: 1 addition & 0 deletions macros/support/src/com_interface/interface_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ fn gen_impl_method(interface_ident: &Ident, method: &TraitItemMethod) -> HelperT
}

quote!(
#[allow(missing_docs)]
#method_sig {
let #interface_ptr_ident = self.as_raw() as *mut #vptr_ident;
((**#interface_ptr_ident).#method_ident)(#(#params),*)
Expand Down
1 change: 1 addition & 0 deletions macros/support/src/com_interface/vptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub fn generate(interface_ident: &Ident) -> HelperTokenStream {
let vtable_ident = vtable::ident(&interface_ident.to_string());

quote!(
#[allow(missing_docs)]
pub type #vptr_ident = *const #vtable_ident;
)
}
Expand Down
2 changes: 1 addition & 1 deletion macros/support/src/com_interface/vtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub fn generate(interface: &ItemTrait) -> HelperTokenStream {
let methods = gen_vtable_methods(&interface);

quote!(
#[allow(non_snake_case)]
#[allow(non_snake_case, missing_docs)]
#[repr(C)]
#[derive(com::VTable)]
pub struct #vtable_ident {
Expand Down
3 changes: 3 additions & 0 deletions macros/support/src/com_interface/vtable_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub fn generate(item: &ItemStruct) -> HelperTokenStream {
let vtable_functions = gen_vtable_functions(item);
let initialized_vtable = gen_initialized_vtable(item);
quote! {
#[doc(hidden)]
#[macro_export]
macro_rules! #vtable_macro {
($class:ty, $offset:ty) => {{
Expand Down Expand Up @@ -100,6 +101,7 @@ fn gen_vtable_function(
});
let return_type = &fun.output;
quote! {
#[allow(missing_docs)]
unsafe extern "stdcall" fn #function_ident<C: #interface_ident, O: com::offset::Offset>(#(#params)*) #return_type {
let this = arg0.sub(O::VALUE) as *const C as *mut C;
(*this).#method_name(#(#args)*)
Expand All @@ -111,6 +113,7 @@ fn gen_initialized_vtable(item: &ItemStruct) -> HelperTokenStream {
let name = &item.ident;
let methods = gen_vtable_method_initialization(item);
quote! {
#[allow(missing_docs)]
#name {
#methods
}
Expand Down
6 changes: 3 additions & 3 deletions src/inproc.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::interfaces::iunknown::IUnknown;
use crate::interfaces::IUnknown;
use crate::sys::{
GetModuleFileNameA, GetModuleHandleA, RegCloseKey, RegCreateKeyExA, RegDeleteKeyA,
RegSetValueExA, ERROR_SUCCESS, HKEY, HRESULT, IID, LSTATUS, SELFREG_E_CLASS, S_OK,
Expand Down Expand Up @@ -178,6 +178,7 @@ pub fn initialize_class_object<T: IUnknown>(
}

#[macro_export]
#[doc(hidden)]
macro_rules! inproc_dll_module {
(($clsid_one:ident, $classtype_one:ty), $(($clsid:ident, $classtype:ty)),*) => {
#[no_mangle]
Expand Down Expand Up @@ -212,7 +213,6 @@ macro_rules! inproc_dll_module {
$crate::inproc::unregister_keys(registry_keys_to_remove)
}


fn get_relevant_registry_keys() -> Vec<com::inproc::RegistryKeyInfo> {
let file_path = com::inproc::get_dll_file_path();
vec![
Expand All @@ -238,5 +238,5 @@ macro_rules! inproc_dll_module {
)),*
]
}
}
};
}
5 changes: 5 additions & 0 deletions src/interfaces/iclass_factory.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! Everything related to the [IClassFactory](https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nn-unknwn-iclassfactory) COM interface
use crate::com_interface;
use crate::sys::{BOOL, FAILED, HRESULT, IID};
use std::ffi::c_void;
Expand All @@ -7,18 +8,22 @@ use crate::{
ComInterface, ComRc,
};

/// [IClassFactory](https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nn-unknwn-iclassfactory) COM interface
#[com_interface("00000001-0000-0000-c000-000000000046")]
pub trait IClassFactory: IUnknown {
/// the [CreateInstance](https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iclassfactory-createinstance) COM method
unsafe fn create_instance(
&self,
aggr: *mut IUnknownVPtr,
riid: *const IID,
ppv: *mut *mut c_void,
) -> HRESULT;
/// the [LockServer](https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iclassfactory-lockserver) COM method
unsafe fn lock_server(&self, increment: BOOL) -> HRESULT;
}

impl ComRc<dyn IClassFactory> {
/// Get an instance of the associated Co Class
pub fn get_instance<T: ComInterface + ?Sized>(&self) -> Option<ComRc<T>> {
let mut ppv = std::ptr::null_mut::<c_void>();
let aggr = std::ptr::null_mut();
Expand Down
3 changes: 3 additions & 0 deletions src/interfaces/iunknown.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
//! Everything related to the [IUnknown](https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nn-unknwn-iunknown) COM interface

use crate::com_interface;
use crate::sys::{HRESULT, IID};
use std::ffi::c_void;

/// [IUnknown](https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nn-unknwn-iunknown) COM interface
#[com_interface("00000000-0000-0000-C000-000000000046")]
pub trait IUnknown {
/// The COM [`QueryInterface` Method]
Expand Down
2 changes: 2 additions & 0 deletions src/interfaces/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Common COM interfaces including IUknown and IClassFactory

pub mod iclass_factory;
pub mod iunknown;

Expand Down
29 changes: 28 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
//! A helper crate for consuming and producing COM interfaces.
//!
//! # Example
//!
//! To work with a COM interface it must first be declared:
//!
//! ```rust
//! /// Define an IAnimal interface wit
//! #[com_interface("EFF8970E-C50F-45E0-9284-291CE5A6F771")]
//! pub trait IAnimal: IUnknown {
//! unsafe fn eat(&self) -> HRESULT;
//! }
//! ```
//!

#![deny(missing_docs)]

#[doc(hidden)]
pub mod inproc;
pub mod interfaces;
#[doc(hidden)]
pub mod offset;
mod ptr;
mod rc;
pub mod runtime;
pub mod sys;

use interfaces::iunknown::IUnknown;
use interfaces::IUnknown;
pub use ptr::ComPtr;
pub use rc::ComRc;
#[doc(inline)]
pub use sys::IID;

/// A COM compliant interface
Expand All @@ -20,10 +40,14 @@ pub use sys::IID;
/// * it is `#[repr(C)]`
/// * the type only contains `extern "stdcall" fn" definitions
pub unsafe trait ComInterface: IUnknown + 'static {
/// A COM compatible V-Table
type VTable;
/// The interface that this interface inherits from
type Super: ComInterface + ?Sized;
/// The associated id for this interface
const IID: IID;

/// Check whether a given IID is in the inheritance hierarchy of this interface
fn is_iid_in_inheritance_chain(riid: &com::IID) -> bool {
riid == &Self::IID
|| (Self::IID != <dyn IUnknown as ComInterface>::IID
Expand All @@ -41,10 +65,13 @@ pub unsafe trait ComInterface: IUnknown + 'static {
/// each of the COM Interfaces the class implements
pub unsafe trait CoClass: IUnknown {}

/// A COM interface that will be exposed in a COM server
pub trait ProductionComInterface<T: IUnknown>: ComInterface {
/// Get the vtable for a particular COM interface
fn vtable<O: offset::Offset>() -> Self::VTable;
}

#[doc(hidden)]
#[macro_export]
macro_rules! vtable {
($class:ident: $interface:ident, $offset:ident) => {
Expand Down
6 changes: 4 additions & 2 deletions src/rc.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::{interfaces::IUnknown, ComInterface, ComPtr};

/// A reference counted COM interface. This smart pointer type automatically
/// calls `AddRef` when cloned and `Release` when dropped.
/// A reference counted COM interface.
///
/// This smart pointer type automatically calls `AddRef` when cloned
/// and `Release` when dropped.
///
/// This is normally the correct way to interact with an interface. If for some
/// (usually unsafe) reason, you need to interact with an interface without
Expand Down
1 change: 1 addition & 0 deletions src/runtime.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![allow(missing_docs)]
use crate::sys::{
CoCreateInstance, CoGetClassObject, CoInitializeEx, CoUninitialize, CLSCTX_INPROC_SERVER,
COINIT_APARTMENTTHREADED, FAILED, HRESULT, IID, S_FALSE, S_OK,
Expand Down
25 changes: 25 additions & 0 deletions src/sys.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,58 @@
//! Types for interacting with COM related system APIs
use std::ffi::c_void;

/// A Windows result code
pub type HRESULT = i32;

/// Equivalent of the [FAILED macro](https://docs.microsoft.com/en-us/windows/win32/api/winerror/nf-winerror-failed)
#[allow(non_snake_case)]
pub fn FAILED(result: HRESULT) -> bool {
result < 0
}

/// BOOL type
pub type BOOL = i32;
/// LSTATUS type
pub type LSTATUS = i32;
/// HKEY type
pub type HKEY = *mut c_void;

/// No error
pub const S_OK: HRESULT = 0;
/// No error
pub const NOERROR: HRESULT = 0;
/// False
pub const S_FALSE: HRESULT = 1;
/// Argument was invalid
pub const E_INVALIDARG: HRESULT = -0x7FF8_FFA9;
/// No interface found
pub const E_NOINTERFACE: HRESULT = -0x7FFF_BFFE;
/// Invalid pointer
pub const E_POINTER: HRESULT = -0x7FFF_BFFD;
/// No aggregation for CoClass
pub const CLASS_E_NOAGGREGATION: HRESULT = -0x7FFB_FEF0;
/// Class is not available
pub const CLASS_E_CLASSNOTAVAILABLE: HRESULT = -0x7FFB_FEEF;
/// No error
pub const ERROR_SUCCESS: u32 = 0;
/// Registration error
pub const SELFREG_E_CLASS: HRESULT = -0x7FFB_FDFF;
/// A threaded apartment
pub const COINIT_APARTMENTTHREADED: u32 = 0x2;
/// A in process server
pub const CLSCTX_INPROC_SERVER: u32 = 0x1;

/// A unique identifier
#[repr(C)]
#[derive(Copy, Clone, PartialEq)]
pub struct IID {
#[allow(missing_docs)]
pub data1: u32,
#[allow(missing_docs)]
pub data2: u16,
#[allow(missing_docs)]
pub data3: u16,
#[allow(missing_docs)]
pub data4: [u8; 8],
}

Expand Down