From b0bc4e5dba3dc0d63074eda25a12b865e9dcd032 Mon Sep 17 00:00:00 2001 From: "Joshua \"Yoshi\" Askharoun" Date: Sat, 25 Jul 2026 13:51:37 -0500 Subject: [PATCH] [WIP] Fix net48 build --- UIX/Microsoft/Iris/OS/CLR/NativeMethods.cs | 3 - .../Iris/OS/CLR/UnsafeNativeMethods.cs | 3 - UIXrender/Interop/EngineApi.cs | 4 ++ UIXrender/Subsystems/Assets/ExtensionsApi.cs | 4 ++ UIXrender/Subsystems/Assets/WaveParser.cs | 56 +++++++++++++++++++ UIXrender/Subsystems/Schema/SchemaApi.cs | 4 ++ UIXrender/Subsystems/Schema/SchemaModel.cs | 22 +++++++- UIXrender/Subsystems/Text/RichTextApi.cs | 4 ++ UIXrender/Subsystems/Text/SimpleTextApi.cs | 4 ++ UIXrender/Subsystems/Tracing/TracingApi.cs | 4 ++ UIXrender/Subsystems/Xml/XmlLiteApi.cs | 4 ++ UIXrender/UIXrender.csproj | 16 ++++-- 12 files changed, 114 insertions(+), 14 deletions(-) diff --git a/UIX/Microsoft/Iris/OS/CLR/NativeMethods.cs b/UIX/Microsoft/Iris/OS/CLR/NativeMethods.cs index 7d280df..125689e 100644 --- a/UIX/Microsoft/Iris/OS/CLR/NativeMethods.cs +++ b/UIX/Microsoft/Iris/OS/CLR/NativeMethods.cs @@ -8,9 +8,6 @@ using System.Security.Permissions; namespace Microsoft.Iris.OS.CLR { -#if WINDOWS - [HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)] -#endif internal static class NativeMethods { public const int S_OK = 0; diff --git a/UIX/Microsoft/Iris/OS/CLR/UnsafeNativeMethods.cs b/UIX/Microsoft/Iris/OS/CLR/UnsafeNativeMethods.cs index 6150c10..f2e94b4 100644 --- a/UIX/Microsoft/Iris/OS/CLR/UnsafeNativeMethods.cs +++ b/UIX/Microsoft/Iris/OS/CLR/UnsafeNativeMethods.cs @@ -13,9 +13,6 @@ using System.Security.Permissions; namespace Microsoft.Iris.OS.CLR { [SuppressUnmanagedCodeSecurity] -#if WINDOWS - [HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)] -#endif internal static class UnsafeNativeMethods { [DllImport("Ole32.dll")] diff --git a/UIXrender/Interop/EngineApi.cs b/UIXrender/Interop/EngineApi.cs index 64dda1f..fdaa14e 100644 --- a/UIXrender/Interop/EngineApi.cs +++ b/UIXrender/Interop/EngineApi.cs @@ -1,3 +1,5 @@ +#if NETCOREAPP + using System; using System.Runtime.InteropServices; using Microsoft.Iris.Interop; @@ -215,3 +217,5 @@ public static unsafe class EngineApi release(pUnknown); } } + +#endif diff --git a/UIXrender/Subsystems/Assets/ExtensionsApi.cs b/UIXrender/Subsystems/Assets/ExtensionsApi.cs index 3110649..41f9f60 100644 --- a/UIXrender/Subsystems/Assets/ExtensionsApi.cs +++ b/UIXrender/Subsystems/Assets/ExtensionsApi.cs @@ -1,3 +1,5 @@ +#if NETCOREAPP + using System; using System.IO; using System.Runtime.InteropServices; @@ -148,3 +150,5 @@ internal sealed class LoadedSound(IntPtr samples) : IDisposable } } } + +#endif diff --git a/UIXrender/Subsystems/Assets/WaveParser.cs b/UIXrender/Subsystems/Assets/WaveParser.cs index 23bd9ee..64e2c5a 100644 --- a/UIXrender/Subsystems/Assets/WaveParser.cs +++ b/UIXrender/Subsystems/Assets/WaveParser.cs @@ -12,6 +12,7 @@ internal static class WaveParser { private const ushort WAVE_FORMAT_PCM = 1; +#if NETCOREAPP public static bool TryParse(ReadOnlySpan source, out SoundHeader header, out byte[] samples) { header = default; @@ -57,6 +58,61 @@ internal static class WaveParser offset = body + (int)chunkSize + ((chunkSize & 1) != 0 ? 1 : 0); } + // Only uncompressed PCM is representable through this surface -- the managed side + // declares WAVE_FORMAT_PCM as its sole format constant, so anything else would be + // silently misinterpreted downstream rather than merely unsupported. + return haveFormat && samples.Length > 0 && header.formatTag == WAVE_FORMAT_PCM; + } +#endif + + public static bool TryParse(byte[] source, out SoundHeader header, out byte[] samples) + { + header = default; + samples = Array.Empty(); + + // "RIFF" "WAVE" then a chunk list. + if (source.Length < 12 || + !(source[0] == 'R' && source[1] == 'I' && source[2] == 'F' && source[3] == 'F') || + !(source[8] == 'W' && source[9] == 'A' && source[10] == 'V' && source[11] == 'E')) + return false; + + bool haveFormat = false; + int offset = 12; + + while (offset + 8 <= source.Length) + { + string chunkId = System.Text.Encoding.UTF8.GetString(source, offset, 4); + int body = offset + 8; + + var chunkSizeOffset = offset + 4; + //uint chunkSize = source[chunkSizeOffset] | source[chunkSizeOffset + 1]; + uint chunkSize = BinaryPrimitives.ReadUInt32LittleEndian(source.Slice(offset + 4, 4)); + + if (body + chunkSize > source.Length) + chunkSize = (uint)(source.Length - body); + + if (chunkId == "fmt " && chunkSize >= 16) + { + ReadOnlySpan fmt = source.Slice(body, (int)chunkSize); + header.formatTag = BinaryPrimitives.ReadUInt16LittleEndian(fmt[..2]); + header.channels = BinaryPrimitives.ReadUInt16LittleEndian(fmt.Slice(2, 2)); + header.samplesPerSec = BinaryPrimitives.ReadUInt32LittleEndian(fmt.Slice(4, 4)); + header.avgBytesPerSec = BinaryPrimitives.ReadUInt32LittleEndian(fmt.Slice(8, 4)); + header.blockAlign = BinaryPrimitives.ReadUInt16LittleEndian(fmt.Slice(12, 2)); + header.bitsPerSample = BinaryPrimitives.ReadUInt16LittleEndian(fmt.Slice(14, 2)); + header.cbExtraData = chunkSize >= 18 ? BinaryPrimitives.ReadUInt16LittleEndian(fmt.Slice(16, 2)) : (ushort)0; + haveFormat = true; + } + else if (chunkId == "data") + { + samples = source.Slice(body, (int)chunkSize).ToArray(); + header.cbDataSize = chunkSize; + } + + // Chunks are word-aligned: an odd-sized chunk is followed by a pad byte. + offset = body + (int)chunkSize + ((chunkSize & 1) != 0 ? 1 : 0); + } + // Only uncompressed PCM is representable through this surface -- the managed side // declares WAVE_FORMAT_PCM as its sole format constant, so anything else would be // silently misinterpreted downstream rather than merely unsupported. diff --git a/UIXrender/Subsystems/Schema/SchemaApi.cs b/UIXrender/Subsystems/Schema/SchemaApi.cs index efede3e..216639f 100644 --- a/UIXrender/Subsystems/Schema/SchemaApi.cs +++ b/UIXrender/Subsystems/Schema/SchemaApi.cs @@ -1,3 +1,5 @@ +#if NETCOREAPP + using System; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -610,3 +612,5 @@ public static unsafe class SchemaApi return OK; } } + +#endif diff --git a/UIXrender/Subsystems/Schema/SchemaModel.cs b/UIXrender/Subsystems/Schema/SchemaModel.cs index 10ee1d5..fec2744 100644 --- a/UIXrender/Subsystems/Schema/SchemaModel.cs +++ b/UIXrender/Subsystems/Schema/SchemaModel.cs @@ -29,7 +29,11 @@ internal sealed class TypeSchema // from assemblies loaded at runtime via SpLoadDll -- that is the entire point of this // subsystem. Annotating the parameter keeps every member of anything that reaches // here rooted, instead of silently trimming the properties/methods markup binds to. - public TypeSchema([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type, uint id) + public TypeSchema( +#if NETCOREAPP + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] +#endif + Type type, uint id) { Type = type; ID = id; @@ -74,7 +78,13 @@ internal sealed class EnumSchema // at runtime, which can genuinely fail under NativeAOT -- and this project // publishes AOT. The underlying-type overload returns a boxed primitive array, no // dynamic array construction involved. - Array underlying = Enum.GetValuesAsUnderlyingType(type); + Array underlying = +#if NETCOREAPP + Enum.GetValuesAsUnderlyingType(type); +#else + Enum.GetValues(type); +#endif + Values = new int[underlying.Length]; for (int i = 0; i < underlying.Length; i++) Values[i] = Convert.ToInt32(underlying.GetValue(i)); @@ -102,7 +112,11 @@ internal sealed class SchemaRegistration public IReadOnlyList Types => _types; public IReadOnlyList Enums => _enums; - public void Add([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type) + public void Add( +#if NETCOREAPP + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] +#endif + Type type) { if (type.IsEnum) _enums.Add(new EnumSchema(type, (uint)_enums.Count)); @@ -110,6 +124,7 @@ internal sealed class SchemaRegistration _types.Add(new TypeSchema(type, (uint)_types.Count)); } +#if NETCOREAPP // Unavoidably trim-unsafe by design, and suppressed rather than left to warn so a real // future warning isn't lost in the noise: this projects types out of an assembly the // host chose at *runtime* (SpLoadDll), which the trimmer cannot see into by @@ -118,6 +133,7 @@ internal sealed class SchemaRegistration // assembly), not by static analysis of UIXrender. [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Types come from assemblies loaded at runtime via SpLoadDll; the host must root them. See comment above.")] [UnconditionalSuppressMessage("Trimming", "IL2072", Justification = "Types come from assemblies loaded at runtime via SpLoadDll; the host must root them. See comment above.")] +#endif public static SchemaRegistration FromAssembly(Assembly assembly) { var registration = new SchemaRegistration(); diff --git a/UIXrender/Subsystems/Text/RichTextApi.cs b/UIXrender/Subsystems/Text/RichTextApi.cs index 6eee4ae..eca5a87 100644 --- a/UIXrender/Subsystems/Text/RichTextApi.cs +++ b/UIXrender/Subsystems/Text/RichTextApi.cs @@ -1,3 +1,5 @@ +#if NETCOREAPP + using System; using System.Runtime.InteropServices; using Microsoft.Iris.Interop; @@ -341,3 +343,5 @@ public static unsafe class RichTextApi return HRESULT.S_OK; } } + +#endif diff --git a/UIXrender/Subsystems/Text/SimpleTextApi.cs b/UIXrender/Subsystems/Text/SimpleTextApi.cs index df40f5a..cf03dad 100644 --- a/UIXrender/Subsystems/Text/SimpleTextApi.cs +++ b/UIXrender/Subsystems/Text/SimpleTextApi.cs @@ -1,3 +1,5 @@ +#if NETCOREAPP + using System; using System.Runtime.InteropServices; using Microsoft.Iris.Interop; @@ -90,3 +92,5 @@ public static unsafe class SimpleTextApi return HRESULT.S_OK; } } + +#endif diff --git a/UIXrender/Subsystems/Tracing/TracingApi.cs b/UIXrender/Subsystems/Tracing/TracingApi.cs index d0a6df0..7a4c62f 100644 --- a/UIXrender/Subsystems/Tracing/TracingApi.cs +++ b/UIXrender/Subsystems/Tracing/TracingApi.cs @@ -1,3 +1,5 @@ +#if NETCOREAPP + using System.Runtime.InteropServices; using Microsoft.Iris.Interop; @@ -23,3 +25,5 @@ public static unsafe class TracingApi public static void SpLogTrace(char* categoryName, char* message, int indentLevel) => TracingState.LogTrace(NativeString.UniToString(categoryName), NativeString.UniToString(message), indentLevel); } + +#endif diff --git a/UIXrender/Subsystems/Xml/XmlLiteApi.cs b/UIXrender/Subsystems/Xml/XmlLiteApi.cs index a9fd5f7..0f62a34 100644 --- a/UIXrender/Subsystems/Xml/XmlLiteApi.cs +++ b/UIXrender/Subsystems/Xml/XmlLiteApi.cs @@ -1,3 +1,5 @@ +#if NETCOREAPP + using System; using System.Runtime.InteropServices; using System.Text; @@ -183,3 +185,5 @@ public static unsafe class XmlLiteApi return true; } } + +#endif diff --git a/UIXrender/UIXrender.csproj b/UIXrender/UIXrender.csproj index 390841a..f0da195 100644 --- a/UIXrender/UIXrender.csproj +++ b/UIXrender/UIXrender.csproj @@ -22,19 +22,25 @@ - - - + + + + + + all + runtime; build; native; contentfiles; analyzers + - - + \ No newline at end of file