Microsoft KB Archive/149710

{|
 * width="100%"|

PRB: Why Thunking to 16-bit MAPI Will Fail Under Win32s

 * }

Q149710

-

The information in this article applies to:


 * Microsoft Win32s versions 1.30, 1.30c

-

SUMMARY
This article discusses the details on why a Win32s client (a 32-bit thunk DLL) cannot thunk to the 16-bit MAPI DLL. It also suggests several workarounds for this situation.

SYMPTOMS
The MAPI interface is not supported under any version of Win32s. In addition, a Win32s client (a 32-bit application or a DLL) cannot directly thunk down to 16-bit MAPI APIs in Windows 3.x. There are several resolutions for this scenario.

CAUSE
When the 16-bit MAPI DLL allocates a buffer on behalf of a call from the 32- bit thunk DLL, your 16-bit code will have to call UTSelectorOffsetToLinear on the returned 16:16 address. The result is a flat 32-bit address that can then be passed back to the 32-bit DLL. But when the 32-bit code is ready to call the 16-bit MAPIFreeBuffer function by way of the thunk, the flat 32-bit address needs to be converted back to the original 16:16 address that the 16-bit code can use. The normal solution is that the 16-bit code would call UTLinearToSelectorOffset on the 32-bit address passed from the 32-bit client before making a call to MAPIFreeBuffer.

But the problem is that in the following nested function call where x is a segmented (16:16) address, Win32s does not guarantee to return the original value of x (16:16 address) back. Hence, when MAPIFreeBuffer is called with this bogus 16:16 address, it fails.

  UTLinearToSelectorOffset( UTSelectorOffsetToLinear(x) )

Note that this address translation problem described here is not specific to the MAPI allocation and de-allocation routines. It applies to all 16-bit MAPI functions that use 16:16 segmented addresses.

RESOLUTION
Here are three approaches you can use to resolve this situation:


 * Correct the address translation problem that is inherent to Win32s. For each 16-bit MAPI function that would use or return a 16:16 segmented address and that needs to be converted to a 32-bit address to be passed on to the 32-bit side, you need to maintain a global lookup table or array on the 16-bit side that associates the new 32-bit address with the corresponding 16:16 address. When the 32-bit code calls into 16-bit code passing a valid 32-bit address, instead of calling UTLinearToSelectorOffset on this 32-bit address, you will have to fetch the corresponding 16:16 address from the lookup table. This 16:16 address can be used with all the MAPI functions on the 16-bit side.
 * Write a separate 16-bit client (a 16-bit DLL) that would implement the MAPI functionality by linking to the 16-bit MAPI DLL. The Win32s client (a 32-bit DLL) would then thunk to the 16-bit client DLL that makes the MAPI calls. The address translation problem does not exist in this scenario because all MAPI functionality is implemented and executed on the 16-bit side by the 16-bit client DLL linking to the 16-bit MAPI DLL.
 * Write a separate 16-bit client (a 16-bit application) that implements the MAPI functionality by linking to the 16-bit MAPI DLL. Then the Win32s client (either a 32-bit application or DLL) can communicate with this 16-bit client by way of the documented IPC (interprocess communication) methods that are available to Win32s. For more information on IPC mechanisms under Win32s, please see the following article in the Microsoft Knowledge Base:

Q95900 Interprocess Communication on Windows NT, Windows 95, & Win32s

Note that Visual Foxpro version 3.0b includes a DLL called Foxmapi.fll that implements the second workaround, allowing 32-bit Visual Foxpro applications to communicate with 16-bit MAPI functions under Win32s.

These three approaches are only suggestions; Microsoft cannot provide support if you decide to implement them in your Win32s-based application.

STATUS
This behavior is by design.

Additional query words: kbinf ipc mapi thunk win16 win32

Keywords : kbOSWin32s

Issue type : kbprb

Technology : kbWin32sSearch