Added support for calling the TLS callback functions.
This commit is contained in:
parent
b203b060c1
commit
d9bab57477
|
@ -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 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
@ -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, ...);
|
||||||
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);
|
||||||
|
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue