diff --git a/src/Foundry.Connect.Tests/NativeWifiApiTests.cs b/src/Foundry.Connect.Tests/NativeWifiApiTests.cs new file mode 100644 index 000000000..8e3ce4e9e --- /dev/null +++ b/src/Foundry.Connect.Tests/NativeWifiApiTests.cs @@ -0,0 +1,27 @@ +// Copyright (c) Foundry Project contributors. +// Licensed under the MIT License. +// See the LICENSE file in the project root for more information. + +using System.Reflection; +using Foundry.Connect.Services.Network; + +namespace Foundry.Connect.Tests; + +public sealed class NativeWifiApiTests +{ + // wlanapi takes interface identifiers as const GUID*. A by-value Guid only reaches the callee as a + // pointer under the x64 calling convention; ARM64 passes it in two registers and every call fails. + [Fact] + public void WlanImports_PassInterfaceGuidsByReference() + { + MethodInfo[] imports = typeof(NativeWifiApi) + .GetMethods(BindingFlags.Static | BindingFlags.NonPublic) + .Where(static method => method.Attributes.HasFlag(MethodAttributes.PinvokeImpl)) + .ToArray(); + + Assert.NotEmpty(imports); + Assert.DoesNotContain( + imports.SelectMany(static method => method.GetParameters()), + static parameter => parameter.ParameterType == typeof(Guid)); + } +} diff --git a/src/Foundry.Connect/Services/Network/NativeWifiApi.cs b/src/Foundry.Connect/Services/Network/NativeWifiApi.cs index 68bfa692c..09382d78f 100644 --- a/src/Foundry.Connect/Services/Network/NativeWifiApi.cs +++ b/src/Foundry.Connect/Services/Network/NativeWifiApi.cs @@ -12,6 +12,11 @@ namespace Foundry.Connect.Services.Network; /// /// Provides the native WLAN API calls used by Foundry.Connect to discover and inspect Wi-Fi state. /// +/// +/// Interface identifiers must be declared as because wlanapi expects +/// const GUID*. A by-value only works on x64, where the calling convention happens to +/// pass 16-byte structures by reference; ARM64 passes them in registers and the calls fail. +/// internal static class NativeWifiApi { private const uint ClientVersion = 2; @@ -404,7 +409,7 @@ private static extern uint WlanEnumInterfaces( [DllImport("wlanapi.dll")] private static extern uint WlanGetAvailableNetworkList( IntPtr clientHandle, - Guid interfaceGuid, + in Guid interfaceGuid, uint flags, IntPtr reserved, out IntPtr availableNetworkList); @@ -412,7 +417,7 @@ private static extern uint WlanGetAvailableNetworkList( [DllImport("wlanapi.dll")] private static extern uint WlanScan( IntPtr clientHandle, - Guid interfaceGuid, + in Guid interfaceGuid, IntPtr dot11Ssid, IntPtr ieData, IntPtr reserved); @@ -420,7 +425,7 @@ private static extern uint WlanScan( [DllImport("wlanapi.dll")] private static extern uint WlanQueryInterface( IntPtr clientHandle, - Guid interfaceGuid, + in Guid interfaceGuid, WlanIntfOpcode opCode, IntPtr reserved, out uint dataSize,