summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtchang%redhat.com <devnull@localhost>2007-03-14 18:04:54 +0000
committerwtchang%redhat.com <devnull@localhost>2007-03-14 18:04:54 +0000
commit921dbd3e36d899d861b46721c765178d214d595f (patch)
tree760b971b360e619563a9a736ea1ebe6c0a90d6c0
parent00366451797891f020008d8a9d6970c101f4b06a (diff)
downloadnspr-hg-921dbd3e36d899d861b46721c765178d214d595f.tar.gz
Bugzilla bug 363997: when running on Windows Vista, set the sockets in the
compatibility mode so that the new TCP/IP stack in Windows Vista can interoperate with all the TCP/IP implementations. The patch is contributed by Seth Spitzer <sspitzer@mozilla.com>. r=wtc,biesi Modified Files: _win95.h w95io.c w95sock.c w95thred.c Tag: NSPRPUB_PRE_4_2_CLIENT_BRANCH
-rw-r--r--pr/include/md/_win95.h2
-rw-r--r--pr/src/md/windows/w95io.c2
-rw-r--r--pr/src/md/windows/w95sock.c112
-rw-r--r--pr/src/md/windows/w95thred.c2
4 files changed, 118 insertions, 0 deletions
diff --git a/pr/include/md/_win95.h b/pr/include/md/_win95.h
index 9d795184..db1e8d47 100644
--- a/pr/include/md/_win95.h
+++ b/pr/include/md/_win95.h
@@ -286,6 +286,8 @@ extern PRBool _pr_useUnicode;
#endif /* MOZ_UNICODE */
/* --- Socket IO stuff --- */
+extern void _PR_MD_InitSockets(void);
+extern void _PR_MD_CleanupSockets(void);
#define _MD_EACCES WSAEACCES
#define _MD_EADDRINUSE WSAEADDRINUSE
#define _MD_EADDRNOTAVAIL WSAEADDRNOTAVAIL
diff --git a/pr/src/md/windows/w95io.c b/pr/src/md/windows/w95io.c
index 08e7df6a..ccbec62a 100644
--- a/pr/src/md/windows/w95io.c
+++ b/pr/src/md/windows/w95io.c
@@ -123,6 +123,8 @@ _PR_MD_INIT_IO()
_PR_NT_InitSids();
InitUnicodeSupport();
+
+ _PR_MD_InitSockets();
}
PRStatus
diff --git a/pr/src/md/windows/w95sock.c b/pr/src/md/windows/w95sock.c
index 58d6f6a0..8837a7f8 100644
--- a/pr/src/md/windows/w95sock.c
+++ b/pr/src/md/windows/w95sock.c
@@ -53,6 +53,100 @@ static PRInt32 socket_io_wait(
/* --- SOCKET IO --------------------------------------------------------- */
+/*
+ * we only want to call WSAIoctl() on Vista and later
+ * so don't pay for it at build time (and avoid including winsock2.h)
+ */
+
+/* from ws2def.h */
+#define IOC_IN 0x80000000 /* copy in parameters */
+#define IOC_VENDOR 0x18000000
+#define _WSAIOW(x,y) (IOC_IN|(x)|(y))
+/* from MSWSockDef.h */
+#define SIO_SET_COMPATIBILITY_MODE _WSAIOW(IOC_VENDOR,300)
+
+typedef enum _WSA_COMPATIBILITY_BEHAVIOR_ID {
+ WsaBehaviorAll = 0,
+ WsaBehaviorReceiveBuffering,
+ WsaBehaviorAutoTuning
+} WSA_COMPATIBILITY_BEHAVIOR_ID, *PWSA_COMPATIBILITY_BEHAVIOR_ID;
+
+/* from sdkddkver.h */
+#define NTDDI_LONGHORN 0x06000000
+
+/* from winsock2.h */
+#define WSAEVENT HANDLE
+
+typedef struct _WSAOVERLAPPED {
+ DWORD Internal;
+ DWORD InternalHigh;
+ DWORD Offset;
+ DWORD OffsetHigh;
+ WSAEVENT hEvent;
+} WSAOVERLAPPED, FAR * LPWSAOVERLAPPED;
+
+typedef void (CALLBACK * LPWSAOVERLAPPED_COMPLETION_ROUTINE)(
+ IN DWORD dwError,
+ IN DWORD cbTransferred,
+ IN LPWSAOVERLAPPED lpOverlapped,
+ IN DWORD dwFlags
+);
+
+typedef int (__stdcall * WSAIOCTLPROC) (
+ SOCKET s,
+ DWORD dwIoControlCode,
+ LPVOID lpvInBuffer,
+ DWORD cbInBuffer,
+ LPVOID lpvOutBuffer,
+ DWORD cbOutBuffer,
+ LPDWORD lpcbBytesReturned,
+ LPWSAOVERLAPPED lpOverlapped,
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
+);
+
+typedef struct _WSA_COMPATIBILITY_MODE {
+ WSA_COMPATIBILITY_BEHAVIOR_ID BehaviorId;
+ ULONG TargetOsVersion;
+} WSA_COMPATIBILITY_MODE, *PWSA_COMPATIBILITY_MODE;
+
+static HMODULE libWinsock2 = NULL;
+static WSAIOCTLPROC wsaioctlProc = NULL;
+static PRBool socketSetCompatMode = PR_FALSE;
+
+void _PR_MD_InitSockets(void)
+{
+ OSVERSIONINFO osvi;
+
+ memset(&osvi, 0, sizeof(osvi));
+ osvi.dwOSVersionInfoSize = sizeof(osvi);
+ GetVersionEx(&osvi);
+
+ /* if Vista or later... */
+ if (osvi.dwMajorVersion >= 6)
+ {
+ libWinsock2 = LoadLibrary("Ws2_32.dll");
+ if (libWinsock2)
+ {
+ wsaioctlProc = (WSAIOCTLPROC)GetProcAddress(libWinsock2,
+ "WSAIoctl");
+ if (wsaioctlProc)
+ {
+ socketSetCompatMode = PR_TRUE;
+ }
+ }
+ }
+}
+
+void _PR_MD_CleanupSockets(void)
+{
+ socketSetCompatMode = PR_FALSE;
+ wsaioctlProc = NULL;
+ if (libWinsock2)
+ {
+ FreeLibrary(libWinsock2);
+ libWinsock2 = NULL;
+ }
+}
PROsfd
_PR_MD_SOCKET(int af, int type, int flags)
@@ -78,6 +172,24 @@ _PR_MD_SOCKET(int af, int type, int flags)
return -1;
}
+ if (socketSetCompatMode)
+ {
+ WSA_COMPATIBILITY_MODE mode;
+ char dummy[4];
+ int ret_dummy;
+
+ mode.BehaviorId = WsaBehaviorAutoTuning;
+ mode.TargetOsVersion = NTDDI_LONGHORN;
+ if (wsaioctlProc(sock, SIO_SET_COMPATIBILITY_MODE,
+ (char *)&mode, sizeof(mode),
+ dummy, 4, &ret_dummy, 0, NULL) == SOCKET_ERROR)
+ {
+ PR_SetError(PR_UNKNOWN_ERROR, WSAGetLastError());
+ closesocket(sock);
+ return -1;
+ }
+ }
+
return (PROsfd)sock;
}
diff --git a/pr/src/md/windows/w95thred.c b/pr/src/md/windows/w95thred.c
index 89cd39ab..5d8045aa 100644
--- a/pr/src/md/windows/w95thred.c
+++ b/pr/src/md/windows/w95thred.c
@@ -73,6 +73,8 @@ void _PR_MD_CLEANUP_BEFORE_EXIT(void)
{
_PR_NT_FreeSids();
+ _PR_MD_CleanupSockets();
+
WSACleanup();
#ifndef _PR_USE_STATIC_TLS