2012-02-29 4 views
1

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

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

+0

все еще проблема? вы бы рассматривали неуправляемую DLL и управляемый интерфейс? Несколько лет назад я сделал что-то подобное - я использовал NDIS на неуправляемой стороне. Если вы это рассмотрите - я отправлю коды. Пожалуйста, дай мне знать. – avs099

+0

Несомненно. Я уже смирился с необходимостью использовать API, поэтому, если у вас уже есть обертки вокруг них, это еще лучше. –

+0

Я начал писать ответ и понял, что вы говорите о беспроводных профилях - вы имеете в виду точки доступа или что-то еще? – avs099

ответ

1

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

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


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

  1. 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; 
    } 
    

    }

  2. 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"; 
        } 
    
    } 
    

    }

  3. 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; 

}

  1. NdisConnect класс - все NDIS волшебство происходит здесь:

< <, когда я вставил код здесь, я пошел более чем 30k предел на пост, так что я создал PasteBin file >> - http://pastebin.com/wMBZAYCQ

+0

Можете ли вы воссоздать новый файл pastebin или что-то более постоянное? Я получаю 404. –

+0

Нечетный. Он работает сейчас. –

+0

pls дайте мне знать, если у вас есть какие-либо вопросы/проблемы с кодами. – avs099