diff --git a/if1632/kernel.spec b/if1632/kernel.spec index d06f4029854..2dd2d9db385 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -397,7 +397,7 @@ file krnl386.exe 490 pascal16 KERNEL_490(word) KERNEL_490 491 pascal RegisterServiceProcess(long long) RegisterServiceProcess 492 stub WOAAbort -493 stub UTInit +493 pascal16 UTInit(long long long long) UTInit16 494 stub KERNEL_494 # 495 is present only in Win98 diff --git a/if1632/thunk.c b/if1632/thunk.c index fbc98ce6158..ec782913fc9 100644 --- a/if1632/thunk.c +++ b/if1632/thunk.c @@ -166,6 +166,7 @@ static const CALLBACKS_TABLE CALLBACK_EmulatorTable = (void *)CallTo16_word_www, /* CallResourceHandlerProc */ (void *)CallTo16_long_l, /* CallWOWCallbackProc */ THUNK_WOWCallback16Ex, /* CallWOWCallback16Ex */ + (void *)CallTo16_long_ll, /* CallUTProc */ (void *)CallTo16_long_l, /* CallASPIPostProc */ (void *)CallTo16_word_lwll, /* CallDrvControlProc */ (void *)CallTo16_word_lwlll, /* CallDrvEnableProc */ diff --git a/if1632/wprocs.spec b/if1632/wprocs.spec index 1ccca024794..c9ea5753b0c 100644 --- a/if1632/wprocs.spec +++ b/if1632/wprocs.spec @@ -8,6 +8,7 @@ type win16 18 pascal ReplaceTextDlgProc(word word word long) ReplaceTextDlgProc16 19 pascal PrintSetupDlgProc(word word word long) PrintSetupDlgProc16 20 pascal PrintDlgProc(word word word long) PrintDlgProc16 +23 pascal UTGlue16(ptr long ptr long) UTGlue16 24 pascal16 TASK_Reschedule() TASK_Reschedule 27 pascal EntryAddrProc(word word) NE_GetEntryPoint 28 pascal MyAlloc(word word word) NE_AllocateSegment diff --git a/include/callback.h b/include/callback.h index 08556954187..066e3edb805 100644 --- a/include/callback.h +++ b/include/callback.h @@ -42,6 +42,7 @@ typedef struct DWORD (CALLBACK *CallWOWCallbackProc)( FARPROC16, DWORD ); BOOL (CALLBACK *CallWOWCallback16Ex)( FARPROC16, DWORD, DWORD, LPVOID, LPDWORD ); + DWORD (CALLBACK *CallUTProc)( FARPROC16, DWORD, DWORD ); LRESULT (CALLBACK *CallASPIPostProc)( FARPROC16, SEGPTR ); /* Following are the graphics driver callbacks */ WORD (CALLBACK *CallDrvControlProc)( FARPROC16, SEGPTR, WORD, diff --git a/misc/callback.c b/misc/callback.c index bd882482d07..327deb65e63 100644 --- a/misc/callback.c +++ b/misc/callback.c @@ -237,6 +237,16 @@ static BOOL WINAPI CALLBACK_CallWOWCallback16Ex( return TRUE; } +/********************************************************************** + * CALLBACK_CallUTProc + */ +static DWORD WINAPI CALLBACK_CallUTProc( DWORD w1, DWORD w2 ) +{ + ERR( relay, "Cannot call a UT thunk proc in Winelib\n" ); + assert( FALSE ); + return 0; +} + /********************************************************************** * CALLBACK_CallTaskRescheduleProc */ @@ -275,6 +285,7 @@ static const CALLBACKS_TABLE CALLBACK_WinelibTable = CALLBACK_CallResourceHandlerProc, /* CallResourceHandlerProc */ CALLBACK_CallWOWCallbackProc, /* CallWOWCallbackProc */ CALLBACK_CallWOWCallback16Ex, /* CallWOWCallback16Ex */ + CALLBACK_CallUTProc, /* CallUTProc */ CALLBACK_CallASPIPostProc, /* CallASPIPostProc */ /* The graphics driver callbacks are never used in Winelib */ NULL, /* CallDrvControlProc */ diff --git a/relay32/Makefile.in b/relay32/Makefile.in index 2e92ec84077..4c1ca52dcd0 100644 --- a/relay32/Makefile.in +++ b/relay32/Makefile.in @@ -48,7 +48,8 @@ DLLS = \ C_SRCS = \ builtin32.c \ relay386.c \ - snoop.c + snoop.c \ + utthunk.c SPEC_FILES = $(DLLS:.spec=.c) diff --git a/relay32/utthunk.c b/relay32/utthunk.c new file mode 100644 index 00000000000..cc747b8d9dc --- /dev/null +++ b/relay32/utthunk.c @@ -0,0 +1,285 @@ +/* + * Win32s Universal Thunk API + * + * Copyright 1999 Ulrich Weigand + */ + +#include "wintypes.h" +#include "heap.h" +#include "module.h" +#include "selectors.h" +#include "callback.h" +#include "debug.h" +#include "debugstr.h" + +#pragma pack(1) + +typedef struct +{ + BYTE popl_eax; + BYTE pushl; + DWORD target; + BYTE pushl_eax; + BYTE ljmp; + DWORD utglue16; + +} UT16THUNK; + +typedef struct +{ + BYTE popl_eax; + BYTE pushl; + DWORD target; + BYTE pushl_eax; + BYTE jmp; + DWORD utglue32; + +} UT32THUNK; + +#pragma pack(4) + +typedef struct tagUTINFO +{ + struct tagUTINFO *next; + HMODULE hModule; + HMODULE16 hModule16; + + UT16THUNK ut16; + UT32THUNK ut32; + +} UTINFO; + +static UTINFO *utAnchor; + +BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL, + LPSTR lpszInitName, LPSTR lpszProcName, + FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack, + LPVOID lpBuff ); + +VOID WINAPI UTUnRegister( HMODULE hModule ); + + +/**************************************************************************** + * UTGlue16 (WPROCS.*) + */ +DWORD WINAPI UTGlue16( LPVOID lpBuff, DWORD dwUserDefined, SEGPTR translationList[], + DWORD (CALLBACK *target)( LPVOID lpBuff, DWORD dwUserDefined ) ) +{ + INT i; + + /* Convert arguments to flat pointers */ + + if ( translationList ) + for ( i = 0; translationList[i]; i++ ) + { + LPVOID flatPtr = PTR_SEG_TO_LIN( translationList[i] ); + *(LPVOID *)flatPtr = PTR_SEG_TO_LIN( *(SEGPTR *)flatPtr ); + } + + /* Call 32-bit routine */ + + return target( lpBuff, dwUserDefined ); +} + +/**************************************************************************** + * UTGlue32 + */ +DWORD WINAPI UTGlue32( FARPROC16 target, LPVOID lpBuff, DWORD dwUserDefined, + LPVOID translationList[] ) +{ + SEGPTR segBuff, *segptrList = NULL; + INT i, nList = 0; + DWORD retv; + + /* Convert arguments to SEGPTRs */ + + if ( translationList ) + for ( nList = 0; translationList[nList]; nList++ ) + ; + + if ( nList ) + { + segptrList = HeapAlloc( GetProcessHeap(), 0, sizeof(SEGPTR)*nList ); + if ( !segptrList ) + { + FIXME( thunk, "Unable to allocate segptrList!" ); + return 0; + } + + for ( i = 0; i < nList; i++ ) + segptrList[i] = *(SEGPTR *)translationList[i] + = MapLS( *(LPVOID *)translationList[i] ); + } + + segBuff = MapLS( lpBuff ); + + /* Call 16-bit routine */ + + retv = Callbacks->CallUTProc( target, segBuff, dwUserDefined ); + + /* Free temporary selectors */ + + UnMapLS( segBuff ); + + if ( nList ) + { + for ( i = 0; i < nList; i++ ) + UnMapLS( segptrList[i] ); + + HeapFree( GetProcessHeap(), 0, segptrList ); + } + + return retv; +} + +/**************************************************************************** + * UTAlloc + */ +static UTINFO *UTAlloc( HMODULE hModule, HMODULE16 hModule16, + FARPROC16 target16, FARPROC target32 ) +{ + UTINFO *ut = HeapAlloc( SegptrHeap, HEAP_ZERO_MEMORY, sizeof(UTINFO) ); + if ( !ut ) return NULL; + + ut->hModule = hModule; + ut->hModule16 = hModule16; + + ut->ut16.popl_eax = 0x58; + ut->ut16.pushl = 0x68; + ut->ut16.target = (DWORD)target32; + ut->ut16.pushl_eax = 0x50; + ut->ut16.ljmp = 0xea; + ut->ut16.utglue16 = (DWORD)MODULE_GetWndProcEntry16( "UTGlue16" ); + + ut->ut32.popl_eax = 0x58; + ut->ut32.pushl = 0x68; + ut->ut32.target = (DWORD)target16; + ut->ut32.pushl_eax = 0x50; + ut->ut32.jmp = 0xe9; + ut->ut32.utglue32 = (DWORD)UTGlue32 - ((DWORD)&ut->ut32.utglue32 + sizeof(DWORD)); + + ut->next = utAnchor; + utAnchor = ut; + + return ut; +} + +/**************************************************************************** + * UTFree + */ +static void UTFree( UTINFO *ut ) +{ + UTINFO **ptr; + + for ( ptr = &utAnchor; *ptr; ptr = &(*ptr)->next ) + if ( *ptr == ut ) + { + *ptr = ut->next; + break; + } + + HeapFree( SegptrHeap, 0, ut ); +} + +/**************************************************************************** + * UTFind + */ +static UTINFO *UTFind( HMODULE hModule ) +{ + UTINFO *ut; + + for ( ut = utAnchor; ut; ut =ut->next ) + if ( ut->hModule == hModule ) + break; + + return ut; +} + + +/**************************************************************************** + * UTRegister (KERNEL32.697) + */ +BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL, + LPSTR lpszInitName, LPSTR lpszProcName, + FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack, + LPVOID lpBuff ) +{ + UTINFO *ut; + HMODULE16 hModule16; + FARPROC16 target16, init16; + + /* Load 16-bit DLL and get UTProc16 entry point */ + + if ( (hModule16 = LoadLibrary16( lpsz16BITDLL )) <= 32 + || (target16 = WIN32_GetProcAddress16( hModule16, lpszProcName )) == 0 ) + return FALSE; + + /* Allocate UTINFO struct */ + + SYSTEM_LOCK(); + if ( (ut = UTFind( hModule )) != NULL ) + ut = NULL; + else + ut = UTAlloc( hModule, hModule16, target16, pfnUT32CallBack ); + SYSTEM_UNLOCK(); + + if ( !ut ) + { + FreeLibrary16( hModule16 ); + return FALSE; + } + + /* Call UTInit16 if present */ + + if ( lpszInitName + && (init16 = WIN32_GetProcAddress16( hModule16, lpszInitName )) != 0 ) + { + SEGPTR callback = SEGPTR_GET( &ut->ut16 ); + SEGPTR segBuff = MapLS( lpBuff ); + + if ( !Callbacks->CallUTProc( init16, callback, segBuff ) ) + { + UnMapLS( segBuff ); + UTUnRegister( hModule ); + return FALSE; + } + UnMapLS( segBuff ); + } + + /* Return 32-bit thunk */ + + *ppfn32Thunk = (FARPROC) &ut->ut32; + + return TRUE; +} + +/**************************************************************************** + * UTUnRegister (KERNEL32.698) + */ +VOID WINAPI UTUnRegister( HMODULE hModule ) +{ + UTINFO *ut; + HMODULE16 hModule16 = 0; + + SYSTEM_LOCK(); + ut = UTFind( hModule ); + if ( !ut ) + { + hModule16 = ut->hModule16; + UTFree( ut ); + } + SYSTEM_UNLOCK(); + + if ( hModule16 ) + FreeLibrary16( hModule16 ); +} + +/**************************************************************************** + * UTInit16 (KERNEL.494) + */ +WORD WINAPI UTInit16( DWORD x1, DWORD x2, DWORD x3, DWORD x4 ) +{ + FIXME( thunk, "(%08lx, %08lx, %08lx, %08lx): stub\n", x1, x2, x3, x4 ); + return 0; +} + diff --git a/win32/newfns.c b/win32/newfns.c index 501452542e0..902a79b8128 100644 --- a/win32/newfns.c +++ b/win32/newfns.c @@ -16,30 +16,6 @@ at a later date. */ #include "debug.h" #include "debugstr.h" -/**************************************************************************** - * UTRegister (KERNEL32.697) - */ -BOOL WINAPI UTRegister(HMODULE hModule, - LPSTR lpsz16BITDLL, - LPSTR lpszInitName, - LPSTR lpszProcName, - /*UT32PROC*/ LPVOID *ppfn32Thunk, - /*FARPROC*/ LPVOID pfnUT32CallBack, - LPVOID lpBuff) -{ - FIXME(updown, "(%#x,...): stub\n",hModule); - return TRUE; -} - -/**************************************************************************** - * UTUnRegister (KERNEL32.698) - */ -BOOL WINAPI UTUnRegister(HMODULE hModule) -{ - FIXME(updown, "(%#x...): stub\n", hModule); - return TRUE; -} - /**************************************************************************** * QueryPerformanceCounter (KERNEL32.564)