This commit is contained in:
Ryan Levick 2019-08-29 19:52:32 +02:00
Родитель 002dc2db23
Коммит 4c44fa889d
5 изменённых файлов: 27 добавлений и 30 удалений

Просмотреть файл

@ -24,7 +24,7 @@ use winapi::{
use com::{ use com::{
create_instance, initialize_ex, uninitialize, ComInterface, ComPtr, IClassFactory, IUnknown, create_instance, initialize_ex, uninitialize, ComInterface, ComPtr, IClassFactory, IUnknown,
IID_ICLASS_FACTORY, IID_ICLASSFACTORY,
}; };
use interface::{ISuperman, CLSID_CLARK_KENT_CLASS}; use interface::{ISuperman, CLSID_CLARK_KENT_CLASS};

Просмотреть файл

@ -1,4 +1,4 @@
use com::{ComInterface, ComPtr, IUnknown, IUnknownMethods}; use com::{ComInterface, ComPtr, IUnknown, IUnknownVTable};
use winapi::shared::guiddef::IID; use winapi::shared::guiddef::IID;
use winapi::um::winnt::HRESULT; use winapi::um::winnt::HRESULT;
@ -30,6 +30,7 @@ pub trait ISuperman: IUnknown {
} }
unsafe impl ComInterface for ISuperman { unsafe impl ComInterface for ISuperman {
type VTable = ISupermanVTable;
const IID: IID = IID_ISUPERMAN; const IID: IID = IID_ISUPERMAN;
} }
@ -38,31 +39,29 @@ pub type ISupermanVPtr = *const ISupermanVTable;
impl<T: ISuperman + ComInterface + ?Sized> ISuperman for ComPtr<T> { impl<T: ISuperman + ComInterface + ?Sized> ISuperman for ComPtr<T> {
fn take_input(&mut self, in_var: u32) -> HRESULT { fn take_input(&mut self, in_var: u32) -> HRESULT {
let itf_ptr = self.into_raw() as *mut ISupermanVPtr; let itf_ptr = self.into_raw() as *mut ISupermanVPtr;
unsafe { ((**itf_ptr).1.TakeInput)(itf_ptr, in_var) } unsafe { ((**itf_ptr).TakeInput)(itf_ptr, in_var) }
} }
fn populate_output(&mut self, out_var: *mut u32) -> HRESULT { fn populate_output(&mut self, out_var: *mut u32) -> HRESULT {
let itf_ptr = self.into_raw() as *mut ISupermanVPtr; let itf_ptr = self.into_raw() as *mut ISupermanVPtr;
unsafe { ((**itf_ptr).1.PopulateOutput)(itf_ptr, out_var) } unsafe { ((**itf_ptr).PopulateOutput)(itf_ptr, out_var) }
} }
fn mutate_and_return(&mut self, in_out_var: *mut u32) -> HRESULT { fn mutate_and_return(&mut self, in_out_var: *mut u32) -> HRESULT {
let itf_ptr = self.into_raw() as *mut ISupermanVPtr; let itf_ptr = self.into_raw() as *mut ISupermanVPtr;
unsafe { ((**itf_ptr).1.MutateAndReturn)(itf_ptr, in_out_var) } unsafe { ((**itf_ptr).MutateAndReturn)(itf_ptr, in_out_var) }
} }
fn take_input_ptr(&mut self, in_ptr_var: *const u32) -> HRESULT { fn take_input_ptr(&mut self, in_ptr_var: *const u32) -> HRESULT {
let itf_ptr = self.into_raw() as *mut ISupermanVPtr; let itf_ptr = self.into_raw() as *mut ISupermanVPtr;
unsafe { ((**itf_ptr).1.TakeInputPtr)(itf_ptr, in_ptr_var) } unsafe { ((**itf_ptr).TakeInputPtr)(itf_ptr, in_ptr_var) }
} }
} }
#[repr(C)]
pub struct ISupermanVTable(pub IUnknownMethods, pub ISupermanMethods);
#[allow(non_snake_case)] #[allow(non_snake_case)]
#[repr(C)] #[repr(C)]
pub struct ISupermanMethods { pub struct ISupermanVTable {
pub base: IUnknownVTable,
pub TakeInput: unsafe extern "stdcall" fn(*mut ISupermanVPtr, in_var: u32) -> HRESULT, pub TakeInput: unsafe extern "stdcall" fn(*mut ISupermanVPtr, in_var: u32) -> HRESULT,
pub PopulateOutput: pub PopulateOutput:
unsafe extern "stdcall" fn(*mut ISupermanVPtr, out_var: *mut u32) -> HRESULT, unsafe extern "stdcall" fn(*mut ISupermanVPtr, out_var: *mut u32) -> HRESULT,

Просмотреть файл

@ -1,7 +1,5 @@
use com::{IUnknown, IUnknownMethods, IUnknownVPtr, IID_IUNKNOWN}; use com::{IUnknown, IUnknownVPtr, IUnknownVTable, IID_IUNKNOWN};
use interface::isuperman::{ use interface::isuperman::{ISuperman, ISupermanVPtr, ISupermanVTable, IID_ISUPERMAN};
ISuperman, ISupermanMethods, ISupermanVPtr, ISupermanVTable, IID_ISUPERMAN,
};
use winapi::{ use winapi::{
ctypes::c_void, ctypes::c_void,
@ -29,7 +27,7 @@ impl Drop for ClarkKent {
impl ISuperman for ClarkKent { impl ISuperman for ClarkKent {
fn take_input(&mut self, in_var: u32) -> HRESULT { fn take_input(&mut self, in_var: u32) -> HRESULT {
println!("Received Input! Input is: {}", in_var); println!("Received Input! Input is: {}", in_var);
if (in_var > 5) { if in_var > 5 {
return E_FAIL; return E_FAIL;
} }
@ -55,7 +53,7 @@ impl ISuperman for ClarkKent {
fn take_input_ptr(&mut self, in_ptr_var: *const u32) -> HRESULT { fn take_input_ptr(&mut self, in_ptr_var: *const u32) -> HRESULT {
unsafe { unsafe {
let in_ptr_var = *in_ptr_var; let in_ptr_var = *in_ptr_var;
if (in_ptr_var > 5) { if in_ptr_var > 5 {
return E_FAIL; return E_FAIL;
} }
} }
@ -155,18 +153,19 @@ impl ClarkKent {
println!("Allocating new Vtable..."); println!("Allocating new Vtable...");
/* Initialising VTable for ISuperman */ /* Initialising VTable for ISuperman */
let iunknown = IUnknownMethods { let iunknown = IUnknownVTable {
QueryInterface: query_interface, QueryInterface: query_interface,
Release: release, Release: release,
AddRef: add_ref, AddRef: add_ref,
}; };
let isuperman = ISupermanMethods { let isuperman = ISupermanVTable {
base: iunknown,
TakeInput: take_input, TakeInput: take_input,
PopulateOutput: populate_output, PopulateOutput: populate_output,
MutateAndReturn: mutate_and_return, MutateAndReturn: mutate_and_return,
TakeInputPtr: take_input_ptr, TakeInputPtr: take_input_ptr,
}; };
let vptr = Box::into_raw(Box::new(ISupermanVTable(iunknown, isuperman))); let vptr = Box::into_raw(Box::new(isuperman));
ClarkKent { ClarkKent {
inner: vptr, inner: vptr,

Просмотреть файл

@ -1,7 +1,7 @@
use crate::clark_kent::ClarkKent; use crate::clark_kent::ClarkKent;
use com::{ use com::{
IClassFactory, IClassFactoryMethods, IClassFactoryVPtr, IClassFactoryVTable, IUnknown, IClassFactory, IClassFactoryVPtr, IClassFactoryVTable, IUnknown, IUnknownVPtr, IUnknownVTable,
IUnknownMethods, IUnknownVPtr, IID_ICLASS_FACTORY, IID_IUNKNOWN, IID_ICLASSFACTORY, IID_IUNKNOWN,
}; };
use winapi::{ use winapi::{
@ -35,12 +35,12 @@ impl IClassFactory for ClarkKentClass {
ck.add_ref(); ck.add_ref();
let hr = ck.query_interface(riid, ppv); let hr = ck.query_interface(riid, ppv);
ck.release(); ck.release();
let ptr = Box::into_raw(ck); let _ptr = Box::into_raw(ck);
hr hr
} }
fn lock_server(&mut self, increment: BOOL) -> HRESULT { fn lock_server(&mut self, _increment: BOOL) -> HRESULT {
println!("LockServer called"); println!("LockServer called");
S_OK S_OK
} }
@ -51,7 +51,7 @@ impl IUnknown for ClarkKentClass {
/* TODO: This should be the safe wrapper. You shouldn't need to write unsafe code here. */ /* TODO: This should be the safe wrapper. You shouldn't need to write unsafe code here. */
unsafe { unsafe {
let riid = &*riid; let riid = &*riid;
if IsEqualGUID(riid, &IID_IUNKNOWN) || IsEqualGUID(riid, &IID_ICLASS_FACTORY) { if IsEqualGUID(riid, &IID_IUNKNOWN) || IsEqualGUID(riid, &IID_ICLASSFACTORY) {
*ppv = self as *const _ as *mut c_void; *ppv = self as *const _ as *mut c_void;
self.add_ref(); self.add_ref();
NOERROR NOERROR
@ -126,16 +126,17 @@ unsafe extern "stdcall" fn lock_server(this: *mut IClassFactoryVPtr, increment:
impl ClarkKentClass { impl ClarkKentClass {
pub(crate) fn new() -> ClarkKentClass { pub(crate) fn new() -> ClarkKentClass {
println!("Allocating new Vtable for ClarkKentClass..."); println!("Allocating new Vtable for ClarkKentClass...");
let iunknown = IUnknownMethods { let iunknown = IUnknownVTable {
QueryInterface: query_interface, QueryInterface: query_interface,
Release: release, Release: release,
AddRef: add_ref, AddRef: add_ref,
}; };
let iclassfactory = IClassFactoryMethods { let iclassfactory = IClassFactoryVTable {
base: iunknown,
CreateInstance: create_instance, CreateInstance: create_instance,
LockServer: lock_server, LockServer: lock_server,
}; };
let vptr = Box::into_raw(Box::new(IClassFactoryVTable(iunknown, iclassfactory))); let vptr = Box::into_raw(Box::new(iclassfactory));
ClarkKentClass { ClarkKentClass {
inner: vptr, inner: vptr,
ref_count: 0, ref_count: 0,

Просмотреть файл

@ -1,8 +1,7 @@
use com::{ use com::{
class_inproc_key_path, class_key_path, failed, get_dll_file_path, register_keys, class_inproc_key_path, class_key_path, failed, get_dll_file_path, register_keys,
unregister_keys, IUnknown, IUnknownVPtr, RegistryKeyInfo, unregister_keys, IUnknown, RegistryKeyInfo,
}; };
use std::ffi::{CStr, CString};
use winapi::shared::{ use winapi::shared::{
guiddef::{IsEqualGUID, REFCLSID, REFIID}, guiddef::{IsEqualGUID, REFCLSID, REFIID},
minwindef::LPVOID, minwindef::LPVOID,
@ -14,7 +13,6 @@ pub use interface::CLSID_CLARK_KENT_CLASS;
mod clark_kent; mod clark_kent;
mod clark_kent_class; mod clark_kent_class;
use clark_kent::ClarkKent;
use clark_kent_class::ClarkKentClass; use clark_kent_class::ClarkKentClass;
#[no_mangle] #[no_mangle]