AgileComPointer<TInterface>
class AgileComPointer<TInterface> : IDisposable where TInterface : ValueType modreq(System.Runtime.InteropServices.UnmanagedType), IComIID
Finalizable wrapper for COM pointers that gives agile access to the specified interface.
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using Windows.Win32.System.Com;
namespace Windows.Win32.Foundation
{
internal class AgileComPointer<[IsUnmanaged] TInterface> : IDisposable where TInterface : struct, IComIID
{
private uint ;
private readonly uint _memoryPressure;
public unsafe AgileComPointer(TInterface* interface, bool takeOwnership, uint memoryPressure = 0)
{
_memoryPressure = 0;
try {
_cookie = GlobalInterfaceTable.RegisterInterface<TInterface>(interface);
if (memoryPressure != 0) {
_memoryPressure = memoryPressure;
GC.AddMemoryPressure(_memoryPressure);
}
} catch {
GC.SuppressFinalize(this);
throw;
} finally {
if (takeOwnership)
((IUnknown*)interface)->Release();
}
}
public unsafe bool IsSameNativeObject([Nullable(new byte[] {
1,
0
})] AgileComPointer<TInterface> other)
{
ComScope<IUnknown> interface = GetInterface<IUnknown>();
try {
ComScope<IUnknown> interface2 = other.GetInterface<IUnknown>();
try {
return interface.Value == interface2.Value;
} finally {
interface2.Dispose();
}
} finally {
interface.Dispose();
}
}
public unsafe bool IsSameNativeObject(TInterface* other)
{
ComScope<IUnknown> interface = GetInterface<IUnknown>();
try {
ComScope<IUnknown> comScope = ComScope<IUnknown>.QueryFrom<TInterface>(other);
try {
return interface.Value == comScope.Value;
} finally {
comScope.Dispose();
}
} finally {
interface.Dispose();
}
}
public ComScope<TInterface> GetInterface()
{
HRESULT result;
ComScope<TInterface> interface = GlobalInterfaceTable.GetInterface<TInterface>(_cookie, out result);
result.ThrowOnFailure((IntPtr)0);
return interface;
}
public ComScope<TAsInterface> GetInterface<[IsUnmanaged] TAsInterface>() where TAsInterface : struct, IComIID
{
HRESULT hr;
ComScope<TAsInterface> result = TryGetInterface<TAsInterface>(out hr);
hr.ThrowOnFailure((IntPtr)0);
return result;
}
public ComScope<TInterface> TryGetInterface(out HRESULT hr)
{
return GlobalInterfaceTable.GetInterface<TInterface>(_cookie, out hr);
}
public ComScope<TAsInterface> TryGetInterface<[IsUnmanaged] TAsInterface>(out HRESULT hr) where TAsInterface : struct, IComIID
{
return GlobalInterfaceTable.GetInterface<TAsInterface>(this._cookie, out hr);
}
[NullableContext(1)]
public object GetManagedObject()
{
ComScope<TInterface> interface = GetInterface();
try {
return ComHelpers.GetObjectForIUnknown<TInterface>(interface);
} finally {
interface.Dispose();
}
}
~AgileComPointer()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
uint num = Interlocked.Exchange(ref _cookie, 0);
if (num != 0) {
if (_memoryPressure != 0)
GC.RemoveMemoryPressure(_memoryPressure);
GlobalInterfaceTable.RevokeInterface(num);
}
}
}
}