Перечисление и переключение беспроводных профилей в WM6 без использования OpenNetCF - PullRequest
1 голос
/ 29 февраля 2012

Я пытаюсь перечислить и переключить профили беспроводных сетей под Windows Mobile 6. Я использую модуль SocketMobile 650. Я практически исключил использование OpenNetCF для этого, поскольку возвращается вызов GetAllNetworkInterfaces ()сетевой интерфейс Wi-Fi, который, по-видимому, не объявляет себя как WirelessZeroConfigNetworkInterface (или даже WirelessNetworkInterface, в этом отношении).

Итак, я вернулся к рассмотрению вызовов API.Мой вопрос: как я могу использовать c # для перечисления и переключения беспроводных профилей без использования OpenNetCF?

1 Ответ

1 голос
/ 11 марта 2012

извините, похоже, что SO "insert code" плохо обрабатывает длинные списки кодов, поэтому коды выглядят плохо. Пожалуйста, скопируйте / вставьте их в свой редактор и выполните переформатирование.

items (1), (2), (3) довольно тривиальны - это просто определения классов / структур / функций экспорта. В пункте (4) происходит вся магия, но я не смог вставить ее сюда (слишком долго), поэтому я скопировал ее в PasteBin (ссылка ниже). Пожалуйста, дайте мне знать, если у вас есть какие-либо вопросы - я постараюсь вам помочь - но идея в том, чтобы использовать низкоуровневую функцию DeviceIoControl для связи с адаптером.


пожалуйста, посмотрите на коды. Я не думаю, что вы сможете их скомпилировать, однако они должны дать вам представление о том, что происходит под капотом. Отказ от ответственности - я написал их 5-6 лет назад, и теперь я бы сделал это совсем по-другому:)

  1. Оболочка C # для C ++ dll:

    публичный класс 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;
    }
    

    }

  2. Определение модели AccessPoint:

    // just took enums from NTDDNDIS.H file...
    

    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 }; * +1022 *

    enum NDIS_802_11_NETWORK_INFRASTRUCTURE { Ndis802_11IBSS, Ndis802_11Infrastructure, Ndis802_11AutoUnknown, Ndis802_11InfrastructureMax // Не реальное значение, определенное как верхняя граница };

    enum NDIS_802_11_NETWORK_TYPE { Ndis802_11FH, Ndis802_11DS, Ndis802_11OFDM5, // Добавлены новые типы для OFDM 5G и 2.4G Ndis802_11OFDM24, Ndis802_11NetworkTypeMax // не является реальным типом, определенным как верхняя граница }; * * Один тысяча двадцать-шесть

    [StructLayout (LayoutKind.Sequential, CharSet = 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";
        }
    
    }
    

    }

  3. C ++ файл # 1 - экспортируемые функции:

    включает "stdafx.h"

    включает "ewf.h"

включает "NdisConnect.h"

включает

NdisConnect g_NdisAdapter (L "ewf_log.txt");

extern HANDLE g_NdisConnectedEvent;

extern "C" EWF_API BOOL WINAPI FindWirelessAdapter () { ENTER;

try
{
    return g_NdisAdapter.FindWirelessAdapter();
}
catch (NdisException* e)
{
    LOG_EXCEPTION(e);
    return FALSE;       
}

LEAVE;
return TRUE;

}

// 1. адаптер init: 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;

}

extern "C" EWF_API BOOL WINAPI TurnWlanOn () { return g_NdisAdapter.TurnWlanOn (); }

extern "C" EWF_API BOOL WINAPI DisconnectFromAdapter () { ВОЙТИ; пытаться { g_NdisAdapter.Disassociate (); } поймать (NdisException * e) { LOG_EXCEPTION (е); возврат ЛОЖЬ;
}

LEAVE;
return TRUE;

}

extern "C" EWF_API BOOL StartScan () { ВОЙТИ; g_NdisAdapter.ScanForAPs ();

return TRUE;

}

extern "C" EWF_API BOOL GetAPsList (APInfo * pAPs, int maxAPs, int * foundAPs) { ВОЙТИ; BOOL res = FALSE;

try
{
    res = g_NdisAdapter.GetAPList(pAPs, maxAPs, foundAPs);
}
catch (NdisException* e)
{
    LOG_EXCEPTION(e);
    return FALSE;
}

LEAVE;
return TRUE;

}

extern "C" EWF_API BOOL ConnectToAP (int maxWaitTimeSeconds, const wchar_t * ssid, bool isWepEnabled, const wchar_t * wepKey) { char 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;

}

  1. Класс NdisConnect - вся магия NDIS происходит здесь:

<< Когда я вставил сюда код, я превысил ограничение в 30 КБ, поэтому я создал файл PasteBin >> - http://pastebin.com/wMBZAYCQ

...