mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
766 lines
18 KiB
766 lines
18 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
SockProc.c
|
|
|
|
Abstract:
|
|
|
|
This module contains support routines for the WinSock DLL.
|
|
|
|
Author:
|
|
|
|
David Treadwell (davidtr) 20-Feb-1992
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "winsockp.h"
|
|
|
|
#include <ctype.h>
|
|
#include <stdarg.h>
|
|
#include <wincon.h>
|
|
|
|
#define MAX_BLOCKING_HOOK_CALLS 1000
|
|
|
|
#if DBG
|
|
BOOLEAN WsaStartupWarning = FALSE;
|
|
#endif
|
|
|
|
|
|
BOOLEAN
|
|
SockEnterApi (
|
|
IN BOOLEAN MustBeStarted,
|
|
IN BOOLEAN BlockingIllegal,
|
|
IN BOOLEAN GetXByYCall
|
|
)
|
|
{
|
|
PWINSOCK_TLS_DATA tlsData;
|
|
|
|
//
|
|
// Bail if we're already detached from the process.
|
|
//
|
|
|
|
if( SockProcessTerminating ) {
|
|
|
|
IF_DEBUG(ENTER) {
|
|
WS_PRINT(( "SockEnterApi: process terminating\n" ));
|
|
}
|
|
|
|
SetLastError( WSANOTINITIALISED );
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Make sure that WSAStartup has been called, if necessary.
|
|
//
|
|
|
|
if ( MustBeStarted && (SockWsaStartupCount == 0 || SockTerminating) ) {
|
|
|
|
IF_DEBUG(ENTER) {
|
|
WS_PRINT(( "SockEnterApi: WSAStartup() not called!\n" ));
|
|
}
|
|
|
|
SetLastError( WSANOTINITIALISED );
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If this thread has not been initialized, do it now.
|
|
//
|
|
|
|
tlsData = GET_THREAD_DATA();
|
|
|
|
if ( tlsData == NULL ) {
|
|
|
|
if ( !SockThreadInitialize() ) {
|
|
|
|
IF_DEBUG(ENTER) {
|
|
WS_PRINT(( "SockEnterApi: SockThreadInitialize failed.\n" ));
|
|
}
|
|
|
|
SetLastError( WSAENOBUFS );
|
|
return FALSE;
|
|
}
|
|
|
|
tlsData = GET_THREAD_DATA();
|
|
}
|
|
|
|
//
|
|
// Make sure that we're not in a blocking call, if appropriate.
|
|
//
|
|
|
|
if ( BlockingIllegal && WSAIsBlocking() ) {
|
|
|
|
IF_DEBUG(ENTER) {
|
|
WS_PRINT(( "SockEnterApi: in blocking call.\n" ));
|
|
}
|
|
|
|
SetLastError( WSAEINPROGRESS );
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If this is a GetXByY call, set up thread variables.
|
|
//
|
|
|
|
if ( GetXByYCall ) {
|
|
SockThreadGetXByYCancelled = FALSE;
|
|
SockThreadProcessingGetXByY = TRUE;
|
|
}
|
|
|
|
//
|
|
// Everything's cool. Proceed.
|
|
//
|
|
|
|
return TRUE;
|
|
|
|
} // SockEnterApi
|
|
|
|
#if DBG
|
|
|
|
VOID
|
|
WsAssert(
|
|
IN PVOID FailedAssertion,
|
|
IN PVOID FileName,
|
|
IN ULONG LineNumber
|
|
)
|
|
{
|
|
BOOL ok;
|
|
CHAR choice[16];
|
|
DWORD bytes;
|
|
DWORD error;
|
|
|
|
IF_DEBUG(CONSOLE) {
|
|
WS_PRINT(( "\n failed: %s\n at line %ld of %s\n",
|
|
FailedAssertion, LineNumber, FileName ));
|
|
do {
|
|
WS_PRINT(( "[B]reak/[I]gnore? " ));
|
|
bytes = sizeof(choice);
|
|
ok = ReadFile(
|
|
GetStdHandle(STD_INPUT_HANDLE),
|
|
&choice,
|
|
bytes,
|
|
&bytes,
|
|
NULL
|
|
);
|
|
if ( ok ) {
|
|
if ( toupper(choice[0]) == 'I' ) {
|
|
break;
|
|
}
|
|
if ( toupper(choice[0]) == 'B' ) {
|
|
DbgUserBreakPoint( );
|
|
}
|
|
} else {
|
|
error = GetLastError( );
|
|
}
|
|
} while ( TRUE );
|
|
|
|
return;
|
|
}
|
|
|
|
RtlAssert( FailedAssertion, FileName, LineNumber, NULL );
|
|
|
|
} // WsAssert
|
|
|
|
BOOLEAN ConsoleInitialized = FALSE;
|
|
|
|
HANDLE DebugFileHandle = INVALID_HANDLE_VALUE;
|
|
PCHAR DebugFileName = "wsdebug.log";
|
|
|
|
|
|
VOID
|
|
WsPrintf (
|
|
char *Format,
|
|
...
|
|
)
|
|
|
|
{
|
|
va_list arglist;
|
|
char OutputBuffer[1024];
|
|
ULONG length;
|
|
BOOL ret;
|
|
|
|
length = (ULONG)wsprintfA( OutputBuffer, "WSOCK32: " );
|
|
|
|
va_start( arglist, Format );
|
|
|
|
wvsprintfA( OutputBuffer + length, Format, arglist );
|
|
|
|
va_end( arglist );
|
|
|
|
IF_DEBUG(DEBUGGER) {
|
|
DbgPrint( "%s", OutputBuffer );
|
|
}
|
|
|
|
IF_DEBUG(CONSOLE) {
|
|
|
|
if ( !ConsoleInitialized ) {
|
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
|
COORD coord;
|
|
|
|
ConsoleInitialized = TRUE;
|
|
(VOID)AllocConsole( );
|
|
(VOID)GetConsoleScreenBufferInfo(
|
|
GetStdHandle(STD_OUTPUT_HANDLE),
|
|
&csbi
|
|
);
|
|
coord.X = (SHORT)(csbi.srWindow.Right - csbi.srWindow.Left + 1);
|
|
coord.Y = (SHORT)((csbi.srWindow.Bottom - csbi.srWindow.Top + 1) * 20);
|
|
(VOID)SetConsoleScreenBufferSize(
|
|
GetStdHandle(STD_OUTPUT_HANDLE),
|
|
coord
|
|
);
|
|
}
|
|
|
|
length = strlen( OutputBuffer );
|
|
|
|
ret = WriteFile(
|
|
GetStdHandle(STD_OUTPUT_HANDLE),
|
|
(LPVOID )OutputBuffer,
|
|
length,
|
|
&length,
|
|
NULL
|
|
);
|
|
if ( !ret ) {
|
|
DbgPrint( "WsPrintf: console WriteFile failed: %ld\n",
|
|
GetLastError( ) );
|
|
}
|
|
}
|
|
|
|
IF_DEBUG(FILE) {
|
|
|
|
if ( DebugFileHandle == INVALID_HANDLE_VALUE ) {
|
|
DebugFileHandle = CreateFile(
|
|
DebugFileName,
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
CREATE_ALWAYS,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
if ( DebugFileHandle == INVALID_HANDLE_VALUE ) {
|
|
|
|
DbgPrint( "WsPrintf: Failed to open winsock debug log file %s: %ld\n",
|
|
DebugFileName, GetLastError( ) );
|
|
|
|
} else {
|
|
|
|
length = strlen( OutputBuffer );
|
|
|
|
ret = WriteFile(
|
|
DebugFileHandle,
|
|
(LPVOID )OutputBuffer,
|
|
length,
|
|
&length,
|
|
NULL
|
|
);
|
|
if ( !ret ) {
|
|
DbgPrint( "WsPrintf: file WriteFile failed: %ld\n",
|
|
GetLastError( ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
} // WsPrintf
|
|
|
|
#endif
|
|
|
|
#if DBG
|
|
|
|
VOID
|
|
WsEnterApiCall (
|
|
IN PCHAR RoutineName,
|
|
IN PVOID Arg1,
|
|
IN PVOID Arg2,
|
|
IN PVOID Arg3,
|
|
IN PVOID Arg4
|
|
)
|
|
{
|
|
ULONG i;
|
|
|
|
CHECK_HEAP;
|
|
|
|
//
|
|
// If this thread has not been initialized, do it now. This is
|
|
// duplicated in SockEnterApi(), but we need it here to
|
|
// access SockIndentLevel below.
|
|
//
|
|
|
|
if ( GET_THREAD_DATA() == NULL ) {
|
|
if ( SockProcessTerminating ||
|
|
!SockThreadInitialize() ) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
IF_DEBUG(ENTER) {
|
|
for ( i = 0; i < SockIndentLevel; i++ ) {
|
|
WS_PRINT(( " " ));
|
|
}
|
|
WS_PRINT(( "---> %s() args 0x%lx 0x%lx 0x%lx 0x%lx\n",
|
|
RoutineName, Arg1, Arg2, Arg3, Arg4 ));
|
|
}
|
|
|
|
SockIndentLevel++;
|
|
|
|
return;
|
|
|
|
} // WsEnter
|
|
|
|
struct _ERROR_STRINGS {
|
|
INT ErrorCode;
|
|
PCHAR ErrorString;
|
|
} ErrorStrings[] = {
|
|
(WSABASEERR+4), "WSAEINTR",
|
|
(WSABASEERR+9), "WSAEBADF",
|
|
(WSABASEERR+13), "WSAEACCES",
|
|
(WSABASEERR+14), "WSAEFAULT",
|
|
(WSABASEERR+22), "WSAEINVAL",
|
|
(WSABASEERR+24), "WSAEMFILE",
|
|
(WSABASEERR+35), "WSAEWOULDBLOCK",
|
|
(WSABASEERR+36), "WSAEINPROGRESS",
|
|
(WSABASEERR+37), "WSAEALREADY",
|
|
(WSABASEERR+38), "WSAENOTSOCK",
|
|
(WSABASEERR+39), "WSAEDESTADDRREQ",
|
|
(WSABASEERR+40), "WSAEMSGSIZE",
|
|
(WSABASEERR+41), "WSAEPROTOTYPE",
|
|
(WSABASEERR+42), "WSAENOPROTOOPT",
|
|
(WSABASEERR+43), "WSAEPROTONOSUPPORT",
|
|
(WSABASEERR+44), "WSAESOCKTNOSUPPORT",
|
|
(WSABASEERR+45), "WSAEOPNOTSUPP",
|
|
(WSABASEERR+46), "WSAEPFNOSUPPORT",
|
|
(WSABASEERR+47), "WSAEAFNOSUPPORT",
|
|
(WSABASEERR+48), "WSAEADDRINUSE",
|
|
(WSABASEERR+49), "WSAEADDRNOTAVAIL",
|
|
(WSABASEERR+50), "WSAENETDOWN",
|
|
(WSABASEERR+51), "WSAENETUNREACH",
|
|
(WSABASEERR+52), "WSAENETRESET",
|
|
(WSABASEERR+53), "WSAECONNABORTED",
|
|
(WSABASEERR+54), "WSAECONNRESET",
|
|
(WSABASEERR+55), "WSAENOBUFS",
|
|
(WSABASEERR+56), "WSAEISCONN",
|
|
(WSABASEERR+57), "WSAENOTCONN",
|
|
(WSABASEERR+58), "WSAESHUTDOWN",
|
|
(WSABASEERR+59), "WSAETOOMANYREFS",
|
|
(WSABASEERR+60), "WSAETIMEDOUT",
|
|
(WSABASEERR+61), "WSAECONNREFUSED",
|
|
(WSABASEERR+62), "WSAELOOP",
|
|
(WSABASEERR+63), "WSAENAMETOOLONG",
|
|
(WSABASEERR+64), "WSAEHOSTDOWN",
|
|
(WSABASEERR+65), "WSAEHOSTUNREACH",
|
|
(WSABASEERR+66), "WSAENOTEMPTY",
|
|
(WSABASEERR+67), "WSAEPROCLIM",
|
|
(WSABASEERR+68), "WSAEUSERS",
|
|
(WSABASEERR+69), "WSAEDQUOT",
|
|
(WSABASEERR+70), "WSAESTALE",
|
|
(WSABASEERR+71), "WSAEREMOTE",
|
|
(WSABASEERR+101), "WSAEDISCON",
|
|
(WSABASEERR+91), "WSASYSNOTREADY",
|
|
(WSABASEERR+92), "WSAVERNOTSUPPORTED",
|
|
(WSABASEERR+93), "WSANOTINITIALISED",
|
|
NO_ERROR, "NO_ERROR"
|
|
};
|
|
|
|
|
|
PCHAR
|
|
WsGetErrorString (
|
|
IN INT Error
|
|
)
|
|
{
|
|
INT i;
|
|
|
|
for ( i = 0; ErrorStrings[i].ErrorCode != NO_ERROR; i++ ) {
|
|
if ( ErrorStrings[i].ErrorCode == Error ) {
|
|
return ErrorStrings[i].ErrorString;
|
|
}
|
|
}
|
|
|
|
return "Unknown";
|
|
|
|
} // WsGetErrorString
|
|
|
|
|
|
VOID
|
|
WsExitApiCall (
|
|
IN PCHAR RoutineName,
|
|
IN INT ReturnValue,
|
|
IN BOOLEAN Failed
|
|
|
|
)
|
|
{
|
|
ULONG i;
|
|
INT error = GetLastError( );
|
|
|
|
if( SockProcessTerminating ||
|
|
GET_THREAD_DATA() == NULL ) {
|
|
SetLastError( error );
|
|
return;
|
|
}
|
|
|
|
CHECK_HEAP;
|
|
|
|
SockIndentLevel--;
|
|
|
|
IF_DEBUG(EXIT) {
|
|
for ( i = 0; i < SockIndentLevel; i++ ) {
|
|
WS_PRINT(( " " ));
|
|
}
|
|
if ( !Failed ) {
|
|
WS_PRINT(( "<--- %s() returning %ld (0x%lx)\n",
|
|
RoutineName, ReturnValue, ReturnValue ));
|
|
} else {
|
|
|
|
PSZ errorString = WsGetErrorString( error );
|
|
|
|
WS_PRINT(( "<--- %s() FAILED--error %ld (0x%lx) == %s\n",
|
|
RoutineName, error, error, errorString ));
|
|
}
|
|
}
|
|
|
|
SetLastError( error );
|
|
|
|
return;
|
|
|
|
} // WsExitApiCall
|
|
|
|
LIST_ENTRY SockHeapListHead;
|
|
ULONG SockTotalAllocations = 0;
|
|
ULONG SockTotalFrees = 0;
|
|
ULONG SockTotalBytesAllocated = 0;
|
|
RTL_RESOURCE SocketHeapLock;
|
|
BOOLEAN SockHeapDebugInitialized = FALSE;
|
|
BOOLEAN SockDebugHeap = FALSE;
|
|
|
|
PVOID SockHeap = NULL;
|
|
PVOID SockCaller1;
|
|
PVOID SockCaller2;
|
|
BOOLEAN SockDoHeapCheck = TRUE;
|
|
BOOLEAN SockDoubleHeapCheck = FALSE;
|
|
|
|
#define WINSOCK_HEAP_CODE_1 0xabcdef00
|
|
#define WINSOCK_HEAP_CODE_2 0x12345678
|
|
#define WINSOCK_HEAP_CODE_3 0x87654321
|
|
#define WINSOCK_HEAP_CODE_4 0x00fedcba
|
|
#define WINSOCK_HEAP_CODE_5 0xa1b2c3d4
|
|
|
|
typedef struct _SOCK_HEAP_HEADER {
|
|
ULONG HeapCode1;
|
|
ULONG HeapCode2;
|
|
LIST_ENTRY GlobalHeapListEntry;
|
|
PCHAR FileName;
|
|
ULONG LineNumber;
|
|
ULONG Size;
|
|
ULONG Pad;
|
|
} SOCK_HEAP_HEADER, *PSOCK_HEAP_HEADER;
|
|
|
|
typedef struct _SOCK_HEAP_TAIL {
|
|
PSOCK_HEAP_HEADER Header;
|
|
ULONG HeapCode3;
|
|
ULONG HeapCode4;
|
|
ULONG HeapCode5;
|
|
} SOCK_HEAP_TAIL, *PSOCK_HEAP_TAIL;
|
|
|
|
#define FREE_LIST_SIZE 64
|
|
SOCK_HEAP_HEADER SockRecentFreeList[FREE_LIST_SIZE];
|
|
ULONG SockRecentFreeListIndex = 0;
|
|
|
|
|
|
VOID
|
|
SockInitializeDebugData (
|
|
VOID
|
|
)
|
|
{
|
|
RtlInitializeResource( &SocketHeapLock );
|
|
InitializeListHead( &SockHeapListHead );
|
|
|
|
} // SockInitializeDebugData
|
|
|
|
|
|
PVOID
|
|
SockAllocateHeap (
|
|
IN ULONG NumberOfBytes,
|
|
PCHAR FileName,
|
|
ULONG LineNumber
|
|
)
|
|
{
|
|
PSOCK_HEAP_HEADER header;
|
|
SOCK_HEAP_TAIL UNALIGNED *tail;
|
|
|
|
//WS_ASSERT( !SockProcessTerminating );
|
|
WS_ASSERT( (NumberOfBytes & 0xF0000000) == 0 );
|
|
WS_ASSERT( SockPrivateHeap != NULL );
|
|
|
|
SockCheckHeap( );
|
|
|
|
RtlAcquireResourceExclusive( &SocketHeapLock, TRUE );
|
|
|
|
header = RtlAllocateHeap( SockPrivateHeap, 0,
|
|
NumberOfBytes + sizeof(*header) + sizeof(*tail) );
|
|
if ( header == NULL ) {
|
|
RtlReleaseResource( &SocketHeapLock );
|
|
|
|
if( SockDoubleHeapCheck ) {
|
|
SockCheckHeap();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
header->HeapCode1 = WINSOCK_HEAP_CODE_1;
|
|
header->HeapCode2 = WINSOCK_HEAP_CODE_2;
|
|
header->FileName = FileName;
|
|
header->LineNumber = LineNumber;
|
|
header->Size = NumberOfBytes;
|
|
|
|
tail = (SOCK_HEAP_TAIL UNALIGNED *)( (PCHAR)(header + 1) + NumberOfBytes );
|
|
tail->Header = header;
|
|
tail->HeapCode3 = WINSOCK_HEAP_CODE_3;
|
|
tail->HeapCode4 = WINSOCK_HEAP_CODE_4;
|
|
tail->HeapCode5 = WINSOCK_HEAP_CODE_5;
|
|
|
|
InsertTailList( &SockHeapListHead, &header->GlobalHeapListEntry );
|
|
SockTotalAllocations++;
|
|
SockTotalBytesAllocated += header->Size;
|
|
|
|
RtlReleaseResource( &SocketHeapLock );
|
|
|
|
if( SockDoubleHeapCheck ) {
|
|
SockCheckHeap();
|
|
}
|
|
|
|
return (PVOID)(header + 1);
|
|
|
|
} // SockAllocateHeap
|
|
|
|
|
|
VOID
|
|
SockFreeHeap (
|
|
IN PVOID Pointer
|
|
)
|
|
{
|
|
PSOCK_HEAP_HEADER header = (PSOCK_HEAP_HEADER)Pointer - 1;
|
|
SOCK_HEAP_TAIL UNALIGNED * tail;
|
|
|
|
//WS_ASSERT( !SockProcessTerminating );
|
|
WS_ASSERT( SockPrivateHeap != NULL );
|
|
|
|
SockCheckHeap( );
|
|
|
|
tail = (SOCK_HEAP_TAIL UNALIGNED *)( (PCHAR)(header + 1) + header->Size );
|
|
|
|
if ( !SockHeapDebugInitialized ) {
|
|
SockInitializeDebugData( );
|
|
SockHeapDebugInitialized = TRUE;
|
|
}
|
|
|
|
RtlAcquireResourceExclusive( &SocketHeapLock, TRUE );
|
|
|
|
WS_ASSERT( header->HeapCode1 == WINSOCK_HEAP_CODE_1 );
|
|
WS_ASSERT( header->HeapCode2 == WINSOCK_HEAP_CODE_2 );
|
|
WS_ASSERT( tail->HeapCode3 == WINSOCK_HEAP_CODE_3 );
|
|
WS_ASSERT( tail->HeapCode4 == WINSOCK_HEAP_CODE_4 );
|
|
WS_ASSERT( tail->HeapCode5 == WINSOCK_HEAP_CODE_5 );
|
|
WS_ASSERT( tail->Header == header );
|
|
|
|
RemoveEntryList( &header->GlobalHeapListEntry );
|
|
SockTotalFrees++;
|
|
SockTotalBytesAllocated -= header->Size;
|
|
|
|
//RtlMoveMemory( &SockRecentFreeList[SockRecentFreeListIndex], header, sizeof(*header ) );
|
|
//SockRecentFreeListIndex++;
|
|
//if ( SockRecentFreeListIndex >= FREE_LIST_SIZE ) {
|
|
// SockRecentFreeListIndex = 0;
|
|
//}
|
|
|
|
RtlZeroMemory( header, sizeof(*header) );
|
|
|
|
header->HeapCode1 = (ULONG)~WINSOCK_HEAP_CODE_1;
|
|
header->HeapCode2 = (ULONG)~WINSOCK_HEAP_CODE_2;
|
|
tail->HeapCode3 = (ULONG)~WINSOCK_HEAP_CODE_3;
|
|
tail->HeapCode4 = (ULONG)~WINSOCK_HEAP_CODE_4;
|
|
tail->HeapCode5 = (ULONG)~WINSOCK_HEAP_CODE_5;
|
|
tail->Header = NULL;
|
|
|
|
RtlReleaseResource( &SocketHeapLock );
|
|
|
|
RtlFreeHeap( SockPrivateHeap, 0, (PVOID)header );
|
|
|
|
if( SockDoubleHeapCheck ) {
|
|
SockCheckHeap();
|
|
}
|
|
|
|
} // SockFreeHeap
|
|
|
|
|
|
VOID
|
|
SockCheckHeap (
|
|
VOID
|
|
)
|
|
{
|
|
PLIST_ENTRY listEntry;
|
|
PLIST_ENTRY lastListEntry = NULL;
|
|
PSOCK_HEAP_HEADER header;
|
|
SOCK_HEAP_TAIL UNALIGNED *tail;
|
|
|
|
if ( !SockHeapDebugInitialized ) {
|
|
SockInitializeDebugData( );
|
|
SockHeapDebugInitialized = TRUE;
|
|
//SockHeap = RtlCreateHeap( HEAP_GROWABLE, 0, 0, 0, 0, NULL );
|
|
//WS_ASSERT( SockHeap != NULL );
|
|
}
|
|
|
|
if ( !SockDoHeapCheck ) {
|
|
return;
|
|
}
|
|
|
|
RtlValidateHeap( SockPrivateHeap, 0, NULL );
|
|
|
|
RtlAcquireResourceExclusive( &SocketHeapLock, TRUE );
|
|
|
|
for ( listEntry = SockHeapListHead.Flink;
|
|
listEntry != &SockHeapListHead;
|
|
listEntry = listEntry->Flink ) {
|
|
|
|
if ( listEntry == NULL ) {
|
|
DbgPrint( "listEntry == NULL, lastListEntry == %lx\n", lastListEntry );
|
|
DbgBreakPoint( );
|
|
}
|
|
|
|
header = CONTAINING_RECORD( listEntry, SOCK_HEAP_HEADER, GlobalHeapListEntry );
|
|
tail = (SOCK_HEAP_TAIL UNALIGNED *)( (PCHAR)(header + 1) + header->Size );
|
|
|
|
if ( header->HeapCode1 != WINSOCK_HEAP_CODE_1 ) {
|
|
DbgPrint( "SockCheckHeap, fail 1, header %lx tail %lx\n", header, tail );
|
|
DbgBreakPoint( );
|
|
}
|
|
|
|
if ( header->HeapCode2 != WINSOCK_HEAP_CODE_2 ) {
|
|
DbgPrint( "SockCheckHeap, fail 2, header %lx tail %lx\n", header, tail );
|
|
DbgBreakPoint( );
|
|
}
|
|
|
|
if ( tail->HeapCode3 != WINSOCK_HEAP_CODE_3 ) {
|
|
DbgPrint( "SockCheckHeap, fail 3, header %lx tail %lx\n", header, tail );
|
|
DbgBreakPoint( );
|
|
}
|
|
|
|
if ( tail->HeapCode4 != WINSOCK_HEAP_CODE_4 ) {
|
|
DbgPrint( "SockCheckHeap, fail 4, header %lx tail %lx\n", header, tail );
|
|
DbgBreakPoint( );
|
|
}
|
|
|
|
if ( tail->HeapCode5 != WINSOCK_HEAP_CODE_5 ) {
|
|
DbgPrint( "SockCheckHeap, fail 5, header %lx tail %lx\n", header, tail );
|
|
DbgBreakPoint( );
|
|
}
|
|
|
|
if ( tail->Header != header ) {
|
|
DbgPrint( "SockCheckHeap, fail 6, header %lx tail %lx\n", header, tail );
|
|
DbgBreakPoint( );
|
|
}
|
|
|
|
lastListEntry = listEntry;
|
|
}
|
|
|
|
RtlGetCallersAddress( &SockCaller1, &SockCaller2 );
|
|
|
|
RtlReleaseResource( &SocketHeapLock );
|
|
|
|
} // SockCheckHeap
|
|
|
|
PVOID GlobalLockCaller;
|
|
PVOID GlobalLockCallersCaller;
|
|
BOOLEAN GlobalLockHeld = FALSE;
|
|
|
|
|
|
VOID
|
|
SockAcquireGlobalLockExclusive (
|
|
VOID
|
|
)
|
|
{
|
|
|
|
WS_ASSERT( !SockProcessTerminating );
|
|
|
|
EnterCriticalSection( &SocketLock );
|
|
RtlGetCallersAddress( &GlobalLockCaller, &GlobalLockCallersCaller );
|
|
GlobalLockHeld = TRUE;
|
|
|
|
} // SockAcquireGlobalLockExclusive
|
|
|
|
VOID
|
|
SockReleaseGlobalLock (
|
|
VOID
|
|
)
|
|
{
|
|
|
|
WS_ASSERT( !SockProcessTerminating );
|
|
|
|
GlobalLockHeld = TRUE;
|
|
LeaveCriticalSection( &SocketLock );
|
|
|
|
} // SockReleaseGlobalLock
|
|
|
|
#endif // if DBG
|
|
|
|
BOOL
|
|
SockThreadInitialize(
|
|
VOID
|
|
)
|
|
{
|
|
|
|
PWINSOCK_TLS_DATA data;
|
|
NTSTATUS status;
|
|
|
|
IF_DEBUG(INIT) {
|
|
WS_PRINT(( "SockThreadInitialize: TEB = %lx\n",
|
|
NtCurrentTeb( ) ));
|
|
}
|
|
|
|
//
|
|
// Allocate space for per-thread data the DLL will have.
|
|
//
|
|
|
|
data = ALLOCATE_HEAP( sizeof(*data) );
|
|
if ( data == NULL ) {
|
|
WS_PRINT(( "SockThreadInitialize: unable to allocate thread data.\n" ));
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Store a pointer to this data area in TLS.
|
|
//
|
|
|
|
if( !SET_THREAD_DATA(data) ) {
|
|
|
|
WS_PRINT(( "SockThreadInitialize: TlsSetValue failed: %ld\n", GetLastError( ) ));
|
|
#if !defined(USE_TEB_FIELD)
|
|
SockTlsSlot = 0xFFFFFFFF;
|
|
#endif // !USE_TEB_FIELD
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Initialize the thread data.
|
|
//
|
|
|
|
RtlZeroMemory( data, sizeof(*data) );
|
|
|
|
data->R_INIT__res.retrans = RES_TIMEOUT;
|
|
data->R_INIT__res.retry = 4;
|
|
data->R_INIT__res.options = RES_DEFAULT;
|
|
|
|
#if DBG
|
|
SockIndentLevel = 0;
|
|
#endif
|
|
|
|
return TRUE;
|
|
|
|
} // SockThreadInitialize
|
|
|