Win32 Thunking Mechanism

As mentioned earlier in this document, the OS/2 subsystem provides a general mechanism to allow 16-bit OS/2 and PM applications to load and call any Win32 DLL. To take advantage of this feature, you typically need to complete the following tasks:

The following 16-bit APIs are to be used by the OS/2 application code. (These APIs are defined in the same manner as OS/2 APIs. See OS/2 1.2 Programmer's Reference Manual.)


USHORT pascal far Dos32LoadModule (
PSZ DLLName,
PULONG pDllHandle);

Purpose: Load a Win32 thunk DLL that will intermediate between an OS/2 application and Win32 APIs.

Returns: If NO_ERROR is returned, the value pointed to by pDllHandle is used for other Win32 thunk APIs as described below. It is invalid for usage with regular OS/2 APIs. If ERROR_MOD_NOT_FOUND is returned, the value pointed to by pDLLHandle is undefined.


USHORT pascal far Dos32GetProcAddr (
ULONG DllHandle,
PSZ pszProcName,
PULONG pWin32Thunk);

Purpose: Get a cookie (flat pointer) to a routine in a Win32 thunk DLL, previously opened by Dos32LoadModule. For example, if the OS/2 application wants to call the WinSocketFoo API, it builds a Win32 intermediate DLL, named MYSOCK.DLL, that exports MyWinSocketFoo. The application calls Dos32LoadModule with MYSOCK.DLL and then Dos32GetProcAddr with pszProcName of value MyWinSocketFoo. If no error is returned, it can use the value pointed to by pWin32Thunk in a later call to Dos32Dispatch, for calling the MyWinSocketFoo routine, which in turn will call a real Win32 API (for example, WinSocketFoo).

Returns: NO_ERROR if the pszProcName is exported by the Win32 intermediate DLL which relates to DllHandle. If ERROR_PROC_NOT_FOUND or ERROR_INVALID_HANDLE is returned, the value pointed to by pWin32Thunk is undefined.


USHORT pascal far Dos32Dispatch (
ULONG Win32Thunk,
PVOID pArguments,
PULONG pRetCode);

Purpose: Dos32Dispatch calls the 32-bit thunk routine Win32Thunk, previously obtained by Dos32GetProcAddr. It returns the error code returned by Win32Thunk in pRetCode. It translates the pArguments 16:16 pointer to a flat pointer and passes it to the Win32Thunk call. The structure pointed to by pArguments, and the values of pRetCode are application specific and are not interpreted or modified by the OS/2 subsystem.

On the Win32 side, i.e. in the Win32 DLL, the Win32 thunk has to be defined as follows:


ULONG MyWinSocketFoo (
PVOID pFlatArg);

The return code from MyWinSocketFoo is application-defined and is copied by the OS/2 subsystem to pRetCode.

Returns: NO_ERROR if the pFlatArg argument is a valid pointer and no exception occurred in the call to it.


USHORT pascal far Dos32FreeModule (
ULONG DllHandle);

Purpose: Unload a Win32 thunk DLL that intermediates between an OS/2 application and Win32 APIs.

Returns: NO_ERROR if DllHandle indeed corresponds to a Win32 DLL previously loaded by Dos32LoadModule (after the call, DllHandle is no longer valid). Otherwise, ERROR_INVALID_HANDLE is returned.


USHORT pascal far FarPtr2FlatPtr(
ULONG FarPtr,
PULONG pFlatPtr);

Purpose: Translates the segmented pointer FarPtr to a flat pointer pointed to by pFlatPtr.

Returns: NO_ERROR if FarPtr is a valid 16:16 pointer: in this case, upon completion of the call pFlatPtr contains a valid 32-bit flat pointer to be used by Win32 code. ERROR_INVALID_PARAMETER is returned if the 16:16 pointer is not valid: in this case the value pointed to by pFlatPtr is undefined.


USHORT pascal far FlatPtr2FarPtr(
ULONG FlatPtr,
PULONG pFarPtr);

Purpose: Translates the flat pointer FlatPtr to a far pointer which it stores into pFarPtr.

Returns: NO_ERROR if the 32-bit FlatPtr maps to a valid 16:16 pointer in the 16-bit application's context: in this case, upon completion of the call pFarPtr contains a valid 16:16 segmented pointer to be used by the 16-bit OS/2 code. Otherwise, i.e. if the 16:16 pointer is not a valid address in the 16-bit application's context, ERROR_INVALID_PARAMETER is returned and pFarPtr is undefined.

The following are the .H file and .DEF file that should be compiled and linked with the 16-bit OS/2 application:

The .H File


//
// Definition of WIN32 thunk APIs.
// extern USHORT pascal far
Dos32LoadModule(PSZ DllName, PULONG pDllHandle); extern USHORT pascal far
Dos32GetProcAddr(ULONG Handle, PSZ pszProcName, PULONG pWin32Thunk); extern USHORT pascal far
Dos32Dispatch(ULONG Win32Thunk, PVOID pArguments, PULONG pRetCode); extern USHORT pascal far
Dos32FreeModule(ULONG DllHandle); extern USHORT pascal far
FarPtr2FlatPtr(ULONG FarPtr, PULONG pFlarPtr); extern USHORT pascal far
FlatPtr2FarPtr(ULONG FlatPtr, PULONG pFarPtr);

The .DEF File


IMPORTS
DOSCALLS.DOS32LOADMODULE
DOSCALLS.DOS32GETPROCADDR
DOSCALLS.DOS32DISPATCH
DOSCALLS.DOS32FREEMODULE
DOSCALLS.FARPTR2FLATPTR
DOSCALLS.FLATPTR2FARPTR