diff --git a/README.md b/README.md
index 5bbffe5..3a5e090 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@ WLAN Profile Viewer is a Windows desktop app to manage wireless LAN profiles. It
##Download
-[Download](https://github.com/emoacht/WlanProfileViewer/releases/download/1.0.0/WlanProfileViewer100.zip)
+[Download](https://github.com/emoacht/WlanProfileViewer/releases/download/1.1.0/WlanProfileViewer110.zip)
##Install
@@ -50,11 +50,13 @@ Settings file will be saved in the following folder.
- [Reactive Extensions][1]
- [Reactive Property][2]
- - [WPF Monitor Aware Window][3]
+ - [Managed Native Wifi][3]
+ - [WPF Monitor Aware Window][4]
[1]: https://github.com/Reactive-Extensions/Rx.NET
[2]: https://github.com/runceel/ReactiveProperty
-[3]: https://github.com/emoacht/WpfMonitorAware
+[3]: https://github.com/emoacht/ManagedNativeWifi
+[4]: https://github.com/emoacht/WpfMonitorAware
##Reference
diff --git a/README_ja.md b/README_ja.md
index 53f65be..3bf4ce1 100644
--- a/README_ja.md
+++ b/README_ja.md
@@ -19,7 +19,7 @@ WLAN Profile Viewerは無線LANプロファイルを管理するためのWindows
##ダウンロード
-[ダウンロード](https://github.com/emoacht/WlanProfileViewer/releases/download/1.0.0/WlanProfileViewer100.zip)
+[ダウンロード](https://github.com/emoacht/WlanProfileViewer/releases/download/1.1.0/WlanProfileViewer110.zip)
##インストール
@@ -50,11 +50,13 @@ WLAN Profile Viewerは無線LANプロファイルを管理するためのWindows
- [Reactive Extensions][1]
- [Reactive Property][2]
- - [WPF Monitor Aware Window][3]
+ - [Managed Native Wifi][3]
+ - [WPF Monitor Aware Window][4]
[1]: https://github.com/Reactive-Extensions/Rx.NET
[2]: https://github.com/runceel/ReactiveProperty
-[3]: https://github.com/emoacht/WpfMonitorAware
+[3]: https://github.com/emoacht/ManagedNativeWifi
+[4]: https://github.com/emoacht/WpfMonitorAware
##参考
diff --git a/ReactivePropertyTest/ReactivePropertyTest.csproj b/ReactivePropertyTest/ReactivePropertyTest.csproj
index 3bdd370..cb27431 100644
--- a/ReactivePropertyTest/ReactivePropertyTest.csproj
+++ b/ReactivePropertyTest/ReactivePropertyTest.csproj
@@ -36,15 +36,15 @@
- ..\packages\ReactiveProperty.2.2.3.1\lib\net45\ReactiveProperty.dll
+ ..\packages\ReactiveProperty.2.2.8\lib\net45\ReactiveProperty.dll
True
- ..\packages\ReactiveProperty.2.2.3.1\lib\net45\ReactiveProperty.DataAnnotations.dll
+ ..\packages\ReactiveProperty.2.2.8\lib\net45\ReactiveProperty.DataAnnotations.dll
True
- ..\packages\ReactiveProperty.2.2.3.1\lib\net45\ReactiveProperty.NET45.dll
+ ..\packages\ReactiveProperty.2.2.8\lib\net45\ReactiveProperty.NET45.dll
True
diff --git a/ReactivePropertyTest/packages.config b/ReactivePropertyTest/packages.config
index 99ac362..88a6a63 100644
--- a/ReactivePropertyTest/packages.config
+++ b/ReactivePropertyTest/packages.config
@@ -1,6 +1,6 @@
-
+
diff --git a/WlanProfileViewer/Library/ManagedNativeWifi.dll b/WlanProfileViewer/Library/ManagedNativeWifi.dll
new file mode 100644
index 0000000..61b47de
Binary files /dev/null and b/WlanProfileViewer/Library/ManagedNativeWifi.dll differ
diff --git a/WlanProfileViewer/Library/ManagedNativeWifi.xml b/WlanProfileViewer/Library/ManagedNativeWifi.xml
new file mode 100644
index 0000000..781200e
--- /dev/null
+++ b/WlanProfileViewer/Library/ManagedNativeWifi.xml
@@ -0,0 +1,544 @@
+
+
+
+ ManagedNativeWifi
+
+
+
+
+ BSS network type
+
+
+
+
+ None
+
+
+
+
+ Infrastructure BSS network
+
+
+
+
+ Independent BSS (IBSS) network (Ad hoc network)
+
+
+
+
+ Any BSS network
+
+
+
+
+ Wireless interface information
+
+
+
+
+ Interface ID
+
+
+
+
+ Interface description
+
+
+
+
+ Interface state
+
+
+
+
+ Constructor
+
+
+
+
+ Wireless interface state
+
+ Equivalent to WLAN_INTERFACE_STATE
+
+
+
+ The interface is not ready to operate.
+
+
+
+
+ The interface is connected to a network.
+
+
+
+
+ The interface is the first node in an ad hoc network. No peer has connected.
+
+
+
+
+ The interface is disconnecting from the current network.
+
+
+
+
+ The interface is not connected to any network.
+
+
+
+
+ The interface is attempting to associate with a network.
+
+
+
+
+ Auto configuration is discovering the settings for the network.
+
+
+
+
+ The interface is in the process of authenticating.
+
+
+
+
+ A managed implementation of Native Wifi API
+
+
+
+
+ Enumerate wireless interface information.
+
+ Wireless interface information
+
+
+
+ Asynchronously request wireless interfaces to scan (rescan) wireless LANs.
+
+ Timeout duration
+ Interface IDs that successfully scanned
+
+
+
+ Asynchronously request wireless interfaces to scan (rescan) wireless LANs.
+
+ Timeout duration
+ Cancellation token
+ Interface IDs that successfully scanned
+
+
+
+ Enumerate SSIDs of available wireless LANs.
+
+ SSIDs
+
+
+
+ Enumerate SSIDs of connected wireless LANs.
+
+ SSIDs
+
+
+
+ Enumerate wireless LAN information on available networks.
+
+ Wireless LAN information
+ If multiple profiles are associated with a same network, there will be multiple
+ entries with the same SSID.
+
+
+
+ Enumerate wireless LAN information on BSS networks.
+
+ Wireless LAN information
+
+
+
+ Enumerate wireless profile names in preference order.
+
+ Wireless profile names
+
+
+
+ Enumerate wireless profile information in preference order.
+
+ Wireless profile information
+
+
+
+ Get a specified wireless profile information.
+
+ Client handle
+ Interface information
+ Profile name
+ Signal quality
+ Position in preference order
+ Whether this profile is connected to a wireless LAN
+ Wireless profile information
+
+ For profile elements, see
+ https://msdn.microsoft.com/en-us/library/windows/desktop/ms707381.aspx
+
+
+
+
+ Set (add or overwrite) the content of a specific profile.
+
+ Interface ID
+ Profile type
+ Profile XML
+ Security descriptor for all-user profile
+ Whether to overwrite an existing profile
+ True if successfully set. False if not.
+
+ If the content of the profile XML is not valid, a Win32Exception will be thrown.
+ In such case, check the reason code in the message and see
+ https://msdn.microsoft.com/en-us/library/windows/desktop/ms707394.aspx
+ https://technet.microsoft.com/en-us/library/3ed3d027-5ae8-4cb0-ade5-0a7c446cd4f7#BKMK_AppndxE
+
+
+
+
+ Set the position of a specified wireless profile in preference order.
+
+ Interface ID
+ Profile name
+ Position (starting from 0)
+ True if successfully set.
+
+
+
+ Delete a specified wireless profile.
+
+ Interface ID
+ Profile name
+ True if successfully deleted. False if could not delete.
+
+
+
+ Attempt to connect to the wireless LAN associated to a specified wireless profile.
+
+ Interface ID
+ Profile name
+ BSS network type
+ True if successfully requested the connection. False if failed.
+
+
+
+ Asynchronously attempt to connect to the wireless LAN associated to a specified wireless profile.
+
+ Interface ID
+ Profile name
+ BSS network type
+ Timeout duration
+ True if successfully connected. False if failed or timed out.
+
+
+
+ Asynchronously attempt to connect to the wireless LAN associated to a specified wireless profile.
+
+ Interface ID
+ Profile name
+ BSS network type
+ Timeout duration
+ Cancellation token
+ True if successfully connected. False if failed or timed out.
+
+
+
+ Disconnect from the wireless LAN associated to a specified wireless interface.
+
+ Interface ID
+ True if successfully requested the disconnection. False if failed.
+
+
+
+ Asynchronously disconnect from the wireless LAN associated to a specified wireless interface.
+
+ Interface ID
+ Timeout duration
+ True if successfully disconnected. False if failed or timed out.
+
+
+
+ Asynchronously disconnect from the wireless LAN associated to a specified wireless interface.
+
+ Interface ID
+ Timeout duration
+ Cancellation token
+ True if successfully disconnected. False if failed or timed out.
+
+
+
+ Detect wireless LAN channel from center frequency.
+
+ Center frequency (KHz)
+ If successfully detected, channel number. If not, 0.
+
+ This method is marked as internal for unit test.
+ As for 5GHz, this method may produce a channel number which is not actually in use.
+ Also, some channel numbers of 5GHz overlap those of 3.6GHz. In such cases, refer
+ the frequency to distinguish them.
+
+
+
+
+ Wireless LAN information
+
+
+
+
+ Associated wireless interface information
+
+
+
+
+ SSID (maximum 32 bytes)
+
+
+
+
+ BSS network type
+
+
+
+
+ Signal quality (0-100)
+
+
+
+
+ Whether security is enabled on this network
+
+
+
+
+ Associated wireless profile name
+
+
+
+
+ Constructor
+
+
+
+
+ Wireless LAN information
+
+
+
+
+ Associated wireless interface information
+
+
+
+
+ SSID (maximum 32 bytes)
+
+
+
+
+ BSS network type
+
+
+
+
+ BSSID (6 bytes)
+
+
+
+
+ Signal strength (RSSI)
+
+
+
+
+ Link quality (0-100)
+
+
+
+
+ Wireless LAN frequency (KHz)
+
+
+
+
+ Wireless LAN channel
+
+
+
+
+ Constructor
+
+
+
+
+ Identifier of wireless LAN
+
+ This class is immutable.
+
+
+
+ Constructor
+
+
+
+
+ Return the identifier in byte array.
+
+ Identifier in byte array
+
+
+
+ Return the identifier in UTF-8 string.
+
+ Identifier in UTF-8 string
+
+
+
+ Wireless profile information
+
+
+
+
+ Profile name
+
+
+
+
+ Associated wireless interface information
+
+
+
+
+ Profile type
+
+
+
+
+ Profile XML
+
+
+
+
+ SSID of associated wireless LAN
+
+
+
+
+ BSS network type of associated wireless LAN
+
+
+
+
+ Authentication type of associated wireless LAN
+
+
+
+
+ Encryption type of associated wireless LAN
+
+
+
+
+ Signal quality of associated wireless LAN
+
+
+
+
+ Position in preference order of associated wireless interface
+
+
+
+
+ Whether this profile is set to be automatically connected
+
+
+
+
+ Whether this profile is currently connected
+
+
+
+
+ Constructor
+
+
+
+
+ Wireless profile type
+
+
+
+
+ All-user profile
+
+
+
+
+ Group policy profile
+
+ Equivalent to WLAN_PROFILE_GROUP_POLICY
+
+
+
+ Per-user profile
+
+ Equivalent to WLAN_PROFILE_USER
+
+
+
+ Return the byte array of SSID.
+
+ Byte array
+
+
+
+ Return the UTF-8 string representation of SSID
+
+ If successfully converted the byte array of SSID, UTF-8 string. If not, null.
+
+
+
+ Return the byte array of MAC address
+
+
+
+
+
+ Return the hexadecimal string representation of MAC address delimited by colon.
+
+ Hexadecimal string
+
+
+
+ Infrastructure BSS network
+
+
+
+
+ Independent BSS (IBSS) network
+
+
+
+
+ Either infrastructure or IBSS network
+
+
+
+
+ Wrapper class only for handle taken by WlanOpenHandle function in Native Wifi API
+
+
+ This implementation is based on:
+ http://referencesource.microsoft.com/#mscorlib/system/runtime/interopservices/safehandle.cs
+
+
+
+
+ Default constructor
+
+ This constructor is for P/Invoke.
+
+
+
diff --git a/WlanProfileViewer/Models/Operation.cs b/WlanProfileViewer/Models/Operation.cs
index 4816db3..69c8292 100644
--- a/WlanProfileViewer/Models/Operation.cs
+++ b/WlanProfileViewer/Models/Operation.cs
@@ -52,6 +52,9 @@ public bool IsSuspended
private ReactiveTimer ReloadTimer { get; }
+ public Operation() : this(new NativeWifiWorker())
+ { }
+
public Operation(IWlanWorker worker)
{
this._worker = worker;
@@ -154,7 +157,7 @@ public async Task LoadProfilesAsync(bool isLatest)
// Calculate count of positions for each interface.
Profiles
- .GroupBy(x => x.InterfaceGuid)
+ .GroupBy(x => x.InterfaceId)
.ToList()
.ForEach(profilesGroup =>
{
@@ -239,21 +242,21 @@ public async Task DeleteProfileAsync()
x => !Profiles.Contains(x));
}
- public async Task ConnectAsync()
+ public async Task ConnectNetworkAsync()
{
Debug.WriteLine("Connect start!");
return await WorkAsync(
- x => _worker.ConnectAsync(x, _workingTimeoutDuration),
+ x => _worker.ConnectNetworkAsync(x, _workingTimeoutDuration),
x => Profiles.Contains(x) && x.IsConnected);
}
- public async Task DisconnectAsync()
+ public async Task DisconnectNetworkAsync()
{
Debug.WriteLine("Disconnect start!");
return await WorkAsync(
- x => _worker.DisconnectAsync(x, _workingTimeoutDuration),
+ x => _worker.DisconnectNetworkAsync(x, _workingTimeoutDuration),
x => Profiles.Contains(x) && !x.IsConnected);
}
diff --git a/WlanProfileViewer/Models/Wlan/AuthenticationMethod.cs b/WlanProfileViewer/Models/Wlan/AuthenticationMethod.cs
index afce33a..fb5ec2f 100644
--- a/WlanProfileViewer/Models/Wlan/AuthenticationMethod.cs
+++ b/WlanProfileViewer/Models/Wlan/AuthenticationMethod.cs
@@ -24,25 +24,25 @@ public enum AuthenticationMethod
///
/// WPA-Enterprise 802.11 authentication
///
- /// WPA in profile xml
+ /// WPA in profile XML
WPA_Enterprise,
///
/// WPA-Personal 802.11 authentication
///
- /// WPAPSK in profile xml
+ /// WPAPSK in profile XML
WPA_Personal,
///
/// WPA2-Enterprise 802.11 authentication
///
- /// WPA2 in profile xml
+ /// WPA2 in profile XML
WPA2_Enterprise,
///
/// WPA2-Personal 802.11 authentication
///
- /// WPA2PSK in profile xml
+ /// WPA2PSK in profile XML
WPA2_Personal
}
}
\ No newline at end of file
diff --git a/WlanProfileViewer/Models/Wlan/IWlanWorker.cs b/WlanProfileViewer/Models/Wlan/IWlanWorker.cs
index 8564999..74db691 100644
--- a/WlanProfileViewer/Models/Wlan/IWlanWorker.cs
+++ b/WlanProfileViewer/Models/Wlan/IWlanWorker.cs
@@ -8,12 +8,12 @@ namespace WlanProfileViewer.Models.Wlan
{
internal interface IWlanWorker
{
- Task> GetProfilesAsync(bool isLatest, TimeSpan timeoutDuration);
+ Task> GetProfilesAsync(bool isLatest, TimeSpan timeout);
Task SetProfilePositionAsync(ProfileItem profileItem, int position);
Task DeleteProfileAsync(ProfileItem profileItem);
- Task ConnectAsync(ProfileItem profileItem, TimeSpan timeoutDuration);
- Task DisconnectAsync(ProfileItem profileItem, TimeSpan timeoutDuration);
+ Task ConnectNetworkAsync(ProfileItem profileItem, TimeSpan timeout);
+ Task DisconnectNetworkAsync(ProfileItem profileItem, TimeSpan timeout);
}
}
\ No newline at end of file
diff --git a/WlanProfileViewer/Models/Wlan/MockWorker.cs b/WlanProfileViewer/Models/Wlan/MockWorker.cs
index 72b48a6..1d1fa22 100644
--- a/WlanProfileViewer/Models/Wlan/MockWorker.cs
+++ b/WlanProfileViewer/Models/Wlan/MockWorker.cs
@@ -12,7 +12,7 @@ internal class MockWorker : IWlanWorker
private List _sourceProfiles;
private readonly Random _random = new Random();
- public async Task> GetProfilesAsync(bool isLatest, TimeSpan timeoutDuration)
+ public async Task> GetProfilesAsync(bool isLatest, TimeSpan timeout)
{
if (_sourceProfiles == null)
_sourceProfiles = PopulateProfiles().ToList();
@@ -34,7 +34,7 @@ public async Task SetProfilePositionAsync(ProfileItem profileItem, int pos
await WaitAsync();
var targetProfiles = _sourceProfiles
- .Where(x => x.InterfaceGuid == profileItem.InterfaceGuid)
+ .Where(x => x.InterfaceId == profileItem.InterfaceId)
.OrderBy(x => x.Position)
.ToList();
@@ -64,7 +64,7 @@ public async Task DeleteProfileAsync(ProfileItem profileItem)
return _sourceProfiles.Remove(profileItem);
}
- public async Task ConnectAsync(ProfileItem profileItem, TimeSpan timeoutDuration)
+ public async Task ConnectNetworkAsync(ProfileItem profileItem, TimeSpan timeout)
{
await WaitAsync();
@@ -76,7 +76,7 @@ public async Task ConnectAsync(ProfileItem profileItem, TimeSpan timeoutDu
return true;
}
- public async Task DisconnectAsync(ProfileItem profileItem, TimeSpan timeoutDuration)
+ public async Task DisconnectNetworkAsync(ProfileItem profileItem, TimeSpan timeout)
{
await WaitAsync();
@@ -108,7 +108,7 @@ private IEnumerable PopulateProfiles()
{
new ProfileItem(
name: "at_STATION_Wi2",
- interfaceGuid: interfaceGuid0,
+ interfaceId: interfaceGuid0,
interfaceName: interfaceName0,
interfaceDescription: interfaceDescription0,
authentication: AuthenticationMethod.Open,
@@ -120,7 +120,7 @@ private IEnumerable PopulateProfiles()
new ProfileItem(
name: "MSFTOPEN",
- interfaceGuid: interfaceGuid0,
+ interfaceId: interfaceGuid0,
interfaceName: interfaceName0,
interfaceDescription: interfaceDescription0,
authentication: AuthenticationMethod.Open,
@@ -132,7 +132,7 @@ private IEnumerable PopulateProfiles()
new ProfileItem(
name: "flashair_W02",
- interfaceGuid: interfaceGuid0,
+ interfaceId: interfaceGuid0,
interfaceName: interfaceName0,
interfaceDescription: interfaceDescription0,
authentication: AuthenticationMethod.WPA2_Personal,
@@ -144,7 +144,7 @@ private IEnumerable PopulateProfiles()
new ProfileItem(
name: "flashair_W03",
- interfaceGuid: interfaceGuid0,
+ interfaceId: interfaceGuid0,
interfaceName: interfaceName0,
interfaceDescription: interfaceDescription0,
authentication: AuthenticationMethod.WPA2_Personal,
@@ -156,7 +156,7 @@ private IEnumerable PopulateProfiles()
new ProfileItem(
name: "WIFIGATE-968",
- interfaceGuid: interfaceGuid0,
+ interfaceId: interfaceGuid0,
interfaceName: interfaceName0,
interfaceDescription: interfaceDescription0,
authentication: AuthenticationMethod.WPA2_Personal,
@@ -168,7 +168,7 @@ private IEnumerable PopulateProfiles()
new ProfileItem(
name: "at_STATION_Wi2",
- interfaceGuid: interfaceGuid1,
+ interfaceId: interfaceGuid1,
interfaceName: interfaceName1,
interfaceDescription: interfaceDescription1,
authentication: AuthenticationMethod.Open,
@@ -180,7 +180,7 @@ private IEnumerable PopulateProfiles()
new ProfileItem(
name: "ねこラン🐾🐾",
- interfaceGuid: interfaceGuid1,
+ interfaceId: interfaceGuid1,
interfaceName: interfaceName1,
interfaceDescription: interfaceDescription1,
authentication: AuthenticationMethod.WPA_Personal,
@@ -192,7 +192,7 @@ private IEnumerable PopulateProfiles()
new ProfileItem(
name: "ZZZZZ...",
- interfaceGuid: interfaceGuid2,
+ interfaceId: interfaceGuid2,
interfaceName: interfaceName2,
interfaceDescription: interfaceDescription2,
authentication: AuthenticationMethod.Open,
diff --git a/WlanProfileViewer/Models/Wlan/NativeWifi.cs b/WlanProfileViewer/Models/Wlan/NativeWifi.cs
deleted file mode 100644
index a841639..0000000
--- a/WlanProfileViewer/Models/Wlan/NativeWifi.cs
+++ /dev/null
@@ -1,1454 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml.Linq;
-
-namespace WlanProfileViewer.Models.Wlan
-{
- ///
- /// A managed implementation of Native Wifi API
- ///
- internal class NativeWifi
- {
- #region Win32
-
- [DllImport("Wlanapi.dll", SetLastError = true)]
- private static extern uint WlanOpenHandle(
- uint dwClientVersion,
- IntPtr pReserved,
- out uint pdwNegotiatedVersion,
- out IntPtr phClientHandle);
-
- [DllImport("Wlanapi.dll", SetLastError = true)]
- private static extern uint WlanCloseHandle(
- IntPtr hClientHandle,
- IntPtr pReserved);
-
- [DllImport("Wlanapi.dll", SetLastError = true)]
- private static extern void WlanFreeMemory(IntPtr pMemory);
-
- [DllImport("Wlanapi.dll", SetLastError = true)]
- private static extern uint WlanEnumInterfaces(
- IntPtr hClientHandle,
- IntPtr pReserved,
- out IntPtr ppInterfaceList);
-
- [DllImport("Wlanapi.dll", SetLastError = true)]
- private static extern uint WlanScan(
- IntPtr hClientHandle,
- [MarshalAs(UnmanagedType.LPStruct)] Guid pInterfaceGuid,
- IntPtr pDot11Ssid,
- IntPtr pIeData,
- IntPtr pReserved);
-
- [DllImport("Wlanapi.dll", SetLastError = true)]
- private static extern uint WlanGetAvailableNetworkList(
- IntPtr hClientHandle,
- [MarshalAs(UnmanagedType.LPStruct)] Guid pInterfaceGuid,
- uint dwFlags,
- IntPtr pReserved,
- out IntPtr ppAvailableNetworkList);
-
- [DllImport("Wlanapi.dll", SetLastError = true)]
- private static extern uint WlanQueryInterface(
- IntPtr hClientHandle,
- [MarshalAs(UnmanagedType.LPStruct)] Guid pInterfaceGuid,
- WLAN_INTF_OPCODE OpCode,
- IntPtr pReserved,
- out uint pdwDataSize,
- ref IntPtr ppData,
- IntPtr pWlanOpcodeValueType);
-
- [DllImport("Wlanapi.dll", SetLastError = true)]
- private static extern uint WlanGetProfileList(
- IntPtr hClientHandle,
- [MarshalAs(UnmanagedType.LPStruct)] Guid pInterfaceGuid,
- IntPtr pReserved,
- out IntPtr ppProfileList);
-
- [DllImport("Wlanapi.dll", SetLastError = true)]
- private static extern uint WlanGetProfile(
- IntPtr hClientHandle,
- [MarshalAs(UnmanagedType.LPStruct)] Guid pInterfaceGuid,
- [MarshalAs(UnmanagedType.LPWStr)] string strProfileName,
- IntPtr pReserved,
- out IntPtr pstrProfileXml,
- ref uint pdwFlags,
- out uint pdwGrantedAccess);
-
- [DllImport("Wlanapi.dll", SetLastError = true)]
- private static extern uint WlanSetProfilePosition(
- IntPtr hClientHandle,
- [MarshalAs(UnmanagedType.LPStruct)] Guid pInterfaceGuid,
- [MarshalAs(UnmanagedType.LPWStr)] string strProfileName,
- uint dwPosition,
- IntPtr pReserved);
-
- [DllImport("Wlanapi.dll", SetLastError = true)]
- private static extern uint WlanDeleteProfile(
- IntPtr hClientHandle,
- [MarshalAs(UnmanagedType.LPStruct)] Guid pInterfaceGuid,
- [MarshalAs(UnmanagedType.LPWStr)] string strProfileName,
- IntPtr pReserved);
-
- [DllImport("Wlanapi.dll", SetLastError = true)]
- private static extern uint WlanConnect(
- IntPtr hClientHandle,
- [MarshalAs(UnmanagedType.LPStruct)] Guid pInterfaceGuid,
- [In] ref WLAN_CONNECTION_PARAMETERS pConnectionParameters,
- IntPtr pReserved);
-
- [DllImport("Wlanapi.dll", SetLastError = true)]
- private static extern uint WlanDisconnect(
- IntPtr hClientHandle,
- [MarshalAs(UnmanagedType.LPStruct)] Guid pInterfaceGuid,
- IntPtr pReserved);
-
- [DllImport("Wlanapi.dll", SetLastError = true)]
- private static extern uint WlanRegisterNotification(
- IntPtr hClientHandle,
- uint dwNotifSource,
- [MarshalAs(UnmanagedType.Bool)] bool bIgnoreDuplicate,
- WLAN_NOTIFICATION_CALLBACK funcCallback,
- IntPtr pCallbackContext,
- IntPtr pReserved,
- uint pdwPrevNotifSource);
-
- private delegate void WLAN_NOTIFICATION_CALLBACK(
- IntPtr data, // Pointer to WLAN_NOTIFICATION_DATA
- IntPtr context);
-
- [DllImport("Kernel32.dll", SetLastError = true)]
- private static extern uint FormatMessage(
- uint dwFlags,
- IntPtr lpSource,
- uint dwMessageId,
- uint dwLanguageId,
- StringBuilder lpBuffer,
- int nSize,
- IntPtr Arguments);
-
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- private struct WLAN_INTERFACE_INFO
- {
- public Guid InterfaceGuid;
-
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
- public string strInterfaceDescription;
-
- public WLAN_INTERFACE_STATE isState;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- private struct WLAN_INTERFACE_INFO_LIST
- {
- public uint dwNumberOfItems;
- public uint dwIndex;
- public WLAN_INTERFACE_INFO[] InterfaceInfo;
-
- public WLAN_INTERFACE_INFO_LIST(IntPtr ppInterfaceList)
- {
- dwNumberOfItems = (uint)Marshal.ReadInt32(ppInterfaceList, 0);
- dwIndex = (uint)Marshal.ReadInt32(ppInterfaceList, 4);
- InterfaceInfo = new WLAN_INTERFACE_INFO[dwNumberOfItems];
-
- var offset = Marshal.SizeOf(typeof(uint)) * 2; // Size of dwNumberOfItems and dwIndex
-
- for (int i = 0; i < dwNumberOfItems; i++)
- {
- var interfaceInfo = new IntPtr(ppInterfaceList.ToInt64() + (Marshal.SizeOf(typeof(WLAN_INTERFACE_INFO)) * i) + offset);
- InterfaceInfo[i] = Marshal.PtrToStructure(interfaceInfo);
- }
- }
- }
-
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- private struct WLAN_AVAILABLE_NETWORK
- {
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
- public string strProfileName;
-
- public DOT11_SSID dot11Ssid;
- public DOT11_BSS_TYPE dot11BssType;
- public uint uNumberOfBssids;
- public bool bNetworkConnectable;
- public uint wlanNotConnectableReason;
- public uint uNumberOfPhyTypes;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- public DOT11_PHY_TYPE[] dot11PhyTypes;
-
- public bool bMorePhyTypes;
- public uint wlanSignalQuality;
- public bool bSecurityEnabled;
- public DOT11_AUTH_ALGORITHM dot11DefaultAuthAlgorithm;
- public DOT11_CIPHER_ALGORITHM dot11DefaultCipherAlgorithm;
- public uint dwFlags;
- public uint dwReserved;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- private struct WLAN_AVAILABLE_NETWORK_LIST
- {
- public uint dwNumberOfItems;
- public uint dwIndex;
- public WLAN_AVAILABLE_NETWORK[] Network;
-
- public WLAN_AVAILABLE_NETWORK_LIST(IntPtr ppAvailableNetworkList)
- {
- dwNumberOfItems = (uint)Marshal.ReadInt32(ppAvailableNetworkList, 0);
- dwIndex = (uint)Marshal.ReadInt32(ppAvailableNetworkList, 4);
- Network = new WLAN_AVAILABLE_NETWORK[dwNumberOfItems];
-
- var offset = Marshal.SizeOf(typeof(uint)) * 2; // Size of dwNumberOfItems and dwIndex
-
- for (int i = 0; i < dwNumberOfItems; i++)
- {
- var availableNetwork = new IntPtr(ppAvailableNetworkList.ToInt64() + (Marshal.SizeOf(typeof(WLAN_AVAILABLE_NETWORK)) * i) + offset);
- Network[i] = Marshal.PtrToStructure(availableNetwork);
- }
- }
- }
-
- [StructLayout(LayoutKind.Sequential)]
- private struct DOT11_SSID
- {
- public uint uSSIDLength;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
- public byte[] ucSSID;
-
- public byte[] ToSsidBytes()
- {
- return (ucSSID != null)
- ? ucSSID.Take((int)uSSIDLength).ToArray()
- : null;
- }
-
- public string ToSsidString()
- {
- return (ucSSID != null)
- ? Encoding.UTF8.GetString(ToSsidBytes())
- : null;
- }
- }
-
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- private struct WLAN_CONNECTION_ATTRIBUTES
- {
- public WLAN_INTERFACE_STATE isState;
- public WLAN_CONNECTION_MODE wlanConnectionMode;
-
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
- public string strProfileName;
-
- public WLAN_ASSOCIATION_ATTRIBUTES wlanAssociationAttributes;
- public WLAN_SECURITY_ATTRIBUTES wlanSecurityAttributes;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- private struct WLAN_ASSOCIATION_ATTRIBUTES
- {
- public DOT11_SSID dot11Ssid;
- public DOT11_BSS_TYPE dot11BssType;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
- public byte[] dot11Bssid; // DOT11_MAC_ADDRESS
-
- public DOT11_PHY_TYPE dot11PhyType;
- public uint uDot11PhyIndex;
- public uint wlanSignalQuality;
- public uint ulRxRate;
- public uint ulTxRate;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- private struct WLAN_SECURITY_ATTRIBUTES
- {
- [MarshalAs(UnmanagedType.Bool)]
- public bool bSecurityEnabled;
-
- [MarshalAs(UnmanagedType.Bool)]
- public bool bOneXEnabled;
-
- public DOT11_AUTH_ALGORITHM dot11AuthAlgorithm;
- public DOT11_CIPHER_ALGORITHM dot11CipherAlgorithm;
- }
-
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- private struct WLAN_PROFILE_INFO
- {
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
- public string strProfileName;
-
- public uint dwFlags;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- private struct WLAN_PROFILE_INFO_LIST
- {
- public uint dwNumberOfItems;
- public uint dwIndex;
- public WLAN_PROFILE_INFO[] ProfileInfo;
-
- public WLAN_PROFILE_INFO_LIST(IntPtr ppProfileList)
- {
- dwNumberOfItems = (uint)Marshal.ReadInt32(ppProfileList, 0);
- dwIndex = (uint)Marshal.ReadInt32(ppProfileList, 4);
- ProfileInfo = new WLAN_PROFILE_INFO[dwNumberOfItems];
-
- var offset = Marshal.SizeOf(typeof(uint)) * 2; // Size of dwNumberOfItems and dwIndex
-
- for (int i = 0; i < dwNumberOfItems; i++)
- {
- var profileInfo = new IntPtr(ppProfileList.ToInt64() + (Marshal.SizeOf(typeof(WLAN_PROFILE_INFO)) * i) + offset);
- ProfileInfo[i] = Marshal.PtrToStructure(profileInfo);
- }
- }
- }
-
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- private struct WLAN_CONNECTION_PARAMETERS
- {
- public WLAN_CONNECTION_MODE wlanConnectionMode;
- [MarshalAs(UnmanagedType.LPWStr)]
- public string strProfile;
- public IntPtr pDot11Ssid; // DOT11_SSID[]
- public IntPtr pDesiredBssidList; // DOT11_BSSID_LIST[]
- public DOT11_BSS_TYPE dot11BssType;
- public uint dwFlags;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct DOT11_BSSID_LIST
- {
- public NDIS_OBJECT_HEADER Header;
- public uint uNumOfEntries;
- public uint uTotalNumOfEntries;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
- public byte[] BSSIDs; // DOT11_MAC_ADDRESS
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct NDIS_OBJECT_HEADER
- {
- public byte Type;
- public byte Revision;
- public ushort Size;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- private struct WLAN_NOTIFICATION_DATA
- {
- public uint NotificationSource;
- public uint NotificationCode;
- public Guid InterfaceGuid;
- public uint dwDataSize;
- public IntPtr pData;
- }
-
- private enum WLAN_INTERFACE_STATE
- {
- wlan_interface_state_not_ready = 0,
- wlan_interface_state_connected = 1,
- wlan_interface_state_ad_hoc_network_formed = 2,
- wlan_interface_state_disconnecting = 3,
- wlan_interface_state_disconnected = 4,
- wlan_interface_state_associating = 5,
- wlan_interface_state_discovering = 6,
- wlan_interface_state_authenticating = 7
- }
-
- private enum WLAN_CONNECTION_MODE
- {
- wlan_connection_mode_profile,
- wlan_connection_mode_temporary_profile,
- wlan_connection_mode_discovery_secure,
- wlan_connection_mode_discovery_unsecure,
- wlan_connection_mode_auto,
- wlan_connection_mode_invalid
- }
-
- private enum DOT11_BSS_TYPE
- {
- ///
- /// Infrastructure BSS network
- ///
- dot11_BSS_type_infrastructure = 1,
-
- ///
- /// Independent BSS (IBSS) network
- ///
- dot11_BSS_type_independent = 2,
-
- ///
- /// Either infrastructure or IBSS network
- ///
- dot11_BSS_type_any = 3,
- }
-
- private enum DOT11_PHY_TYPE : uint
- {
- dot11_phy_type_unknown = 0,
- dot11_phy_type_any = 0,
- dot11_phy_type_fhss = 1,
- dot11_phy_type_dsss = 2,
- dot11_phy_type_irbaseband = 3,
- dot11_phy_type_ofdm = 4,
- dot11_phy_type_hrdsss = 5,
- dot11_phy_type_erp = 6,
- dot11_phy_type_ht = 7,
- dot11_phy_type_vht = 8,
- dot11_phy_type_IHV_start = 0x80000000,
- dot11_phy_type_IHV_end = 0xffffffff
- }
-
- private enum DOT11_AUTH_ALGORITHM : uint
- {
- DOT11_AUTH_ALGO_80211_OPEN = 1,
- DOT11_AUTH_ALGO_80211_SHARED_KEY = 2,
- DOT11_AUTH_ALGO_WPA = 3,
- DOT11_AUTH_ALGO_WPA_PSK = 4,
- DOT11_AUTH_ALGO_WPA_NONE = 5,
- DOT11_AUTH_ALGO_RSNA = 6,
- DOT11_AUTH_ALGO_RSNA_PSK = 7,
- DOT11_AUTH_ALGO_IHV_START = 0x80000000,
- DOT11_AUTH_ALGO_IHV_END = 0xffffffff
- }
-
- private enum DOT11_CIPHER_ALGORITHM : uint
- {
- DOT11_CIPHER_ALGO_NONE = 0x00,
- DOT11_CIPHER_ALGO_WEP40 = 0x01,
- DOT11_CIPHER_ALGO_TKIP = 0x02,
- DOT11_CIPHER_ALGO_CCMP = 0x04,
- DOT11_CIPHER_ALGO_WEP104 = 0x05,
- DOT11_CIPHER_ALGO_WPA_USE_GROUP = 0x100,
- DOT11_CIPHER_ALGO_RSN_USE_GROUP = 0x100,
- DOT11_CIPHER_ALGO_WEP = 0x101,
- DOT11_CIPHER_ALGO_IHV_START = 0x80000000,
- DOT11_CIPHER_ALGO_IHV_END = 0xffffffff
- }
-
- private enum WLAN_INTF_OPCODE : uint
- {
- wlan_intf_opcode_autoconf_start = 0x000000000,
- wlan_intf_opcode_autoconf_enabled,
- wlan_intf_opcode_background_scan_enabled,
- wlan_intf_opcode_media_streaming_mode,
- wlan_intf_opcode_radio_state,
- wlan_intf_opcode_bss_type,
- wlan_intf_opcode_interface_state,
- wlan_intf_opcode_current_connection,
- wlan_intf_opcode_channel_number,
- wlan_intf_opcode_supported_infrastructure_auth_cipher_pairs,
- wlan_intf_opcode_supported_adhoc_auth_cipher_pairs,
- wlan_intf_opcode_supported_country_or_region_string_list,
- wlan_intf_opcode_current_operation_mode,
- wlan_intf_opcode_supported_safe_mode,
- wlan_intf_opcode_certified_safe_mode,
- wlan_intf_opcode_hosted_network_capable,
- wlan_intf_opcode_management_frame_protection_capable,
- wlan_intf_opcode_autoconf_end = 0x0fffffff,
- wlan_intf_opcode_msm_start = 0x10000100,
- wlan_intf_opcode_statistics,
- wlan_intf_opcode_rssi,
- wlan_intf_opcode_msm_end = 0x1fffffff,
- wlan_intf_opcode_security_start = 0x20010000,
- wlan_intf_opcode_security_end = 0x2fffffff,
- wlan_intf_opcode_ihv_start = 0x30000000,
- wlan_intf_opcode_ihv_end = 0x3fffffff
- }
-
- private enum WLAN_NOTIFICATION_ACM : uint
- {
- wlan_notification_acm_start = 0,
- wlan_notification_acm_autoconf_enabled,
- wlan_notification_acm_autoconf_disabled,
- wlan_notification_acm_background_scan_enabled,
- wlan_notification_acm_background_scan_disabled,
- wlan_notification_acm_bss_type_change,
- wlan_notification_acm_power_setting_change,
- wlan_notification_acm_scan_complete,
- wlan_notification_acm_scan_fail,
- wlan_notification_acm_connection_start,
- wlan_notification_acm_connection_complete,
- wlan_notification_acm_connection_attempt_fail,
- wlan_notification_acm_filter_list_change,
- wlan_notification_acm_interface_arrival,
- wlan_notification_acm_interface_removal,
- wlan_notification_acm_profile_change,
- wlan_notification_acm_profile_name_change,
- wlan_notification_acm_profiles_exhausted,
- wlan_notification_acm_network_not_available,
- wlan_notification_acm_network_available,
- wlan_notification_acm_disconnecting,
- wlan_notification_acm_disconnected,
- wlan_notification_acm_adhoc_network_state_change,
- wlan_notification_acm_profile_unblocked,
- wlan_notification_acm_screen_power_change,
- wlan_notification_acm_profile_blocked,
- wlan_notification_acm_scan_list_refresh,
- wlan_notification_acm_end
- }
-
- private const uint WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_ADHOC_PROFILES = 0x00000001;
- private const uint WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_MANUAL_HIDDEN_PROFILES = 0x00000002;
-
- private const uint ERROR_SUCCESS = 0;
- private const uint ERROR_INVALID_PARAMETER = 87;
- private const uint ERROR_INVALID_HANDLE = 6;
- private const uint ERROR_INVALID_STATE = 5023;
- private const uint ERROR_NOT_FOUND = 1168;
- private const uint ERROR_NOT_ENOUGH_MEMORY = 8;
- private const uint ERROR_ACCESS_DENIED = 5;
- private const uint ERROR_NOT_SUPPORTED = 50;
- private const uint ERROR_SERVICE_NOT_ACTIVE = 1062;
- private const uint ERROR_NDIS_DOT11_AUTO_CONFIG_ENABLED = 0x80342000;
- private const uint ERROR_NDIS_DOT11_MEDIA_IN_USE = 0x80342001;
- private const uint ERROR_NDIS_DOT11_POWER_STATE_INVALID = 0x80342002;
-
- private const uint WLAN_NOTIFICATION_SOURCE_NONE = 0;
- private const uint WLAN_NOTIFICATION_SOURCE_ALL = 0x0000FFFF;
- private const uint WLAN_NOTIFICATION_SOURCE_ACM = 0x00000008;
- private const uint WLAN_NOTIFICATION_SOURCE_HNWK = 0x00000080;
- private const uint WLAN_NOTIFICATION_SOURCE_ONEX = 0x00000004;
- private const uint WLAN_NOTIFICATION_SOURCE_MSM = 0x00000010;
- private const uint WLAN_NOTIFICATION_SOURCE_SECURITY = 0x00000020;
- private const uint WLAN_NOTIFICATION_SOURCE_IHV = 0x00000040;
-
- private const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
-
- #endregion
-
- #region Type
-
- ///
- /// BSS type
- ///
- public enum BssType
- {
- ///
- /// None
- ///
- None = 0,
-
- ///
- /// Infrastructure BSS network
- ///
- Infrastructure,
-
- ///
- /// Independent BSS (IBSS) network (Ad hoc network)
- ///
- Independent,
-
- ///
- /// Any BSS network
- ///
- Any
- }
-
- ///
- /// Wireless profile information
- ///
- public class ProfilePack
- {
- ///
- /// Profile name
- ///
- public string Name { get; private set; }
-
- ///
- /// GUID of associated wireless LAN interface
- ///
- public Guid InterfaceGuid { get; private set; }
-
- ///
- /// Description of associated wireless LAN interface
- ///
- public string InterfaceDescription { get; private set; }
-
- ///
- /// SSID of associated wireless LAN
- ///
- public string Ssid { get; private set; }
-
- ///
- /// BSS type of associated wireless LAN
- ///
- public BssType BssType { get; private set; }
-
- ///
- /// Authentication type of associated wireless LAN
- ///
- public string Authentication { get; private set; }
-
- ///
- /// Encryption type of associated wireless LAN
- ///
- public string Encryption { get; private set; }
-
- ///
- /// Position in preference order of associated wireless LAN interface
- ///
- public int Position { get; private set; }
-
- ///
- /// Whether this profile is set to be automatically connected
- ///
- public bool IsAutomatic { get; private set; }
-
- ///
- /// Signal level of associated wireless LAN
- ///
- public int Signal { get; private set; }
-
- ///
- /// Whether this profile is currently connected
- ///
- public bool IsConnected { get; private set; }
-
- public ProfilePack(
- string name,
- Guid interfaceGuid,
- string interfaceDescription,
- string ssid,
- BssType bssType,
- string authentication,
- string encryption,
- int position,
- bool isAutomatic,
- int signal,
- bool isConnected)
- {
- this.Name = name;
- this.InterfaceGuid = interfaceGuid;
- this.InterfaceDescription = interfaceDescription;
- this.Ssid = ssid;
- this.BssType = bssType;
- this.Authentication = authentication;
- this.Encryption = encryption;
- this.Position = position;
- this.IsAutomatic = isAutomatic;
- this.Signal = signal;
- this.IsConnected = isConnected;
- }
- }
-
- ///
- /// Wireless LAN information
- ///
- public class NetworkPack
- {
- ///
- /// GUID of associated wireless LAN interface
- ///
- public Guid InterfaceGuid { get; private set; }
-
- ///
- /// SSID
- ///
- public string Ssid { get; private set; }
-
- ///
- /// BSS type
- ///
- public BssType BssType { get; private set; }
-
- ///
- /// Signal level
- ///
- public int Signal { get; private set; }
-
- ///
- /// Name of associated wireless profile
- ///
- public string ProfileName { get; private set; }
-
- public NetworkPack(Guid interfaceGuid, string ssid, BssType bssType, int signal, string profileName)
- {
- this.InterfaceGuid = interfaceGuid;
- this.Ssid = ssid;
- this.BssType = bssType;
- this.Signal = signal;
- this.ProfileName = profileName;
- }
- }
-
- #endregion
-
- #region Scan networks
-
- ///
- /// Request wireless interfaces to scan available wireless LANs.
- ///
- /// Timeout duration
- /// Interface GUIDs that the requests succeeded
- public static async Task> ScanAsync(TimeSpan timeoutDuration)
- {
- using (var client = new WlanClient())
- {
- var interfaceInfoList = GetInterfaceInfoList(client.Handle);
- var interfaceGuids = interfaceInfoList.Select(x => x.InterfaceGuid).ToArray();
-
- var tcs = new TaskCompletionSource();
- var handler = new ScanHandler(tcs, interfaceGuids);
-
- Action callback = (data, context) =>
- {
- var notificationData = Marshal.PtrToStructure(data);
- if (notificationData.NotificationSource != WLAN_NOTIFICATION_SOURCE_ACM)
- return;
-
- //Debug.WriteLine("Callback: {0}", (WLAN_NOTIFICATION_ACM)notificationData.NotificationCode);
-
- switch (notificationData.NotificationCode)
- {
- case (uint)WLAN_NOTIFICATION_ACM.wlan_notification_acm_scan_complete:
- Debug.WriteLine("Scan succeeded.");
- handler.SetSuccess(notificationData.InterfaceGuid);
- break;
- case (uint)WLAN_NOTIFICATION_ACM.wlan_notification_acm_scan_fail:
- Debug.WriteLine("Scan failed.");
- handler.SetFailure(notificationData.InterfaceGuid);
- break;
- }
- };
-
- RegisterNotification(client.Handle, WLAN_NOTIFICATION_SOURCE_ACM, callback);
-
- foreach (var interfaceGuid in interfaceGuids)
- {
- var result = Scan(client.Handle, interfaceGuid);
- if (!result)
- handler.SetFailure(interfaceGuid);
- }
-
- var scanTask = tcs.Task;
- await Task.WhenAny(scanTask, Task.Delay(timeoutDuration));
-
- return handler.Results;
- }
- }
-
- private class ScanHandler
- {
- private TaskCompletionSource _tcs;
- private readonly List _targets = new List();
- private readonly List _results = new List();
-
- public IEnumerable Results { get { return _results.ToArray(); } }
-
- public ScanHandler(TaskCompletionSource tcs, IEnumerable targets)
- {
- this._tcs = tcs;
- this._targets.AddRange(targets);
- }
-
- private readonly object _locker = new object();
-
- public void SetSuccess(Guid value)
- {
- lock (_locker)
- {
- _targets.Remove(value);
- _results.Add(value);
-
- CheckTargets();
- }
- }
-
- public void SetFailure(Guid value)
- {
- lock (_locker)
- {
- _targets.Remove(value);
-
- CheckTargets();
- }
- }
-
- private void CheckTargets()
- {
- if ((_targets.Count <= 0) && !_tcs.Task.IsCompleted)
- Task.Run(() => _tcs.SetResult(true));
- }
- }
-
- #endregion
-
- #region Enumerate networks
-
- ///
- /// Enumerate available wireless LANs.
- ///
- /// Wireless LANs
- /// If multiple profiles are associated with a same network, there will be multiple entries
- /// with the same SSID.
- public static IEnumerable EnumerateAvailableNetworks()
- {
- using (var client = new WlanClient())
- {
- var interfaceInfoList = GetInterfaceInfoList(client.Handle);
-
- foreach (var interfaceInfo in interfaceInfoList)
- {
- var availableNetworkList = GetAvailableNetworkList(client.Handle, interfaceInfo.InterfaceGuid);
-
- foreach (var availableNetwork in availableNetworkList)
- {
- //Debug.WriteLine("Interface: {0}, SSID: {1}, Signal: {2}",
- // interfaceInfo.strInterfaceDescription,
- // availableNetwork.dot11Ssid.ToSsidString(),
- // availableNetwork.wlanSignalQuality);
-
- yield return new NetworkPack(
- interfaceInfo.InterfaceGuid,
- availableNetwork.dot11Ssid.ToSsidString(),
- ConvertToBssType(availableNetwork.dot11BssType),
- (int)availableNetwork.wlanSignalQuality,
- availableNetwork.strProfileName);
- }
- }
- }
- }
-
- #endregion
-
- #region Enumerate Profiles
-
- ///
- /// Enumerate wireless profiles in preference order.
- ///
- /// Wireless profiles
- public static IEnumerable EnumerateProfiles()
- {
- using (var client = new WlanClient())
- {
- var interfaceInfoList = GetInterfaceInfoList(client.Handle);
-
- foreach (var interfaceInfo in interfaceInfoList)
- {
- var availableNetworkList = GetAvailableNetworkList(client.Handle, interfaceInfo.InterfaceGuid)
- .Where(x => !string.IsNullOrWhiteSpace(x.strProfileName))
- .ToArray();
-
- var connection = GetConnectionAttributes(client.Handle, interfaceInfo.InterfaceGuid);
- var interfaceIsConnected = (connection.isState == WLAN_INTERFACE_STATE.wlan_interface_state_connected);
-
- var profileInfoList = GetProfileInfoList(client.Handle, interfaceInfo.InterfaceGuid);
-
- int position = 0;
-
- foreach (var profileInfo in profileInfoList)
- {
- var availableNetwork = availableNetworkList.FirstOrDefault(x => x.strProfileName.Equals(profileInfo.strProfileName, StringComparison.Ordinal));
- var signal = (int)availableNetwork.wlanSignalQuality;
-
- var profileIsConnected = interfaceIsConnected && profileInfo.strProfileName.Equals(connection.strProfileName, StringComparison.Ordinal);
-
- //Debug.WriteLine("Interface: {0}, Profile: {1}, Position: {2}, Signal {3}, IsConnected {4}",
- // interfaceInfo.strInterfaceDescription,
- // profileInfo.strProfileName,
- // position,
- // signal,
- // profileIsConnected);
-
- var profile = GetProfile(
- client.Handle,
- profileInfo.strProfileName,
- interfaceInfo.InterfaceGuid,
- interfaceInfo.strInterfaceDescription,
- position++,
- signal,
- profileIsConnected);
-
- if (profile != null)
- yield return profile;
- }
- }
- }
- }
-
- ///
- /// Get a wireless profile.
- ///
- /// Client handle
- /// Profile name
- /// Interface GUID
- /// Interface description
- /// Whether this profile is connected to a wireless LAN
- /// Wireless profile
- ///
- /// For profile elements, see
- /// https://msdn.microsoft.com/en-us/library/windows/desktop/ms707381.aspx
- ///
- private static ProfilePack GetProfile(IntPtr clientHandle, string profileName, Guid interfaceGuid, string interfaceDescription, int position, int signal, bool isConnected)
- {
- var source = GetProfileXml(clientHandle, interfaceGuid, profileName);
- if (string.IsNullOrWhiteSpace(source))
- return null;
-
- XElement rootXml;
- using (var sr = new StringReader(source))
- rootXml = XElement.Load(sr);
-
- var ns = rootXml.Name.Namespace;
-
- var ssidXml = rootXml.Descendants(ns + "SSID").FirstOrDefault();
- var ssid = (ssidXml != null) ? ssidXml.Descendants(ns + "name").First().Value : null;
-
- var connectionTypeXml = rootXml.Descendants(ns + "connectionType").FirstOrDefault();
- var bssType = (connectionTypeXml != null) ? ConvertToBssType(connectionTypeXml.Value) : default(BssType);
-
- var connectionModeXml = rootXml.Descendants(ns + "connectionMode").FirstOrDefault();
- var isAutomatic = (connectionModeXml != null) && connectionModeXml.Value.Equals("auto", StringComparison.OrdinalIgnoreCase);
-
- var authenticationXml = rootXml.Descendants(ns + "authentication").FirstOrDefault();
- var authentication = (authenticationXml != null) ? authenticationXml.Value : null;
-
- var encryptionXml = rootXml.Descendants(ns + "encryption").FirstOrDefault();
- var encryption = (encryptionXml != null) ? encryptionXml.Value : null;
-
- //Debug.WriteLine("SSID: {0}, BssType: {1}, Authentication: {2}, Encryption: {3}, IsAutomatic: {4}",
- // ssid,
- // bssType,
- // authentication,
- // encryption,
- // isAutomatic);
-
- return new ProfilePack(
- profileName,
- interfaceGuid,
- interfaceDescription,
- ssid,
- bssType,
- authentication,
- encryption,
- position,
- isAutomatic,
- signal,
- isConnected);
- }
-
- #endregion
-
- #region Set profile position
-
- ///
- /// Set the position of a wireless profile in preference order.
- ///
- /// Profile name
- /// Interface GUID
- /// Position (starting from 0)
- /// True if set.
- public static bool SetProfilePosition(string profileName, Guid interfaceGuid, int position)
- {
- if (string.IsNullOrWhiteSpace(profileName))
- return false;
-
- if (interfaceGuid == default(Guid))
- return false;
-
- if (position < 0)
- return false;
-
- using (var client = new WlanClient())
- {
- return SetProfilePosition(client.Handle, interfaceGuid, profileName, (uint)position);
- }
- }
-
- #endregion
-
- #region Delete profile
-
- ///
- /// Delete a wireless profile.
- ///
- /// Profile name
- /// Interface GUID
- /// True if deleted. False if could not delete.
- public static bool DeleteProfile(string profileName, Guid interfaceGuid)
- {
- if (string.IsNullOrWhiteSpace(profileName))
- return false;
-
- if (interfaceGuid == default(Guid))
- return false;
-
- using (var client = new WlanClient())
- {
- return DeleteProfile(client.Handle, interfaceGuid, profileName);
- }
- }
-
- #endregion
-
- #region Connect/Disconnect
-
- ///
- /// Attempt to connect to a wireless LAN.
- ///
- /// Profile name
- /// Interface GUID
- /// BSS type
- /// Timeout duration
- /// True if succeeded. False if failed or timed out.
- public static async Task ConnectAsync(string profileName, Guid interfaceGuid, BssType bssType, TimeSpan timeoutDuration)
- {
- if (string.IsNullOrWhiteSpace(profileName))
- return false;
-
- if (interfaceGuid == default(Guid))
- return false;
-
- using (var client = new WlanClient())
- {
- var tcs = new TaskCompletionSource();
-
- Action callback = (data, context) =>
- {
- var notificationData = Marshal.PtrToStructure(data);
- if (notificationData.NotificationSource != WLAN_NOTIFICATION_SOURCE_ACM)
- return;
-
- //Debug.WriteLine("Callback: {0}", (WLAN_NOTIFICATION_ACM)notificationData.NotificationCode);
-
- switch (notificationData.NotificationCode)
- {
- case (uint)WLAN_NOTIFICATION_ACM.wlan_notification_acm_connection_complete:
- Task.Run(() => tcs.SetResult(true));
- break;
- case (uint)WLAN_NOTIFICATION_ACM.wlan_notification_acm_connection_attempt_fail:
- Task.Run(() => tcs.SetResult(false));
- break;
- }
- };
-
- RegisterNotification(client.Handle, WLAN_NOTIFICATION_SOURCE_ACM, callback);
-
- var result = Connect(client.Handle, interfaceGuid, profileName, ConvertFromBssType(bssType));
- if (!result)
- tcs.SetResult(false);
-
- var connectTask = tcs.Task;
- var completedTask = await Task.WhenAny(connectTask, Task.Delay(timeoutDuration));
-
- return (completedTask == connectTask) ? connectTask.Result : false;
- }
- }
-
- ///
- /// Disconnect from a wireless LAN.
- ///
- /// Interface GUID
- /// Timeout duration
- /// True if succeeded. False if failed or timed out.
- public static async Task DisconnectAsync(Guid interfaceGuid, TimeSpan timeoutDuration)
- {
- if (interfaceGuid == default(Guid))
- return false;
-
- using (var client = new WlanClient())
- {
- var tcs = new TaskCompletionSource();
-
- Action callback = (data, context) =>
- {
- var notificationData = Marshal.PtrToStructure(data);
- if (notificationData.NotificationSource != WLAN_NOTIFICATION_SOURCE_ACM)
- return;
-
- //Debug.WriteLine("Callback: {0}", (WLAN_NOTIFICATION_ACM)notificationData.NotificationCode);
-
- switch (notificationData.NotificationCode)
- {
- case (uint)WLAN_NOTIFICATION_ACM.wlan_notification_acm_disconnected:
- Task.Run(() => tcs.SetResult(true));
- break;
- }
- };
-
- RegisterNotification(client.Handle, WLAN_NOTIFICATION_SOURCE_ACM, callback);
-
- var result = Disconnect(client.Handle, interfaceGuid);
- if (!result)
- tcs.SetResult(false);
-
- var disconnectTask = tcs.Task;
- var completedTask = await Task.WhenAny(disconnectTask, Task.Delay(timeoutDuration));
-
- return (completedTask == disconnectTask) ? disconnectTask.Result : false;
- }
- }
-
- #endregion
-
- #region Helper
-
- private static DOT11_BSS_TYPE ConvertFromBssType(BssType source)
- {
- switch (source)
- {
- case BssType.Infrastructure:
- return DOT11_BSS_TYPE.dot11_BSS_type_infrastructure;
- case BssType.Independent:
- return DOT11_BSS_TYPE.dot11_BSS_type_independent;
- default:
- return DOT11_BSS_TYPE.dot11_BSS_type_any;
- }
- }
-
- private static BssType ConvertToBssType(DOT11_BSS_TYPE source)
- {
- switch (source)
- {
- case DOT11_BSS_TYPE.dot11_BSS_type_infrastructure:
- return BssType.Infrastructure;
- case DOT11_BSS_TYPE.dot11_BSS_type_independent:
- return BssType.Independent;
- default:
- return BssType.Any;
- }
- }
-
- private static BssType ConvertToBssType(string source)
- {
- if (string.IsNullOrWhiteSpace(source))
- {
- return default(BssType);
- }
- if (source.Equals("ESS", StringComparison.OrdinalIgnoreCase))
- {
- return BssType.Infrastructure;
- }
- if (source.Equals("IBSS", StringComparison.OrdinalIgnoreCase))
- {
- return BssType.Independent;
- }
- return BssType.Any;
- }
-
- #endregion
-
- #region Base
-
- private class WlanClient : IDisposable
- {
- private IntPtr _clientHandle = IntPtr.Zero;
-
- public IntPtr Handle { get { return _clientHandle; } }
-
- public WlanClient()
- {
- uint negotiatedVersion;
- var result = WlanOpenHandle(
- 2, // Client version for Windows Vista and Windows Server 2008
- IntPtr.Zero,
- out negotiatedVersion,
- out _clientHandle);
-
- CheckResult(result, "WlanOpenHandle", true);
- }
-
- #region Dispose
-
- private bool _disposed = false;
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (_disposed)
- return;
-
- if (_clientHandle != IntPtr.Zero)
- WlanCloseHandle(_clientHandle, IntPtr.Zero);
-
- _disposed = true;
- }
-
- ~WlanClient()
- {
- Dispose(false);
- }
-
- #endregion
- }
-
- private static WLAN_INTERFACE_INFO[] GetInterfaceInfoList(IntPtr clientHandle)
- {
- var interfaceList = IntPtr.Zero;
- try
- {
- var result = WlanEnumInterfaces(
- clientHandle,
- IntPtr.Zero,
- out interfaceList);
-
- return CheckResult(result, "WlanEnumInterfaces", true)
- ? new WLAN_INTERFACE_INFO_LIST(interfaceList).InterfaceInfo
- : null; // Not to be used
- }
- finally
- {
- if (interfaceList != IntPtr.Zero)
- WlanFreeMemory(interfaceList);
- }
- }
-
- private static bool Scan(IntPtr clientHandle, Guid interfaceGuid)
- {
- var result = WlanScan(
- clientHandle,
- interfaceGuid,
- IntPtr.Zero,
- IntPtr.Zero,
- IntPtr.Zero);
-
- // ERROR_NDIS_DOT11_POWER_STATE_INVALID will be returned if the interface is turned off.
- return CheckResult(result, "WlanScan", false);
- }
-
- private static WLAN_AVAILABLE_NETWORK[] GetAvailableNetworkList(IntPtr clientHandle, Guid interfaceGuid)
- {
- var availableNetworkList = IntPtr.Zero;
- try
- {
- var result = WlanGetAvailableNetworkList(
- clientHandle,
- interfaceGuid,
- WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_MANUAL_HIDDEN_PROFILES,
- IntPtr.Zero,
- out availableNetworkList);
-
- // ERROR_NDIS_DOT11_POWER_STATE_INVALID will be returned if the interface is turned off.
- return CheckResult(result, "WlanGetAvailableNetworkList", false)
- ? new WLAN_AVAILABLE_NETWORK_LIST(availableNetworkList).Network
- : new WLAN_AVAILABLE_NETWORK[] { };
- }
- finally
- {
- if (availableNetworkList != IntPtr.Zero)
- WlanFreeMemory(availableNetworkList);
- }
- }
-
- private static WLAN_CONNECTION_ATTRIBUTES GetConnectionAttributes(IntPtr clientHandle, Guid interfaceGuid)
- {
- var queryData = IntPtr.Zero;
- try
- {
- uint dataSize;
- var result = WlanQueryInterface(
- clientHandle,
- interfaceGuid,
- WLAN_INTF_OPCODE.wlan_intf_opcode_current_connection,
- IntPtr.Zero,
- out dataSize,
- ref queryData,
- IntPtr.Zero);
-
- // ERROR_INVALID_STATE will be returned if the client is not connected to a network.
- return CheckResult(result, "WlanQueryInterface", false)
- ? Marshal.PtrToStructure(queryData)
- : default(WLAN_CONNECTION_ATTRIBUTES);
- }
- finally
- {
- if (queryData != IntPtr.Zero)
- WlanFreeMemory(queryData);
- }
- }
-
- private static WLAN_PROFILE_INFO[] GetProfileInfoList(IntPtr clientHandle, Guid interfaceGuid)
- {
- var profileList = IntPtr.Zero;
- try
- {
- var result = WlanGetProfileList(
- clientHandle,
- interfaceGuid,
- IntPtr.Zero,
- out profileList);
-
- return CheckResult(result, "WlanGetProfileList", false)
- ? new WLAN_PROFILE_INFO_LIST(profileList).ProfileInfo
- : new WLAN_PROFILE_INFO[] { };
- }
- finally
- {
- if (profileList != IntPtr.Zero)
- WlanFreeMemory(profileList);
- }
- }
-
- private static string GetProfileXml(IntPtr clientHandle, Guid interfaceGuid, string profileName)
- {
- var profileXml = IntPtr.Zero;
- try
- {
- uint flags = 0U;
- uint grantedAccess;
- var result = WlanGetProfile(
- clientHandle,
- interfaceGuid,
- profileName,
- IntPtr.Zero,
- out profileXml,
- ref flags,
- out grantedAccess);
-
- // ERROR_NOT_FOUND will be returned if the profile is not found.
- return CheckResult(result, "WlanGetProfile", false)
- ? Marshal.PtrToStringUni(profileXml)
- : null; // To be used
- }
- finally
- {
- if (profileXml != IntPtr.Zero)
- WlanFreeMemory(profileXml);
- }
- }
-
- private static bool SetProfilePosition(IntPtr clientHandle, Guid interfaceGuid, string profileName, uint position)
- {
- var result = WlanSetProfilePosition(
- clientHandle,
- interfaceGuid,
- profileName,
- position,
- IntPtr.Zero);
-
- // ERROR_INVALID_PARAMETER will be returned if the interface is removed.
- // ERROR_NOT_FOUND will be returned if the position of a profile is invalid.
- return CheckResult(result, "WlanSetProfilePosition", false);
- }
-
- private static bool DeleteProfile(IntPtr clientHandle, Guid interfaceGuid, string profileName)
- {
- var result = WlanDeleteProfile(
- clientHandle,
- interfaceGuid,
- profileName,
- IntPtr.Zero);
-
- // ERROR_INVALID_PARAMETER will be returned if the interface is removed.
- // ERROR_NOT_FOUND will be returned if the profile is not found.
- return CheckResult(result, "WlanDeleteProfile", false);
- }
-
- private static bool Connect(IntPtr clientHandle, Guid interfaceGuid, string profileName, DOT11_BSS_TYPE bssType)
- {
- var connectionParameters = new WLAN_CONNECTION_PARAMETERS
- {
- wlanConnectionMode = WLAN_CONNECTION_MODE.wlan_connection_mode_profile,
- strProfile = profileName,
- dot11BssType = bssType,
- dwFlags = 0U
- };
-
- var result = WlanConnect(
- clientHandle,
- interfaceGuid,
- ref connectionParameters,
- IntPtr.Zero);
-
- // ERROR_NOT_FOUND will be returned if the interface is removed.
- return CheckResult(result, "WlanConnect", false);
- }
-
- private static bool Disconnect(IntPtr clientHandle, Guid interfaceGuid)
- {
- var result = WlanDisconnect(
- clientHandle,
- interfaceGuid,
- IntPtr.Zero);
-
- // ERROR_NOT_FOUND will be returned if the interface is removed.
- return CheckResult(result, "WlanDisconnect", false);
- }
-
- private static void RegisterNotification(IntPtr clientHandle, uint notificationSource, Action callback)
- {
- // Storing a delegate in class field is necessary to prevent garbage collector from collecting it
- // before the delegate is called. Otherwise, CallbackOnCollectedDelegate may occur.
- _notificationCallback = new WLAN_NOTIFICATION_CALLBACK(callback);
-
- var result = WlanRegisterNotification(clientHandle,
- notificationSource,
- false,
- _notificationCallback,
- IntPtr.Zero,
- IntPtr.Zero,
- 0);
-
- CheckResult(result, "WlanRegisterNotification", true);
- }
-
- private static WLAN_NOTIFICATION_CALLBACK _notificationCallback;
-
- private static bool CheckResult(uint result, string methodName, bool willThrowOnFailure)
- {
- if (result == ERROR_SUCCESS)
- return true;
-
- if (!willThrowOnFailure)
- {
- switch (result)
- {
- case ERROR_INVALID_PARAMETER:
- case ERROR_INVALID_STATE:
- case ERROR_NOT_FOUND:
- case ERROR_NOT_ENOUGH_MEMORY:
- case ERROR_ACCESS_DENIED:
- case ERROR_NOT_SUPPORTED:
- case ERROR_SERVICE_NOT_ACTIVE:
- case ERROR_NDIS_DOT11_AUTO_CONFIG_ENABLED:
- case ERROR_NDIS_DOT11_MEDIA_IN_USE:
- case ERROR_NDIS_DOT11_POWER_STATE_INVALID:
- return false;
-
- case ERROR_INVALID_HANDLE:
- break;
- }
- }
- throw CreateWin32Exception(result, methodName);
- }
-
- private static Win32Exception CreateWin32Exception(uint errorCode, string methodName)
- {
- var sb = new StringBuilder(512); // This 512 capacity is arbitrary.
-
- var result = FormatMessage(
- FORMAT_MESSAGE_FROM_SYSTEM,
- IntPtr.Zero,
- errorCode,
- 0x0409, // US (English)
- sb,
- sb.Capacity,
- IntPtr.Zero);
-
- var message = string.Format("Method: {0}, Code: {1}", methodName, errorCode);
- if (0 < result)
- message += string.Format(", Message: {0}", sb.ToString());
-
- return new Win32Exception((int)errorCode, message);
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/WlanProfileViewer/Models/Wlan/NativeWifiWorker.cs b/WlanProfileViewer/Models/Wlan/NativeWifiWorker.cs
index ebca11e..a530c51 100644
--- a/WlanProfileViewer/Models/Wlan/NativeWifiWorker.cs
+++ b/WlanProfileViewer/Models/Wlan/NativeWifiWorker.cs
@@ -5,29 +5,31 @@
using System.Threading;
using System.Threading.Tasks;
+using ManagedNativeWifi;
+
namespace WlanProfileViewer.Models.Wlan
{
internal class NativeWifiWorker : IWlanWorker
{
#region Get profiles
- public async Task> GetProfilesAsync(bool isLatest, TimeSpan timeoutDuration)
+ public async Task> GetProfilesAsync(bool isLatest, TimeSpan timeout)
{
if (isLatest)
- await NativeWifi.ScanAsync(timeoutDuration).ConfigureAwait(false);
+ await NativeWifi.ScanNetworksAsync(timeout).ConfigureAwait(false);
var profilePacks = await Task.Run(() => NativeWifi.EnumerateProfiles()).ConfigureAwait(false);
return profilePacks.Select(x => new ProfileItem(
name: x.Name,
- interfaceGuid: x.InterfaceGuid,
+ interfaceId: x.Interface.Id,
interfaceName: null,
- interfaceDescription: x.InterfaceDescription,
+ interfaceDescription: x.Interface.Description,
authentication: ConvertToAuthentication(x.Authentication),
encryption: ConvertToEncryption(x.Encryption),
position: x.Position,
isAutomatic: x.IsAutomatic,
- signal: x.Signal,
+ signal: x.SignalQuality,
isConnected: x.IsConnected));
}
@@ -72,7 +74,7 @@ public async Task SetProfilePositionAsync(ProfileItem profileItem, int pos
if (position < 0)
throw new ArgumentOutOfRangeException(nameof(position));
- return await Task.Run(() => NativeWifi.SetProfilePosition(profileItem.Name, profileItem.InterfaceGuid, position));
+ return await Task.Run(() => NativeWifi.SetProfilePosition(profileItem.InterfaceId, profileItem.Name, position));
}
#endregion
@@ -84,27 +86,27 @@ public async Task DeleteProfileAsync(ProfileItem profileItem)
if (profileItem == null)
throw new ArgumentNullException(nameof(profileItem));
- return await Task.Run(() => NativeWifi.DeleteProfile(profileItem.Name, profileItem.InterfaceGuid));
+ return await Task.Run(() => NativeWifi.DeleteProfile(profileItem.InterfaceId, profileItem.Name));
}
#endregion
#region Connect/Disconnect
- public async Task ConnectAsync(ProfileItem profileItem, TimeSpan timeoutDuration)
+ public async Task ConnectNetworkAsync(ProfileItem profileItem, TimeSpan timeout)
{
if (profileItem == null)
throw new ArgumentNullException(nameof(profileItem));
- return await NativeWifi.ConnectAsync(profileItem.Name, profileItem.InterfaceGuid, NativeWifi.BssType.Any, timeoutDuration);
+ return await NativeWifi.ConnectNetworkAsync(profileItem.InterfaceId, profileItem.Name, BssType.Any, timeout);
}
- public async Task DisconnectAsync(ProfileItem profileItem, TimeSpan timeoutDuration)
+ public async Task DisconnectNetworkAsync(ProfileItem profileItem, TimeSpan timeout)
{
if (profileItem == null)
throw new ArgumentNullException(nameof(profileItem));
- return await NativeWifi.DisconnectAsync(profileItem.InterfaceGuid, timeoutDuration);
+ return await NativeWifi.DisconnectNetworkAsync(profileItem.InterfaceId, timeout);
}
#endregion
diff --git a/WlanProfileViewer/Models/Wlan/Netsh.cs b/WlanProfileViewer/Models/Wlan/Netsh.cs
index 86f70fa..52be87b 100644
--- a/WlanProfileViewer/Models/Wlan/Netsh.cs
+++ b/WlanProfileViewer/Models/Wlan/Netsh.cs
@@ -29,9 +29,9 @@ public enum NetworkType
private class ShortProfilePack
{
- public string Name { get; set; }
- public string InterfaceName { get; set; }
- public int Position { get; set; }
+ public string Name { get; }
+ public string InterfaceName { get; }
+ public int Position { get; }
public ShortProfilePack(string name, string interfaceName, int position)
{
@@ -43,20 +43,20 @@ public ShortProfilePack(string name, string interfaceName, int position)
public class ProfilePack
{
- public string Name { get; private set; }
- public string InterfaceName { get; private set; }
- public string Ssid { get; private set; }
- public NetworkType NetworkType { get; private set; }
- public string Authentication { get; private set; }
- public string Encryption { get; private set; }
- public int Position { get; private set; }
- public bool IsAutomatic { get; private set; }
+ public string Name { get; }
+ public string InterfaceName { get; }
+ public string Ssid { get; }
+ public NetworkType NetworkType { get; }
+ public string Authentication { get; }
+ public string Encryption { get; }
+ public int Position { get; }
+ public bool IsAutomatic { get; }
public ProfilePack(
string name,
string interfaceName,
string ssid,
- NetworkType netwotrkType,
+ NetworkType networkType,
string authentication,
string encryption,
int position,
@@ -65,7 +65,7 @@ public ProfilePack(
this.Name = name;
this.InterfaceName = interfaceName;
this.Ssid = ssid;
- this.NetworkType = netwotrkType;
+ this.NetworkType = networkType;
this.Authentication = authentication;
this.Encryption = encryption;
this.Position = position;
@@ -75,24 +75,24 @@ public ProfilePack(
public class InterfacePack
{
- public string Name { get; private set; }
- public string Description { get; private set; }
- public Guid Guid { get; private set; }
- public string PhysicalAddress { get; private set; }
- public bool IsConnected { get; private set; }
- public string ProfileName { get; private set; }
+ public string Name { get; }
+ public string Description { get; }
+ public Guid Id { get; }
+ public string PhysicalAddress { get; }
+ public bool IsConnected { get; }
+ public string ProfileName { get; }
public InterfacePack(
string name,
string description,
- Guid guid,
+ Guid id,
string physicalAddress,
bool isConnected,
string profileName)
{
this.Name = name;
this.Description = description;
- this.Guid = guid;
+ this.Id = id;
this.PhysicalAddress = physicalAddress;
this.IsConnected = isConnected;
this.ProfileName = profileName;
@@ -101,12 +101,12 @@ public InterfacePack(
public class NetworkPack
{
- public string InterfaceName { get; private set; }
- public string Ssid { get; private set; }
- public NetworkType NetworkType { get; private set; }
- public string Authenticaion { get; private set; }
- public string Encryption { get; private set; }
- public int Signal { get; private set; }
+ public string InterfaceName { get; }
+ public string Ssid { get; }
+ public NetworkType NetworkType { get; }
+ public string Authenticaion { get; }
+ public string Encryption { get; }
+ public int Signal { get; }
public NetworkPack(
string interfaceName,
@@ -142,7 +142,7 @@ private static IEnumerable EnumerateInterfaces(IEnumerable EnumerateInterfaces(IEnumerable EnumerateInterfaces(IEnumerable EnumerateNetworks(IEnumerable ou
// encryption,
// signal.Value);
- yield return new NetworkPack(interfaceName, ssid, networkType, authentication, encryption, signal.Value);
+ yield return new NetworkPack(
+ interfaceName: interfaceName,
+ ssid: ssid,
+ networkType: networkType,
+ authentication: authentication,
+ encryption: encryption,
+ signal: signal.Value);
ssid = null;
networkType = default(NetworkType);
@@ -315,7 +327,7 @@ public static async Task> GetProfilesAsync()
var shortProfiles = EnumerateShortProfiles(outputLines);
- return (await Task.WhenAll(shortProfiles.Select(async x => await GetProfileAsync(x.Name, x.InterfaceName, x.Position))))
+ return (await Task.WhenAll(shortProfiles.Select(async x => await GetProfileAsync(x.InterfaceName, x.Name, x.Position))))
.Where(x => x != null);
}
@@ -347,22 +359,22 @@ private static IEnumerable EnumerateShortProfiles(IEnumerable<
}
}
- public static async Task GetProfileAsync(string profileName, string interfaceName, int position)
+ public static async Task GetProfileAsync(string interfaceName, string profileName, int position)
{
- if (string.IsNullOrWhiteSpace(profileName))
- return null;
-
if (string.IsNullOrWhiteSpace(interfaceName))
- return null;
+ throw new ArgumentNullException(nameof(interfaceName));
+
+ if (string.IsNullOrWhiteSpace(profileName))
+ throw new ArgumentNullException(nameof(profileName));
var command = $@"netsh wlan show profile name=""{profileName}"" interface=""{interfaceName}""";
var outputLines = await ExecuteNetshAsync(command).ConfigureAwait(false);
- return GetProfile(outputLines, profileName, interfaceName, position);
+ return GetProfile(outputLines, interfaceName, profileName, position);
}
- private static ProfilePack GetProfile(IEnumerable outputLines, string profileName, string interfaceName, int position)
+ private static ProfilePack GetProfile(IEnumerable outputLines, string interfaceName, string profileName, int position)
{
bool? isAutomatic = null;
string ssid = null;
@@ -420,7 +432,7 @@ private static ProfilePack GetProfile(IEnumerable outputLines, string pr
(encryption == null))
return null;
- //Debug.WriteLine("Profile: {0}, Interface: {1}, SSID: {2}, BSS type: {3}, Authentication: {4}, Encryption: {5}, Position: {6}, IsAutomatic: {7}",
+ //Debug.WriteLine("Profile: {0}, Interface: {1}, SSID: {2}, BSS: {3}, Authentication: {4}, Encryption: {5}, Position: {6}, IsAutomatic: {7}",
// profileName,
// interfaceName,
// ssid,
@@ -431,30 +443,30 @@ private static ProfilePack GetProfile(IEnumerable outputLines, string pr
// isAutomatic.Value);
return new ProfilePack(
- profileName,
- interfaceName,
- ssid,
- networkType,
- authentication,
- encryption,
- position,
- isAutomatic.Value);
+ name: profileName,
+ interfaceName: interfaceName,
+ ssid: ssid,
+ networkType: networkType,
+ authentication: authentication,
+ encryption: encryption,
+ position: position,
+ isAutomatic: isAutomatic.Value);
}
#endregion
#region Set profile position
- public static async Task SetProfilePositionAync(string profileName, string interfaceName, int position)
+ public static async Task SetProfilePositionAync(string interfaceName, string profileName, int position)
{
- if (string.IsNullOrWhiteSpace(profileName))
- return false;
-
if (string.IsNullOrWhiteSpace(interfaceName))
- return false;
+ throw new ArgumentNullException(nameof(interfaceName));
+
+ if (string.IsNullOrWhiteSpace(profileName))
+ throw new ArgumentNullException(nameof(profileName));
if (position < 0)
- return false;
+ throw new ArgumentOutOfRangeException(nameof(position));
position++; // According to the error message, "Profile preference order starts with 1."
@@ -471,10 +483,10 @@ public static async Task SetProfilePositionAync(string profileName, string
#region Delete profile
- public static async Task DeleteProfileAsync(string profileName, string interfaceName)
+ public static async Task DeleteProfileAsync(string interfaceName, string profileName)
{
if (string.IsNullOrWhiteSpace(profileName))
- return false;
+ throw new ArgumentNullException(nameof(profileName));
var command = $@"netsh wlan delete profile name=""{profileName}""";
if (!string.IsNullOrWhiteSpace(interfaceName))
@@ -493,13 +505,13 @@ public static async Task DeleteProfileAsync(string profileName, string int
#region Connect/Disconnect
- public static async Task ConnectAsync(string profileName, string interfaceName)
+ public static async Task ConnectNetworkAsync(string interfaceName, string profileName)
{
- if (string.IsNullOrWhiteSpace(profileName))
- return false;
-
if (string.IsNullOrWhiteSpace(interfaceName))
- return false;
+ throw new ArgumentNullException(nameof(interfaceName));
+
+ if (string.IsNullOrWhiteSpace(profileName))
+ throw new ArgumentNullException(nameof(profileName));
var command = $@"netsh wlan connect name=""{profileName}"" interface=""{interfaceName}""";
@@ -510,10 +522,10 @@ public static async Task ConnectAsync(string profileName, string interface
return outputLines.Contains(expected);
}
- public static async Task DisconnectAsync(string interfaceName)
+ public static async Task DisconnectNetworkAsync(string interfaceName)
{
if (string.IsNullOrWhiteSpace(interfaceName))
- return false;
+ throw new ArgumentNullException(nameof(interfaceName));
var command = $@"netsh wlan disconnect interface=""{interfaceName}""";
diff --git a/WlanProfileViewer/Models/Wlan/NetshWorker.cs b/WlanProfileViewer/Models/Wlan/NetshWorker.cs
index 0942efe..f5fc174 100644
--- a/WlanProfileViewer/Models/Wlan/NetshWorker.cs
+++ b/WlanProfileViewer/Models/Wlan/NetshWorker.cs
@@ -10,7 +10,7 @@ internal class NetshWorker : IWlanWorker
{
#region Get profiles
- public async Task> GetProfilesAsync(bool isLatest, TimeSpan timeoutDuration)
+ public async Task> GetProfilesAsync(bool isLatest, TimeSpan timeout)
{
var interfacePacks = (await Netsh.GetInterfacesAsync().ConfigureAwait(false))
.ToArray(); // ToArray method is necessary.
@@ -28,7 +28,7 @@ from interfacePack in interfacePacks
where profilePack.InterfaceName.Equals(interfacePack.Name, StringComparison.Ordinal)
select new ProfileItem(
name: profilePack.Name,
- interfaceGuid: interfacePack.Guid,
+ interfaceId: interfacePack.Id,
interfaceName: profilePack.InterfaceName,
interfaceDescription: interfacePack.Description,
authentication: ConvertToAuthentication(profilePack.Authentication),
@@ -87,7 +87,7 @@ public async Task SetProfilePositionAsync(ProfileItem profileItem, int pos
if (position < 0)
throw new ArgumentOutOfRangeException(nameof(position));
- return await Netsh.SetProfilePositionAync(profileItem.Name, profileItem.InterfaceName, position);
+ return await Netsh.SetProfilePositionAync(profileItem.InterfaceName, profileItem.Name, position);
}
#endregion
@@ -99,27 +99,27 @@ public async Task DeleteProfileAsync(ProfileItem profileItem)
if (profileItem == null)
throw new ArgumentNullException(nameof(profileItem));
- return await Netsh.DeleteProfileAsync(profileItem.Name, profileItem.InterfaceName);
+ return await Netsh.DeleteProfileAsync(profileItem.InterfaceName, profileItem.Name);
}
#endregion
#region Connect/Disconnect
- public async Task ConnectAsync(ProfileItem profileItem, TimeSpan timeoutDuration)
+ public async Task ConnectNetworkAsync(ProfileItem profileItem, TimeSpan timeout)
{
if (profileItem == null)
throw new ArgumentNullException(nameof(profileItem));
- return await Netsh.ConnectAsync(profileItem.Name, profileItem.InterfaceName);
+ return await Netsh.ConnectNetworkAsync(profileItem.InterfaceName, profileItem.Name);
}
- public async Task DisconnectAsync(ProfileItem profileItem, TimeSpan timeoutDuration)
+ public async Task DisconnectNetworkAsync(ProfileItem profileItem, TimeSpan timeout)
{
if (profileItem == null)
throw new ArgumentNullException(nameof(profileItem));
- return await Netsh.DisconnectAsync(profileItem.InterfaceName);
+ return await Netsh.DisconnectNetworkAsync(profileItem.InterfaceName);
}
#endregion
diff --git a/WlanProfileViewer/Models/Wlan/ProfileItem.cs b/WlanProfileViewer/Models/Wlan/ProfileItem.cs
index 83a9464..af9abb4 100644
--- a/WlanProfileViewer/Models/Wlan/ProfileItem.cs
+++ b/WlanProfileViewer/Models/Wlan/ProfileItem.cs
@@ -17,9 +17,9 @@ public class ProfileItem : BindableBase
public string Name { get; }
///
- /// Interface GUID
+ /// Interface ID
///
- public Guid InterfaceGuid { get; }
+ public Guid InterfaceId { get; }
///
/// Interface name (only for Netsh)
@@ -44,7 +44,7 @@ public class ProfileItem : BindableBase
///
/// Profile ID
///
- public string Id => _id ?? (_id = Name + InterfaceGuid.ToString());
+ public string Id => _id ?? (_id = Name + InterfaceId.ToString());
private string _id;
///
@@ -114,7 +114,7 @@ public bool IsConnected
public ProfileItem(
string name,
- Guid interfaceGuid,
+ Guid interfaceId,
string interfaceName,
string interfaceDescription,
AuthenticationMethod authentication,
@@ -127,11 +127,11 @@ public ProfileItem(
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentNullException(nameof(name));
- if (interfaceGuid == default(Guid))
- throw new ArgumentException(nameof(interfaceGuid));
+ if (interfaceId == Guid.Empty)
+ throw new ArgumentException(nameof(interfaceId));
this.Name = name;
- this.InterfaceGuid = interfaceGuid;
+ this.InterfaceId = interfaceId;
this.InterfaceName = interfaceName;
this.InterfaceDescription = interfaceDescription;
this.Authentication = authentication;
diff --git a/WlanProfileViewer/Properties/AssemblyInfo.cs b/WlanProfileViewer/Properties/AssemblyInfo.cs
index 5890f14..dbaa559 100644
--- a/WlanProfileViewer/Properties/AssemblyInfo.cs
+++ b/WlanProfileViewer/Properties/AssemblyInfo.cs
@@ -51,5 +51,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.2")]
-[assembly: AssemblyFileVersion("1.0.0.2")]
+[assembly: AssemblyVersion("1.1.0.4")]
+[assembly: AssemblyFileVersion("1.1.0.4")]
diff --git a/WlanProfileViewer/ViewModels/MainWindowViewModel.cs b/WlanProfileViewer/ViewModels/MainWindowViewModel.cs
index ca41a0e..3fe4762 100644
--- a/WlanProfileViewer/ViewModels/MainWindowViewModel.cs
+++ b/WlanProfileViewer/ViewModels/MainWindowViewModel.cs
@@ -182,7 +182,7 @@ public MainWindowViewModel()
.CombineLatestValuesAreAllTrue()
.ToReactiveCommand();
ConnectCommand
- .Subscribe(async _ => await Op.ConnectAsync());
+ .Subscribe(async _ => await Op.ConnectNetworkAsync());
#endregion
@@ -195,7 +195,7 @@ public MainWindowViewModel()
.CombineLatestValuesAreAllTrue()
.ToReactiveCommand();
DisconnectCommand
- .Subscribe(async _ => await Op.DisconnectAsync());
+ .Subscribe(async _ => await Op.DisconnectNetworkAsync());
#endregion
diff --git a/WlanProfileViewer/WlanProfileViewer.csproj b/WlanProfileViewer/WlanProfileViewer.csproj
index e236e73..56e4757 100644
--- a/WlanProfileViewer/WlanProfileViewer.csproj
+++ b/WlanProfileViewer/WlanProfileViewer.csproj
@@ -41,21 +41,25 @@
Resources\ring.ico
+
+ False
+ Library\ManagedNativeWifi.dll
+
False
Library\MonitorAware.dll
- ..\packages\ReactiveProperty.2.2.3.1\lib\net45\ReactiveProperty.dll
+ ..\packages\ReactiveProperty.2.2.8\lib\net45\ReactiveProperty.dll
True
- ..\packages\ReactiveProperty.2.2.3.1\lib\net45\ReactiveProperty.DataAnnotations.dll
+ ..\packages\ReactiveProperty.2.2.8\lib\net45\ReactiveProperty.DataAnnotations.dll
True
- ..\packages\ReactiveProperty.2.2.3.1\lib\net45\ReactiveProperty.NET45.dll
+ ..\packages\ReactiveProperty.2.2.8\lib\net45\ReactiveProperty.NET45.dll
True
@@ -118,7 +122,6 @@
-
@@ -196,6 +199,8 @@
+
+
diff --git a/WlanProfileViewer/packages.config b/WlanProfileViewer/packages.config
index 99ac362..88a6a63 100644
--- a/WlanProfileViewer/packages.config
+++ b/WlanProfileViewer/packages.config
@@ -1,6 +1,6 @@
-
+