diff --git a/src/Files.App.CsWin32/Windows.Win32.ComPtr.cs b/src/Files.App.CsWin32/Windows.Win32.ComPtr.cs new file mode 100644 index 000000000000..d3896fc8fa4e --- /dev/null +++ b/src/Files.App.CsWin32/Windows.Win32.ComPtr.cs @@ -0,0 +1,52 @@ +// Copyright (c) 2024 Files Community +// Licensed under the MIT License. See the LICENSE. + +using System; +using System.Runtime.CompilerServices; +using Windows.Win32; +using Windows.Win32.System.Com; + +namespace Windows.Win32 +{ + /// + /// Contains a COM pointer and a set of methods to work with the pointer safely. + /// + public unsafe struct ComPtr : IDisposable where T : unmanaged + { + private T* _ptr; + + public bool IsNull + => _ptr == default; + + public ComPtr(T* ptr) + { + _ptr = ptr; + + if (ptr is not null) + ((IUnknown*)ptr)->AddRef(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly T* Get() + { + return _ptr; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly T** GetAddressOf() + { + return (T**)Unsafe.AsPointer(ref Unsafe.AsRef(in this)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + T* ptr = _ptr; + if (ptr is not null) + { + _ptr = null; + ((IUnknown*)ptr)->Release(); + } + } + } +}