qtmobility/src/bearer/qnativewifiengine_win.cpp
changeset 0 cfcbf08528c4
child 5 453da2cfceef
equal deleted inserted replaced
-1:000000000000 0:cfcbf08528c4
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qnativewifiengine_win_p.h"
       
    43 #include "qnetworkconfiguration_p.h"
       
    44 
       
    45 #include <QtCore/qmutex.h>
       
    46 #include <QtCore/private/qmutexpool_p.h>
       
    47 #include <QtCore/qlibrary.h>
       
    48 #include <QtCore/qstringlist.h>
       
    49 
       
    50 #include <QtCore/qdebug.h>
       
    51 
       
    52 #include <wtypes.h>
       
    53 #undef interface
       
    54 
       
    55 QTM_BEGIN_NAMESPACE
       
    56 
       
    57 Q_GLOBAL_STATIC(QNativeWifiEngine, nativeWifiEngine)
       
    58 
       
    59 #define WLAN_MAX_NAME_LENGTH 256
       
    60 #define WLAN_MAX_PHY_TYPE_NUMBER 8
       
    61 #define WLAN_NOTIFICATION_SOURCE_ALL 0x0000ffff
       
    62 #define WLAN_AVAILABLE_NETWORK_CONNECTED 1
       
    63 #define WLAN_AVAILABLE_NETWORK_HAS_PROFILE 2
       
    64 #define DOT11_SSID_MAX_LENGTH 32
       
    65 
       
    66 struct WLAN_NOTIFICATION_DATA {
       
    67     DWORD NotificationSource;
       
    68     DWORD NotificationCode;
       
    69     GUID InterfaceGuid;
       
    70     DWORD dwDataSize;
       
    71     PVOID pData;
       
    72 };
       
    73 
       
    74 enum WLAN_INTERFACE_STATE {
       
    75     wlan_interface_state_not_ready = 0,
       
    76     wlan_interface_state_connected,
       
    77     wlan_interface_state_ad_hoc_network_formed,
       
    78     wlan_interface_state_disconnecting,
       
    79     wlan_interface_state_disconnected,
       
    80     wlan_interface_state_associating,
       
    81     wlan_interface_state_discovering,
       
    82     wlan_interface_state_authenticating
       
    83 };
       
    84 
       
    85 struct WLAN_INTERFACE_INFO {
       
    86     GUID InterfaceGuid;
       
    87     WCHAR strInterfaceDescription[WLAN_MAX_NAME_LENGTH];
       
    88     WLAN_INTERFACE_STATE isState;
       
    89 };
       
    90 
       
    91 struct WLAN_INTERFACE_INFO_LIST {
       
    92     DWORD dwNumberOfItems;
       
    93     DWORD dwIndex;
       
    94     WLAN_INTERFACE_INFO InterfaceInfo[1];
       
    95 };
       
    96 
       
    97 struct DOT11_SSID {
       
    98     ULONG uSSIDLength;
       
    99     UCHAR ucSSID[DOT11_SSID_MAX_LENGTH];
       
   100 };
       
   101 
       
   102 struct NDIS_OBJECT_HEADER {
       
   103     UCHAR Type;
       
   104     UCHAR Revision;
       
   105     USHORT Size;
       
   106 };
       
   107 
       
   108 typedef UCHAR DOT11_MAC_ADDRESS[6];
       
   109 struct DOT11_BSSID_LIST {
       
   110     NDIS_OBJECT_HEADER Header;
       
   111     ULONG uNumberOfEntries;
       
   112     ULONG uTotalNumOfEntries;
       
   113     DOT11_MAC_ADDRESS BSSIDs[1];
       
   114 };
       
   115 
       
   116 enum DOT11_BSS_TYPE {
       
   117     dot11_BSS_type_infrastructure = 1,
       
   118     dot11_BSS_type_independent = 2,
       
   119     dot11_BSS_type_any = 3
       
   120 };
       
   121 
       
   122 enum DOT11_PHY_TYPE {
       
   123     dot11_phy_type_unknown = 0,
       
   124     dot11_phy_type_any = dot11_phy_type_unknown,
       
   125     dot11_phy_type_fhss = 1,
       
   126     dot11_phy_type_dsss = 2,
       
   127     dot11_phy_type_irbaseband = 3,
       
   128     dot11_phy_type_ofdm = 4,
       
   129     dot11_phy_type_hrdsss = 5,
       
   130     dot11_phy_type_erp = 6,
       
   131     dot11_phy_type_ht = 7,
       
   132     dot11_phy_type_IHV_start = 0x80000000,
       
   133     dot11_phy_type_IHV_end = 0xffffffff
       
   134 };
       
   135 
       
   136 enum DOT11_AUTH_ALGORITHM {
       
   137     DOT11_AUTH_ALGO_80211_OPEN = 1,
       
   138     DOT11_AUTH_ALGO_80211_SHARED_KEY = 2,
       
   139     DOT11_AUTH_ALGO_WPA = 3,
       
   140     DOT11_AUTH_ALGO_WPA_PSK = 4,
       
   141     DOT11_AUTH_ALGO_WPA_NONE = 5,
       
   142     DOT11_AUTH_ALGO_RSNA = 6,
       
   143     DOT11_AUTH_ALGO_RSNA_PSK = 7,
       
   144     DOT11_AUTH_ALGO_IHV_START = 0x80000000,
       
   145     DOT11_AUTH_ALGO_IHV_END = 0xffffffff
       
   146 };
       
   147 
       
   148 enum DOT11_CIPHER_ALGORITHM {
       
   149     DOT11_CIPHER_ALGO_NONE = 0x00,
       
   150     DOT11_CIPHER_ALGO_WEP40 = 0x01,
       
   151     DOT11_CIPHER_ALGO_TKIP = 0x02,
       
   152     DOT11_CIPHER_ALGO_CCMP = 0x04,
       
   153     DOT11_CIPHER_ALGO_WEP104 = 0x05,
       
   154     DOT11_CIPHER_ALGO_WPA_USE_GROUP = 0x100,
       
   155     DOT11_CIPHER_ALGO_RSN_USE_GROUP = 0x100,
       
   156     DOT11_CIPHER_ALGO_WEP = 0x101,
       
   157     DOT11_CIPHER_ALGO_IHV_START = 0x80000000,
       
   158     DOT11_CIPHER_ALGO_IHV_END = 0xffffffff
       
   159 };
       
   160 
       
   161 struct WLAN_AVAILABLE_NETWORK {
       
   162     WCHAR strProfileName[WLAN_MAX_NAME_LENGTH];
       
   163     DOT11_SSID dot11Ssid;
       
   164     DOT11_BSS_TYPE dot11BssType;
       
   165     ULONG uNumberOfBssids;
       
   166     BOOL bNetworkConnectable;
       
   167     DWORD wlanNotConnectableReason;
       
   168     ULONG uNumberOfPhyTypes;
       
   169     DOT11_PHY_TYPE dot11PhyTypes[WLAN_MAX_PHY_TYPE_NUMBER];
       
   170     BOOL bMorePhyTypes;
       
   171     ULONG wlanSignalQuality;
       
   172     BOOL bSecurityEnabled;
       
   173     DOT11_AUTH_ALGORITHM dot11DefaultAuthAlgorithm;
       
   174     DOT11_CIPHER_ALGORITHM dot11DefaultCipherAlgorithm;
       
   175     DWORD dwFlags;
       
   176     DWORD dwReserved;
       
   177 };
       
   178 
       
   179 struct WLAN_AVAILABLE_NETWORK_LIST {
       
   180     DWORD dwNumberOfItems;
       
   181     DWORD dwIndex;
       
   182     WLAN_AVAILABLE_NETWORK Network[1];
       
   183 };
       
   184 
       
   185 enum WLAN_INTF_OPCODE {
       
   186     wlan_intf_opcode_autoconf_start = 0x000000000,
       
   187     wlan_intf_opcode_autoconf_enabled,
       
   188     wlan_intf_opcode_background_scan_enabled,
       
   189     wlan_intf_opcode_media_streaming_mode,
       
   190     wlan_intf_opcode_radio_state,
       
   191     wlan_intf_opcode_bss_type,
       
   192     wlan_intf_opcode_interface_state,
       
   193     wlan_intf_opcode_current_connection,
       
   194     wlan_intf_opcode_channel_number,
       
   195     wlan_intf_opcode_supported_infrastructure_auth_cipher_pairs,
       
   196     wlan_intf_opcode_supported_adhoc_auth_cipher_pairs,
       
   197     wlan_intf_opcode_supported_country_or_region_string_list,
       
   198     wlan_intf_opcode_current_operation_mode,
       
   199     wlan_intf_opcode_supported_safe_mode,
       
   200     wlan_intf_opcode_certified_safe_mode,
       
   201     wlan_intf_opcode_autoconf_end = 0x0fffffff,
       
   202     wlan_intf_opcode_msm_start = 0x10000100,
       
   203     wlan_intf_opcode_statistics,
       
   204     wlan_intf_opcode_rssi,
       
   205     wlan_intf_opcode_msm_end = 0x1fffffff,
       
   206     wlan_intf_opcode_security_start = 0x20010000,
       
   207     wlan_intf_opcode_security_end = 0x2fffffff,
       
   208     wlan_intf_opcode_ihv_start = 0x30000000,
       
   209     wlan_intf_opcode_ihv_end = 0x3fffffff
       
   210 };
       
   211 
       
   212 enum WLAN_OPCODE_VALUE_TYPE {
       
   213     wlan_opcode_value_type_query_only = 0,
       
   214     wlan_opcode_value_type_set_by_group_policy,
       
   215     wlan_opcode_value_type_set_by_user,
       
   216     wlan_opcode_value_type_invalid
       
   217 };
       
   218 
       
   219 enum WLAN_CONNECTION_MODE {
       
   220     wlan_connection_mode_profile = 0,
       
   221     wlan_connection_mode_temporary_profile,
       
   222     wlan_connection_mode_discovery_secure,
       
   223     wlan_connection_mode_discovery_unsecure,
       
   224     wlan_connection_mode_auto,
       
   225     wlan_connection_mode_invalid
       
   226 };
       
   227 
       
   228 struct WLAN_CONNECTION_PARAMETERS {
       
   229     WLAN_CONNECTION_MODE wlanConnectionMode;
       
   230     LPCWSTR strProfile;
       
   231     DOT11_SSID *pDot11Ssid;
       
   232     DOT11_BSSID_LIST *pDesiredBssidList;
       
   233     DOT11_BSS_TYPE dot11BssType;
       
   234     DWORD dwFlags;
       
   235 };
       
   236 
       
   237 struct WLAN_RAW_DATA {
       
   238     DWORD dwDataSize;
       
   239     BYTE DataBlob[1];
       
   240 };
       
   241 
       
   242 enum WLAN_NOTIFICATION_ACM {
       
   243     wlan_notification_acm_start = 0,
       
   244     wlan_notification_acm_autoconf_enabled,
       
   245     wlan_notification_acm_autoconf_disabled,
       
   246     wlan_notification_acm_background_scan_enabled,
       
   247     wlan_notification_acm_background_scan_disabled,
       
   248     wlan_notification_acm_bss_type_change,
       
   249     wlan_notification_acm_power_setting_change,
       
   250     wlan_notification_acm_scan_complete,
       
   251     wlan_notification_acm_scan_fail,
       
   252     wlan_notification_acm_connection_start,
       
   253     wlan_notification_acm_connection_complete,
       
   254     wlan_notification_acm_connection_attempt_fail,
       
   255     wlan_notification_acm_filter_list_change,
       
   256     wlan_notification_acm_interface_arrival,
       
   257     wlan_notification_acm_interface_removal,
       
   258     wlan_notification_acm_profile_change,
       
   259     wlan_notification_acm_profile_name_change,
       
   260     wlan_notification_acm_profiles_exhausted,
       
   261     wlan_notification_acm_network_not_available,
       
   262     wlan_notification_acm_network_available,
       
   263     wlan_notification_acm_disconnecting,
       
   264     wlan_notification_acm_disconnected,
       
   265     wlan_notification_acm_adhoc_network_state_change,
       
   266     wlan_notification_acm_end
       
   267 };
       
   268 
       
   269 struct WLAN_ASSOCIATION_ATTRIBUTES {
       
   270     DOT11_SSID dot11Ssid;
       
   271     DOT11_BSS_TYPE dot11BssType;
       
   272     DOT11_MAC_ADDRESS dot11Bssid;
       
   273     DOT11_PHY_TYPE dot11PhyType;
       
   274     ULONG uDot11PhyIndex;
       
   275     ULONG wlanSignalQuality;
       
   276     ULONG ulRxRate;
       
   277     ULONG ulTxRate;
       
   278 };
       
   279 
       
   280 struct WLAN_SECURITY_ATTRIBUTES {
       
   281     BOOL bSecurityEnabled;
       
   282     BOOL bOneXEnabled;
       
   283     DOT11_AUTH_ALGORITHM dot11AuthAlgorithm;
       
   284     DOT11_CIPHER_ALGORITHM dot11CipherAlgorithm;
       
   285 };
       
   286 
       
   287 struct WLAN_CONNECTION_ATTRIBUTES {
       
   288     WLAN_INTERFACE_STATE isState;
       
   289     WLAN_CONNECTION_MODE wlanConnectionMode;
       
   290     WCHAR strProfileName[WLAN_MAX_NAME_LENGTH];
       
   291     WLAN_ASSOCIATION_ATTRIBUTES wlanAssociationAttributes;
       
   292     WLAN_SECURITY_ATTRIBUTES wlanSecurityAttributes;
       
   293 };
       
   294 
       
   295 typedef void (WINAPI *WLAN_NOTIFICATION_CALLBACK)(WLAN_NOTIFICATION_DATA *, PVOID);
       
   296 
       
   297 typedef DWORD (WINAPI *WlanOpenHandleProto)
       
   298     (DWORD dwClientVersion, PVOID pReserved, PDWORD pdwNegotiatedVersion, PHANDLE phClientHandle);
       
   299 typedef DWORD (WINAPI *WlanRegisterNotificationProto)
       
   300     (HANDLE hClientHandle, DWORD dwNotifSource, BOOL bIgnoreDuplicate,
       
   301      WLAN_NOTIFICATION_CALLBACK funcCallback, PVOID pCallbackContext,
       
   302      PVOID pReserved, PDWORD pdwPrevNotifSource);
       
   303 typedef DWORD (WINAPI *WlanEnumInterfacesProto)
       
   304     (HANDLE hClientHandle, PVOID pReserved, WLAN_INTERFACE_INFO_LIST **ppInterfaceList);
       
   305 typedef DWORD (WINAPI *WlanGetAvailableNetworkListProto)
       
   306     (HANDLE hClientHandle, const GUID* pInterfaceGuid, DWORD dwFlags, PVOID pReserved,
       
   307      WLAN_AVAILABLE_NETWORK_LIST **ppAvailableNetworkList);
       
   308 typedef DWORD (WINAPI *WlanQueryInterfaceProto)
       
   309     (HANDLE hClientHandle, const GUID *pInterfaceGuid, WLAN_INTF_OPCODE OpCode, PVOID pReserved,
       
   310      PDWORD pdwDataSize, PVOID *ppData, WLAN_OPCODE_VALUE_TYPE *pWlanOpcodeValueType);
       
   311 typedef DWORD (WINAPI *WlanConnectProto)
       
   312     (HANDLE hClientHandle, const GUID *pInterfaceGuid,
       
   313      const WLAN_CONNECTION_PARAMETERS *pConnectionParameters, PVOID pReserved);
       
   314 typedef DWORD (WINAPI *WlanDisconnectProto)
       
   315     (HANDLE hClientHandle, const GUID *pInterfaceGuid, PVOID pReserved);
       
   316 typedef DWORD (WINAPI *WlanScanProto)
       
   317     (HANDLE hClientHandle, const GUID *pInterfaceGuid, const DOT11_SSID *pDot11Ssid,
       
   318      const WLAN_RAW_DATA *pIeData, PVOID pReserved);
       
   319 typedef VOID (WINAPI *WlanFreeMemoryProto)(PVOID pMemory);
       
   320 typedef DWORD (WINAPI *WlanCloseHandleProto)(HANDLE hClientHandle, PVOID pReserved);
       
   321 
       
   322 static WlanOpenHandleProto local_WlanOpenHandle = 0;
       
   323 static WlanRegisterNotificationProto local_WlanRegisterNotification = 0;
       
   324 static WlanEnumInterfacesProto local_WlanEnumInterfaces = 0;
       
   325 static WlanGetAvailableNetworkListProto local_WlanGetAvailableNetworkList = 0;
       
   326 static WlanQueryInterfaceProto local_WlanQueryInterface = 0;
       
   327 static WlanConnectProto local_WlanConnect = 0;
       
   328 static WlanDisconnectProto local_WlanDisconnect = 0;
       
   329 static WlanScanProto local_WlanScan = 0;
       
   330 static WlanFreeMemoryProto local_WlanFreeMemory = 0;
       
   331 static WlanCloseHandleProto local_WlanCloseHandle = 0;
       
   332 
       
   333 static void resolveLibrary()
       
   334 {
       
   335     static volatile bool triedResolve = false;
       
   336 
       
   337     if (!triedResolve) {
       
   338 #ifndef QT_NO_THREAD
       
   339         QMutexLocker locker(QMutexPool::globalInstanceGet(&local_WlanOpenHandle));
       
   340 #endif
       
   341 
       
   342         if (!triedResolve) {
       
   343             local_WlanOpenHandle = (WlanOpenHandleProto)
       
   344                 QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanOpenHandle");
       
   345             local_WlanRegisterNotification = (WlanRegisterNotificationProto)
       
   346                 QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanRegisterNotification");
       
   347             local_WlanEnumInterfaces = (WlanEnumInterfacesProto)
       
   348                 QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanEnumInterfaces");
       
   349             local_WlanGetAvailableNetworkList = (WlanGetAvailableNetworkListProto)
       
   350                 QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanGetAvailableNetworkList");
       
   351             local_WlanQueryInterface = (WlanQueryInterfaceProto)
       
   352                 QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanQueryInterface");
       
   353             local_WlanConnect = (WlanConnectProto)
       
   354                 QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanConnect");
       
   355             local_WlanDisconnect = (WlanDisconnectProto)
       
   356                 QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanDisconnect");
       
   357             local_WlanScan = (WlanScanProto)
       
   358                 QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanScan");
       
   359             local_WlanFreeMemory = (WlanFreeMemoryProto)
       
   360                 QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanFreeMemory");
       
   361             local_WlanCloseHandle = (WlanCloseHandleProto)
       
   362                 QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanCloseHandle");
       
   363 
       
   364             triedResolve = true;
       
   365         }
       
   366     }
       
   367 }
       
   368 
       
   369 void qNotificationCallback(WLAN_NOTIFICATION_DATA *data, QNativeWifiEngine *d)
       
   370 {
       
   371     Q_UNUSED(d);
       
   372 
       
   373     switch (data->NotificationCode) {
       
   374     case wlan_notification_acm_connection_complete:
       
   375     case wlan_notification_acm_disconnected:
       
   376         d->emitConfigurationsChanged();
       
   377         break;
       
   378     default:
       
   379         qDebug() << "wlan unknown notification";
       
   380     }
       
   381 }
       
   382 
       
   383 QNativeWifiEngine::QNativeWifiEngine(QObject *parent)
       
   384 :   QNetworkSessionEngine(parent), handle(0)
       
   385 {
       
   386     DWORD clientVersion;
       
   387 
       
   388     DWORD result = local_WlanOpenHandle(1, 0, &clientVersion, &handle);
       
   389     if (result != ERROR_SUCCESS) {
       
   390         if (result != ERROR_SERVICE_NOT_ACTIVE)
       
   391             qWarning("%s: WlanOpenHandle failed with error %ld\n", __FUNCTION__, result);
       
   392 
       
   393         return;
       
   394     }
       
   395 
       
   396     result = local_WlanRegisterNotification(handle, WLAN_NOTIFICATION_SOURCE_ALL, true,
       
   397                                             WLAN_NOTIFICATION_CALLBACK(qNotificationCallback),
       
   398                                             this, 0, 0);
       
   399     if (result != ERROR_SUCCESS)
       
   400         qWarning("%s: WlanRegisterNotification failed with error %ld\n", __FUNCTION__, result);
       
   401 
       
   402     // On Windows XP SP2 and SP3 only connection and disconnection notifications are available.
       
   403     // We need to poll for changes in available wireless networks.
       
   404     connect(&pollTimer, SIGNAL(timeout()), this, SIGNAL(configurationsChanged()));
       
   405     pollTimer.setInterval(10000);
       
   406 }
       
   407 
       
   408 QNativeWifiEngine::~QNativeWifiEngine()
       
   409 {
       
   410     local_WlanCloseHandle(handle, 0);
       
   411 }
       
   412 
       
   413 QList<QNetworkConfigurationPrivate *> QNativeWifiEngine::getConfigurations(bool *ok)
       
   414 {
       
   415     if (ok)
       
   416         *ok = false;
       
   417 
       
   418     QList<QNetworkConfigurationPrivate *> foundConfigurations;
       
   419 
       
   420     // enumerate interfaces
       
   421     WLAN_INTERFACE_INFO_LIST *interfaceList;
       
   422     DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList);
       
   423     if (result != ERROR_SUCCESS) {
       
   424         qWarning("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result);
       
   425         return foundConfigurations;
       
   426     }
       
   427 
       
   428     for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) {
       
   429         const WLAN_INTERFACE_INFO &interface = interfaceList->InterfaceInfo[i];
       
   430 
       
   431         WLAN_AVAILABLE_NETWORK_LIST *networkList;
       
   432         result = local_WlanGetAvailableNetworkList(handle, &interface.InterfaceGuid,
       
   433                                                    3, 0, &networkList);
       
   434         if (result != ERROR_SUCCESS) {
       
   435             qWarning("%s: WlanGetAvailableNetworkList failed with error %ld\n",
       
   436                      __FUNCTION__, result);
       
   437             continue;
       
   438         }
       
   439 
       
   440         QStringList seenNetworks;
       
   441 
       
   442         for (unsigned int j = 0; j < networkList->dwNumberOfItems; ++j) {
       
   443             WLAN_AVAILABLE_NETWORK &network = networkList->Network[j];
       
   444 
       
   445             QString networkName;
       
   446 
       
   447             if (network.strProfileName[0] != 0) {
       
   448                 networkName = QString::fromWCharArray(network.strProfileName);
       
   449             } else {
       
   450                 networkName = QByteArray(reinterpret_cast<char *>(network.dot11Ssid.ucSSID),
       
   451                                          network.dot11Ssid.uSSIDLength);
       
   452             }
       
   453 
       
   454             // don't add duplicate networks
       
   455             if (seenNetworks.contains(networkName))
       
   456                 continue;
       
   457             else
       
   458                 seenNetworks.append(networkName);
       
   459 
       
   460             QNetworkConfigurationPrivate *cpPriv = new QNetworkConfigurationPrivate;
       
   461 
       
   462             cpPriv->isValid = true;
       
   463 
       
   464             cpPriv->name = networkName;
       
   465             cpPriv->id = QString::number(qHash(QLatin1String("WLAN:") + cpPriv->name));
       
   466 
       
   467             if (!(network.dwFlags & WLAN_AVAILABLE_NETWORK_HAS_PROFILE))
       
   468                 cpPriv->state = QNetworkConfiguration::Undefined;
       
   469 
       
   470             if (network.strProfileName[0] != 0) {
       
   471                 if (network.bNetworkConnectable) {
       
   472                     if (network.dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED)
       
   473                         cpPriv->state = QNetworkConfiguration::Active;
       
   474                     else
       
   475                         cpPriv->state = QNetworkConfiguration::Discovered;
       
   476                 } else {
       
   477                     cpPriv->state = QNetworkConfiguration::Defined;
       
   478                 }
       
   479             }
       
   480 
       
   481             cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
       
   482             cpPriv->bearer = QLatin1String("WLAN");
       
   483 
       
   484 
       
   485             foundConfigurations.append(cpPriv);
       
   486         }
       
   487 
       
   488         local_WlanFreeMemory(networkList);
       
   489     }
       
   490 
       
   491     local_WlanFreeMemory(interfaceList);
       
   492 
       
   493     if (ok)
       
   494         *ok = true;
       
   495 
       
   496     pollTimer.start();
       
   497 
       
   498     return foundConfigurations;
       
   499 }
       
   500 
       
   501 QString QNativeWifiEngine::getInterfaceFromId(const QString &id)
       
   502 {
       
   503     // enumerate interfaces
       
   504     WLAN_INTERFACE_INFO_LIST *interfaceList;
       
   505     DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList);
       
   506     if (result != ERROR_SUCCESS) {
       
   507         qWarning("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result);
       
   508         return QString();
       
   509     }
       
   510 
       
   511     for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) {
       
   512         const WLAN_INTERFACE_INFO &interface = interfaceList->InterfaceInfo[i];
       
   513 
       
   514         DWORD dataSize;
       
   515         WLAN_CONNECTION_ATTRIBUTES *connectionAttributes;
       
   516         result = local_WlanQueryInterface(handle, &interface.InterfaceGuid,
       
   517                                           wlan_intf_opcode_current_connection, 0, &dataSize,
       
   518                                           reinterpret_cast<PVOID *>(&connectionAttributes), 0);
       
   519         if (result != ERROR_SUCCESS) {
       
   520             if (result != ERROR_INVALID_STATE)
       
   521                 qWarning("%s: WlanQueryInterface failed with error %ld\n", __FUNCTION__, result);
       
   522 
       
   523             continue;
       
   524         }
       
   525 
       
   526         if (qHash(QLatin1String("WLAN:") +
       
   527                   QString::fromWCharArray(connectionAttributes->strProfileName)) == id.toUInt()) {
       
   528             QString guid("{%1-%2-%3-%4%5-%6%7%8%9%10%11}");
       
   529 
       
   530             guid = guid.arg(interface.InterfaceGuid.Data1, 8, 16, QChar('0'));
       
   531             guid = guid.arg(interface.InterfaceGuid.Data2, 4, 16, QChar('0'));
       
   532             guid = guid.arg(interface.InterfaceGuid.Data3, 4, 16, QChar('0'));
       
   533             for (int i = 0; i < 8; ++i)
       
   534                 guid = guid.arg(interface.InterfaceGuid.Data4[i], 2, 16, QChar('0'));
       
   535 
       
   536             local_WlanFreeMemory(connectionAttributes);
       
   537 
       
   538             return guid.toUpper();
       
   539         }
       
   540 
       
   541         local_WlanFreeMemory(connectionAttributes);
       
   542         local_WlanFreeMemory(interfaceList);
       
   543     }
       
   544 
       
   545     return QString();
       
   546 }
       
   547 
       
   548 bool QNativeWifiEngine::hasIdentifier(const QString &id)
       
   549 {
       
   550     // enumerate interfaces
       
   551     WLAN_INTERFACE_INFO_LIST *interfaceList;
       
   552     DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList);
       
   553     if (result != ERROR_SUCCESS) {
       
   554         qWarning("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result);
       
   555         return false;
       
   556     }
       
   557 
       
   558     for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) {
       
   559         const WLAN_INTERFACE_INFO &interface = interfaceList->InterfaceInfo[i];
       
   560 
       
   561         WLAN_AVAILABLE_NETWORK_LIST *networkList;
       
   562         result = local_WlanGetAvailableNetworkList(handle, &interface.InterfaceGuid,
       
   563                                                    3, 0, &networkList);
       
   564         if (result != ERROR_SUCCESS) {
       
   565             qWarning("%s: WlanGetAvailableNetworkList failed with error %ld\n",
       
   566                      __FUNCTION__, result);
       
   567             continue;
       
   568         }
       
   569 
       
   570         for (unsigned int j = 0; j < networkList->dwNumberOfItems; ++j) {
       
   571             WLAN_AVAILABLE_NETWORK &network = networkList->Network[j];
       
   572 
       
   573             QString networkName;
       
   574 
       
   575             if (network.strProfileName[0] != 0) {
       
   576                 networkName = QString::fromWCharArray(network.strProfileName);
       
   577             } else {
       
   578                 networkName = QByteArray(reinterpret_cast<char *>(network.dot11Ssid.ucSSID),
       
   579                                          network.dot11Ssid.uSSIDLength);
       
   580             }
       
   581 
       
   582             if (qHash(QLatin1String("WLAN:") + networkName) == id.toUInt()) {
       
   583                 local_WlanFreeMemory(networkList);
       
   584                 local_WlanFreeMemory(interfaceList);
       
   585                 return true;
       
   586             }
       
   587         }
       
   588 
       
   589         local_WlanFreeMemory(networkList);
       
   590     }
       
   591 
       
   592     local_WlanFreeMemory(interfaceList);
       
   593 
       
   594     return false;
       
   595 }
       
   596 
       
   597 /*QString QNativeWifiEngine::bearerName(const QString &)
       
   598 {
       
   599     return QLatin1String("WLAN");
       
   600 }*/
       
   601 
       
   602 void QNativeWifiEngine::connectToId(const QString &id)
       
   603 {
       
   604     WLAN_INTERFACE_INFO_LIST *interfaceList;
       
   605     DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList);
       
   606     if (result != ERROR_SUCCESS) {
       
   607         qWarning("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result);
       
   608         emit connectionError(id, InterfaceLookupError);
       
   609         return;
       
   610     }
       
   611 
       
   612     QString profile;
       
   613 
       
   614     for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) {
       
   615         const WLAN_INTERFACE_INFO &interface = interfaceList->InterfaceInfo[i];
       
   616 
       
   617         WLAN_AVAILABLE_NETWORK_LIST *networkList;
       
   618         result = local_WlanGetAvailableNetworkList(handle, &interface.InterfaceGuid,
       
   619                                                    3, 0, &networkList);
       
   620         if (result != ERROR_SUCCESS) {
       
   621             qWarning("%s: WlanGetAvailableNetworkList failed with error %ld\n",
       
   622                      __FUNCTION__, result);
       
   623             continue;
       
   624         }
       
   625 
       
   626         for (unsigned int j = 0; j < networkList->dwNumberOfItems; ++j) {
       
   627             WLAN_AVAILABLE_NETWORK &network = networkList->Network[j];
       
   628 
       
   629             profile = QString::fromWCharArray(network.strProfileName);
       
   630 
       
   631             if (qHash(QLatin1String("WLAN:") + profile) == id.toUInt())
       
   632                 break;
       
   633             else
       
   634                 profile.clear();
       
   635         }
       
   636 
       
   637         local_WlanFreeMemory(networkList);
       
   638 
       
   639         if (!profile.isEmpty()) {
       
   640             WLAN_CONNECTION_PARAMETERS parameters;
       
   641             parameters.wlanConnectionMode = wlan_connection_mode_profile;
       
   642             parameters.strProfile = reinterpret_cast<LPCWSTR>(profile.utf16());
       
   643             parameters.pDot11Ssid = 0;
       
   644             parameters.pDesiredBssidList = 0;
       
   645             parameters.dot11BssType = dot11_BSS_type_any;
       
   646             parameters.dwFlags = 0;
       
   647 
       
   648             DWORD result = local_WlanConnect(handle, &interface.InterfaceGuid, &parameters, 0);
       
   649             if (result != ERROR_SUCCESS) {
       
   650                 qWarning("%s: WlanConnect failed with error %ld\n", __FUNCTION__, result);
       
   651                 emit connectionError(id, ConnectError);
       
   652                 break;
       
   653             }
       
   654 
       
   655             break;
       
   656         }
       
   657     }
       
   658 
       
   659     local_WlanFreeMemory(interfaceList);
       
   660 
       
   661     if (profile.isEmpty())
       
   662         emit connectionError(id, InterfaceLookupError);
       
   663 }
       
   664 
       
   665 void QNativeWifiEngine::disconnectFromId(const QString &id)
       
   666 {
       
   667     QString interface = getInterfaceFromId(id);
       
   668 
       
   669     if (interface.isEmpty()) {
       
   670         emit connectionError(id, InterfaceLookupError);
       
   671         return;
       
   672     }
       
   673 
       
   674     QStringList split = interface.mid(1, interface.length() - 2).split('-');
       
   675 
       
   676     GUID guid;
       
   677     guid.Data1 = split.at(0).toUInt(0, 16);
       
   678     guid.Data2 = split.at(1).toUShort(0, 16);
       
   679     guid.Data3 = split.at(2).toUShort(0, 16);
       
   680     guid.Data4[0] = split.at(3).left(2).toUShort(0, 16);
       
   681     guid.Data4[1] = split.at(3).right(2).toUShort(0, 16);
       
   682     for (int i = 0; i < 6; ++i)
       
   683         guid.Data4[i + 2] = split.at(4).mid(i*2, 2).toUShort(0, 16);
       
   684 
       
   685     DWORD result = local_WlanDisconnect(handle, &guid, 0);
       
   686     if (result != ERROR_SUCCESS) {
       
   687         qWarning("%s: WlanDisconnect failed with error %ld\n", __FUNCTION__, result);
       
   688         emit connectionError(id, DisconnectionError);
       
   689         return;
       
   690     }
       
   691 }
       
   692 
       
   693 void QNativeWifiEngine::requestUpdate()
       
   694 {
       
   695     // enumerate interfaces
       
   696     WLAN_INTERFACE_INFO_LIST *interfaceList;
       
   697     DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList);
       
   698     if (result != ERROR_SUCCESS) {
       
   699         qWarning("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result);
       
   700         return;
       
   701     }
       
   702 
       
   703     for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) {
       
   704         result = local_WlanScan(handle, &interfaceList->InterfaceInfo[i].InterfaceGuid, 0, 0, 0);
       
   705         if (result != ERROR_SUCCESS)
       
   706             qWarning("%s: WlanScan failed with error %ld\n", __FUNCTION__, result);
       
   707     }
       
   708 }
       
   709 
       
   710 QNativeWifiEngine *QNativeWifiEngine::instance()
       
   711 {
       
   712     resolveLibrary();
       
   713 
       
   714     // native wifi dll not available
       
   715     if (!local_WlanOpenHandle)
       
   716         return 0;
       
   717 
       
   718     QNativeWifiEngine *engine = nativeWifiEngine();
       
   719 
       
   720     // could not initialise subsystem
       
   721     if (engine && engine->handle == 0)
       
   722         return 0;
       
   723 
       
   724     return engine;
       
   725 }
       
   726 
       
   727 #include "moc_qnativewifiengine_win_p.cpp"
       
   728 
       
   729 QTM_END_NAMESPACE