Introduction
In my previous article, we have seen how to query miniport driver using DeviceIOControl
function. DeviceIOControl
function uses IOCTL_NDIS_QUERY_GLOBAL_STATS IOCTL
and many developers are misusing this IOCTL
. So this IOCTL
will be deprecated in later operating system releases.
Instead of IOCTL_NDIS_QUERY_GLOBAL_STATS IOCTL
, Windows Management Instrumentation (WMI) interfaces can be used for querying miniport driver information. A client application which consumes Windows Management Instrumentation (WMI) mechanism can query and set OIDs maintained by NDIS Miniport drivers.
Background
Windows Management Instrumentation (WMI) is a kernel mode service that drivers can use to make measurement and instrumentation data available to user-mode applications.
NDIS automatically registers with WMI each instance of a miniport driver as a data provider. After it is registered, WMI clients can query and set OIDs supported by the miniport driver. NDIS automatically registers GUID for standard miniport driver OIDs. You can check the standard NDIS WMI classes using wbemtest.exe tool. Run wbemtest.exe from command window and connect with “root\wmi
” namespace. Now you can enumerate all NDIS WMI classes using ‘Enum Classes…’ option.
Using the Code
This article demonstrates how to query Signal Strength of a wireless network. A Wireless network card driver exposes various 802.11 OIDs and many of these OIDs are mapped into various WMI classes.
In this example code snippet given below, I am using MSNdis_80211_ReceivedSignalStrength
WMI class. This is the WMI class corresponding to 802.11 OID OID_802_11_RSSI. The instance of this class returns the signal strength of currently connected wireless network. Anyway I am not going to explain in depth about System.Management
namespace classes. With the help of System.Management
namespace classes, we can access the instance of the above WMI class.
public static void printSignalStrength(string wlanInterfaceName)
{
try
{
ManagementScope ms = new ManagementScope("\\\\localhost\\root\\wmi");
string wmiquery = string.Format("SELECT Ndis80211ReceivedSignalStrength
FROM MSNdis_80211_ReceivedSignalStrength
where InstanceName=\"{0}\"", wlanInterfaceName);
ObjectQuery oq = new ObjectQuery(wmiquery);
ManagementObjectSearcher query = new ManagementObjectSearcher(ms, oq);
ManagementObjectCollection moc = query.Get();
ManagementObjectCollection.ManagementObjectEnumerator moe = moc.GetEnumerator();
while (moe.MoveNext()) ;
Int32 rssi = (Int32)moe.Current.GetPropertyValue
("Ndis80211ReceivedSignalStrength");
Console.WriteLine("Received Signal Strength : {0}", rssi);
}
catch (ManagementException e)
{
Console.WriteLine("Exception: {0}", e.Message);
}
catch (Exception e)
{
Console.WriteLine("Exception: {0}", e.Message);
}
}
Here MSNdis_80211_ReceivedSignalStrength
class provides a data member ‘InstanceName
’ which specifies the card name used for querying signal strength. In the above example, I have hardcoded it to my wireless card name. You can check wireless adapter names using Device Manager->Network Adapters and specify a card name shown in your machine. Since MSNdis_80211_ReceivedSignalStrength
requires an active wireless network connection, please ensure that your wireless card is connected into a network.
System.Management
namespace provides access to management information about the system, devices, etc. Applications can query management information using classes like ManagementObjectSearcher
, ManagementQuery
, ManagementScope
, etc. In the above code snippet, you have seen how I have used it in a C# application.
ManagementScope ms = new ManagementScope("\\\\localhost\\root\\wmi");
ManagementScope class specifies namespace or scope for management operations. The next statement specifies the WMI query. Here we are trying to access signal strength of currently connected wireless network. So in our case, signal strength is management information.
string wmiquery = string.Format("SELECT Ndis80211ReceivedSignalStrength FROM
MSNdis_80211_ReceivedSignalStrength where InstanceName=\"{0}\"", wlanInterfaceName);
ObjectQuery oq = new ObjectQuery(wmiquery);
ManagementObjectSearcher query = new ManagementObjectSearcher(ms, oq);
ManagementObjectSearcher
class retrieves management objects on the system based on the specified query. It can be used to enumerate any management objects in the system like network adapters, processes, etc.
ManagementObjectCollection moc = query.Get();
ManagementObjectCollection.ManagementObjectEnumerator moe = moc.GetEnumerator();
while (moe.MoveNext()) ;
Int32 rssi = (Int32)moe.Current.GetPropertyValue("Ndis80211ReceivedSignalStrength");
The above code shows how to retrieve collection of management objects using ManagementObjectSearcher
class. Moreover we can access the value of property 'Ndis80211ReceivedSignalStrength
' directly from the object collection enumerator.
References
- How to query miniport driver information (802.11 OIDs) using DeviceIOControl() function?
- How to access wireless network parameters using native WiFi API?
Conclusion
This article demonstrates how to access signal strength using Windows Management Instrumentation (WMI) mechanism. In the next article, I will show you another way of accessing miniport driver information using native Wi-Fi API.