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:
Ulrich Weigand 1998-10-11 19:31:10 +00:00 committed by Alexandre Julliard
parent 2e244c45a3
commit a3527cf369
7 changed files with 161 additions and 228 deletions

View File

@ -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,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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];
}
/**********************************************************************