1 // Copyright © 2017 winapi-rs developers
2 // Licensed under the Apache License, Version 2.0
3 // <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
4 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
5 // All files in the project carrying such notice may not be copied, modified, or distributed
6 // except according to those terms.
10 use crate::winapi
::CoInitializeEx
;
11 use crate::winapi
::IUnknown
;
12 use crate::winapi
::Interface
;
13 use crate::winapi
::BSTR
;
14 use crate::winapi
::COINIT_MULTITHREADED
;
15 use crate::winapi
::{SysFreeString, SysStringLen}
;
16 use crate::winapi
::{HRESULT, S_FALSE, S_OK}
;
17 use std
::ffi
::{OsStr, OsString}
;
20 use std
::os
::windows
::ffi
::{OsStrExt, OsStringExt}
;
21 use std
::ptr
::null_mut
;
22 use std
::slice
::from_raw_parts
;
24 pub fn initialize() -> Result
<(), HRESULT
> {
25 let err
= unsafe { CoInitializeEx(null_mut(), COINIT_MULTITHREADED) }
;
26 if err
!= S_OK
&& err
!= S_FALSE
{
27 // S_FALSE just means COM is already initialized
33 pub struct ComPtr
<T
>(*mut T
)
40 /// Creates a `ComPtr` to wrap a raw pointer.
41 /// It takes ownership over the pointer which means it does __not__ call `AddRef`.
42 /// `T` __must__ be a COM interface that inherits from `IUnknown`.
43 pub unsafe fn from_raw(ptr
: *mut T
) -> ComPtr
<T
> {
44 assert
!(!ptr
.is_null());
47 /// Casts up the inheritance chain
48 pub fn up
<U
>(self) -> ComPtr
<U
>
53 ComPtr(self.into_raw() as *mut U
)
55 /// Extracts the raw pointer.
56 /// You are now responsible for releasing it yourself.
57 pub fn into_raw(self) -> *mut T
{
62 /// For internal use only.
63 fn as_unknown(&self) -> &IUnknown
{
64 unsafe { &*(self.0 as *mut IUnknown) }
66 /// Performs QueryInterface fun.
67 pub fn cast
<U
>(&self) -> Result
<ComPtr
<U
>, i32>
71 let mut obj
= null_mut();
72 let err
= unsafe { self.as_unknown().QueryInterface(&U::uuidof(), &mut obj) }
;
76 Ok(unsafe { ComPtr::from_raw(obj as *mut U) }
)
79 impl<T
> Deref
for ComPtr
<T
>
84 fn deref(&self) -> &T
{
88 impl<T
> Clone
for ComPtr
<T
>
92 fn clone(&self) -> Self {
94 self.as_unknown().AddRef();
95 ComPtr
::from_raw(self.0)
99 impl<T
> Drop
for ComPtr
<T
>
105 self.as_unknown().Release();
109 pub struct BStr(BSTR
);
111 pub unsafe fn from_raw(s
: BSTR
) -> BStr
{
114 pub fn to_osstring(&self) -> OsString
{
115 let len
= unsafe { SysStringLen(self.0) }
;
116 let slice
= unsafe { from_raw_parts(self.0, len as usize) }
;
117 OsStringExt
::from_wide(slice
)
122 unsafe { SysFreeString(self.0) }
;
127 fn to_wide(&self) -> Vec
<u16>;
128 fn to_wide_null(&self) -> Vec
<u16>;
134 fn to_wide(&self) -> Vec
<u16> {
135 self.as_ref().encode_wide().collect()
137 fn to_wide_null(&self) -> Vec
<u16> {
138 self.as_ref().encode_wide().chain(Some(0)).collect()
145 fn from_wide(wide
: &[u16]) -> Self;
146 fn from_wide_null(wide
: &[u16]) -> Self {
147 let len
= wide
.iter().take_while(|&&c
| c
!= 0).count();
148 Self::from_wide(&wide
[..len
])
151 impl FromWide
for OsString
{
152 fn from_wide(wide
: &[u16]) -> OsString
{
153 OsStringExt
::from_wide(wide
)