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:
Ulrich Weigand 1999-12-05 02:50:38 +00:00 committed by Alexandre Julliard
parent 937f4d3ec3
commit 2149934a2d
3 changed files with 115 additions and 45 deletions

View file

@ -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 );

View file

@ -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 */

View file

@ -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) );
}