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.
317 lines
6.1 KiB
317 lines
6.1 KiB
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
init.c
|
|
|
|
Abstract:
|
|
|
|
This module contains DLL initialization code for the Winsock 2
|
|
to Winsock 1.1 Mapper Service Provider.
|
|
|
|
Author:
|
|
|
|
Keith Moore (keithmo) 29-May-1996
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
|
|
BOOL
|
|
SockInitializeDll(
|
|
IN PVOID DllHandle,
|
|
IN ULONG Reason,
|
|
IN PVOID Context OPTIONAL
|
|
)
|
|
{
|
|
|
|
//
|
|
// On a thread detach, set up the context param so that all
|
|
// necessary deallocations will occur.
|
|
//
|
|
|
|
if( Reason == DLL_THREAD_DETACH ) {
|
|
|
|
Context = NULL;
|
|
|
|
}
|
|
|
|
switch( Reason ) {
|
|
|
|
case DLL_PROCESS_ATTACH:
|
|
|
|
//
|
|
// Remember our module handle.
|
|
//
|
|
|
|
SockModuleHandle = (HMODULE)DllHandle;
|
|
|
|
#if DBG || ENABLE_CS_DEBUG
|
|
SockInitializeDebugData();
|
|
#endif // DBG || ENABLE_CS_DEBUG
|
|
|
|
#if DBG
|
|
//
|
|
// If there is a file in the current directory called "ws2map.dbg"
|
|
// open it and read the first line to set the debugging flags.
|
|
//
|
|
|
|
{
|
|
HANDLE handle;
|
|
|
|
handle = CreateFile(
|
|
"ws2map.dbg",
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
if( handle == INVALID_HANDLE_VALUE ) {
|
|
|
|
//
|
|
// Set default value.
|
|
//
|
|
|
|
SockDebugFlags = SOCK_DEBUG_DEBUGGER;
|
|
|
|
} else {
|
|
|
|
CHAR buffer[11];
|
|
DWORD bytesRead;
|
|
|
|
ZeroMemory( buffer, sizeof(buffer) );
|
|
|
|
if( ReadFile( handle, buffer, 10, &bytesRead, NULL ) ) {
|
|
|
|
buffer[bytesRead] = '\0';
|
|
|
|
SockDebugFlags = strtoul( buffer, NULL, 16 );
|
|
|
|
} else {
|
|
|
|
SOCK_PRINT((
|
|
"read file failed: %ld\n",
|
|
GetLastError()
|
|
));
|
|
|
|
}
|
|
|
|
CloseHandle( handle );
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
IF_DEBUG(INIT) {
|
|
|
|
SOCK_PRINT((
|
|
"SockInitializeDll: process attach, PID = %lx\n",
|
|
GetCurrentProcessId()
|
|
));
|
|
|
|
}
|
|
|
|
//
|
|
// Initialize the global lists.
|
|
//
|
|
|
|
InitializeListHead( &SockGlobalSocketListHead );
|
|
InitializeListHead( &SockHookerListHead );
|
|
|
|
//
|
|
// *** lock acquisition order: it is legal to acquire SockGlobalLock
|
|
// while holding an individual socket lock, but not the other way
|
|
// around!
|
|
//
|
|
|
|
SockInitializeCriticalSection( &SockGlobalLock );
|
|
|
|
//
|
|
// Allocate space in TLS.
|
|
//
|
|
|
|
SockTlsSlot = TlsAlloc( );
|
|
|
|
if( SockTlsSlot == TLS_OUT_OF_INDEXES ) {
|
|
|
|
SOCK_PRINT((
|
|
"SockInitializeDll: TlsAlloc failed: %ld\n",
|
|
GetLastError()
|
|
));
|
|
|
|
SockDeleteCriticalSection( &SockGlobalLock );
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
|
|
IF_DEBUG(INIT) {
|
|
|
|
SOCK_PRINT((
|
|
"SockInitializeDll: process detach, PID = %lx\n",
|
|
GetCurrentProcessId()
|
|
));
|
|
|
|
}
|
|
|
|
//
|
|
// Only clean up resources if we're being called because of a
|
|
// FreeLibrary(). If this is because of process termination,
|
|
// do not clean up, as the system will do it for us. Also,
|
|
// if we get called at process termination, it is likely that
|
|
// a thread was terminated while it held a winsock lock, which
|
|
// would cause a deadlock if we then tried to grab the lock.
|
|
//
|
|
|
|
if( Context == NULL ) {
|
|
|
|
INT errTmp;
|
|
|
|
WSPCleanup( &errTmp );
|
|
SockDeleteCriticalSection( &SockGlobalLock );
|
|
|
|
}
|
|
|
|
SockProcessTerminating = TRUE;
|
|
|
|
//
|
|
// Fall through...
|
|
//
|
|
|
|
case DLL_THREAD_DETACH:
|
|
|
|
IF_DEBUG(INIT) {
|
|
|
|
SOCK_PRINT((
|
|
"SockInitializeDll: thread detach, TID = %lx\n",
|
|
GetCurrentThreadId()
|
|
));
|
|
|
|
}
|
|
|
|
//
|
|
// If the TLS information for this thread has been initialized,
|
|
// free the thread data buffer.
|
|
//
|
|
|
|
if( Context == NULL &&
|
|
SOCK_GET_THREAD_DATA() != NULL ) {
|
|
|
|
SOCK_FREE_HEAP( SOCK_GET_THREAD_DATA() );
|
|
SOCK_SET_THREAD_DATA( NULL );
|
|
|
|
}
|
|
|
|
//
|
|
// If this is a process detach, free the TLS slot we're using.
|
|
//
|
|
|
|
if( Reason == DLL_PROCESS_DETACH && Context == NULL ) {
|
|
|
|
if ( SockTlsSlot != TLS_OUT_OF_INDEXES ) {
|
|
|
|
SOCK_REQUIRE( TlsFree( SockTlsSlot ) );
|
|
SockTlsSlot = TLS_OUT_OF_INDEXES;
|
|
|
|
}
|
|
|
|
//
|
|
// Also kill the async helper window.
|
|
//
|
|
|
|
SockDestroyAsyncWindow();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
break;
|
|
|
|
default:
|
|
SOCK_ASSERT( FALSE );
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
} // SockInitializeDll
|
|
|
|
|
|
|
|
BOOL
|
|
SockInitializeThread(
|
|
VOID
|
|
)
|
|
{
|
|
|
|
PSOCK_TLS_DATA tlsData;
|
|
|
|
IF_DEBUG(INIT) {
|
|
|
|
SOCK_PRINT((
|
|
"SockInitializeThread: TID = %lx\n",
|
|
GetCurrentThreadId()
|
|
));
|
|
|
|
}
|
|
|
|
//
|
|
// Allocate space for per-thread data the DLL will have.
|
|
//
|
|
|
|
tlsData = SOCK_ALLOCATE_HEAP( sizeof(*tlsData) );
|
|
|
|
if( tlsData == NULL ) {
|
|
|
|
SOCK_PRINT((
|
|
"SockInitializeThread: unable to allocate thread data.\n"
|
|
));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
//
|
|
// Initialize the thread data.
|
|
//
|
|
|
|
ZeroMemory(
|
|
tlsData,
|
|
sizeof(*tlsData)
|
|
);
|
|
|
|
//
|
|
// Store a pointer to this data area in TLS.
|
|
//
|
|
|
|
if( !SOCK_SET_THREAD_DATA(tlsData) ) {
|
|
|
|
SOCK_PRINT((
|
|
"SockInitializeThread: TlsSetValue() failed: %d\n",
|
|
GetLastError()
|
|
));
|
|
|
|
SOCK_FREE_HEAP( tlsData );
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
} // SockInitializeThread
|
|
|