mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-05 17:02:13 +00:00
Bugfix: Call DllEntryPoint for *every* process that loads the DLL, not
just for the first one. Bypass 32->16->32 transition when calling DllEntryPoint of built-in.
This commit is contained in:
parent
937f4d3ec3
commit
2149934a2d
|
@ -227,6 +227,7 @@ extern BOOL NE_CreateSegment( NE_MODULE *pModule, int segnum );
|
|||
extern BOOL NE_CreateAllSegments( NE_MODULE *pModule );
|
||||
extern HINSTANCE16 NE_GetInstance( NE_MODULE *pModule );
|
||||
extern void NE_InitializeDLLs( HMODULE16 hModule );
|
||||
extern void NE_DllProcessAttach( HMODULE16 hModule );
|
||||
|
||||
/* loader/ne/convert.c */
|
||||
HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size );
|
||||
|
|
|
@ -971,7 +971,10 @@ static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_
|
|||
* when we load implicitly linked DLLs this will be done by InitTask().
|
||||
*/
|
||||
if(pModule->flags & NE_FFLAGS_LIBMODULE)
|
||||
{
|
||||
NE_InitializeDLLs(hModule);
|
||||
NE_DllProcessAttach(hModule);
|
||||
}
|
||||
}
|
||||
return hinst;
|
||||
}
|
||||
|
@ -1268,7 +1271,7 @@ static BOOL16 NE_FreeModule( HMODULE16 hModule, BOOL call_wep )
|
|||
|
||||
/* Free the objects owned by the DLL module */
|
||||
TASK_CallTaskSignalProc( USIG16_DLL_UNLOAD, hModule );
|
||||
PROCESS_CallUserSignalProc( USIG_DLL_UNLOAD_WIN16, hModule );
|
||||
PROCESS_CallUserSignalProc( USIG_DLL_UNLOAD_WIN16, 0, hModule );
|
||||
}
|
||||
else
|
||||
call_wep = FALSE; /* We are freeing a task -> no more WEPs */
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "file.h"
|
||||
#include "module.h"
|
||||
#include "stackframe.h"
|
||||
#include "builtin16.h"
|
||||
#include "debugtools.h"
|
||||
#include "xmalloc.h"
|
||||
#include "toolhelp.h"
|
||||
|
@ -613,50 +614,6 @@ static BOOL NE_InitDLL( TDB* pTask, NE_MODULE *pModule )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NE_CallDllEntryPoint
|
||||
*
|
||||
* Call the DllEntryPoint of DLLs with subsystem >= 4.0
|
||||
*/
|
||||
|
||||
static void NE_CallDllEntryPoint( NE_MODULE *pModule, DWORD dwReason )
|
||||
{
|
||||
WORD hInst, ds, heap;
|
||||
FARPROC16 entryPoint;
|
||||
WORD ordinal;
|
||||
CONTEXT86 context;
|
||||
LPBYTE stack = (LPBYTE)CURRENT_STACK16;
|
||||
|
||||
if (!(pModule->flags & NE_FFLAGS_BUILTIN) && pModule->expected_version < 0x0400) return;
|
||||
if (!(ordinal = NE_GetOrdinal( pModule->self, "DllEntryPoint" ))) return;
|
||||
if (!(entryPoint = NE_GetEntryPoint( pModule->self, ordinal ))) return;
|
||||
|
||||
memset( &context, 0, sizeof(context) );
|
||||
|
||||
NE_GetDLLInitParams( pModule, &hInst, &ds, &heap );
|
||||
|
||||
DS_reg(&context) = ds;
|
||||
ES_reg(&context) = ds; /* who knows ... */
|
||||
|
||||
CS_reg(&context) = HIWORD(entryPoint);
|
||||
EIP_reg(&context) = LOWORD(entryPoint);
|
||||
EBP_reg(&context) = OFFSETOF( NtCurrentTeb()->cur_stack )
|
||||
+ (WORD)&((STACK16FRAME*)0)->bp;
|
||||
|
||||
*(DWORD *)(stack - 4) = dwReason; /* dwReason */
|
||||
*(WORD *) (stack - 6) = hInst; /* hInst */
|
||||
*(WORD *) (stack - 8) = ds; /* wDS */
|
||||
*(WORD *) (stack - 10) = heap; /* wHeapSize */
|
||||
*(DWORD *)(stack - 14) = 0; /* dwReserved1 */
|
||||
*(WORD *) (stack - 16) = 0; /* wReserved2 */
|
||||
|
||||
TRACE_(dll)("Calling DllEntryPoint, cs:ip=%04lx:%04lx\n",
|
||||
CS_reg(&context), EIP_reg(&context));
|
||||
|
||||
Callbacks->CallRegisterShortProc( &context, 16 );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* NE_InitializeDLLs
|
||||
*
|
||||
|
@ -683,7 +640,116 @@ void NE_InitializeDLLs( HMODULE16 hModule )
|
|||
GlobalFree16( to_init );
|
||||
}
|
||||
NE_InitDLL( pTask, pModule );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* NE_CallDllEntryPoint
|
||||
*
|
||||
* Call the DllEntryPoint of DLLs with subsystem >= 4.0
|
||||
*/
|
||||
|
||||
static void NE_CallDllEntryPoint( NE_MODULE *pModule, DWORD dwReason )
|
||||
{
|
||||
WORD hInst, ds, heap;
|
||||
FARPROC16 entryPoint;
|
||||
WORD ordinal;
|
||||
|
||||
if (!(pModule->flags & NE_FFLAGS_LIBMODULE)) return;
|
||||
if (!(pModule->flags & NE_FFLAGS_BUILTIN) && pModule->expected_version < 0x0400) return;
|
||||
if (!(ordinal = NE_GetOrdinal( pModule->self, "DllEntryPoint" ))) return;
|
||||
if (!(entryPoint = NE_GetEntryPoint( pModule->self, ordinal ))) return;
|
||||
|
||||
NE_GetDLLInitParams( pModule, &hInst, &ds, &heap );
|
||||
|
||||
TRACE_(dll)( "Calling %s DllEntryPoint, cs:ip=%04x:%04x\n",
|
||||
NE_MODULE_NAME( pModule ),
|
||||
SELECTOROF(entryPoint), OFFSETOF(entryPoint) );
|
||||
|
||||
if ( pModule->flags & NE_FFLAGS_BUILTIN )
|
||||
{
|
||||
DWORD WINAPI (*entryProc)(DWORD,WORD,WORD,WORD,DWORD,WORD) =
|
||||
(DWORD WINAPI (*)(DWORD,WORD,WORD,WORD,DWORD,WORD))
|
||||
((ENTRYPOINT16 *)PTR_SEG_TO_LIN( entryPoint ))->target;
|
||||
|
||||
entryProc( dwReason, hInst, ds, heap, 0, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
LPBYTE stack = (LPBYTE)CURRENT_STACK16;
|
||||
CONTEXT86 context;
|
||||
|
||||
memset( &context, 0, sizeof(context) );
|
||||
DS_reg(&context) = ds;
|
||||
ES_reg(&context) = ds; /* who knows ... */
|
||||
|
||||
CS_reg(&context) = HIWORD(entryPoint);
|
||||
EIP_reg(&context) = LOWORD(entryPoint);
|
||||
EBP_reg(&context) = OFFSETOF( NtCurrentTeb()->cur_stack )
|
||||
+ (WORD)&((STACK16FRAME*)0)->bp;
|
||||
|
||||
*(DWORD *)(stack - 4) = dwReason; /* dwReason */
|
||||
*(WORD *) (stack - 6) = hInst; /* hInst */
|
||||
*(WORD *) (stack - 8) = ds; /* wDS */
|
||||
*(WORD *) (stack - 10) = heap; /* wHeapSize */
|
||||
*(DWORD *)(stack - 14) = 0; /* dwReserved1 */
|
||||
*(WORD *) (stack - 16) = 0; /* wReserved2 */
|
||||
|
||||
Callbacks->CallRegisterShortProc( &context, 16 );
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NE_DllProcessAttach
|
||||
*
|
||||
* Call the DllEntryPoint of all modules this one (recursively)
|
||||
* depends on, according to the order in which they were loaded.
|
||||
*
|
||||
* Note that --as opposed to the PE module case-- there is no notion
|
||||
* of 'module loaded into a process' for NE modules, and hence we
|
||||
* have no place to store the fact that the DllEntryPoint of a
|
||||
* given module was already called on behalf of this process (e.g.
|
||||
* due to some earlier LoadLibrary16 call).
|
||||
*
|
||||
* Thus, we just call the DllEntryPoint twice in that case. Win9x
|
||||
* appears to behave this way as well ...
|
||||
*
|
||||
* This routine must only be called with the Win16Lock held.
|
||||
*
|
||||
* FIXME: We should actually abort loading in case the DllEntryPoint
|
||||
* returns FALSE ...
|
||||
*
|
||||
*/
|
||||
void NE_DllProcessAttach( HMODULE16 hModule )
|
||||
{
|
||||
NE_MODULE *pModule;
|
||||
WORD *pModRef;
|
||||
int i;
|
||||
|
||||
if (!(pModule = NE_GetPtr( hModule ))) return;
|
||||
assert( !(pModule->flags & NE_FFLAGS_WIN32) );
|
||||
|
||||
/* Check for recursive call */
|
||||
if ( pModule->misc_flags & 0x80 ) return;
|
||||
|
||||
TRACE_(dll)("(%s) - START\n", NE_MODULE_NAME(pModule) );
|
||||
|
||||
/* Tag current module to prevent recursive loop */
|
||||
pModule->misc_flags |= 0x80;
|
||||
|
||||
/* Recursively attach all DLLs this one depends on */
|
||||
pModRef = NE_MODULE_TABLE( pModule );
|
||||
for ( i = 0; i < pModule->modref_count; i++ )
|
||||
if ( pModRef[i] )
|
||||
NE_DllProcessAttach( (HMODULE16)pModRef[i] );
|
||||
|
||||
/* Call DLL entry point */
|
||||
NE_CallDllEntryPoint( pModule, DLL_PROCESS_ATTACH );
|
||||
|
||||
/* Remove recursion flag */
|
||||
pModule->misc_flags &= ~0x80;
|
||||
|
||||
TRACE_(dll)("(%s) - END\n", NE_MODULE_NAME(pModule) );
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue