Implemented new PE DLL initalization code, trying to call the
DllEntryPoint routines always in correct order :-) Bypass snooping when getting data buffer addresses (thunk buffers, __GP handlers) and for 32-bit routines directly called from 16-bit (due to stack address size problems).
This commit is contained in:
parent
2e244c45a3
commit
a3527cf369
|
@ -119,11 +119,16 @@ typedef struct _wine_modref
|
|||
|
||||
HMODULE32 module;
|
||||
|
||||
int nDeps;
|
||||
struct _wine_modref **deps;
|
||||
int initDone;
|
||||
|
||||
char *modname;
|
||||
char *shortname;
|
||||
char *longname;
|
||||
} WINE_MODREF;
|
||||
|
||||
|
||||
/* Resource types */
|
||||
typedef struct resource_typeinfo_s NE_TYPEINFO;
|
||||
typedef struct resource_nameinfo_s NE_NAMEINFO;
|
||||
|
@ -138,8 +143,9 @@ typedef struct resource_nameinfo_s NE_NAMEINFO;
|
|||
(((OFSTRUCT *)((char*)(pModule) + (pModule)->fileinfo))->szPathName)
|
||||
|
||||
/* module.c */
|
||||
extern FARPROC32 MODULE_GetProcAddress32( struct _PDB32*pdb,HMODULE32 hModule,LPCSTR function );
|
||||
extern FARPROC32 MODULE_GetProcAddress32( struct _PDB32*pdb,HMODULE32 hModule,LPCSTR function,BOOL32 snoop );
|
||||
extern WINE_MODREF *MODULE32_LookupHMODULE( struct _PDB32 *process, HMODULE32 hModule );
|
||||
extern void MODULE_InitializeDLLs( struct _PDB32 *process, HMODULE32 root, DWORD type, LPVOID lpReserved );
|
||||
extern HMODULE32 MODULE_FindModule32( struct _PDB32 *process, LPCSTR path );
|
||||
extern HMODULE32 MODULE_CreateDummyModule( const OFSTRUCT *ofs );
|
||||
extern FARPROC16 MODULE_GetWndProcEntry16( const char *name );
|
||||
|
@ -154,6 +160,7 @@ extern void NE_WalkModules(void);
|
|||
extern void NE_RegisterModule( NE_MODULE *pModule );
|
||||
extern WORD NE_GetOrdinal( HMODULE16 hModule, const char *name );
|
||||
extern FARPROC16 NE_GetEntryPoint( HMODULE16 hModule, WORD ordinal );
|
||||
extern FARPROC16 NE_GetEntryPointEx( HMODULE16 hModule, WORD ordinal, BOOL16 snoop );
|
||||
extern BOOL16 NE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset );
|
||||
extern int NE_OpenFile( NE_MODULE *pModule );
|
||||
extern HINSTANCE16 NE_LoadModule( LPCSTR name, HINSTANCE16 *hPrevInstance,
|
||||
|
|
|
@ -27,7 +27,7 @@ struct _PDB32;
|
|||
struct _wine_modref;
|
||||
extern int PE_unloadImage(HMODULE32 hModule);
|
||||
extern FARPROC32 PE_FindExportedFunction(
|
||||
struct _PDB32 *process,struct _wine_modref *wm, LPCSTR funcName
|
||||
struct _PDB32 *process,struct _wine_modref *wm, LPCSTR funcName, BOOL32 snoop
|
||||
);
|
||||
extern void my_wcstombs(char * result, u_short * source, int len);
|
||||
extern BOOL32 PE_EnumResourceTypes32A(HMODULE32,ENUMRESTYPEPROC32A,LONG);
|
||||
|
@ -45,8 +45,8 @@ extern HINSTANCE16 PE_CreateProcess( LPCSTR name, LPCSTR cmd_line,
|
|||
LPPROCESS_INFORMATION info );
|
||||
|
||||
struct _THDB; /* forward definition */
|
||||
extern void PE_InitializeDLLs(struct _PDB32*,DWORD,LPVOID);
|
||||
extern void PE_InitTls(struct _THDB*);
|
||||
extern void PE_InitDLL(struct _wine_modref *wm, DWORD type, LPVOID lpReserved);
|
||||
|
||||
extern LPIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(LPIMAGE_RESOURCE_DIRECTORY,LPCWSTR,DWORD,BOOL32);
|
||||
|
||||
|
|
|
@ -52,6 +52,71 @@ MODULE32_LookupHMODULE(PDB32 *process,HMODULE32 hmod) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* MODULE_InitializeDLLs
|
||||
*
|
||||
* Call the initialization routines of all DLLs belonging to the
|
||||
* current process. This is somewhat complicated due to the fact that
|
||||
*
|
||||
* - we have to respect the module dependencies, i.e. modules implicitly
|
||||
* referenced by another module have to be initialized before the module
|
||||
* itself can be initialized
|
||||
*
|
||||
* - the initialization routine of a DLL can itself call LoadLibrary,
|
||||
* thereby introducing a whole new set of dependencies (even involving
|
||||
* the 'old' modules) at any time during the whole process
|
||||
*
|
||||
* (Note that this routine can be recursively entered not only directly
|
||||
* from itself, but also via LoadLibrary from one of the called initialization
|
||||
* routines.)
|
||||
*/
|
||||
void MODULE_InitializeDLLs( PDB32 *process, HMODULE32 root,
|
||||
DWORD type, LPVOID lpReserved )
|
||||
{
|
||||
WINE_MODREF *wm = MODULE32_LookupHMODULE( process, root );
|
||||
int i;
|
||||
|
||||
if (!wm) return;
|
||||
|
||||
/* If called for main EXE, check for invalid recursion */
|
||||
if ( !root && wm->initDone )
|
||||
{
|
||||
FIXME(module, "Invalid recursion!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Tag current MODREF to prevent recursive loop */
|
||||
wm->initDone = TRUE;
|
||||
|
||||
/* Recursively initialize all child DLLs */
|
||||
for ( i = 0; i < wm->nDeps; i++ )
|
||||
if ( wm->deps[i] && !wm->deps[i]->initDone )
|
||||
MODULE_InitializeDLLs( process,
|
||||
wm->deps[i]->module, type, lpReserved );
|
||||
|
||||
/* Now we can call the initialization routine */
|
||||
switch ( wm->type )
|
||||
{
|
||||
case MODULE32_PE:
|
||||
PE_InitDLL( wm, type, lpReserved );
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR(module, "wine_modref type %d not handled.\n", wm->type);
|
||||
break;
|
||||
}
|
||||
|
||||
/* If called for main EXE, reset recursion flags */
|
||||
if ( !root )
|
||||
for ( wm = process->modref_list; wm; wm = wm->next )
|
||||
{
|
||||
if (!wm->initDone)
|
||||
FIXME(module, "Orphaned module in modref_list?\n");
|
||||
|
||||
wm->initDone = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* MODULE_CreateDummyModule
|
||||
|
@ -305,7 +370,7 @@ static HINSTANCE16 NE_CreateProcess( LPCSTR name, LPCSTR cmd_line, LPCSTR env,
|
|||
}
|
||||
else
|
||||
{
|
||||
hInstance = NE_LoadModule( name, &hPrevInstance, FALSE, FALSE );
|
||||
hInstance = NE_LoadModule( name, &hPrevInstance, TRUE, FALSE );
|
||||
if (hInstance < 32) return hInstance;
|
||||
|
||||
if ( !(pModule = NE_GetPtr(hInstance))
|
||||
|
@ -699,9 +764,9 @@ HMODULE32 MODULE_LoadLibraryEx32A(LPCSTR libname,PDB32*process,HFILE32 hfile,DWO
|
|||
strcat( buffer, ".dll" );
|
||||
hmod = PE_LoadLibraryEx32A(buffer,process,hfile,flags);
|
||||
}
|
||||
/* initialize all DLLs, which haven't been initialized yet. */
|
||||
/* initialize DLL just loaded */
|
||||
if (hmod >= 32)
|
||||
PE_InitializeDLLs( process, DLL_PROCESS_ATTACH, NULL);
|
||||
MODULE_InitializeDLLs( PROCESS_Current(), hmod, DLL_PROCESS_ATTACH, NULL);
|
||||
return hmod;
|
||||
}
|
||||
|
||||
|
@ -996,9 +1061,16 @@ FARPROC16 WINAPI GetProcAddress16( HMODULE16 hModule, SEGPTR name )
|
|||
*/
|
||||
FARPROC32 WINAPI GetProcAddress32( HMODULE32 hModule, LPCSTR function )
|
||||
{
|
||||
return MODULE_GetProcAddress32( PROCESS_Current(), hModule, function );
|
||||
return MODULE_GetProcAddress32( PROCESS_Current(), hModule, function, TRUE );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* WIN16_GetProcAddress32 (KERNEL.453)
|
||||
*/
|
||||
FARPROC32 WINAPI WIN16_GetProcAddress32( HMODULE32 hModule, LPCSTR function )
|
||||
{
|
||||
return MODULE_GetProcAddress32( PROCESS_Current(), hModule, function, FALSE );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MODULE_GetProcAddress32 (internal)
|
||||
|
@ -1006,7 +1078,8 @@ FARPROC32 WINAPI GetProcAddress32( HMODULE32 hModule, LPCSTR function )
|
|||
FARPROC32 MODULE_GetProcAddress32(
|
||||
PDB32 *process, /* [in] process context */
|
||||
HMODULE32 hModule, /* [in] current module handle */
|
||||
LPCSTR function ) /* [in] function to be looked up */
|
||||
LPCSTR function, /* [in] function to be looked up */
|
||||
BOOL32 snoop )
|
||||
{
|
||||
WINE_MODREF *wm = MODULE32_LookupHMODULE(process,hModule);
|
||||
|
||||
|
@ -1019,7 +1092,7 @@ FARPROC32 MODULE_GetProcAddress32(
|
|||
switch (wm->type)
|
||||
{
|
||||
case MODULE32_PE:
|
||||
return PE_FindExportedFunction( process, wm, function);
|
||||
return PE_FindExportedFunction( process, wm, function, snoop );
|
||||
case MODULE32_ELF:
|
||||
return ELF_FindExportedFunction( process, wm, function);
|
||||
default:
|
||||
|
@ -1062,11 +1135,13 @@ typedef struct _GPHANDLERDEF
|
|||
SEGPTR WINAPI HasGPHandler( SEGPTR address )
|
||||
{
|
||||
HMODULE16 hModule;
|
||||
int gpOrdinal;
|
||||
SEGPTR gpPtr;
|
||||
GPHANDLERDEF *gpHandler;
|
||||
|
||||
if ( (hModule = FarGetOwner( SELECTOROF(address) )) != 0
|
||||
&& (gpPtr = (SEGPTR)WIN32_GetProcAddress16( hModule, "__GP" )) != 0
|
||||
&& (gpOrdinal = NE_GetOrdinal( hModule, "__GP" )) != 0
|
||||
&& (gpPtr = (SEGPTR)NE_GetEntryPointEx( hModule, gpOrdinal, FALSE )) != 0
|
||||
&& !IsBadReadPtr16( gpPtr, sizeof(GPHANDLERDEF) )
|
||||
&& (gpHandler = PTR_SEG_TO_LIN( gpPtr )) != NULL )
|
||||
{
|
||||
|
|
|
@ -60,7 +60,6 @@
|
|||
#include "snoop.h"
|
||||
#include "debug.h"
|
||||
|
||||
static void PE_InitDLL(WINE_MODREF *wm, DWORD type, LPVOID lpReserved);
|
||||
|
||||
/* convert PE image VirtualAddress to Real Address */
|
||||
#define RVA(x) ((unsigned int)load_addr+(unsigned int)(x))
|
||||
|
@ -122,7 +121,8 @@ void dump_exports( HMODULE32 hModule )
|
|||
FARPROC32 PE_FindExportedFunction(
|
||||
PDB32 *process, /* [in] process context */
|
||||
WINE_MODREF *wm, /* [in] WINE modreference */
|
||||
LPCSTR funcName ) /* [in] function name */
|
||||
LPCSTR funcName, /* [in] function name */
|
||||
BOOL32 snoop )
|
||||
{
|
||||
u_short * ordinal;
|
||||
u_long * function;
|
||||
|
@ -163,7 +163,8 @@ FARPROC32 PE_FindExportedFunction(
|
|||
addr = function[*ordinal];
|
||||
if (!addr) return NULL;
|
||||
if ((addr < rva_start) || (addr >= rva_end))
|
||||
return SNOOP_GetProcAddress32(wm->module,ename,*ordinal,(FARPROC32)RVA(addr));
|
||||
return snoop? SNOOP_GetProcAddress32(wm->module,ename,*ordinal,(FARPROC32)RVA(addr))
|
||||
: (FARPROC32)RVA(addr);
|
||||
forward = (char *)RVA(addr);
|
||||
break;
|
||||
}
|
||||
|
@ -192,7 +193,8 @@ FARPROC32 PE_FindExportedFunction(
|
|||
ename = "";
|
||||
}
|
||||
if ((addr < rva_start) || (addr >= rva_end))
|
||||
return SNOOP_GetProcAddress32(wm->module,ename,(DWORD)funcName-exports->Base,(FARPROC32)RVA(addr));
|
||||
return snoop? SNOOP_GetProcAddress32(wm->module,ename,(DWORD)funcName-exports->Base,(FARPROC32)RVA(addr))
|
||||
: (FARPROC32)RVA(addr);
|
||||
forward = (char *)RVA(addr);
|
||||
}
|
||||
if (forward)
|
||||
|
@ -207,7 +209,7 @@ FARPROC32 PE_FindExportedFunction(
|
|||
module[end-forward] = 0;
|
||||
hMod = MODULE_FindModule32(process,module);
|
||||
assert(hMod);
|
||||
return MODULE_GetProcAddress32( process, hMod, end + 1);
|
||||
return MODULE_GetProcAddress32( process, hMod, end + 1, snoop );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -240,6 +242,10 @@ DWORD fixup_imports (PDB32 *process,WINE_MODREF *wm)
|
|||
for (i = 0; pe_imp->Name; pe_imp++)
|
||||
i++;
|
||||
|
||||
/* Allocate module dependency list */
|
||||
wm->nDeps = i;
|
||||
wm->deps = HeapAlloc(process->heap, 0, i*sizeof(WINE_MODREF *));
|
||||
|
||||
/* load the imported modules. They are automatically
|
||||
* added to the modref list of the process.
|
||||
*/
|
||||
|
@ -247,7 +253,6 @@ DWORD fixup_imports (PDB32 *process,WINE_MODREF *wm)
|
|||
/* FIXME: should terminate on 0 Characteristics */
|
||||
for (i = 0, pe_imp = pem->pe_import; pe_imp->Name; pe_imp++) {
|
||||
HMODULE32 hImpModule;
|
||||
WINE_MODREF **ywm;
|
||||
IMAGE_IMPORT_BY_NAME *pe_name;
|
||||
LPIMAGE_THUNK_DATA import_list,thunk_list;
|
||||
char *name = (char *) RVA(pe_imp->Name);
|
||||
|
@ -268,35 +273,9 @@ DWORD fixup_imports (PDB32 *process,WINE_MODREF *wm)
|
|||
ERR (module, "Module %s not found\n", name);
|
||||
return 1;
|
||||
}
|
||||
xwm = wm->next;
|
||||
while (xwm) {
|
||||
if (xwm->module == hImpModule)
|
||||
break;
|
||||
xwm = xwm->next;
|
||||
}
|
||||
if (xwm) {
|
||||
/* It has been loaded *BEFORE* us, so we have to initialize
|
||||
* it before us. We cannot just link in the xwm before wm,
|
||||
* since xwm might reference more dlls which would be in the
|
||||
* wrong order after that.
|
||||
* Instead we link in wm right AFTER xwm, which should keep
|
||||
* the correct order. (I am not 100% sure about that.)
|
||||
*/
|
||||
/* unlink wm from chain */
|
||||
ywm = &(process->modref_list);
|
||||
while (*ywm) {
|
||||
if ((*ywm)==wm)
|
||||
break;
|
||||
ywm = &((*ywm)->next);
|
||||
}
|
||||
*ywm = wm->next;
|
||||
|
||||
/* link wm directly AFTER xwm */
|
||||
wm->next = xwm->next;
|
||||
xwm->next = wm;
|
||||
|
||||
}
|
||||
i++;
|
||||
xwm = MODULE32_LookupHMODULE(process, hImpModule);
|
||||
assert( xwm );
|
||||
wm->deps[i++] = xwm;
|
||||
|
||||
/* FIXME: forwarder entries ... */
|
||||
|
||||
|
@ -311,7 +290,7 @@ DWORD fixup_imports (PDB32 *process,WINE_MODREF *wm)
|
|||
|
||||
TRACE(win32, "--- Ordinal %s,%d\n", name, ordinal);
|
||||
thunk_list->u1.Function=MODULE_GetProcAddress32(
|
||||
process, hImpModule, (LPCSTR)ordinal
|
||||
process, hImpModule, (LPCSTR)ordinal, TRUE
|
||||
);
|
||||
if (!thunk_list->u1.Function) {
|
||||
ERR(win32,"No implementation for %s.%d, setting to 0xdeadbeef\n",
|
||||
|
@ -322,7 +301,7 @@ DWORD fixup_imports (PDB32 *process,WINE_MODREF *wm)
|
|||
pe_name = (LPIMAGE_IMPORT_BY_NAME)RVA(import_list->u1.AddressOfData);
|
||||
TRACE(win32, "--- %s %s.%d\n", pe_name->Name, name, pe_name->Hint);
|
||||
thunk_list->u1.Function=MODULE_GetProcAddress32(
|
||||
process, hImpModule, pe_name->Name
|
||||
process, hImpModule, pe_name->Name, TRUE
|
||||
);
|
||||
if (!thunk_list->u1.Function) {
|
||||
ERR(win32,"No implementation for %s.%d(%s), setting to 0xdeadbeef\n",
|
||||
|
@ -343,7 +322,7 @@ DWORD fixup_imports (PDB32 *process,WINE_MODREF *wm)
|
|||
|
||||
TRACE(win32,"--- Ordinal %s.%d\n",name,ordinal);
|
||||
thunk_list->u1.Function=MODULE_GetProcAddress32(
|
||||
process, hImpModule, (LPCSTR) ordinal
|
||||
process, hImpModule, (LPCSTR) ordinal, TRUE
|
||||
);
|
||||
if (!thunk_list->u1.Function) {
|
||||
ERR(win32, "No implementation for %s.%d, setting to 0xdeadbeef\n",
|
||||
|
@ -355,7 +334,7 @@ DWORD fixup_imports (PDB32 *process,WINE_MODREF *wm)
|
|||
TRACE(win32,"--- %s %s.%d\n",
|
||||
pe_name->Name,name,pe_name->Hint);
|
||||
thunk_list->u1.Function=MODULE_GetProcAddress32(
|
||||
process, hImpModule, pe_name->Name
|
||||
process, hImpModule, pe_name->Name, TRUE
|
||||
);
|
||||
if (!thunk_list->u1.Function) {
|
||||
ERR(win32, "No implementation for %s.%d, setting to 0xdeadbeef\n",
|
||||
|
@ -915,12 +894,19 @@ int PE_UnloadImage( HMODULE32 hModule )
|
|||
* DLL_PROCESS_ATTACH. Only new created threads do DLL_THREAD_ATTACH
|
||||
* (SDK)
|
||||
*/
|
||||
static void PE_InitDLL(WINE_MODREF *wm, DWORD type,LPVOID lpReserved)
|
||||
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)
|
||||
wm->binfmt.pe.flags |= PE_MODREF_PROCESS_ATTACHED;
|
||||
{
|
||||
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
|
||||
|
@ -936,32 +922,11 @@ static void PE_InitDLL(WINE_MODREF *wm, DWORD type,LPVOID lpReserved)
|
|||
DLLENTRYPROC32 entry = (void*)RVA_PTR( wm->module,OptionalHeader.AddressOfEntryPoint );
|
||||
TRACE(relay, "CallTo32(entryproc=%p,module=%08x,type=%ld,res=%p)\n",
|
||||
entry, wm->module, type, lpReserved );
|
||||
|
||||
entry( wm->module, type, lpReserved );
|
||||
}
|
||||
}
|
||||
|
||||
/* Call the DLLentry function of all dlls used by that process.
|
||||
* (NOTE: this may recursively call this function (if a library calls
|
||||
* LoadLibrary) ... but it won't matter)
|
||||
*/
|
||||
void PE_InitializeDLLs(PDB32 *process,DWORD type,LPVOID lpReserved) {
|
||||
WINE_MODREF *wm;
|
||||
|
||||
for (wm = process->modref_list;wm;wm=wm->next) {
|
||||
PE_MODREF *pem = NULL;
|
||||
if (wm->type!=MODULE32_PE)
|
||||
continue;
|
||||
pem = &(wm->binfmt.pe);
|
||||
if (pem->flags & PE_MODREF_NO_DLL_CALLS)
|
||||
continue;
|
||||
if (type==DLL_PROCESS_ATTACH) {
|
||||
if (pem->flags & PE_MODREF_PROCESS_ATTACHED)
|
||||
continue;
|
||||
}
|
||||
PE_InitDLL( wm, type, lpReserved );
|
||||
}
|
||||
}
|
||||
|
||||
void PE_InitTls(THDB *thdb)
|
||||
{
|
||||
WINE_MODREF *wm;
|
||||
|
|
|
@ -250,7 +250,7 @@ static void TASK_CallToStart(void)
|
|||
LocalInit( pTask->hInstance, 0, pModule->heap_size );
|
||||
|
||||
InitApp( pTask->hModule );
|
||||
PE_InitializeDLLs( PROCESS_Current(), DLL_PROCESS_ATTACH, (LPVOID)-1 );
|
||||
MODULE_InitializeDLLs( PROCESS_Current(), 0, DLL_PROCESS_ATTACH, (LPVOID)-1 );
|
||||
TRACE(relay, "(entryproc=%p)\n", entry );
|
||||
|
||||
#if 1
|
||||
|
@ -892,9 +892,8 @@ void WINAPI PostEvent( HTASK16 hTask )
|
|||
|
||||
if ( !THREAD_IsWin16( THREAD_Current() ) )
|
||||
{
|
||||
FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel);
|
||||
memset(0, 0, 4096);
|
||||
return;
|
||||
WARN(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel);
|
||||
/* return; */
|
||||
}
|
||||
|
||||
pTask->nEvents++;
|
||||
|
|
|
@ -365,7 +365,7 @@ void THREAD_Start( THDB *thdb )
|
|||
LPTHREAD_START_ROUTINE func = (LPTHREAD_START_ROUTINE)thdb->entry_point;
|
||||
assert( THREAD_Current() == thdb );
|
||||
CLIENT_InitThread();
|
||||
PE_InitializeDLLs( thdb->process, DLL_THREAD_ATTACH, NULL );
|
||||
MODULE_InitializeDLLs( thdb->process, NULL, DLL_THREAD_ATTACH, NULL );
|
||||
ExitThread( func( thdb->entry_arg ) );
|
||||
}
|
||||
|
||||
|
@ -413,7 +413,7 @@ void WINAPI ExitThread(
|
|||
/* Remove thread from process's list */
|
||||
THREAD_RemoveQueue( &thdb->process->thread_list, thdb );
|
||||
|
||||
PE_InitializeDLLs( thdb->process, DLL_THREAD_DETACH, NULL );
|
||||
MODULE_InitializeDLLs( thdb->process, NULL, DLL_THREAD_DETACH, NULL );
|
||||
|
||||
SYSTEM_LOCK();
|
||||
thdb->exit_code = code;
|
||||
|
|
185
win32/kernel32.c
185
win32/kernel32.c
|
@ -81,30 +81,32 @@ static void _write_qtthunk(
|
|||
/***********************************************************************
|
||||
* _loadthunk
|
||||
*/
|
||||
static LPVOID _loadthunk(LPSTR module, LPSTR func, LPSTR module32,
|
||||
struct ThunkDataCommon *TD32)
|
||||
static LPVOID _loadthunk(LPCSTR module, LPCSTR func, LPCSTR module32,
|
||||
struct ThunkDataCommon *TD32, DWORD checksum)
|
||||
{
|
||||
struct ThunkDataCommon *TD16;
|
||||
HMODULE32 hmod;
|
||||
int ordinal;
|
||||
|
||||
if ((hmod = LoadLibrary16(module)) <= 32)
|
||||
{
|
||||
ERR(thunk, "(%s, %s, %s, %p): Unable to load '%s', error %d\n",
|
||||
module, func, module32, TD32, module, hmod);
|
||||
ERR(thunk, "(%s, %s, %s): Unable to load '%s', error %d\n",
|
||||
module, func, module32, module, hmod);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(TD16 = PTR_SEG_TO_LIN(WIN32_GetProcAddress16(hmod, func))))
|
||||
if ( !(ordinal = NE_GetOrdinal(hmod, func))
|
||||
|| !(TD16 = PTR_SEG_TO_LIN(NE_GetEntryPointEx(hmod, ordinal, FALSE))))
|
||||
{
|
||||
ERR(thunk, "(%s, %s, %s, %p): Unable to find '%s'\n",
|
||||
module, func, module32, TD32, func);
|
||||
ERR(thunk, "(%s, %s, %s): Unable to find '%s'\n",
|
||||
module, func, module32, func);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (TD32 && memcmp(TD16->magic, TD32->magic, 4))
|
||||
{
|
||||
ERR(thunk, "(%s, %s, %s, %p): Bad magic %c%c%c%c (should be %c%c%c%c)\n",
|
||||
module, func, module32, TD32,
|
||||
ERR(thunk, "(%s, %s, %s): Bad magic %c%c%c%c (should be %c%c%c%c)\n",
|
||||
module, func, module32,
|
||||
TD16->magic[0], TD16->magic[1], TD16->magic[2], TD16->magic[3],
|
||||
TD32->magic[0], TD32->magic[1], TD32->magic[2], TD32->magic[3]);
|
||||
return 0;
|
||||
|
@ -112,8 +114,15 @@ static LPVOID _loadthunk(LPSTR module, LPSTR func, LPSTR module32,
|
|||
|
||||
if (TD32 && TD16->checksum != TD32->checksum)
|
||||
{
|
||||
ERR(thunk, "(%s, %s, %s, %p): Wrong checksum %08lx (should be %08lx)\n",
|
||||
module, func, module32, TD32, TD16->checksum, TD32->checksum);
|
||||
ERR(thunk, "(%s, %s, %s): Wrong checksum %08lx (should be %08lx)\n",
|
||||
module, func, module32, TD16->checksum, TD32->checksum);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!TD32 && checksum && checksum != *(LPDWORD)TD16)
|
||||
{
|
||||
ERR(thunk, "(%s, %s, %s): Wrong checksum %08lx (should be %08lx)\n",
|
||||
module, func, module32, *(LPDWORD)TD16, checksum);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -125,7 +134,7 @@ static LPVOID _loadthunk(LPSTR module, LPSTR func, LPSTR module32,
|
|||
*/
|
||||
LPVOID WINAPI GetThunkStuff(LPSTR module, LPSTR func)
|
||||
{
|
||||
return _loadthunk(module, func, "<kernel>", NULL);
|
||||
return _loadthunk(module, func, "<kernel>", NULL, 0L);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -177,7 +186,7 @@ UINT32 WINAPI ThunkConnect32(
|
|||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
struct ThunkDataCommon *TD16;
|
||||
if (!(TD16 = _loadthunk(module16, thunkfun16, module32, TD)))
|
||||
if (!(TD16 = _loadthunk(module16, thunkfun16, module32, TD, 0L)))
|
||||
return 0;
|
||||
|
||||
if (directionSL)
|
||||
|
@ -489,34 +498,15 @@ DWORD WINAPI ThunkInitLS(
|
|||
LPCSTR dll16, /* [in] name of win16 dll */
|
||||
LPCSTR dll32 /* [in] name of win32 dll (FIXME: not used?) */
|
||||
) {
|
||||
HINSTANCE16 hmod;
|
||||
LPDWORD addr;
|
||||
SEGPTR segaddr;
|
||||
|
||||
hmod = LoadLibrary16(dll16);
|
||||
if (hmod<32) {
|
||||
WARN(thunk,"failed to load 16bit DLL %s, error %d\n",
|
||||
dll16,hmod);
|
||||
if (!(addr = _loadthunk( dll16, thkbuf, dll32, NULL, len )))
|
||||
return 0;
|
||||
}
|
||||
segaddr = (DWORD)WIN32_GetProcAddress16(hmod,(LPSTR)thkbuf);
|
||||
if (!segaddr) {
|
||||
WARN(thunk,"no %s exported from %s!\n",thkbuf,dll16);
|
||||
return 0;
|
||||
}
|
||||
addr = (LPDWORD)PTR_SEG_TO_LIN(segaddr);
|
||||
if (addr[0] != len) {
|
||||
WARN(thunk,"thkbuf length mismatch? %ld vs %ld\n",len,addr[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!addr[1])
|
||||
return 0;
|
||||
*(DWORD*)thunk = addr[1];
|
||||
|
||||
TRACE(thunk, "loaded module %d, func %s (%d) @ %p (%p), returning %p\n",
|
||||
hmod, HIWORD(thkbuf)==0 ? "<ordinal>" : thkbuf, (int)thkbuf,
|
||||
(void*)segaddr, addr, (void*)addr[1]);
|
||||
|
||||
return addr[1];
|
||||
}
|
||||
|
||||
|
@ -684,9 +674,7 @@ LPVOID WINAPI ThunkInitLSF(
|
|||
LPCSTR dll32 /* [in] name of win32 dll */
|
||||
) {
|
||||
HMODULE32 hkrnl32 = GetModuleHandle32A("KERNEL32");
|
||||
HMODULE16 hmod;
|
||||
LPDWORD addr,addr2;
|
||||
DWORD segaddr;
|
||||
|
||||
/* FIXME: add checks for valid code ... */
|
||||
/* write pointers to kernel32.89 and kernel32.90 (+ordinal base of 1) */
|
||||
|
@ -694,30 +682,13 @@ LPVOID WINAPI ThunkInitLSF(
|
|||
*(DWORD*)(thunk+0x6D) = (DWORD)GetProcAddress32(hkrnl32,(LPSTR)89);
|
||||
|
||||
|
||||
hmod = LoadLibrary16(dll16);
|
||||
if (hmod<32) {
|
||||
ERR(thunk,"failed to load 16bit DLL %s, error %d\n",
|
||||
dll16,hmod);
|
||||
return NULL;
|
||||
}
|
||||
segaddr = (DWORD)WIN32_GetProcAddress16(hmod,(LPSTR)thkbuf);
|
||||
if (!segaddr) {
|
||||
ERR(thunk,"no %s exported from %s!\n",thkbuf,dll16);
|
||||
return NULL;
|
||||
}
|
||||
addr = (LPDWORD)PTR_SEG_TO_LIN(segaddr);
|
||||
if (addr[0] != len) {
|
||||
ERR(thunk,"thkbuf length mismatch? %ld vs %ld\n",len,addr[0]);
|
||||
return NULL;
|
||||
}
|
||||
if (!(addr = _loadthunk( dll16, thkbuf, dll32, NULL, len )))
|
||||
return 0;
|
||||
|
||||
addr2 = PTR_SEG_TO_LIN(addr[1]);
|
||||
if (HIWORD(addr2))
|
||||
*(DWORD*)thunk = (DWORD)addr2;
|
||||
|
||||
TRACE(thunk, "loaded module %d, func %s(%d) @ %p (%p), returning %p\n",
|
||||
hmod, HIWORD(thkbuf)==0 ? "<ordinal>" : thkbuf, (int)thkbuf,
|
||||
(void*)segaddr, addr, addr2);
|
||||
|
||||
return addr2;
|
||||
}
|
||||
|
||||
|
@ -796,30 +767,11 @@ VOID WINAPI ThunkInitSL(
|
|||
LPCSTR dll32 /* [in] win32 dll. FIXME: strange, unused */
|
||||
) {
|
||||
LPDWORD addr;
|
||||
HMODULE16 hmod;
|
||||
SEGPTR segaddr;
|
||||
|
||||
hmod = LoadLibrary16(dll16);
|
||||
if (hmod < 32) {
|
||||
ERR(thunk,"couldn't load %s, error %d\n",dll16,hmod);
|
||||
if (!(addr = _loadthunk( dll16, thkbuf, dll32, NULL, len )))
|
||||
return;
|
||||
}
|
||||
segaddr = (SEGPTR)WIN32_GetProcAddress16(hmod,(LPSTR)thkbuf);
|
||||
if (!segaddr) {
|
||||
ERR(thunk,"haven't found %s in %s!\n",thkbuf,dll16);
|
||||
return;
|
||||
}
|
||||
addr = (LPDWORD)PTR_SEG_TO_LIN(segaddr);
|
||||
if (addr[0] != len) {
|
||||
ERR(thunk,"length of thkbuf differs from expected length! "
|
||||
"(%ld vs %ld)\n",addr[0],len);
|
||||
return;
|
||||
}
|
||||
|
||||
*(DWORD*)PTR_SEG_TO_LIN(addr[1]) = (DWORD)thunk;
|
||||
|
||||
TRACE(thunk, "loaded module %d, func %s(%d) @ %p (%p)\n",
|
||||
hmod, HIWORD(thkbuf)==0 ? "<ordinal>" : thkbuf,
|
||||
(int)thkbuf, (void*)segaddr, addr);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
@ -908,82 +860,17 @@ DWORD WINAPIV SSCall(
|
|||
}
|
||||
|
||||
/**********************************************************************
|
||||
* InitCBClient (KERNEL.623)
|
||||
* W32S_BackTo32 (KERNEL32.51)
|
||||
*/
|
||||
WORD WINAPI InitCBClient(DWORD x)
|
||||
REGS_ENTRYPOINT(W32S_BackTo32)
|
||||
{
|
||||
FIXME(thunk,"(0x%08lx): stub\n",x);
|
||||
return TRUE;
|
||||
}
|
||||
LPDWORD stack = (LPDWORD)ESP_reg( context );
|
||||
FARPROC32 proc = (FARPROC32) stack[0];
|
||||
|
||||
/**********************************************************************
|
||||
* RegisterCBClient (KERNEL.619)
|
||||
* Seems to store y and z depending on x in some internal lists...
|
||||
*/
|
||||
WORD WINAPI RegisterCBClient(WORD x,DWORD y,DWORD z)
|
||||
{
|
||||
FIXME(thunk,"(0x%04x,0x%08lx,0x%08lx): stub\n",x,y,z);
|
||||
return x;
|
||||
}
|
||||
EAX_reg( context ) = proc( stack[2], stack[3], stack[4], stack[5], stack[6],
|
||||
stack[7], stack[8], stack[9], stack[10], stack[11] );
|
||||
|
||||
/**********************************************************************
|
||||
* KERNEL_607 (KERNEL)
|
||||
*/
|
||||
LPVOID WINAPI _KERNEL_607(SEGPTR target, LPVOID relay, DWORD dummy)
|
||||
{
|
||||
TDB *pTask = (TDB*)GlobalLock16(GetCurrentTask());
|
||||
LPBYTE thunk = HeapAlloc( GetProcessHeap(), 0, 22 ), x = thunk;
|
||||
|
||||
*x++=0x90; *x++=0x68; *((DWORD*)x)++=(DWORD)relay; /* nop; pushl relay */
|
||||
*x++=0x90; *x++=0x68; *((DWORD*)x)++=(DWORD)target; /* nop; pushl target */
|
||||
*x++=0x90; *x++=0x58; /* nop; popl eax */
|
||||
*x++=0xC3; /* ret */
|
||||
*x++=0xCC; *x++=0xCC;
|
||||
*x++=0x01; /* type: LS */
|
||||
*((WORD *)x)++ = pTask->hInstance; /* owner */
|
||||
*((WORD *)x)++ = 0; /* next */
|
||||
|
||||
return thunk;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* KERNEL_608 (KERNEL)
|
||||
*/
|
||||
SEGPTR WINAPI _KERNEL_608(LPVOID target, SEGPTR relay, DWORD dummy)
|
||||
{
|
||||
TDB *pTask = (TDB*)GlobalLock16(GetCurrentTask());
|
||||
LPBYTE thunk = HeapAlloc( GetProcessHeap(), 0, 22 ), x = thunk;
|
||||
WORD sel;
|
||||
|
||||
*x++=0x66; *x++=0x68; *((DWORD*)x)++=(DWORD)relay; /* pushl relay */
|
||||
*x++=0x66; *x++=0x68; *((DWORD*)x)++=(DWORD)target; /* pushl target */
|
||||
*x++=0x66; *x++=0x58; /* popl eax */
|
||||
*x++=0xCB; /* ret */
|
||||
*x++=0xCC; *x++=0xCC;
|
||||
*x++=0x02; /* type: SL */
|
||||
*((WORD *)x)++ = pTask->hInstance; /* owner */
|
||||
*((WORD *)x)++ = 0; /* next */
|
||||
|
||||
sel = SELECTOR_AllocBlock( thunk, 22, SEGMENT_CODE, FALSE, FALSE );
|
||||
return PTR_SEG_OFF_TO_SEGPTR( sel, 0 );
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* KERNEL_611 (KERNEL)
|
||||
*/
|
||||
VOID WINAPI _KERNEL_611(DWORD relay, DWORD target)
|
||||
{
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* KERNEL_612 (KERNEL)
|
||||
*/
|
||||
BOOL16 WINAPI _KERNEL_612(LPBYTE target)
|
||||
{
|
||||
return target[ 0] == 0x66 && target[ 1] == 0x68
|
||||
&& target[ 6] == 0x66 && target[ 2] == 0x68
|
||||
&& target[12] == 0x66 && target[13] == 0x58
|
||||
&& target[14] == 0xCB;
|
||||
EIP_reg( context ) = stack[1];
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
|
Loading…
Reference in New Issue