зеркало из https://github.com/mozilla/pjs.git
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
This commit is contained in:
Родитель
2378a183d7
Коммит
d2247c4052
|
@ -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
|
||||
|
|
|
@ -123,6 +123,8 @@ _PR_MD_INIT_IO()
|
|||
_PR_NT_InitSids();
|
||||
|
||||
InitUnicodeSupport();
|
||||
|
||||
_PR_MD_InitSockets();
|
||||
}
|
||||
|
||||
PRStatus
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,8 @@ void _PR_MD_CLEANUP_BEFORE_EXIT(void)
|
|||
{
|
||||
_PR_NT_FreeSids();
|
||||
|
||||
_PR_MD_CleanupSockets();
|
||||
|
||||
WSACleanup();
|
||||
|
||||
#ifndef _PR_USE_STATIC_TLS
|
||||
|
|
Загрузка…
Ссылка в новой задаче