From c4159b7f0c9f0015d19dfd381f0b5910667f9986 Mon Sep 17 00:00:00 2001 From: Ryo Yamashita Date: Mon, 11 Dec 2023 14:35:24 +0900 Subject: [PATCH] Add `init_apartment` --- crates/oadef/src/lib.rs | 42 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/crates/oadef/src/lib.rs b/crates/oadef/src/lib.rs index f5b53c0..d493bf7 100644 --- a/crates/oadef/src/lib.rs +++ b/crates/oadef/src/lib.rs @@ -6,7 +6,7 @@ use std::{ slice, }; -use derive_more::Into; +use derive_more::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Into, Not}; use duplicate::duplicate_item; use thiserror::Error; use windows::{ @@ -15,8 +15,9 @@ use windows::{ Foundation::VARIANT_BOOL, System::{ Com::{ - CLSIDFromProgID, CoCreateInstance, IDispatch, CLSCTX_ALL, DISPATCH_METHOD, - DISPATCH_PROPERTYGET, DISPATCH_PROPERTYPUT, DISPPARAMS, SAFEARRAY, + CLSIDFromProgID, CoCreateInstance, CoInitializeEx, CoUninitialize, IDispatch, + CLSCTX_ALL, COINIT, COINIT_APARTMENTTHREADED, COINIT_MULTITHREADED, + DISPATCH_METHOD, DISPATCH_PROPERTYGET, DISPATCH_PROPERTYPUT, DISPPARAMS, SAFEARRAY, }, Ole::{SafeArrayCreateVector, SafeArrayPutElement}, Variant::{ @@ -30,6 +31,41 @@ use windows::{ pub use oadef_macros::{new, TryFrom_Out}; +pub fn init_apartment(dwcoinit: Coinit) -> windows::core::Result { + unsafe { + // SAFETY: according to com-rs, this function is safe as long as the first argument is + // null? + CoInitializeEx(None, COINIT(dwcoinit.0)) + }?; + Ok(CoUninitializeOnDrop) +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Not, BitAnd, BitAndAssign, BitOr, BitOrAssign)] +pub struct Coinit(i32); + +impl Coinit { + pub const MULTITHREADED: Self = Self(COINIT_MULTITHREADED.0); + pub const APARTMENTTHREADED: Self = Self(COINIT_APARTMENTTHREADED.0); +} + +impl Default for Coinit { + fn default() -> Self { + Self::MULTITHREADED + } +} + +#[must_use] +pub struct CoUninitializeOnDrop; + +impl Drop for CoUninitializeOnDrop { + fn drop(&mut self) { + unsafe { + // SAFETY: according to com-rs, this function itself is safe? + CoUninitialize(); + } + } +} + pub fn idispatch_from_prog_id(lpszprogid: PCWSTR) -> windows::core::Result { let clsid = unsafe { // SAFETY: this function itself is safe?