diff --git a/src/Shmuelie.WinRTServer/BaseActivationFactory.cs b/src/Shmuelie.WinRTServer/BaseActivationFactory.cs
index b75c9f0..021a5e9 100644
--- a/src/Shmuelie.WinRTServer/BaseActivationFactory.cs
+++ b/src/Shmuelie.WinRTServer/BaseActivationFactory.cs
@@ -1,13 +1,14 @@
using System;
-using System.Runtime.InteropServices.WindowsRuntime;
namespace Shmuelie.WinRTServer;
///
/// Base for a WinRT Activation Factory for a .NET type.
///
-///
-public abstract class BaseActivationFactory : IActivationFactory
+#if !NETSTANDARD
+[System.Runtime.Versioning.SupportedOSPlatform("windows8.0")]
+#endif
+public abstract class BaseActivationFactory
{
///
public abstract object ActivateInstance();
diff --git a/src/Shmuelie.WinRTServer/BaseClassFactory.cs b/src/Shmuelie.WinRTServer/BaseClassFactory.cs
index aaa25ce..b115404 100644
--- a/src/Shmuelie.WinRTServer/BaseClassFactory.cs
+++ b/src/Shmuelie.WinRTServer/BaseClassFactory.cs
@@ -5,7 +5,6 @@ namespace Shmuelie.WinRTServer;
///
/// Base for a COM class factory for a .NET type.
///
-///
/// Does not support aggregation. Will always return CLASS_E_NOAGGREGATION if requested.
public abstract class BaseClassFactory
{
diff --git a/src/Shmuelie.WinRTServer/ComServer.cs b/src/Shmuelie.WinRTServer/ComServer.cs
index 0a3ce1a..a603670 100644
--- a/src/Shmuelie.WinRTServer/ComServer.cs
+++ b/src/Shmuelie.WinRTServer/ComServer.cs
@@ -4,8 +4,9 @@
using System.Threading.Tasks;
using System.Timers;
using Shmuelie.Interop.Windows;
-using static Shmuelie.Interop.Windows.ComBaseAPI;
-using static Shmuelie.Interop.Windows.Windows;
+using Windows.Win32.Foundation;
+using Windows.Win32.System.Com;
+using static Windows.Win32.PInvoke;
namespace Shmuelie.WinRTServer;
@@ -42,8 +43,9 @@ public sealed class ComServer : IAsyncDisposable
public unsafe ComServer()
{
using ComPtr options = default;
- Guid clsid = IGlobalOptions.CLSID;
- if (CoCreateInstance(&clsid, null, (uint)CLSCTX.CLSCTX_INPROC_SERVER, __uuidof(), (void**)options.GetAddressOf()) == S.S_OK)
+ Guid clsid = CLSID_GlobalOptions;
+ Guid iid = IGlobalOptions.IID_Guid;
+ if (CoCreateInstance(&clsid, null, CLSCTX.CLSCTX_INPROC_SERVER, &iid, (void**)options.GetAddressOf()) == HRESULT.S_OK)
{
options.Get()->Set(GLOBALOPT_PROPERTIES.COMGLB_RO_SETTINGS, (nuint)GLOBALOPT_RO_FLAGS.COMGLB_FAST_RUNDOWN);
}
@@ -128,7 +130,7 @@ public unsafe bool RegisterClassFactory(BaseClassFactory factory)
proxy.Attach(BaseClassFactoryProxy.Create(factory));
uint cookie;
- Marshal.ThrowExceptionForHR(CoRegisterClassObject(&clsid, (IUnknown*)proxy.Get(), (uint)CLSCTX.CLSCTX_LOCAL_SERVER, (uint)(REGCLS.REGCLS_MULTIPLEUSE | REGCLS.REGCLS_SUSPENDED), &cookie));
+ Marshal.ThrowExceptionForHR(CoRegisterClassObject(&clsid, (IUnknown*)proxy.Get(), CLSCTX.CLSCTX_LOCAL_SERVER, (REGCLS.REGCLS_MULTIPLEUSE | REGCLS.REGCLS_SUSPENDED), &cookie));
factories.Add(clsid, (factory, cookie));
return true;
diff --git a/src/Shmuelie.WinRTServer/Internal/BaseActivationFactoryProxy.cs b/src/Shmuelie.WinRTServer/Internal/BaseActivationFactoryProxy.cs
index d55dd20..e9b38a2 100644
--- a/src/Shmuelie.WinRTServer/Internal/BaseActivationFactoryProxy.cs
+++ b/src/Shmuelie.WinRTServer/Internal/BaseActivationFactoryProxy.cs
@@ -2,14 +2,20 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
+using Windows.Win32.System.WinRT;
+using Windows.Win32.System.Com;
+using Windows.Win32.Foundation;
+using static Windows.Win32.PInvoke;
using Shmuelie.Interop.Windows;
-using static Shmuelie.Interop.Windows.Windows;
namespace Shmuelie.WinRTServer;
///
/// CCW for .
///
+#if !NETSTANDARD
+[System.Runtime.Versioning.SupportedOSPlatform("windows8.0")]
+#endif
internal unsafe struct BaseActivationFactoryProxy
{
private static readonly void** Vtbl = InitVtbl();
@@ -64,7 +70,7 @@ public uint Release()
private static class Impl
{
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
- public delegate int QueryInterfaceDelegate(BaseActivationFactoryProxy* @this, Guid* riid, void** ppvObject);
+ public delegate HRESULT QueryInterfaceDelegate(BaseActivationFactoryProxy* @this, Guid* riid, void** ppvObject);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate uint AddRefDelegate(BaseActivationFactoryProxy* @this);
@@ -73,16 +79,16 @@ private static class Impl
public delegate uint ReleaseDelegate(BaseActivationFactoryProxy* @this);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
- public delegate int GetIidsDelegate(BaseActivationFactoryProxy* @this, uint* iidCount, Guid** iids);
+ public delegate HRESULT GetIidsDelegate(BaseActivationFactoryProxy* @this, uint* iidCount, Guid** iids);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
- public delegate int GetRuntimeClassNameDelegate(BaseActivationFactoryProxy* @this, HSTRING* className);
+ public delegate HRESULT GetRuntimeClassNameDelegate(BaseActivationFactoryProxy* @this, HSTRING* className);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
- public delegate int GetTrustLevelDelegate(BaseActivationFactoryProxy* @this, TrustLevel* trustLevel);
+ public delegate HRESULT GetTrustLevelDelegate(BaseActivationFactoryProxy* @this, TrustLevel* trustLevel);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
- public delegate int ActivateInstanceDelegate(BaseActivationFactoryProxy* @this, IInspectable** instance);
+ public delegate HRESULT ActivateInstanceDelegate(BaseActivationFactoryProxy* @this, IInspectable** instance);
///
/// The cached for IUnknown.QueryInterface(REFIID, void**).
@@ -110,20 +116,20 @@ private static class Impl
///
/// Implements IUnknown.QueryInterface(REFIID, void**).
///
- private static int QueryInterface(BaseActivationFactoryProxy* @this, Guid* riid, void** ppvObject)
+ private static HRESULT QueryInterface(BaseActivationFactoryProxy* @this, Guid* riid, void** ppvObject)
{
- if (riid->Equals(__uuidof()) ||
- riid->Equals(__uuidof()) ||
- riid->Equals(__uuidof()))
+ if (riid->Equals(IUnknown.IID_Guid) ||
+ riid->Equals(IInspectable.IID_Guid) ||
+ riid->Equals(IActivationFactory.IID_Guid))
{
_ = Interlocked.Increment(ref Unsafe.As(ref @this->_referenceCount));
*ppvObject = @this;
- return S.S_OK;
+ return HRESULT.S_OK;
}
- return E.E_NOINTERFACE;
+ return HRESULT.E_NOINTERFACE;
}
///
@@ -151,99 +157,99 @@ public static uint Release(BaseActivationFactoryProxy* @this)
return referenceCount;
}
- public static int GetIids(BaseActivationFactoryProxy* @this, uint* iidCount, Guid** iids)
+ public static HRESULT GetIids(BaseActivationFactoryProxy* @this, uint* iidCount, Guid** iids)
{
if (iidCount is null || iids is null)
{
- return E.E_INVALIDARG;
+ return HRESULT.E_INVALIDARG;
}
*iidCount = 1;
*iids = (Guid*)Marshal.AllocHGlobal(sizeof(Guid));
- *iids[0] = __uuidof();
- return S.S_OK;
+ *iids[0] = IActivationFactory.IID_Guid;
+ return HRESULT.S_OK;
}
- public static int GetRuntimeClassName(BaseActivationFactoryProxy* @this, HSTRING* className)
+ public static HRESULT GetRuntimeClassName(BaseActivationFactoryProxy* @this, HSTRING* className)
{
try
{
if (className is null)
{
- return E.E_INVALIDARG;
+ return HRESULT.E_INVALIDARG;
}
BaseActivationFactory? factory = Unsafe.As(@this->_factory.Target);
if (factory is null)
{
- return E.E_HANDLE;
+ return HRESULT.E_HANDLE;
}
string? fullName = factory.GetType().FullName;
if (fullName is null)
{
- return E.E_UNEXPECTED;
+ return HRESULT.E_UNEXPECTED;
}
fixed (char* fullNamePtr = fullName)
{
- return WinString.WindowsCreateString((ushort*)fullNamePtr, (uint)fullName.Length, className);
+ return WindowsCreateString((PCWSTR)fullNamePtr, (uint)fullName.Length, className);
}
}
catch (Exception e)
{
- return Marshal.GetHRForException(e);
+ return (HRESULT)Marshal.GetHRForException(e);
}
}
- public static int GetTrustLevel(BaseActivationFactoryProxy* @this, TrustLevel* trustLevel)
+ public static HRESULT GetTrustLevel(BaseActivationFactoryProxy* @this, TrustLevel* trustLevel)
{
if (trustLevel is null)
{
- return E.E_INVALIDARG;
+ return HRESULT.E_INVALIDARG;
}
*trustLevel = TrustLevel.BaseTrust;
- return S.S_OK;
+ return HRESULT.S_OK;
}
- public static int ActivateInstance(BaseActivationFactoryProxy* @this, IInspectable** instance)
+ public static HRESULT ActivateInstance(BaseActivationFactoryProxy* @this, IInspectable** instance)
{
try
{
if (instance is null)
{
- return E.E_INVALIDARG;
+ return HRESULT.E_INVALIDARG;
}
BaseActivationFactory? factory = Unsafe.As(@this->_factory.Target);
if (factory is null)
{
- return E.E_HANDLE;
+ return HRESULT.E_HANDLE;
}
object managedInstance = factory.ActivateInstance();
using ComPtr unkwnPtr = default;
unkwnPtr.Attach((IUnknown*)Marshal.GetIUnknownForObject(managedInstance));
- int result = unkwnPtr.CopyTo(instance);
- if (result != S.S_OK)
+ HRESULT result = unkwnPtr.CopyTo(instance);
+ if (result != HRESULT.S_OK)
{
return result;
}
factory.OnInstanceCreated(managedInstance);
- return S.S_OK;
+ return HRESULT.S_OK;
}
catch (Exception e)
{
- return Marshal.GetHRForException(e);
+ return (HRESULT)Marshal.GetHRForException(e);
}
}
}
diff --git a/src/Shmuelie.WinRTServer/Internal/BaseClassFactoryProxy.cs b/src/Shmuelie.WinRTServer/Internal/BaseClassFactoryProxy.cs
index 8b7a981..31ca47c 100644
--- a/src/Shmuelie.WinRTServer/Internal/BaseClassFactoryProxy.cs
+++ b/src/Shmuelie.WinRTServer/Internal/BaseClassFactoryProxy.cs
@@ -2,9 +2,9 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
-using Shmuelie.Interop.Windows;
-using static Shmuelie.Interop.Windows.ComBaseAPI;
-using static Shmuelie.Interop.Windows.Windows;
+using Windows.Win32.Foundation;
+using Windows.Win32.System.Com;
+using static Windows.Win32.PInvoke;
namespace Shmuelie.WinRTServer;
@@ -63,7 +63,7 @@ public uint Release()
private static class Impl
{
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
- public delegate int QueryInterfaceDelegate(BaseClassFactoryProxy* @this, Guid* riid, void** ppvObject);
+ public delegate HRESULT QueryInterfaceDelegate(BaseClassFactoryProxy* @this, Guid* riid, void** ppvObject);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate uint AddRefDelegate(BaseClassFactoryProxy* @this);
@@ -72,10 +72,10 @@ private static class Impl
public delegate uint ReleaseDelegate(BaseClassFactoryProxy* @this);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
- public delegate int CreateInstanceDelegate(BaseClassFactoryProxy* @this, IUnknown* pUnkOuter, Guid* riid, void** ppvObject);
+ public delegate HRESULT CreateInstanceDelegate(BaseClassFactoryProxy* @this, IUnknown* pUnkOuter, Guid* riid, void** ppvObject);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
- public delegate int LockServerDelegate(BaseClassFactoryProxy* @this, int fLock);
+ public delegate HRESULT LockServerDelegate(BaseClassFactoryProxy* @this, int fLock);
///
/// The cached for IUnknown.QueryInterface(REFIID, void**).
@@ -99,19 +99,19 @@ private static class Impl
///
/// Implements IUnknown.QueryInterface(REFIID, void**).
///
- private static int QueryInterface(BaseClassFactoryProxy* @this, Guid* riid, void** ppvObject)
+ private static HRESULT QueryInterface(BaseClassFactoryProxy* @this, Guid* riid, void** ppvObject)
{
- if (riid->Equals(__uuidof()) ||
- riid->Equals(__uuidof()))
+ if (riid->Equals(IUnknown.IID_Guid) ||
+ riid->Equals(IClassFactory.IID_Guid))
{
_ = Interlocked.Increment(ref Unsafe.As(ref @this->_referenceCount));
*ppvObject = @this;
- return S.S_OK;
+ return HRESULT.S_OK;
}
- return E.E_NOINTERFACE;
+ return HRESULT.E_NOINTERFACE;
}
///
@@ -139,30 +139,30 @@ public static uint Release(BaseClassFactoryProxy* @this)
return referenceCount;
}
- public static int CreateInstance(BaseClassFactoryProxy* @this, IUnknown* pUnkOuter, Guid* riid, void** ppvObject)
+ public static HRESULT CreateInstance(BaseClassFactoryProxy* @this, IUnknown* pUnkOuter, Guid* riid, void** ppvObject)
{
try
{
if (pUnkOuter is not null)
{
- return WinError.CLASS_E_NOAGGREGATION;
+ return HRESULT.CLASS_E_NOAGGREGATION;
}
BaseClassFactory? factory = Unsafe.As(@this->_factory.Target);
if (factory is null)
{
- return E.E_HANDLE;
+ return HRESULT.E_HANDLE;
}
- if (!riid->Equals(__uuidof()) && !riid->Equals(factory.Iid))
+ if (!riid->Equals(IUnknown.IID_Guid) && !riid->Equals(factory.Iid))
{
- return E.E_NOINTERFACE;
+ return HRESULT.E_NOINTERFACE;
}
var instance = factory.CreateInstance();
- if (riid->Equals(__uuidof()))
+ if (riid->Equals(IUnknown.IID_Guid))
{
*ppvObject = (void*)Marshal.GetIUnknownForObject(instance);
}
@@ -172,7 +172,7 @@ public static int CreateInstance(BaseClassFactoryProxy* @this, IUnknown* pUnkOut
if (t is null)
{
- return E.E_UNEXPECTED;
+ return HRESULT.E_UNEXPECTED;
}
*ppvObject = (void*)Marshal.GetComInterfaceForObject(instance, t);
@@ -182,12 +182,12 @@ public static int CreateInstance(BaseClassFactoryProxy* @this, IUnknown* pUnkOut
}
catch (Exception e)
{
- return Marshal.GetHRForException(e);
+ return (HRESULT)Marshal.GetHRForException(e);
}
- return S.S_OK;
+ return HRESULT.S_OK;
}
- public static int LockServer(BaseClassFactoryProxy* @this, int fLock)
+ public static HRESULT LockServer(BaseClassFactoryProxy* @this, int fLock)
{
try
{
@@ -202,9 +202,9 @@ public static int LockServer(BaseClassFactoryProxy* @this, int fLock)
}
catch (Exception e)
{
- return Marshal.GetHRForException(e);
+ return (HRESULT)Marshal.GetHRForException(e);
}
- return S.S_OK;
+ return HRESULT.S_OK;
}
}
}
diff --git a/src/Shmuelie.WinRTServer/NativeMethods.json b/src/Shmuelie.WinRTServer/NativeMethods.json
new file mode 100644
index 0000000..38318d6
--- /dev/null
+++ b/src/Shmuelie.WinRTServer/NativeMethods.json
@@ -0,0 +1,8 @@
+{
+ "$schema": "https://aka.ms/CsWin32.schema.json",
+ "allowMarshaling": false,
+ "comInterop": {
+ "preserveSigMethods": [ "*" ]
+ },
+ "useSafeHandles": false
+}
diff --git a/src/Shmuelie.WinRTServer/NativeMethods.txt b/src/Shmuelie.WinRTServer/NativeMethods.txt
new file mode 100644
index 0000000..1aaebe3
--- /dev/null
+++ b/src/Shmuelie.WinRTServer/NativeMethods.txt
@@ -0,0 +1,24 @@
+WindowsCreateString
+IInspectable
+IUnknown
+IActivationFactory
+E_NOINTERFACE
+S_OK
+E_INVALIDARG
+E_HANDLE
+E_UNEXPECTED
+IClassFactory
+CLASS_E_NOAGGREGATION
+CoAddRefServerProcess
+CoReleaseServerProcess
+IGlobalOptions
+CoCreateInstance
+CoRegisterClassObject
+CoRevokeClassObject
+CoResumeClassObjects
+CoSuspendClassObjects
+RoInitialize
+RoRegisterActivationFactories
+RoRevokeActivationFactories
+S_FALSE
+GLOBALOPT_RO_FLAGS
\ No newline at end of file
diff --git a/src/Shmuelie.WinRTServer/Shmuelie.WinRTServer.csproj b/src/Shmuelie.WinRTServer/Shmuelie.WinRTServer.csproj
index 49450e2..6299a57 100644
--- a/src/Shmuelie.WinRTServer/Shmuelie.WinRTServer.csproj
+++ b/src/Shmuelie.WinRTServer/Shmuelie.WinRTServer.csproj
@@ -16,7 +16,10 @@
-
+
+ all
+ runtime; build; native; contentfiles; analyzers
+
diff --git a/src/Shmuelie.WinRTServer/WinRtServer.cs b/src/Shmuelie.WinRTServer/WinRtServer.cs
index 33ab885..5bc9c4d 100644
--- a/src/Shmuelie.WinRTServer/WinRtServer.cs
+++ b/src/Shmuelie.WinRTServer/WinRtServer.cs
@@ -4,11 +4,11 @@
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Timers;
+using Windows.Win32.System.WinRT;
+using Windows.Win32.System.Com;
+using Windows.Win32.Foundation;
+using static Windows.Win32.PInvoke;
using Shmuelie.Interop.Windows;
-using static Shmuelie.Interop.Windows.ComBaseAPI;
-using static Shmuelie.Interop.Windows.RoAPI;
-using static Shmuelie.Interop.Windows.Windows;
-using static Shmuelie.Interop.Windows.WinString;
namespace Shmuelie.WinRTServer;
@@ -17,13 +17,16 @@ namespace Shmuelie.WinRTServer;
///
///
///
+#if !NETSTANDARD
+[System.Runtime.Versioning.SupportedOSPlatform("windows8.0")]
+#endif
public sealed class WinRtServer : IAsyncDisposable
{
private readonly Dictionary factories = [];
- private readonly DllGetActivationFactory activationFactoryCallbackWrapper;
+ private readonly unsafe Delegate activationFactoryCallbackWrapper;
- private unsafe readonly delegate* unmanaged[Stdcall] activationFactoryCallbackPointer;
+ private unsafe readonly delegate* unmanaged[Stdcall] activationFactoryCallbackPointer;
///
/// Collection of created instances.
@@ -40,7 +43,7 @@ public sealed class WinRtServer : IAsyncDisposable
///
private TaskCompletionSource