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 @@
#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 );
}
......@@ -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);
}
}
......
......@@ -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;
}
......@@ -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 */
......@@ -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)
*/
INT16 WINAPI THUNK_EnumObjects16( HDC16 hdc, INT16 nObjType,
......@@ -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;
......
......@@ -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,
......
......@@ -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 */
......@@ -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
......@@ -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"
......
......@@ -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:
......
......@@ -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 );
......
......@@ -1230,8 +1230,9 @@ void WINAPI SwitchStackBack16( CONTEXT86 *context )
newFrame->frame32 = oldFrame->frame32;
if (TRACE_ON(relay))
{
newFrame->module_cs = oldFrame->module_cs;
newFrame->callfrom_ip = oldFrame->callfrom_ip;
newFrame->entry_ip = oldFrame->entry_ip;
newFrame->entry_cs = oldFrame->entry_cs;
}
}
......
......@@ -5,9 +5,11 @@
* Copyright 1996 Alexandre Julliard
*/
#include <string.h>
#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,7 +2291,7 @@ 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.lResult = WINPROC_CallWndProc16( func, hwnd, msg16,
mp16.wParam, mp16.lParam );
WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 );
return mp16.lResult;
......@@ -2214,7 +2314,7 @@ 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.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,
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;
......
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