diff --git a/include/module.h b/include/module.h index b7439e83cbb..55a376b5d75 100644 --- a/include/module.h +++ b/include/module.h @@ -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, diff --git a/include/pe_image.h b/include/pe_image.h index bace33f6464..d58042511c7 100644 --- a/include/pe_image.h +++ b/include/pe_image.h @@ -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); diff --git a/loader/module.c b/loader/module.c index c26df0d5d7e..93aadfe851b 100644 --- a/loader/module.c +++ b/loader/module.c @@ -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 ) { diff --git a/loader/pe_image.c b/loader/pe_image.c index 5c282f4b7c7..8e5f65fdc0d 100644 --- a/loader/pe_image.c +++ b/loader/pe_image.c @@ -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; diff --git a/loader/task.c b/loader/task.c index e55207e6843..cd9ff46e9bd 100644 --- a/loader/task.c +++ b/loader/task.c @@ -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++; diff --git a/scheduler/thread.c b/scheduler/thread.c index 3a0ff9775c0..255e3fe2675 100644 --- a/scheduler/thread.c +++ b/scheduler/thread.c @@ -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; diff --git a/win32/kernel32.c b/win32/kernel32.c index 160435e67cc..4973b8ff58c 100644 --- a/win32/kernel32.c +++ b/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, "", NULL); + return _loadthunk(module, func, "", 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 ? "" : 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 ? "" : 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 ? "" : 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]; } /**********************************************************************