Fixed #226 by correcting layout and marshaling for WlanSetFilterList and DOT11_SSID

pull/229/head
dahall 2021-04-26 18:03:45 -06:00
parent 89f5605f65
commit 2ea499979c
3 changed files with 100 additions and 79 deletions

View File

@ -2,6 +2,7 @@
using System.Runtime.InteropServices;
using System.Text;
using Vanara.Extensions;
using Vanara.InteropServices;
namespace Vanara.PInvoke
{
@ -4687,7 +4688,8 @@ namespace Vanara.PInvoke
// hClientHandle, WLAN_FILTER_LIST_TYPE wlanFilterListType, const PDOT11_NETWORK_LIST pNetworkList, PVOID pReserved );
[DllImport(Lib.Wlanapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wlanapi.h", MSDNShortId = "697682c9-cb26-42d6-86b5-d7adebcedc68")]
public static extern Win32Error WlanSetFilterList(HWLANSESSION hClientHandle, WLAN_FILTER_LIST_TYPE wlanFilterListType, [Optional] DOT11_NETWORK_LIST pNetworkList, IntPtr pReserved = default);
public static extern Win32Error WlanSetFilterList(HWLANSESSION hClientHandle, WLAN_FILTER_LIST_TYPE wlanFilterListType,
[In, Optional, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(VanaraCustomMarshaler<DOT11_NETWORK_LIST>))] DOT11_NETWORK_LIST pNetworkList, IntPtr pReserved = default);
/// <summary>The <c>WlanSetInterface</c> function sets user-configurable parameters for a specified interface.</summary>
/// <param name="hClientHandle">The client's session handle, obtained by a previous call to the WlanOpenHandle function.</param>
@ -5716,14 +5718,14 @@ namespace Vanara.PInvoke
[StructLayout(LayoutKind.Sequential)]
public struct HWFDSERVICE : IHandle
{
private IntPtr handle;
private readonly IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="HWFDSERVICE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public HWFDSERVICE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="HWFDSERVICE"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static HWFDSERVICE NULL => new HWFDSERVICE(IntPtr.Zero);
public static HWFDSERVICE NULL => new(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
@ -5736,7 +5738,7 @@ namespace Vanara.PInvoke
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="HWFDSERVICE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HWFDSERVICE(IntPtr h) => new HWFDSERVICE(h);
public static implicit operator HWFDSERVICE(IntPtr h) => new(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
@ -5764,14 +5766,14 @@ namespace Vanara.PInvoke
[StructLayout(LayoutKind.Sequential)]
public struct HWFDSESSION : IHandle
{
private IntPtr handle;
private readonly IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="HWFDSESSION"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public HWFDSESSION(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="HWFDSESSION"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static HWFDSESSION NULL => new HWFDSESSION(IntPtr.Zero);
public static HWFDSESSION NULL => new(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
@ -5784,7 +5786,7 @@ namespace Vanara.PInvoke
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="HWFDSESSION"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HWFDSESSION(IntPtr h) => new HWFDSESSION(h);
public static implicit operator HWFDSESSION(IntPtr h) => new(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
@ -5812,14 +5814,14 @@ namespace Vanara.PInvoke
[StructLayout(LayoutKind.Sequential)]
public struct HWLANSESSION : IHandle
{
private IntPtr handle;
private readonly IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="HWLANSESSION"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public HWLANSESSION(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="HWLANSESSION"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static HWLANSESSION NULL => new HWLANSESSION(IntPtr.Zero);
public static HWLANSESSION NULL => new(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
@ -5832,7 +5834,7 @@ namespace Vanara.PInvoke
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="HWLANSESSION"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HWLANSESSION(IntPtr h) => new HWLANSESSION(h);
public static implicit operator HWLANSESSION(IntPtr h) => new(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>

View File

@ -103,6 +103,15 @@ namespace Vanara.PInvoke
/// <summary>A DOT11_BSS_TYPE value that indicates the BSS type of the network.</summary>
public DOT11_BSS_TYPE dot11BssType;
/// <summary>Initializes a new instance of the <see cref="DOT11_NETWORK"/> struct.</summary>
/// <param name="ssid">The SSID of a visible wireless network.</param>
/// <param name="bssType">A DOT11_BSS_TYPE value that indicates the BSS type of the network.</param>
public DOT11_NETWORK(string ssid, DOT11_BSS_TYPE bssType = DOT11_BSS_TYPE.dot11_BSS_type_infrastructure)
{
dot11BssType = bssType;
dot11Ssid = new DOT11_SSID { ucSSID = ssid, uSSIDLength = (uint)(ssid?.Length ?? 0) };
}
}
/// <summary>A <c>DOT11_SSID</c> structure contains the SSID of an interface.</summary>
@ -119,15 +128,18 @@ namespace Vanara.PInvoke
// https://docs.microsoft.com/en-us/windows/win32/nativewifi/dot11-ssid typedef struct _DOT11_SSID { ULONG uSSIDLength; UCHAR
// ucSSID[DOT11_SSID_MAX_LENGTH]; } DOT11_SSID, *PDOT11_SSID;
[PInvokeData("wlantypes.h", MSDNShortId = "f2b15ef9-99ee-4505-8575-224112024d7a")]
[StructLayout(LayoutKind.Sequential)]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct DOT11_SSID
{
/// <summary>The length, in bytes, of the <c>ucSSID</c> array.</summary>
public uint uSSIDLength;
/// <summary>The SSID. DOT11_SSID_MAX_LENGTH is set to 32.</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = DOT11_SSID_MAX_LENGTH)]
public byte[] ucSSID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = DOT11_SSID_MAX_LENGTH)]
public string ucSSID;
/// <inheritdoc/>
public override string ToString() => ucSSID?.Substring(0, (int)uSSIDLength);
}
/// <summary>The <c>EAP_METHOD_TYPE</c> structure contains type, identification, and author information about an EAP method.</summary>
@ -3034,6 +3046,20 @@ namespace Vanara.PInvoke
[StructLayout(LayoutKind.Sequential)]
public class DOT11_NETWORK_LIST
{
/// <summary>Initializes a new instance of the <see cref="DOT11_NETWORK_LIST"/> class.</summary>
public DOT11_NETWORK_LIST() { }
/// <summary>
/// Initializes a new instance of the <see cref="DOT11_NETWORK_LIST"/> class setting the <see cref="Network"/> and <see
/// cref="dwNumberOfItems"/> fields based on <paramref name="network"/>.
/// </summary>
/// <param name="network">An array of DOT11_NETWORK structures that contain 802.11 wireless network information.</param>
public DOT11_NETWORK_LIST(DOT11_NETWORK[] network)
{
Network = network;
dwNumberOfItems = (uint)(network?.Length ?? 0);
}
/// <summary>Contains the number of items in the <c>Network</c> member.</summary>
public uint dwNumberOfItems;

View File

@ -112,19 +112,16 @@ namespace WlanApi
}
[Test]
public void WlanGetFilterListTest()
public void WlanGetFilterListTest([Values] WLAN_FILTER_LIST_TYPE listType)
{
foreach (WLAN_FILTER_LIST_TYPE e in Enum.GetValues(typeof(WLAN_FILTER_LIST_TYPE)))
Assert.That(WlanGetFilterList(hWlan, listType, default, out var list), ResultIs.Successful);
if (list is null)
TestContext.WriteLine($"{listType} => [none]");
else
{
Assert.That(WlanGetFilterList(hWlan, e, default, out var list), ResultIs.Successful);
if (list is null)
TestContext.WriteLine($"{e} => [none]");
else
{
Assert.That(list.dwNumberOfItems, Is.GreaterThan(0U));
Assert.That(list.Network.Length, Is.EqualTo(list.dwNumberOfItems));
TestContext.WriteLine("{0} => {1}", e, string.Join(", ", list.Network.Select(n => $"{n.dot11BssType}")));
}
Assert.That(list.dwNumberOfItems, Is.GreaterThan(0U));
Assert.That(list.Network.Length, Is.EqualTo(list.dwNumberOfItems));
TestContext.WriteLine("{0} => {1}", listType, string.Join(", ", list.Network.Select(n => $"{n.dot11Ssid} : {n.dot11BssType}")));
}
}
@ -180,14 +177,11 @@ namespace WlanApi
}
[Test]
public void WlanGetSecuritySettingsTest()
public void WlanGetSecuritySettingsTest([Values] WLAN_SECURABLE_OBJECT e)
{
foreach (WLAN_SECURABLE_OBJECT e in Enum.GetValues(typeof(WLAN_SECURABLE_OBJECT)))
{
if (e == WLAN_SECURABLE_OBJECT.WLAN_SECURABLE_OBJECT_COUNT) continue;
Assert.That(WlanGetSecuritySettings(hWlan, e, out var value, out var sddl, out var access), ResultIs.Successful);
TestContext.WriteLine($"{e}: {access}, {value}\n\t{sddl}");
}
if (e == WLAN_SECURABLE_OBJECT.WLAN_SECURABLE_OBJECT_COUNT) return;
Assert.That(WlanGetSecuritySettings(hWlan, e, out var value, out var sddl, out var access), ResultIs.Successful);
TestContext.WriteLine($"{e}: {access}, {value}\n\t{sddl}");
}
[Test]
@ -202,17 +196,14 @@ namespace WlanApi
}
[Test]
public void WlanHostedNetworkQueryPropertyTest()
public void WlanHostedNetworkQueryPropertyTest([Values] WLAN_HOSTED_NETWORK_OPCODE e)
{
foreach (WLAN_HOSTED_NETWORK_OPCODE e in Enum.GetValues(typeof(WLAN_HOSTED_NETWORK_OPCODE)))
{
var err = WlanHostedNetworkQueryProperty(hWlan, e, out var sz, out var data, out var type);
if (err == Win32Error.ERROR_BAD_CONFIGURATION) continue;
Assert.That(err, ResultIs.Successful);
TestContext.WriteLine($"{e} = {type}");
var t = CorrespondingTypeAttribute.GetCorrespondingTypes(e, CorrespondingAction.Get).First();
data.DangerousGetHandle().Convert(sz, t).WriteValues();
}
var err = WlanHostedNetworkQueryProperty(hWlan, e, out var sz, out var data, out var type);
if (err == Win32Error.ERROR_BAD_CONFIGURATION) return;
Assert.That(err, ResultIs.Successful);
TestContext.WriteLine($"{e} = {type}");
var t = CorrespondingTypeAttribute.GetCorrespondingTypes(e, CorrespondingAction.Get).First();
data.DangerousGetHandle().Convert(sz, t).WriteValues();
}
[Test]
@ -268,29 +259,23 @@ namespace WlanApi
}
[Test]
public void WlanQueryAutoConfigParameterTest()
public void WlanQueryAutoConfigParameterTest([Values] WLAN_AUTOCONF_OPCODE e)
{
foreach (WLAN_AUTOCONF_OPCODE e in Enum.GetValues(typeof(WLAN_AUTOCONF_OPCODE)))
{
var t = CorrespondingTypeAttribute.GetCorrespondingTypes(e, CorrespondingAction.Get).FirstOrDefault();
if (t is null) continue;
Assert.That(WlanQueryAutoConfigParameter(hWlan, e, default, out var sz, out var data, out var type), ResultIs.Successful);
TestContext.WriteLine($"{e} = {type}");
data.DangerousGetHandle().Convert(sz, t).WriteValues();
}
var t = CorrespondingTypeAttribute.GetCorrespondingTypes(e, CorrespondingAction.Get).FirstOrDefault();
if (t is null) return;
Assert.That(WlanQueryAutoConfigParameter(hWlan, e, default, out var sz, out var data, out var type), ResultIs.Successful);
TestContext.WriteLine($"{e} = {type}");
data.DangerousGetHandle().Convert(sz, t).WriteValues();
}
[Test]
public void WlanQueryInterfaceTest()
public void WlanQueryInterfaceTest([Values] WLAN_INTF_OPCODE e)
{
foreach (WLAN_INTF_OPCODE e in Enum.GetValues(typeof(WLAN_INTF_OPCODE)))
{
var t = CorrespondingTypeAttribute.GetCorrespondingTypes(e, CorrespondingAction.Get).FirstOrDefault();
if (t is null) continue;
if (WlanQueryInterface(hWlan, PrimaryInterface, e, default, out var sz, out var data, out var type).Failed) continue;
TestContext.WriteLine($"{e} = {type}");
data.DangerousGetHandle().Convert(sz, t).WriteValues();
}
var t = CorrespondingTypeAttribute.GetCorrespondingTypes(e, CorrespondingAction.Get).FirstOrDefault();
if (t is null) return;
if (WlanQueryInterface(hWlan, PrimaryInterface, e, default, out var sz, out var data, out var type).Failed) return;
TestContext.WriteLine($"{e} = {type}");
data.DangerousGetHandle().Convert(sz, t).WriteValues();
}
[Test]
@ -304,10 +289,7 @@ namespace WlanApi
{
Assert.That(WlanRegisterNotification(hWlan, WLAN_NOTIFICATION_SOURCE.WLAN_NOTIFICATION_SOURCE_ALL, true, Callback, default, default, out var prev), ResultIs.Successful);
void Callback(ref WLAN_NOTIFICATION_DATA Arg1, IntPtr Arg2)
{
Arg1.WriteValues();
}
static void Callback(ref WLAN_NOTIFICATION_DATA Arg1, IntPtr Arg2) => Arg1.WriteValues();
}
[Test]
@ -338,33 +320,44 @@ namespace WlanApi
}
[Test]
public void WlanSetAutoConfigParameterTest()
public void WlanSetAutoConfigParameterTest([Values] WLAN_AUTOCONF_OPCODE e)
{
foreach (WLAN_AUTOCONF_OPCODE e in Enum.GetValues(typeof(WLAN_AUTOCONF_OPCODE)))
{
var t = CorrespondingTypeAttribute.GetCorrespondingTypes(e, CorrespondingAction.Set).FirstOrDefault();
if (t is null) continue;
Assert.That(WlanQueryAutoConfigParameter(hWlan, e, default, out var sz, out var data, out var type), ResultIs.Successful);
Assert.That(WlanSetAutoConfigParameter(hWlan, e, sz, data), ResultIs.Successful);
}
var t = CorrespondingTypeAttribute.GetCorrespondingTypes(e, CorrespondingAction.Set).FirstOrDefault();
if (t is null) return;
Assert.That(WlanQueryAutoConfigParameter(hWlan, e, default, out var sz, out var data, out var type), ResultIs.Successful);
Assert.That(WlanSetAutoConfigParameter(hWlan, e, sz, data), ResultIs.Successful);
}
[Test]
public void WlanSetFilterListTest()
{
Assert.That(WlanGetFilterList(hWlan, WLAN_FILTER_LIST_TYPE.wlan_filter_list_type_user_permit, default, out var filters), ResultIs.Successful);
Assert.That(WlanSetFilterList(hWlan, WLAN_FILTER_LIST_TYPE.wlan_filter_list_type_user_permit, null), ResultIs.Successful);
Assert.That(WlanGetFilterList(hWlan, WLAN_FILTER_LIST_TYPE.wlan_filter_list_type_user_permit, default, out var clearedfilters), ResultIs.Successful);
Assert.That(clearedfilters.dwNumberOfItems, Is.EqualTo(0U));
DOT11_NETWORK_LIST allow_filters = new(new DOT11_NETWORK[]
{
new("TestFilter1", DOT11_BSS_TYPE.dot11_BSS_type_infrastructure),
new("TestFilter2", DOT11_BSS_TYPE.dot11_BSS_type_infrastructure),
new("TestFilter3", DOT11_BSS_TYPE.dot11_BSS_type_infrastructure),
});
Assert.That(WlanSetFilterList(hWlan, WLAN_FILTER_LIST_TYPE.wlan_filter_list_type_user_permit, allow_filters), ResultIs.Successful);
Assert.That(WlanGetFilterList(hWlan, WLAN_FILTER_LIST_TYPE.wlan_filter_list_type_user_permit, default, out var addedfilters), ResultIs.Successful);
Assert.That(addedfilters.dwNumberOfItems, Is.EqualTo(allow_filters.dwNumberOfItems));
Assert.That(WlanSetFilterList(hWlan, WLAN_FILTER_LIST_TYPE.wlan_filter_list_type_user_permit, filters), ResultIs.Successful);
}
[Test]
public void WlanSetInterfaceTest()
public void WlanSetInterfaceTest([Values] WLAN_INTF_OPCODE e)
{
foreach (WLAN_INTF_OPCODE e in Enum.GetValues(typeof(WLAN_INTF_OPCODE)))
{
var t = CorrespondingTypeAttribute.GetCorrespondingTypes(e, CorrespondingAction.Set).FirstOrDefault();
if (t is null || e == WLAN_INTF_OPCODE.wlan_intf_opcode_radio_state) continue;
if (WlanQueryInterface(hWlan, PrimaryInterface, e, default, out var sz, out var data, out var type).Failed) continue;
Assert.That(WlanSetInterface(hWlan, PrimaryInterface, e, sz, data), ResultIs.Successful);
}
var t = CorrespondingTypeAttribute.GetCorrespondingTypes(e, CorrespondingAction.Set).FirstOrDefault();
if (t is null || e == WLAN_INTF_OPCODE.wlan_intf_opcode_radio_state) return;
if (WlanQueryInterface(hWlan, PrimaryInterface, e, default, out var sz, out var data, out _).Failed) return;
Assert.That(WlanSetInterface(hWlan, PrimaryInterface, e, sz, data), ResultIs.Successful);
}
[Test]