Platform SDK: Win32 API |
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]
Value | Meaning |
---|---|
? | 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.