Compile your thunk script using the thunk compiler to create an .ASM file containing the flat thunk. The thunk compiler has the following syntax:
thunk [{-|/}options] infile[.ext]
? | Displays the help screen. |
h | Displays the help screen. |
o name | Overrides the default output filename. |
p n | Changes the 16-bit structure alignment (default = 2). |
P n | Changes the 32-bit structure alignment (default = 4). |
t name | Overrides the default base name. |
Nx name | Specifies the name segment or class, where x is either C32 (for 32-bit code segment name) or C16 (for 16-bit code segment name). |
The .ASM file produced by the thunk compiler contains code for both sides of the thunk. The 16-bit code in the .ASM file includes a jump table containing the 16:16 address of each function named in the thunk scripts. The 16-bit linker must be able to resolve these references; the functions must either be implemented in the 16-bit DLL or be imported by the DLL. The 32-bit code in the .ASM file contains a WINAPI function for each thunk, which converts its parameters to 16-bit values, then calls the 16-bit target referenced in the jump table. When a Win32-based application uses a 16-bit function through the thunk, it calls these compiler-generated functions directly.
Assemble the resulting .ASM file to create the 16-bit side of the thunk by defining IS_16. For example, using Microsoft MASM version 6.11, you can use the following command line:
ml /DIS_16 /c /W3 /nologo /Fo thk16.obj 16to32.asm
Assemble the resulting .ASM file to create the 32-bit side of the thunk by defining IS_32. For example, using Microsoft MASM version 6.11, you can use the following command line:
ml /DIS_32 /c /W3 /nologo /Fo thk32.obj 16to32.asm
Create the following declaration for the LineTo function in the thunk script:
typedef bool BOOL;
typedef unsigned int UINT;
typedef UINT HANDLE;
typedef HANDLE HDC;
BOOL LineTo(HDC, int, int)
{
}
When the thunk compiler processes the thunk script, it generates the following 16-bit code:
externDef LineTo:far16
FT_gdiTargetTable label word
dw offset LineTo
dw seg LineTo
In addition, the thunk compiler generates the following 32-bit code:
public LineTo@12
LineTo@12:
mov cl,0
; LineTo(16) = LineTo(32) {}
;
; dword ptr [ebp+8]: param1
; dword ptr [ebp+12]: param2
; dword ptr [ebp+16]: param3
;
public IILineTo@12
IILineTo@12:
call QT_Entry
push word ptr [ebp+8] ;param1: dword->word
push word ptr [ebp+12] ;param2: dword->word
push word ptr [ebp+16] ;param3: dword->word
call QT_Target_gdi
movsx ebx,ax
jmp QT_Exit12
When a Win32-based application calls the LineTo function, it is this routine that is executed. The routine builds a 16-bit call frame, calls a local routine requesting the appropriate address in the jump table, and sign-extends the return value. Each component receives its own set of routines (with the QT_ prefix), which automatically use the correct jump table.