src/systeminfo/qsysteminfo_win.cpp
changeset 0 876b1a06bc25
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/systeminfo/qsysteminfo_win.cpp	Wed Aug 25 15:49:42 2010 +0300
@@ -0,0 +1,1945 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qsysteminfo.h"
+#include "qsysteminfo_win_p.h"
+#include <qt_windows.h>
+
+#include <QtCore/qmutex.h>
+
+#include <QStringList>
+#include <QSize>
+#include <QFile>
+#include <QTextStream>
+#include <QLocale>
+#include <QLibraryInfo>
+#include <QApplication>
+#include <QDesktopWidget>
+#include <QDebug>
+#include <QSettings>
+#include <QSysInfo>
+#include <QNetworkInterface>
+#include <QList>
+#include <QSettings>
+#include <QDir>
+#include <QNetworkInterface>
+#include <QString>
+#include <QTimer>
+#include <QBasicTimer>
+#include <QtCore/qlibrary.h>
+#include <QUuid>
+#include <QSysInfo>
+
+#include <qabstracteventdispatcher.h>
+
+#include <locale.h>
+#ifdef Q_OS_WINCE
+#include <simmgr.h>
+#include <Winbase.h>
+#include <Winuser.h>
+#include <Pm.h>
+#endif
+
+
+#if !defined( Q_CC_MINGW)
+#ifndef Q_OS_WINCE
+#include "qwmihelper_win_p.h"
+
+
+
+enum NDIS_MEDIUM {
+    NdisMedium802_3 = 0,
+    NdisMediumWirelessWan = 9,
+};
+
+enum NDIS_PHYSICAL_MEDIUM {
+    NdisPhysicalMediumUnspecified = 0,
+    NdisPhysicalMediumWirelessLan = 1,
+    NdisPhysicalMediumBluetooth = 10,
+    NdisPhysicalMediumWiMax = 12,
+};
+
+#define OID_GEN_MEDIA_SUPPORTED 0x00010103
+#define OID_GEN_PHYSICAL_MEDIUM 0x00010202
+
+#define IOCTL_NDIS_QUERY_GLOBAL_STATS \
+    CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD, 0, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
+
+#endif
+#endif
+
+
+
+#define WLAN_MAX_NAME_LENGTH 256
+#define DOT11_SSID_MAX_LENGTH 32
+#define WLAN_NOTIFICATION_SOURCE_ALL 0x0000ffff
+
+enum WLAN_INTF_OPCODE {
+    wlan_intf_opcode_autoconf_start = 0x000000000,
+    wlan_intf_opcode_autoconf_enabled,
+    wlan_intf_opcode_background_scan_enabled,
+    wlan_intf_opcode_media_streaming_mode,
+    wlan_intf_opcode_radio_state,
+    wlan_intf_opcode_bss_type,
+    wlan_intf_opcode_interface_state,
+    wlan_intf_opcode_current_connection,
+    wlan_intf_opcode_channel_number,
+    wlan_intf_opcode_supported_infrastructure_auth_cipher_pairs,
+    wlan_intf_opcode_supported_adhoc_auth_cipher_pairs,
+    wlan_intf_opcode_supported_country_or_region_string_list,
+    wlan_intf_opcode_current_operation_mode,
+    wlan_intf_opcode_supported_safe_mode,
+    wlan_intf_opcode_certified_safe_mode,
+    wlan_intf_opcode_autoconf_end = 0x0fffffff,
+    wlan_intf_opcode_msm_start = 0x10000100,
+    wlan_intf_opcode_statistics,
+    wlan_intf_opcode_rssi,
+    wlan_intf_opcode_msm_end = 0x1fffffff,
+    wlan_intf_opcode_security_start = 0x20010000,
+    wlan_intf_opcode_security_end = 0x2fffffff,
+    wlan_intf_opcode_ihv_start = 0x30000000,
+    wlan_intf_opcode_ihv_end = 0x3fffffff
+};
+
+enum WLAN_OPCODE_VALUE_TYPE {
+    wlan_opcode_value_type_query_only = 0,
+    wlan_opcode_value_type_set_by_group_policy,
+    wlan_opcode_value_type_set_by_user,
+    wlan_opcode_value_type_invalid
+};
+
+enum WLAN_INTERFACE_STATE {
+    wlan_interface_state_not_ready = 0,
+    wlan_interface_state_connected,
+    wlan_interface_state_ad_hoc_network_formed,
+    wlan_interface_state_disconnecting,
+    wlan_interface_state_disconnected,
+    wlan_interface_state_associating,
+    wlan_interface_state_discovering,
+    wlan_interface_state_authenticating
+};
+
+struct WLAN_INTERFACE_INFO {
+    GUID InterfaceGuid;
+    WCHAR strInterfaceDescription[WLAN_MAX_NAME_LENGTH];
+    WLAN_INTERFACE_STATE isState;
+};
+
+struct WLAN_INTERFACE_INFO_LIST {
+    DWORD dwNumberOfItems;
+    DWORD dwIndex;
+    WLAN_INTERFACE_INFO InterfaceInfo[1];
+};
+
+struct WLAN_NOTIFICATION_DATA {
+    DWORD NotificationSource;
+    DWORD NotificationCode;
+    GUID InterfaceGuid;
+    DWORD dwDataSize;
+    PVOID pData;
+};
+
+enum WLAN_CONNECTION_MODE {
+    wlan_connection_mode_profile = 0,
+    wlan_connection_mode_temporary_profile,
+    wlan_connection_mode_discovery_secure,
+    wlan_connection_mode_discovery_unsecure,
+    wlan_connection_mode_auto,
+    wlan_connection_mode_invalid
+};
+
+enum DOT11_PHY_TYPE {
+        dot11_phy_type_unknown = 0,
+        dot11_phy_type_any = dot11_phy_type_unknown,
+        dot11_phy_type_fhss = 1,
+        dot11_phy_type_dsss = 2,
+        dot11_phy_type_irbaseband = 3,
+        dot11_phy_type_ofdm = 4,
+        dot11_phy_type_hrdsss = 5,
+        dot11_phy_type_erp = 6,
+        dot11_phy_type_ht = 7,
+        dot11_phy_type_IHV_start = 0x80000000,
+        dot11_phy_type_IHV_end = 0xffffffff
+    };
+
+
+enum DOT11_AUTH_ALGORITHM {
+    DOT11_AUTH_ALGO_80211_OPEN = 1,
+    DOT11_AUTH_ALGO_80211_SHARED_KEY = 2,
+    DOT11_AUTH_ALGO_WPA = 3,
+    DOT11_AUTH_ALGO_WPA_PSK = 4,
+    DOT11_AUTH_ALGO_WPA_NONE = 5,
+    DOT11_AUTH_ALGO_RSNA = 6,
+    DOT11_AUTH_ALGO_RSNA_PSK = 7,
+    DOT11_AUTH_ALGO_IHV_START = 0x80000000,
+    DOT11_AUTH_ALGO_IHV_END = 0xffffffff
+};
+
+
+enum DOT11_CIPHER_ALGORITHM {
+    DOT11_CIPHER_ALGO_NONE = 0x00,
+    DOT11_CIPHER_ALGO_WEP40 = 0x01,
+    DOT11_CIPHER_ALGO_TKIP = 0x02,
+    DOT11_CIPHER_ALGO_CCMP = 0x04,
+    DOT11_CIPHER_ALGO_WEP104 = 0x05,
+    DOT11_CIPHER_ALGO_WPA_USE_GROUP = 0x100,
+    DOT11_CIPHER_ALGO_RSN_USE_GROUP = 0x100,
+    DOT11_CIPHER_ALGO_WEP = 0x101,
+    DOT11_CIPHER_ALGO_IHV_START = 0x80000000,
+    DOT11_CIPHER_ALGO_IHV_END = 0xffffffff
+};
+
+
+enum DOT11_BSS_TYPE {
+    dot11_BSS_type_infrastructure = 1,
+    dot11_BSS_type_independent = 2,
+    dot11_BSS_type_any = 3
+};
+
+
+struct DOT11_SSID {
+    ULONG uSSIDLength;
+    UCHAR ucSSID[DOT11_SSID_MAX_LENGTH];
+};
+
+typedef UCHAR DOT11_MAC_ADDRESS[6];
+
+struct WLAN_ASSOCIATION_ATTRIBUTES {
+    DOT11_SSID dot11Ssid;
+    DOT11_BSS_TYPE dot11BssType;
+    DOT11_MAC_ADDRESS dot11Bssid;
+    DOT11_PHY_TYPE dot11PhyType;
+    ULONG uDot11PhyIndex;
+    ULONG wlanSignalQuality;
+    ULONG ulRxRate;
+    ULONG ulTxRate;
+};
+
+struct WLAN_SECURITY_ATTRIBUTES {
+    BOOL bSecurityEnabled;
+    BOOL bOneXEnabled;
+    DOT11_AUTH_ALGORITHM dot11AuthAlgorithm;
+    DOT11_CIPHER_ALGORITHM dot11CipherAlgorithm;
+};
+
+struct WLAN_CONNECTION_ATTRIBUTES {
+    WLAN_INTERFACE_STATE isState;
+    WLAN_CONNECTION_MODE wlanConnectionMode;
+    WCHAR strProfileName[WLAN_MAX_NAME_LENGTH];
+    WLAN_ASSOCIATION_ATTRIBUTES wlanAssociationAttributes;
+    WLAN_SECURITY_ATTRIBUTES wlanSecurityAttributes;
+};
+
+enum WLAN_NOTIFICATION_ACM {
+    wlan_notification_acm_start = 0,
+    wlan_notification_acm_autoconf_enabled,
+    wlan_notification_acm_autoconf_disabled,
+    wlan_notification_acm_background_scan_enabled,
+    wlan_notification_acm_background_scan_disabled,
+    wlan_notification_acm_bss_type_change,
+    wlan_notification_acm_power_setting_change,
+    wlan_notification_acm_scan_complete,
+    wlan_notification_acm_scan_fail,
+    wlan_notification_acm_connection_start,
+    wlan_notification_acm_connection_complete,
+    wlan_notification_acm_connection_attempt_fail,
+    wlan_notification_acm_filter_list_change,
+    wlan_notification_acm_interface_arrival,
+    wlan_notification_acm_interface_removal,
+    wlan_notification_acm_profile_change,
+    wlan_notification_acm_profile_name_change,
+    wlan_notification_acm_profiles_exhausted,
+    wlan_notification_acm_network_not_available,
+    wlan_notification_acm_network_available,
+    wlan_notification_acm_disconnecting,
+    wlan_notification_acm_disconnected,
+    wlan_notification_acm_adhoc_network_state_change,
+    wlan_notification_acm_end
+};
+
+enum _WLAN_NOTIFICATION_MSM {
+    wlan_notification_msm_start = 0,
+    wlan_notification_msm_associating,
+    wlan_notification_msm_associated,
+    wlan_notification_msm_authenticating,
+    wlan_notification_msm_connected,
+    wlan_notification_msm_roaming_start,
+    wlan_notification_msm_roaming_end,
+    wlan_notification_msm_radio_state_change,
+    wlan_notification_msm_signal_quality_change,
+    wlan_notification_msm_disassociating,
+    wlan_notification_msm_disconnected,
+    wlan_notification_msm_peer_join,
+    wlan_notification_msm_peer_leave,
+    wlan_notification_msm_adapter_removal,
+    wlan_notification_msm_adapter_operation_mode_change,
+    wlan_notification_msm_end
+};
+
+typedef void (WINAPI *WLAN_NOTIFICATION_CALLBACK) (WLAN_NOTIFICATION_DATA *, PVOID);
+
+#define _WCHAR_T_DEFINED
+#define _TIME64_T_DEFINED
+
+typedef struct _BLUETOOTH_FIND_RADIO_PARAMS {
+    DWORD   dwSize;             //  IN  sizeof this structure
+} BLUETOOTH_FIND_RADIO_PARAMS;
+
+
+typedef DWORD (WINAPI *WlanOpenHandleProto)
+    (DWORD dwClientVersion, PVOID pReserved, PDWORD pdwNegotiatedVersion, PHANDLE phClientHandle);
+static WlanOpenHandleProto local_WlanOpenHandle = 0;
+
+typedef DWORD (WINAPI *WlanCloseHandleProto)(HANDLE hClientHandle, PVOID pReserved);
+static WlanCloseHandleProto local_WlanCloseHandle = 0;
+
+#if !defined(Q_OS_WINCE)
+typedef DWORD (WINAPI *WlanEnumInterfacesProto)
+    (HANDLE hClientHandle, PVOID pReserved, WLAN_INTERFACE_INFO_LIST **ppInterfaceList);
+static WlanEnumInterfacesProto local_WlanEnumInterfaces = 0;
+
+typedef DWORD (WINAPI *WlanQueryInterfaceProto)
+    (HANDLE hClientHandle, const GUID *pInterfaceGuid, WLAN_INTF_OPCODE OpCode, PVOID pReserved,
+     PDWORD pdwDataSize, PVOID *ppData, WLAN_OPCODE_VALUE_TYPE *pWlanOpcodeValueType);
+static WlanQueryInterfaceProto local_WlanQueryInterface = 0;
+
+typedef DWORD (WINAPI *WlanRegisterNotificationProto)
+    (HANDLE hClientHandle, DWORD dwNotifSource, BOOL bIgnoreDuplicate,
+     WLAN_NOTIFICATION_CALLBACK funcCallback, PVOID pCallbackContext,
+     PVOID pReserved, PDWORD pdwPrevNotifSource);
+static WlanRegisterNotificationProto local_WlanRegisterNotification = 0;
+#endif
+
+typedef VOID (WINAPI *WlanFreeMemoryProto)(PVOID pMemory);
+static WlanFreeMemoryProto local_WlanFreeMemory = 0;
+
+typedef BOOL (WINAPI *BluetoothFindRadioClose)(HANDLE hFind);
+static BluetoothFindRadioClose local_BluetoothFindRadioClose=0;
+
+typedef HANDLE (WINAPI *BluetoothFindFirstRadio)(const BLUETOOTH_FIND_RADIO_PARAMS * pbtfrp,HANDLE * phRadio);
+static BluetoothFindFirstRadio local_BluetoothFindFirstRadio=0;
+
+QTM_BEGIN_NAMESPACE
+
+Q_GLOBAL_STATIC_WITH_ARGS(QMutex, dynamicLoadMutex, (QMutex::Recursive));
+
+static void resolveLibrary()
+{
+#if !defined( Q_OS_WINCE)
+            static volatile bool triedResolve = false;
+
+    if (!triedResolve) {
+#ifndef QT_NO_THREAD
+        QMutexLocker locker(dynamicLoadMutex());
+#endif
+
+        if (!triedResolve) {
+            local_WlanOpenHandle = (WlanOpenHandleProto)
+                                   QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanOpenHandle");
+            local_WlanRegisterNotification = (WlanRegisterNotificationProto)
+                                             QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanRegisterNotification");
+            local_WlanEnumInterfaces = (WlanEnumInterfacesProto)
+                                       QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanEnumInterfaces");
+            local_WlanQueryInterface = (WlanQueryInterfaceProto)
+                                       QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanQueryInterface");
+            local_WlanFreeMemory = (WlanFreeMemoryProto)
+                                   QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanFreeMemory");
+            local_WlanCloseHandle = (WlanCloseHandleProto)
+                                    QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanCloseHandle");
+
+
+            local_BluetoothFindFirstRadio = (BluetoothFindFirstRadio)
+                                            QLibrary::resolve(QLatin1String("Bthprops.cpl"), "BluetoothFindFirstRadio");
+            local_BluetoothFindRadioClose = (BluetoothFindRadioClose)
+                                            QLibrary::resolve(QLatin1String("Bthprops.cpl"), "BluetoothFindRadioClose");
+
+            triedResolve = true;
+        }
+    }
+#endif
+}
+
+Q_GLOBAL_STATIC(QSystemNetworkInfoPrivate, qsystemNetworkInfoPrivate)
+
+typedef struct _DISPLAY_BRIGHTNESS {
+    UCHAR ucDisplayPolicy;
+    UCHAR ucACBrightness;
+    UCHAR ucDCBrightness;
+} DISPLAY_BRIGHTNESS, *PDISPLAY_BRIGHTNESS;
+
+
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+static WLAN_CONNECTION_ATTRIBUTES *getWifiConnectionAttributes()
+{
+    if(!local_WlanOpenHandle)
+        return NULL;
+    DWORD version =  0;
+    HANDLE clientHandle = NULL;
+    DWORD result;
+    WLAN_CONNECTION_ATTRIBUTES  *connAtts = NULL;
+
+    WLAN_INTERFACE_INFO_LIST *interfacesInfoList = NULL;
+    result = local_WlanOpenHandle( 2, NULL, &version, &clientHandle );
+    if( result != ERROR_SUCCESS) {
+        local_WlanFreeMemory(connAtts);
+        local_WlanCloseHandle(clientHandle,  0);
+        return NULL;
+    }
+    result = local_WlanEnumInterfaces(clientHandle, NULL, &interfacesInfoList);
+
+    if( result != ERROR_SUCCESS) {
+        local_WlanCloseHandle(clientHandle, NULL);
+        local_WlanFreeMemory(connAtts);
+        return NULL;
+    }
+
+    for( uint i = 0; i < interfacesInfoList->dwNumberOfItems; i++ ) {
+        WLAN_INTERFACE_INFO *interfaceInfo = &interfacesInfoList->InterfaceInfo[i];
+        GUID& guid = interfaceInfo->InterfaceGuid;
+        WLAN_INTERFACE_STATE wlanInterfaceState = interfaceInfo->isState;
+
+        if( wlanInterfaceState == wlan_interface_state_not_ready ) {
+            continue;
+        }
+
+        ULONG size = 0;
+        result = local_WlanQueryInterface( clientHandle, &guid,  wlan_intf_opcode_current_connection, NULL, &size, (PVOID*) &connAtts, NULL );
+        if( result != ERROR_SUCCESS ) {
+            continue;
+        }
+    }
+    local_WlanCloseHandle(clientHandle, NULL);
+    return connAtts;
+}
+#endif
+
+QSystemInfoPrivate::QSystemInfoPrivate(QObject *parent)
+ : QObject(parent)
+{
+    currentLanguageStr = currentLanguage();
+    QTimer::singleShot(1000, this,SLOT(currentLanguageTimeout()));
+}
+
+QSystemInfoPrivate::~QSystemInfoPrivate()
+{
+
+}
+
+void QSystemInfoPrivate::currentLanguageTimeout()
+{
+    const QString tmpLang = currentLanguage();
+    if(currentLanguageStr != tmpLang) {
+        currentLanguageStr = tmpLang;
+        emit currentLanguageChanged(currentLanguageStr);
+    }
+
+    QTimer::singleShot(1000, this,SLOT(currentLanguageTimeout()));
+}
+
+QString QSystemInfoPrivate::currentLanguage() const
+{
+    QString lang = QLocale::system().name().left(2);
+    if(lang.isEmpty() || lang == "C") {
+        lang = "en";
+    }
+    return lang;
+}
+
+
+QStringList QSystemInfoPrivate::availableLanguages() const
+{
+    QDir transDir(QLibraryInfo::location (QLibraryInfo::TranslationsPath));
+    QStringList langList;
+    if(transDir.exists()) {
+        QStringList localeList = transDir.entryList( QStringList() << "qt_*.qm" ,QDir::Files
+                                                     | QDir::NoDotAndDotDot, QDir::Name);
+        foreach(const QString localeName, localeList) {
+            const QString lang = localeName.mid(3,2);
+            if(!langList.contains(lang) && !lang.isEmpty() && !lang.contains("help")) {
+                langList << lang;
+            }
+        }
+        if(!langList.isEmpty()) {
+            return langList;
+        }
+    }
+    return QStringList() << currentLanguage();
+}
+
+QString QSystemInfoPrivate::version(QSystemInfo::Version type,  const QString &parameter)
+{
+    Q_UNUSED(parameter);
+    QString errorStr = "Not Available";
+    bool useDate = false;
+    if(parameter == "versionDate") {
+        useDate = true;
+    }
+    switch(type) {
+    case QSystemInfo::Os :
+        {
+#if !defined(Q_OS_WINCE)
+            OSVERSIONINFOEX versionInfo;
+            versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+
+            GetVersionEx((OSVERSIONINFO *) &versionInfo);
+            return QString::number(versionInfo.dwMajorVersion) +"."
+                    +QString::number(versionInfo.dwMinorVersion)+"."
+                    +QString::number(versionInfo.dwBuildNumber)+"."
+                    +QString::number(versionInfo.wServicePackMajor)+"."
+                    +QString::number(versionInfo.wServicePackMinor);
+#else
+            OSVERSIONINFO versionInfo;
+            versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+            GetVersionEx((OSVERSIONINFO *) &versionInfo);
+            return QString::number(versionInfo.dwMajorVersion) +"."
+                    +QString::number(versionInfo.dwMinorVersion)+"."
+                    +QString::number(versionInfo.dwBuildNumber);
+#endif
+        }
+        break;
+    case QSystemInfo::QtCore :
+       return  qVersion();
+       break;
+   case QSystemInfo::Firmware :
+       {
+       }
+       break;
+    };
+  return errorStr;
+}
+
+
+QString QSystemInfoPrivate::currentCountryCode() const
+{
+    return QLocale::system().name().mid(3,2);
+}
+
+
+bool QSystemInfoPrivate::hasFeatureSupported(QSystemInfo::Feature feature)
+{
+    bool featureSupported = false;
+    switch (feature) {
+    case QSystemInfo::BluetoothFeature :
+        {
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+
+            resolveLibrary();
+            if(local_BluetoothFindFirstRadio == 0 ) {
+                qDebug() << "Bluetooth library could not resolve or be loaded";
+                return false;
+            }
+            BLUETOOTH_FIND_RADIO_PARAMS  radioParams = { sizeof(BLUETOOTH_FIND_RADIO_PARAMS)};
+            HANDLE radio;
+            if(local_BluetoothFindFirstRadio(&radioParams, &radio) != NULL) {
+                featureSupported = true;
+                local_BluetoothFindRadioClose(radio);
+            } else {
+
+            }
+#endif
+        }
+        break;
+    case QSystemInfo::CameraFeature :
+        {
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+#endif
+        }
+        break;
+    case QSystemInfo::FmradioFeature :
+        {
+            //PageId.FMRadio?
+        }
+        break;
+    case QSystemInfo::IrFeature :
+        {
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+            WMIHelper *wHelper;
+            wHelper = new WMIHelper(this);
+            wHelper->setWmiNamespace("root/cimv2");
+            wHelper->setClassName("Win32_InfraredDevice");
+            wHelper->setClassProperty(QStringList() << "ConfigManagerErrorCode");
+
+            QVariant v = wHelper->getWMIData();
+            if(v.toUInt() == 1) {
+                featureSupported = true;
+            }
+#endif
+        }
+        break;
+    case QSystemInfo::LedFeature :
+        {
+#ifdef Q_OS_WINCE
+
+#else
+#endif
+        }
+        break;
+    case QSystemInfo::MemcardFeature :
+        {
+            QSystemStorageInfo mi;
+            QStringList drives = mi.logicalDrives();
+            foreach(const QString drive, drives) {
+                if(mi.typeForDrive(drive) == QSystemStorageInfo::RemovableDrive) {
+                    featureSupported = true;
+                }
+            }
+        }
+        break;
+    case QSystemInfo::UsbFeature :
+        {
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+            WMIHelper *wHelper;
+            wHelper = new WMIHelper(this);
+            wHelper->setWmiNamespace("root/cimv2");
+            wHelper->setClassName("Win32_USBHub");
+            wHelper->setClassProperty(QStringList() << "ConfigManagerErrorCode");
+            QVariant v = wHelper->getWMIData();
+            if(v.toUInt() == 0) {
+                featureSupported = true;
+            }
+#endif
+        }
+        break;
+    case QSystemInfo::VibFeature :
+        {
+#ifdef Q_OS_WINCE
+
+#else
+#endif
+        }
+        break;
+    case QSystemInfo::WlanFeature :
+        {
+            QSystemNetworkInfo ni;
+            if(ni.interfaceForMode(QSystemNetworkInfo::WlanMode).isValid()) {
+                featureSupported = true;
+            }
+        }
+        break;
+    case QSystemInfo::SimFeature :
+        {
+#ifdef Q_OS_WINCE
+            HSIM handle;
+            HRESULT result = SimInitialize(0,NULL,NULL,&handle);
+            if(result == S_OK) {
+                featureSupported = true;
+                SimDeinitialize(handle);
+            }
+#else
+#endif
+        }
+        break;
+    case QSystemInfo::LocationFeature :
+        {
+#ifdef Q_OS_WINCE
+
+#else
+#endif
+        }
+        break;
+    case QSystemInfo::VideoOutFeature :
+        {
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+            WMIHelper *wHelper;
+            wHelper = new WMIHelper(this);
+            wHelper->setWmiNamespace("root/cimv2");
+            wHelper->setClassName("VideoModeDescriptor");
+            wHelper->setClassProperty(QStringList() << "VideoStandardType");
+            QVariant v = wHelper->getWMIData();
+            if(v.toUInt() > 5) {
+                featureSupported = true;
+            }
+#endif
+        }
+        break;
+    case QSystemInfo::HapticsFeature:
+        break;
+    default:
+        featureSupported = false;
+        break;
+    };
+    return featureSupported;
+}
+
+QTM_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QTM_PREPEND_NAMESPACE(QSystemNetworkInfo)::NetworkMode)
+Q_DECLARE_METATYPE(QTM_PREPEND_NAMESPACE(QSystemNetworkInfo)::NetworkStatus)
+QTM_BEGIN_NAMESPACE
+
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+
+void wlanNotificationCallback(WLAN_NOTIFICATION_DATA *pNotifyData, QSystemNetworkInfoPrivate *netInfo)
+{
+    // xp only supports disconnected and complete
+    switch(pNotifyData->NotificationCode) {
+    case wlan_notification_acm_scan_complete:
+        break;
+    case wlan_notification_acm_disconnecting:
+        break;
+    case wlan_notification_acm_disconnected:
+    case wlan_notification_acm_connection_attempt_fail:
+    case wlan_notification_acm_network_not_available:
+        netInfo->emitNetworkStatusChanged(QSystemNetworkInfo::WlanMode,
+                                          QSystemNetworkInfo::NoNetworkAvailable);
+        break;
+    case wlan_notification_acm_profile_name_change:
+        break;
+    case  wlan_notification_msm_connected:
+        netInfo->emitNetworkStatusChanged(QSystemNetworkInfo::WlanMode,
+                                          QSystemNetworkInfo::Connected);
+        break;
+    case wlan_notification_acm_connection_start:
+        netInfo->emitNetworkStatusChanged(QSystemNetworkInfo::WlanMode,
+                                          QSystemNetworkInfo::Searching);
+        break;
+    case wlan_notification_msm_signal_quality_change:
+        netInfo->emitNetworkSignalStrengthChanged(QSystemNetworkInfo::WlanMode,
+                                                  reinterpret_cast<qint32>(pNotifyData->pData));
+        break;
+    default:
+        break;
+    };
+}
+#endif
+
+QSystemNetworkInfoPrivate::QSystemNetworkInfoPrivate(QObject *parent)
+    : QObject(parent)
+{
+    wlanCallbackInitialized = false;
+    qRegisterMetaType<QSystemNetworkInfo::NetworkMode>("QSystemNetworkInfo::NetworkMode");
+    qRegisterMetaType<QSystemNetworkInfo::NetworkStatus>("QSystemNetworkInfo::NetworkStatus");
+    resolveLibrary();
+
+    startWifiCallback();
+
+     timerMs = 5000;
+     switch(QSysInfo::WindowsVersion) {
+     case  QSysInfo::WV_VISTA:
+     case QSysInfo::WV_WINDOWS7:
+         break;
+     default:
+         {
+             if(local_WlanOpenHandle)
+                 QTimer::singleShot(timerMs, this, SLOT(networkStrengthTimeout()));
+         }
+         break;
+     };
+ }
+
+QSystemNetworkInfoPrivate::~QSystemNetworkInfoPrivate()
+{
+#if !defined( Q_OS_WINCE)
+    if(hWlan != 0)
+         local_WlanCloseHandle(hWlan, 0);
+#endif
+}
+
+void QSystemNetworkInfoPrivate::startWifiCallback()
+{
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+    if(networkStatus(QSystemNetworkInfo::WlanMode) != QSystemNetworkInfo::Connected
+    && wlanCallbackInitialized){
+        return;
+    }
+    DWORD version =  0;
+    hWlan = NULL;
+    DWORD result;
+    if(local_WlanOpenHandle)
+        result = local_WlanOpenHandle(2, NULL, &version, &hWlan );
+    if( result != ERROR_SUCCESS ) {
+        qDebug() << "Error opening Wlanapi 2" << result ;
+        return ;
+    }
+    if( result != ERROR_SUCCESS) {
+        qDebug() << "Error in enumerating wireless interfaces" << result;
+        return ;
+    }
+    if (ERROR_SUCCESS != local_WlanRegisterNotification(hWlan,
+                                                  WLAN_NOTIFICATION_SOURCE_ALL,
+                                                  true,
+                                                  WLAN_NOTIFICATION_CALLBACK(wlanNotificationCallback),
+                                                  this, 0, 0)) {
+        qDebug() << "failed";
+    } else {
+        wlanCallbackInitialized = true;
+    }
+#endif
+}
+
+
+QSystemNetworkInfoPrivate *QSystemNetworkInfoPrivate::instance()
+{
+    resolveLibrary();
+    return qsystemNetworkInfoPrivate();
+}
+
+void QSystemNetworkInfoPrivate::emitNetworkStatusChanged(QSystemNetworkInfo::NetworkMode mode,
+                                                         QSystemNetworkInfo::NetworkStatus status)
+{
+    emit networkStatusChanged(mode, status);
+    if (status == QSystemNetworkInfo::NoNetworkAvailable
+        || status == QSystemNetworkInfo::Connected) {
+        startWifiCallback();
+        emit networkNameChanged(mode, networkName(mode));
+        if(isDefaultMode(mode)) {
+            emit networkModeChanged(mode);
+        }
+    } else {
+        networkSignalStrengthChanged(mode, 0);
+    }
+}
+
+void QSystemNetworkInfoPrivate::emitNetworkSignalStrengthChanged(QSystemNetworkInfo::NetworkMode mode,int /*strength*/)
+{
+    switch(QSysInfo::WindowsVersion) {
+    case QSysInfo::WV_VISTA:
+    case QSysInfo::WV_WINDOWS7:
+        break;
+    default:
+        QTimer::singleShot(timerMs, this, SLOT(networkStrengthTimeout()));
+        break;
+    };
+    networkSignalStrength(mode);
+}
+
+void QSystemNetworkInfoPrivate::timerEvent(QTimerEvent *event)
+{
+   if (event->timerId() == netStrengthTimer.timerId()) {
+      networkStrengthTimeout();
+   } else {
+      QObject::timerEvent(event);
+   }
+}
+
+
+void QSystemNetworkInfoPrivate::networkStrengthTimeout()
+{
+    QList<QSystemNetworkInfo::NetworkMode> modeList;
+    modeList << QSystemNetworkInfo::GsmMode;
+    modeList << QSystemNetworkInfo::CdmaMode;
+    modeList << QSystemNetworkInfo::WcdmaMode;
+    modeList << QSystemNetworkInfo::WlanMode;
+    modeList << QSystemNetworkInfo::EthernetMode;
+    modeList << QSystemNetworkInfo::BluetoothMode;
+    modeList << QSystemNetworkInfo::WimaxMode;
+
+    foreach(const QSystemNetworkInfo::NetworkMode mode, modeList) {
+        networkSignalStrength(mode);
+    }
+    switch(QSysInfo::WindowsVersion) {
+    case QSysInfo::WV_VISTA:
+    case QSysInfo::WV_WINDOWS7:
+        break;
+    default:
+        if(local_WlanOpenHandle)
+            QTimer::singleShot(timerMs, this, SLOT(networkStrengthTimeout()));
+        break;
+    };
+ }
+
+void QSystemNetworkInfoPrivate::networkStatusTimeout()
+{
+    QList<QSystemNetworkInfo::NetworkMode> modeList;
+    modeList << QSystemNetworkInfo::GsmMode;
+    modeList << QSystemNetworkInfo::CdmaMode;
+    modeList << QSystemNetworkInfo::WcdmaMode;
+    modeList << QSystemNetworkInfo::WlanMode;
+    modeList << QSystemNetworkInfo::EthernetMode;
+    modeList << QSystemNetworkInfo::BluetoothMode;
+    modeList << QSystemNetworkInfo::WimaxMode;
+
+    foreach(const QSystemNetworkInfo::NetworkMode mode, modeList) {
+        networkStatus(mode);
+    }
+
+ }
+
+
+QSystemNetworkInfo::NetworkStatus QSystemNetworkInfoPrivate::networkStatus(QSystemNetworkInfo::NetworkMode mode)
+{
+    switch(mode) {
+        case QSystemNetworkInfo::GsmMode:
+        break;
+        case QSystemNetworkInfo::CdmaMode:
+        break;
+        case QSystemNetworkInfo::WcdmaMode:
+        break;
+    case QSystemNetworkInfo::WlanMode:
+        {
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+            if(local_WlanOpenHandle) {
+                WLAN_CONNECTION_ATTRIBUTES *connAtts = getWifiConnectionAttributes();
+                if(connAtts != NULL) {
+                    if(connAtts->isState  == wlan_interface_state_authenticating) {
+                        local_WlanFreeMemory(connAtts);
+                        return QSystemNetworkInfo::Searching;
+                    }
+                    if(connAtts->isState  == wlan_interface_state_connected) {
+                        local_WlanFreeMemory(connAtts);
+                        return QSystemNetworkInfo::Connected;
+                    }
+                }
+                local_WlanFreeMemory(connAtts);
+            }
+#endif
+        }
+        break;
+    case QSystemNetworkInfo::EthernetMode:
+        {
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+            WMIHelper *wHelper;
+            wHelper = new WMIHelper(this);
+            wHelper->setWmiNamespace("root/cimv2");
+            wHelper->setClassName("Win32_NetworkAdapter");
+            wHelper->setClassProperty(QStringList() << "NetConnectionStatus");
+            QString cond;
+            cond = QString("WHERE MACAddress = '%1'").arg( interfaceForMode(mode).hardwareAddress());
+            wHelper->setConditional(cond.toLatin1());
+            QVariant v = wHelper->getWMIData();
+            if(v.toUInt() == 2) {
+                return QSystemNetworkInfo::Connected;
+            }
+#endif
+        }
+        break;
+        case QSystemNetworkInfo::BluetoothMode:
+        {
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+            WMIHelper *wHelper;
+            wHelper = new WMIHelper(this);
+            wHelper->setWmiNamespace("root/cimv2");
+            wHelper->setClassName("Win32_NetworkAdapter");
+            wHelper->setClassProperty(QStringList() << "NetConnectionStatus");
+            QString cond;
+            cond = QString("WHERE MACAddress = '%1'").arg( interfaceForMode(mode).hardwareAddress());
+            wHelper->setConditional(cond.toLatin1());
+            QVariant v = wHelper->getWMIData();
+            if(v.toUInt() == 2) {
+                return QSystemNetworkInfo::Connected;
+            }
+#endif
+        }
+        break;
+    case QSystemNetworkInfo::WimaxMode:
+        break;
+    };
+    return QSystemNetworkInfo::NoNetworkAvailable;
+}
+
+int QSystemNetworkInfoPrivate::networkSignalStrength(QSystemNetworkInfo::NetworkMode mode)
+{
+    switch(mode) {
+        case QSystemNetworkInfo::GsmMode:
+        break;
+        case QSystemNetworkInfo::CdmaMode:
+        break;
+        case QSystemNetworkInfo::WcdmaMode:
+        break;
+    case QSystemNetworkInfo::WlanMode:
+        {
+
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+            if(local_WlanOpenHandle) {
+
+                DWORD version =  0;
+                DWORD result;
+
+                WLAN_INTERFACE_INFO_LIST *interfacesInfoList = NULL;
+                if (hWlan ==0) {
+                    result = local_WlanOpenHandle( 2, NULL, &version, &hWlan );
+                    if( result != ERROR_SUCCESS ) {
+                        qDebug() << "Error opening Wlanapi 3" << result ;
+                        local_WlanCloseHandle(hWlan,  0);
+                        return 0;
+                    }
+                }
+                result = local_WlanEnumInterfaces(hWlan, NULL, &interfacesInfoList);
+
+                if( result != ERROR_SUCCESS) {
+                    qDebug() << "Error in enumerating wireless interfaces" << result;
+                    local_WlanCloseHandle(hWlan,  0);
+                    return 0;
+                }
+
+                for( uint i = 0; i < interfacesInfoList->dwNumberOfItems; i++ ) {
+                    WLAN_INTERFACE_INFO *interfaceInfo = &interfacesInfoList->InterfaceInfo[i];
+                    GUID& guid = interfaceInfo->InterfaceGuid;
+                    WLAN_INTERFACE_STATE wlanInterfaceState = interfaceInfo->isState;
+
+                    if( wlanInterfaceState == wlan_interface_state_not_ready ) {
+                        qDebug() << "Interface not ready";
+                        continue;
+                    }
+
+                    ULONG size = 0;
+                    WLAN_CONNECTION_ATTRIBUTES  *connAtts = NULL;
+                    result = local_WlanQueryInterface( hWlan, &guid,  wlan_intf_opcode_current_connection, NULL, &size, (PVOID*) &connAtts, NULL );
+
+                    if( result != ERROR_SUCCESS ) {
+                        continue;
+                    }
+                    ulong sig =  connAtts->wlanAssociationAttributes.wlanSignalQuality;
+                    local_WlanFreeMemory(connAtts);
+                    local_WlanFreeMemory(interfacesInfoList);
+
+                    if (sig != wifiStrength) {
+                        emit networkSignalStrengthChanged(mode, sig);
+                        wifiStrength = sig;
+                    }
+                    return sig;
+                }
+            }
+#endif
+        }
+        break;
+    case QSystemNetworkInfo::EthernetMode:
+        {
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+            WMIHelper *wHelper;
+            wHelper = new WMIHelper(this);
+            wHelper->setWmiNamespace("root/cimv2");
+            wHelper->setClassName("Win32_NetworkAdapter");
+            wHelper->setClassProperty(QStringList() << "NetConnectionStatus");
+            QString cond;
+            cond = QString("WHERE MACAddress = '%1'").arg( interfaceForMode(mode).hardwareAddress());
+            wHelper->setConditional(cond.toLatin1());
+            QVariant v = wHelper->getWMIData();
+            quint32 strength = v.toUInt();
+            quint32 tmpStrength;
+
+            if( strength == 2
+               || strength == 9) {
+                tmpStrength = 100;
+            } else {
+               tmpStrength = 0;
+            }
+
+            if(tmpStrength != ethStrength) {
+                ethStrength = tmpStrength;
+                emit networkSignalStrengthChanged(mode, ethStrength);
+            }
+
+            return ethStrength;
+#endif
+        }
+        break;
+    case QSystemNetworkInfo::BluetoothMode:
+        break;
+    case QSystemNetworkInfo::WimaxMode:
+        break;
+    };
+    return -1;
+}
+
+int QSystemNetworkInfoPrivate::cellId()
+{
+    return -1;
+}
+
+int QSystemNetworkInfoPrivate::locationAreaCode()
+{
+    return -1;
+}
+
+QString QSystemNetworkInfoPrivate::currentMobileCountryCode()
+{
+    return QString();
+}
+
+QString QSystemNetworkInfoPrivate::currentMobileNetworkCode()
+{
+    return QString();
+}
+
+QString QSystemNetworkInfoPrivate::homeMobileCountryCode()
+{
+    return QString();
+}
+
+QString QSystemNetworkInfoPrivate::homeMobileNetworkCode()
+{
+    return QString();
+}
+
+QString QSystemNetworkInfoPrivate::networkName(QSystemNetworkInfo::NetworkMode mode)
+{
+    QString netname = "";
+    switch(mode) {
+    case QSystemNetworkInfo::WlanMode:
+        {
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+            if(local_WlanOpenHandle) {
+                netname = "";
+                WLAN_CONNECTION_ATTRIBUTES *connAtts = getWifiConnectionAttributes();
+                if(connAtts != NULL) {
+                    DOT11_SSID ssid;
+                    ssid = connAtts->wlanAssociationAttributes.dot11Ssid;
+                    for(uint i = 0; i < ssid.uSSIDLength;i++) {
+                        netname += ssid.ucSSID[i];
+                    }
+                }
+                local_WlanFreeMemory(connAtts);
+            }
+#endif
+        }
+        break;
+    case QSystemNetworkInfo::EthernetMode:
+        {
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+            WMIHelper *wHelper;
+            wHelper = new WMIHelper(this);
+            wHelper->setWmiNamespace("root/cimv2");
+            wHelper->setClassName("Win32_ComputerSystem");
+            wHelper->setClassProperty(QStringList() << "Domain");
+
+            QVariant v = wHelper->getWMIData();
+            netname = v.toString();
+#endif
+        }
+        break;
+    default:
+        break;
+    };
+    return netname;
+}
+
+QString QSystemNetworkInfoPrivate::macAddress(QSystemNetworkInfo::NetworkMode mode)
+{
+    QString mac = interfaceForMode(mode).hardwareAddress();
+    return mac;
+}
+
+QNetworkInterface QSystemNetworkInfoPrivate::interfaceForMode(QSystemNetworkInfo::NetworkMode mode)
+{
+    QList<QNetworkInterface> interfaceList;
+    interfaceList = QNetworkInterface::allInterfaces();
+    QListIterator<QNetworkInterface> i(interfaceList);
+    while(i.hasNext()) {
+       QNetworkInterface netInterface = i.next();
+        if (!netInterface.isValid() || (netInterface.flags() & QNetworkInterface::IsLoopBack)) {
+            continue;
+        }
+
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+
+        if(local_WlanOpenHandle) {
+            unsigned long oid;
+            DWORD bytesWritten;
+
+            NDIS_MEDIUM medium ;
+            NDIS_PHYSICAL_MEDIUM physicalMedium = NdisPhysicalMediumUnspecified;
+
+            HANDLE handle = CreateFile((TCHAR *)QString("\\\\.\\%1").arg(netInterface.name()).utf16(), 0,
+                                       FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+
+            if (handle == INVALID_HANDLE_VALUE) {
+                continue;
+            }
+
+            oid = OID_GEN_MEDIA_SUPPORTED;
+            bytesWritten;
+            bool result = DeviceIoControl(handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid, sizeof(oid),
+                                          &medium, sizeof(medium), &bytesWritten, 0);
+            if (!result) {
+                CloseHandle(handle);
+                qDebug() << "DeviceIo result is false";
+                return QNetworkInterface();
+                continue;
+            }
+
+            oid = OID_GEN_PHYSICAL_MEDIUM;
+            bytesWritten = 0;
+            result = DeviceIoControl(handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid, sizeof(oid),
+                                     &physicalMedium, sizeof(physicalMedium), &bytesWritten, 0);
+
+
+            if (!result) {
+                CloseHandle(handle);
+                if (medium == NdisMedium802_3 && mode == QSystemNetworkInfo::EthernetMode) {
+                    return netInterface;
+                } else {
+                    continue;
+                }
+            }
+
+            CloseHandle(handle);
+            if (physicalMedium == NdisMediumWirelessWan && mode == QSystemNetworkInfo::WlanMode) {
+                //some wifi devices show up here
+                return netInterface;
+            }
+
+            if (medium == NdisMedium802_3) {
+                switch (physicalMedium) {
+                case NdisPhysicalMediumUnspecified:
+                    {
+                        if(mode == QSystemNetworkInfo::EthernetMode) {
+                            return netInterface;
+                        }
+                    }
+                    break;
+                case NdisPhysicalMediumWirelessLan:
+                    {
+                        if(mode == QSystemNetworkInfo::WlanMode) {
+                            return netInterface;
+                        }
+                    }
+                    break;
+                case NdisPhysicalMediumBluetooth:
+                    {
+                        if(mode == QSystemNetworkInfo::BluetoothMode) {
+                            return netInterface;
+                        }
+                    }
+                    break;
+#ifdef NDIS_SUPPORT_NDIS6
+                case NdisPhysicalMediumWiMax:
+                    {
+                        if(mode == QSystemNetworkInfo::WimaxMode) {
+                            return netInterface;
+                        }
+                    }
+                    break;
+#endif
+                };
+            }
+        }
+#endif
+    }
+
+    return QNetworkInterface();
+}
+
+bool QSystemNetworkInfoPrivate::isDefaultMode(QSystemNetworkInfo::NetworkMode mode)
+{
+    bool isDefaultGateway = false;
+    QNetworkInterface netInterface = interfaceForMode(mode);
+    QString deviceNameReg;
+
+    switch(QSysInfo::WindowsVersion) {
+    case  QSysInfo::WV_VISTA:
+    case QSysInfo::WV_WINDOWS7:
+        deviceNameReg = QString("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%1\\").arg(netInterface.name());
+        break;
+    default:
+        deviceNameReg = QString("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\%1\\Parameters\\Tcpip").arg(netInterface.name());
+        break;
+    };
+
+    QSettings deviceSettings(deviceNameReg, QSettings::NativeFormat);
+
+    if(!deviceSettings.value("DhcpDefaultGateway").toStringList().isEmpty()
+         || !deviceSettings.value("DefaultGateway").toStringList().isEmpty()) {
+        isDefaultGateway = true;
+    }
+    return isDefaultGateway;
+}
+
+QSystemNetworkInfo::NetworkMode QSystemNetworkInfoPrivate::currentMode()
+{
+    QList <QSystemNetworkInfo::NetworkMode> modeList;
+    modeList << QSystemNetworkInfo::GsmMode
+            << QSystemNetworkInfo::CdmaMode
+            << QSystemNetworkInfo::WcdmaMode
+            << QSystemNetworkInfo::WlanMode
+            << QSystemNetworkInfo::EthernetMode
+            << QSystemNetworkInfo::BluetoothMode
+            << QSystemNetworkInfo::WimaxMode;
+
+    for (int i = 0; i < modeList.size(); ++i) {
+        if ( isDefaultMode(modeList.at(i)))
+            return modeList.at(i);
+    }
+
+    return QSystemNetworkInfo::UnknownMode;
+}
+
+QSystemDisplayInfoPrivate::QSystemDisplayInfoPrivate(QObject *parent)
+        : QObject(parent)
+{
+}
+
+QSystemDisplayInfoPrivate::~QSystemDisplayInfoPrivate()
+{
+}
+
+int QSystemDisplayInfoPrivate::displayBrightness(int /*screen*/)
+{
+#if !defined( Q_CC_MINGW)
+#if !defined( Q_OS_WINCE)
+    WMIHelper *wHelper;
+    wHelper = new WMIHelper(this);
+    wHelper->setWmiNamespace("root/wmi");
+    wHelper->setClassName("WmiMonitorBrightness");
+    wHelper->setClassProperty(QStringList() << "CurrentBrightness");
+
+    QVariant v = wHelper->getWMIData();
+
+    return v.toUInt();
+#else
+    // This could would detect the state of the backlight, which is as close as we're going to get 
+    // for WinCE.  Unfortunately, some devices don't honour the Microsoft power management API.
+    // This means that the following code is not portable across WinCE devices and so shouldn't 
+    // be included.
+
+    //CEDEVICE_POWER_STATE powerState;
+    //
+    //if (ERROR_SUCCESS != GetDevicePower(L"BKL1:", POWER_NAME, &powerState))
+    //    return -1;
+    //
+    //// Backlight is on
+    //if (powerState == D0)
+    //    return 100;
+    //
+    //// Screen is on, backlight is off
+    //if (powerState == D1)
+    //    return 50;
+    //
+    //// Screen is off
+    //return 0;
+#endif
+#endif
+
+    return -1;
+}
+
+int QSystemDisplayInfoPrivate::colorDepth(int screen)
+{
+    QDesktopWidget wid;
+    HWND hWnd = wid.screen(screen)->winId();
+    HDC deviceContextHandle = GetDC(hWnd);
+    int bpp = GetDeviceCaps(deviceContextHandle ,BITSPIXEL);
+    int planes = GetDeviceCaps(deviceContextHandle, PLANES);
+    if(planes > 1) {
+        bpp = 1 << planes;
+    }
+    ReleaseDC(NULL, deviceContextHandle);
+
+    return bpp;
+}
+
+QSystemStorageInfoPrivate::QSystemStorageInfoPrivate(QObject *parent)
+        : QObject(parent)
+{
+}
+
+
+QSystemStorageInfoPrivate::~QSystemStorageInfoPrivate()
+{
+}
+
+qint64 QSystemStorageInfoPrivate::availableDiskSpace(const QString &driveVolume)
+{
+    qint64 freeBytes;
+    qint64 totalBytes;
+    qint64 totalFreeBytes;
+
+#if !defined(Q_OS_WINCE)
+    SetErrorMode(SEM_FAILCRITICALERRORS);
+#endif
+    bool ok = GetDiskFreeSpaceEx((WCHAR *)driveVolume.utf16(),(PULARGE_INTEGER)&freeBytes, (PULARGE_INTEGER)&totalBytes, (PULARGE_INTEGER)&totalFreeBytes);
+#if !defined(Q_OS_WINCE)
+    SetErrorMode(0);
+#endif
+    if(!ok)
+        totalFreeBytes = 0;
+    return totalFreeBytes;
+}
+
+qint64 QSystemStorageInfoPrivate::totalDiskSpace(const QString &driveVolume)
+{
+    qint64 freeBytes;
+    qint64 totalBytes;
+    qint64 totalFreeBytes;
+
+#if !defined(Q_OS_WINCE)
+    SetErrorMode(SEM_FAILCRITICALERRORS);
+#endif
+    bool ok = GetDiskFreeSpaceEx((WCHAR *)driveVolume.utf16(),(PULARGE_INTEGER)&freeBytes, (PULARGE_INTEGER)&totalBytes, (PULARGE_INTEGER)&totalFreeBytes);
+#if !defined(Q_OS_WINCE)
+    SetErrorMode(0);
+#endif
+    if(!ok)
+        totalBytes = 0;
+    return totalBytes;
+}
+
+QSystemStorageInfo::DriveType QSystemStorageInfoPrivate::typeForDrive(const QString &driveVolume)
+{
+#if !defined( Q_OS_WINCE)
+    uint result =  GetDriveType((WCHAR *)driveVolume.utf16());
+    switch(result) {
+    case 0:
+    case 1:
+        return QSystemStorageInfo::NoDrive;
+        break;
+    case 2:
+        return QSystemStorageInfo::RemovableDrive;
+        break;
+    case 3:
+        return QSystemStorageInfo::InternalDrive;
+        break;
+    case 4:
+        return QSystemStorageInfo::RemoteDrive;
+        break;
+    case 5:
+        return QSystemStorageInfo::CdromDrive;
+        break;
+    case 6:
+        break;
+    };
+#endif
+    return QSystemStorageInfo::NoDrive;
+}
+
+QStringList QSystemStorageInfoPrivate::logicalDrives()
+{
+    QStringList drivesList;
+    QFileInfoList drives = QDir::drives();
+    foreach(QFileInfo drive, drives) {
+        QString letter =  drive.absoluteFilePath();
+        letter.chop(1);
+        if(totalDiskSpace(letter) > 0) {
+            drivesList.append(letter);
+        }
+    }
+    return drivesList;
+}
+
+#if defined(Q_OS_WINCE)
+QPowerNotificationThread::QPowerNotificationThread(QSystemDeviceInfoPrivate *parent)
+    : parent(parent),
+    done(false)
+{
+    wakeUpEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+}
+
+QPowerNotificationThread::~QPowerNotificationThread() {
+    mutex.lock();
+
+    done = true;
+    SetEvent(wakeUpEvent);
+
+    mutex.unlock();
+
+    wait();
+
+    CloseHandle(wakeUpEvent);
+}
+
+void QPowerNotificationThread::run() {
+
+    const int MaxMessageSize = sizeof(POWER_BROADCAST) + sizeof(POWER_BROADCAST_POWER_INFO) 
+        + MAX_PATH;
+
+    MSGQUEUEOPTIONS messageQueueOptions = { 0 };
+    messageQueueOptions.dwSize = sizeof(messageQueueOptions);
+    messageQueueOptions.dwFlags = MSGQUEUE_NOPRECOMMIT;
+    messageQueueOptions.dwMaxMessages = 0;
+    messageQueueOptions.cbMaxMessage = MaxMessageSize;
+    messageQueueOptions.bReadAccess = true;
+
+    HANDLE messageQueue = CreateMsgQueue(NULL, &messageQueueOptions);
+
+    if (messageQueue == NULL)
+        return;
+
+    HANDLE powerNotificationHandle = RequestPowerNotifications(messageQueue, PBT_TRANSITION 
+            | PBT_POWERINFOCHANGE);
+
+    if (messageQueue == NULL)
+        return;
+
+    HANDLE events[2] = {messageQueue, wakeUpEvent};
+
+    while(true) {
+        DWORD dwRet = WaitForMultipleObjects(2, events, FALSE, INFINITE);
+
+        mutex.lock();
+
+        if (done) {
+            mutex.unlock();
+            break;
+        }
+
+        if (dwRet == WAIT_OBJECT_0) {
+
+            BYTE buffer[MaxMessageSize];
+            DWORD bytesRead = 0;
+            DWORD messageProperties;
+
+            if (!ReadMsgQueue(messageQueue, &buffer, MaxMessageSize, &bytesRead, 0, &messageProperties)) {
+                continue;
+            }
+
+            if (bytesRead < sizeof(POWER_BROADCAST)) {
+                continue;
+            }
+
+            POWER_BROADCAST *broadcast = (POWER_BROADCAST*) (buffer);
+
+            if (broadcast->Message == PBT_POWERINFOCHANGE) {
+                POWER_BROADCAST_POWER_INFO *info = (POWER_BROADCAST_POWER_INFO*) broadcast->SystemPowerState;                
+                parent->batteryLevel();
+            }
+
+            parent->currentPowerState();
+
+        } else if (dwRet == WAIT_OBJECT_0 + 1) {
+            // we should only be here if the wakeUpEvent was signalled
+            // which only occurs when the thread is being stopped
+            Q_ASSERT(done);
+        } else if (dwRet = WAIT_FAILED) {
+            continue;
+        }
+
+        mutex.unlock();
+    }
+
+    StopPowerNotifications(powerNotificationHandle);
+    CloseMsgQueue(messageQueue);
+    CloseHandle(messageQueue);
+}
+
+#endif
+
+QSystemDeviceInfoPrivate *QSystemDeviceInfoPrivate::self = 0;
+
+#if !defined(Q_OS_WINCE)
+bool qax_winEventFilter(void *message)
+{
+    MSG *pMsg = (MSG*)message;
+    if( pMsg->message == WM_POWERBROADCAST) {
+        switch (pMsg->wParam) {
+        case PBT_APMPOWERSTATUSCHANGE:
+            QSystemDeviceInfoPrivate::instance()->batteryLevel();
+            QSystemDeviceInfoPrivate::instance()->currentPowerState();
+            break;
+            break;
+        default:
+            break;
+        };
+    }
+
+    return false;
+}
+#endif
+
+QSystemDeviceInfoPrivate::QSystemDeviceInfoPrivate(QObject *parent)
+        : QObject(parent)
+{
+    batteryLevelCache = 0;
+    currentPowerStateCache = QSystemDeviceInfo::UnknownPower;
+    batteryStatusCache = QSystemDeviceInfo::NoBatteryLevel;
+#if !defined(Q_OS_WINCE)
+    QAbstractEventDispatcher::instance()->setEventFilter(qax_winEventFilter);
+#else
+    powerNotificationThread = new QPowerNotificationThread(this);
+    powerNotificationThread->start();
+#endif
+    if(!self)
+        self = this;
+
+}
+
+QSystemDeviceInfoPrivate::~QSystemDeviceInfoPrivate()
+{
+#if defined(Q_OS_WINCE)
+    delete powerNotificationThread;
+#endif
+}
+
+QSystemDeviceInfo::Profile QSystemDeviceInfoPrivate::currentProfile()
+{
+    return QSystemDeviceInfo::UnknownProfile;
+}
+
+QSystemDeviceInfo::InputMethodFlags QSystemDeviceInfoPrivate::inputMethodType()
+{
+    QSystemDeviceInfo::InputMethodFlags methods;
+
+#if !defined(Q_OS_WINCE)
+    int mouseResult = GetSystemMetrics(SM_CMOUSEBUTTONS);
+    if(mouseResult > 0) {
+        if((methods & QSystemDeviceInfo::Mouse) != QSystemDeviceInfo::Mouse) {
+            methods |= QSystemDeviceInfo::Mouse;
+
+        }
+    }
+# if defined(SM_TABLETPC)
+    int tabletResult = GetSystemMetrics(SM_TABLETPC);
+    if(tabletResult > 0) {
+        if((methods & QSystemDeviceInfo::SingleTouch) != QSystemDeviceInfo::SingleTouch) {
+            methods |= QSystemDeviceInfo::SingleTouch;
+
+        }
+    }
+# endif
+#else 
+    // detect the presence of a mouse
+    RECT rect;
+    if (GetClipCursor(&rect)) {
+        if ((methods & QSystemDeviceInfo::Mouse) != QSystemDeviceInfo::Mouse) {
+            methods |= QSystemDeviceInfo::Mouse;
+        }
+    }
+    // We could also try to detect the presence of a stylus / single touch input.
+    // A team from Microsoft was unable to do this in a way which scaled across multiple devices.    
+    // For more details see:
+    // http://blogs.msdn.com/netcfteam/archive/2006/10/02/Platform-detection-III_3A00_-How-to-detect-a-touch-screen-on-Windows-CE-in-.NET-CF.aspx
+    // Since all non-Qt apps on non-compliant devices will be able to use the touch screen
+    // (by virtue of being written for one particular device) shipping a library which will cause 
+    // just the Qt apps to fail may not be the best move.
+#endif
+    int keyboardType = GetKeyboardType(0);
+    switch(keyboardType) {
+    case 1:
+    case 3:
+        {
+            if((methods & QSystemDeviceInfo::Keyboard) != QSystemDeviceInfo::Keyboard) {
+                methods |= QSystemDeviceInfo::Keyboard;
+
+            }
+        }
+        break;
+    case 2:
+    case 4:
+        {
+            if((methods & QSystemDeviceInfo::Keyboard) != QSystemDeviceInfo::Keyboard) {
+                methods |= QSystemDeviceInfo::Keyboard;
+
+            }
+            if((methods & QSystemDeviceInfo::Keypad) != QSystemDeviceInfo::Keypad) {
+                methods |= QSystemDeviceInfo::Keypad;
+
+            }
+        }
+        break;
+    case 5:
+        {
+            if((methods & QSystemDeviceInfo::Keypad) != QSystemDeviceInfo::Keypad) {
+                methods |= QSystemDeviceInfo::Keypad;
+
+            }
+        }
+        break;
+    default:
+        break;
+
+    };
+
+    return methods;
+}
+
+
+QSystemDeviceInfo::PowerState QSystemDeviceInfoPrivate::currentPowerState()
+{
+#ifdef Q_OS_WINCE
+    SYSTEM_POWER_STATUS_EX status;
+    GetSystemPowerStatusEx(&status, true);
+
+#else
+    SYSTEM_POWER_STATUS status;
+    GetSystemPowerStatus(&status);
+#endif
+    QSystemDeviceInfo::PowerState state = QSystemDeviceInfo::UnknownPower;
+
+    if(status.ACLineStatus  == AC_LINE_ONLINE) {
+        state = QSystemDeviceInfo::WallPower;
+    }
+    if(status.ACLineStatus  == AC_LINE_OFFLINE) {
+        state = QSystemDeviceInfo::BatteryPower;
+    }
+    if(status.BatteryFlag & BATTERY_FLAG_CHARGING) {
+        state = QSystemDeviceInfo::WallPowerChargingBattery;
+    }
+    if( currentPowerStateCache != state) {
+        currentPowerStateCache = state;
+        emit powerStateChanged(state);
+    }
+
+    return state;
+}
+
+QString QSystemDeviceInfoPrivate::imei()
+{
+        return "";
+}
+
+QString QSystemDeviceInfoPrivate::imsi()
+{
+        return "";
+}
+
+QString QSystemDeviceInfoPrivate::manufacturer()
+{
+   QString manu;
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+    WMIHelper *wHelper;
+    wHelper = new WMIHelper(this);
+    wHelper->setWmiNamespace("root/cimv2");
+    wHelper->setClassName("Win32_ComputerSystemProduct");
+    wHelper->setClassProperty(QStringList() << "Vendor");
+    QVariant v = wHelper->getWMIData();
+    manu = v.toString();
+    if(manu.isEmpty()) {
+        manu = "System manufacturer";
+    }
+    delete wHelper;
+#endif
+    return manu;
+}
+
+QString QSystemDeviceInfoPrivate::model()
+{
+   QString model;
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+    WMIHelper *wHelper;
+    wHelper = new WMIHelper(this);
+    wHelper->setWmiNamespace("root/cimv2");
+
+    wHelper->setClassName("Win32_ComputerSystem");
+    wHelper->setClassProperty(QStringList() << "Model");
+    QVariant v = wHelper->getWMIData();
+    model = v.toString();
+
+    wHelper->setClassName("Win32_ComputerSystem");
+    wHelper->setClassProperty(QStringList() << "PCSystemType");
+    v = wHelper->getWMIData();
+    switch(v.toUInt()) {
+    case 0:
+        model += "";
+        break;
+    case 1:
+        model += "Desktop";
+        break;
+    case 2:
+        model += "Mobile";
+        break;
+    case 3:
+        model += "Workstation";
+        break;
+    case 4:
+        model += "Enterprise Server";
+        break;
+    case 5:
+        model += "Small/Home Server";
+        break;
+    case 6:
+        model += "Applicance PC";
+        break;
+    case 7:
+        model += "Performace Server";
+        break;
+    case 8:
+        model += "Maximum";
+        break;
+
+    };
+    delete wHelper;
+#endif
+    return model;
+}
+
+QString QSystemDeviceInfoPrivate::productName()
+{
+   QString name;
+#if !defined( Q_CC_MINGW) && !defined( Q_OS_WINCE)
+    WMIHelper *wHelper;
+    wHelper = new WMIHelper(this);
+    wHelper->setWmiNamespace("root/cimv2");
+    wHelper->setClassName("Win32_ComputerSystemProduct");
+    wHelper->setClassProperty(QStringList() << "Name");
+    QVariant v = wHelper->getWMIData();
+    name = v.toString();
+
+    if(name.isEmpty()) {
+        wHelper->setClassName("Win32_ComputerSystem");
+        wHelper->setClassProperty(QStringList() << "PCSystemType");
+        v = wHelper->getWMIData();
+        name = v.toString();
+        if(name.isEmpty()) {
+            name = "Unspecified product";
+        }
+    }
+
+    delete wHelper;
+#endif
+    return name;
+}
+
+int QSystemDeviceInfoPrivate::batteryLevel()
+{
+    int bat = 0;
+#ifdef Q_OS_WINCE
+    SYSTEM_POWER_STATUS_EX status;
+    if(GetSystemPowerStatusEx(&status, true) ) {
+        bat = status.BatteryLifePercent;
+    } else {
+       qDebug() << "Battery status failed";
+       return 0;
+    }
+#else
+    SYSTEM_POWER_STATUS status;
+    if(GetSystemPowerStatus( &status) ) {
+        bat = status.BatteryLifePercent;
+    } else {
+       qDebug() << "Battery status failed";
+       return 0;
+    }
+#endif
+    if(bat == 255) //battery unknown level status
+        bat = 0;
+
+    if(batteryLevelCache != bat) {
+       batteryLevelCache = bat;
+       emit batteryLevelChanged(bat);
+    }
+
+    if(batteryLevelCache < 4 && batteryStatusCache != QSystemDeviceInfo::BatteryCritical) {
+        batteryStatusCache = QSystemDeviceInfo::BatteryCritical;
+        emit batteryStatusChanged(batteryStatusCache);
+    } else if((batteryLevelCache > 3 && batteryLevelCache < 11) && batteryStatusCache != QSystemDeviceInfo::BatteryVeryLow) {
+        batteryStatusCache = QSystemDeviceInfo::BatteryVeryLow;
+        emit batteryStatusChanged(batteryStatusCache);
+    } else if((batteryLevelCache > 10 && batteryLevelCache < 41) && batteryStatusCache != QSystemDeviceInfo::BatteryLow) {
+        batteryStatusCache = QSystemDeviceInfo::BatteryLow;
+        emit batteryStatusChanged(batteryStatusCache);
+    } else if(batteryLevelCache > 40 && batteryStatusCache != QSystemDeviceInfo::BatteryNormal) {
+        batteryStatusCache = QSystemDeviceInfo::BatteryNormal;
+        emit batteryStatusChanged(batteryStatusCache);
+    }
+
+    return bat;
+}
+
+QSystemDeviceInfo::SimStatus QSystemDeviceInfoPrivate::simStatus()
+{
+#ifdef Q_OS_WINCE
+    HSIM handle;
+    DWORD lockedState;
+    HRESULT result = SimInitialize(0,NULL,NULL,&handle);
+    if(result == S_OK) {
+        SimGetPhoneLockedState(handle,&lockedState);
+        if(lockedState == SIM_LOCKEDSTATE_READY) {
+            return QSystemDeviceInfo::SingleSimAvailable;
+        } else {
+            return QSystemDeviceInfo::SimLocked;
+        }
+
+
+    } else if(result == SIM_E_NOSIM) {
+        return QSystemDeviceInfo::SimNotAvailable;
+    }
+    SimDeinitialize(handle);
+
+#endif
+    return QSystemDeviceInfo::SimNotAvailable;
+}
+
+bool QSystemDeviceInfoPrivate::isDeviceLocked()
+{
+#ifdef Q_OS_WINCE
+    HSIM handle;
+    DWORD lockedState;
+    HRESULT result = SimInitialize(0,NULL,NULL,&handle);
+    if(result == S_OK) {
+        SimGetPhoneLockedState(handle,&lockedState);
+        if(lockedState != SIM_LOCKEDSTATE_READY) {
+            return true;
+        }
+    }
+#else
+    QSystemScreenSaverPrivate si;
+    if( SystemParametersInfo( SPI_GETSCREENSAVERRUNNING,true,0,0)
+        && si.screenSaverSecureEnabled() )
+        return true;
+
+#endif
+    return false;
+}
+
+QSystemScreenSaverPrivate::QSystemScreenSaverPrivate(QObject *parent)
+        : QObject(parent)
+{
+    screenSaverSecureEnabled();
+}
+
+bool QSystemScreenSaverPrivate::screenSaverSecureEnabled()
+{
+    screenSaverSecure = false;
+    QSettings screenSettingsTmp("HKEY_CURRENT_USER\\Software\\Policies\\Microsoft\\Windows\\Control Panel\\Desktop", QSettings::NativeFormat);
+    if(!screenSettingsTmp.value("SCRNSAVE.EXE").toString().isEmpty()) {
+        settingsPath = "HKEY_CURRENT_USER\\Software\\Policies\\Microsoft\\Windows\\Control Panel\\Desktop";
+    } else {
+        settingsPath = "HKEY_CURRENT_USER\\Control Panel\\Desktop";
+    }
+
+    QSettings screenSettings(settingsPath, QSettings::NativeFormat);
+    if(screenSettings.value("ScreenSaverIsSecure").toString() == "1") {
+        screenSaverSecure = true;
+    }
+    screenPath = screenSettings.value("SCRNSAVE.EXE").toString();
+    return screenSaverSecure;
+}
+
+
+bool QSystemScreenSaverPrivate::setScreenSaverInhibit()
+{
+    if(screenSaverSecure)
+        return false;
+#if !defined(Q_OS_WINCE)
+    return SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,true,0,SPIF_SENDWININICHANGE);
+#else
+    return false;
+#endif
+}
+
+bool QSystemScreenSaverPrivate::screenSaverInhibited()
+{
+    QSettings screenSettings(settingsPath, QSettings::NativeFormat);
+    return !screenSettings.value("SCRNSAVE.EXE").toString().isEmpty();
+}
+
+
+#include "moc_qsysteminfo_win_p.cpp"
+
+QTM_END_NAMESPACE