Types of Thunking Available in Win32 Platforms

Last reviewed: April 7, 1997
Article ID: Q125710
1.30 4.00 | 3.50 3.51 4.00
WINDOWS   | WINDOWS NT
kbprg

The information in this article applies to:

  • Microsoft Win32 Application Programming Interface (API) included with:

        - Microsoft Windows NT versions 3.5, 3.51, 4.0
        - Microsoft Windows 95 version 4.0
        - Microsoft Win32s version 1.30a, 1.30c
    

SUMMARY

Neither Windows NT, Windows 95, or Win32s 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 into code on the other side of the boundary. Each Win32 platform employs one or more thunking mechanisms. This table summarizes the thunking mechanisms provided by the different Win32 platforms.

                   +-Win32s-+-Windows 95-+-Windows NT-+
   Generic Thunk   |        |      X     |      X     |
                   +--------+------------+------------+
   Universal Thunk |    X   |            |            |
                   +--------+------------+------------+
   Flat Thunk      |        |      X     |            |
                   +--------+------------+------------+

Generic Thunks allow a 16-bit Windows-based application to load and call a Win32-based DLL on Windows NT and Windows 95.

Windows 95 also supports a thunk compiler and the Flat Thunks mechanism, that allows a Win32-based application to load and call a 16-bit DLL or a 16-bit application to load and call a Win32-based DLL.

Win32s Universal Thunks (UT) allow a Win32-based application running under Windows 3.1 to load and call a 16-bit DLL. You can also use UT to allow a 16-bit Windows-based application to call a 32-bit DLL under Win32s, but this isn't officially supported. Certain things do not work on the 32-bit side because the app was loaded within the context of a 16-bit Windows- based application.

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

MORE INFORMATION

Windows NT

Windows NT supports Generic Thunks, which allow 16-bit code to call into 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 subsystem (or environment) called WOW (Windows On Win32). Each application runs as a thread in a VDM (virtual DOS machine).

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-based DLL called by the thunk is loaded into the VDM address space. The following is a example of thunking a call to GetVersionEx():

      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;
      }

Win32s

All 16-bit Windows-based and Win32-based applications run in a single address space in Win32s. The mechanism that is provided for accessing 16- bit code from 32-bit code is called the Universal Thunk. The Universal Thunks mechanism consists of 4 APIs. The major APIs, UTRegister() and UTUnRegister(), are exported by KERNEL32. The prototype for UTRegister() is:

      BOOL UTRegister(HANDLE hModule,          // Win32-based DLL handle
                      LPCTSTR lpsz16BITDLL,    // 16-bit DLL to call
                      LPCTSTR lpszInitName,    // thunk initialization
                                               // procedure
                      LPCTSTR lpszProcName,    // thunk procedure
                      UT32PROC *ppfn32Thunk,   // pointer to thunk
                                               // procedure
                      FARPROC pfnUT32CallBack, // optional callback
                      LPVOID lpBuff);          // shared memory buffer

NOTES: lpszInitName, pfnUT32CallBack, and lpBuff are optional parameters. The value for ppfn32Thunk is the returned value of the 32-bit function pointer to the thunk procedure. The buffer lpBuff is a globally allocated shared memory buffer that is available to the 16-bit initialization routine via a 16-bit selelctor:offset pointer.

The function pointer returned in ppfn32Thunk has the following syntax:

      WORD (*ppfn32Thunk)(lpBuff, dwUserDefined, *lpTranslationList);

where lpBuff is the pointer to the shared data area, dwUserDefined is available for application use (it is most commonly used as a switch for multiple thunked functions), and lpTranslationList is an array of flat pointers within lpBuff that are to be translated into selector:offset pointers.

This method is not portable to other platforms.

Windows 95

Thunking in Windows 95 allows 16-bit code to call 32-bit code and vice- versa using a mechanism called Flat Thunks. Flat Thunks under Windows 95 uses the thunk compiler and other components that are included with the Win32 SDK. 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. NOTE: These thunks are not portable to other platforms.

The thunk compiler produces a single assembly language file. This single assembly language file should be assembled using two different flags - DIS_32 and -DIS_16 to produce a 16-bit and 32-bit object files. These object modules should be liked to their respective 16-bit and 32-bit DLL's. There are no special APIs used, all you have to do is call the function.

In addition to Flat Thunks, Windows 95 supports the Windows NT Generic Thunk mechanism. Generic thunks are recommended for portability between Windows 95 and Windows NT.

REFERENCES

For more information on Generic Thunks, see GENTHUNK.TXT on the Win32 SDK CD-ROM (under the \MSTOOLS\DOCS\MISC directory), and refer to the following Microsoft Knowledge Base article:

   ARTICLE-ID: Q104009
   TITLE     :Generic Thunks: Calling a Win32 DLL from a Win16 Application

For more information on the Universal Thunk, see the "Win32s Programmer's Reference" and the UTSAMP sample on the Win32 SDK CD.

For more information on Flat Thunks and the Thunk compiler under Windows 95, Universal Thunk, refer to the Win32 SDK documentation under the section "Programming and Tools Guides, Programmer's Guide to Windows 95, Using Windows 95 Features, Thunk Compiler".

In addition, you can query the Microsoft Knowledge Base with the appropriate keywords on each thunk mechanism to find further information.


KBCategory: kbprg
KBSubcategory: SubSys BseThunks
Additional reference words: 1.30 1.30c 3.50 3.51 4.00
Keywords : BseThunks SubSys W32sThunk kbprg
Version : 1.30 4.00 | 3.50 3.51 4.00
Platform : NT WINDOWS


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: April 7, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.