diff --git a/dlls/kernel/thunk.c b/dlls/kernel/thunk.c index 01805c9c914..5c1b2a01b49 100644 --- a/dlls/kernel/thunk.c +++ b/dlls/kernel/thunk.c @@ -1446,6 +1446,7 @@ typedef struct _THUNKLET #define THUNKLET_TYPE_SL 2 static HANDLE ThunkletHeap = 0; +static WORD ThunkletCodeSel; static THUNKLET *ThunkletAnchor = NULL; static FARPROC ThunkletSysthunkGlueLS = 0; @@ -1454,6 +1455,13 @@ static SEGPTR ThunkletSysthunkGlueSL = 0; static FARPROC ThunkletCallbackGlueLS = 0; static SEGPTR ThunkletCallbackGlueSL = 0; + +/* map a thunk allocated on ThunkletHeap to a 16-bit pointer */ +inline static SEGPTR get_segptr( void *thunk ) +{ + return MAKESEGPTR( ThunkletCodeSel, (char *)thunk - (char *)ThunkletHeap ); +} + /*********************************************************************** * THUNK_Init */ @@ -1461,17 +1469,19 @@ BOOL THUNK_Init(void) { LPBYTE thunk; - ThunkletHeap = HeapCreate(HEAP_WINE_SEGPTR | HEAP_WINE_CODE16SEG, 0, 0); + ThunkletHeap = HeapCreate( 0, 0x10000, 0x10000 ); if (!ThunkletHeap) return FALSE; + ThunkletCodeSel = SELECTOR_AllocBlock( (void *)ThunkletHeap, 0x10000, WINE_LDT_FLAGS_CODE ); + thunk = HeapAlloc( ThunkletHeap, 0, 5 ); if (!thunk) return FALSE; - + ThunkletSysthunkGlueLS = (FARPROC)thunk; *thunk++ = 0x58; /* popl eax */ *thunk++ = 0xC3; /* ret */ - ThunkletSysthunkGlueSL = HEAP_GetSegptr( ThunkletHeap, 0, thunk ); + ThunkletSysthunkGlueSL = get_segptr( thunk ); *thunk++ = 0x66; *thunk++ = 0x58; /* popl eax */ *thunk++ = 0xCB; /* lret */ @@ -1571,7 +1581,7 @@ SEGPTR THUNK_AllocSLThunklet( FARPROC target, DWORD relay, ThunkletAnchor = thunk; } - return HEAP_GetSegptr( ThunkletHeap, 0, thunk ); + return get_segptr( thunk ); } /********************************************************************** @@ -1700,7 +1710,7 @@ SEGPTR WINAPI FindSLThunkletCallback( FARPROC target, DWORD relay ) thunk = THUNK_FindThunklet( (DWORD)target, relay, (DWORD)ThunkletCallbackGlueSL, THUNKLET_TYPE_SL ); - return HEAP_GetSegptr( ThunkletHeap, 0, thunk ); + return get_segptr( thunk ); } @@ -1855,21 +1865,35 @@ void WINAPI CBClientThunkSLEx( CONTEXT86 *context ) * A 16:16 segmented pointer to the function is returned. * Written without any docu. */ -SEGPTR WINAPI Get16DLLAddress(HMODULE handle, LPSTR func_name) { - HANDLE ThunkHeap = HeapCreate(HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 64); - LPBYTE x; - LPVOID tmpheap = HeapAlloc(ThunkHeap, 0, 32); - SEGPTR thunk = HEAP_GetSegptr(ThunkHeap, 0, tmpheap); - DWORD proc_16; +SEGPTR WINAPI Get16DLLAddress(HMODULE handle, LPSTR func_name) +{ + static WORD code_sel32; + FARPROC16 proc_16; + LPBYTE thunk; - if (!handle) handle=GetModuleHandle16("WIN32S16"); - proc_16 = (DWORD)GetProcAddress16(handle, func_name); + if (!code_sel32) + { + code_sel32 = SELECTOR_AllocBlock( (void *)ThunkletHeap, 0x10000, + WINE_LDT_FLAGS_CODE | WINE_LDT_FLAGS_32BIT ); + if (!code_sel32) return 0; + } + if (!(thunk = HeapAlloc( ThunkletHeap, 0, 32 ))) return 0; - x=MapSL(thunk); - *x++=0xba; *(DWORD*)x=proc_16;x+=4; /* movl proc_16, $edx */ - *x++=0xea; *(DWORD*)x=(DWORD)GetProcAddress(GetModuleHandleA("KERNEL32"),"QT_Thunk");x+=4; /* jmpl QT_Thunk */ - *(WORD*)x=__get_cs(); - return thunk; + if (!handle) handle = GetModuleHandle16("WIN32S16"); + proc_16 = GetProcAddress16(handle, func_name); + + /* movl proc_16, $edx */ + *thunk++ = 0xba; + *(FARPROC16 *)thunk = proc_16; + thunk += sizeof(FARPROC16); + + /* jmpl QT_Thunk */ + *thunk++ = 0xea; + *(FARPROC *)thunk = GetProcAddress(GetModuleHandleA("KERNEL32"),"QT_Thunk"); + thunk += sizeof(FARPROC16); + *(WORD *)thunk = __get_cs(); + + return MAKESEGPTR( code_sel32, (char *)thunk - (char *)ThunkletHeap ); } diff --git a/dlls/kernel/utthunk.c b/dlls/kernel/utthunk.c index 32d0996c730..e3e09c4fd22 100644 --- a/dlls/kernel/utthunk.c +++ b/dlls/kernel/utthunk.c @@ -6,7 +6,6 @@ #include "wine/winbase16.h" #include "ntddk.h" -#include "heap.h" #include "module.h" #include "callback.h" #include "debugtools.h" @@ -154,7 +153,7 @@ static UTINFO *UTAlloc( HMODULE hModule, HMODULE16 hModule16, if ( !UTGlue16_Segptr ) return NULL; } - ut = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY|HEAP_WINE_SEGPTR, sizeof(UTINFO) ); + ut = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(UTINFO) ); if ( !ut ) return NULL; ut->hModule = hModule; @@ -194,7 +193,7 @@ static void UTFree( UTINFO *ut ) break; } - HeapFree( GetProcessHeap(), HEAP_WINE_SEGPTR, ut ); + HeapFree( GetProcessHeap(), 0, ut ); } /**************************************************************************** @@ -250,16 +249,18 @@ BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL, if ( lpszInitName && (init16 = GetProcAddress16( hModule16, lpszInitName )) != 0 ) { - SEGPTR callback = SEGPTR_GET( &ut->ut16 ); + SEGPTR callback = MapLS( &ut->ut16 ); SEGPTR segBuff = MapLS( lpBuff ); if ( !UTTHUNK_CallTo16_long_ll( init16, callback, segBuff ) ) { UnMapLS( segBuff ); + UnMapLS( callback ); UTUnRegister( hModule ); return FALSE; } UnMapLS( segBuff ); + UnMapLS( callback ); } /* Return 32-bit thunk */ diff --git a/windows/winproc.c b/windows/winproc.c index 755f582169b..385418162e3 100644 --- a/windows/winproc.c +++ b/windows/winproc.c @@ -15,6 +15,7 @@ #include "wine/winbase16.h" #include "wine/winuser16.h" #include "stackframe.h" +#include "selectors.h" #include "builtin16.h" #include "controls.h" #include "heap.h" @@ -103,6 +104,7 @@ static LRESULT WINAPI WINPROC_Thunk16To32A( WNDPROC func, LPBYTE args ); static LRESULT WINAPI WINPROC_Thunk16To32W( WNDPROC func, LPBYTE args ); static HANDLE WinProcHeap; +static WORD WinProcSel; /********************************************************************** @@ -110,8 +112,10 @@ static HANDLE WinProcHeap; */ BOOL WINPROC_Init(void) { - WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 ); - if (!WinProcHeap) + WinProcHeap = HeapCreate( 0, 0x10000, 0x10000 ); + WinProcSel = SELECTOR_AllocBlock( (void *)WinProcHeap, 0x10000, + WINE_LDT_FLAGS_CODE | WINE_LDT_FLAGS_32BIT ); + if (!WinProcHeap || !WinProcSel) { WARN_(relay)("Unable to create winproc heap\n" ); return FALSE; @@ -366,25 +370,26 @@ static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type, */ WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type ) { + WINDOWPROC *ptr = (WINDOWPROC *)proc; + if (!proc) return NULL; if (type == WIN_PROC_16) /* We want a 16:16 address */ { - if (((WINDOWPROC *)proc)->type == WIN_PROC_16) - return ((WINDOWPROC *)proc)->thunk.t_from32.proc; + if (ptr->type == WIN_PROC_16) + return ptr->thunk.t_from32.proc; else - return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0, - &((WINDOWPROC *)proc)->thunk ); + return (WNDPROC16)MAKESEGPTR( WinProcSel, (char *)&ptr->thunk - (char *)WinProcHeap ); } else /* We want a 32-bit address */ { - if (((WINDOWPROC *)proc)->type == WIN_PROC_16) - return (WNDPROC16)&((WINDOWPROC *)proc)->thunk; - else if (type != ((WINDOWPROC *)proc)->type) + if (ptr->type == WIN_PROC_16) + return (WNDPROC16)&ptr->thunk; + else if (type != ptr->type) /* Have to return the jmp address if types don't match */ - return (WNDPROC16)&((WINDOWPROC *)proc)->jmp; + return (WNDPROC16)&ptr->jmp; else /* Some Win16 programs want to get back the proc they set */ - return (WNDPROC16)((WINDOWPROC *)proc)->thunk.t_from16.proc; + return (WNDPROC16)ptr->thunk.t_from16.proc; } }