use super::IoError;
use std::marker::PhantomData;
use std::ptr;
use windows::Win32::Foundation::RPC_E_CHANGED_MODE;
use windows::Win32::System::Com::{CoInitializeEx, CoUninitialize, COINIT_APARTMENTTHREADED};
thread_local!(static COM_INITIALIZED: ComInitialized = {
unsafe {
let result = CoInitializeEx(ptr::null_mut(), COINIT_APARTMENTTHREADED);
match result.clone().map_err(|e| e.code()) {
Ok(_) |
Err(RPC_E_CHANGED_MODE) => {
ComInitialized {
result,
_ptr: PhantomData,
}
},
Err(e) => {
panic!("Failed to initialize COM: {}", IoError::from_raw_os_error(e.0));
}
}
}
});
struct ComInitialized {
result: windows::core::Result<()>,
_ptr: PhantomData<*mut ()>,
}
impl Drop for ComInitialized {
#[inline]
fn drop(&mut self) {
if self.result.is_ok() {
unsafe { CoUninitialize() };
}
}
}
#[inline]
pub fn com_initialized() {
COM_INITIALIZED.with(|_| {});
}