Microsoft KB Archive/114340

INF: Win32s 1.1 Limitations PSS ID Number: Q114340 Article last modified on 07-08-1994

1.10

WINDOWS

= SUMMARY =

The following is a list of limitations of Win32s, not including the complete list of unsupported Win32 APIs.

= MORE INFORMATION =

  Thread creation is not supported.   Win32s uses the Windows 3.1 nonpreemptive scheduling mechanism.   Win32s has a shared address space, so instance data for dynamic link libraries (DLLs) is not supported.   Win32 processes should be started from a Win16 application through WinExec or Int 21 4B. LoadModule does not start a Win32 process.   Win32 applications cannot use the EM_SETHANDLE or EM_GETHANDLE messages to access the text in a multiline edit control. These messages allow the sharing of local memory handles between an application and USER.EXE. In Win32s, an application’s local heap is 32-bit, so USER.EXE cannot interpret the local handle. To read and write multiline edit control text, an application should use WM_GETTEXT and WM_SETTEXT. Text for multiline edit controls is stored in the 16-bit local heap in DGROUP, which is allocated by Windows 3.1 for the WIN32S.EXE stub that is loaded before each Win32 application is loaded. This means that the size of edit control text is limited to somewhat less than 64K.   The CBT hook thunks do not copy back the contents of structures, so any changes will be lost.   Win32 applications should not call through return from SetWindowsHook. SetWindowsHook returns a pointer to the next hook in the chain. To call this function, the application is supposed to call DefHookProc and pass a pointer to a variable where this address is stored. Because Win32s simulates the old hook API in terms of the new, SetWindowsHook actually passes back a hook handle, not a function pointer.   Win32s requires all modules to be linked with 4K alignment. Temporarily, the loader supports 64K as well. </li>  Integer ID must be a 16-bit value. </li>  PostMessage and PeekMessage do not thunk structures. These functions do not allocate space for repacking structures, because there is no way to know when to free up the space. </li>  Private application messages should not use high word of wParam. Win32s uses Windows 3.1 to deliver window messages. For unknown messages, wParam is truncated to make it fit into 16 bits. Therefore, Win32 applications should not put 32-bit quantities into the wParam of privately defined messages, which are unknown to the thunk layer. </li>  Win32s allows a Win32 application to allocate memory at a specific address; however, because of the shared address space on Windows 3.1, this is more likely to fail under Win32s. </li>  DDE messages are always posted, not sent, except for two: WM_DDE_INITIATE and WM_DDE_ACK, responding to the former. The sent form of WM_DDE_ACK is different from the posted form. When sent, no thunking of lParam is necessary when going between 16- and 32-bit format. However, when posting, the lParam parameter is repacked as two DWORDs into private memory, allocated by COMBO.DLL (or by USER.DLL in Windows NT). The thunk layer makes this distinction through the InSendMessage function. Therefore, a Win32 application should not do anything in the processing of a WM_DDE_INITIATE message that would cause the return code from InSendMessage to be FALSE. </li>  The following DDE messages are handled differently by different applications under Windows and Win32: WM_DDE_ACK WM_DDE_ADVISE WM_DDE_DATA WM_DDE_EXECUTE WM_DDE_POKE Because of widening of handles, there is not enough space in the Win32 message parameters for all the Windows 3.1 data. Win32 applications are required to call helper functions that package the data into memory (DDEPACK structure) referenced by a special handle. Win32s implements the helper functions, and allocates the DDEPACK structure on behalf of 16-bit code when necessary. As with other memory handles shared through DDE, there are rules concerning who frees the memory allocated by these helper routines: lParam = PackDDElParam(…) if( PostMessage(…,lParam) ) receiving window has obligation of freeing memory lParam now invalid for this process else FreeDDElParam(…,lParam) A Win32s hook procedure that has called CallNextHookProc should not use the lParam handle if the latter’s return code indicates that the message has been processed. The hooks that could possibly process a DDE message are: WH_DEBUG WH_HARDWARE WH_KEYBOARD WH_MOUSE WH_MSGFILTER WH_SYSMSGFILTER In each case, if the hook proc (and therefore CallNextHookEx) returns a non-zero value, the message was either discarded or processed. WndProcs should not use the lParam of a DDE message after handing it off to any other message API, because they cannot know if the message has been processed and therefore must assume that it has been. </li>  WDEB386 does not support FreeSegment for 32-bit segments. Win32s Kernel Debugger support depends on it. </li>  Resource table size for PE is limited to 32K (not including the resource data). </li>  SetClipbrdData must be used only with global handle. Otherwise the data can not be accessed by other applications. </li>  Win32s supports printing exactly as Windows 3.1 does. Win32s does not add beziers, paths, or transforms to GDI; to let applications use these features on PostScript printers, you must call the Escape function with the appropriate escape codes. Applications link to Windows 3.1 printer drivers through the LoadLibrary and GetProcAddress APIs, which have special support for this purpose. There is no mechanism allowing a Win32 application to link to a 16-bit DLL. </li>  Win32s does not support the following GDI escape codes: BANDINFO ;24 GETSETPAPERBINS ;29 ENUMPAPERMETRICS ;34 EXTTEXTOUT ;512 SETALLJUSTVALUES ;771 </li>  Integer atoms must be in the range 0 0x3FFF. This restriction is necessary for the current implementation of the window properties API thunks: SetProp, GetProp, RemoveProp, EnumProps, and EnumPropsEx. Integer atoms above 0x4000 are rejected by the thunk layer. </li>  Arrays must fit in 64K after converting to 16-bit format. An array passed to a function such as SetCharABCWidths or Polyline must fit within 64K after its elements have been converted to their 16-bit form. Its 32-bit form may be bigger than 64K. </li>  Temporarily, all Windows 3.1 APIs that return void return 1 to the Win32 application. </li>  Win32 child window ID’s must be sign-extended 16-bit values. This excludes the use of 32-bit pointer values as child ID’s. </li>  When calling PeekMessage, a Win32 application should not filter any messages for Windows 3.1 internal window classes (button, edit, scrollbar, and so forth). The messages for these controls are mapped to different values in Win32, and checking for the necessity of mapping is time-consuming. </li> <li> The dwThreadId parameter in SetWindowsHookEx is ignored. The dwThreadId is translated to hTask in Windows 3.1. There’s a bug in Windows 3.1 where if hTask!=NULL, the call may fail. This needs further investigation. </li> <li> Floating point (FP) emulation by exception cannot be performed in 16-bit applications. When tasks are switched between applications, the CR0-EM bit state is not preserved, in order to support 32-bit application FP emulation by exception without breaking the existing 16-bit applications that use FP instructions. The CR0-EM bit is assumed to be cleared during execution of 16-bit-application FP instructions. Upon executing a 16-bit application FP instruction, the bit is cleared and reset when switching back to a 32-bit application. The CR0-EM bit management is done in the Win32s VxD, thus disabling the possibility of getting an int 7 exception just by setting the CR0-EM bit in a 16-bit application. </li> <li> EndDialog nResult parameter is sign-extended. Applications specify the return value for the DialogBox function by way of the nResult parameter to the EndDialog function. This parameter is of type “int”, which is 32-bit in Win32s. However, this value is thunked through to the Windows 3.1 EndDialog function, which truncates it to a 16-bit value. Win32s sign-extends the return code from DialogBox. </li> <li> GetClipBox returns SIMPLEREGION(2) and COMPLEXREGION(3). Because Windows NT is a preemptive multitasking system, GetClipBox on Windows NT never returns SIMPLEREGION(2); the reason for this is that between the time the API was called and the time the application gets the result, the region may change. Win32s can return both SIMPLEREGION(2) and COMPLEXREGION(3). </li> <li> PeekMessage filtering for posted messages (hWnd==-1) is not supported. The hWnd is replaced with NULL. </li> <li> Message queue length is limited to Windows default: 8 (or whatever the length) was set by DefaultQueueSize=n in WIN.INI. This limit may be increased in the future to a larger size, but there will always be a limit. </li> <li> GetFileTime and SetFileTime process only the lpLastWriteTime parameter and return an error if this parameter is not supplied. </li> <li> The precision of the time of a file is 2 seconds (DOS limitation). </li> <li> CommDlg does not support private dialog templates. The dialog templates need to be converted back and forth between 16- and 32-bit formats. Until Win32s 1.15, private dialog templates are not supported. </li> <li> GetPrivateProfileString returns an error when the lpszSection parameter is NULL instead of giving all the section names in the inifile, as it does under Windows NT. </li> <li> TLS locations are the same in all processes for a specific DLL. This is because Win32s does not support instance data for DLLs. The TLS locations are unique per DLL. Each DLL should call TlsAlloc only once per index if it is running under Win32s. The index returned is then valid for all Win32 processes. The DLL can maintain several indices. </li> <li> GlobalCompact is thunked through to the Windows 3.1 GlobalCompact. This API has no effect on memory allocated through VirtualAlloc, which does not come from the Win3.1 global heap. </li> <li> GetVolumeInformation does not support the Volume ID. </li> <li> GetFileInformationByHandle and the CRT fstat that uses it are not supported. Both are supported in Win32s, version 1.15. The dwFileAttribute of GetFileInformationByHandle is always zero. This also causes fstat to return an st_mode of read/write regardless the actual attribute. </li> <li> CreatePolyPolygonRgn requires a closed polygon, as it does under Windows 3.1. If the polygons are not closed, the Windows NT call closes the polygons for you. In Windows 3.1/Win32s, if the polygons are not closed, the call does not create the region correctly or returns an error for an invalid parameter. </li> <li> Win32s does not support DIB_PAL_INDICES option for SetDIBits. It will be supported in future release. DIB_PAL_PHYSINDICES and DIB_PAL_LOGINDICES are not supported either. </li> <li> The WH_FOREGROUNDIDLE hook type is not supported. Windows 3.1 does not provide the necessary support. </li> <li> The brush styles BS_DIBPATTERNPT and BS_PATTERN8X8 are not supported and cause an error to be returned. </li> <li> The hFile in DLL and PROCESS events is not supported under Win32s because there is no support for duplicating file handles between processes (basically an MS-DOS limitation). There are two ways to access the image bytes: ReadProcessMemory or open the file in compatibility mode (the name is provided in lplpImageName). </li> <li> Under Windows NT, NetBIOS keeps a different name table for each process. On Win32s, there is only one NetBIOS name table for the system. Each name (group or unique) added by a process is kept in a doubly linked list. Through NCBRESET or by destroying the process, we delete all the names that were added by the process. Win32s does not implement the full NetBIOS 3.0 specification, which has a separate name table per process. </li> <li> When calling 32-bit code from 16-bit code with UT (for example, from interrupt routine) the stack must be at least 10K. The interrupt routine must ensure that the stack will be big enough. </li> <li> Get/SetThreadContext can be called only from within an exception. At all other times, this function returns FALSE and the error code is set to ERROR_CAN_NOT_COMPLETE. </li> <li> CreateProcess PROCESS_INFORMATION is not supported for 16-bit applications. A valid structure must be passed to CreateProcess, but the function fills all the fields with NULLs and zeroes. </li> <li> CreateProcess does not support handle inheritance. </li> <li> CreateFile FILE_FLAG_NO_BUFFERING and FILE_FLAG_WRITE_THROUGH are not supported. </li> <li> Win32s does not support NT event mechanism; therefore, the ncb_event field in NCB structure is not supported. </li> <li> CreateFileMapping does not support SEC_NOCACHE nor SEC_NOCOMMIT. The call fails with ERROR_INVALID_PARAMETER. </li> <li> When EM_GETFIRSTVISIBLELINE is sent to a single-line edit control, the return is always 0. This is the underlying Windows 3.1 behavior. New behavior was added under Windows NT. The return is the same for a multi- line edit control under Win32s and Windows NT. </li> <li> Always use device-independent bitmaps for color bitmaps. Win32s supports the four Win32 “device-dependent” bitmap APIs. These are device- dependent in the sense that the bitmap bits are supplied without a color table to explain their meaning. CreateBitmap CreateBitmapIndirect GetBitmapBits SetBitmapBits These are well-defined and fully supported for monochrome bitmaps. For color bitmaps, these APIs are not well defined and Win32s relies on Windows 3.1 for their support. This means that an application cannot know the format of the bits returned by GetBitmapBits and should not attempt to directly manipulate them. The values returned by GetDeviceCaps for PLANES and BITSPIXEL, and the values returned by GetObject for a bitmap, do not necessarily indicate the format of the bits returned by GetBitmapBits.It is possible for the GDI DIB APIs to be unsupported on some displays. However, it is now rare for display drivers to not support DIBs. The one case where it is not uncommon to encounter a lack of DIB support is with printer drivers, which may not support the GetDIBits API, though most do support the SetDIBits API. Win32s does not transform the bits in any way when passing them on to a Windows 3.1 API. When running an application that creates a device- dependent bitmap through CreateBitmap or CreateBitmapIndirect, be aware that the bits it is passing in may not be in the right format for the device. Windows NT takes care of this by treating the bits as a DIB whose format is consistent with the PLANES and BITSPIXEL values; but Win32s simply passes them through. </li> <li> After calling FindText, an application cannot directly access the FINDREPLACE structure. When an application calls the common dialog box function FindText, it passes a FINDREPLACE structure. The FindText dialog box communicates with the owner window through a registered message, in which the lParam points to the structure. The thunks repack this structure in place, so that unless the application is processing the registered message, it should not access the structure. </li> <li> Subclassing a window that owns a FindText common dialog does not work. The FindText thunk repacks the FINDREPLACE structure in place. This means that 32-bit WndProcs cannot subclass 16-bit owners of FindText dialog boxes without likely trashing four bytes beyond the end of the structure, because the 32-bit FINDREPLACE is four bytes bigger than the 16-bit version. For 32-bit owners of the dialog box, there are also problems. Whenever the structure might be referenced by 16-bit code, it needs to be in the 16-bit format. However, when the FindText dialog box terminates, the structure needs to be in 32-bit format so that the application can read the final values. The dialog box indicates to its owner that it is about to be destroyed by sending the commdlg_FindReplace message with the FR_DIALOGTERM bit set in the Flags field of the FINDREPLACE structure. After sending this message, the FindText dialog does not reference the structure anymore, so that the commdlg_FindReplace thunk leaves it in 32-bit format. The problem occurs when the owner has been subclassed. Once the message has moved to the 32-bit side, the structure is not reconverted to 16- bit. Suppose the dialog box owner was subclassed by a 16-bit WndProc, which was in turn subclassed by a 32-bit WndProc. When a message is sent to the owner, it will first go to 32-bit, then to 16-bit, then back to 32-bit to the original WndProc: <ol style="list-style-type: decimal;"> <li> 16->32 message sent to 32-bit subclasser (repacked to 32-bit) </li> <li> 32->16 message sent to 16-bit subclasser (not repacked) </li> <li> 16->32 message sent to 32-bit original WndProc (not repacked) </li></ol>

The 16-bit subclasser cannot interpret the message parameters because they are in 32-bit format. Between steps 2 and 3, the structure is not repacked because it’s already in 32-bit format. When a Win32 application calls FindText, allocate the following: <ol style="list-style-type: decimal;"> <li> A structure that contains the htask of WIN32S.EXE </li> <li> The original 32-bit FINDREPLACE pointer </li> <li> A count of the number of times the structure has been thunked without returning </li> <li> A 16-bit format copy of FINDREPLACE </li></ol>

The structure is repacked into the 16-bit version and this copy is passed to Windows. The count is initially zero. When the commdlg_FindReplace message is sent in either direction (16->32 or 32->16), repack the structure on the stack. If it was originally 32-bit, increment the count. When returning, unpack the structure and, if originally 32-bit, decrement the count. If the Flags field of the structure has the FR_DIALOGTERM bit set, the structure is originally 32- bit, and the count goes to 0 on a return, then repack the structure back to the original 32-bit space. </li></ul>

Additional reference words: 1.10 KBCategory: Prg KBSubcategory: W32s

=
================================================================

Copyright Microsoft Corporation 1994.