Only interface and com crates compile

This commit is contained in:
adrianwithah 2019-08-15 17:37:40 +01:00
Родитель 13df1e17cf
Коммит 2c873c0a7c
11 изменённых файлов: 189 добавлений и 423 удалений

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

@ -1,6 +1,6 @@
use com::{ComInterface, ComPtr, IUnknownMethods, RawIUnknown};
use winapi::shared::{guiddef::IID, winerror::HRESULT};
use winapi::shared::guiddef::IID;
use com::{ComInterface, ComPtr, IUnknown, IUnknownMethods};
use winapi::um::winnt::HRESULT;
pub const IID_IANIMAL: IID = IID {
Data1: 0xeff8970e,
@ -9,50 +9,20 @@ pub const IID_IANIMAL: IID = IID {
Data4: [0x92, 0x84, 0x29, 0x1c, 0xe5, 0xa6, 0xf7, 0x71],
};
#[repr(C)]
pub struct IAnimal {
inner: RawIAnimal,
}
impl IAnimal {
pub fn eat(&mut self) {
self.inner.eat()
}
pub fn query_interface<T: ComInterface>(&mut self) -> Option<ComPtr<T>> {
let inner: &mut RawIUnknown = self.inner.as_mut();
inner.query_interface()
}
pub trait IAnimal: IUnknown {
fn eat(&mut self) -> HRESULT;
}
unsafe impl ComInterface for IAnimal {
const IID: IID = IID_IANIMAL;
}
#[repr(C)]
pub struct RawIAnimal {
vtable: *const IAnimalVTable,
}
pub type IAnimalVPtr = *const IAnimalVTable;
impl RawIAnimal {
pub fn eat(&mut self) {
let _ = unsafe { self.raw_eat() };
}
unsafe fn raw_eat(&mut self) -> HRESULT {
((*self.vtable).1.Eat)(self as *mut RawIAnimal)
}
}
impl std::convert::AsRef<RawIUnknown> for RawIAnimal {
fn as_ref(&self) -> &RawIUnknown {
unsafe { &*(self as *const RawIAnimal as *const RawIUnknown) }
}
}
impl std::convert::AsMut<RawIUnknown> for RawIAnimal {
fn as_mut(&mut self) -> &mut RawIUnknown {
unsafe { &mut *(self as *mut RawIAnimal as *mut RawIUnknown) }
impl <T: IAnimal + ComInterface + ?Sized> IAnimal for ComPtr<T> {
fn eat(&mut self) -> HRESULT {
let itf_ptr = self.into_raw() as *mut IAnimalVPtr;
unsafe { ((**itf_ptr).1.Eat)(itf_ptr) }
}
}
@ -62,5 +32,5 @@ pub struct IAnimalVTable(IUnknownMethods, IAnimalMethods);
#[allow(non_snake_case)]
#[repr(C)]
pub struct IAnimalMethods {
pub Eat: unsafe extern "stdcall" fn(*mut RawIAnimal) -> HRESULT,
pub Eat: unsafe extern "stdcall" fn(*mut IAnimalVPtr) -> HRESULT,
}

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

@ -1,5 +1,5 @@
use super::ianimal::{IAnimalMethods, RawIAnimal};
use com::{ComInterface, ComPtr, IUnknownMethods, RawIUnknown};
use super::ianimal::{IAnimalMethods};
use com::{ComInterface, ComPtr, IUnknownMethods, IUnknown};
use winapi::shared::{guiddef::IID, winerror::HRESULT};
@ -10,70 +10,27 @@ pub const IID_ICAT: IID = IID {
Data4: [0x8d, 0x92, 0xd2, 0x74, 0xc7, 0x57, 0x8b, 0x53],
};
#[repr(C)]
pub struct ICat {
pub inner: RawICat,
}
impl ICat {
pub fn query_interface<T: ComInterface>(&mut self) -> Option<ComPtr<T>> {
let inner: &mut RawIUnknown = self.inner.as_mut();
inner.query_interface()
}
pub fn eat(&mut self) {
let inner: &mut RawIAnimal = self.inner.as_mut();
inner.eat()
}
pub fn ignore_humans(&mut self) {
let _ = unsafe { self.inner.raw_ignore_humans() };
}
pub trait ICat: IUnknown {
fn ignore_humans(&mut self) -> HRESULT;
}
unsafe impl ComInterface for ICat {
const IID: IID = IID_ICAT;
}
#[repr(C)]
pub struct RawICat {
pub vtable: *const ICatVTable,
}
pub type ICatVPtr = *const ICatVTable;
impl RawICat {
pub unsafe fn raw_ignore_humans(&mut self) -> HRESULT {
((*self.vtable).2.IgnoreHumans)(self as *mut RawICat)
}
}
impl std::convert::AsRef<RawIUnknown> for RawICat {
fn as_ref(&self) -> &RawIUnknown {
unsafe { &*(self as *const RawICat as *const RawIUnknown) }
}
}
impl std::convert::AsMut<RawIUnknown> for RawICat {
fn as_mut(&mut self) -> &mut RawIUnknown {
unsafe { &mut *(self as *mut RawICat as *mut RawIUnknown) }
}
}
impl std::convert::AsRef<RawIAnimal> for RawICat {
fn as_ref(&self) -> &RawIAnimal {
unsafe { &*(self as *const RawICat as *const RawIAnimal) }
}
}
impl std::convert::AsMut<RawIAnimal> for RawICat {
fn as_mut(&mut self) -> &mut RawIAnimal {
unsafe { &mut *(self as *mut RawICat as *mut RawIAnimal) }
impl <T: ICat + ComInterface + ?Sized> ICat for ComPtr<T> {
fn ignore_humans(&mut self) -> HRESULT {
let itf_ptr = self.into_raw() as *mut ICatVPtr;
unsafe { ((**itf_ptr).2.IgnoreHumans)(itf_ptr) }
}
}
#[allow(non_snake_case)]
#[repr(C)]
pub struct ICatMethods {
pub IgnoreHumans: unsafe extern "stdcall" fn(*mut RawICat) -> HRESULT,
pub IgnoreHumans: unsafe extern "stdcall" fn(*mut ICatVPtr) -> HRESULT,
}
#[repr(C)]

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

@ -1,4 +1,4 @@
use com::{ComInterface, ComPtr, IClassFactoryMethods, IUnknownMethods, RawIUnknown};
use com::{ComInterface, ComPtr, IClassFactoryMethods, IUnknownMethods, IUnknown,};
use winapi::shared::guiddef::IID;
@ -9,42 +9,15 @@ pub const IID_ICAT_CLASS: IID = IID {
Data4: [0x8d, 0x92, 0xd2, 0x74, 0xc7, 0x57, 0x8b, 0x53],
};
#[repr(C)]
pub struct ICatClass {
pub inner: RawICatClass,
}
impl ICatClass {
pub fn query_interface<T: ComInterface>(&mut self) -> Option<ComPtr<T>> {
let inner: &mut RawIUnknown = self.inner.as_mut();
inner.query_interface()
}
}
pub trait ICatClass: IUnknown {}
unsafe impl ComInterface for ICatClass {
const IID: IID = IID_ICAT_CLASS;
}
#[repr(C)]
pub struct RawICatClass {
pub vtable: *const ICatClassVTable,
}
pub type ICatClassVPtr = *const ICatClassVTable;
impl std::convert::AsRef<RawIUnknown> for RawICatClass {
fn as_ref(&self) -> &RawIUnknown {
unsafe { &*(self as *const RawICatClass as *const RawIUnknown) }
}
}
impl std::convert::AsMut<RawIUnknown> for RawICatClass {
fn as_mut(&mut self) -> &mut RawIUnknown {
unsafe { &mut *(self as *mut RawICatClass as *mut RawIUnknown) }
}
}
#[allow(non_snake_case)]
#[repr(C)]
pub struct ICatClassMethods {}
impl <T: ICatClass + ComInterface + ?Sized> ICatClass for ComPtr<T> {}
#[repr(C)]
pub struct ICatClassVTable(
@ -52,3 +25,9 @@ pub struct ICatClassVTable(
pub IClassFactoryMethods,
pub ICatClassMethods,
);
#[allow(non_snake_case)]
#[repr(C)]
pub struct ICatClassMethods {}

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

@ -1,5 +1,5 @@
use super::ianimal::{IAnimalMethods, RawIAnimal};
use com::{ComInterface, ComPtr, IUnknownMethods, RawIUnknown};
use super::ianimal::{IAnimalMethods, IAnimal,};
use com::{ComInterface, ComPtr, IUnknownMethods, IUnknown,};
use winapi::shared::{guiddef::IID, winerror::HRESULT};
@ -10,70 +10,27 @@ pub const IID_IDOMESTIC_ANIMAL: IID = IID {
Data4: [0x93, 0x3e, 0x9c, 0xf7, 0xb2, 0x34, 0x59, 0xe8],
};
#[repr(C)]
pub struct IDomesticAnimal {
pub inner: RawIDomesticAnimal,
}
impl IDomesticAnimal {
pub fn query_interface<T: ComInterface>(&mut self) -> Option<ComPtr<T>> {
let inner: &mut RawIUnknown = self.inner.as_mut();
inner.query_interface()
}
pub fn eat(&mut self) {
let inner: &mut RawIAnimal = self.inner.as_mut();
inner.eat()
}
pub fn train(&mut self) {
let _ = unsafe { self.inner.raw_train() };
}
pub trait IDomesticAnimal: IAnimal {
fn train(&mut self) -> HRESULT;
}
unsafe impl ComInterface for IDomesticAnimal {
const IID: IID = IID_IDOMESTIC_ANIMAL;
}
#[repr(C)]
pub struct RawIDomesticAnimal {
pub vtable: *const IDomesticAnimalVTable,
}
pub type IDomesticAnimalVPtr = *const IDomesticAnimalVTable;
impl RawIDomesticAnimal {
unsafe fn raw_train(&mut self) -> HRESULT {
((*self.vtable).2.Train)(self as *mut RawIDomesticAnimal)
}
}
impl std::convert::AsRef<RawIUnknown> for RawIDomesticAnimal {
fn as_ref(&self) -> &RawIUnknown {
unsafe { &*(self as *const RawIDomesticAnimal as *const RawIUnknown) }
}
}
impl std::convert::AsMut<RawIUnknown> for RawIDomesticAnimal {
fn as_mut(&mut self) -> &mut RawIUnknown {
unsafe { &mut *(self as *mut RawIDomesticAnimal as *mut RawIUnknown) }
}
}
impl std::convert::AsRef<RawIAnimal> for RawIDomesticAnimal {
fn as_ref(&self) -> &RawIAnimal {
unsafe { &*(self as *const RawIDomesticAnimal as *const RawIAnimal) }
}
}
impl std::convert::AsMut<RawIAnimal> for RawIDomesticAnimal {
fn as_mut(&mut self) -> &mut RawIAnimal {
unsafe { &mut *(self as *mut RawIDomesticAnimal as *mut RawIAnimal) }
impl <T: IDomesticAnimal + ComInterface + ?Sized> IDomesticAnimal for ComPtr<T> {
fn train(&mut self) -> HRESULT {
let itf_ptr = self.into_raw() as *mut IDomesticAnimalVPtr;
unsafe { ((**itf_ptr).2.Train)(itf_ptr) }
}
}
#[allow(non_snake_case)]
#[repr(C)]
pub struct IDomesticAnimalMethods {
pub Train: unsafe extern "stdcall" fn(*mut RawIDomesticAnimal) -> HRESULT,
pub Train: unsafe extern "stdcall" fn(*mut IDomesticAnimalVPtr) -> HRESULT,
}
#[repr(C)]

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

@ -1,4 +1,4 @@
use com::{ComInterface, ComPtr, IUnknownMethods, RawIUnknown};
use com::{ComInterface, ComPtr, IUnknownMethods, IUnknown,};
use winapi::shared::guiddef::IID;
@ -9,40 +9,15 @@ pub const IID_IEXAMPLE: IID = IID {
Data4: [0xA9, 0xF9, 0x05, 0xAC, 0x67, 0x52, 0x5E, 0x43],
};
#[repr(C)]
pub struct IExample {
inner: RawIExample,
}
impl IExample {
pub fn query_interface<T: ComInterface>(&mut self) -> Option<ComPtr<T>> {
let inner: &mut RawIUnknown = self.inner.as_mut();
inner.query_interface()
}
}
pub trait IExample: IUnknown {}
unsafe impl ComInterface for IExample {
const IID: IID = IID_IEXAMPLE;
}
#[repr(C)]
pub struct RawIExample {
vtable: *const IExampleVTable,
}
pub type IExampleVPtr = *const IExampleVTable;
impl RawIExample {}
impl std::convert::AsRef<RawIUnknown> for RawIExample {
fn as_ref(&self) -> &RawIUnknown {
unsafe { &*(self as *const RawIExample as *const RawIUnknown) }
}
}
impl std::convert::AsMut<RawIUnknown> for RawIExample {
fn as_mut(&mut self) -> &mut RawIUnknown {
unsafe { &mut *(self as *mut RawIExample as *mut RawIUnknown) }
}
}
impl <T: IExample + ComInterface + ?Sized> IExample for ComPtr<T> {}
#[repr(C)]
pub struct IExampleMethods {}

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

@ -1,4 +1,4 @@
use com::{ComInterface, ComPtr, IUnknownMethods, RawIUnknown};
use com::{ComInterface, ComPtr, IUnknownMethods, IUnknown,};
use winapi::shared::{guiddef::IID, winerror::HRESULT};
@ -9,53 +9,27 @@ pub const IID_IFILE_MANAGER: IID = IID {
Data4: [0x83, 0x51, 0x04, 0x48, 0x89, 0xd5, 0xe3, 0x7e],
};
#[repr(C)]
pub struct IFileManager {
pub inner: RawIFileManager,
}
impl IFileManager {
pub fn query_interface<T: ComInterface>(&mut self) -> Option<ComPtr<T>> {
let inner: &mut RawIUnknown = self.inner.as_mut();
inner.query_interface()
}
pub fn delete_all(&mut self) {
let _ = unsafe { self.inner.raw_delete_all() };
}
pub trait IFileManager: IUnknown {
fn delete_all(&mut self) -> HRESULT;
}
unsafe impl ComInterface for IFileManager {
const IID: IID = IID_IFILE_MANAGER;
}
#[repr(C)]
pub struct RawIFileManager {
pub vtable: *const IFileManagerVTable,
}
pub type IFileManagerVPtr = *const IFileManagerVTable;
impl RawIFileManager {
unsafe fn raw_delete_all(&mut self) -> HRESULT {
((*self.vtable).1.DeleteAll)(self as *mut RawIFileManager)
}
}
impl std::convert::AsRef<RawIUnknown> for RawIFileManager {
fn as_ref(&self) -> &RawIUnknown {
unsafe { &*(self as *const RawIFileManager as *const RawIUnknown) }
}
}
impl std::convert::AsMut<RawIUnknown> for RawIFileManager {
fn as_mut(&mut self) -> &mut RawIUnknown {
unsafe { &mut *(self as *mut RawIFileManager as *mut RawIUnknown) }
impl <T: IFileManager + ComInterface + ?Sized> IFileManager for ComPtr<T> {
fn delete_all(&mut self) -> HRESULT {
let itf_ptr = self.into_raw() as *mut IFileManagerVPtr;
unsafe { ((**itf_ptr).1.DeleteAll)(itf_ptr) }
}
}
#[allow(non_snake_case)]
#[repr(C)]
pub struct IFileManagerMethods {
pub DeleteAll: unsafe extern "stdcall" fn(*mut RawIFileManager) -> HRESULT,
pub DeleteAll: unsafe extern "stdcall" fn(*mut IFileManagerVPtr) -> HRESULT,
}
#[repr(C)]
pub struct IFileManagerVTable(pub IUnknownMethods, pub IFileManagerMethods);

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

@ -1,4 +1,4 @@
use com::{ComInterface, ComPtr, IUnknownMethods, RawIUnknown};
use com::{ComInterface, ComPtr, IUnknownMethods, IUnknown,};
use winapi::shared::{guiddef::IID, winerror::HRESULT};
@ -9,53 +9,26 @@ pub const IID_ILOCAL_FILE_MANAGER: IID = IID {
Data4: [0xb1, 0x08, 0x78, 0x95, 0xb0, 0xaf, 0x21, 0xad],
};
#[repr(C)]
pub struct ILocalFileManager {
pub inner: RawILocalFileManager,
}
impl ILocalFileManager {
pub fn query_interface<T: ComInterface>(&mut self) -> Option<ComPtr<T>> {
let inner: &mut RawIUnknown = self.inner.as_mut();
inner.query_interface()
}
pub fn delete_local(&mut self) {
let _ = unsafe { self.inner.raw_delete_local() };
}
pub trait ILocalFileManager: IUnknown {
fn delete_local(&mut self) -> HRESULT;
}
unsafe impl ComInterface for ILocalFileManager {
const IID: IID = IID_ILOCAL_FILE_MANAGER;
}
#[repr(C)]
pub struct RawILocalFileManager {
pub vtable: *const ILocalFileManagerVTable,
}
pub type ILocalFileManagerVPtr = *const ILocalFileManagerVTable;
impl RawILocalFileManager {
unsafe fn raw_delete_local(&mut self) -> HRESULT {
((*self.vtable).1.DeleteLocal)(self as *mut RawILocalFileManager)
impl <T: ILocalFileManager + ComInterface + ?Sized> ILocalFileManager for ComPtr<T> {
fn delete_local(&mut self) -> HRESULT {
let itf_ptr = self.into_raw() as *mut ILocalFileManagerVPtr;
unsafe { ((**itf_ptr).1.DeleteLocal)(itf_ptr) }
}
}
impl std::convert::AsRef<RawIUnknown> for RawILocalFileManager {
fn as_ref(&self) -> &RawIUnknown {
unsafe { &*(self as *const RawILocalFileManager as *const RawIUnknown) }
}
}
impl std::convert::AsMut<RawIUnknown> for RawILocalFileManager {
fn as_mut(&mut self) -> &mut RawIUnknown {
unsafe { &mut *(self as *mut RawILocalFileManager as *mut RawIUnknown) }
}
}
#[allow(non_snake_case)]
#[repr(C)]
pub struct ILocalFileManagerMethods {
pub DeleteLocal: unsafe extern "stdcall" fn(*mut RawILocalFileManager) -> HRESULT,
pub DeleteLocal: unsafe extern "stdcall" fn(*mut ILocalFileManagerVPtr) -> HRESULT,
}
#[repr(C)]

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

@ -1,53 +1,56 @@
// An issue with having T be Human is that I am never
// actually possessing the entire Human struct, just
// an interface pointer.
use crate::iunknown::RawIUnknown;
use crate::ComInterface;
use std::ops::Deref;
use std::ops::DerefMut;
use std::ptr::NonNull;
pub struct ComPtr<T: ComInterface> {
ptr: NonNull<T>,
use super::*;
use std::marker::PhantomData;
use winapi::ctypes::c_void;
pub struct ComPtr<T: ComInterface + ?Sized> {
ptr: NonNull<c_void>,
phantom: PhantomData<T>,
}
impl<T: ComInterface> Deref for ComPtr<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { self.ptr.as_ref() }
}
}
impl<T: ComInterface> DerefMut for ComPtr<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.ptr.as_mut() }
}
}
impl<T: ComInterface> ComPtr<T> {
impl<T: ComInterface + ?Sized> ComPtr<T> {
/// NonNull<T> must be safely convertable to *mut RawIUnknown
pub fn new(ptr: NonNull<T>) -> Self {
ComPtr { ptr }
pub fn new(ptr: NonNull<c_void>) -> Self {
ComPtr {
ptr,
phantom: PhantomData,
}
}
fn add_ref(&self) {
unsafe { (*(self.ptr.as_ptr() as *mut RawIUnknown)).raw_add_ref() };
pub fn into_raw(&self) -> *mut c_void {
self.ptr.as_ptr()
}
pub fn get_ptr(&self) -> NonNull<c_void> {
self.ptr
}
fn cast_and_add_ref(&self) {
unsafe { (*(self as *const _ as *const ComPtr<IUnknown>)).add_ref(); }
}
}
impl<T: ComInterface + ?Sized> Drop for ComPtr<T> {
fn drop(&mut self) {
println!("Dropped!");
unsafe {
(*(self as *const _ as *const ComPtr<IUnknown>)).release();
}
}
}
impl<T: ComInterface> Clone for ComPtr<T> {
fn clone(&self) -> Self {
self.add_ref();
ComPtr { ptr: self.ptr }
}
}
impl<T: ComInterface> Drop for ComPtr<T> {
fn drop(&mut self) {
unsafe {
(*(self.ptr.as_ptr() as *mut RawIUnknown)).raw_release();
self.cast_and_add_ref();
ComPtr {
ptr: self.ptr,
phantom: PhantomData
}
}
}

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

@ -1,20 +1,13 @@
use crate::{
comptr::ComPtr,
failed,
iunknown::{IUnknownMethods, RawIUnknown},
ComInterface,
};
use super::*;
use winapi::shared::guiddef::IID;
use winapi::shared::guiddef::REFIID;
use winapi::shared::ntdef::HRESULT;
use winapi::shared::minwindef::BOOL;
use winapi::ctypes::c_void;
use winapi::{
ctypes::c_void,
shared::{
guiddef::{IID, REFIID},
minwindef::BOOL,
},
um::winnt::HRESULT,
};
use std::marker::PhantomData;
// uuid(0x000e0000, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46)
#[allow(non_upper_case_globals)]
pub const IID_ICLASS_FACTORY: IID = IID {
Data1: 0x01u32,
Data2: 0u16,
@ -26,8 +19,8 @@ pub const IID_ICLASS_FACTORY: IID = IID {
#[repr(C)]
pub struct IClassFactoryMethods {
pub CreateInstance: unsafe extern "stdcall" fn(
*mut RawIClassFactory,
*mut RawIUnknown,
*mut IClassFactoryVPtr,
*mut IUnknownVPtr,
REFIID,
*mut *mut c_void,
) -> HRESULT,
@ -36,66 +29,52 @@ pub struct IClassFactoryMethods {
#[repr(C)]
pub struct IClassFactoryVTable(pub IUnknownMethods, pub IClassFactoryMethods);
#[repr(C)]
pub struct RawIClassFactory {
pub vtable: *const IClassFactoryVTable,
pub type IClassFactoryVPtr = *const IClassFactoryVTable;
pub trait IClassFactory: IUnknown {
fn create_instance(&mut self, aggr: *mut IUnknownVPtr, riid: REFIID, ppv: *mut *mut c_void) -> HRESULT;
fn lock_server(&self, increment: BOOL) -> HRESULT;
}
impl RawIClassFactory {
pub unsafe fn raw_create_instance(&mut self, riid: REFIID, ppv: *mut *mut c_void) -> HRESULT {
// TODO: Support aggregation!
// https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iclassfactory-createinstance
((*self.vtable).1.CreateInstance)(
self as *mut RawIClassFactory,
std::ptr::null_mut(),
riid,
ppv,
)
impl <T: IClassFactory + ComInterface + ?Sized> IClassFactory for ComPtr<T> {
fn create_instance(&mut self, aggr: *mut IUnknownVPtr, riid: REFIID, ppv: *mut *mut c_void) -> HRESULT {
let itf_ptr = self.into_raw() as *mut IClassFactoryVPtr;
unsafe { ((**itf_ptr).1.CreateInstance)(itf_ptr, aggr, riid, ppv) }
}
pub unsafe fn raw_lock_server(&mut self, increment: bool) -> HRESULT {
((*self.vtable).1.LockServer)(increment as BOOL)
}
pub fn create_instance<T: ComInterface>(&mut self) -> Option<ComPtr<T>> {
let mut ppv = std::ptr::null_mut::<c_void>();
let hr = unsafe { self.raw_create_instance(&T::IID as *const IID, &mut ppv) };
if failed(hr) {
// TODO: decide what failures are possible
return None;
}
Some(ComPtr::new(std::ptr::NonNull::new(ppv as *mut T)?))
fn lock_server(&self, increment: BOOL) -> HRESULT {
let itf_ptr = self.into_raw() as *mut IClassFactoryVPtr;
unsafe { ((**itf_ptr).1.LockServer)(increment) }
}
}
#[repr(C)]
pub struct IClassFactory {
pub inner: RawIClassFactory,
}
impl IClassFactory {
pub fn query_interface<T: ComInterface>(&mut self) -> Option<ComPtr<T>> {
let inner: &mut RawIUnknown = self.inner.as_mut();
inner.query_interface()
}
pub fn create_instance<T: ComInterface>(&mut self) -> Option<ComPtr<T>> {
self.inner.create_instance()
}
}
unsafe impl ComInterface for IClassFactory {
const IID: IID = IID_ICLASS_FACTORY;
}
impl std::convert::AsRef<RawIUnknown> for RawIClassFactory {
fn as_ref(&self) -> &RawIUnknown {
unsafe { &*(self as *const RawIClassFactory as *const RawIUnknown) }
impl ComPtr<IClassFactory> {
pub fn get_instance<T: ComInterface>(&mut self) -> Option<ComPtr<T>> {
let mut ppv = std::ptr::null_mut::<c_void>();
let mut aggr = std::ptr::null_mut();
let hr = unsafe {
self.create_instance(aggr, &T::IID as *const IID, &mut ppv)
};
if failed(hr) {
// TODO: decide what failures are possible
return None;
}
Some(ComPtr::new(std::ptr::NonNull::new(ppv as *mut c_void)?))
}
}
impl std::convert::AsMut<RawIUnknown> for RawIClassFactory {
fn as_mut(&mut self) -> &mut RawIUnknown {
unsafe { &mut *(self as *mut RawIClassFactory as *mut RawIUnknown) }
}
}
// impl From<ComPtr<IClassFactory>> for ComPtr<IUnknown> {
// fn from(comptr: ComPtr<IClassFactory>) -> ComPtr<IUnknown> {
// println!("Wrapped!");
// ComPtr::wrap(comptr.get_ptr())
// // ComPtr {
// // ptr: comptr.get_ptr(),
// // phantom: PhantomData
// // }
// }
// }

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

@ -1,13 +1,10 @@
use crate::{comptr::ComPtr, failed, ComInterface};
use winapi::{
ctypes::c_void,
shared::{guiddef::IID, winerror::E_NOINTERFACE},
um::winnt::HRESULT,
};
use super::*;
use std::os::raw::c_void;
use winapi::shared::guiddef::GUID;
use winapi::shared::ntdef::HRESULT;
#[allow(non_upper_case_globals)]
pub const IID_IUNKNOWN: IID = IID {
pub const IID_IUNKNOWN: GUID = GUID {
Data1: 0u32,
Data2: 0u16,
Data3: 0u16,
@ -18,54 +15,56 @@ pub const IID_IUNKNOWN: IID = IID {
#[repr(C)]
pub struct IUnknownMethods {
pub QueryInterface:
unsafe extern "stdcall" fn(*mut RawIUnknown, *const IID, *mut *mut c_void) -> HRESULT,
pub AddRef: unsafe extern "stdcall" fn(*mut RawIUnknown) -> u32,
pub Release: unsafe extern "stdcall" fn(*mut RawIUnknown) -> u32,
unsafe extern "stdcall" fn(*mut IUnknownVPtr, *const IID, *mut *mut c_void) -> HRESULT,
pub AddRef: unsafe extern "stdcall" fn(*mut IUnknownVPtr) -> u32,
pub Release: unsafe extern "stdcall" fn(*mut IUnknownVPtr) -> u32,
}
#[repr(C)]
pub struct IUnknownVTable(pub IUnknownMethods);
#[repr(C)]
pub struct RawIUnknown {
pub vtable: *const IUnknownVTable,
pub type IUnknownVPtr = *const IUnknownVTable;
pub trait IUnknown {
fn query_interface(&mut self, riid: *const IID, ppv: *mut *mut c_void) -> HRESULT;
fn add_ref(&self) -> u32;
fn release(&self) -> u32;
}
impl RawIUnknown {
pub unsafe fn raw_query_interface(
&mut self,
riid: *const IID,
ppv: *mut *mut c_void,
) -> HRESULT {
((*self.vtable).0.QueryInterface)(self, riid, ppv)
}
pub unsafe fn raw_add_ref(&mut self) -> u32 {
((*self.vtable).0.AddRef)(self)
}
pub unsafe fn raw_release(&mut self) -> u32 {
((*self.vtable).0.Release)(self)
}
pub fn query_interface<T: ComInterface>(&mut self) -> Option<ComPtr<T>> {
let mut ppv = std::ptr::null_mut::<c_void>();
let hr = unsafe { self.raw_query_interface(&T::IID as *const IID, &mut ppv) };
if failed(hr) {
assert!(hr == E_NOINTERFACE);
return None;
}
Some(ComPtr::new(std::ptr::NonNull::new(ppv as *mut T)?))
}
impl <T: ComInterface + ?Sized> IUnknown for ComPtr<T> {
fn query_interface(&mut self, riid: *const IID, ppv: *mut *mut c_void) -> HRESULT {
let itf_ptr = self.into_raw() as *mut IUnknownVPtr;
unsafe { ((**itf_ptr).0.QueryInterface)(itf_ptr, riid, ppv) }
}
#[repr(C)]
pub struct IUnknown {
inner: RawIUnknown,
fn add_ref(&self) -> u32 {
let itf_ptr = self.into_raw() as *mut IUnknownVPtr;
unsafe { ((**itf_ptr).0.AddRef)(itf_ptr) }
}
impl IUnknown {
pub fn query_interface<T: ComInterface>(&mut self) -> Option<ComPtr<T>> {
self.inner.query_interface()
fn release(&self) -> u32 {
let itf_ptr = self.into_raw() as *mut IUnknownVPtr;
unsafe { ((**itf_ptr).0.Release)(itf_ptr) }
}
}
unsafe impl ComInterface for IUnknown {
const IID: IID = IID_IUNKNOWN;
}
impl<T: IUnknown + ComInterface + ?Sized> ComPtr<T> {
fn query_interface(&mut self, riid: *const IID, ppv: *mut *mut c_void) -> HRESULT {
let itf_ptr = self.into_raw() as *mut IUnknownVPtr;
unsafe { ((**itf_ptr).0.QueryInterface)(itf_ptr, riid, ppv) }
}
fn add_ref(&self) -> u32 {
let itf_ptr = self.into_raw() as *mut IUnknownVPtr;
unsafe { ((**itf_ptr).0.AddRef)(itf_ptr) }
}
fn release(&self) -> u32 {
let itf_ptr = self.into_raw() as *mut IUnknownVPtr;
unsafe { ((**itf_ptr).0.Release)(itf_ptr) }
}
}

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

@ -5,10 +5,10 @@ mod iunknown;
pub use comptr::ComPtr;
pub use iclassfactory::{
IClassFactory, IClassFactoryMethods, IClassFactoryVTable, RawIClassFactory, IID_ICLASS_FACTORY,
IClassFactory, IClassFactoryMethods, IClassFactoryVTable, IID_ICLASS_FACTORY,
};
pub use inproc::*;
pub use iunknown::{IUnknown, IUnknownMethods, IUnknownVTable, RawIUnknown, IID_IUNKNOWN};
pub use iunknown::{IUnknown, IUnknownMethods, IUnknownVTable, IID_IUNKNOWN, IUnknownVPtr};
extern crate winapi;
use winapi::shared::{guiddef::IID, winerror::HRESULT};