Locking Your Own Data Segment

Now that you are thoroughly paranoid about locking and unlocking memory blocks, you may start to wonder about the automatic data segment of the program itself. When the program begins executing, your automatic data segment has a lock count of 1, and the data segment cannot be moved in memory. Windows decrements that lock count when the program makes one of the following calls: GetMessage, PeekMessage, WaitMessage, LocalAlloc, or LocalReAlloc.

The GetMessage, PeekMessage, and WaitMessage calls can cause a switch from your program to another program. When your program gets control again, your data segment may have been moved. A LocalAlloc or LocalReAlloc call can cause Windows to expand the size of your local heap, in the process moving the data segment to another location in memory. Windows increments the lock count when it returns from these calls to your program. So in most cases, your program's data segment is locked when your program has control. This means that you can construct (through casting) far pointers to data in your data segment, and they will remain valid until you make one of these five calls or exit the window procedure.

If you want to prevent the movement of your data segment during a LocalAlloc or LocalReAlloc call, you can increase the lock count by 1 before calling the function:

LockData (0) ;

Following the LockData call, the lock count of your data segment will be 2. When Windows decrements the count during a LocalAlloc or LocalReAlloc call, it will still be positive and your data segment will still be locked. You can decrement the lock count by calling:

UnlockData (0) ;

If you're brave, you might also want to take the opposite approach. You might be willing to keep your data segment unlocked while making Windows calls. You would do this by calling UnlockData to decrement the lock count to 0 and then LockData to increment it to 1 again before exiting the window procedure. When your data segment is unlocked, Windows has more flexibility in moving segments in memory because Windows can move your data segment as well. However, when your data segment is unlocked, you should not make any Windows calls that require a far pointer to your data segment. Depending on what happens during that call, the pointer may become invalid by the time Windows needs to use it.