Added support for calling the TLS callback functions.

This commit is contained in:
Alexandre Julliard 2003-05-08 04:13:26 +00:00
parent b203b060c1
commit d9bab57477
4 changed files with 50 additions and 28 deletions

View File

@ -55,6 +55,14 @@ static WINE_EXCEPTION_FILTER(page_fault)
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
} }
static const char * const reason_names[] =
{
"PROCESS_DETACH",
"PROCESS_ATTACH",
"THREAD_ATTACH",
"THREAD_DETACH"
};
static CRITICAL_SECTION loader_section = CRITICAL_SECTION_INIT( "loader_section" ); static CRITICAL_SECTION loader_section = CRITICAL_SECTION_INIT( "loader_section" );
static WINE_MODREF *cached_modref; static WINE_MODREF *cached_modref;
static WINE_MODREF *current_modref; static WINE_MODREF *current_modref;
@ -388,13 +396,37 @@ WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename )
return wm; return wm;
} }
/*************************************************************************
* call_tls_callbacks
*/
static void call_tls_callbacks( HMODULE module, UINT reason )
{
const IMAGE_TLS_DIRECTORY *dir;
const PIMAGE_TLS_CALLBACK *callback;
ULONG dirsize;
dir = RtlImageDirectoryEntryToData( module, TRUE, IMAGE_DIRECTORY_ENTRY_TLS, &dirsize );
if (!dir || !dir->AddressOfCallBacks) return;
for (callback = dir->AddressOfCallBacks; *callback; callback++)
{
if (TRACE_ON(relay))
DPRINTF("%04lx:Call TLS callback (proc=%p,module=%p,reason=%s,reserved=0)\n",
GetCurrentThreadId(), *callback, module, reason_names[reason] );
(*callback)( module, reason, NULL );
if (TRACE_ON(relay))
DPRINTF("%04lx:Ret TLS callback (proc=%p,module=%p,reason=%s,reserved=0)\n",
GetCurrentThreadId(), *callback, module, reason_names[reason] );
}
}
/************************************************************************* /*************************************************************************
* MODULE_InitDLL * MODULE_InitDLL
*/ */
static BOOL MODULE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved ) static BOOL MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved )
{ {
static const char * const typeName[] = { "PROCESS_DETACH", "PROCESS_ATTACH",
"THREAD_ATTACH", "THREAD_DETACH" };
char mod_name[32]; char mod_name[32];
BOOL retv = TRUE; BOOL retv = TRUE;
DLLENTRYPROC entry = wm->ldr.EntryPoint; DLLENTRYPROC entry = wm->ldr.EntryPoint;
@ -403,6 +435,7 @@ static BOOL MODULE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved )
/* Skip calls for modules loaded with special load flags */ /* Skip calls for modules loaded with special load flags */
if (wm->ldr.Flags & LDR_DONT_RESOLVE_REFS) return TRUE; if (wm->ldr.Flags & LDR_DONT_RESOLVE_REFS) return TRUE;
if (wm->ldr.TlsIndex != -1) call_tls_callbacks( wm->ldr.BaseAddress, reason );
if (!entry || !(wm->ldr.Flags & LDR_IMAGE_IS_DLL)) return TRUE; if (!entry || !(wm->ldr.Flags & LDR_IMAGE_IS_DLL)) return TRUE;
if (TRACE_ON(relay)) if (TRACE_ON(relay))
@ -410,20 +443,20 @@ static BOOL MODULE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved )
size_t len = max( strlen(wm->modname), sizeof(mod_name)-1 ); size_t len = max( strlen(wm->modname), sizeof(mod_name)-1 );
memcpy( mod_name, wm->modname, len ); memcpy( mod_name, wm->modname, len );
mod_name[len] = 0; mod_name[len] = 0;
DPRINTF("%04lx:Call PE DLL (proc=%p,module=%p (%s),type=%ld,res=%p)\n", DPRINTF("%04lx:Call PE DLL (proc=%p,module=%p (%s),reason=%s,res=%p)\n",
GetCurrentThreadId(), entry, module, mod_name, type, lpReserved ); GetCurrentThreadId(), entry, module, mod_name, reason_names[reason], lpReserved );
} }
else TRACE("(%p (%s),%s,%p) - CALL\n", module, wm->modname, typeName[type], lpReserved ); else TRACE("(%p (%s),%s,%p) - CALL\n", module, wm->modname, reason_names[reason], lpReserved );
retv = entry( module, type, lpReserved ); retv = entry( module, reason, lpReserved );
/* The state of the module list may have changed due to the call /* The state of the module list may have changed due to the call
to the dll. We cannot assume that this module has not been to the dll. We cannot assume that this module has not been
deleted. */ deleted. */
if (TRACE_ON(relay)) if (TRACE_ON(relay))
DPRINTF("%04lx:Ret PE DLL (proc=%p,module=%p (%s),type=%ld,res=%p) retval=%x\n", DPRINTF("%04lx:Ret PE DLL (proc=%p,module=%p (%s),reason=%s,res=%p) retval=%x\n",
GetCurrentThreadId(), entry, module, mod_name, type, lpReserved, retv ); GetCurrentThreadId(), entry, module, mod_name, reason_names[reason], lpReserved, retv );
else TRACE("(%p,%s,%p) - RETURN %d\n", module, typeName[type], lpReserved, retv ); else TRACE("(%p,%s,%p) - RETURN %d\n", module, reason_names[reason], lpReserved, retv );
return retv; return retv;
} }
@ -526,7 +559,7 @@ BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
* sequence at MODULE_DllProcessAttach. Unless the bForceDetach flag * sequence at MODULE_DllProcessAttach. Unless the bForceDetach flag
* is set, only DLLs with zero refcount are notified. * is set, only DLLs with zero refcount are notified.
*/ */
void MODULE_DllProcessDetach( BOOL bForceDetach, LPVOID lpReserved ) static void MODULE_DllProcessDetach( BOOL bForceDetach, LPVOID lpReserved )
{ {
WINE_MODREF *wm; WINE_MODREF *wm;
@ -603,7 +636,7 @@ NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE hModule)
RtlEnterCriticalSection( &loader_section ); RtlEnterCriticalSection( &loader_section );
wm = get_modref( hModule ); wm = get_modref( hModule );
if ( !wm ) if (!wm || wm->ldr.TlsIndex != -1)
ret = STATUS_DLL_NOT_FOUND; ret = STATUS_DLL_NOT_FOUND;
else else
wm->ldr.Flags |= LDR_NO_DLL_CALLS; wm->ldr.Flags |= LDR_NO_DLL_CALLS;
@ -1065,24 +1098,23 @@ NTSTATUS WINAPI LdrQueryProcessModuleInformation(PSYSTEM_MODULE_INFORMATION smi,
* LdrShutdownProcess (NTDLL.@) * LdrShutdownProcess (NTDLL.@)
* *
*/ */
NTSTATUS WINAPI LdrShutdownProcess(void) void WINAPI LdrShutdownProcess(void)
{ {
TRACE("()\n"); TRACE("()\n");
MODULE_DllProcessDetach( TRUE, (LPVOID)1 ); MODULE_DllProcessDetach( TRUE, (LPVOID)1 );
return STATUS_SUCCESS; /* FIXME */
} }
/****************************************************************** /******************************************************************
* LdrShutdownThread (NTDLL.@) * LdrShutdownThread (NTDLL.@)
* *
*/ */
NTSTATUS WINAPI LdrShutdownThread(void) void WINAPI LdrShutdownThread(void)
{ {
WINE_MODREF *wm; WINE_MODREF *wm;
TRACE("()\n"); TRACE("()\n");
/* don't do any detach calls if process is exiting */ /* don't do any detach calls if process is exiting */
if (process_detaching) return STATUS_SUCCESS; if (process_detaching) return;
/* FIXME: there is still a race here */ /* FIXME: there is still a race here */
RtlEnterCriticalSection( &loader_section ); RtlEnterCriticalSection( &loader_section );
@ -1098,7 +1130,6 @@ NTSTATUS WINAPI LdrShutdownThread(void)
} }
RtlLeaveCriticalSection( &loader_section ); RtlLeaveCriticalSection( &loader_section );
return STATUS_SUCCESS; /* FIXME */
} }
/*********************************************************************** /***********************************************************************

View File

@ -182,7 +182,6 @@ enum binary_type
/* module.c */ /* module.c */
extern BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved ); extern BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved );
extern void MODULE_DllProcessDetach( BOOL bForceDetach, LPVOID lpReserved );
extern void MODULE_DllThreadAttach( LPVOID lpReserved ); extern void MODULE_DllThreadAttach( LPVOID lpReserved );
extern WINE_MODREF *MODULE_FindModule( LPCSTR path ); extern WINE_MODREF *MODULE_FindModule( LPCSTR path );
extern HMODULE16 MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 ); extern HMODULE16 MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 );

