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.
323 lines
7.6 KiB
323 lines
7.6 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
init.h
|
|
|
|
Abstract:
|
|
|
|
This module contains initialization code for WinSock.DLL.
|
|
|
|
Author:
|
|
|
|
David Treadwell (davidtr) 20-Feb-1992
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "winsockp.h"
|
|
#include <stdlib.h>
|
|
|
|
BOOL
|
|
SockInitialize (
|
|
IN PVOID DllHandle,
|
|
IN ULONG Reason,
|
|
IN PVOID Context OPTIONAL
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
SYSTEM_INFO systemInfo;
|
|
DWORD error;
|
|
BOOL success;
|
|
NT_PRODUCT_TYPE productType;
|
|
|
|
//
|
|
// 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
|
|
//
|
|
// If there is a file in the current directory called "msafddebug"
|
|
// open it and read the first line to set the debugging flags.
|
|
//
|
|
|
|
{
|
|
HANDLE handle;
|
|
|
|
handle = CreateFile(
|
|
"MsafdDebug",
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
if( handle == INVALID_HANDLE_VALUE ) {
|
|
|
|
//
|
|
// Set default value.
|
|
//
|
|
|
|
WsDebug = WINSOCK_DEBUG_DEBUGGER;
|
|
|
|
} else {
|
|
|
|
CHAR buffer[11];
|
|
DWORD bytesRead;
|
|
|
|
RtlZeroMemory( buffer, sizeof(buffer) );
|
|
|
|
if ( ReadFile( handle, buffer, 10, &bytesRead, NULL ) ) {
|
|
|
|
buffer[bytesRead] = '\0';
|
|
|
|
WsDebug = strtoul( buffer, NULL, 16 );
|
|
|
|
} else {
|
|
|
|
WS_PRINT(( "read file failed: %ld\n", GetLastError( ) ));
|
|
}
|
|
|
|
CloseHandle( handle );
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
IF_DEBUG(INIT) {
|
|
WS_PRINT(( "SockInitialize: process attach, PEB = %lx\n",
|
|
NtCurrentPeb( ) ));
|
|
}
|
|
|
|
//
|
|
// Initialize the lists of sockets and helper DLLs.
|
|
//
|
|
|
|
InitializeListHead( &SockHelperDllListHead );
|
|
InitializeListHead( &SocketListHead );
|
|
|
|
//
|
|
// *** lock acquisition order: it is legal to acquire SocketLock
|
|
// while holding an individual socket lock, but not the other way
|
|
// around!
|
|
//
|
|
|
|
try {
|
|
|
|
SockInitializeCriticalSection( &SocketLock );
|
|
error = NO_ERROR;
|
|
|
|
} except( SOCK_EXCEPTION_FILTER() ) {
|
|
|
|
error = GetExceptionCode();
|
|
|
|
}
|
|
|
|
if( error != NO_ERROR ) {
|
|
|
|
WS_PRINT(( "SockInitialize: InitializeCriticalSection; %ld\n", error ));
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
error = WahCreateContextTable(
|
|
&SockContextTable,
|
|
0
|
|
);
|
|
|
|
if( error != NO_ERROR ) {
|
|
|
|
WS_PRINT(( "SockInitialize: WahCreateContextTable failed; %ld\n", error ));
|
|
SockDeleteCriticalSection( &SocketLock );
|
|
return FALSE;
|
|
}
|
|
|
|
#if !defined(USE_TEB_FIELD)
|
|
//
|
|
// Allocate space in TLS so that we can convert global variables
|
|
// to thread variables.
|
|
//
|
|
|
|
SockTlsSlot = TlsAlloc( );
|
|
|
|
if ( SockTlsSlot == 0xFFFFFFFF ) {
|
|
|
|
WS_PRINT(( "SockInitialize: TlsAlloc failed: %ld\n", GetLastError( ) ));
|
|
SockDeleteCriticalSection( &SocketLock );
|
|
WahDestroyContextTable( SockContextTable );
|
|
return FALSE;
|
|
}
|
|
#endif // !USE_TEB_FIELD
|
|
|
|
//
|
|
// Create private WinSock heap on MP machines. UP machines
|
|
// just use the process heap.
|
|
//
|
|
|
|
GetSystemInfo( &systemInfo );
|
|
|
|
if( systemInfo.dwNumberOfProcessors > 1 ) {
|
|
|
|
SockPrivateHeap = RtlCreateHeap( HEAP_GROWABLE | // Flags
|
|
HEAP_CLASS_1,
|
|
NULL, // HeapBase
|
|
0, // ReserveSize
|
|
0, // CommitSize
|
|
NULL, // Lock
|
|
NULL ); // Parameters
|
|
|
|
} else {
|
|
|
|
WS_ASSERT( SockPrivateHeap == NULL );
|
|
|
|
}
|
|
|
|
if ( SockPrivateHeap == NULL ) {
|
|
|
|
//
|
|
// This is either a UP box, or RtlCreateHeap() failed. In
|
|
// either case, just use the process heap.
|
|
//
|
|
|
|
SockPrivateHeap = RtlProcessHeap();
|
|
|
|
}
|
|
|
|
//
|
|
// Remember the NT product type that we're running on. We gab
|
|
// it here for efficiency, and use it to tune some parameters on
|
|
// the workstation vs. server product types.
|
|
//
|
|
|
|
success = RtlGetNtProductType( &productType );
|
|
|
|
if ( !success || productType == NtProductWinNt ) {
|
|
|
|
SockProductTypeWorkstation = TRUE;
|
|
|
|
} else {
|
|
|
|
SockProductTypeWorkstation = FALSE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
|
|
IF_DEBUG(INIT) {
|
|
WS_PRINT(( "SockInitialize: process detach, PEB = %lx\n",
|
|
NtCurrentPeb( ) ));
|
|
}
|
|
|
|
//
|
|
// 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( &SocketLock );
|
|
|
|
if( SockContextTable != NULL ) {
|
|
WahDestroyContextTable( SockContextTable );
|
|
}
|
|
}
|
|
|
|
SockProcessTerminating = TRUE;
|
|
|
|
// *** lack of break is intentional!
|
|
|
|
case DLL_THREAD_DETACH:
|
|
|
|
IF_DEBUG(INIT) {
|
|
WS_PRINT(( "SockInitialize: thread detach, TEB = %lx\n",
|
|
NtCurrentTeb( ) ));
|
|
}
|
|
|
|
//
|
|
// If the TLS information for this thread has been initialized,
|
|
// close the thread event and free the thread data buffer.
|
|
//
|
|
|
|
if ( Context == NULL &&
|
|
GET_THREAD_DATA() != NULL ) {
|
|
|
|
NtClose( SockThreadEvent );
|
|
FREE_THREAD_DATA( GET_THREAD_DATA() );
|
|
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 !defined(USE_TEB_FIELD)
|
|
if ( SockTlsSlot != 0xFFFFFFFF ) {
|
|
|
|
BOOLEAN ret;
|
|
|
|
ret = TlsFree( SockTlsSlot );
|
|
WS_ASSERT( ret );
|
|
|
|
SockTlsSlot = 0xFFFFFFFF;
|
|
}
|
|
#endif // !USE_TEB_FIELD
|
|
|
|
//
|
|
// Also destroy any private WinSock heap.
|
|
//
|
|
|
|
if ( SockPrivateHeap != RtlProcessHeap() ) {
|
|
|
|
WS_ASSERT( SockPrivateHeap != NULL );
|
|
RtlDestroyHeap( SockPrivateHeap );
|
|
SockPrivateHeap = NULL;
|
|
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
break;
|
|
|
|
default:
|
|
|
|
WS_ASSERT( FALSE );
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
} // SockInitialize
|
|
|