зеркало из https://github.com/microsoft/com-rs.git
Only interface and com crates compile
This commit is contained in:
Родитель
13df1e17cf
Коммит
2c873c0a7c
|
@ -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)
|
||||
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) }
|
||||
}
|
||||
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)?))
|
||||
}
|
||||
}
|
||||
|
||||
#[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};
|
||||
|
|
Загрузка…
Ссылка в новой задаче