mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-05 18:09:24 +00:00
Fixed sequence of DLL_PROCESS_DETACH notification calls.
Moved PE_MODREF flags to WINE_MODREF level. Better handling of LoadLibraryEx flags. PE_InitTls() changed to work only on the current thread.
This commit is contained in:
parent
1c40024b15
commit
e469a583ca
|
@ -111,6 +111,7 @@ typedef enum { MODULE32_PE=1, MODULE32_ELF /* ,... */ } MODULE32_TYPE;
|
|||
typedef struct _wine_modref
|
||||
{
|
||||
struct _wine_modref *next;
|
||||
struct _wine_modref *prev;
|
||||
MODULE32_TYPE type;
|
||||
union {
|
||||
PE_MODREF pe;
|
||||
|
@ -121,13 +122,24 @@ typedef struct _wine_modref
|
|||
|
||||
int nDeps;
|
||||
struct _wine_modref **deps;
|
||||
int initDone;
|
||||
|
||||
int flags;
|
||||
int refCount;
|
||||
|
||||
char *modname;
|
||||
char *shortname;
|
||||
char *longname;
|
||||
} WINE_MODREF;
|
||||
|
||||
#define WINE_MODREF_INTERNAL 0x00000001
|
||||
#define WINE_MODREF_NO_DLL_CALLS 0x00000002
|
||||
#define WINE_MODREF_PROCESS_ATTACHED 0x00000004
|
||||
#define WINE_MODREF_PROCESS_DETACHED 0x00000008
|
||||
#define WINE_MODREF_LOAD_AS_DATAFILE 0x00000010
|
||||
#define WINE_MODREF_DONT_RESOLVE_REFS 0x00000020
|
||||
#define WINE_MODREF_MARKER 0x80000000
|
||||
|
||||
|
||||
|
||||
/* Resource types */
|
||||
typedef struct resource_typeinfo_s NE_TYPEINFO;
|
||||
|
|
|
@ -11,12 +11,6 @@ typedef struct {
|
|||
PIMAGE_IMPORT_DESCRIPTOR pe_import;
|
||||
PIMAGE_EXPORT_DIRECTORY pe_export;
|
||||
PIMAGE_RESOURCE_DIRECTORY pe_resource;
|
||||
int flags;
|
||||
#define PE_MODREF_PROCESS_ATTACHED 0x00000001
|
||||
#define PE_MODREF_NO_DLL_CALLS 0x00000002
|
||||
#define PE_MODREF_RELOCS_DONE 0x00000004
|
||||
#define PE_MODREF_TLS_ALLOCED 0x00000008
|
||||
#define PE_MODREF_INTERNAL 0x00000010
|
||||
int tlsindex;
|
||||
} PE_MODREF;
|
||||
|
||||
|
@ -41,8 +35,7 @@ extern BOOL PE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCST
|
|||
BOOL inherit, LPSTARTUPINFOA startup,
|
||||
LPPROCESS_INFORMATION info );
|
||||
|
||||
struct _THDB; /* forward definition */
|
||||
extern void PE_InitTls(struct _THDB*);
|
||||
extern void PE_InitTls(void);
|
||||
extern void PE_InitDLL(struct _wine_modref *wm, DWORD type, LPVOID lpReserved);
|
||||
|
||||
extern PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA(PIMAGE_RESOURCE_DIRECTORY,LPCSTR,DWORD,BOOL);
|
||||
|
|
|
@ -123,7 +123,6 @@ extern THDB *THREAD_Create( struct _PDB *pdb, DWORD flags,
|
|||
extern THDB *THREAD_Current(void);
|
||||
extern BOOL THREAD_IsWin16( THDB *thdb );
|
||||
extern THDB *THREAD_IdToTHDB( DWORD id );
|
||||
extern DWORD THREAD_TlsAlloc( THDB *thread );
|
||||
|
||||
/* scheduler/sysdeps.c */
|
||||
extern int SYSDEPS_SpawnThread( THDB *thread );
|
||||
|
|
182
loader/module.c
182
loader/module.c
|
@ -73,37 +73,84 @@ WINE_MODREF *MODULE32_LookupHMODULE( HMODULE hmod )
|
|||
static void MODULE_DoInitializeDLLs( WINE_MODREF *wm,
|
||||
DWORD type, LPVOID lpReserved )
|
||||
{
|
||||
int i;
|
||||
WINE_MODREF *xwm;
|
||||
int i, skip = FALSE;
|
||||
|
||||
assert( wm && !wm->initDone );
|
||||
TRACE( module, "(%08x,%ld,%p) - START\n",
|
||||
wm->module, type, lpReserved );
|
||||
assert( wm && !(wm->flags & WINE_MODREF_MARKER) );
|
||||
TRACE( module, "(%s,%08x,%ld,%p) - START\n",
|
||||
wm->modname, wm->module, type, lpReserved );
|
||||
|
||||
/* Tag current MODREF to prevent recursive loop */
|
||||
wm->initDone = TRUE;
|
||||
wm->flags |= WINE_MODREF_MARKER;
|
||||
|
||||
/* Recursively initialize all child DLLs */
|
||||
for ( i = 0; i < wm->nDeps; i++ )
|
||||
if ( wm->deps[i] && !wm->deps[i]->initDone )
|
||||
MODULE_DoInitializeDLLs( wm->deps[i], type, lpReserved );
|
||||
|
||||
/* Now we can call the initialization routine */
|
||||
switch ( wm->type )
|
||||
switch ( type )
|
||||
{
|
||||
case MODULE32_PE:
|
||||
PE_InitDLL( wm, type, lpReserved );
|
||||
default:
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
/* Recursively attach all DLLs this one depends on */
|
||||
for ( i = 0; i < wm->nDeps; i++ )
|
||||
if ( wm->deps[i] && !(wm->deps[i]->flags & WINE_MODREF_MARKER) )
|
||||
MODULE_DoInitializeDLLs( wm->deps[i], type, lpReserved );
|
||||
break;
|
||||
|
||||
case MODULE32_ELF:
|
||||
/* no need to do that, dlopen() already does */
|
||||
break;
|
||||
default:
|
||||
ERR(module, "wine_modref type %d not handled.\n", wm->type);
|
||||
case DLL_PROCESS_DETACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
/* Recursively detach all DLLs that depend on this one */
|
||||
for ( xwm = PROCESS_Current()->modref_list; xwm; xwm = xwm->next )
|
||||
if ( !(xwm->flags & WINE_MODREF_MARKER) )
|
||||
for ( i = 0; i < xwm->nDeps; i++ )
|
||||
if ( xwm->deps[i] == wm )
|
||||
{
|
||||
MODULE_DoInitializeDLLs( xwm, type, lpReserved );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE( module, "(%08x,%ld,%p) - END\n",
|
||||
wm->module, type, lpReserved );
|
||||
/* Evaluate module flags */
|
||||
|
||||
if ( ( wm->flags & WINE_MODREF_NO_DLL_CALLS )
|
||||
|| ( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS )
|
||||
|| ( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE ) )
|
||||
skip = TRUE;
|
||||
|
||||
if ( type == DLL_PROCESS_ATTACH )
|
||||
if ( wm->flags & WINE_MODREF_PROCESS_ATTACHED )
|
||||
skip = TRUE;
|
||||
else
|
||||
wm->flags |= WINE_MODREF_PROCESS_ATTACHED;
|
||||
|
||||
if ( type == DLL_PROCESS_DETACH )
|
||||
if ( wm->flags & WINE_MODREF_PROCESS_DETACHED )
|
||||
skip = TRUE;
|
||||
else
|
||||
wm->flags |= WINE_MODREF_PROCESS_DETACHED;
|
||||
|
||||
if ( !skip )
|
||||
{
|
||||
/* Now we can call the initialization routine */
|
||||
TRACE( module, "(%s,%08x,%ld,%p) - CALL\n",
|
||||
wm->modname, wm->module, type, lpReserved );
|
||||
|
||||
switch ( wm->type )
|
||||
{
|
||||
case MODULE32_PE:
|
||||
PE_InitDLL( wm, type, lpReserved );
|
||||
break;
|
||||
|
||||
case MODULE32_ELF:
|
||||
/* no need to do that, dlopen() already does */
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR(module, "wine_modref type %d not handled.\n", wm->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE( module, "(%s,%08x,%ld,%p) - END\n",
|
||||
wm->modname, wm->module, type, lpReserved );
|
||||
}
|
||||
|
||||
void MODULE_InitializeDLLs( HMODULE root, DWORD type, LPVOID lpReserved )
|
||||
|
@ -119,7 +166,7 @@ void MODULE_InitializeDLLs( HMODULE root, DWORD type, LPVOID lpReserved )
|
|||
|
||||
/* First, check whether initialization is currently in progress */
|
||||
for ( wm = PROCESS_Current()->modref_list; wm; wm = wm->next )
|
||||
if ( wm->initDone )
|
||||
if ( wm->flags & WINE_MODREF_MARKER )
|
||||
{
|
||||
inProgress = TRUE;
|
||||
break;
|
||||
|
@ -135,7 +182,7 @@ void MODULE_InitializeDLLs( HMODULE root, DWORD type, LPVOID lpReserved )
|
|||
if ( root )
|
||||
{
|
||||
wm = MODULE32_LookupHMODULE( root );
|
||||
if ( wm && !wm->initDone )
|
||||
if ( wm && !(wm->flags & WINE_MODREF_MARKER) )
|
||||
MODULE_DoInitializeDLLs( wm, type, lpReserved );
|
||||
}
|
||||
else
|
||||
|
@ -147,9 +194,26 @@ void MODULE_InitializeDLLs( HMODULE root, DWORD type, LPVOID lpReserved )
|
|||
if ( !root )
|
||||
{
|
||||
/* If called for main EXE, initialize all DLLs */
|
||||
for ( wm = PROCESS_Current()->modref_list; wm; wm = wm->next )
|
||||
if ( !wm->initDone )
|
||||
MODULE_DoInitializeDLLs( wm, type, lpReserved );
|
||||
switch ( type )
|
||||
{
|
||||
default: /* Hmmm. */
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
for ( wm = PROCESS_Current()->modref_list; wm; wm = wm->next )
|
||||
if ( !wm->next )
|
||||
break;
|
||||
for ( ; wm; wm = wm->prev )
|
||||
if ( !(wm->flags & WINE_MODREF_MARKER) )
|
||||
MODULE_DoInitializeDLLs( wm, type, lpReserved );
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
for ( wm = PROCESS_Current()->modref_list; wm; wm = wm->next )
|
||||
if ( !(wm->flags & WINE_MODREF_MARKER) )
|
||||
MODULE_DoInitializeDLLs( wm, type, lpReserved );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -160,7 +224,7 @@ void MODULE_InitializeDLLs( HMODULE root, DWORD type, LPVOID lpReserved )
|
|||
|
||||
/* We're finished, so we reset all recursion flags */
|
||||
for ( wm = PROCESS_Current()->modref_list; wm; wm = wm->next )
|
||||
wm->initDone = FALSE;
|
||||
wm->flags &= ~WINE_MODREF_MARKER;
|
||||
}
|
||||
|
||||
TRACE( module, "(%08x,%ld,%p) - END\n", root, type, lpReserved );
|
||||
|
@ -169,6 +233,49 @@ void MODULE_InitializeDLLs( HMODULE root, DWORD type, LPVOID lpReserved )
|
|||
LeaveCriticalSection( &PROCESS_Current()->crit_section );
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DisableThreadLibraryCalls (KERNEL32.74)
|
||||
*
|
||||
* Don't call DllEntryPoint for DLL_THREAD_{ATTACH,DETACH} if set.
|
||||
*/
|
||||
BOOL WINAPI DisableThreadLibraryCalls( HMODULE hModule )
|
||||
{
|
||||
WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
|
||||
if ( !wm ) return FALSE;
|
||||
|
||||
wm->flags |= WINE_MODREF_NO_DLL_CALLS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* MODULE_IncRefCount
|
||||
*/
|
||||
static void MODULE_IncRefCount( HMODULE hModule )
|
||||
{
|
||||
WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
|
||||
if ( !wm ) return;
|
||||
|
||||
EnterCriticalSection( &PROCESS_Current()->crit_section );
|
||||
wm->refCount++;
|
||||
LeaveCriticalSection( &PROCESS_Current()->crit_section );
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* MODULE_DecRefCount
|
||||
*/
|
||||
static int MODULE_DecRefCount( HMODULE hModule )
|
||||
{
|
||||
int retv;
|
||||
WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
|
||||
if ( !wm ) return 0;
|
||||
|
||||
EnterCriticalSection( &PROCESS_Current()->crit_section );
|
||||
if ( ( retv = wm->refCount ) > 0 ) wm->refCount--;
|
||||
LeaveCriticalSection( &PROCESS_Current()->crit_section );
|
||||
|
||||
return retv;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* MODULE_CreateDummyModule
|
||||
|
@ -1103,15 +1210,14 @@ HMODULE WINAPI LoadLibraryExA(LPCSTR libname,HFILE hfile,DWORD flags)
|
|||
HMODULE hmod;
|
||||
hmod = MODULE_LoadLibraryExA( libname, hfile, flags );
|
||||
|
||||
/* at least call not the dllmain...*/
|
||||
if ( DONT_RESOLVE_DLL_REFERENCES==flags || LOAD_LIBRARY_AS_DATAFILE==flags )
|
||||
{ FIXME(module,"flag not properly supported %lx\n", flags);
|
||||
return hmod;
|
||||
}
|
||||
if ( hmod >= 32 )
|
||||
{
|
||||
/* Increment RefCount */
|
||||
MODULE_IncRefCount( hmod );
|
||||
|
||||
/* initialize DLL just loaded */
|
||||
if ( hmod >= 32 )
|
||||
MODULE_InitializeDLLs( hmod, DLL_PROCESS_ATTACH, (LPVOID)-1 );
|
||||
/* Initialize DLL just loaded */
|
||||
MODULE_InitializeDLLs( hmod, DLL_PROCESS_ATTACH, NULL );
|
||||
}
|
||||
|
||||
return hmod;
|
||||
}
|
||||
|
@ -1159,8 +1265,10 @@ HMODULE WINAPI LoadLibraryExW(LPCWSTR libnameW,HFILE hfile,DWORD flags)
|
|||
*/
|
||||
BOOL WINAPI FreeLibrary(HINSTANCE hLibModule)
|
||||
{
|
||||
FIXME(module,"(0x%08x): stub\n", hLibModule);
|
||||
return TRUE; /* FIXME */
|
||||
if ( MODULE_DecRefCount( hLibModule ) != 1 ) return TRUE;
|
||||
|
||||
FIXME(module,"(0x%08x): should unload now\n", hLibModule);
|
||||
return TRUE; /* FIXME */
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -740,11 +740,18 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule,
|
|||
HEAP_ZERO_MEMORY, sizeof(*wm) );
|
||||
wm->module = hModule;
|
||||
|
||||
if ( builtin )
|
||||
wm->flags |= WINE_MODREF_INTERNAL;
|
||||
if ( flags & DONT_RESOLVE_DLL_REFERENCES )
|
||||
wm->flags |= WINE_MODREF_DONT_RESOLVE_REFS;
|
||||
if ( flags & LOAD_LIBRARY_AS_DATAFILE )
|
||||
wm->flags |= WINE_MODREF_LOAD_AS_DATAFILE;
|
||||
|
||||
wm->type = MODULE32_PE;
|
||||
wm->binfmt.pe.flags = builtin? PE_MODREF_INTERNAL : 0;
|
||||
wm->binfmt.pe.pe_export = pe_export;
|
||||
wm->binfmt.pe.pe_import = pe_import;
|
||||
wm->binfmt.pe.pe_resource = pe_resource;
|
||||
wm->binfmt.pe.tlsindex = -1;
|
||||
|
||||
if ( pe_export )
|
||||
modname = (char *)RVA( pe_export->Name );
|
||||
|
@ -753,8 +760,7 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule,
|
|||
/* try to find out the name from the OFSTRUCT */
|
||||
char *s;
|
||||
modname = ofs->szPathName;
|
||||
while ((s=strchr(modname,'\\')))
|
||||
modname = s+1;
|
||||
if ((s=strrchr(modname,'\\'))) modname = s+1;
|
||||
}
|
||||
wm->modname = HEAP_strdupA( GetProcessHeap(), 0, modname );
|
||||
|
||||
|
@ -766,8 +772,11 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule,
|
|||
|
||||
/* Link MODREF into process list */
|
||||
|
||||
EnterCriticalSection( &PROCESS_Current()->crit_section );
|
||||
|
||||
wm->next = PROCESS_Current()->modref_list;
|
||||
PROCESS_Current()->modref_list = wm;
|
||||
if ( wm->next ) wm->next->prev = wm;
|
||||
|
||||
if ( !(nt->FileHeader.Characteristics & IMAGE_FILE_DLL) )
|
||||
{
|
||||
|
@ -776,6 +785,9 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule,
|
|||
PROCESS_Current()->exe_modref = wm;
|
||||
}
|
||||
|
||||
LeaveCriticalSection( &PROCESS_Current()->crit_section );
|
||||
|
||||
|
||||
/* Dump Exports */
|
||||
|
||||
if ( pe_export )
|
||||
|
@ -783,16 +795,23 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule,
|
|||
|
||||
/* Fixup Imports */
|
||||
|
||||
if ( pe_import && fixup_imports( wm ) )
|
||||
if ( pe_import && fixup_imports( wm )
|
||||
&& !( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE )
|
||||
&& !( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS ) )
|
||||
{
|
||||
/* remove entry from modref chain */
|
||||
WINE_MODREF **xwm;
|
||||
for ( xwm = &PROCESS_Current()->modref_list; *xwm; xwm = &(*xwm)->next )
|
||||
if ( *xwm == wm )
|
||||
{
|
||||
*xwm = wm->next;
|
||||
break;
|
||||
}
|
||||
EnterCriticalSection( &PROCESS_Current()->crit_section );
|
||||
|
||||
if ( !wm->prev )
|
||||
PROCESS_Current()->modref_list = wm->next;
|
||||
else
|
||||
wm->prev->next = wm->next;
|
||||
|
||||
if ( wm->next ) wm->next->prev = wm->prev;
|
||||
wm->next = wm->prev = NULL;
|
||||
|
||||
LeaveCriticalSection( &PROCESS_Current()->crit_section );
|
||||
|
||||
/* FIXME: there are several more dangling references
|
||||
* left. Including dlls loaded by this dll before the
|
||||
* failed one. Unrolling is rather difficult with the
|
||||
|
@ -943,15 +962,6 @@ void PE_InitDLL(WINE_MODREF *wm, DWORD type, LPVOID lpReserved)
|
|||
{
|
||||
if (wm->type!=MODULE32_PE)
|
||||
return;
|
||||
if (wm->binfmt.pe.flags & PE_MODREF_NO_DLL_CALLS)
|
||||
return;
|
||||
if (type==DLL_PROCESS_ATTACH)
|
||||
{
|
||||
if (wm->binfmt.pe.flags & PE_MODREF_PROCESS_ATTACHED)
|
||||
return;
|
||||
|
||||
wm->binfmt.pe.flags |= PE_MODREF_PROCESS_ATTACHED;
|
||||
}
|
||||
|
||||
/* DLL_ATTACH_PROCESS:
|
||||
* lpreserved is NULL for dynamic loads, not-NULL for static loads
|
||||
|
@ -979,7 +989,7 @@ void PE_InitDLL(WINE_MODREF *wm, DWORD type, LPVOID lpReserved)
|
|||
* Pointers in those structs are not RVAs but real pointers which have been
|
||||
* relocated by do_relocations() already.
|
||||
*/
|
||||
void PE_InitTls(THDB *thdb)
|
||||
void PE_InitTls( void )
|
||||
{
|
||||
WINE_MODREF *wm;
|
||||
PE_MODREF *pem;
|
||||
|
@ -987,10 +997,9 @@ void PE_InitTls(THDB *thdb)
|
|||
DWORD size,datasize;
|
||||
LPVOID mem;
|
||||
PIMAGE_TLS_DIRECTORY pdir;
|
||||
PDB *pdb = thdb->process;
|
||||
int delta;
|
||||
|
||||
for (wm = pdb->modref_list;wm;wm=wm->next) {
|
||||
for (wm = PROCESS_Current()->modref_list;wm;wm=wm->next) {
|
||||
if (wm->type!=MODULE32_PE)
|
||||
continue;
|
||||
pem = &(wm->binfmt.pe);
|
||||
|
@ -1002,11 +1011,10 @@ void PE_InitTls(THDB *thdb)
|
|||
DataDirectory[IMAGE_FILE_THREAD_LOCAL_STORAGE].VirtualAddress);
|
||||
|
||||
|
||||
if (!(pem->flags & PE_MODREF_TLS_ALLOCED)) {
|
||||
pem->tlsindex = THREAD_TlsAlloc(thdb);
|
||||
if ( pem->tlsindex == -1 ) {
|
||||
pem->tlsindex = TlsAlloc();
|
||||
*pdir->AddressOfIndex=pem->tlsindex;
|
||||
}
|
||||
pem->flags |= PE_MODREF_TLS_ALLOCED;
|
||||
datasize= pdir->EndAddressOfRawData-pdir->StartAddressOfRawData;
|
||||
size = datasize + pdir->SizeOfZeroFill;
|
||||
mem=VirtualAlloc(0,size,MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);
|
||||
|
@ -1018,21 +1026,8 @@ void PE_InitTls(THDB *thdb)
|
|||
if (*cbs)
|
||||
FIXME(win32, "TLS Callbacks aren't going to be called\n");
|
||||
}
|
||||
/* Don't use TlsSetValue, we are in the wrong thread */
|
||||
thdb->tls_array[pem->tlsindex] = mem;
|
||||
|
||||
TlsSetValue( pem->tlsindex, mem );
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DisableThreadLibraryCalls (KERNEL32.74)
|
||||
* Don't call DllEntryPoint for DLL_THREAD_{ATTACH,DETACH} if set.
|
||||
*/
|
||||
BOOL WINAPI DisableThreadLibraryCalls(HMODULE hModule)
|
||||
{
|
||||
WINE_MODREF *wm;
|
||||
|
||||
for (wm=PROCESS_Current()->modref_list;wm;wm=wm->next)
|
||||
if ((wm->module == hModule) && (wm->type==MODULE32_PE))
|
||||
wm->binfmt.pe.flags|=PE_MODREF_NO_DLL_CALLS;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -363,14 +363,14 @@ void PROCESS_Start(void)
|
|||
|
||||
/* Initialize thread-local storage */
|
||||
|
||||
PE_InitTls( thdb );
|
||||
PE_InitTls();
|
||||
|
||||
if (PE_HEADER(pModule->module32)->OptionalHeader.Subsystem==IMAGE_SUBSYSTEM_WINDOWS_CUI)
|
||||
AllocConsole();
|
||||
|
||||
/* Now call the entry point */
|
||||
|
||||
MODULE_InitializeDLLs( 0, DLL_PROCESS_ATTACH, (LPVOID)-1 );
|
||||
MODULE_InitializeDLLs( 0, DLL_PROCESS_ATTACH, (LPVOID)1 );
|
||||
entry = (LPTHREAD_START_ROUTINE)RVA_PTR(pModule->module32,
|
||||
OptionalHeader.AddressOfEntryPoint);
|
||||
TRACE(relay, "(entryproc=%p)\n", entry );
|
||||
|
@ -509,7 +509,7 @@ error:
|
|||
*/
|
||||
void WINAPI ExitProcess( DWORD status )
|
||||
{
|
||||
MODULE_InitializeDLLs( 0, DLL_PROCESS_DETACH, NULL );
|
||||
MODULE_InitializeDLLs( 0, DLL_PROCESS_DETACH, (LPVOID)1 );
|
||||
|
||||
if ( THREAD_IsWin16( THREAD_Current() ) )
|
||||
TASK_KillCurrentTask( status );
|
||||
|
|
|
@ -261,7 +261,6 @@ THDB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16
|
|||
if (!THREAD_InitTHDB( thdb, stack_size, alloc_stack16, sa )) goto error;
|
||||
thdb->next = THREAD_First;
|
||||
THREAD_First = thdb;
|
||||
PE_InitTls( thdb );
|
||||
return thdb;
|
||||
|
||||
error:
|
||||
|
@ -282,6 +281,7 @@ static void THREAD_Start(void)
|
|||
{
|
||||
THDB *thdb = THREAD_Current();
|
||||
LPTHREAD_START_ROUTINE func = (LPTHREAD_START_ROUTINE)thdb->entry_point;
|
||||
PE_InitTls();
|
||||
MODULE_InitializeDLLs( 0, DLL_THREAD_ATTACH, NULL );
|
||||
ExitThread( func( thdb->entry_arg ) );
|
||||
}
|
||||
|
@ -412,10 +412,17 @@ void WINAPI SetLastErrorEx(
|
|||
|
||||
|
||||
/**********************************************************************
|
||||
* THREAD_TlsAlloc
|
||||
* TlsAlloc [KERNEL32.530] Allocates a TLS index.
|
||||
*
|
||||
* Allocates a thread local storage index
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TLS Index
|
||||
* Failure: 0xFFFFFFFF
|
||||
*/
|
||||
DWORD THREAD_TlsAlloc(THDB *thread)
|
||||
DWORD WINAPI TlsAlloc( void )
|
||||
{
|
||||
THDB *thread = THREAD_Current();
|
||||
DWORD i, mask, ret = 0;
|
||||
DWORD *bits = thread->process->tls_bits;
|
||||
EnterCriticalSection( &thread->process->crit_section );
|
||||
|
@ -437,21 +444,6 @@ DWORD THREAD_TlsAlloc(THDB *thread)
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* TlsAlloc [KERNEL32.530] Allocates a TLS index.
|
||||
*
|
||||
* Allocates a thread local storage index
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TLS Index
|
||||
* Failure: 0xFFFFFFFF
|
||||
*/
|
||||
DWORD WINAPI TlsAlloc(void)
|
||||
{
|
||||
return THREAD_TlsAlloc(THREAD_Current());
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* TlsFree [KERNEL32.531] Releases a TLS index.
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue