diff --git a/PInvoke/WlanApi/WlanApi.Funcs.cs b/PInvoke/WlanApi/WlanApi.Funcs.cs index a87775cb..17394309 100644 --- a/PInvoke/WlanApi/WlanApi.Funcs.cs +++ b/PInvoke/WlanApi/WlanApi.Funcs.cs @@ -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 pNetworkList, IntPtr pReserved = default); /// The WlanSetInterface function sets user-configurable parameters for a specified interface. /// The client's session handle, obtained by a previous call to the WlanOpenHandle function. @@ -5716,14 +5718,14 @@ namespace Vanara.PInvoke [StructLayout(LayoutKind.Sequential)] public struct HWFDSERVICE : IHandle { - private IntPtr handle; + private readonly IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. public HWFDSERVICE(IntPtr preexistingHandle) => handle = preexistingHandle; /// Returns an invalid handle by instantiating a object with . - public static HWFDSERVICE NULL => new HWFDSERVICE(IntPtr.Zero); + public static HWFDSERVICE NULL => new(IntPtr.Zero); /// Gets a value indicating whether this instance is a null handle. public bool IsNull => handle == IntPtr.Zero; @@ -5736,7 +5738,7 @@ namespace Vanara.PInvoke /// Performs an implicit conversion from to . /// The pointer to a handle. /// The result of the conversion. - public static implicit operator HWFDSERVICE(IntPtr h) => new HWFDSERVICE(h); + public static implicit operator HWFDSERVICE(IntPtr h) => new(h); /// Implements the operator !=. /// The first handle. @@ -5764,14 +5766,14 @@ namespace Vanara.PInvoke [StructLayout(LayoutKind.Sequential)] public struct HWFDSESSION : IHandle { - private IntPtr handle; + private readonly IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. public HWFDSESSION(IntPtr preexistingHandle) => handle = preexistingHandle; /// Returns an invalid handle by instantiating a object with . - public static HWFDSESSION NULL => new HWFDSESSION(IntPtr.Zero); + public static HWFDSESSION NULL => new(IntPtr.Zero); /// Gets a value indicating whether this instance is a null handle. public bool IsNull => handle == IntPtr.Zero; @@ -5784,7 +5786,7 @@ namespace Vanara.PInvoke /// Performs an implicit conversion from to . /// The pointer to a handle. /// The result of the conversion. - public static implicit operator HWFDSESSION(IntPtr h) => new HWFDSESSION(h); + public static implicit operator HWFDSESSION(IntPtr h) => new(h); /// Implements the operator !=. /// The first handle. @@ -5812,14 +5814,14 @@ namespace Vanara.PInvoke [StructLayout(LayoutKind.Sequential)] public struct HWLANSESSION : IHandle { - private IntPtr handle; + private readonly IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. public HWLANSESSION(IntPtr preexistingHandle) => handle = preexistingHandle; /// Returns an invalid handle by instantiating a object with . - public static HWLANSESSION NULL => new HWLANSESSION(IntPtr.Zero); + public static HWLANSESSION NULL => new(IntPtr.Zero); /// Gets a value indicating whether this instance is a null handle. public bool IsNull => handle == IntPtr.Zero; @@ -5832,7 +5834,7 @@ namespace Vanara.PInvoke /// Performs an implicit conversion from to . /// The pointer to a handle. /// The result of the conversion. - public static implicit operator HWLANSESSION(IntPtr h) => new HWLANSESSION(h); + public static implicit operator HWLANSESSION(IntPtr h) => new(h); /// Implements the operator !=. /// The first handle. diff --git a/PInvoke/WlanApi/WlanApi.Structs.cs b/PInvoke/WlanApi/WlanApi.Structs.cs index 77b81eb8..5ab0868d 100644 --- a/PInvoke/WlanApi/WlanApi.Structs.cs +++ b/PInvoke/WlanApi/WlanApi.Structs.cs @@ -103,6 +103,15 @@ namespace Vanara.PInvoke /// A DOT11_BSS_TYPE value that indicates the BSS type of the network. public DOT11_BSS_TYPE dot11BssType; + + /// Initializes a new instance of the struct. + /// The SSID of a visible wireless network. + /// A DOT11_BSS_TYPE value that indicates the BSS type of the network. + 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) }; + } } /// A DOT11_SSID structure contains the SSID of an interface. @@ -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 { /// The length, in bytes, of the ucSSID array. public uint uSSIDLength; /// The SSID. DOT11_SSID_MAX_LENGTH is set to 32. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = DOT11_SSID_MAX_LENGTH)] - public byte[] ucSSID; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DOT11_SSID_MAX_LENGTH)] + public string ucSSID; + + /// + public override string ToString() => ucSSID?.Substring(0, (int)uSSIDLength); } /// The EAP_METHOD_TYPE structure contains type, identification, and author information about an EAP method. @@ -3034,6 +3046,20 @@ namespace Vanara.PInvoke [StructLayout(LayoutKind.Sequential)] public class DOT11_NETWORK_LIST { + /// Initializes a new instance of the class. + public DOT11_NETWORK_LIST() { } + + /// + /// Initializes a new instance of the class setting the and fields based on . + /// + /// An array of DOT11_NETWORK structures that contain 802.11 wireless network information. + public DOT11_NETWORK_LIST(DOT11_NETWORK[] network) + { + Network = network; + dwNumberOfItems = (uint)(network?.Length ?? 0); + } + /// Contains the number of items in the Network member. public uint dwNumberOfItems; diff --git a/UnitTests/PInvoke/WlanApi/WlanApiTests.cs b/UnitTests/PInvoke/WlanApi/WlanApiTests.cs index 37fd2832..12d4bb92 100644 --- a/UnitTests/PInvoke/WlanApi/WlanApiTests.cs +++ b/UnitTests/PInvoke/WlanApi/WlanApiTests.cs @@ -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]