]> git.proxmox.com Git - rustc.git/blame - vendor/windows/src/core/com_interface.rs
Update upstream source from tag 'upstream/1.70.0+dfsg1'
[rustc.git] / vendor / windows / src / core / com_interface.rs
CommitLineData
353b0b11
FG
1use super::*;
2use imp::IWeakReferenceSource;
3
4/// Provides low-level access to a COM interface.
5///
6/// This trait is automatically implemented by the generated bindings and should not be
7/// implemented manually.
8///
9/// # Safety
10///
11/// It is only safe to implement this trait if the implementing type is a valid COM interface pointer meaning
12/// the following criteria are met:
13/// * its in-memory representation is equal to `NonNull<NonNull<Self::VTable>>`
14/// * the vtable is correctly structured beginning with the `IUnknown` function pointers
15/// * the vtable must be the correct vtable for the supplied IID
16pub unsafe trait ComInterface: Interface + Clone {
17 /// A unique identifier representing this interface.
18 const IID: GUID;
19
20 /// Attempts to cast the current interface to another interface using `QueryInterface`.
21 ///
22 /// The name `cast` is preferred to `query` because there is a WinRT method named query but not one
23 /// named cast.
24 fn cast<T: ComInterface>(&self) -> Result<T> {
25 let mut result = None;
26 // SAFETY: `result` is valid for writing an interface pointer and it is safe
27 // to cast the `result` pointer as `T` on success because we are using the `IID` tied
28 // to `T` which the implementor of `ComInterface` has guaranteed is correct
29 unsafe { self.query(&T::IID, &mut result as *mut _ as _).and_some(result) }
30 }
31
32 /// Attempts to create a [`Weak`] reference to this object.
33 fn downgrade(&self) -> Result<Weak<Self>> {
34 self.cast::<IWeakReferenceSource>().and_then(|source| Weak::downgrade(&source))
35 }
36
37 /// Call `QueryInterface` on this interface
38 ///
39 /// # SAFETY
40 ///
41 /// `interface` must be a non-null, valid pointer for writing an interface pointer
42 #[doc(hidden)]
43 unsafe fn query(&self, iid: &GUID, interface: *mut *const std::ffi::c_void) -> HRESULT {
44 (self.assume_vtable::<IUnknown>().QueryInterface)(self.as_raw(), iid, interface)
45 }
46}