View File

@ -844,6 +844,8 @@ void WINAPIV DbgPrint(LPCSTR fmt, ...);
NTSTATUS WINAPI LdrAccessResource(HMODULE,const IMAGE_RESOURCE_DATA_ENTRY*,void**,PULONG); NTSTATUS WINAPI LdrAccessResource(HMODULE,const IMAGE_RESOURCE_DATA_ENTRY*,void**,PULONG);
NTSTATUS WINAPI LdrFindResourceDirectory_U(HMODULE,const LDR_RESOURCE_INFO*,ULONG,const IMAGE_RESOURCE_DIRECTORY**); NTSTATUS WINAPI LdrFindResourceDirectory_U(HMODULE,const LDR_RESOURCE_INFO*,ULONG,const IMAGE_RESOURCE_DIRECTORY**);
NTSTATUS WINAPI LdrFindResource_U(HMODULE,const LDR_RESOURCE_INFO*,ULONG,const IMAGE_RESOURCE_DATA_ENTRY**); NTSTATUS WINAPI LdrFindResource_U(HMODULE,const LDR_RESOURCE_INFO*,ULONG,const IMAGE_RESOURCE_DATA_ENTRY**);
void WINAPI LdrShutdownProcess(void);
void WINAPI LdrShutdownThread(void);
NTSTATUS WINAPI NtAccessCheck(PSECURITY_DESCRIPTOR,HANDLE,ACCESS_MASK,PGENERIC_MAPPING,PPRIVILEGE_SET,PULONG,PULONG,PBOOLEAN); NTSTATUS WINAPI NtAccessCheck(PSECURITY_DESCRIPTOR,HANDLE,ACCESS_MASK,PGENERIC_MAPPING,PPRIVILEGE_SET,PULONG,PULONG,PBOOLEAN);
NTSTATUS WINAPI NtAdjustPrivilegesToken(HANDLE,BOOLEAN,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD); NTSTATUS WINAPI NtAdjustPrivilegesToken(HANDLE,BOOLEAN,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD);
NTSTATUS WINAPI NtAllocateVirtualMemory(HANDLE,PVOID*,PVOID,ULONG*,ULONG,ULONG); NTSTATUS WINAPI NtAllocateVirtualMemory(HANDLE,PVOID*,PVOID,ULONG*,ULONG,ULONG);
@ -1277,8 +1279,6 @@ NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE, PANSI_STRING, ULONG, void**);
NTSTATUS WINAPI LdrLoadDll(LPCWSTR, DWORD, PUNICODE_STRING, HMODULE*); NTSTATUS WINAPI LdrLoadDll(LPCWSTR, DWORD, PUNICODE_STRING, HMODULE*);
NTSTATUS WINAPI LdrLockLoaderLock(ULONG,ULONG*,ULONG*); NTSTATUS WINAPI LdrLockLoaderLock(ULONG,ULONG*,ULONG*);
NTSTATUS WINAPI LdrQueryProcessModuleInformation(SYSTEM_MODULE_INFORMATION*, ULONG, ULONG*); NTSTATUS WINAPI LdrQueryProcessModuleInformation(SYSTEM_MODULE_INFORMATION*, ULONG, ULONG*);
NTSTATUS WINAPI LdrShutdownProcess(void);
NTSTATUS WINAPI LdrShutdownThread(void);
NTSTATUS WINAPI LdrUnloadDll(HMODULE); NTSTATUS WINAPI LdrUnloadDll(HMODULE);
NTSTATUS WINAPI LdrUnlockLoaderLock(ULONG,ULONG); NTSTATUS WINAPI LdrUnlockLoaderLock(ULONG,ULONG);

View File

@ -421,14 +421,6 @@ void PE_InitTls( void )
NtAllocateVirtualMemory( GetCurrentProcess(), &mem, NULL, &size, NtAllocateVirtualMemory( GetCurrentProcess(), &mem, NULL, &size,
MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE ); MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
memcpy(mem,_fixup_address(&(peh->OptionalHeader),delta,(LPVOID)pdir->StartAddressOfRawData),datasize); memcpy(mem,_fixup_address(&(peh->OptionalHeader),delta,(LPVOID)pdir->StartAddressOfRawData),datasize);
if (pdir->AddressOfCallBacks) {
PIMAGE_TLS_CALLBACK *cbs;
cbs = _fixup_address(&(peh->OptionalHeader),delta,pdir->AddressOfCallBacks);
if (*cbs)
FIXME("TLS Callbacks aren't going to be called\n");
}
TlsSetValue( wm->ldr.TlsIndex, mem ); TlsSetValue( wm->ldr.TlsIndex, mem );
} }
} }