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)
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 WINE_MODREF *cached_modref;
static WINE_MODREF *current_modref;
......@@ -388,13 +396,37 @@ WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename )
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
*/
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];
BOOL retv = TRUE;
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 */
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 (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 );
memcpy( mod_name, wm->modname, len );
mod_name[len] = 0;
DPRINTF("%04lx:Call PE DLL (proc=%p,module=%p (%s),type=%ld,res=%p)\n",
GetCurrentThreadId(), entry, module, mod_name, type, lpReserved );
DPRINTF("%04lx:Call PE DLL (proc=%p,module=%p (%s),reason=%s,res=%p)\n",
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
to the dll. We cannot assume that this module has not been
deleted. */
if (TRACE_ON(relay))
DPRINTF("%04lx:Ret PE DLL (proc=%p,module=%p (%s),type=%ld,res=%p) retval=%x\n",
GetCurrentThreadId(), entry, module, mod_name, type, lpReserved, retv );
else TRACE("(%p,%s,%p) - RETURN %d\n", module, typeName[type], lpReserved, retv );
DPRINTF("%04lx:Ret PE DLL (proc=%p,module=%p (%s),reason=%s,res=%p) retval=%x\n",
GetCurrentThreadId(), entry, module, mod_name, reason_names[reason], lpReserved, retv );
else TRACE("(%p,%s,%p) - RETURN %d\n", module, reason_names[reason], lpReserved, retv );
return retv;
}
......@@ -526,7 +559,7 @@ BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
* sequence at MODULE_DllProcessAttach. Unless the bForceDetach flag
* 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;
......@@ -603,7 +636,7 @@ NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE hModule)
RtlEnterCriticalSection( &loader_section );
wm = get_modref( hModule );
if ( !wm )
if (!wm || wm->ldr.TlsIndex != -1)
ret = STATUS_DLL_NOT_FOUND;
else
wm->ldr.Flags |= LDR_NO_DLL_CALLS;
......@@ -1065,24 +1098,23 @@ NTSTATUS WINAPI LdrQueryProcessModuleInformation(PSYSTEM_MODULE_INFORMATION smi,
* LdrShutdownProcess (NTDLL.@)
*
*/
NTSTATUS WINAPI LdrShutdownProcess(void)
void WINAPI LdrShutdownProcess(void)
{
TRACE("()\n");
MODULE_DllProcessDetach( TRUE, (LPVOID)1 );
return STATUS_SUCCESS; /* FIXME */
}
/******************************************************************
* LdrShutdownThread (NTDLL.@)
*
*/
NTSTATUS WINAPI LdrShutdownThread(void)
void WINAPI LdrShutdownThread(void)
{
WINE_MODREF *wm;
TRACE("()\n");
/* 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 */
RtlEnterCriticalSection( &loader_section );
......@@ -1098,7 +1130,6 @@ NTSTATUS WINAPI LdrShutdownThread(void)
}
RtlLeaveCriticalSection( &loader_section );
return STATUS_SUCCESS; /* FIXME */
}
/***********************************************************************
......
......@@ -182,7 +182,6 @@ enum binary_type
/* module.c */
extern BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved );
extern void MODULE_DllProcessDetach( BOOL bForceDetach, LPVOID lpReserved );
extern void MODULE_DllThreadAttach( LPVOID lpReserved );
extern WINE_MODREF *MODULE_FindModule( LPCSTR path );
extern HMODULE16 MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 );
......
......@@ -844,6 +844,8 @@ void WINAPIV DbgPrint(LPCSTR fmt, ...);
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 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 NtAdjustPrivilegesToken(HANDLE,BOOLEAN,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD);
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 LdrLockLoaderLock(ULONG,ULONG*,ULONG*);
NTSTATUS WINAPI LdrQueryProcessModuleInformation(SYSTEM_MODULE_INFORMATION*, ULONG, ULONG*);
NTSTATUS WINAPI LdrShutdownProcess(void);
NTSTATUS WINAPI LdrShutdownThread(void);
NTSTATUS WINAPI LdrUnloadDll(HMODULE);
NTSTATUS WINAPI LdrUnlockLoaderLock(ULONG,ULONG);
......
......@@ -421,14 +421,6 @@ void PE_InitTls( void )
NtAllocateVirtualMemory( GetCurrentProcess(), &mem, NULL, &size,
MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
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 );
}
}
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