summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShane Kearns <ext-shane.2.kearns@nokia.com>2012-06-19 17:38:40 +0100
committerQt by Nokia <qt-info@nokia.com>2012-06-22 13:43:28 +0200
commit1655cb5a690895631238b5b7a9a1f0c8ad32fbc4 (patch)
tree3379e9bd122e0c6bb70f4360fc1f33ff0a8cef80
parent66589cd545e302ca535579f248071f77bc8b261b (diff)
Fix non inheritable socket creation on old windows versions
The documentation is misleading, as using the new API actually causes WSASocket to fail. New behaviour: On windows vista or earlier: skip the new API, use old one On windows 7: try the new API first, if it fails try the old one On windows 8: try the new API only The windows 7 behaviour is because we don't know if the service pack has been installed or not. (And IT departments may have specifically installed/blocked the hotfix) Task-number: QTBUG-26224 Change-Id: I6da47959919caee0cd2697f1ae1fca46aa33c1ff Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Mikhail Vorozhtsov
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp37
1 files changed, 21 insertions, 16 deletions
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index 60c4c73950..8b354a8c50 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -307,10 +307,11 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
return -1;
}
*/
+ QSysInfo::WinVersion osver = QSysInfo::windowsVersion();
//Windows XP and 2003 support IPv6 but not dual stack sockets
int protocol = (socketProtocol == QAbstractSocket::IPv6Protocol
- || (socketProtocol == QAbstractSocket::AnyIPProtocol && QSysInfo::windowsVersion() >= QSysInfo::WV_6_0)) ? AF_INET6 : AF_INET;
+ || (socketProtocol == QAbstractSocket::AnyIPProtocol && osver >= QSysInfo::WV_6_0)) ? AF_INET6 : AF_INET;
int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM;
// MSDN KB179942 states that on winnt 4 WSA_FLAG_OVERLAPPED is needed if socket is to be non blocking
@@ -318,12 +319,29 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
// WSA_FLAG_NO_HANDLE_INHERIT is atomic (like linux O_CLOEXEC), but requires windows 7 SP 1 or later
// SetHandleInformation is supported since W2K but isn't atomic
- // According to the MS docs, we can use the new flag and call GetHandleInformation to see if it was successful
#ifndef WSA_FLAG_NO_HANDLE_INHERIT
#define WSA_FLAG_NO_HANDLE_INHERIT 0x80
#endif
- SOCKET socket = ::WSASocket(protocol, type, 0, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT | WSA_FLAG_OVERLAPPED);
+ SOCKET socket = INVALID_SOCKET;
+ // Windows 7 or later, try the new API
+ if (osver >= QSysInfo::WV_6_1)
+ socket = ::WSASocket(protocol, type, 0, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT | WSA_FLAG_OVERLAPPED);
+ // previous call fails if the windows 7 service pack 1 or hot fix isn't installed.
+
+ // Try the old API if the new one failed on Windows 7, or always on earlier versions
+ if (socket == INVALID_SOCKET && osver <= QSysInfo::WV_6_1) {
+ socket = ::WSASocket(protocol, type, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
+#ifdef HANDLE_FLAG_INHERIT
+ if (socket != INVALID_SOCKET) {
+ // make non inheritable the old way
+ BOOL handleFlags = SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0);
+#ifdef QNATIVESOCKETENGINE_DEBUG
+ qDebug() << "QNativeSocketEnginePrivate::createNewSocket - set inheritable" << handleFlags;
+#endif
+ }
+#endif
+ }
if (socket == INVALID_SOCKET) {
int err = WSAGetLastError();
@@ -349,19 +367,6 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
return false;
}
-#ifdef HANDLE_FLAG_INHERIT
- // check if the WSASocket was successful or not at creating a non inheritable socket
- DWORD handleFlags = 0xFF;
- if (GetHandleInformation((HANDLE)socket, &handleFlags) && (handleFlags & HANDLE_FLAG_INHERIT)) {
- // make non inheritable the old way
- if (SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0))
- handleFlags = 0;
- }
-#ifdef QNATIVESOCKETENGINE_DEBUG
- qDebug() << "QNativeSocketEnginePrivate::createNewSocket - set inheritable" << handleFlags;
-#endif
-#endif
-
#if !defined(Q_OS_WINCE)
if (socketType == QAbstractSocket::UdpSocket) {
// enable new behavior using