private void TranslateEncryptionKey(ref WLANConfiguration config, string key, AuthenticationMode authMode, WEPStatus privacyMode) { if (privacyMode == WEPStatus.WEPEnabled) { if ((key.Length != 10) && (key.Length != 26)) { throw new ArgumentException("The encryption key for WEP must be either 10 or 26 characters"); } byte[] keyMaterial = HexStringToBytes(key); config.KeyMaterial = keyMaterial; config.CtlFlags |= WZCControl.WEPKPresent | WZCControl.WEPKXFormat; if (key.Length == 10) { config.CtlFlags |= WZCControl.WEPK40Bit; } config.KeyMaterial = EncryptKeyMaterial(keyMaterial); } else if ((privacyMode == WEPStatus.AESEnabled) || (privacyMode == WEPStatus.TKIPEnabled)) { config.KeyLength = key.Length; if ((config.KeyLength < 8) || (config.KeyLength > 63)) { throw new ArgumentException("The encryption key for WPA-PSK/TKIP must be either between 8 and 63"); } WZC.WZCPassword2Key(ref config, key); config.CtlFlags |= WZCControl.WEPKPresent | WZCControl.WEPKXFormat | WZCControl.ONEXEnabled; config.WPAMCastCipher = (int)WEPStatus.TKIPEnabled; config.KeyMaterial = EncryptKeyMaterial(config.KeyMaterial); } }
public static int QueryAdapter(string adapterName, out INTF_ENTRY entry) { // Attempt to get the status of the indicated // interface by calling WZCQueryInterface. If // it works, we return true; if not, false. // Note that the first parameter, the WZC server, // is set to null, apparently indicating that the // local machine is the target. entry = new INTF_ENTRY(); INTF_FLAGS flags = 0; entry.Guid = adapterName; int retVal = 0; try { retVal = WZC.WZCQueryInterface(null, INTF_FLAGS.INTF_ALL, ref entry, out flags); } catch (Exception ex) { // on a throw, the return value needs to get set to a non-zero try { WZC.WZCDeleteIntfObj(ref entry); } catch { } return(-1); } return(retVal); }
internal unsafe void RefreshList(Boolean clearCache) { // If we are to clear the driver's cache of SSID // values, call the appropriate method. //Console.WriteLine("Entering RefreshList"); if (clearCache) { this.ClearCache(); // This seems to be needed to avoid having // a list of zero elements returned. System.Threading.Thread.Sleep(20); } m_aps.Clear(); if (m_adapter is WirelessZeroConfigNetworkInterface) { m_aps.AddRange(WZC.GetAPs(m_adapter.Name)); } else { GetNDISAPs(); } }
/// <summary> /// Creates a new entry with given name in memory /// </summary> /// <param name="guid">Name</param> /// <returns>Entry</returns> public static INTF_ENTRY GetEntry(string guid) { INTF_ENTRY entry = new INTF_ENTRY(); entry.Guid = guid; INTF_FLAGS dwOutFlags; int uret = WZC.WZCQueryInterface(null, INTF_FLAGS.INTF_ALL, ref entry, out dwOutFlags); if (uret > 0) { throw new NetworkInformationException(uret); } return(entry); }
public void Dispose() { if (wszDescr != IntPtr.Zero) { Marshal.FreeHGlobal(this.wszDescr); } if (wszGuid != IntPtr.Zero) { Marshal.FreeHGlobal(this.wszGuid); } if (bInitialized != 0) { WZC.WZCDeleteIntfObj(ref this); } }
/// <summary> /// Removes a network from the adapter's preferred list /// </summary> /// <param name="SSID">The SSID of the network to remove</param> public bool RemovePreferredNetwork(string SSID) { if ((SSID == null) || (SSID == string.Empty)) { throw new ArgumentException("Invalid SSID"); } // Get the current preferred list of SSID values. // First, we need to get an INTF_ENTRY for this adapter. INTF_ENTRY entry; int uret = WZC.QueryAdapter(this.Name, out entry); try { if (uret > 0) { // There is no list. Return false. return(false); } // Find the indicated item and remove it from // the list by creating a new list and setting // that as the preferred list. RAW_DATA rdold = entry.rdStSSIDList; WLANConfigurationList prefl = new WLANConfigurationList(rdold); // If there are no items in the list, return false. if (prefl.NumberOfItems == 0) { return(false); } // Build the new list. WLANConfigurationList prefnew = new WLANConfigurationList(prefl.NumberOfItems - 1); // Start at the top of the old list and copy items // from old to new, until we find the item to be // removed. int j = 0; int i; for (i = 0; i < prefl.NumberOfItems; i++) { WLANConfiguration item = prefl.Item(i); if (item.SSID == SSID) { // Skip to next item without incrementing // j. } else { prefnew.SetItem(j, item); j++; } } // Check for whether the item was found in the // list or not. If not, we don't reset the // wireless settings and instead return false. if (j == i) { return(false); } // Replace the old list with the new one // for the rest of the code. Entry #0 // is unset. prefl = prefnew; // Must now copy the new preferred list to the entry that // we will send with WZCSetInterface. entry.rdStSSIDList = prefl.rawData; // Finally, we are ready to select the new SSID as our // primary preferred connection. uret = WZC.SetAdapter(entry, INTF_FLAGS.INTF_ALL_FLAGS | INTF_FLAGS.INTF_PREFLIST); if (uret != 0) { throw new System.ComponentModel.Win32Exception(uret, "Unable to Set WZC Interface"); } } finally { entry.Dispose(); } return(uret <= 0); }
/// <summary> /// Sets wireless settings associated with a given interface and AP, adding to, rather than replacing the preferred list of APs. This version of the /// method is designed for the case where *all* of the options are going to be set, where no initial configuration exists at all and where existing /// items in the preferred list should be maintained. After this method executes, if it is successful, the specified SSID will be at the top, highest- /// priority, end of the preferred list. /// </summary> /// <param name="SSID"> /// Target SSID to connect /// </param> /// <param name="infrastructureMode"> /// Is infrastructure /// </param> /// <param name="authKey"> /// WEP key or WPA shared key string representing hex string (each two characters are converted to a single byte) /// </param> /// <param name="keyIndex"> /// Index of the WEP key. Valid values are 1-4 /// </param> /// <param name="authMode"> /// Authentication mode for the connection /// </param> /// <param name="privacyMode"> /// Privacy (encryption) mode for the connection /// </param> /// <param name="eapParams"> /// Parameters describing how the connection should use EAP to authenticate the user to the network /// </param> /// <returns>true if succeeded</returns> #endregion public bool AddPreferredNetwork(string SSID, bool infrastructureMode, string authKey, int keyIndex, AuthenticationMode authMode, WEPStatus privacyMode, EAPParameters eapParams) { if ((keyIndex <= 0) || (keyIndex > 4)) { throw new ArgumentException("Invalid keyIndex (must be between 1 and 4)"); } if ((SSID == null) || (SSID == string.Empty)) { throw new ArgumentException("Invalid SSID"); } // We may yet need to do some processing on the key, // if it is a WPA key. We need a WZC_WLAN_CONFIG // structure to pass to the WZC routine that does // this processing, however, so that is done below. // Get the current preferred list of SSID values. // First, we need to get an INTF_ENTRY for this adapter. INTF_ENTRY entry; int uret = WZC.QueryAdapter(this.Name, out entry); try { if (uret != 0) { throw new System.ComponentModel.Win32Exception(uret, "No preferred list found"); } // We need to push the indicated item to the top of the // preferred list. Once we do that and call WZCSetInterface // the connection will be established to that SSID. // The preferred list is in the rdStSSIDList field. RAW_DATA rdold = entry.rdStSSIDList; WLANConfigurationList prefl = new WLANConfigurationList(rdold); // Start at the bottom of the list. If the current item // is the one we want to copy, save it and start copying // items down in the list. WLANConfiguration targetItem = null; int i; for (i = (int)prefl.NumberOfItems - 1; i >= 0; i--) { targetItem = prefl.Item(i); if (targetItem.SSID == SSID) { break; } } // If we get no match for our SSID value, the item // is *not* in the preferred list, so we can // skip removing it. if (i >= 0) { // Now, copy the items before i on the // list down to cover i. This leaves // position 0 in the list as a copy of // position 1. We'll fill in position 0 // with the new most-preferred SSID. for (int j = i; j >= 1; j--) { // Copy old list item j-1 to new list item j. prefl.SetItem(j, prefl.Item(j - 1)); } } else { // The item was not in the list. We have // to expand the list and move all of // the original items down one spot. WLANConfigurationList prefl2 = new WLANConfigurationList(prefl.NumberOfItems + 1); for (int j = 0; j < (int)prefl.NumberOfItems; j++) { // Copy from old list to new list. prefl2.SetItem(j + 1, prefl.Item(j)); } // Replace the old list with the new one // for the rest of the code. Entry #0 // is unset. prefl = prefl2; } // Create a new item and put that in the list // at item #0, which presently exists but // doesn't mean anything (it's either a // totally blank item, if the SSID was not // in the list before the call, or it's the // old first item in the list). // Unlike the other SetWirelessSettings versions, // we *don't* get the current configuration here; // our parameters will set that. WLANConfiguration thisConfig = MakeSSIDEntry(SSID, infrastructureMode, authKey, keyIndex, authMode, privacyMode, eapParams); // OK, finally, set the item in the preferred // list according to the parameters to this // call. prefl.SetItem(0, thisConfig); // Must now copy the new preferred list to the entry that // we will sent with WZCSetInterface. entry.rdStSSIDList = prefl.rawData; // Finally, we are ready to select the new SSID as our // primary preferred connection. uret = WZC.SetAdapter(entry, INTF_FLAGS.INTF_PREFLIST); if (uret != 0) { throw new System.ComponentModel.Win32Exception(uret, "Unable to Set WZC Interface"); } } finally { entry.Dispose(); } return(true); }
/// <summary> /// Connects to an already-configured wireless network by SSID /// </summary> /// <param name="SSID"></param> /// <returns></returns> public bool ConnectToPreferredNetwork(string SSID) { INTF_ENTRY entry; int uret = WZC.QueryAdapter(this.Name, out entry); try { if (uret != 0) { throw new System.ComponentModel.Win32Exception(uret, "Unable to Query WZC Interface"); } // We need to push the indicated item to the top of the // preferred list. Once we do that and call WZCSetInterface // the connection will be established to that SSID. // The preferred list is in the rdStSSIDList field. RAW_DATA rdold = entry.rdStSSIDList; WLANConfigurationList prefl = new WLANConfigurationList(rdold); // Start at the bottom of the list. If the current item // is the one we want to copy, save it and start copying // items down in the list. WLANConfiguration targetItem = null; int i; for (i = (int)prefl.NumberOfItems - 1; i >= 0; i--) { targetItem = prefl.Item(i); if (targetItem.SSID == SSID) { break; } } // If we get no match for our SSID value, the item is *not* // in the preferred list. Return false. if (targetItem == null) { return(false); } // If the SSID is already first in the list, we're done. if (i > 0) { // Now, copy the rest of the items one place down in the // list. for (int j = i; j >= 1; j--) { // Copy old list item j-1 to new list item j. prefl.SetItem(j, prefl.Item(j - 1)); } // Put the saved target item in index 0 in the new list. prefl.SetItem(0, targetItem); } uret = WZC.SetAdapter(entry, INTF_FLAGS.INTF_ALL_FLAGS | INTF_FLAGS.INTF_PREFLIST); if (uret != 0) { throw new System.ComponentModel.Win32Exception(uret, "Unable to Set WZC Interface"); } } finally { entry.Dispose(); } return(true); }
/// <summary> /// The ProcessKey routine makes necessary modifications /// to the key material of a WPA key before it is passed /// to WZC routines. The processing done to it depends /// on how it was generated. /// </summary> /// <param name="kt"> /// The key type, indicating how the key material in /// the structure was originally generated /// </param> /// <param name="config"> /// The configuration being changed /// </param> /// <param name="passphrase"> /// For WPA-PSK passphrase type, the passphrase. /// </param> internal void ProcessKey(KeyType kt, ref WLANConfiguration config, string passphrase) { // Define fake key material for 'encrypting' the // keys. byte[] chFakeKeyMaterial = new byte[] { 0x56, 0x09, 0x08, 0x98, 0x4D, 0x08, 0x11, 0x66, 0x42, 0x03, 0x01, 0x67, 0x66 }; byte[] key; uint i; switch (kt) { case KeyType.WPAPassphrase: // We set this explicitly here. It was set // out of line in the NetUI code. config.Privacy = WEPStatus.TKIPEnabled; config.KeyLength = WLANConfiguration.WZCCTL_MAX_WEPK_MATERIAL; config.CtlFlags |= WZCControl.WEPKXFormat | WZCControl.ONEXEnabled | WZCControl.WEPKPresent; WZC.WZCPassword2Key(ref config, passphrase); // Note that, since the config structure doesn't // actually have a byte[] for key material, we // can't modify bytes of that 'array' in-place. key = config.KeyMaterial; for (i = 0; i < WLANConfiguration.WZCCTL_MAX_WEPK_MATERIAL; i++) { key[i] ^= chFakeKeyMaterial[(7 * i) % 13]; } config.KeyMaterial = key; config.EapolParams.EapFlags = EAPFlags.Enabled; config.EapolParams.EapType = EAPType.TLS; config.EapolParams.Enable8021x = true; // config.WPAMCastCipher = Ndis802_11Encryption2Enabled; break; case KeyType.WPABinary: // We set this explicitly here. It was set // out of line in the NetUI code. config.Privacy = WEPStatus.TKIPEnabled; config.KeyLength = WLANConfiguration.WZCCTL_MAX_WEPK_MATERIAL; config.CtlFlags |= WZCControl.WEPKPresent; // Note that, since the config structure doesn't // actually have a byte[] for key material, we // can't modify bytes of that 'array' in-place. key = config.KeyMaterial; for (i = 0; i < WLANConfiguration.WZCCTL_MAX_WEPK_MATERIAL; i++) { config.KeyMaterial[i] ^= chFakeKeyMaterial[(7 * i) % 13]; } config.KeyMaterial = key; config.EapolParams.EapFlags = EAPFlags.Enabled; config.EapolParams.EapType = EAPType.TLS; config.EapolParams.Enable8021x = true; // config.WPAMCastCipher = Ndis802_11Encryption2Enabled; break; } }
/// <summary> /// Reset WZC configuration data. Wireless card will disconnect if it was connected. /// </summary> public void Reset() { WZC.ResetAdapter(this.Name); }
public static int SetAdapter(INTF_ENTRY entry, INTF_FLAGS flags) { return(WZC.WZCSetInterface(null, flags, ref entry, null)); }
/// <summary> /// Returns objects that describe the network interfaces on the local computer. /// </summary> /// <returns> /// A System.Net.NetworkInformation.NetworkInterface array that contains objects /// that describe the available network interfaces, or an empty array if no interfaces /// are detected. /// </returns> public unsafe static INetworkInterface[] GetAllNetworkInterfaces() { NetworkInterface[] interfaceList; uint size; // get buffer size requirement NativeMethods.GetInterfaceInfo(null, out size); byte[] ifTable = new byte[size]; // pin the table buffer fixed(byte *pifTable = ifTable) { byte *p = pifTable; /* table looks like this: * typedef struct _IP_INTERFACE_INFO { * LONG NumAdapters; * IP_ADAPTER_INDEX_MAP Adapter[1]; * } IP_INTERFACE_INFO, *PIP_INTERFACE_INFO; * * typedef struct _IP_ADAPTER_INDEX_MAP { * ULONG Index; * WCHAR Name [MAX_ADAPTER_NAME]; * } IP_ADAPTER_INDEX_MAP, *PIP_ADAPTER_INDEX_MAP; */ // get the table data NativeMethods.GetInterfaceInfo(pifTable, out size); // get interface count int interfaceCount = *p; interfaceList = new NetworkInterface[interfaceCount]; p += 4; // get each interface for (int i = 0; i < interfaceCount; i++) { // get interface index int index = (int)*((int *)p); p += 4; // get interface name byte[] nameBytes = new byte[256]; Marshal.Copy(new IntPtr(p), nameBytes, 0, nameBytes.Length); string name = Encoding.Unicode.GetString(nameBytes, 0, nameBytes.Length); int nullIndex = name.IndexOf('\0'); if (nullIndex > 0) { name = name.Substring(0, nullIndex); } p += 256; // check the wireless capabilities try { NDISUIO.QueryOID(NDIS_OID.WEP_STATUS, name); // didn't throw, so it's wireless - determinine if it's WZC compatible INTF_ENTRY entry; if (WZC.QueryAdapter(name, out entry) == NativeMethods.NO_ERROR) { // this is a WZC wireless adapter interfaceList[i] = new WirelessZeroConfigNetworkInterface(index, name); } else { // this is a non-WZC wireless adapter interfaceList[i] = new WirelessNetworkInterface(index, name); } entry.Dispose(); } catch { // if it's not wireless, it will throw and end up here interfaceList[i] = new NetworkInterface(index, name); } } } return(interfaceList); }