извините, похоже, что SO "insert code" не обрабатывает длинные списки кодов, поэтому коды выглядят плохо. Скопируйте/вставьте их в свой редактор и переформатируйте.
элементы (1), (2), (3) довольно тривиальны - это просто определения классов/структур/функций экспорта. Пункт (4) - это то, где происходит всякая магия, но я не смог вставить его сюда (слишком долго), поэтому я скопировал его в PasteBin (ссылка ниже). Пожалуйста, дайте мне знать, если у вас возникнут вопросы - я постараюсь вам помочь, но идея состоит в том, чтобы использовать низкоуровневую функцию DeviceIoControl для связи с адаптером.
Пожалуйста, взгляните на коды. Я не думаю, что вы сможете их скомпилировать, однако они должны дать вам представление о том, что происходит под капотом. Отказ от ответственности - я их написал 5-6 лет назад, а сейчас я хотел бы сделать это совсем другое :)
C# обертка для библиотеки DLL C++:
общественного класса WiFiDllWrapper { частный класс DllFunctions { [DllImport ("EWF.DLL ")] внутренний статический ехЬегп BOOL TurnWlanOn();
[DllImport("ewf.dll")]
internal static extern bool FindWirelessAdapter();
[DllImport("ewf.dll")]
internal static extern bool ConnectToAdapter();
[DllImport("ewf.dll")]
internal static extern bool DisconnectFromAdapter();
[DllImport("ewf.dll")]
internal static extern bool StartScan();
// gets a list of APs from NIC
[DllImport("ewf.dll")]
internal static extern bool GetAPsList([In, Out] APInfo[] pAPs, int maxAPs, ref int foundAPs);
// connects to a selected AP
[DllImport("ewf.dll")]
internal static extern bool ConnectToAP(int maxWaitTimeSeconds, string ssid, bool isWepEnabled, string wepKey);
[DllImport("ewf.dll")]
internal static extern bool RenewIPAddress(int maxWaitTimeSeconds);
}
public static bool TurnWlanOn()
{
return DllFunctions.TurnWlanOn();
}
public static bool FindWirelessAdapter()
{
return DllFunctions.FindWirelessAdapter();
}
public static bool ConnectToNdis()
{
bool bDisableWzcViaDriver = (Settings.GetOSVersion() != OSVersion.WM2003);
bool bRes = DllFunctions.ConnectToAdapter();
return bRes;
}
public static bool DisconnectFromNdis()
{
return DllFunctions.DisconnectFromAdapter();
}
public static void StartScan()
{
DllFunctions.StartScan();
}
public static bool ConnectToAP(int maxWaitTimeSeconds, string ssid, bool isWepEnabled, string wepKey)
{
DllFunctions.ConnectToAP(maxWaitTimeSeconds, ssid, isWepEnabled, wepKey);
return true;
}
public static bool RenewIPAddress(int maxWaitTimeSeconds)
{
return DllFunctions.RenewIPAddress(maxWaitTimeSeconds);
}
public static List<AccessPoint> GetAPsList()
{
int numberOfItems = 0; // gets a number of actually found devices
APInfo[] OutputList = new APInfo[30];
if (DllFunctions.GetAPsList(OutputList, OutputList.Length, ref numberOfItems) == false)
throw new Exception("AP scan failed!");
List<AccessPoint> lst = new List<AccessPoint>();
for (int i = 0; i < numberOfItems; i++)
lst.Add(new AccessPoint(OutputList[i]));
return lst;
}
}
AccessPoint определения модели:
// just took enums from NTDDNDIS.H file...
перечисление NDIS_802_11_WEP_STATUS { Ndis802_11WEPEnabled, Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, Ndis802_11WEPDisabled, Ndis802_11Encryptio nDisabled = 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_NETWORK_INFRASTRUCTURE { Ndis802_11IBSS, Ndis802_11Infrastructure, Ndis802_11AutoUnknown, Ndis802_11InfrastructureMax // Не реальное значение, определяется как верхняя граница };
перечисление NDIS_802_11_NETWORK_TYPE { Ndis802_11FH, Ndis802_11DS, Ndis802_11OFDM5, // Добавлены новые типы для OFDM-5G и 2.4G Ndis802_11OFDM24, Ndis802_11NetworkTypeMax // не вещественного типа, определенного в качестве верхней границы };
[StructLayout (LayoutKind.Sequential, НаборСимволов = CharSet.Unicode)] структура Apinfo { [MarshalAs (UnmanagedType.ByValTStr, SizeConst = 40)] общественного строка _ssid; // идентификатор SSID из AP
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string _mac; // MAC address of the AP
//[MarshalAs(UnmanagedType.U4)]
public int _rssi; // signal strength in dB
//[MarshalAs(UnmanagedType.U4)]
public uint _wepStatus;
[MarshalAs(UnmanagedType.I4)]
public NDIS_802_11_NETWORK_INFRASTRUCTURE _networkInfrastructure;
[MarshalAs(UnmanagedType.I4)]
public NDIS_802_11_NETWORK_TYPE _networkType;
[MarshalAs(UnmanagedType.U4)]
public uint BeaconPeriod; // units are Kusec
[MarshalAs(UnmanagedType.U4)]
public uint DSConfig; // Frequency, units are kHz
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] _rates; // MSDN: Each byte describes a single rate in units of 0.5 Mbps
}
общественного класса AccessPoint { // если уровень мощности (в дБм) ниже, чем это, то сигнал слабый Const INT STRONG_WEEK_dBm_THRESHOLD = -70 ;
public static bool IsSignalWeak(int SignalStrengthdBm)
{
return SignalStrengthdBm < STRONG_WEEK_dBm_THRESHOLD;
}
internal AccessPoint(APInfo apInfo)
{
_ssid = apInfo._ssid;
_mac = apInfo._mac;
_rssi = apInfo._rssi;
_wepStatus = apInfo._wepStatus;
_networkInfrastructure = apInfo._networkInfrastructure;
_networkType = apInfo._networkType;
BeaconPeriod = apInfo.BeaconPeriod;
DSConfig = apInfo.DSConfig;
_rates = apInfo._rates;
}
private string _ssid; // SSID of the AP
private string _mac; // MAC address of the AP
private int _rssi; // signal strength in dB
private uint _wepStatus;
private NDIS_802_11_NETWORK_INFRASTRUCTURE _networkInfrastructure;
private NDIS_802_11_NETWORK_TYPE _networkType;
private uint BeaconPeriod; // units are Kusec
private uint DSConfig; // Frequency, units are kHz
private byte[] _rates; // MSDN: Each byte describes a single rate in units of 0.5 Mbps
public bool IsEncrypted
{
get
{
return _wepStatus != 0;
}
}
/// <summary>
/// Beacon Interval in ms
/// </summary>
public ulong BeaconInterval
{
get { return BeaconPeriod; }
}
/// <summary>
/// Frequency in MHz
/// </summary>
public ulong Frequency
{
get { return (DSConfig/1000); }
}
/// <summary>
/// Supported Rates by AP. Part of them belongs to Basic Rate Set.
/// </summary>
public string Rates
{
get
{
Array.Sort(_rates);
string basicRateSet = "", notBasicRateSet = "";
for (int i = 0; i < _rates.Length; i++)
{
if (_rates[i] == 0)
continue;
// Each supported rate from the BSSBasicRateSet is encoded as a byte with the most significant bit (bit 7) set to 1.
if ((_rates[i] & (1 << 7)) > 0)
basicRateSet += ((_rates[i] - 128)/2).ToString() + "; ";
// Rates that are not included in the BSSBasicRateSet are encoded with the most significant bit set to zero.
else
notBasicRateSet += (_rates[i]/2).ToString() + "; ";
}
return "BSSBasicRateSet: {" + basicRateSet + "}. other: {" + notBasicRateSet + "}";
}
}
/// <summary>
/// Number of wireless channel
/// </summary>
public ulong Channel
{
get
{
ulong centralFreqMHz = DSConfig/1000;
if (centralFreqMHz > 2400 && centralFreqMHz < 2500) // then this is 802.11b/g
{
/*
Regional allocated use of 802.11b/g channels
1 to 11 -- North America (USA and Canada)
1 to 13 -- Austria, Belgium, Denmark, Finland, France, Germany, Greece, Iceland, Ireland, Italy, Liechtenstein, Luxembourg, Netherlands, Norway, Portugal, Spain, Sweden, Switzerland, United Kingdom.
1 to 14 -- Japan, China, Hong Kong, Philippines, Taiwan, Thailand, Singapore, South Korea
*/
switch (centralFreqMHz)
{
case 2412:
return 1;
case 2417:
return 2;
case 2422:
return 3;
case 2427:
return 4;
case 2432:
return 5;
case 2437:
return 6;
case 2442:
return 7;
case 2447:
return 8;
case 2452:
return 9;
case 2457:
return 10;
case 2462:
return 11;
case 2467:
return 12;
case 2472:
return 13;
case 2484:
return 14;
default:
return 0;
}
}
else if (centralFreqMHz > 5100 && centralFreqMHz < 5900) // this is 802.11a
{
switch (centralFreqMHz)
{
case 5170:
return 34;
case 5180:
return 36;
case 5190:
return 38;
case 5200:
return 40;
case 5210:
return 42;
case 5220:
return 44;
case 5230:
return 46;
case 5240:
return 48;
case 5260:
return 52;
case 5280:
return 56;
case 5300:
return 60;
case 5320:
return 64;
case 5500:
return 100;
case 5520:
return 104;
case 5540:
return 108;
case 5560:
return 112;
case 5580:
return 116;
case 5600:
return 120;
case 5620:
return 124;
case 5640:
return 128;
case 5660:
return 132;
case 5680:
return 136;
case 5700:
return 140;
case 5745:
return 149;
case 5765:
return 153;
case 5785:
return 157;
case 5805:
return 161;
default:
return 0;
}
}
else
return 0;
}
}
/// <summary>
/// SSID of the AP
/// </summary>
public string SSID
{
get { return _ssid; }
}
/// <summary>
/// MAC address "XX-XX-XX-XX-XX-XX"
/// </summary>
public string MAC
{
get { return _mac; }
}
/// <summary>
/// Signal strength in dB
/// </summary>
public int SignalStrength
{
get { return (int)_rssi; }
}
/// <summary>
/// MSDN:
/// Specifies a WEP/WPA/WPA2 encryption requirement. A value of 0 indicates that privacy is disabled.
/// A value of 1 indicates that privacy is enabled.
/// </summary>
public string WEP
{
get { return (_wepStatus == 0 ? "WEP disabled" : "WEP enabled"); }
}
/// <summary>
/// Indicates the physical layer for the AP
/// </summary>
public string NetworkType
{
get
{
if (_networkType == NDIS_802_11_NETWORK_TYPE.Ndis802_11FH)
return "frequency-hopping spread-spectrum PHY";
else if (_networkType == NDIS_802_11_NETWORK_TYPE.Ndis802_11DS)
return "direct-sequence spread-spectrum PHY";
else if (_networkType == NDIS_802_11_NETWORK_TYPE.Ndis802_11OFDM24)
return "OFDM 2.4 GHz";
else if (_networkType == NDIS_802_11_NETWORK_TYPE.Ndis802_11OFDM5)
return "OFDM 5 GHz";
else
return "PHY is not FH, nor DS";
}
}
/// <summary>
/// Indicates current network mode for AP
/// </summary>
public string NetworkMode
{
get
{
if (_networkInfrastructure == NDIS_802_11_NETWORK_INFRASTRUCTURE.Ndis802_11IBSS)
return "IBSS (ad hoc) mode";
else if (_networkInfrastructure == NDIS_802_11_NETWORK_INFRASTRUCTURE.Ndis802_11Infrastructure)
return "Infrastructure (ESS) mode";
else if (_networkInfrastructure == NDIS_802_11_NETWORK_INFRASTRUCTURE.Ndis802_11AutoUnknown)
return "Automatic network mode";
else
return "not specified";
}
}
}
C++ файл # 1 - экспортируемые функции:
включают "stdafx.h"
включают "ewf.h"
включают " NdisConnect.h "
Включает
NdisConnect g_NdisAdapter (L "ewf_log.TXT ");
ехЬегп HANDLE g_NdisConnectedEvent;
ехЬегп "С" EWF_API BOOL WINAPI FindWirelessAdapter() { ENTER;
try
{
return g_NdisAdapter.FindWirelessAdapter();
}
catch (NdisException* e)
{
LOG_EXCEPTION(e);
return FALSE;
}
LEAVE;
return TRUE;
}
// 1. инициализации адаптера: CreateFile (NDISUIO_DEVICE_NAME, - сделано в g_NdisAdapter ctor // 2. отключить WZC // 3. адаптер перезаписи // 4. открыть адаптер extern "C" EWF_API BOOL WINAPI ConnectToAdapter() { ENTER;
try
{
if (FALSE == g_NdisAdapter.FindWirelessAdapter())
return FALSE;
if (false == g_NdisAdapter.DisableWZC_Driver())
g_NdisAdapter.DisableWZC_API();
g_NdisAdapter.RebindAdapter();
g_NdisAdapter.OpenDevice();
}
catch (NdisException* e)
{
LOG_EXCEPTION(e);
return FALSE;
}
LEAVE;
return TRUE;
}
ехЬегп "С" EWF_API BOOL WINAPI TurnWlanOn() { возврата g_NdisAdapter.TurnWlanOn(); }
ехЬегп "С" EWF_API BOOL WINAPI DisconnectFromAdapter() { ENTER; try { g_NdisAdapter.Disassociate(); } catch (NdisException * e) { LOG_EXCEPTION (e); return FALSE;
}
LEAVE;
return TRUE;
}
ехЬегп "С" EWF_API BOOL StartScan() { ENTER; g_NdisAdapter.ScanForAPs();
return TRUE;
}
ехЬегп "С" EWF_API BOOL GetAPsList (Apinfo * PAPS, Int, Int maxAPs * foundAPs) { ENTER; BOOL res = FALSE;
try
{
res = g_NdisAdapter.GetAPList(pAPs, maxAPs, foundAPs);
}
catch (NdisException* e)
{
LOG_EXCEPTION(e);
return FALSE;
}
LEAVE;
return TRUE;
}
ехЬегп "С" EWF_API BOOL ConnectToAP (интермедиат maxWaitTimeSeconds, сопзЬ wchar_t * SSID, BOOL isWepEnabled, Const wchar_t * wepKey) { символ cSSID [33], cWepKey [30]; localFunctionCT2A (ssid, cSSID, sizeof (cSSID)); localFunctionCT2A (wepKey, cWepKey, sizeof (cWepKey));
ENTER_FUNC("SSID = " << cSSID << ", wep enabled = " << isWepEnabled << ", wep key = '" << cWepKey << "'");
g_NdisAdapter.Disassociate();
Sleep(2000);
ResetEvent(g_NdisConnectedEvent);
g_NdisAdapter.ConnectToAP(cSSID, isWepEnabled, cWepKey);
if (WAIT_OBJECT_0 != WaitForSingleObject(g_NdisConnectedEvent, maxWaitTimeSeconds*1000))
{
LOG("Did not get CONNECTED event from NDIS...");
return FALSE;
}
LEAVE;
return TRUE;
}
- NdisConnect класс - все NDIS волшебство происходит здесь:
< <, когда я вставил код здесь, я пошел более чем 30k предел на пост, так что я создал PasteBin file >> - http://pastebin.com/wMBZAYCQ
все еще проблема? вы бы рассматривали неуправляемую DLL и управляемый интерфейс? Несколько лет назад я сделал что-то подобное - я использовал NDIS на неуправляемой стороне. Если вы это рассмотрите - я отправлю коды. Пожалуйста, дай мне знать. – avs099
Несомненно. Я уже смирился с необходимостью использовать API, поэтому, если у вас уже есть обертки вокруг них, это еще лучше. –
Я начал писать ответ и понял, что вы говорите о беспроводных профилях - вы имеете в виду точки доступа или что-то еще? – avs099