diff --git a/if1632/kernel.spec b/if1632/kernel.spec index b930df5fa26..a8f3aa33d4c 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -417,12 +417,12 @@ file krnl386.exe 509 stub WOWKILLREMOTETASK 511 stub WOWKILLREMOTETASK 512 stub WOWQUERYDEBUG -513 pascal LoadLibraryEx32W(ptr long long) LoadLibraryEx32W16 # Both NT/95 -514 pascal16 FreeLibrary32W(long) FreeLibrary # Both NT/95 -515 pascal GetProcAddress32W(long str) GetProcAddress # Both NT/95 -516 pascal GetVDMPointer32W(segptr word) GetVDMPointer32W # Both NT/95 -517 pascal CallProc32W() CallProc32W_16 # Both NT/95 -518 pascal CallProcEx32W() CallProcEx32W_16 # Both NT/95 +513 pascal LoadLibraryEx32W(ptr long long) LoadLibraryEx32W16 # Both NT/95 +514 pascal FreeLibrary32W(long) FreeLibrary32W16 # Both NT/95 +515 pascal GetProcAddress32W(long str) GetProcAddress32W16 # Both NT/95 +516 pascal GetVDMPointer32W(segptr word) GetVDMPointer32W16 # Both NT/95 +517 pascal CallProc32W() CallProc32W16 # Both NT/95 +518 pascal CallProcEx32W() CallProcEx32W16 # Both NT/95 519 stub EXITKERNELTHUNK # the __MOD_ variables are WORD datareferences, the current values are invented. 520 equate __MOD_KERNEL 4200 diff --git a/if1632/relay.c b/if1632/relay.c index 4b2d16675d8..44a3c49ca82 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -394,112 +394,3 @@ void WINAPI Throw16( LPCATCHBUF lpbuf, INT16 retval, CONTEXT86 *context ) ERR("Switching stack segment with Throw() not supported; expect crash now\n" ); } - -/********************************************************************** - * RELAY_CallProc32W - * - * Helper for CallProc[Ex]32W - */ -static DWORD RELAY_CallProc32W(int Ex) -{ - DWORD nrofargs, argconvmask; - FARPROC proc32; - DWORD *args, ret; - VA_LIST16 valist; - int i; - int aix; - - SYSLEVEL_ReleaseWin16Lock(); - - VA_START16( valist ); - nrofargs = VA_ARG16( valist, DWORD ); - argconvmask = VA_ARG16( valist, DWORD ); - proc32 = VA_ARG16( valist, FARPROC ); - TRACE("CallProc32W(%ld,%ld,%p, Ex%d args[",nrofargs,argconvmask,proc32,Ex); - args = (DWORD*)HEAP_xalloc( GetProcessHeap(), 0, - sizeof(DWORD)*nrofargs ); - /* CallProcEx doesn't need its args reversed */ - for (i=0;idwAvailVirtual = 32*1024*1024; } - -/********************************************************************** - * WOWGlobalAllocLock (KERNEL32.62) - * - * Combined GlobalAlloc and GlobalLock. - */ -SEGPTR WINAPI WOWGlobalAllocLock16(DWORD flags,DWORD cb,HGLOBAL16 *hmem) -{ - HGLOBAL16 xhmem; - xhmem = GlobalAlloc16(flags,cb); - if (hmem) *hmem = xhmem; - return WIN16_GlobalLock16(xhmem); -} - - -/********************************************************************** - * WOWGlobalUnlockFree (KERNEL32.64) - * - * Combined GlobalUnlock and GlobalFree. - */ -WORD WINAPI WOWGlobalUnlockFree16(DWORD vpmem) { - if (!GlobalUnlock16(HIWORD(vpmem))) - return 0; - return GlobalFree16(HIWORD(vpmem)); -} - - /*********************************************************************** * A20Proc16 (KERNEL.165) */ diff --git a/memory/selector.c b/memory/selector.c index 6cab7760c67..978568790f2 100644 --- a/memory/selector.c +++ b/memory/selector.c @@ -770,44 +770,6 @@ void WINAPI REGS_FUNC(FreeMappedBuffer)( CONTEXT *context ) #endif } -/********************************************************************** - * WOWGetVDMPointer (KERNEL32.55) - * Get linear from segmented pointer. (MSDN lib) - */ -LPVOID WINAPI WOWGetVDMPointer(DWORD vp,DWORD nrofbytes,BOOL protected) -{ - /* FIXME: add size check too */ - if (protected) - return PTR_SEG_TO_LIN(vp); - else - return DOSMEM_MapRealToLinear(vp); -} - -/********************************************************************** - * GetVDMPointer32W (KERNEL.516) - */ -LPVOID WINAPI GetVDMPointer32W(DWORD vp,WORD mode) -{ - return WOWGetVDMPointer(vp,0,(DWORD)mode); -} - -/********************************************************************** - * WOWGetVDMPointerFix (KERNEL32.55) - * Dito, but fix heapsegment (MSDN lib) - */ -LPVOID WINAPI WOWGetVDMPointerFix(DWORD vp,DWORD nrofbytes,BOOL protected) -{ - /* FIXME: fix heapsegment */ - return WOWGetVDMPointer(vp,nrofbytes,protected); -} - -/********************************************************************** - * WOWGetVDMPointerUnFix (KERNEL32.56) - */ -void WINAPI WOWGetVDMPointerUnfix(DWORD vp) -{ - /* FIXME: unfix heapsegment */ -} /*********************************************************************** * UTSelectorOffsetToLinear (WIN32S16.48) diff --git a/relay32/Makefile.in b/relay32/Makefile.in index 93137d30371..a754e26a79f 100644 --- a/relay32/Makefile.in +++ b/relay32/Makefile.in @@ -32,7 +32,8 @@ C_SRCS = \ builtin32.c \ relay386.c \ snoop.c \ - utthunk.c + utthunk.c \ + wowthunk.c GEN_ASM_SRCS = \ call32.s diff --git a/relay32/kernel32.spec b/relay32/kernel32.spec index c0192781b98..afd325acc9b 100644 --- a/relay32/kernel32.spec +++ b/relay32/kernel32.spec @@ -72,16 +72,16 @@ import ntdll.dll 55 stdcall K32WOWCallback16Ex(ptr long long ptr ptr) WOWCallback16Ex 56 stdcall K32WOWGetVDMPointer(long long long) WOWGetVDMPointer 57 stdcall K32WOWHandle32(long long) WOWHandle32 - 58 stub K32WOWHandle16 - 59 stdcall K32WOWGlobalAlloc16(long long) GlobalAlloc16 - 60 stdcall K32WOWGlobalLock16(long) WIN16_GlobalLock16 - 61 stdcall K32WOWGlobalUnlock16(long) GlobalUnlock16 - 62 stdcall K32WOWGlobalFree16(long) GlobalFree16 + 58 stdcall K32WOWHandle16(long long) WOWHandle16 + 59 stdcall K32WOWGlobalAlloc16(long long) WOWGlobalAlloc16 + 60 stdcall K32WOWGlobalLock16(long) WOWGlobalLock16 + 61 stdcall K32WOWGlobalUnlock16(long) WOWGlobalUnlock16 + 62 stdcall K32WOWGlobalFree16(long) WOWGlobalFree16 63 stdcall K32WOWGlobalAllocLock16(long long ptr) WOWGlobalAllocLock16 64 stdcall K32WOWGlobalUnlockFree16(long) WOWGlobalUnlockFree16 - 65 stub K32WOWGlobalLockSize16 - 66 stub K32WOWYield16 - 67 stub K32WOWDirectedYield16 + 65 stdcall K32WOWGlobalLockSize16(long ptr) WOWGlobalLockSize16 + 66 stdcall K32WOWYield16() WOWYield16 + 67 stdcall K32WOWDirectedYield16(long) WOWDirectedYield16 68 stdcall K32WOWGetVDMPointerFix(long long long) WOWGetVDMPointerFix 69 stdcall K32WOWGetVDMPointerUnfix(long) WOWGetVDMPointerUnfix 70 stdcall K32WOWGetDescriptor(long long) WOWGetDescriptor diff --git a/relay32/wow32.spec b/relay32/wow32.spec index 339e8a3cfb5..179fc9e0338 100644 --- a/relay32/wow32.spec +++ b/relay32/wow32.spec @@ -4,17 +4,17 @@ type win32 1 stdcall WOWGetDescriptor(long long) WOWGetDescriptor 2 stdcall WOWCallback16(long long) WOWCallback16 3 stdcall WOWCallback16Ex(ptr long long ptr ptr) WOWCallback16Ex - 4 stub WOWDirectedYield16 + 4 stdcall WOWDirectedYield16(long) WOWDirectedYield16 5 stdcall WOWGetVDMPointer(long long long) WOWGetVDMPointer 6 stdcall WOWGetVDMPointerFix(long long long) WOWGetVDMPointerFix 7 stdcall WOWGetVDMPointerUnfix(long) WOWGetVDMPointerUnfix - 8 stub WOWGlobalAlloc16 + 8 stdcall WOWGlobalAlloc16(long long) WOWGlobalAlloc16 9 stdcall WOWGlobalAllocLock16(long long ptr) WOWGlobalAllocLock16 - 10 stub WOWGlobalFree16 - 11 stub WOWGlobalLock16 - 12 stub WOWGlobalLockSize16 - 13 stub WOWGlobalUnlock16 + 10 stdcall WOWGlobalFree16(long) WOWGlobalFree16 + 11 stdcall WOWGlobalLock16(long) WOWGlobalLock16 + 12 stdcall WOWGlobalLockSize16(long ptr) WOWGlobalLockSize16 + 13 stdcall WOWGlobalUnlock16(long) WOWGlobalUnlock16 14 stdcall WOWGlobalUnlockFree16(long) WOWGlobalUnlockFree16 - 15 stub WOWHandle16 + 15 stdcall WOWHandle16(long long) WOWHandle16 16 stdcall WOWHandle32(long long) WOWHandle32 - 17 stub WOWYield16 + 17 stdcall WOWYield16() WOWYield16 diff --git a/relay32/wowthunk.c b/relay32/wowthunk.c new file mode 100644 index 00000000000..41760af02ee --- /dev/null +++ b/relay32/wowthunk.c @@ -0,0 +1,469 @@ +/* + * Win32 WOW Generic Thunk API + * + * Copyright 1999 Ulrich Weigand + */ + +#include "wine/winbase16.h" +#include "winbase.h" +#include "wownt32.h" +#include "heap.h" +#include "miscemu.h" +#include "syslevel.h" +#include "stackframe.h" +#include "builtin16.h" +#include "debugtools.h" + +DEFAULT_DEBUG_CHANNEL(thunk) + +/* + * 32-bit WOW routines (in WOW32, but actually forwarded to KERNEL32) + */ + +/********************************************************************** + * WOWGetDescriptor (WOW32.1) (KERNEL32.70) + */ +BOOL WINAPI WOWGetDescriptor( SEGPTR segptr, LPLDT_ENTRY ldtent ) +{ + return GetThreadSelectorEntry( GetCurrentThreadId(), + segptr >> 16, ldtent ); +} + +/********************************************************************** + * WOWGetVDMPointer (WOW32.5) (KERNEL32.56) + */ +LPVOID WINAPI WOWGetVDMPointer( DWORD vp, DWORD dwBytes, BOOL fProtectedMode ) +{ + /* FIXME: add size check too */ + + if ( fProtectedMode ) + return PTR_SEG_TO_LIN( vp ); + else + return DOSMEM_MapRealToLinear( vp ); +} + +/********************************************************************** + * WOWGetVDMPointerFix (WOW32.6) (KERNEL32.68) + */ +LPVOID WINAPI WOWGetVDMPointerFix( DWORD vp, DWORD dwBytes, BOOL fProtectedMode ) +{ + /* + * Hmmm. According to the docu, we should call: + * + * GlobalFix16( SELECTOROF(vp) ); + * + * But this is unnecessary under Wine, as we never move global + * memory segments in linear memory anyway. + * + * (I'm not so sure what we are *supposed* to do if + * fProtectedMode is TRUE, anyway ...) + */ + + return WOWGetVDMPointer( vp, dwBytes, fProtectedMode ); +} + +/********************************************************************** + * WOWGetVDMPointerUnFix (WOW32.7) (KERNEL32.69) + */ +VOID WINAPI WOWGetVDMPointerUnfix( DWORD vp ) +{ + /* + * See above why we don't call: + * + * GlobalUnfix16( SELECTOROF(vp) ); + * + */ +} + +/********************************************************************** + * WOWGlobalAlloc16 (WOW32.8) (KERNEL32.59) + */ +WORD WINAPI WOWGlobalAlloc16( WORD wFlags, DWORD cb ) +{ + return (WORD)GlobalAlloc16( wFlags, cb ); +} + +/********************************************************************** + * WOWGlobalFree16 (WOW32.10) (KERNEL32.62) + */ +WORD WINAPI WOWGlobalFree16( WORD hMem ) +{ + return (WORD)GlobalFree16( (HGLOBAL16)hMem ); +} + +/********************************************************************** + * WOWGlobalLock16 (WOW32.11) (KERNEL32.60) + */ +DWORD WINAPI WOWGlobalLock16( WORD hMem ) +{ + return (DWORD)WIN16_GlobalLock16( (HGLOBAL16)hMem ); +} + +/********************************************************************** + * WOWGlobalUnlock16 (WOW32.13) (KERNEL32.61) + */ +BOOL WINAPI WOWGlobalUnlock16( WORD hMem ) +{ + return (BOOL)GlobalUnlock16( (HGLOBAL16)hMem ); +} + +/********************************************************************** + * WOWGlobalAllocLock16 (WOW32.9) (KERNEL32.63) + */ +DWORD WINAPI WOWGlobalAllocLock16( WORD wFlags, DWORD cb, WORD *phMem ) +{ + WORD hMem = WOWGlobalAlloc16( wFlags, cb ); + if (phMem) *phMem = hMem; + + return WOWGlobalLock16( hMem ); +} + +/********************************************************************** + * WOWGlobalLockSize16 (WOW32.12) (KERNEL32.65) + */ +DWORD WINAPI WOWGlobalLockSize16( WORD hMem, PDWORD pcb ) +{ + if ( pcb ) + *pcb = GlobalSize16( (HGLOBAL16)hMem ); + + return WOWGlobalLock16( hMem ); +} + +/********************************************************************** + * WOWGlobalUnlockFree16 (WOW32.14) (KERNEL32.64) + */ +WORD WINAPI WOWGlobalUnlockFree16( DWORD vpMem ) +{ + if ( !WOWGlobalUnlock16( HIWORD(vpMem) ) ) + return FALSE; + + return WOWGlobalFree16( HIWORD(vpMem) ); +} + + +/********************************************************************** + * WOWYield16 (WOW32.17) (KERNEL32.66) + */ +VOID WINAPI WOWYield16( void ) +{ + /* + * This does the right thing for both Win16 and Win32 tasks. + * More or less, at least :-/ + */ + Yield16(); +} + +/********************************************************************** + * WOWDirectedYield16 (WOW32.4) (KERNEL32.67) + */ +VOID WINAPI WOWDirectedYield16( WORD htask16 ) +{ + /* + * Argh. Our scheduler doesn't like DirectedYield by Win32 + * tasks at all. So we do hope that this routine is indeed + * only ever called by Win16 tasks that have thunked up ... + */ + DirectedYield16( (HTASK16)htask16 ); +} + + +/*********************************************************************** + * WOWHandle32 (WOW32.16) (KERNEL32.57) + */ +HANDLE WINAPI WOWHandle32( WORD handle, WOW_HANDLE_TYPE type ) +{ + switch ( type ) + { + case WOW_TYPE_HWND: + case WOW_TYPE_HMENU: + case WOW_TYPE_HDWP: + case WOW_TYPE_HDROP: + case WOW_TYPE_HDC: + case WOW_TYPE_HFONT: + case WOW_TYPE_HMETAFILE: + case WOW_TYPE_HRGN: + case WOW_TYPE_HBITMAP: + case WOW_TYPE_HBRUSH: + case WOW_TYPE_HPALETTE: + case WOW_TYPE_HPEN: + case WOW_TYPE_HACCEL: + case WOW_TYPE_HTASK: + case WOW_TYPE_FULLHWND: + return (HANDLE)handle; + + default: + ERR( "handle 0x%04x of unknown type %d\n", handle, type ); + return (HANDLE)handle; + } +} + +/*********************************************************************** + * WOWHandle16 (WOW32.15) (KERNEL32.58) + */ +WORD WINAPI WOWHandle16( HANDLE handle, WOW_HANDLE_TYPE type ) +{ + if ( HIWORD(handle ) ) + ERR( "handle 0x%08x of type %d has non-zero HIWORD\n", handle, type ); + + switch ( type ) + { + case WOW_TYPE_HWND: + case WOW_TYPE_HMENU: + case WOW_TYPE_HDWP: + case WOW_TYPE_HDROP: + case WOW_TYPE_HDC: + case WOW_TYPE_HFONT: + case WOW_TYPE_HMETAFILE: + case WOW_TYPE_HRGN: + case WOW_TYPE_HBITMAP: + case WOW_TYPE_HBRUSH: + case WOW_TYPE_HPALETTE: + case WOW_TYPE_HPEN: + case WOW_TYPE_HACCEL: + case WOW_TYPE_HTASK: + case WOW_TYPE_FULLHWND: + return LOWORD(handle); + + default: + ERR( "handle 0x%08x of unknown type %d\n", handle, type ); + return LOWORD(handle); + } +} + +/********************************************************************** + * WOWCallback16 (WOW32.2) (KERNEL32.54) + */ +DWORD WINAPI WOWCallback16( DWORD vpfn16, DWORD dwParam ) +{ + DWORD ret; + + if ( !WOWCallback16Ex( vpfn16, WCB16_PASCAL, + sizeof(DWORD), &dwParam, &ret ) ) + ret = 0L; + + return ret; +} + +/********************************************************************** + * WOWCallback16Ex (WOW32.3) (KERNEL32.55) + */ +BOOL WINAPI WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags, + DWORD cbArgs, LPVOID pArgs, LPDWORD pdwRetCode ) +{ + DWORD ret; + + /* + * Arguments must be prepared in the correct order by the caller + * (both for PASCAL and CDECL calling convention), so we simply + * copy them to the 16-bit stack ... + */ + memcpy( (LPBYTE)CURRENT_STACK16 - cbArgs, (LPBYTE)pArgs, cbArgs ); + + + /* + * Actually, we should take care whether the called routine cleans up + * its stack or not. Fortunately, our CallTo16 core doesn't rely on + * the callee to do so; after the routine has returned, the 16-bit + * stack pointer is always reset to the position it had before. + */ + + ret = CallTo16Long( (FARPROC16)vpfn16, cbArgs ); + + if ( pdwRetCode ) + *pdwRetCode = ret; + + return TRUE; /* success */ +} + + + +/* + * 16-bit WOW routines (in KERNEL) + */ + +/********************************************************************** + * GetVDMPointer32W16 (KERNEL.516) + */ +DWORD WINAPI GetVDMPointer32W16( SEGPTR vp, UINT16 fMode ) +{ + return (DWORD)WOWGetVDMPointer( vp, 0, (DWORD)fMode ); +} + +/*********************************************************************** + * LoadLibraryEx32W16 (KERNEL.513) + */ +DWORD WINAPI LoadLibraryEx32W16( LPCSTR lpszLibFile, DWORD hFile, DWORD dwFlags ) +{ + HMODULE hModule; + + SYSLEVEL_ReleaseWin16Lock(); + hModule = LoadLibraryExA( lpszLibFile, (HANDLE)hFile, dwFlags ); + SYSLEVEL_RestoreWin16Lock(); + + return (DWORD)hModule; +} + +/*********************************************************************** + * GetProcAddress32W16 (KERNEL.515) + */ +DWORD WINAPI GetProcAddress32W16( DWORD hModule, LPCSTR lpszProc ) +{ + return (DWORD)GetProcAddress( (HMODULE)hModule, lpszProc ); +} + +/*********************************************************************** + * FreeLibrary32W16 (KERNEL.514) + */ +DWORD WINAPI FreeLibrary32W16( DWORD hLibModule ) +{ + BOOL retv; + + SYSLEVEL_ReleaseWin16Lock(); + retv = FreeLibrary( (HMODULE)hLibModule ); + SYSLEVEL_RestoreWin16Lock(); + + return (DWORD)retv; +} + + +/********************************************************************** + * WOW_CallProc32W + */ +static DWORD WOW_CallProc32W16( BOOL Ex ) +{ + DWORD nrofargs, argconvmask; + FARPROC proc32; + DWORD *args, ret; + VA_LIST16 valist; + int i; + int aix; + + SYSLEVEL_ReleaseWin16Lock(); + + VA_START16( valist ); + nrofargs = VA_ARG16( valist, DWORD ); + argconvmask = VA_ARG16( valist, DWORD ); + proc32 = VA_ARG16( valist, FARPROC ); + TRACE("(%ld,%ld,%p, Ex%d args[",nrofargs,argconvmask,proc32,Ex); + args = (DWORD*)HEAP_xalloc( GetProcessHeap(), 0, + sizeof(DWORD)*nrofargs ); + /* CallProcEx doesn't need its args reversed */ + for (i=0;iCallWOWCallbackProc(fproc,arg); - TRACE_(thunk)("... returns %ld\n",ret); - return ret; -} - -/********************************************************************** - * WOWCallback16Ex (KERNEL32.55)(WOW32.3) - * Calls a function in 16bit code. - * RETURNS - * TRUE for success - */ -BOOL WINAPI WOWCallback16Ex( - FARPROC16 vpfn16, /* [in] win16 function to call */ - DWORD dwFlags, /* [in] flags */ - DWORD cbArgs, /* [in] nr of arguments */ - LPVOID pArgs, /* [in] pointer to arguments (LPDWORD) */ - LPDWORD pdwRetCode /* [out] return value of win16 function */ -) { - return Callbacks->CallWOWCallback16Ex(vpfn16,dwFlags,cbArgs,pArgs,pdwRetCode); -} - /*********************************************************************** * ThunkInitLS (KERNEL32.43) * A thunkbuffer link routine @@ -1064,21 +1031,6 @@ BOOL16 WINAPI IsPeFormat16( return (xmagic == IMAGE_NT_SIGNATURE); } -/*********************************************************************** - * WOWHandle32 (KERNEL32.57)(WOW32.16) - * Converts a win16 handle of type into the respective win32 handle. - * We currently just return this handle, since most handles are the same - * for win16 and win32. - * RETURNS - * The new handle - */ -HANDLE WINAPI WOWHandle32( - WORD handle, /* [in] win16 handle */ - WOW_HANDLE_TYPE type /* [in] handle type */ -) { - TRACE_(win32)("(0x%04x,%d)\n",handle,type); - return (HANDLE)handle; -} /*********************************************************************** * K32Thk1632Prolog (KERNEL32.492) diff --git a/win32/ordinals.c b/win32/ordinals.c index 6b0966fd3eb..3f8cf854b9e 100644 --- a/win32/ordinals.c +++ b/win32/ordinals.c @@ -22,13 +22,6 @@ DECLARE_DEBUG_CHANNEL(thread) DECLARE_DEBUG_CHANNEL(win) DECLARE_DEBUG_CHANNEL(win32) -/********************************************************************** - * WOWGetDescriptor (KERNEL32.88) (WOW32.1) - */ -BOOL WINAPI WOWGetDescriptor(SEGPTR segptr,LPLDT_ENTRY ldtent) -{ - return GetThreadSelectorEntry(GetCurrentThreadId(),segptr>>16,ldtent); -} /*********************************************************************** * GetWin16DOSEnv (KERNEL32.34)