PRB: GlobalAlloc() Pagelocks Blocks on Win32s (114611)



The information in this article applies to:

  • Microsoft Win32s 1.3c
  • Microsoft Win32s 1.1
  • Microsoft Win32s 1.15
  • Microsoft Win32s 1.2
  • Microsoft Win32s 1.3

This article was previously published under Q114611

SYMPTOMS

If a Win32-based application running in Win32s uses GlobalAlloc() to allocate memory from the global heap with GMEM_FIXED, with GPTR, with GMEM_ZEROINIT, or without specifying GMEM_MOVEABLE the memory allocated will be fixed and page-locked.

CAUSE

When a Win32 application running under Win32s on Windows 3.1 calls GlobalAlloc() the call is translated via a thunk supplied by Win32s in a 16- bit DLL. The 16-bit DLL then calls the Windows 3.1 function GlobalAlloc(). When GlobalAlloc() is called from a DLL in Windows 3.1 the allocated memory will be fixed and page-locked unless GMEM_MOVEABLE is specified.

RESOLUTION

The GlobalAlloc() flags should always include GMEM_MOVEABLE if memory does not need to be fixed and page-locked. This is expected behavior for Windows 3.1.

MORE INFORMATION

A Windows-based application will not fix or page-lock memory even when specifically using the GMEM_FIXED flag. This behavior is unique to Windows version 3.1; using GlobalAlloc() with GMEM_FIXED to allocate fixed and page- locked memory must be done in a DLL.

In Windows 3.1, the GMEM_FIXED flag is defined as 0x0000. Using GMEM_ZEROINIT without GMEM_MOVEABLE will command GlobalAlloc() to allocate using GMEM_FIXED by default. Since Win32s passes all GlobalAlloc() calls to the Windows 3.1 GlobalAlloc() by a DLL, GlobalAlloc() called from either a Win32 application or a Win32 DLL will allocate the block fixed and page- locked unless the GMEM_MOVEABLE flag is specified.

The following code illustrates this case:
   {
   HGLOBAL hMem;

   // allocate a block from the global heap

   hMem = GlobalAlloc(GMEM_ZEROINIT, 512);

     .
     .
     .

   }
				
Although this source code is compatible between applications for Windows 3.1 and applications for Windows NT running on Win32s, the result is different. A 16-bit application running on Windows 3.1 will allocate the memory as moveable and zero the contents. A Win32 application running on Win32s will allocate the memory as fixed and page-locked and zero the contents.

REFERENCES

Appendix B, titled "System Limits", of the "Win32s Programmer's Reference Manual" briefly mentions on page 56 not to use GMEM_FIXED in GlobalAlloc() called by 32-bit applications.

Modification Type:MajorLast Reviewed:4/13/2004
Keywords:KB114611