INF: Rules for Locking Data

PSS ID Number: Q11267
Article last modified on 11-05-1993

1.x 2.03 2.10 3.00
WINDOWS

----------------------------------------------------------------------
The information in this article applies to:

 - Microsoft Windows Software Development Kit for Windows version 3.0
----------------------------------------------------------------------

SUMMARY
=======
The following explains the circumstances under which LockData() and
UnlockData() are needed to prevent long pointers from being
invalidated by segment movement.

MORE INFORMATION
================
The rules for data segment locking are as follows:
1. An application's data segment is created with a lock count of one.
2. When a call to GetMessage(), WaitMessage(), or PeekMessage() is
   made, the lock count of SS (which is the same segment as DS, since
   SS==DS in an application), is decremented by one before
   relinquishing control to another application. The lock count is
   incremented again when it returns. Thus, while another application
   is running, the DS has a lock count of 0 and is free to move
   around, unless the application has incremented the lock count.
3. LocalAlloc() and LocalRealloc() can decrement an application's data
   segment lock count by one to expand the local heap.
These rules imply that only GetMessage(), PeekMessage(), LocalAlloc(),
and LocalRealloc() can invalidate outstanding 32-bit pointers.
LockData() and UnlockData() are necessary only if these calls are made
and 32-bit pointers are outstanding.
If the application's data segment is movable, it must not keep any
outstanding 32-bit pointers into DS past any call that can unlock and
move DS, unless the application uses LockData() to increment the lock
count and prevent movement. A typical outstanding 32-bit pointer would
be of the form
   lpChar = (LPSTR)(address of a global or frame variable)
-or-
   lpChar = (LPSTR)LocalLock(...)
Calls of the following form create a 32-bit pointer, but are safe
because DS is locked and TextOut() doesn't unlock it:
   TextOut(..., (LPSTR)"Hello", ...)

Notes
-----
1. MessageBox() and DialogBox() both call GetMessage() implicitly.
   AddAtom() calls LocalAlloc() implicitly.
2. In a DLL, SS!=DS so that GetMessage(), PeekMessage(), and
   WaitMessage() decrement the lock count on only SS so that the DS's
   lock count remains unchanged. LocalAlloc() and LocalRealloc()
   decrement the lock count of DS without affecting SS.
3. WM_CREATE messages contain an lParam, which is a far pointer to a
   CREATESTRUCT structure. This structure resides in the application's
   stack, so this long pointer will be invalidated if you cause your
   DS to move while processing WM_CREATE.

Additional reference words: 2.x 3.0
KBCategory: 
KBSubcategory: KrMmFixlockwire
Copyright Microsoft Corporation 1993.