Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .agents/skills/cswin32-com/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ attaches it to every generated COM struct **only on .NET 7+**. On net472:

public unsafe partial struct IUnknown : IComIID
{
readonly Guid IComIID.Guid => IID_Guid; // CsWin32-emitted field, always present
readonly ref readonly Guid IComIID.Guid
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref Unsafe.AsRef(in IID_Guid); // CsWin32-emitted field, always present
}
}
```

Expand Down
7 changes: 6 additions & 1 deletion .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,12 @@ jobs:
uses: codecov/codecov-action@v5
with:
files: artifacts/coverage/Cobertura.xml
fail_ci_if_error: true
# Coverage upload is informational and must not gate the build. The
# Codecov uploader has an intermittent sha256/GPG signature race on the
# CDN that hard-fails otherwise unrelated PRs (Codecov-side bug, "no
# security issue" per the maintainers):
# https://github.com/codecov/codecov-action/issues/1940
fail_ci_if_error: false
disable_search: true
token: ${{ secrets.CODECOV_TOKEN }}
- name: Upload raw logs
Expand Down
12 changes: 6 additions & 6 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="KlutzyNinja.Touki" Version="0.2.0-alpha.1" />
<PackageVersion Include="BenchmarkDotNet" Version="0.15.2" />
<PackageVersion Include="KlutzyNinja.Touki" Version="0.3.0-alpha.1" />
<PackageVersion Include="BenchmarkDotNet" Version="0.15.8" />
<PackageVersion Include="AwesomeAssertions" Version="9.4.0" />
<PackageVersion Include="Microsoft.Build" Version="17.14.8" />
<PackageVersion Include="Microsoft.CodeAnalysis.ResxSourceGenerator" Version="5.0.0-1.25277.114" />
<PackageVersion Include="Microsoft.CSharp" Version="4.7.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="10.0.300" />
<PackageVersion Include="Microsoft.Testing.Extensions.CodeCoverage" Version="18.7.0" />
<PackageVersion Include="Microsoft.Windows.CsWin32" Version="0.3.242" />
<PackageVersion Include="MinVer" Version="6.0.0" />
<PackageVersion Include="Microsoft.Windows.CsWin32" Version="0.3.275" />
<PackageVersion Include="MinVer" Version="7.0.0" />
<PackageVersion Include="MSTest" Version="4.2.3" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != '$(DotNetCoreVersion)'">
<PackageVersion Include="Microsoft.Bcl.HashCode" Version="6.0.0" />
<PackageVersion Include="Microsoft.Bcl.Memory" Version="10.0.7" />
<PackageVersion Include="Microsoft.Bcl.Memory" Version="10.0.8" />
<PackageVersion Include="Microsoft.IO.Redist" Version="6.1.3" />
<PackageVersion Include="PolySharp" Version="1.15.0" />
<PackageVersion Include="System.Memory" Version="4.6.3" />
Expand Down
2 changes: 1 addition & 1 deletion madowaku/Framework/Windows/Win32/IComIID.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ public interface IComIID
/// <summary>
/// The identifier (IID) GUID for this interface.
/// </summary>
Guid Guid { get; }
ref readonly Guid Guid { get; }
}
}
6 changes: 5 additions & 1 deletion madowaku/Framework/Windows/Win32/System/Com/IUnknown.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@ namespace Windows.Win32.System.Com;
/// </summary>
public unsafe partial struct IUnknown : IComIID
{
readonly Guid IComIID.Guid => IID_Guid;
readonly ref readonly Guid IComIID.Guid
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref Unsafe.AsRef(in IID_Guid);
}
}
6 changes: 5 additions & 1 deletion madowaku/Framework/Windows/Win32/System/Ole/IRecordInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@ namespace Windows.Win32.System.Ole;
/// </summary>
public partial struct IRecordInfo : IComIID
{
readonly Guid IComIID.Guid => IID_Guid;
readonly ref readonly Guid IComIID.Guid
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref Unsafe.AsRef(in IID_Guid);
}
}
32 changes: 25 additions & 7 deletions madowaku/Windows/Win32/Foundation/IID.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,37 @@ private static ref readonly Guid IID_NULL
}
}

// We cast away the "readonly" here as there is no way to communicate that through a pointer and
// Marshal APIs take the Guid as ref. Even though none of our usages actually change the state.

/// <summary>
/// Gets a pointer to the IID <see cref="Guid"/> for the given <typeparamref name="T"/>.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Guid* Get<T>() where T : unmanaged, IComIID
{
#if NET
return (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in T.Guid));
#else
return (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in default(T).Guid));
#endif
}

/// <summary>
/// Gets a reference to the IID <see cref="Guid"/> for the given <typeparamref name="T"/>.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Guid Get<T>() where T : unmanaged, IComIID
public static ref readonly Guid GetRef<T>() where T : unmanaged, IComIID
{
#if NETFRAMEWORK
// In .NET Framework we need to use the interface to get the Guid.
return default(T).Guid;
#if NET
return ref T.Guid;
#else
return T.Guid;
return ref default(T).Guid;
Comment thread
JeremyKuhne marked this conversation as resolved.
#endif
}

/// <summary>
/// Empty <see cref="Guid"/>.
/// Empty <see cref="Guid"/> (GUID_NULL in docs).
/// </summary>
public static Guid* Empty() => (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in IID_NULL));
public static Guid* NULL() => (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in IID_NULL));
}
3 changes: 1 addition & 2 deletions madowaku/Windows/Win32/System/Com/ComClassFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,8 @@ public ComScope<TInterface> CreateInstance<TInterface>()
public ComScope<TInterface> TryCreateInstance<TInterface>(out HRESULT result)
where TInterface : unmanaged, IComIID
{
Guid iid = IID.Get<TInterface>();
ComScope<TInterface> scope = default;
result = _classFactory->CreateInstance(null, &iid, scope);
result = _classFactory->CreateInstance(null, IID.Get<TInterface>(), scope);
return scope;
}

Expand Down
3 changes: 1 addition & 2 deletions madowaku/Windows/Win32/System/Com/ComScope{T}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,8 @@ public ComScope<TInterface> QueryInterface<TInterface>() where TInterface : unma
/// </summary>
public ComScope<TInterface> TryQueryInterface<TInterface>(out HRESULT result) where TInterface : unmanaged, IComIID
{
Guid iid = IID.Get<TInterface>();
ComScope<TInterface> scope = new(null);
result = ((IUnknown*)Pointer)->QueryInterface(&iid, scope);
result = ((IUnknown*)Pointer)->QueryInterface(IID.Get<TInterface>(), scope);
return scope;
}

Expand Down
7 changes: 2 additions & 5 deletions madowaku/Windows/Win32/System/Com/GlobalInterfaceTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,9 @@ public static uint RegisterInterface<TInterface>(TInterface* @interface)
where TInterface : unmanaged, IComIID
{
uint cookie;
Guid iid = IID.Get<TInterface>();

s_globalInterfaceTable->RegisterInterfaceInGlobal(
(IUnknown*)@interface,
&iid,
IID.Get<TInterface>(),
&cookie).ThrowOnFailure();

return cookie;
Expand All @@ -61,9 +59,8 @@ public static uint RegisterInterface<TInterface>(TInterface* @interface)
public static ComScope<TInterface> GetInterface<TInterface>(uint cookie, out HRESULT result)
where TInterface : unmanaged, IComIID
{
Guid iid = IID.Get<TInterface>();
ComScope<TInterface> @interface = new(null);
result = s_globalInterfaceTable->GetInterfaceFromGlobal(cookie, &iid, (void**)&@interface);
result = s_globalInterfaceTable->GetInterfaceFromGlobal(cookie, IID.Get<TInterface>(), (void**)&@interface);
return @interface;
}

Expand Down
Loading