Microsoft KB Archive/125710

{|
 * width="100%"|

PRB: Types of Thunking Available in Win32 Platforms

 * }

Q125710

This article discusses a Beta release of a Microsoft product. The information in this article is provided as-is and is subject to change without notice.

No formal product support is available from Microsoft for this Beta product. For information about obtaining support for a Beta release, please see the documentation included with the Beta product files, or check the Web location from which you downloaded the release.

-

The information in this article applies to:


 * Microsoft Win32 Software Development Kit (SDK), on platform(s):
 * Microsoft Windows NT Server versions 3.5, 3.51, 4.0
 * Microsoft Windows NT Workstation versions 3.5, 3.51, 4.0
 * Microsoft Windows 95
 * Microsoft Win32s versions 1.30a, 1.3c
 * the operating system: Microsoft Windows 2000

-

SYMPTOMS
Windows NT, Windows 95, Windows 98, and Windows 2000 do not allow direct mixing of 16-bit code and 32-bit code in the same process. All these platforms support some sort of an IPC mechanism, such as DDE, RPC, OLE, named pipes, and WM_COPYDATA, that you can use for communication between 16-bit code and 32-bit code. However, there are occasions when it is necessary to call a function in 32-bit code from 16-bit code or vice-versa.

Thunks allow code on one side of the 16-32 process boundary to call code on the other side of the boundary. Each Win32 platform employs one or more thunking mechanisms. The following table summarizes the thunking mechanisms provided by the different Win32 platforms:

Generic thunks allow a 16-bit Windows-based application to load and call a Win32-based DLL.

Windows 95 and Windows 98 also support a second method called flat thunks, which allows a Win32 application to load and call a 16-bit DLL, or a 16-bit application to load and call a Win32 DLL.

This article describes the types of thunking mechanisms available on each Win32 platform.

Windows NT and Windows 2000
Windows NT and Windows 2000 support generic thunks, which allow 16-bit code to call 32-bit code. Generic thunks must be initiated from a 16-bit Windows-based application. Once the thunk is established, the 32-bit code can make a callback to the 16-bit code using WOWCallback16. The generic thunk is implemented by using a set of API functions that are exported by the WOWKERNEL and Wow32.dll.

In Windows NT, 16-bit Windows-based applications are executed in a VDM (virtual DOS machine) running the WOW (Windows on Win32) subsystem. The WOW subsystem is a Win32 process. Each 16-bit application runs as a thread in a VDM's WOW process.

Using generic thunks is like explicitly loading a DLL. The five major APIs used in generic thunking are: LoadLibraryEx32W, FreeLibrary32W, GetProcAddress32W, CallProc32W, or CallProcEx32W. Their functionality is very similar to LoadLibraryEx, FreeLibrary, GetProcAddress, and calling the function through a function pointer. The Win32 DLL called by the thunk is loaded into the VDM address space. The following is an example of thunking a call to GetVersionEx via a generic thunk:

Sample Code
     void FAR PASCAL __export MyGetVersionEx(OSVERSIONINFO *lpVersionInfo) {        HINSTANCE32 hKernel32; FARPROC lpGetVersionEx;

// Load KERNEL32.DLL if (!(hKernel32 = LoadLibraryEx32W("KERNEL32.DLL", NULL, NULL))) {           MessageBox(NULL, "LoadLibraryEx32W Failed", "DLL16", MB_OK); return; }

// Get the address of GetVersionExA in KERNEL32.DLL if (!(lpGetVersionEx = GetProcAddress32W( hKernel32, "GetVersionExA"))) {           MessageBox(NULL, "GetProcAddress32W Failed", "DLL16", MB_OK); return; }        lpVersionInfo->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

// Call GetVersionExA CallProc32W(lpVersionInfo, lpGetVersionEx, 1, 1);

// Free KERNEL32.DLL if (!FreeLibrary32W(hKernel32)) {           MessageBox(NULL, "FreeLibrary32W Failed", "DLL16", MB_OK); return; }        return; }

Windows 95 and Windows 98
Windows 95 and Windows 98 allow 16-bit code to call 32-bit code and vice- versa using a mechanism called flat thunks. Flat thunks use a thunk compiler and updated 16-bit resource compiler that are included with the Platform SDK. Because the output of the thunk compiler is an assembly- language file, a copy of Microsoft Macro Assembler (MASM) 6.1 or later is also needed.

To use the thunk compiler, you need to create a thunk script, which is the function prototype with additional information about input and output variables. The thunk compiler produces a single assembly language file. This assembly language file must be assembled twice, each time using one of two different flags, -DIS_32 and -DIS_16, to produce 16-bit and 32-bit object files. These object modules must be liked to their respective 16-bit and 32-bit DLLs. There are no special APIs used, all you have to do is call the thunked function on one side of the thunk, and implement it on the other side.

NOTE: These thunks are not portable to other platforms.

In addition to flat thunks, Windows 95 and Windows 98 support the generic thunk mechanism. Generic thunks are recommended for portability between Windows 95/Windows 98 and Windows NT/Windows 2000.