ComScope<T>
struct ComScope<T> where T : ValueType modreq(System.Runtime.InteropServices.UnmanagedType), IComIID
Lifetime management struct for a native COM pointer. Meant to be utilized in a using statement
to ensure Release is called when going out of scope with the using.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Windows.Win32.System.Com;
namespace Windows.Win32.Foundation
{
[CompilerFeatureRequired("RefStructs")]
internal readonly ref struct ComScope<[IsUnmanaged] T> where T : struct, IComIID
{
private readonly IntPtr _value;
public unsafe T* Value => (T*)(long)_value;
public unsafe IUnknown* AsUnknown => (IUnknown*)(long)_value;
public bool IsNull => _value == (IntPtr)0;
public unsafe ComScope(T* value)
{
_value = (IntPtr)value;
}
public unsafe static implicit operator T*([In] [IsReadOnly] ref ComScope<T> scope)
{
return (T*)(long)scope._value;
}
public unsafe static implicit operator void*([In] [IsReadOnly] ref ComScope<T> scope)
{
return (void*)(long)scope._value;
}
public static implicit operator IntPtr([In] [IsReadOnly] ref ComScope<T> scope)
{
return scope._value;
}
public unsafe static implicit operator T**([In] [IsReadOnly] ref ComScope<T> scope)
{
return (T**)Unsafe.AsPointer<IntPtr>(ref Unsafe.AsRef<IntPtr>(ref scope._value));
}
public unsafe static implicit operator void**([In] [IsReadOnly] ref ComScope<T> scope)
{
return (void**)Unsafe.AsPointer<IntPtr>(ref Unsafe.AsRef<IntPtr>(ref scope._value));
}
public unsafe ComScope<TTo> TryQuery<[IsUnmanaged] TTo>(out HRESULT hr) where TTo : struct, IComIID
{
ComScope<TTo> scope = new ComScope<TTo>(null);
hr = ((IUnknown*)this.Value)->QueryInterface(IID.Get<TTo>(), (void**)ref scope);
return scope;
}
public unsafe ComScope<TTo> Query<[IsUnmanaged] TTo>() where TTo : struct, IComIID
{
ComScope<TTo> scope = new ComScope<TTo>(null);
((IUnknown*)this.Value)->QueryInterface(IID.Get<TTo>(), (void**)ref scope).ThrowOnFailure((IntPtr)0);
return scope;
}
public unsafe static ComScope<T> TryQueryFrom<[IsUnmanaged] TFrom>(TFrom* from, out HRESULT hr) where TFrom : struct, IComIID
{
ComScope<T> scope = new ComScope<T>(null);
hr = ((from == null) ? HRESULT.E_POINTER : ((IUnknown*)from)->QueryInterface(IID.Get<T>(), (void**)ref scope));
return scope;
}
public unsafe static ComScope<T> QueryFrom<[IsUnmanaged] TFrom>(TFrom* from) where TFrom : struct, IComIID
{
if (from == null)
HRESULT.E_POINTER.ThrowOnFailure((IntPtr)0);
ComScope<T> scope = new ComScope<T>(null);
((IUnknown*)from)->QueryInterface(IID.Get<T>(), (void**)ref scope).ThrowOnFailure((IntPtr)0);
return scope;
}
public unsafe bool SupportsInterface<[IsUnmanaged] TInterface>() where TInterface : struct, IComIID
{
if (typeof(TInterface) == typeof(T))
return true;
IUnknown* ptr = default(IUnknown*);
if (this.AsUnknown->QueryInterface(IID.Get<TInterface>(), (void**)(&ptr)).Succeeded) {
ptr->Release();
return true;
}
return false;
}
public unsafe void Dispose()
{
IUnknown* value = (IUnknown*)(long)_value;
*(void**)ref this = null;
if (value != null)
value->Release();
}
}
}