Commit c50a1d05 authored by Ulrich Weigand's avatar Ulrich Weigand Committed by Alexandre Julliard

Adapted to new-style Wine thunks.

Removed some now unnecessary function pointers.
parent 6ab0fb18
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "winbase.h" #include "winbase.h"
#include "wine/winbase16.h" #include "wine/winbase16.h"
#include "wine/winestring.h" #include "wine/winestring.h"
#include "builtin16.h"
#include "builtin32.h" #include "builtin32.h"
#include "global.h" #include "global.h"
#include "heap.h" #include "heap.h"
...@@ -19,25 +20,12 @@ ...@@ -19,25 +20,12 @@
#include "stackframe.h" #include "stackframe.h"
#include "user.h" #include "user.h"
#include "process.h" #include "process.h"
#include "snoop.h"
#include "task.h" #include "task.h"
#include "debugtools.h" #include "debugtools.h"
#include "toolhelp.h" #include "toolhelp.h"
DEFAULT_DEBUG_CHANNEL(module) 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 typedef struct
{ {
const WIN16_DESCRIPTOR *descr; /* DLL descriptor */ const WIN16_DESCRIPTOR *descr; /* DLL descriptor */
...@@ -209,8 +197,6 @@ BOOL BUILTIN_Init(void) ...@@ -209,8 +197,6 @@ BOOL BUILTIN_Init(void)
WORD vector; WORD vector;
HMODULE16 hModule; HMODULE16 hModule;
fnBUILTIN_LoadModule = BUILTIN_LoadModule;
for (dll = BuiltinDLLs; dll->descr; dll++) for (dll = BuiltinDLLs; dll->descr; dll++)
{ {
if (dll->flags & DLL_FLAG_ALWAYS_USED) if (dll->flags & DLL_FLAG_ALWAYS_USED)
...@@ -228,8 +214,6 @@ BOOL BUILTIN_Init(void) ...@@ -228,8 +214,6 @@ BOOL BUILTIN_Init(void)
INT_SetPMHandler( vector, proc ); INT_SetPMHandler( vector, proc );
} }
SNOOP16_Init();
return TRUE; return TRUE;
} }
...@@ -266,7 +250,7 @@ HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL force ) ...@@ -266,7 +250,7 @@ HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL force )
* Return the ordinal, name, and type info corresponding to a CS:IP address. * Return the ordinal, name, and type info corresponding to a CS:IP address.
* This is used only by relay debugging. * 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; WORD i, max_offset;
register BYTE *p; register BYTE *p;
...@@ -274,7 +258,7 @@ LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, LPSTR name, WORD *pOrd ) ...@@ -274,7 +258,7 @@ LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, LPSTR name, WORD *pOrd )
ET_BUNDLE *bundle; ET_BUNDLE *bundle;
ET_ENTRY *entry; ET_ENTRY *entry;
if (!(pModule = NE_GetPtr( FarGetOwner16( GlobalHandle16(cs) )))) if (!(pModule = NE_GetPtr( FarGetOwner16( GlobalHandle16( frame->module_cs ) ))))
return NULL; return NULL;
max_offset = 0; max_offset = 0;
...@@ -285,7 +269,7 @@ LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, LPSTR name, WORD *pOrd ) ...@@ -285,7 +269,7 @@ LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, LPSTR name, WORD *pOrd )
entry = (ET_ENTRY *)((BYTE *)bundle+6); entry = (ET_ENTRY *)((BYTE *)bundle+6);
for (i = bundle->first + 1; i <= bundle->last; i++) 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->segnum == 1) /* code segment ? */
&& (entry->offs >= max_offset)) && (entry->offs >= max_offset))
{ {
...@@ -313,7 +297,7 @@ LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, LPSTR name, WORD *pOrd ) ...@@ -313,7 +297,7 @@ LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, LPSTR name, WORD *pOrd )
*pOrd, *p, (char *)(p + 1) ); *pOrd, *p, (char *)(p + 1) );
/* Retrieve type info string */ /* 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 ) ...@@ -326,8 +310,7 @@ void WINAPI BUILTIN_DefaultIntHandler( CONTEXT86 *context )
{ {
WORD ordinal; WORD ordinal;
char name[80]; char name[80];
STACK16FRAME *frame = CURRENT_STACK16; BUILTIN_GetEntryPoint16( CURRENT_STACK16, name, &ordinal );
BUILTIN_GetEntryPoint16( frame->entry_cs, frame->entry_ip, name, &ordinal );
INT_BARF( context, ordinal - FIRST_INTERRUPT_ORDINAL ); INT_BARF( context, ordinal - FIRST_INTERRUPT_ORDINAL );
} }
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "heap.h" #include "heap.h"
#include "module.h" #include "module.h"
#include "stackframe.h" #include "stackframe.h"
#include "builtin16.h"
#include "task.h" #include "task.h"
#include "syslevel.h" #include "syslevel.h"
#include "debugstr.h" #include "debugstr.h"
...@@ -77,7 +78,7 @@ void RELAY_DebugCallFrom16( CONTEXT86 *context ) ...@@ -77,7 +78,7 @@ void RELAY_DebugCallFrom16( CONTEXT86 *context )
if (!TRACE_ON(relay)) return; if (!TRACE_ON(relay)) return;
frame = CURRENT_STACK16; 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 (!args) return; /* happens for the two snoop register relays */
if (!RELAY_ShowDebugmsgRelay(funstr)) return; if (!RELAY_ShowDebugmsgRelay(funstr)) return;
DPRINTF( "Call %s(",funstr); DPRINTF( "Call %s(",funstr);
...@@ -205,7 +206,7 @@ void RELAY_DebugCallFrom16Ret( CONTEXT86 *context, int ret_val ) ...@@ -205,7 +206,7 @@ void RELAY_DebugCallFrom16Ret( CONTEXT86 *context, int ret_val )
if (!TRACE_ON(relay)) return; if (!TRACE_ON(relay)) return;
frame = CURRENT_STACK16; frame = CURRENT_STACK16;
args = BUILTIN_GetEntryPoint16(frame->entry_cs,frame->entry_ip,funstr,&ordinal); args = BUILTIN_GetEntryPoint16( frame, funstr, &ordinal );
if (!args) return; if (!args) return;
if (!RELAY_ShowDebugmsgRelay(funstr)) return; if (!RELAY_ShowDebugmsgRelay(funstr)) return;
DPRINTF( "Ret %s() ",funstr); DPRINTF( "Ret %s() ",funstr);
...@@ -246,7 +247,7 @@ void RELAY_Unimplemented16(void) ...@@ -246,7 +247,7 @@ void RELAY_Unimplemented16(void)
WORD ordinal; WORD ordinal;
char name[80]; char name[80];
STACK16FRAME *frame = CURRENT_STACK16; 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", MESSAGE("No handler for Win16 routine %s (called from %04x:%04x)\n",
name, frame->cs, frame->ip ); name, frame->cs, frame->ip );
ExitProcess(1); ExitProcess(1);
...@@ -256,31 +257,29 @@ void RELAY_Unimplemented16(void) ...@@ -256,31 +257,29 @@ void RELAY_Unimplemented16(void)
/*********************************************************************** /***********************************************************************
* RELAY_DebugCallTo16 * RELAY_DebugCallTo16
* *
* 'stack' points to the called function address on the 32-bit stack. * 'target' contains either the function to call (normal CallTo16)
* Stack layout: * or a pointer to the CONTEXT86 struct (register CallTo16).
* ... ... * 'nb_args' is the number of argument bytes on the 16-bit stack;
* (stack+8) arg2 * 'reg_func' specifies whether we have a register CallTo16 or not.
* (stack+4) arg1
* (stack) func to call
*/ */
void RELAY_DebugCallTo16( int* stack, int nb_args ) void RELAY_DebugCallTo16( LPVOID target, int nb_args, BOOL reg_func )
{ {
WORD *stack16;
TEB *teb; TEB *teb;
if (!TRACE_ON(relay)) return; if (!TRACE_ON(relay)) return;
teb = NtCurrentTeb(); 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]; CONTEXT86 *context = (CONTEXT86 *)target;
WORD *stack16 = (WORD *)THREAD_STACK16(teb);
DPRINTF("CallTo16(func=%04lx:%04x,ds=%04lx", DPRINTF("CallTo16(func=%04lx:%04x,ds=%04lx",
CS_reg(context), LOWORD(EIP_reg(context)), DS_reg(context) ); CS_reg(context), LOWORD(EIP_reg(context)), DS_reg(context) );
nb_args = stack[1] / sizeof(WORD); while (nb_args--) DPRINTF( ",0x%04x", *--stack16 );
while (nb_args--) {
--stack16;
DPRINTF( ",0x%04x", *stack16 );
}
DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(teb->cur_stack), DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(teb->cur_stack),
OFFSETOF(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", 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 ) ...@@ -291,13 +290,8 @@ void RELAY_DebugCallTo16( int* stack, int nb_args )
else else
{ {
DPRINTF("CallTo16(func=%04x:%04x,ds=%04x", DPRINTF("CallTo16(func=%04x:%04x,ds=%04x",
HIWORD(stack[0]), LOWORD(stack[0]), HIWORD(target), LOWORD(target), SELECTOROF(teb->cur_stack) );
SELECTOROF(teb->cur_stack) ); while (nb_args--) DPRINTF( ",0x%04x", *--stack16 );
stack++;
while (nb_args--) {
DPRINTF(",0x%04x", *stack );
stack++;
}
DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(teb->cur_stack), DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(teb->cur_stack),
OFFSETOF(teb->cur_stack) ); OFFSETOF(teb->cur_stack) );
} }
...@@ -398,16 +392,6 @@ void WINAPI Throw16( LPCATCHBUF lpbuf, INT16 retval, CONTEXT86 *context ) ...@@ -398,16 +392,6 @@ void WINAPI Throw16( LPCATCHBUF lpbuf, INT16 retval, CONTEXT86 *context )
if (lpbuf[8] != SS_reg(context)) if (lpbuf[8] != SS_reg(context))
ERR("Switching stack segment with Throw() not supported; expect crash now\n" ); 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);
}
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "global.h" #include "global.h"
#include "selectors.h" #include "selectors.h"
#include "stackframe.h" #include "stackframe.h"
#include "builtin16.h"
#include "snoop.h" #include "snoop.h"
#include "debugstr.h" #include "debugstr.h"
#include "debugtools.h" #include "debugtools.h"
...@@ -22,17 +23,8 @@ DEFAULT_DEBUG_CHANNEL(snoop) ...@@ -22,17 +23,8 @@ DEFAULT_DEBUG_CHANNEL(snoop)
#include "pshpack1.h" #include "pshpack1.h"
void WINAPI SNOOP16_Entry(CONTEXT86 *context); void WINAPI SNOOP16_Entry(FARPROC proc, LPBYTE args, CONTEXT86 *context);
void WINAPI SNOOP16_Return(CONTEXT86 *context); void WINAPI SNOOP16_Return(FARPROC proc, LPBYTE args, 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
*/
typedef struct tagSNOOP16_FUN { typedef struct tagSNOOP16_FUN {
/* code part */ /* code part */
...@@ -71,15 +63,15 @@ typedef struct tagSNOOP16_RETURNENTRIES { ...@@ -71,15 +63,15 @@ typedef struct tagSNOOP16_RETURNENTRIES {
} SNOOP16_RETURNENTRIES; } SNOOP16_RETURNENTRIES;
typedef struct tagSNOOP16_RELAY { typedef struct tagSNOOP16_RELAY {
/* code part */ WORD pushbp; /* 0x5566 */
BYTE prefix; /* 0x66 , 32bit prefix */ BYTE pusheax; /* 0x50 */
BYTE pushbp; /* 0x55 */ WORD pushax; /* 0x5066 */
BYTE pushl; /* 0x68 */ BYTE pushl; /* 0x68 */
DWORD realfun; /* SNOOP16_Return */ DWORD realfun; /* SNOOP16_Return */
BYTE lcall; /* 0x9a call absolute with segment */ BYTE lcall; /* 0x9a call absolute with segment */
DWORD callfromregs; DWORD callfromregs;
WORD seg; WORD seg;
/* unreached */ WORD lret; /* 0xcb66 */
} SNOOP16_RELAY; } SNOOP16_RELAY;
#include "poppack.h" #include "poppack.h"
...@@ -98,20 +90,25 @@ SNOOP16_RegisterDLL(NE_MODULE *pModule,LPCSTR name) { ...@@ -98,20 +90,25 @@ SNOOP16_RegisterDLL(NE_MODULE *pModule,LPCSTR name) {
if (!snr) { if (!snr) {
xsnr=GLOBAL_Alloc(GMEM_ZEROINIT,2*sizeof(*snr),0,TRUE,TRUE,FALSE); xsnr=GLOBAL_Alloc(GMEM_ZEROINIT,2*sizeof(*snr),0,TRUE,TRUE,FALSE);
snr = GlobalLock16(xsnr); snr = GlobalLock16(xsnr);
snr[0].prefix = 0x66; snr[0].pushbp = 0x5566;
snr[0].pushbp = 0x55; snr[0].pusheax = 0x50;
snr[0].pushax = 0x5066;
snr[0].pushl = 0x68; snr[0].pushl = 0x68;
snr[0].realfun = (DWORD)SNOOP16_Entry; snr[0].realfun = (DWORD)SNOOP16_Entry;
snr[0].lcall = 0x9a; snr[0].lcall = 0x9a;
snr[0].callfromregs = (DWORD)KERNEL_CallFrom16_p_regs_; snr[0].callfromregs = (DWORD)CallFrom16Register;
GET_CS(snr[0].seg); GET_CS(snr[0].seg);
snr[1].prefix = 0x66; snr[0].lret = 0xcb66;
snr[1].pushbp = 0x55;
snr[1].pushbp = 0x5566;
snr[1].pusheax = 0x50;
snr[1].pushax = 0x5066;
snr[1].pushl = 0x68; snr[1].pushl = 0x68;
snr[1].realfun = (DWORD)SNOOP16_Return; snr[1].realfun = (DWORD)SNOOP16_Return;
snr[1].lcall = 0x9a; snr[1].lcall = 0x9a;
snr[1].callfromregs = (DWORD)KERNEL_CallFrom16_p_regs_; snr[1].callfromregs = (DWORD)CallFrom16Register;
GET_CS(snr[1].seg); GET_CS(snr[1].seg);
snr[1].lret = 0xcb66;
} }
while (*dll) { while (*dll) {
if ((*dll)->hmod == pModule->self) if ((*dll)->hmod == pModule->self)
...@@ -209,7 +206,7 @@ SNOOP16_GetProcAddress16(HMODULE16 hmod,DWORD ordinal,FARPROC16 origfun) { ...@@ -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))) #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 ordinal=0;
DWORD entry=(DWORD)PTR_SEG_OFF_TO_LIN(CS_reg(context),LOWORD(EIP_reg(context)))-5; DWORD entry=(DWORD)PTR_SEG_OFF_TO_LIN(CS_reg(context),LOWORD(EIP_reg(context)))-5;
WORD xcs = CS_reg(context); WORD xcs = CS_reg(context);
...@@ -276,7 +273,7 @@ void WINAPI SNOOP16_Entry(CONTEXT86 *context) { ...@@ -276,7 +273,7 @@ void WINAPI SNOOP16_Entry(CONTEXT86 *context) {
DPRINTF(") ret=%04x:%04x\n",HIWORD(ret->origreturn),LOWORD(ret->origreturn)); 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); 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 /* 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 ...@@ -326,8 +323,3 @@ FARPROC16 SNOOP16_GetProcAddress16(HMODULE16 hmod,DWORD ordinal,FARPROC16 origfu
} }
#endif /* !__i386__ */ #endif /* !__i386__ */
void
SNOOP16_Init() {
fnSNOOP16_GetProcAddress16=SNOOP16_GetProcAddress16;
fnSNOOP16_RegisterDLL=SNOOP16_RegisterDLL;
}
...@@ -104,7 +104,6 @@ extern LONG CALLBACK THUNK_CallTo16_long_llllllllllllllll(FARPROC16,LONG,LONG,LO ...@@ -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,LONG,LONG, LONG,LONG,LONG,LONG,LONG,
LONG,LONG,LONG); LONG,LONG,LONG);
extern void CALLBACK THUNK_CallFrom16_p_long_wwwll();
/* ### stop build ### */ /* ### stop build ### */
...@@ -137,9 +136,6 @@ typedef struct tagTHUNK ...@@ -137,9 +136,6 @@ typedef struct tagTHUNK
static THUNK *firstThunk = NULL; 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, static BOOL WINAPI THUNK_WOWCallback16Ex( FARPROC16,DWORD,DWORD,
LPVOID,LPDWORD ); LPVOID,LPDWORD );
static BOOL THUNK_ThunkletInit( void ); static BOOL THUNK_ThunkletInit( void );
...@@ -149,8 +145,6 @@ static const CALLBACKS_TABLE CALLBACK_EmulatorTable = ...@@ -149,8 +145,6 @@ static const CALLBACKS_TABLE CALLBACK_EmulatorTable =
{ {
(void *)CallTo16RegisterShort, /* CallRegisterShortProc */ (void *)CallTo16RegisterShort, /* CallRegisterShortProc */
(void *)CallTo16RegisterLong, /* CallRegisterLongProc */ (void *)CallTo16RegisterLong, /* CallRegisterLongProc */
(void*)THUNK_CallFrom16_p_long_wwwll, /* CallFrom16WndProc */
THUNK_CallWndProc16, /* CallWndProc */
(void *)THUNK_CallTo16_long_lwwll, /* CallDriverProc */ (void *)THUNK_CallTo16_long_lwwll, /* CallDriverProc */
(void *)THUNK_CallTo16_word_wwlll, /* CallDriverCallback */ (void *)THUNK_CallTo16_word_wwlll, /* CallDriverCallback */
(void *)THUNK_CallTo16_word_wwlll, /* CallTimeFuncProc */ (void *)THUNK_CallTo16_word_wwlll, /* CallTimeFuncProc */
...@@ -243,80 +237,6 @@ static void THUNK_Free( THUNK *thunk ) ...@@ -243,80 +237,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) * THUNK_EnumObjects16 (GDI.71)
*/ */
INT16 WINAPI THUNK_EnumObjects16( HDC16 hdc, INT16 nObjType, INT16 WINAPI THUNK_EnumObjects16( HDC16 hdc, INT16 nObjType,
...@@ -1023,7 +943,6 @@ UINT WINAPI ThunkConnect16( ...@@ -1023,7 +943,6 @@ UINT WINAPI ThunkConnect16(
void WINAPI C16ThkSL(CONTEXT86 *context) void WINAPI C16ThkSL(CONTEXT86 *context)
{ {
extern void CallFrom16Thunk(void);
LPBYTE stub = PTR_SEG_TO_LIN(EAX_reg(context)), x = stub; LPBYTE stub = PTR_SEG_TO_LIN(EAX_reg(context)), x = stub;
WORD cs, ds; WORD cs, ds;
GET_CS(cs); GET_CS(cs);
...@@ -1037,7 +956,9 @@ void WINAPI C16ThkSL(CONTEXT86 *context) ...@@ -1037,7 +956,9 @@ void WINAPI C16ThkSL(CONTEXT86 *context)
* mov edx, es:[ecx + $EDX] * mov edx, es:[ecx + $EDX]
* push bp * push bp
* push edx * push edx
* call __FLATCS:CallFrom16_t_long_ * push dx
* push edx
* call __FLATCS:CallFrom16Thunk
*/ */
*x++ = 0xB8; *((WORD *)x)++ = ds; *x++ = 0xB8; *((WORD *)x)++ = ds;
...@@ -1048,6 +969,8 @@ void WINAPI C16ThkSL(CONTEXT86 *context) ...@@ -1048,6 +969,8 @@ void WINAPI C16ThkSL(CONTEXT86 *context)
*x++ = 0x55; *x++ = 0x55;
*x++ = 0x66; *x++ = 0x52; *x++ = 0x66; *x++ = 0x52;
*x++ = 0x52;
*x++ = 0x66; *x++ = 0x52;
*x++ = 0x66; *x++ = 0x9A; *((DWORD *)x)++ = (DWORD)CallFrom16Thunk; *x++ = 0x66; *x++ = 0x9A; *((DWORD *)x)++ = (DWORD)CallFrom16Thunk;
*((WORD *)x)++ = cs; *((WORD *)x)++ = cs;
...@@ -1073,7 +996,6 @@ void WINAPI C16ThkSL01(CONTEXT86 *context) ...@@ -1073,7 +996,6 @@ void WINAPI C16ThkSL01(CONTEXT86 *context)
struct ThunkDataSL16 *SL16 = PTR_SEG_TO_LIN(EDX_reg(context)); struct ThunkDataSL16 *SL16 = PTR_SEG_TO_LIN(EDX_reg(context));
struct ThunkDataSL *td = SL16->fpData; struct ThunkDataSL *td = SL16->fpData;
extern void CallFrom16Thunk(void);
DWORD procAddress = (DWORD)GetProcAddress16(GetModuleHandle16("KERNEL"), 631); DWORD procAddress = (DWORD)GetProcAddress16(GetModuleHandle16("KERNEL"), 631);
WORD cs; WORD cs;
GET_CS(cs); GET_CS(cs);
...@@ -1094,7 +1016,9 @@ void WINAPI C16ThkSL01(CONTEXT86 *context) ...@@ -1094,7 +1016,9 @@ void WINAPI C16ThkSL01(CONTEXT86 *context)
* call C16ThkSL01 * call C16ThkSL01
* push bp * push bp
* push edx * push edx
* call __FLATCS:CallFrom16_t_long_ * push dx
* push edx
* call __FLATCS:CallFrom16Thunk
*/ */
*x++ = 0x66; *x++ = 0x33; *x++ = 0xC0; *x++ = 0x66; *x++ = 0x33; *x++ = 0xC0;
...@@ -1103,6 +1027,8 @@ void WINAPI C16ThkSL01(CONTEXT86 *context) ...@@ -1103,6 +1027,8 @@ void WINAPI C16ThkSL01(CONTEXT86 *context)
*x++ = 0x55; *x++ = 0x55;
*x++ = 0x66; *x++ = 0x52; *x++ = 0x66; *x++ = 0x52;
*x++ = 0x52;
*x++ = 0x66; *x++ = 0x52;
*x++ = 0x66; *x++ = 0x9A; *((DWORD *)x)++ = (DWORD)CallFrom16Thunk; *x++ = 0x66; *x++ = 0x9A; *((DWORD *)x)++ = (DWORD)CallFrom16Thunk;
*((WORD *)x)++ = cs; *((WORD *)x)++ = cs;
......
...@@ -22,9 +22,6 @@ typedef struct ...@@ -22,9 +22,6 @@ typedef struct
{ {
LONG (CALLBACK *CallRegisterShortProc)( CONTEXT86 *, INT ); LONG (CALLBACK *CallRegisterShortProc)( CONTEXT86 *, INT );
LONG (CALLBACK *CallRegisterLongProc)( 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, LRESULT (CALLBACK *CallDriverProc)( DRIVERPROC16, DWORD, HDRVR16,
UINT16, LPARAM, LPARAM ); UINT16, LPARAM, LPARAM );
LRESULT (CALLBACK *CallDriverCallback)( FARPROC16, HANDLE16, UINT16, LRESULT (CALLBACK *CallDriverCallback)( FARPROC16, HANDLE16, UINT16,
......
...@@ -231,17 +231,9 @@ extern HINSTANCE16 NE_CreateInstance( NE_MODULE *pModule, HINSTANCE16 *prev, ...@@ -231,17 +231,9 @@ extern HINSTANCE16 NE_CreateInstance( NE_MODULE *pModule, HINSTANCE16 *prev,
/* loader/ne/convert.c */ /* loader/ne/convert.c */
HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size ); 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 */ /* relay32/builtin.c */
extern HMODULE BUILTIN32_LoadImage(LPCSTR name, OFSTRUCT *ofs); extern HMODULE BUILTIN32_LoadImage(LPCSTR name, OFSTRUCT *ofs);
extern WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR name, DWORD flags, DWORD *err); extern WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR name, DWORD flags, DWORD *err);
extern void BUILTIN32_UnloadLibrary(WINE_MODREF *wm); extern void BUILTIN32_UnloadLibrary(WINE_MODREF *wm);
/* if1632/builtin.c */
extern HMODULE16 (*fnBUILTIN_LoadModule)(LPCSTR name, BOOL force);
#endif /* __WINE_MODULE_H */ #endif /* __WINE_MODULE_H */
...@@ -8,8 +8,7 @@ ...@@ -8,8 +8,7 @@
extern void SNOOP_RegisterDLL(HMODULE,LPCSTR,DWORD); extern void SNOOP_RegisterDLL(HMODULE,LPCSTR,DWORD);
extern FARPROC SNOOP_GetProcAddress(HMODULE,LPCSTR,DWORD,FARPROC); extern FARPROC SNOOP_GetProcAddress(HMODULE,LPCSTR,DWORD,FARPROC);
extern void (*fnSNOOP16_RegisterDLL)(NE_MODULE*,LPCSTR); extern void SNOOP16_RegisterDLL(NE_MODULE*,LPCSTR);
extern FARPROC16 (*fnSNOOP16_GetProcAddress16)(HMODULE16,DWORD,FARPROC16); extern FARPROC16 SNOOP16_GetProcAddress16(HMODULE16,DWORD,FARPROC16);
extern void SNOOP16_Init();
extern int SNOOP_ShowDebugmsgSnoop(const char *dll,int ord,const char *fname); extern int SNOOP_ShowDebugmsgSnoop(const char *dll,int ord,const char *fname);
#endif #endif
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "global.h" #include "global.h"
#include "heap.h" #include "heap.h"
#include "module.h" #include "module.h"
#include "snoop.h"
#include "neexe.h" #include "neexe.h"
#include "pe_image.h" #include "pe_image.h"
#include "dosexe.h" #include "dosexe.h"
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "process.h" #include "process.h"
#include "toolhelp.h" #include "toolhelp.h"
#include "snoop.h" #include "snoop.h"
#include "builtin16.h"
#include "stackframe.h" #include "stackframe.h"
#include "debugtools.h" #include "debugtools.h"
#include "file.h" #include "file.h"
...@@ -34,15 +35,10 @@ ...@@ -34,15 +35,10 @@
DEFAULT_DEBUG_CHANNEL(module) DEFAULT_DEBUG_CHANNEL(module)
FARPROC16 (*fnSNOOP16_GetProcAddress16)(HMODULE16,DWORD,FARPROC16) = NULL;
void (*fnSNOOP16_RegisterDLL)(NE_MODULE*,LPCSTR) = NULL;
#define hFirstModule (pThhook->hExeHead) #define hFirstModule (pThhook->hExeHead)
static NE_MODULE *pCachedModule = 0; /* Module cached by NE_OpenFile */ 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 BOOL16 NE_FreeModule( HMODULE16 hModule, BOOL call_wep );
static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_only ); static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_only );
...@@ -323,10 +319,10 @@ FARPROC16 NE_GetEntryPointEx( HMODULE16 hModule, WORD ordinal, BOOL16 snoop ) ...@@ -323,10 +319,10 @@ FARPROC16 NE_GetEntryPointEx( HMODULE16 hModule, WORD ordinal, BOOL16 snoop )
else sel = GlobalHandleToSel16(NE_SEG_TABLE(pModule)[sel-1].hSeg); else sel = GlobalHandleToSel16(NE_SEG_TABLE(pModule)[sel-1].hSeg);
if (sel==0xffff) if (sel==0xffff)
return (FARPROC16)PTR_SEG_OFF_TO_SEGPTR( sel, offset ); return (FARPROC16)PTR_SEG_OFF_TO_SEGPTR( sel, offset );
if (!snoop || !fnSNOOP16_GetProcAddress16) if (!snoop)
return (FARPROC16)PTR_SEG_OFF_TO_SEGPTR( sel, offset ); return (FARPROC16)PTR_SEG_OFF_TO_SEGPTR( sel, offset );
else 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 ) ...@@ -729,8 +725,8 @@ static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs )
else pModule->dlls_to_init = 0; else pModule->dlls_to_init = 0;
NE_RegisterModule( pModule ); NE_RegisterModule( pModule );
if (fnSNOOP16_RegisterDLL) SNOOP16_RegisterDLL(pModule,ofs->szPathName);
fnSNOOP16_RegisterDLL(pModule,ofs->szPathName);
return hModule; return hModule;
} }
...@@ -911,7 +907,7 @@ static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_ ...@@ -911,7 +907,7 @@ static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_
case MODULE_LOADORDER_BI: case MODULE_LOADORDER_BI:
TRACE("Trying built-in '%s'\n", libname); TRACE("Trying built-in '%s'\n", libname);
hinst = fnBUILTIN_LoadModule(libname, TRUE); hinst = BUILTIN_LoadModule(libname, TRUE);
break; break;
default: default:
......
...@@ -96,7 +96,6 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum ) ...@@ -96,7 +96,6 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum )
{ {
/* Implement self-loading segments */ /* Implement self-loading segments */
SELFLOADHEADER *selfloadheader; SELFLOADHEADER *selfloadheader;
STACK16FRAME *stack16Top;
DWORD oldstack; DWORD oldstack;
WORD old_hSeg, new_hSeg; WORD old_hSeg, new_hSeg;
HFILE hFile32; HFILE hFile32;
...@@ -107,16 +106,8 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum ) ...@@ -107,16 +106,8 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum )
oldstack = NtCurrentTeb()->cur_stack; oldstack = NtCurrentTeb()->cur_stack;
old_hSeg = pSeg->hSeg; old_hSeg = pSeg->hSeg;
NtCurrentTeb()->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel, NtCurrentTeb()->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel,
0xff00 - sizeof(*stack16Top)); 0xff00 - sizeof(STACK16FRAME));
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;
TRACE_(dll)("CallLoadAppSegProc(hmodule=0x%04x,hf=0x%04x,segnum=%d\n", TRACE_(dll)("CallLoadAppSegProc(hmodule=0x%04x,hf=0x%04x,segnum=%d\n",
pModule->self,hf,segnum ); pModule->self,hf,segnum );
DuplicateHandle( GetCurrentProcess(), hf, GetCurrentProcess(), &hFile32, DuplicateHandle( GetCurrentProcess(), hf, GetCurrentProcess(), &hFile32,
...@@ -403,7 +394,6 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule ) ...@@ -403,7 +394,6 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule )
HFILE16 hFile16; HFILE16 hFile16;
/* Handle self-loading modules */ /* Handle self-loading modules */
SELFLOADHEADER *selfloadheader; SELFLOADHEADER *selfloadheader;
STACK16FRAME *stack16Top;
HMODULE16 hselfload = GetModuleHandle16("WPROCS"); HMODULE16 hselfload = GetModuleHandle16("WPROCS");
DWORD oldstack; DWORD oldstack;
WORD saved_hSeg = pSegTable[pModule->dgroup - 1].hSeg; WORD saved_hSeg = pSegTable[pModule->dgroup - 1].hSeg;
...@@ -420,17 +410,7 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule ) ...@@ -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)); pModule->self_loading_sel = SEL(GLOBAL_Alloc(GMEM_ZEROINIT, 0xFF00, pModule->self, FALSE, FALSE, FALSE));
oldstack = NtCurrentTeb()->cur_stack; oldstack = NtCurrentTeb()->cur_stack;
NtCurrentTeb()->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel, NtCurrentTeb()->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel,
0xff00 - sizeof(*stack16Top) ); 0xff00 - sizeof(STACK16FRAME) );
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;
DuplicateHandle( GetCurrentProcess(), NE_OpenFile(pModule), DuplicateHandle( GetCurrentProcess(), NE_OpenFile(pModule),
GetCurrentProcess(), &hf, 0, FALSE, DUPLICATE_SAME_ACCESS ); GetCurrentProcess(), &hf, 0, FALSE, DUPLICATE_SAME_ACCESS );
......
...@@ -1230,8 +1230,9 @@ void WINAPI SwitchStackBack16( CONTEXT86 *context ) ...@@ -1230,8 +1230,9 @@ void WINAPI SwitchStackBack16( CONTEXT86 *context )
newFrame->frame32 = oldFrame->frame32; newFrame->frame32 = oldFrame->frame32;
if (TRACE_ON(relay)) if (TRACE_ON(relay))
{ {
newFrame->module_cs = oldFrame->module_cs;
newFrame->callfrom_ip = oldFrame->callfrom_ip;
newFrame->entry_ip = oldFrame->entry_ip; newFrame->entry_ip = oldFrame->entry_ip;
newFrame->entry_cs = oldFrame->entry_cs;
} }
} }
......
...@@ -5,9 +5,11 @@ ...@@ -5,9 +5,11 @@
* Copyright 1996 Alexandre Julliard * Copyright 1996 Alexandre Julliard
*/ */
#include <string.h>
#include "wine/winbase16.h" #include "wine/winbase16.h"
#include "winuser.h" #include "winuser.h"
#include "callback.h" #include "stackframe.h"
#include "builtin16.h"
#include "heap.h" #include "heap.h"
#include "selectors.h" #include "selectors.h"
#include "struct32.h" #include "struct32.h"
...@@ -26,19 +28,22 @@ DECLARE_DEBUG_CHANNEL(win) ...@@ -26,19 +28,22 @@ DECLARE_DEBUG_CHANNEL(win)
/* Window procedure 16-to-32-bit thunk, /* Window procedure 16-to-32-bit thunk,
* see BuildSpec16Files() in tools/build.c */ * see BuildSpec16Files() in tools/build.c */
#include "pshpack1.h"
typedef struct typedef struct
{ {
BYTE popl_eax; /* popl %eax (return address) */ WORD pushw_bp; /* pushw %bp */
BYTE pushl_func; /* pushl $proc */ BYTE pushl_func; /* pushl $proc */
WNDPROC proc WINE_PACKED; WNDPROC proc;
BYTE pushl_eax; /* pushl %eax */ WORD pushw_ax; /* pushw %ax */
WORD pushw_bp WINE_PACKED; /* pushw %bp */ BYTE pushl_relay; /* pushl $relay */
BYTE pushl_thunk; /* pushl $thunkfrom16 */ void (*relay)(); /* WINPROC_Thunk16To32A/W() */
void (*thunk32)() WINE_PACKED; BYTE lcall; /* lcall cs:glue */
BYTE lcall; /* lcall cs:relay */ void (*glue)(); /* CallFrom16Long */
void (*relay)() WINE_PACKED; /* WINPROC_CallProc16To32A/W() */ WORD cs; /* __FLATCS */
WORD cs WINE_PACKED; WORD lret; /* lret $10 */
WORD nArgs;
} WINPROC_THUNK_FROM16; } WINPROC_THUNK_FROM16;
#include "poppack.h"
/* Window procedure 32-to-16-bit thunk, /* Window procedure 32-to-16-bit thunk,
* see BuildSpec32Files() in tools/build.c */ * see BuildSpec32Files() in tools/build.c */
...@@ -89,12 +94,8 @@ static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd, ...@@ -89,12 +94,8 @@ static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd, static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
UINT msg, WPARAM wParam, UINT msg, WPARAM wParam,
LPARAM lParam ); LPARAM lParam );
static LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg, static LRESULT WINAPI WINPROC_Thunk16To32A( WNDPROC func, LPBYTE args );
WPARAM16 wParam, LPARAM lParam, static LRESULT WINAPI WINPROC_Thunk16To32W( WNDPROC func, LPBYTE args );
WNDPROC func );
static LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
WPARAM16 wParam, LPARAM lParam,
WNDPROC func );
static HANDLE WinProcHeap; static HANDLE WinProcHeap;
...@@ -135,6 +136,79 @@ static LRESULT WINPROC_CallWndProc( WNDPROC proc, HWND hwnd, UINT msg, ...@@ -135,6 +136,79 @@ static LRESULT WINPROC_CallWndProc( WNDPROC proc, HWND hwnd, UINT msg,
return retvalue; 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 * WINPROC_GetPtr
...@@ -214,18 +288,19 @@ static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type, ...@@ -214,18 +288,19 @@ static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
break; break;
case WIN_PROC_32A: case WIN_PROC_32A:
case WIN_PROC_32W: 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.pushl_func = 0x68; /* pushl $proc */
proc->thunk.t_from16.proc = (FARPROC)func; proc->thunk.t_from16.proc = (FARPROC)func;
proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */ proc->thunk.t_from16.pushw_ax = 0x5066; /* pushw %ax */
proc->thunk.t_from16.pushw_bp = 0x5566; /* pushw %bp */ proc->thunk.t_from16.pushl_relay = 0x68; /* pushl $relay */
proc->thunk.t_from16.pushl_thunk = 0x68; /* pushl $thunkfrom16 */ proc->thunk.t_from16.relay = (type == WIN_PROC_32A) ?
proc->thunk.t_from16.thunk32 = (type == WIN_PROC_32A) ? (void(*)())WINPROC_Thunk16To32A :
(void(*)())WINPROC_CallProc16To32A : (void(*)())WINPROC_Thunk16To32W;
(void(*)())WINPROC_CallProc16To32W; proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:glue */
proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:relay */ proc->thunk.t_from16.glue = (void*)CallFrom16Long;
proc->thunk.t_from16.relay = (void*)Callbacks->CallFrom16WndProc;
GET_CS(proc->thunk.t_from16.cs); GET_CS(proc->thunk.t_from16.cs);
proc->thunk.t_from16.lret = 0xca66;
proc->thunk.t_from16.nArgs = 10;
proc->jmp.jmp = 0xe9; proc->jmp.jmp = 0xe9;
/* Fixup relative jump */ /* Fixup relative jump */
proc->jmp.proc = (WNDPROC)((DWORD)func - proc->jmp.proc = (WNDPROC)((DWORD)func -
...@@ -2138,9 +2213,9 @@ static LRESULT WINPROC_CallProc32WTo32A( WNDPROC func, HWND hwnd, ...@@ -2138,9 +2213,9 @@ static LRESULT WINPROC_CallProc32WTo32A( WNDPROC func, HWND hwnd,
* *
* Call a 32-bit window procedure, translating the 16-bit args. * Call a 32-bit window procedure, translating the 16-bit args.
*/ */
LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg, static LRESULT WINPROC_CallProc16To32A( WNDPROC func, HWND16 hwnd,
WPARAM16 wParam, LPARAM lParam, UINT16 msg, WPARAM16 wParam,
WNDPROC func ) LPARAM lParam )
{ {
LRESULT result; LRESULT result;
UINT msg32; UINT msg32;
...@@ -2152,15 +2227,28 @@ LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg, ...@@ -2152,15 +2227,28 @@ LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
return WINPROC_UnmapMsg16To32A( hwnd, msg32, wParam32, lParam, result ); 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 * WINPROC_CallProc16To32W
* *
* Call a 32-bit window procedure, translating the 16-bit args. * Call a 32-bit window procedure, translating the 16-bit args.
*/ */
LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg, static LRESULT WINPROC_CallProc16To32W( WNDPROC func, HWND16 hwnd,
WPARAM16 wParam, LPARAM lParam, UINT16 msg, WPARAM16 wParam,
WNDPROC func ) LPARAM lParam )
{ {
LRESULT result; LRESULT result;
UINT msg32; UINT msg32;
...@@ -2174,6 +2262,18 @@ LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg, ...@@ -2174,6 +2262,18 @@ LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
return WINPROC_UnmapMsg16To32W( hwnd, msg32, wParam32, lParam, result ); 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 * WINPROC_CallProc32ATo16
...@@ -2191,7 +2291,7 @@ static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd, ...@@ -2191,7 +2291,7 @@ static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam, if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam,
&msg16, &mp16.wParam, &mp16.lParam ) == -1) &msg16, &mp16.wParam, &mp16.lParam ) == -1)
return 0; return 0;
mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16, mp16.lResult = WINPROC_CallWndProc16( func, hwnd, msg16,
mp16.wParam, mp16.lParam ); mp16.wParam, mp16.lParam );
WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 ); WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 );
return mp16.lResult; return mp16.lResult;
...@@ -2214,7 +2314,7 @@ static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd, ...@@ -2214,7 +2314,7 @@ static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam, if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
&mp16.lParam ) == -1) &mp16.lParam ) == -1)
return 0; return 0;
mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16, mp16.lResult = WINPROC_CallWndProc16( func, hwnd, msg16,
mp16.wParam, mp16.lParam ); mp16.wParam, mp16.lParam );
WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, &mp16 ); WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, &mp16 );
return mp16.lResult; return mp16.lResult;
...@@ -2230,27 +2330,27 @@ LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg, ...@@ -2230,27 +2330,27 @@ LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
WINDOWPROC *proc = WINPROC_GetPtr( func ); WINDOWPROC *proc = WINPROC_GetPtr( func );
if (!proc) if (!proc)
return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam ); return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
#if testing #if testing
func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 ); 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 #endif
switch(proc->type) switch(proc->type)
{ {
case WIN_PROC_16: case WIN_PROC_16:
if (!proc->thunk.t_from32.proc) return 0; if (!proc->thunk.t_from32.proc) return 0;
return Callbacks->CallWndProc( proc->thunk.t_from32.proc, return WINPROC_CallWndProc16( proc->thunk.t_from32.proc,
hwnd, msg, wParam, lParam ); hwnd, msg, wParam, lParam );
case WIN_PROC_32A: case WIN_PROC_32A:
if (!proc->thunk.t_from16.proc) return 0; if (!proc->thunk.t_from16.proc) return 0;
return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam, return WINPROC_CallProc16To32A( proc->thunk.t_from16.proc,
proc->thunk.t_from16.proc ); hwnd, msg, wParam, lParam );
case WIN_PROC_32W: case WIN_PROC_32W:
if (!proc->thunk.t_from16.proc) return 0; if (!proc->thunk.t_from16.proc) return 0;
return WINPROC_CallProc16To32W( hwnd, msg, wParam, lParam, return WINPROC_CallProc16To32W( proc->thunk.t_from16.proc,
proc->thunk.t_from16.proc ); hwnd, msg, wParam, lParam );
default: default:
WARN_(relay)("Invalid proc %p\n", proc ); WARN_(relay)("Invalid proc %p\n", proc );
return 0; return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment