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
27 changes: 27 additions & 0 deletions src/Foundry.Connect.Tests/NativeWifiApiTests.cs
Original file line number Diff line number Diff line change
@@ -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));
}
}
11 changes: 8 additions & 3 deletions src/Foundry.Connect/Services/Network/NativeWifiApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ namespace Foundry.Connect.Services.Network;
/// <summary>
/// Provides the native WLAN API calls used by Foundry.Connect to discover and inspect Wi-Fi state.
/// </summary>
/// <remarks>
/// Interface identifiers must be declared as <see langword="in"/> <see cref="Guid"/> because wlanapi expects
/// <c>const GUID*</c>. A by-value <see cref="Guid"/> 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.
/// </remarks>
internal static class NativeWifiApi
{
private const uint ClientVersion = 2;
Expand Down Expand Up @@ -404,23 +409,23 @@ 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);

[DllImport("wlanapi.dll")]
private static extern uint WlanScan(
IntPtr clientHandle,
Guid interfaceGuid,
in Guid interfaceGuid,
IntPtr dot11Ssid,
IntPtr ieData,
IntPtr reserved);

[DllImport("wlanapi.dll")]
private static extern uint WlanQueryInterface(
IntPtr clientHandle,
Guid interfaceGuid,
in Guid interfaceGuid,
WlanIntfOpcode opCode,
IntPtr reserved,
out uint dataSize,
Expand Down
Loading