From c50a1d05deded9e8b369bcd4b4ddcf43b1243ecb Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Sun, 15 Aug 1999 12:45:01 +0000 Subject: [PATCH] Adapted to new-style Wine thunks. Removed some now unnecessary function pointers. --- if1632/builtin.c | 29 ++----- if1632/relay.c | 54 +++++-------- if1632/snoop.c | 48 +++++------- if1632/thunk.c | 94 +++------------------- include/callback.h | 3 - include/module.h | 8 -- include/snoop.h | 5 +- loader/module.c | 1 + loader/ne/module.c | 16 ++-- loader/ne/segment.c | 26 +------ loader/task.c | 5 +- windows/winproc.c | 186 ++++++++++++++++++++++++++++++++++---------- 12 files changed, 213 insertions(+), 262 deletions(-) diff --git a/if1632/builtin.c b/if1632/builtin.c index 6fb852bfbe..7be0d6799c 100644 --- a/if1632/builtin.c +++ b/if1632/builtin.c @@ -10,6 +10,7 @@ #include "winbase.h" #include "wine/winbase16.h" #include "wine/winestring.h" +#include "builtin16.h" #include "builtin32.h" #include "global.h" #include "heap.h" @@ -19,25 +20,12 @@ #include "stackframe.h" #include "user.h" #include "process.h" -#include "snoop.h" #include "task.h" #include "debugtools.h" #include "toolhelp.h" DEFAULT_DEBUG_CHANNEL(module) -/* Built-in modules descriptors */ -/* Don't change these structures! (see tools/build.c) */ - -typedef struct -{ - const char *name; /* DLL name */ - void *module_start; /* 32-bit address of the module data */ - int module_size; /* Size of the module data */ - const BYTE *code_start; /* 32-bit address of DLL code */ - const BYTE *data_start; /* 32-bit address of DLL data */ -} WIN16_DESCRIPTOR; - typedef struct { const WIN16_DESCRIPTOR *descr; /* DLL descriptor */ @@ -209,8 +197,6 @@ BOOL BUILTIN_Init(void) WORD vector; HMODULE16 hModule; - fnBUILTIN_LoadModule = BUILTIN_LoadModule; - for (dll = BuiltinDLLs; dll->descr; dll++) { if (dll->flags & DLL_FLAG_ALWAYS_USED) @@ -228,8 +214,6 @@ BOOL BUILTIN_Init(void) INT_SetPMHandler( vector, proc ); } - SNOOP16_Init(); - return TRUE; } @@ -266,7 +250,7 @@ HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL force ) * Return the ordinal, name, and type info corresponding to a CS:IP address. * This is used only by relay debugging. */ -LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, LPSTR name, WORD *pOrd ) +LPCSTR BUILTIN_GetEntryPoint16( STACK16FRAME *frame, LPSTR name, WORD *pOrd ) { WORD i, max_offset; register BYTE *p; @@ -274,7 +258,7 @@ LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, LPSTR name, WORD *pOrd ) ET_BUNDLE *bundle; ET_ENTRY *entry; - if (!(pModule = NE_GetPtr( FarGetOwner16( GlobalHandle16(cs) )))) + if (!(pModule = NE_GetPtr( FarGetOwner16( GlobalHandle16( frame->module_cs ) )))) return NULL; max_offset = 0; @@ -285,7 +269,7 @@ LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, LPSTR name, WORD *pOrd ) entry = (ET_ENTRY *)((BYTE *)bundle+6); for (i = bundle->first + 1; i <= bundle->last; i++) { - if ((entry->offs < ip) + if ((entry->offs < frame->entry_ip) && (entry->segnum == 1) /* code segment ? */ && (entry->offs >= max_offset)) { @@ -313,7 +297,7 @@ LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, LPSTR name, WORD *pOrd ) *pOrd, *p, (char *)(p + 1) ); /* Retrieve type info string */ - return *(LPCSTR *)((LPBYTE)PTR_SEG_OFF_TO_LIN( cs, ip ) - 6) + 10; + return *(LPCSTR *)((LPBYTE)PTR_SEG_OFF_TO_LIN( frame->module_cs, frame->callfrom_ip ) + 4); } @@ -326,8 +310,7 @@ void WINAPI BUILTIN_DefaultIntHandler( CONTEXT86 *context ) { WORD ordinal; char name[80]; - STACK16FRAME *frame = CURRENT_STACK16; - BUILTIN_GetEntryPoint16( frame->entry_cs, frame->entry_ip, name, &ordinal ); + BUILTIN_GetEntryPoint16( CURRENT_STACK16, name, &ordinal ); INT_BARF( context, ordinal - FIRST_INTERRUPT_ORDINAL ); } diff --git a/if1632/relay.c b/if1632/relay.c index f7bde62438..4b2d16675d 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -12,6 +12,7 @@ #include "heap.h" #include "module.h" #include "stackframe.h" +#include "builtin16.h" #include "task.h" #include "syslevel.h" #include "debugstr.h" @@ -77,7 +78,7 @@ void RELAY_DebugCallFrom16( CONTEXT86 *context ) if (!TRACE_ON(relay)) return; frame = CURRENT_STACK16; - args = BUILTIN_GetEntryPoint16(frame->entry_cs,frame->entry_ip,funstr,&ordinal); + args = BUILTIN_GetEntryPoint16( frame, funstr, &ordinal ); if (!args) return; /* happens for the two snoop register relays */ if (!RELAY_ShowDebugmsgRelay(funstr)) return; DPRINTF( "Call %s(",funstr); @@ -205,7 +206,7 @@ void RELAY_DebugCallFrom16Ret( CONTEXT86 *context, int ret_val ) if (!TRACE_ON(relay)) return; frame = CURRENT_STACK16; - args = BUILTIN_GetEntryPoint16(frame->entry_cs,frame->entry_ip,funstr,&ordinal); + args = BUILTIN_GetEntryPoint16( frame, funstr, &ordinal ); if (!args) return; if (!RELAY_ShowDebugmsgRelay(funstr)) return; DPRINTF( "Ret %s() ",funstr); @@ -246,7 +247,7 @@ void RELAY_Unimplemented16(void) WORD ordinal; char name[80]; STACK16FRAME *frame = CURRENT_STACK16; - BUILTIN_GetEntryPoint16(frame->entry_cs,frame->entry_ip,name,&ordinal); + BUILTIN_GetEntryPoint16( frame, name, &ordinal ); MESSAGE("No handler for Win16 routine %s (called from %04x:%04x)\n", name, frame->cs, frame->ip ); ExitProcess(1); @@ -256,31 +257,29 @@ void RELAY_Unimplemented16(void) /*********************************************************************** * RELAY_DebugCallTo16 * - * 'stack' points to the called function address on the 32-bit stack. - * Stack layout: - * ... ... - * (stack+8) arg2 - * (stack+4) arg1 - * (stack) func to call + * 'target' contains either the function to call (normal CallTo16) + * or a pointer to the CONTEXT86 struct (register CallTo16). + * 'nb_args' is the number of argument bytes on the 16-bit stack; + * 'reg_func' specifies whether we have a register CallTo16 or not. */ -void RELAY_DebugCallTo16( int* stack, int nb_args ) +void RELAY_DebugCallTo16( LPVOID target, int nb_args, BOOL reg_func ) { + WORD *stack16; TEB *teb; if (!TRACE_ON(relay)) return; teb = NtCurrentTeb(); + stack16 = (WORD *)THREAD_STACK16(teb); - if (nb_args == -1) /* Register function */ + nb_args /= sizeof(WORD); + + if ( reg_func ) { - CONTEXT86 *context = (CONTEXT86 *)stack[0]; - WORD *stack16 = (WORD *)THREAD_STACK16(teb); + CONTEXT86 *context = (CONTEXT86 *)target; + DPRINTF("CallTo16(func=%04lx:%04x,ds=%04lx", CS_reg(context), LOWORD(EIP_reg(context)), DS_reg(context) ); - nb_args = stack[1] / sizeof(WORD); - while (nb_args--) { - --stack16; - DPRINTF( ",0x%04x", *stack16 ); - } + while (nb_args--) DPRINTF( ",0x%04x", *--stack16 ); DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(teb->cur_stack), OFFSETOF(teb->cur_stack) ); DPRINTF(" AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x BP=%04x ES=%04x FS=%04x\n", @@ -291,13 +290,8 @@ void RELAY_DebugCallTo16( int* stack, int nb_args ) else { DPRINTF("CallTo16(func=%04x:%04x,ds=%04x", - HIWORD(stack[0]), LOWORD(stack[0]), - SELECTOROF(teb->cur_stack) ); - stack++; - while (nb_args--) { - DPRINTF(",0x%04x", *stack ); - stack++; - } + HIWORD(target), LOWORD(target), SELECTOROF(teb->cur_stack) ); + while (nb_args--) DPRINTF( ",0x%04x", *--stack16 ); DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(teb->cur_stack), OFFSETOF(teb->cur_stack) ); } @@ -398,16 +392,6 @@ void WINAPI Throw16( LPCATCHBUF lpbuf, INT16 retval, CONTEXT86 *context ) if (lpbuf[8] != SS_reg(context)) ERR("Switching stack segment with Throw() not supported; expect crash now\n" ); - - if (TRACE_ON(relay)) /* Make sure we have a valid entry point address */ - { - static FARPROC16 entryPoint = NULL; - - if (!entryPoint) /* Get entry point for Throw() */ - entryPoint = NE_GetEntryPoint( GetModuleHandle16("KERNEL"), 56 ); - pFrame->entry_cs = SELECTOROF(entryPoint); - pFrame->entry_ip = OFFSETOF(entryPoint); - } } diff --git a/if1632/snoop.c b/if1632/snoop.c index ccc35f2e32..699999cef1 100644 --- a/if1632/snoop.c +++ b/if1632/snoop.c @@ -12,6 +12,7 @@ #include "global.h" #include "selectors.h" #include "stackframe.h" +#include "builtin16.h" #include "snoop.h" #include "debugstr.h" #include "debugtools.h" @@ -22,17 +23,8 @@ DEFAULT_DEBUG_CHANNEL(snoop) #include "pshpack1.h" -void WINAPI SNOOP16_Entry(CONTEXT86 *context); -void WINAPI SNOOP16_Return(CONTEXT86 *context); -extern void KERNEL_CallFrom16_p_regs_(); - -/* Generic callfrom16_p_regs function entry. - * pushw %bp 0x55 - * pushl $DOS3Call DWORD fun32 - * .byte 0x9a 0x9a - * .long CallFrom16_p_regs_ DWORD addr - * .long 0x90900023 WORD seg;nop;nop - */ +void WINAPI SNOOP16_Entry(FARPROC proc, LPBYTE args, CONTEXT86 *context); +void WINAPI SNOOP16_Return(FARPROC proc, LPBYTE args, CONTEXT86 *context); typedef struct tagSNOOP16_FUN { /* code part */ @@ -71,15 +63,15 @@ typedef struct tagSNOOP16_RETURNENTRIES { } SNOOP16_RETURNENTRIES; typedef struct tagSNOOP16_RELAY { - /* code part */ - BYTE prefix; /* 0x66 , 32bit prefix */ - BYTE pushbp; /* 0x55 */ + WORD pushbp; /* 0x5566 */ + BYTE pusheax; /* 0x50 */ + WORD pushax; /* 0x5066 */ BYTE pushl; /* 0x68 */ DWORD realfun; /* SNOOP16_Return */ BYTE lcall; /* 0x9a call absolute with segment */ DWORD callfromregs; WORD seg; - /* unreached */ + WORD lret; /* 0xcb66 */ } SNOOP16_RELAY; #include "poppack.h" @@ -98,20 +90,25 @@ SNOOP16_RegisterDLL(NE_MODULE *pModule,LPCSTR name) { if (!snr) { xsnr=GLOBAL_Alloc(GMEM_ZEROINIT,2*sizeof(*snr),0,TRUE,TRUE,FALSE); snr = GlobalLock16(xsnr); - snr[0].prefix = 0x66; - snr[0].pushbp = 0x55; + snr[0].pushbp = 0x5566; + snr[0].pusheax = 0x50; + snr[0].pushax = 0x5066; snr[0].pushl = 0x68; snr[0].realfun = (DWORD)SNOOP16_Entry; snr[0].lcall = 0x9a; - snr[0].callfromregs = (DWORD)KERNEL_CallFrom16_p_regs_; + snr[0].callfromregs = (DWORD)CallFrom16Register; GET_CS(snr[0].seg); - snr[1].prefix = 0x66; - snr[1].pushbp = 0x55; + snr[0].lret = 0xcb66; + + snr[1].pushbp = 0x5566; + snr[1].pusheax = 0x50; + snr[1].pushax = 0x5066; snr[1].pushl = 0x68; snr[1].realfun = (DWORD)SNOOP16_Return; snr[1].lcall = 0x9a; - snr[1].callfromregs = (DWORD)KERNEL_CallFrom16_p_regs_; + snr[1].callfromregs = (DWORD)CallFrom16Register; GET_CS(snr[1].seg); + snr[1].lret = 0xcb66; } while (*dll) { if ((*dll)->hmod == pModule->self) @@ -209,7 +206,7 @@ SNOOP16_GetProcAddress16(HMODULE16 hmod,DWORD ordinal,FARPROC16 origfun) { } #define CALLER1REF (*(DWORD*)(PTR_SEG_OFF_TO_LIN(SS_reg(context),LOWORD(ESP_reg(context))+4))) -void WINAPI SNOOP16_Entry(CONTEXT86 *context) { +void WINAPI SNOOP16_Entry(FARPROC proc, LPBYTE args, CONTEXT86 *context) { DWORD ordinal=0; DWORD entry=(DWORD)PTR_SEG_OFF_TO_LIN(CS_reg(context),LOWORD(EIP_reg(context)))-5; WORD xcs = CS_reg(context); @@ -276,7 +273,7 @@ void WINAPI SNOOP16_Entry(CONTEXT86 *context) { DPRINTF(") ret=%04x:%04x\n",HIWORD(ret->origreturn),LOWORD(ret->origreturn)); } -void WINAPI SNOOP16_Return(CONTEXT86 *context) { +void WINAPI SNOOP16_Return(FARPROC proc, LPBYTE args, CONTEXT86 *context) { SNOOP16_RETURNENTRY *ret = (SNOOP16_RETURNENTRY*)((char *) PTR_SEG_OFF_TO_LIN(CS_reg(context),LOWORD(EIP_reg(context)))-5); /* We haven't found out the nrofargs yet. If we called a cdecl @@ -326,8 +323,3 @@ FARPROC16 SNOOP16_GetProcAddress16(HMODULE16 hmod,DWORD ordinal,FARPROC16 origfu } #endif /* !__i386__ */ -void -SNOOP16_Init() { - fnSNOOP16_GetProcAddress16=SNOOP16_GetProcAddress16; - fnSNOOP16_RegisterDLL=SNOOP16_RegisterDLL; -} diff --git a/if1632/thunk.c b/if1632/thunk.c index 46fe8eff90..e753c3b10e 100644 --- a/if1632/thunk.c +++ b/if1632/thunk.c @@ -104,7 +104,6 @@ extern LONG CALLBACK THUNK_CallTo16_long_llllllllllllllll(FARPROC16,LONG,LONG,LO LONG,LONG,LONG,LONG,LONG, LONG,LONG,LONG,LONG,LONG, LONG,LONG,LONG); -extern void CALLBACK THUNK_CallFrom16_p_long_wwwll(); /* ### stop build ### */ @@ -137,9 +136,6 @@ typedef struct tagTHUNK static THUNK *firstThunk = NULL; -static LRESULT WINAPI THUNK_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, - UINT16 msg, WPARAM16 wParam, - LPARAM lParam ); static BOOL WINAPI THUNK_WOWCallback16Ex( FARPROC16,DWORD,DWORD, LPVOID,LPDWORD ); static BOOL THUNK_ThunkletInit( void ); @@ -149,8 +145,6 @@ static const CALLBACKS_TABLE CALLBACK_EmulatorTable = { (void *)CallTo16RegisterShort, /* CallRegisterShortProc */ (void *)CallTo16RegisterLong, /* CallRegisterLongProc */ - (void*)THUNK_CallFrom16_p_long_wwwll, /* CallFrom16WndProc */ - THUNK_CallWndProc16, /* CallWndProc */ (void *)THUNK_CallTo16_long_lwwll, /* CallDriverProc */ (void *)THUNK_CallTo16_word_wwlll, /* CallDriverCallback */ (void *)THUNK_CallTo16_word_wwlll, /* CallTimeFuncProc */ @@ -242,80 +236,6 @@ static void THUNK_Free( THUNK *thunk ) } -/*********************************************************************** - * THUNK_CallWndProc16 - * - * Call a 16-bit window procedure - */ -static LRESULT WINAPI THUNK_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, - UINT16 msg, WPARAM16 wParam, - LPARAM lParam ) -{ - CONTEXT86 context; - LRESULT ret; - WORD *args; - WND *wndPtr = WIN_FindWndPtr( hwnd ); - DWORD offset = 0; - TEB *teb = NtCurrentTeb(); - int iWndsLocks; - - /* Window procedures want ax = hInstance, ds = es = ss */ - - memset(&context, '\0', sizeof(context)); - DS_reg(&context) = SELECTOROF(teb->cur_stack); - ES_reg(&context) = DS_reg(&context); - EAX_reg(&context) = wndPtr ? wndPtr->hInstance : DS_reg(&context); - CS_reg(&context) = SELECTOROF(proc); - EIP_reg(&context) = OFFSETOF(proc); - EBP_reg(&context) = OFFSETOF(teb->cur_stack) - + (WORD)&((STACK16FRAME*)0)->bp; - - WIN_ReleaseWndPtr(wndPtr); - - if (lParam) - { - /* Some programs (eg. the "Undocumented Windows" examples, JWP) only - work if structures passed in lParam are placed in the stack/data - segment. Programmers easily make the mistake of converting lParam - to a near rather than a far pointer, since Windows apparently - allows this. We copy the structures to the 16 bit stack; this is - ugly but makes these programs work. */ - switch (msg) - { - case WM_CREATE: - case WM_NCCREATE: - offset = sizeof(CREATESTRUCT16); break; - case WM_DRAWITEM: - offset = sizeof(DRAWITEMSTRUCT16); break; - case WM_COMPAREITEM: - offset = sizeof(COMPAREITEMSTRUCT16); break; - } - if (offset) - { - void *s = PTR_SEG_TO_LIN(lParam); - lParam = stack16_push( offset ); - memcpy( PTR_SEG_TO_LIN(lParam), s, offset ); - } - } - - iWndsLocks = WIN_SuspendWndsLock(); - - args = (WORD *)THREAD_STACK16(teb) - 5; - args[0] = LOWORD(lParam); - args[1] = HIWORD(lParam); - args[2] = wParam; - args[3] = msg; - args[4] = hwnd; - - ret = CallTo16RegisterShort( &context, 5 * sizeof(WORD) ); - if (offset) stack16_pop( offset ); - - WIN_RestoreWndsLock(iWndsLocks); - - return ret; -} - - /*********************************************************************** * THUNK_EnumObjects16 (GDI.71) */ @@ -1023,7 +943,6 @@ UINT WINAPI ThunkConnect16( void WINAPI C16ThkSL(CONTEXT86 *context) { - extern void CallFrom16Thunk(void); LPBYTE stub = PTR_SEG_TO_LIN(EAX_reg(context)), x = stub; WORD cs, ds; GET_CS(cs); @@ -1037,7 +956,9 @@ void WINAPI C16ThkSL(CONTEXT86 *context) * mov edx, es:[ecx + $EDX] * push bp * push edx - * call __FLATCS:CallFrom16_t_long_ + * push dx + * push edx + * call __FLATCS:CallFrom16Thunk */ *x++ = 0xB8; *((WORD *)x)++ = ds; @@ -1048,6 +969,8 @@ void WINAPI C16ThkSL(CONTEXT86 *context) *x++ = 0x55; *x++ = 0x66; *x++ = 0x52; + *x++ = 0x52; + *x++ = 0x66; *x++ = 0x52; *x++ = 0x66; *x++ = 0x9A; *((DWORD *)x)++ = (DWORD)CallFrom16Thunk; *((WORD *)x)++ = cs; @@ -1073,7 +996,6 @@ void WINAPI C16ThkSL01(CONTEXT86 *context) struct ThunkDataSL16 *SL16 = PTR_SEG_TO_LIN(EDX_reg(context)); struct ThunkDataSL *td = SL16->fpData; - extern void CallFrom16Thunk(void); DWORD procAddress = (DWORD)GetProcAddress16(GetModuleHandle16("KERNEL"), 631); WORD cs; GET_CS(cs); @@ -1094,7 +1016,9 @@ void WINAPI C16ThkSL01(CONTEXT86 *context) * call C16ThkSL01 * push bp * push edx - * call __FLATCS:CallFrom16_t_long_ + * push dx + * push edx + * call __FLATCS:CallFrom16Thunk */ *x++ = 0x66; *x++ = 0x33; *x++ = 0xC0; @@ -1103,6 +1027,8 @@ void WINAPI C16ThkSL01(CONTEXT86 *context) *x++ = 0x55; *x++ = 0x66; *x++ = 0x52; + *x++ = 0x52; + *x++ = 0x66; *x++ = 0x52; *x++ = 0x66; *x++ = 0x9A; *((DWORD *)x)++ = (DWORD)CallFrom16Thunk; *((WORD *)x)++ = cs; diff --git a/include/callback.h b/include/callback.h index b2f528a180..87b4dccc8b 100644 --- a/include/callback.h +++ b/include/callback.h @@ -22,9 +22,6 @@ typedef struct { LONG (CALLBACK *CallRegisterShortProc)( CONTEXT86 *, INT ); LONG (CALLBACK *CallRegisterLongProc)( CONTEXT86 *, INT ); - VOID (CALLBACK *CallFrom16WndProc)(void); - LRESULT (CALLBACK *CallWndProc)( WNDPROC16, HWND16, UINT16, - WPARAM16, LPARAM ); LRESULT (CALLBACK *CallDriverProc)( DRIVERPROC16, DWORD, HDRVR16, UINT16, LPARAM, LPARAM ); LRESULT (CALLBACK *CallDriverCallback)( FARPROC16, HANDLE16, UINT16, diff --git a/include/module.h b/include/module.h index 2468be33d9..1081a7f82b 100644 --- a/include/module.h +++ b/include/module.h @@ -231,17 +231,9 @@ extern HINSTANCE16 NE_CreateInstance( NE_MODULE *pModule, HINSTANCE16 *prev, /* loader/ne/convert.c */ HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size ); -/* if1632/builtin.c */ -extern BOOL BUILTIN_Init(void); -extern HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL force ); -extern LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, LPSTR name, WORD *pOrd ); - /* relay32/builtin.c */ extern HMODULE BUILTIN32_LoadImage(LPCSTR name, OFSTRUCT *ofs); extern WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR name, DWORD flags, DWORD *err); extern void BUILTIN32_UnloadLibrary(WINE_MODREF *wm); -/* if1632/builtin.c */ -extern HMODULE16 (*fnBUILTIN_LoadModule)(LPCSTR name, BOOL force); - #endif /* __WINE_MODULE_H */ diff --git a/include/snoop.h b/include/snoop.h index 09f4fc63b8..76d1cf319d 100644 --- a/include/snoop.h +++ b/include/snoop.h @@ -8,8 +8,7 @@ extern void SNOOP_RegisterDLL(HMODULE,LPCSTR,DWORD); extern FARPROC SNOOP_GetProcAddress(HMODULE,LPCSTR,DWORD,FARPROC); -extern void (*fnSNOOP16_RegisterDLL)(NE_MODULE*,LPCSTR); -extern FARPROC16 (*fnSNOOP16_GetProcAddress16)(HMODULE16,DWORD,FARPROC16); -extern void SNOOP16_Init(); +extern void SNOOP16_RegisterDLL(NE_MODULE*,LPCSTR); +extern FARPROC16 SNOOP16_GetProcAddress16(HMODULE16,DWORD,FARPROC16); extern int SNOOP_ShowDebugmsgSnoop(const char *dll,int ord,const char *fname); #endif diff --git a/loader/module.c b/loader/module.c index 8cd2fbcd5c..a1cee6a596 100644 --- a/loader/module.c +++ b/loader/module.c @@ -18,6 +18,7 @@ #include "global.h" #include "heap.h" #include "module.h" +#include "snoop.h" #include "neexe.h" #include "pe_image.h" #include "dosexe.h" diff --git a/loader/ne/module.c b/loader/ne/module.c index dc76b7c095..7dc258ab87 100644 --- a/loader/ne/module.c +++ b/loader/ne/module.c @@ -25,6 +25,7 @@ #include "process.h" #include "toolhelp.h" #include "snoop.h" +#include "builtin16.h" #include "stackframe.h" #include "debugtools.h" #include "file.h" @@ -34,15 +35,10 @@ DEFAULT_DEBUG_CHANNEL(module) -FARPROC16 (*fnSNOOP16_GetProcAddress16)(HMODULE16,DWORD,FARPROC16) = NULL; -void (*fnSNOOP16_RegisterDLL)(NE_MODULE*,LPCSTR) = NULL; - #define hFirstModule (pThhook->hExeHead) static NE_MODULE *pCachedModule = 0; /* Module cached by NE_OpenFile */ -static HMODULE16 NE_LoadBuiltin(LPCSTR name,BOOL force) { return 0; } -HMODULE16 (*fnBUILTIN_LoadModule)(LPCSTR name,BOOL force) = NE_LoadBuiltin; static BOOL16 NE_FreeModule( HMODULE16 hModule, BOOL call_wep ); static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_only ); @@ -323,10 +319,10 @@ FARPROC16 NE_GetEntryPointEx( HMODULE16 hModule, WORD ordinal, BOOL16 snoop ) else sel = GlobalHandleToSel16(NE_SEG_TABLE(pModule)[sel-1].hSeg); if (sel==0xffff) return (FARPROC16)PTR_SEG_OFF_TO_SEGPTR( sel, offset ); - if (!snoop || !fnSNOOP16_GetProcAddress16) + if (!snoop) return (FARPROC16)PTR_SEG_OFF_TO_SEGPTR( sel, offset ); else - return (FARPROC16)fnSNOOP16_GetProcAddress16(hModule,ordinal,(FARPROC16)PTR_SEG_OFF_TO_SEGPTR( sel, offset )); + return (FARPROC16)SNOOP16_GetProcAddress16(hModule,ordinal,(FARPROC16)PTR_SEG_OFF_TO_SEGPTR( sel, offset )); } @@ -729,8 +725,8 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs ) else pModule->dlls_to_init = 0; NE_RegisterModule( pModule ); - if (fnSNOOP16_RegisterDLL) - fnSNOOP16_RegisterDLL(pModule,ofs->szPathName); + SNOOP16_RegisterDLL(pModule,ofs->szPathName); + return hModule; } @@ -911,7 +907,7 @@ static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_ case MODULE_LOADORDER_BI: TRACE("Trying built-in '%s'\n", libname); - hinst = fnBUILTIN_LoadModule(libname, TRUE); + hinst = BUILTIN_LoadModule(libname, TRUE); break; default: diff --git a/loader/ne/segment.c b/loader/ne/segment.c index e9f30ebb53..4d53b339bd 100644 --- a/loader/ne/segment.c +++ b/loader/ne/segment.c @@ -96,7 +96,6 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum ) { /* Implement self-loading segments */ SELFLOADHEADER *selfloadheader; - STACK16FRAME *stack16Top; DWORD oldstack; WORD old_hSeg, new_hSeg; HFILE hFile32; @@ -107,16 +106,8 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum ) oldstack = NtCurrentTeb()->cur_stack; old_hSeg = pSeg->hSeg; NtCurrentTeb()->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel, - 0xff00 - sizeof(*stack16Top)); - stack16Top = CURRENT_STACK16; - stack16Top->frame32 = 0; - stack16Top->ds = stack16Top->es = pModule->self_loading_sel; - stack16Top->entry_point = 0; - stack16Top->entry_ip = 0; - stack16Top->entry_cs = 0; - stack16Top->bp = 0; - stack16Top->ip = 0; - stack16Top->cs = 0; + 0xff00 - sizeof(STACK16FRAME)); + TRACE_(dll)("CallLoadAppSegProc(hmodule=0x%04x,hf=0x%04x,segnum=%d\n", pModule->self,hf,segnum ); DuplicateHandle( GetCurrentProcess(), hf, GetCurrentProcess(), &hFile32, @@ -403,7 +394,6 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule ) HFILE16 hFile16; /* Handle self-loading modules */ SELFLOADHEADER *selfloadheader; - STACK16FRAME *stack16Top; HMODULE16 hselfload = GetModuleHandle16("WPROCS"); DWORD oldstack; WORD saved_hSeg = pSegTable[pModule->dgroup - 1].hSeg; @@ -420,17 +410,7 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule ) pModule->self_loading_sel = SEL(GLOBAL_Alloc(GMEM_ZEROINIT, 0xFF00, pModule->self, FALSE, FALSE, FALSE)); oldstack = NtCurrentTeb()->cur_stack; NtCurrentTeb()->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel, - 0xff00 - sizeof(*stack16Top) ); - stack16Top = CURRENT_STACK16; - stack16Top->frame32 = 0; - stack16Top->ebp = 0; - stack16Top->ds = stack16Top->es = pModule->self_loading_sel; - stack16Top->entry_point = 0; - stack16Top->entry_ip = 0; - stack16Top->entry_cs = 0; - stack16Top->bp = 0; - stack16Top->ip = 0; - stack16Top->cs = 0; + 0xff00 - sizeof(STACK16FRAME) ); DuplicateHandle( GetCurrentProcess(), NE_OpenFile(pModule), GetCurrentProcess(), &hf, 0, FALSE, DUPLICATE_SAME_ACCESS ); diff --git a/loader/task.c b/loader/task.c index 0584a98b5f..3f18afb8b9 100644 --- a/loader/task.c +++ b/loader/task.c @@ -1230,8 +1230,9 @@ void WINAPI SwitchStackBack16( CONTEXT86 *context ) newFrame->frame32 = oldFrame->frame32; if (TRACE_ON(relay)) { - newFrame->entry_ip = oldFrame->entry_ip; - newFrame->entry_cs = oldFrame->entry_cs; + newFrame->module_cs = oldFrame->module_cs; + newFrame->callfrom_ip = oldFrame->callfrom_ip; + newFrame->entry_ip = oldFrame->entry_ip; } } diff --git a/windows/winproc.c b/windows/winproc.c index fc3e698945..1681dbece2 100644 --- a/windows/winproc.c +++ b/windows/winproc.c @@ -5,9 +5,11 @@ * Copyright 1996 Alexandre Julliard */ +#include #include "wine/winbase16.h" #include "winuser.h" -#include "callback.h" +#include "stackframe.h" +#include "builtin16.h" #include "heap.h" #include "selectors.h" #include "struct32.h" @@ -26,19 +28,22 @@ DECLARE_DEBUG_CHANNEL(win) /* Window procedure 16-to-32-bit thunk, * see BuildSpec16Files() in tools/build.c */ +#include "pshpack1.h" typedef struct { - BYTE popl_eax; /* popl %eax (return address) */ + WORD pushw_bp; /* pushw %bp */ BYTE pushl_func; /* pushl $proc */ - WNDPROC proc WINE_PACKED; - BYTE pushl_eax; /* pushl %eax */ - WORD pushw_bp WINE_PACKED; /* pushw %bp */ - BYTE pushl_thunk; /* pushl $thunkfrom16 */ - void (*thunk32)() WINE_PACKED; - BYTE lcall; /* lcall cs:relay */ - void (*relay)() WINE_PACKED; /* WINPROC_CallProc16To32A/W() */ - WORD cs WINE_PACKED; + WNDPROC proc; + WORD pushw_ax; /* pushw %ax */ + BYTE pushl_relay; /* pushl $relay */ + void (*relay)(); /* WINPROC_Thunk16To32A/W() */ + BYTE lcall; /* lcall cs:glue */ + void (*glue)(); /* CallFrom16Long */ + WORD cs; /* __FLATCS */ + WORD lret; /* lret $10 */ + WORD nArgs; } WINPROC_THUNK_FROM16; +#include "poppack.h" /* Window procedure 32-to-16-bit thunk, * see BuildSpec32Files() in tools/build.c */ @@ -89,12 +94,8 @@ static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd, static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); -static LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg, - WPARAM16 wParam, LPARAM lParam, - WNDPROC func ); -static LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg, - WPARAM16 wParam, LPARAM lParam, - WNDPROC func ); +static LRESULT WINAPI WINPROC_Thunk16To32A( WNDPROC func, LPBYTE args ); +static LRESULT WINAPI WINPROC_Thunk16To32W( WNDPROC func, LPBYTE args ); static HANDLE WinProcHeap; @@ -135,6 +136,79 @@ static LRESULT WINPROC_CallWndProc( WNDPROC proc, HWND hwnd, UINT msg, return retvalue; } +/*********************************************************************** + * WINPROC_CallWndProc16 + * + * Call a 16-bit window procedure + */ +static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, + UINT16 msg, WPARAM16 wParam, + LPARAM lParam ) +{ + CONTEXT86 context; + LRESULT ret; + WORD *args; + WND *wndPtr = WIN_FindWndPtr( hwnd ); + DWORD offset = 0; + TEB *teb = NtCurrentTeb(); + int iWndsLocks; + + /* Window procedures want ax = hInstance, ds = es = ss */ + + memset(&context, '\0', sizeof(context)); + DS_reg(&context) = SELECTOROF(teb->cur_stack); + ES_reg(&context) = DS_reg(&context); + EAX_reg(&context) = wndPtr ? wndPtr->hInstance : DS_reg(&context); + CS_reg(&context) = SELECTOROF(proc); + EIP_reg(&context) = OFFSETOF(proc); + EBP_reg(&context) = OFFSETOF(teb->cur_stack) + + (WORD)&((STACK16FRAME*)0)->bp; + + WIN_ReleaseWndPtr(wndPtr); + + if (lParam) + { + /* Some programs (eg. the "Undocumented Windows" examples, JWP) only + work if structures passed in lParam are placed in the stack/data + segment. Programmers easily make the mistake of converting lParam + to a near rather than a far pointer, since Windows apparently + allows this. We copy the structures to the 16 bit stack; this is + ugly but makes these programs work. */ + switch (msg) + { + case WM_CREATE: + case WM_NCCREATE: + offset = sizeof(CREATESTRUCT16); break; + case WM_DRAWITEM: + offset = sizeof(DRAWITEMSTRUCT16); break; + case WM_COMPAREITEM: + offset = sizeof(COMPAREITEMSTRUCT16); break; + } + if (offset) + { + void *s = PTR_SEG_TO_LIN(lParam); + lParam = stack16_push( offset ); + memcpy( PTR_SEG_TO_LIN(lParam), s, offset ); + } + } + + iWndsLocks = WIN_SuspendWndsLock(); + + args = (WORD *)THREAD_STACK16(teb) - 5; + args[0] = LOWORD(lParam); + args[1] = HIWORD(lParam); + args[2] = wParam; + args[3] = msg; + args[4] = hwnd; + + ret = CallTo16RegisterShort( &context, 5 * sizeof(WORD) ); + if (offset) stack16_pop( offset ); + + WIN_RestoreWndsLock(iWndsLocks); + + return ret; +} + /********************************************************************** * WINPROC_GetPtr @@ -214,18 +288,19 @@ static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type, break; case WIN_PROC_32A: case WIN_PROC_32W: - proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */ + proc->thunk.t_from16.pushw_bp = 0x5566; /* pushw %bp */ proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */ proc->thunk.t_from16.proc = (FARPROC)func; - proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */ - proc->thunk.t_from16.pushw_bp = 0x5566; /* pushw %bp */ - proc->thunk.t_from16.pushl_thunk = 0x68; /* pushl $thunkfrom16 */ - proc->thunk.t_from16.thunk32 = (type == WIN_PROC_32A) ? - (void(*)())WINPROC_CallProc16To32A : - (void(*)())WINPROC_CallProc16To32W; - proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:relay */ - proc->thunk.t_from16.relay = (void*)Callbacks->CallFrom16WndProc; + proc->thunk.t_from16.pushw_ax = 0x5066; /* pushw %ax */ + proc->thunk.t_from16.pushl_relay = 0x68; /* pushl $relay */ + proc->thunk.t_from16.relay = (type == WIN_PROC_32A) ? + (void(*)())WINPROC_Thunk16To32A : + (void(*)())WINPROC_Thunk16To32W; + proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:glue */ + proc->thunk.t_from16.glue = (void*)CallFrom16Long; GET_CS(proc->thunk.t_from16.cs); + proc->thunk.t_from16.lret = 0xca66; + proc->thunk.t_from16.nArgs = 10; proc->jmp.jmp = 0xe9; /* Fixup relative jump */ proc->jmp.proc = (WNDPROC)((DWORD)func - @@ -2138,9 +2213,9 @@ static LRESULT WINPROC_CallProc32WTo32A( WNDPROC func, HWND hwnd, * * Call a 32-bit window procedure, translating the 16-bit args. */ -LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg, - WPARAM16 wParam, LPARAM lParam, - WNDPROC func ) +static LRESULT WINPROC_CallProc16To32A( WNDPROC func, HWND16 hwnd, + UINT16 msg, WPARAM16 wParam, + LPARAM lParam ) { LRESULT result; UINT msg32; @@ -2152,15 +2227,28 @@ LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg, return WINPROC_UnmapMsg16To32A( hwnd, msg32, wParam32, lParam, result ); } +/********************************************************************** + * WINPROC_Thunk16To32A + */ +static LRESULT WINAPI WINPROC_Thunk16To32A( WNDPROC func, LPBYTE args ) +{ + HWND16 hwnd = *(HWND16 *)( args+8 ); + UINT16 msg = *(HWND16 *)( args+6 ); + WPARAM16 wParam = *(HWND16 *)( args+4 ); + LPARAM lParam = *(LPARAM *)( args+0 ); + + return WINPROC_CallProc16To32A( func, hwnd, msg, wParam, lParam ); +} + /********************************************************************** * WINPROC_CallProc16To32W * * Call a 32-bit window procedure, translating the 16-bit args. */ -LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg, - WPARAM16 wParam, LPARAM lParam, - WNDPROC func ) +static LRESULT WINPROC_CallProc16To32W( WNDPROC func, HWND16 hwnd, + UINT16 msg, WPARAM16 wParam, + LPARAM lParam ) { LRESULT result; UINT msg32; @@ -2174,6 +2262,18 @@ LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg, return WINPROC_UnmapMsg16To32W( hwnd, msg32, wParam32, lParam, result ); } +/********************************************************************** + * WINPROC_Thunk16To32W + */ +static LRESULT WINAPI WINPROC_Thunk16To32W( WNDPROC func, LPBYTE args ) +{ + HWND16 hwnd = *(HWND16 *)( args+8 ); + UINT16 msg = *(HWND16 *)( args+6 ); + WPARAM16 wParam = *(HWND16 *)( args+4 ); + LPARAM lParam = *(LPARAM *)( args+0 ); + + return WINPROC_CallProc16To32W( func, hwnd, msg, wParam, lParam ); +} /********************************************************************** * WINPROC_CallProc32ATo16 @@ -2191,8 +2291,8 @@ static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd, if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam, &msg16, &mp16.wParam, &mp16.lParam ) == -1) return 0; - mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16, - mp16.wParam, mp16.lParam ); + mp16.lResult = WINPROC_CallWndProc16( func, hwnd, msg16, + mp16.wParam, mp16.lParam ); WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 ); return mp16.lResult; } @@ -2214,8 +2314,8 @@ static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd, if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam, &mp16.lParam ) == -1) return 0; - mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16, - mp16.wParam, mp16.lParam ); + mp16.lResult = WINPROC_CallWndProc16( func, hwnd, msg16, + mp16.wParam, mp16.lParam ); WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, &mp16 ); return mp16.lResult; } @@ -2230,27 +2330,27 @@ LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg, WINDOWPROC *proc = WINPROC_GetPtr( func ); if (!proc) - return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam ); + return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam ); #if testing func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 ); - return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam ); + return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam ); #endif switch(proc->type) { case WIN_PROC_16: if (!proc->thunk.t_from32.proc) return 0; - return Callbacks->CallWndProc( proc->thunk.t_from32.proc, - hwnd, msg, wParam, lParam ); + return WINPROC_CallWndProc16( proc->thunk.t_from32.proc, + hwnd, msg, wParam, lParam ); case WIN_PROC_32A: if (!proc->thunk.t_from16.proc) return 0; - return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam, - proc->thunk.t_from16.proc ); + return WINPROC_CallProc16To32A( proc->thunk.t_from16.proc, + hwnd, msg, wParam, lParam ); case WIN_PROC_32W: if (!proc->thunk.t_from16.proc) return 0; - return WINPROC_CallProc16To32W( hwnd, msg, wParam, lParam, - proc->thunk.t_from16.proc ); + return WINPROC_CallProc16To32W( proc->thunk.t_from16.proc, + hwnd, msg, wParam, lParam ); default: WARN_(relay)("Invalid proc %p\n", proc ); return 0; -- 2.32.0.93.g670b81a890