Commit d9bab574 authored by Alexandre Julliard's avatar Alexandre Julliard

Added support for calling the TLS callback functions.

parent b203b060
...@@ -55,6 +55,14 @@ static WINE_EXCEPTION_FILTER(page_fault) ...@@ -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 ) ...@@ -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 ) ...@@ -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 ) ...@@ -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 ) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -1098,7 +1130,6 @@ NTSTATUS WINAPI LdrShutdownThread(void)
} }
RtlLeaveCriticalSection( &loader_section ); RtlLeaveCriticalSection( &loader_section );
return STATUS_SUCCESS; /* FIXME */
} }
/*********************************************************************** /***********************************************************************
......
...@@ -182,7 +182,6 @@ enum binary_type ...@@ -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 );
......
...@@ -844,6 +844,8 @@ void WINAPIV DbgPrint(LPCSTR fmt, ...); ...@@ -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**); ...@@ -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);
......
...@@ -421,14 +421,6 @@ void PE_InitTls( void ) ...@@ -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 );
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment