diff options
author | wtchang%redhat.com <devnull@localhost> | 2007-03-14 18:04:54 +0000 |
---|---|---|
committer | wtchang%redhat.com <devnull@localhost> | 2007-03-14 18:04:54 +0000 |
commit | 921dbd3e36d899d861b46721c765178d214d595f (patch) | |
tree | 760b971b360e619563a9a736ea1ebe6c0a90d6c0 | |
parent | 00366451797891f020008d8a9d6970c101f4b06a (diff) | |
download | nspr-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.h | 2 | ||||
-rw-r--r-- | pr/src/md/windows/w95io.c | 2 | ||||
-rw-r--r-- | pr/src/md/windows/w95sock.c | 112 | ||||
-rw-r--r-- | pr/src/md/windows/w95thred.c | 2 |
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 |