I have a certain number of external devices, let's call them Things.
Each Thing interfaces with the computer through a PnP Card plugged into a PCI slot.
Each Card has ports for 4 Things.
I need to obtain a UID for each Thing that persists and is consistent between reboots.
Note that the Things do not have a built in UID that I can access.
My idea to solve this problem is to get a UID for each port on the Cards. It seems to me that I just have to figure out which PCI slot each Card is plugged in to. That isn't going to change on reboot, and certainly the ports are going to be in the same order... so I can essentially label each port with the UID and know which UID each Thing is associated with.
I have done a fair bit of searching to figure out what C# objects would be of most use. The closest I have found is the ManagementObjectSearcher object from the System.Management library. Here is some simple code I wrote to see if this would get me what I want:
static void Main(string[] args)
{
IDsearch();
Console.ReadLine();
}
static void IDsearch()
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_PnPEntity");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("DeviceID: {0}", queryObj["DeviceID"]);
Console.WriteLine("Description: {0}", queryObj["Description"]);
}
}
This produces output like the following for every PnP devices on my computer:
DeviceID: ACPI\GENUINEINTEL_-_INTEL64_FAMILY_6_MODEL_60_-_INTEL(R)_CORE(TM)_I7-4790_CPU_#_3.60GHZ\_1
Description: Intel Processor
DeviceID: USB\VID_0CF3&PID_3004\ALASKA_DAY_2006
Description: Dell Wireless 1535C Bluetooth Device
This would fit my requirements if I could also obtain the PCI slot number.
I also came across the Win32_SystemSlot class, but this does not seem to give me a description of what is actually plugged into the slot! So at this point, I can get descriptions without PCI slots... and PCI slots without descriptions. I just can't map them together, which is what I need. I must be overlooking something or not asking the right question, because this strikes me as a pretty common thing.
Thank you for your help.
That sounds extremely fragile, what if the machine get moved and the devices get plugged into different ports. Is is a personal project or something you are trying to distribute. If the latter you should find another way. Are the "Things" of your own creation? If so you need to include the ability for each to have a unique identifier. If not you should contact the manufacturer and inquire. Trying to identify it by port may cause you lots of headaches down the road
I think you're looking for a combination of the Win32_Bus and the Win32_DeviceBus classes.
The Win32_Bus represents a physical bus as seen by a computer running a Windows operating system (Microsoft Docs). The bus type can be PCI and bus number seems to be an enumeration of the different physical PCI buses.
The Win32_DeviceBus relates a system bus and a logical device using the bus. This class is used to discover which devices are on which bus (Microsoft Docs). On my platform the device associated with a bus was always a Win32_PnPEntity.
Using these classes you should be able to find the physical bus attributes from a given Win32_PnPEntity.
Related
I need to read a machine's MAC id in C# which stays fixed irrespective of the connection types e.g. connected to Work through network cable, wifi, VPN through Home wifi, through a Dongle or even can be offline.
So basically it need not necessarily be the MAC id of network interface which is "Up", i just need the MAC id which is/stays constant.
With the help of answers in the below link and other suggestions,
Reliable method to get machine's MAC address in C#
I am able to read the MAC ids, but still don't understand which one to consider that will reliably give me the fixed MAC id, which i can use in my application for some sort of verification in that particular system.
Here are the details of all network interfaces of that system, when the system is connected to "Work" through VPN using Home Wifi and connected to "Work" network directly:
Please suggest which one i should consider and what should be the right condition to filter out the interface with fixed MAC id in C#.
As indicated as "Related" to my question and also as pointed by #Caius Jard, i got the solution from the below link which will suit for my need:
How to determine MAC Address of the actual physical network card -- not virtual network interfaces created by VPN's (.NET C#)
because i want to:
-> take the MAC id of the physical card (i.e. excluding all virtual, pseudo, logical, usb) and don't allow my application without any physical card
-> consider the 1st card, in case more than 1 cards are installed
I have modified the query as per my need with the help of details given in below link:
https://weblogs.sqlteam.com/mladenp/2010/11/04/find-only-physical-network-adapters-with-wmi-win32_networkadapter-class/
So, my final solution looks like below:
ManagementObjectSearcher searcher = new ManagementObjectSearcher
(#"SELECT Index,MACAddress,PNPDeviceID
FROM Win32_NetworkAdapter
WHERE MACAddress IS NOT NULL AND PNPDeviceID IS NOT NULL AND Manufacturer != 'Microsoft' AND PNPDeviceID LIKE '%PCI\\%'");
IList<ManagementObject> mObject = searcher.Get()
.Cast<ManagementObject>()
.OrderBy(p => Convert.ToUInt32(p.Properties["Index"].Value))
.ToList();
foreach (var obj in mObject)
{
var mac = obj["MACAddress"].ToString();
mac = mac.Replace(":", string.Empty);
return mac;
}
Your physical (vs. virtual, logical) interface MAC addresses should stay same (at least until the physical device is replaced). Your "Ethernet 3", for example.
Suppose I'm programming a game and I want the option of banning people from it after violating the terms. I can ban them per account, I can also ban their IP but it's not going to ban them from my game forever. They will just have to create a new account and change their IP.
Is there something like a machine-ID that is unique for every machine in the world? If there is, is it possible to read it using a program language? Is it possible for the user to change this machine-ID?
Bulletproof solution?
I would say no solution will be 100% secure, even with huge invested money..
What you can do, is to make it as hard as possible for normal users, and this way minimize the cheaters.
You could make a hash id of the pc machine id + the mac address + the motherboard id + the harddisk id, etc. But a clever cracker/hacker could get around this. I mean take a look at companies like Microsoft that uses millions in making a secure way and still people can get around the activation in some way... ;)
In windows there is a hardware id, that you might be intrested in.
HKEY_LOCAL_MACHINE\Software\Microsoft\Cryptography\MachineGuid
Take a look at WMI too, there are examples of how to use it with c++
Windows Management Instrumentation (WMI) is a set of extensions to the Windows Driver Model that provides an operating system interface through which instrumented components.
see WMI c++ exmaples
How about hard disk serial number which you can get in WMI Win32_DiskDrive.
ManagementObjectSearcher searcher = null;
try
{
searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("SerialNumber: {0}", queryObj["SerialNumber"]);
queryObj.Dispose();
}
}
finally
{
if (searcher != null)
searcher.Dispose();
}
I am writing a program in C# to perform a hardware audit across many Windows XP workstations.
I need to determine which PCI devices are actual cards connected via a motherboard slot - NOT onboard devices that also use the PCI buses (built into the motherboard).
I can successfully list all devices that use all the PCI buses using a variety of WMI classes, but none provide any indication of what is onboard vs. what is connected via a slot.
I am not fussy about how the information is retrieved or from where it sourced (e.g. Pinvoke, WMI, registry, etc) as long as it's reliable.
Thank you!
After many hours I came up with a 'reasonably' reliable approach.
This logic fundamentally assumes that the slotted PCI device bus ID is unique and separate from all other (onboard) PCI bus IDs. So far my tests have shown this to be the case; regardless this is still an assumption.
My code is rather long and I'm sure it could be improved so instead I'll explain the process in pseudo-code:
Determine how many slots are in use (and only proceed if at least one slot is actually in use):
"SELECT SlotDesignation FROM Win32_SystemSlot WHERE CurrentUsage = 4"
Store all the device IDs that belong to the PCI bus:
"SELECT DeviceID FROM Win32_Bus where BusType = 5"
Capture all system and logical device associations:
"SELECT * FROM Win32_DeviceBus"
Search all system and logical device associations (antecedent property) and count each time each deviceID occurs.
You can now determine the DeviceID where the slotted PCI devices reside by finding the DeviceID that occurs the same number of times as the number of devices found in the system slots.
For each of the Win32_DeviceBus results that contain the DeviceID (in the antecedent property) the dependent property will reference another DeviceID to be used for the Win32_PnPEntity class.
Query the Win32_PnPEntity with the newly captured DeviceID and you now have all your device info (or rather, all information the the Win32_PnPEntity provides)!
"SELECT * FROM Win32_PnPEntity WHERE DeviceID = '" + deviceID + "'"
Unfortunately I could not find ANY way to utilize the severely limited information returned by the Win32_SystemSlot class (that would have made life too easy!) other than the count of results returned by the 'in use' query.
Note that it may be possible to encounter more than one PCI bus that has the same number of devices as the count of slots that are in use. If this scenario were to arise (I haven't encountered it yet) then it'd suggest raising an exception rather than continuing and assuming you're querying the correct PCI bus.
TL;DR version of this question: WMI Win32_NetworkAdapter class contains information I need, but is too slow. What's a faster method of getting information for the MACAddress, ConfigManagerErrorCode, and PNPDeviceID columns on Windows?
I need to retrieve information for attached network adapters so I can get a MAC address to uniquely identify the local Microsoft Windows computer. The WMI Win32_NetworkAdapter class seems to have the information I'm looking for. The MACAddress, ConfigManagerErrorCode, and PNPDeviceID columns are the only ones I really need:
MACAddress: the MAC address (goal of this operation)
ConfigManagerErrorCode: allows me to determine if the adapter is enabled and running or not. (If it's disabled then I should use a MAC address previously cached by my app, if available).
PNPDeviceID: By checking for a prefix of "PCI" (and possibly other interfaces, if necessary) I can filter out non-physical adapters, of which there are several on my Windows 7 box (including virtual adapters, like for VMware / VirtualBox).
My plan was to filter out non-physical devices using PNPDeviceID. Then I would use the MACAddress column on any remaining table entries (saving the address to a cache). When the device is disabled (as possibly indicated by a non-zero ConfigManagerErrorCode) and the MACAddress is null, I can use a previously-seen MACAddress for that device from my cache.
You can see the contents of this table on my Windows 7 computer. You can see there's tons of junk in there, but only one entry with a "PCI" PNPDeviceID.
wmic:root\cli>NIC GET Caption, ConfigManagerErrorCode, MACAddress, PNPDeviceID
Caption ConfigManagerErrorCode MACAddress PNPDeviceID
[00000000] WAN Miniport (SSTP) 0 ROOT\MS_SSTPMINIPORT\0000
[00000001] WAN Miniport (IKEv2) 0 ROOT\MS_AGILEVPNMINIPORT\0000
[00000002] WAN Miniport (L2TP) 0 ROOT\MS_L2TPMINIPORT\0000
[00000003] WAN Miniport (PPTP) 0 ROOT\MS_PPTPMINIPORT\0000
[00000004] WAN Miniport (PPPOE) 0 ROOT\MS_PPPOEMINIPORT\0000
[00000005] WAN Miniport (IPv6) 0 ROOT\MS_NDISWANIPV6\0000
[00000006] WAN Miniport (Network Monitor) 0 ROOT\MS_NDISWANBH\0000
[00000007] Intel(R) 82567LM-2 Gigabit Network Connection 0 00:1C:C0:B0:C4:89 PCI\VEN_8086&DEV_10CC&SUBSYS_00008086&REV_00\3&33FD14CA&0&C8
[00000008] WAN Miniport (IP) 0 ROOT\MS_NDISWANIP\0000
[00000009] Microsoft ISATAP Adapter 0 ROOT\*ISATAP\0000
[00000010] RAS Async Adapter 0 20:41:53:59:4E:FF SW\{EEAB7790-C514-11D1-B42B-00805FC1270E}\ASYNCMAC
[00000011] Microsoft Teredo Tunneling Adapter 0 ROOT\*TEREDO\0000
[00000012] VirtualBox Bridged Networking Driver Miniport 0 00:1C:C0:B0:C4:89 ROOT\SUN_VBOXNETFLTMP\0000
[00000013] VirtualBox Host-Only Ethernet Adapter 0 08:00:27:00:C4:A1 ROOT\NET\0000
[00000014] Microsoft ISATAP Adapter 0 ROOT\*ISATAP\0001
[00000015] VMware Virtual Ethernet Adapter for VMnet1 0 00:50:56:C0:00:01 ROOT\VMWARE\0000
[00000016] Microsoft ISATAP Adapter 0 ROOT\*ISATAP\0002
[00000017] VMware Virtual Ethernet Adapter for VMnet8 0 00:50:56:C0:00:08 ROOT\VMWARE\0001
[00000018] Microsoft ISATAP Adapter 0 ROOT\*ISATAP\0003
(If I disable my physical adapter, then the MACAddress column goes to null, and ConfigManagerErrorCode changes to non-zero).
Unfortunately, this class is simply too slow. Any query on Win32_NetworkAdapter consistently takes 0.3 seconds on my relatively modern Windows 7 Core i7-based computer. So using this will add yet another 0.3 seconds to application startup (or worse), which I find unacceptable. This is especially because I can't think of a single valid reason why it should take so long to figure out what MAC addresses and plug-and-play device IDs are on the local computer.
Searching for other methods to get a MAC address yielded the GetAdaptersInfo and the newer GetAdaptersAddresses functions. They don't have the 0.3 second penalty that WMI imposes. These functions are the ones used by the .NET Framework's NetworkInterface class (as determined by examining .NET source code), and the "ipconfig" command line tool (as determined by using Dependency Walker).
I made a simple example in C# that lists all network adapters using the NetworkInterface class. Unfortunately, using these APIs seems to have two shortcomings:
These APIs don't even list disabled network adapters to begin with. That means I can't look up the MAC address for a disabled adapter from my cache.
I don't see how I can get the PNPDeviceID to filter out non-physical adapters.
My question is: what method can I use to get the MAC address of the local computer's physical adapters (whether it is enabled or not) in a few tens of milliseconds at most?
(I'm experienced at both C# and C++ and am fine with reading other languages, so I really don't care what language might be used in answers).
EDIT: In response to Alex K's suggestion for using return immediate and forward only, and also to provide some sample WMI code for what I am doing - here is some C# code that lists the columns of interest:
public static void NetTest() {
System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
EnumerationOptions opt = new EnumerationOptions();
// WMI flag suggestions from Alex K:
opt.ReturnImmediately = true;
opt.Rewindable = false;
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\cimv2", "select MACAddress, PNPDeviceID, ConfigManagerErrorCode from Win32_NetworkAdapter", opt);
foreach (ManagementObject obj in searcher.Get()) {
Console.WriteLine("=========================================");
foreach (PropertyData pd in obj.Properties) {
Console.WriteLine("{0} = {1}", pd.Name, pd.Value);
}
}
Console.WriteLine(sw.Elapsed.TotalSeconds);
}
I called this function 3 times and each time got about 0.36 seconds printed on the last line. So the suggested flags don't seem to have any effect: positive or negative. This is not too surprising, as the answer at How to make forward-only, read-only WMI queries in C#? seems to indicate that no change in performance will be observed unless there are a large number of records (e.g. hundreds to thousands), which is not the case with Win32_NetworkAdapter table.
EDIT 2: Multiple answers have been proposed to use SendARP from the IP helper API (this is the same API that has the GetAdaptersInfo function). What advantages does this give over GetAdaptersInfo for finding the local MAC address? I cannot think of any - on the surface, GetAdaptersInfo seems to return a more thorough set of information than SendARP does for local adapters. Now that I think about it, I think that a big part of my question centers over the concept of enumeration: what adapters exist on the computer in the first place? SendARP does not perform enumeration: it assumes you already know the IP address of the adapter you want a MAC for. I need to figure out what adapters exist on the system. Some issues this raises:
What happens if the network cable is unplugged? This would be very common on a laptop, for example (unplugged Ethernet, disconnected WiFi card). I tried using NetworkInterface.GetAllNetworkInterfaces() and listing all the unicast addresses using GetIPProperties().UnicastAddresses when the media is unplugged. No addresses are listed by Windows, so I can't think of any address that could be passed to SendARP. Intuitively, it makes sense that an unplugged adapter would still have a physical address, but no IP address (since it is not on a network with a DHCP server).
Which brings me to: how do I get a list of local IP addresses to test with SendARP?
How do I get the PNPDeviceID (or similar ID that can be used to filter non-physical adapters) for each adapter?
How do I list disabled adapters, so I can look up a MAC address from my cache (i.e. the MAC address I found when it was last enabled)?
These issues don't seem to be addressed by SendARP, and are the major reason I asked this question (otherwise I'd be using GetAdaptersInfo and moving on with things...).
I wound up cutting WMI completely out of the equation and made a significant improvement while still getting the information I wanted. As noted with WMI, it was taking > 0.30 seconds to get results. With my version, I can get the same information in about 0.01 seconds.
I used the setup API, configuration manager API, and then made OID requests directly on the NDIS network driver to get the MAC address. The setup API seems obnoxiously slow, especially when getting things like property values. It's imperative to keep setup API calls at a minimum. (You can actually see just how bad it is by looking at how long it takes to load the "Details" tab of a device in Device manager).
A guess on why WMI was so slow: I noted that WMI's Win32_NetworkAdapter always took the same amount of time no matter which subset of properties I queried. Seems like the WMI Win32_NetworkAdapter class programmers were lazy and didn't optimize their class to only gather requested information like other WMI classes do. They probably gather all information, whether requested or not. They probably significantly rely on Setup API to do this, and the excessive calls to the slow Setup API to get unwanted information is what makes it so slow.
High level overview of what I did:
Use SetupDiGetClassDevs to get all network devices that are present on the system.
I filter out all results that don't have an enumerator of "PCI" (use SetupDiGetDeviceRegistryProperty with SPDRP_ENUMERATOR_NAME to get the enumerator).
For the remainder, I can use CM_Get_DevNode_Status to get the device status and error code. All devices with removable device status codes are filtered out.
If DN_HAS_PROBLEM is set such that there is a non-zero error code then the device is probably disabled (or has some other problem). The driver isn't loaded so we can't make a request to the driver. Therefore in this case I load the MAC address for the network card from a cache I maintain.
A parent device could be removable so I filter those out too by recursively examining the device tree using CM_Get_Parent and CM_Get_DevNode_Status to look for parent removable devices.
Any remaining devices are nonremovable network cards on the PCI bus.
For each network device, I use SetupDiGetClassDevs with GUID_NDIS_LAN_CLASS GUID and DIGCF_DEVICEINTERFACE flag to get its interfaces (this only works if the device is enabled / does not have a problem).
Use IOCTL_NDIS_QUERY_GLOBAL_STATS with OID_802_3_PERMANENT_ADDRESS on the driver's interface to get the permanent MAC address. Save it in the cache, and then return.
The result is a robust indication of MAC addresses on the PC that should be immune to "fake" network cards made by VMware, VirtualBox, largely immune to network cards that are temporarily disabled, and immune to transient network cards attached via USB, ExpressCard, PC Card, or any future removable interface.
EDIT: IOCTL_NDIS_QUERY_GLOBAL_STATS isn't supported by all network cards. The vast majority work, but some Intel cards do not. See How to reliably and quickly get the MAC address of a network card given its device instance ID
You should be able to get everything you need from the System.Net namespace. For example, the following sample is lifted from MSDN and does what you asked for in the original version of the question. It displays the physical addresses of all interfaces on the local computer.
public static void ShowNetworkInterfaces()
{
IPGlobalProperties computerProperties = IPGlobalProperties.GetIPGlobalProperties();
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
Console.WriteLine("Interface information for {0}.{1} ",
computerProperties.HostName, computerProperties.DomainName);
if (nics == null || nics.Length < 1)
{
Console.WriteLine(" No network interfaces found.");
return;
}
Console.WriteLine(" Number of interfaces .................... : {0}", nics.Length);
foreach (NetworkInterface adapter in nics)
{
IPInterfaceProperties properties = adapter.GetIPProperties(); // .GetIPInterfaceProperties();
Console.WriteLine();
Console.WriteLine(adapter.Description);
Console.WriteLine(String.Empty.PadLeft(adapter.Description.Length,'='));
Console.WriteLine(" Interface type .......................... : {0}", adapter.NetworkInterfaceType);
Console.Write(" Physical address ........................ : ");
PhysicalAddress address = adapter.GetPhysicalAddress();
byte[] bytes = address.GetAddressBytes();
for(int i = 0; i< bytes.Length; i++)
{
// Display the physical address in hexadecimal.
Console.Write("{0}", bytes[i].ToString("X2"));
// Insert a hyphen after each byte, unless we are at the end of the
// address.
if (i != bytes.Length -1)
{
Console.Write("-");
}
}
Console.WriteLine();
}
}
Now my team working in a network project using windows application c#. I didn't know how to programmatically detect Cipher type and Encryption level from a wireless network device from windows 2003 server.
After searching i got WMI (Windows Management Instrumentation) for solving the problem.+
Please suggest example/reference for finding Cipher type and Encryption level from a wireless network device from windows 2003 server
just found you question. The information which you search for originate from NDIS driver. WMI only gives you a subset of such information. Every NDIS driver support some standard requests which can be send with respect of DeviceIoControl function (see http://msdn.microsoft.com/en-us/library/aa363216%28v=VS.85%29.aspx). As an input (lpInBuffer parameter) you should give a DWORD with an OID code, a control code which identify the request, As an output you receive a structure with information filed, or in your case a DWORD (enum value). For example, if you asked NDIS driver for
#define OID_802_11_WEP_STATUS 0x0D01011B
(as DWORD value of lpInBuffer parameter) it returns back also DWORD with information like
// Also aliased typedef to new name
typedef enum _NDIS_802_11_WEP_STATUS
{
Ndis802_11WEPEnabled,
Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
Ndis802_11WEPDisabled,
Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
Ndis802_11WEPKeyAbsent,
Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
Ndis802_11WEPNotSupported,
Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
Ndis802_11Encryption2Enabled,
Ndis802_11Encryption2KeyAbsent,
Ndis802_11Encryption3Enabled,
Ndis802_11Encryption3KeyAbsent
} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS,
NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
request for
#define OID_802_11_AUTHENTICATION_MODE 0x0D010118
returns
typedef enum _NDIS_802_11_AUTHENTICATION_MODE
{
Ndis802_11AuthModeOpen,
Ndis802_11AuthModeShared,
Ndis802_11AuthModeAutoSwitch,
Ndis802_11AuthModeWPA,
Ndis802_11AuthModeWPAPSK,
Ndis802_11AuthModeWPANone,
Ndis802_11AuthModeWPA2,
Ndis802_11AuthModeWPA2PSK,
Ndis802_11AuthModeMax // Not a real mode, defined as upper bound
} NDIS_802_11_AUTHENTICATION_MODE;
request for
#define OID_802_11_INFRASTRUCTURE_MODE 0x0D010108
returns
typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE
{
Ndis802_11IBSS,
Ndis802_11Infrastructure,
Ndis802_11AutoUnknown,
Ndis802_11InfrastructureMax // Not a real value, defined as upper bound
} NDIS_802_11_NETWORK_INFRASTRUCTURE;
and so on. You can find all different constants which you needs in ntddndis.h after installing of Windows DDK.
To open a device handle you should use CreateFile function. Instead of file name you should give a string with the prefix "\\.\" and adapter name (adapter guids). Adapter names you can enumerate with different way. One of the easiest is the subkey names of the registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Adapters.
All what I explained above work exactly like http://msdn.microsoft.com/en-us/library/aa964902%28v=VS.85%29.aspx or other examples of usage DeviceIoControl. The full list of IoControl requests which must support some device class is described in DDK. I repeat one more time, that for usage of that one need only use DeviceIoControl and not write a device driver.
More as 10 years ago I play a little with such requests which I described here. I tested my old program works without any problems now. One need only use OIDs which you need and not much more.
UPDATED: I found a good link http://pages.infinit.net/codeguru/WiFiArticle.htm which explains in other words the same what I just written. It seems to me that one use here wrong parameters in CreateFile. One have to use FILE_SHARE_READ | FILE_SHARE_WRITE to makes all working. Example http://code.google.com/p/haggle/source/browse/winmobile/Haggle/WindowsWiFiUtils.cpp (see bool WindowsWiFiUtils:init(), bool WindowsWiFiUtils::setEncryptionMode(unsigned long adapterIndex, const unsigned int mode) etc) looks like much better and contain a lot of methods which can be also interesting for you. It is a C++ example, but it's very easy to rewrite this in C#.
UPDATED 2: One more way is usage of "Native Wifi API" http://msdn.microsoft.com/en-us/library/ms706556%28VS.85%29.aspx like WlanQueryInterface (for example with wlan_intf_opcode_supported_infrastructure_auth_cipher_pairs) or WZCQueryInterface, but it seems not supported on Windows Server 2003, what you need. Generally "Native Wifi API" is probably more reliable way to give maximum information (or modify it), but WMI can be also a good pragmatical alternative.
As far as WMI is concerned you are fairly limited in the wireless connection information you can retrieve.
Running a WMI query for "Select * from MSNdis_80211_WEPStatus where active=true" should give you a numerical result where:
0=WEP is in use
2=Connection is unsecured
4=WPA-PSK is in use
6=WPA is in use
7=Disconnected
To run this query from powershell you can simply do:
PS C:\WINDOWS> gwmi -query "Select * from MSNdis_80211_WEPStatus where active=true" -namespace root\wmi
From C# the following should work:
using System;
using System.Management;
class Query_SelectQuery
{
public static int Main(string[] args)
{
SelectQuery selectQuery = new
SelectQuery("Select * from MSNdis_80211_WEPStatus where active=true");
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\wmi", selectQuery);
foreach (ManagementObject resultVal in searcher.Get())
{
Console.WriteLine(resultVal.ToString());
}
Console.ReadLine();
return 0;
}
}
If you have multiple active wireless connections it gets more difficult because you have to get the SSID values by querying the Ndis80211Ssid property in the MSNdis_80211_ServiceSetIdentifier class.
If you were on Windows {Vista, 7, Server 2008} you could run netsh wlan export from a command shell and get it to output a nice .xml file with your network settings (not including the wireless key) but I don't think there's any way to get this to work on Windows XP, Server 2003 or other unlisted operating systems.
Another option if you need more detailed configuration information specifically under Windows 2003 Server is to access the group policy settings as detailed in this article:
http://technet.microsoft.com/en-us/library/bb878079.aspx
I don't have a Windows Server 2003 machine handy to test with but you should be able to access these Group Policy Objects and settings through WMI under the root\RSoP namespace
Running wbemtest from console or using the Microsoft WMI Code Creator tool will let you look around the available WMI objects and classes to figure out exactly where those Group Policy Objects are lying.
Querying for Group Policy WMI Objects looks kinda painful though :(