Click to See Complete Forum and Search --> : Mapping Address Spaces for 32 bit Windows


Dan Kelly
November 29th, 1999, 10:34 AM
I have what should be a simple problem, but it may be a bug in Windows. I want to read the text for a SysListView32 window that is not within my application (in a different address space). The problem seems to be that Windows only maps the message level address pointer when accessing Windows routines. This works fine for the older 16 bit window types. However, the messages for the 32-bit ListViews are not flat and contain a pointer for the text string. Requesting text will thereby crash the application that owns the listview. (You address an unmapped address pointer.) I cannot map the address since it is internal to a Windows defined structure required by the ListView access routines. Although Windows documentation states that you should not (can not) use pointers within data structures being passed between applications in 32 bit Windows, the newer 32 bit Windows system functions do just that. This would not be a problem if Windows maps all of its pointer, but it appears to Map only the highest level pointer. (Microsoft designed the 32-bit mapping functions for the older 16-bit environments, which did not require mapping and then deisgn 32-bit windows so that it could not map them.)

Does anybody know a solution?

Feng Yuan
December 3rd, 1999, 08:27 PM
Do may need to be more specific on what's your program.

For several messages, Windows does special processing to make sure pointer to buffer works well across process address space. For example WM_GETTEXT, WM_GETTEXT, WM_COPYDATA all have pointers and all work across address space.

I'm not sure about specific list view messages. If you have the source code for both sides, try to avoid the problem use something like WM_COPYDATA. If you really want to hack into other process, injet a DLL into it. If you know the address, try ReadProcessMemory.

Dan Kelly
December 6th, 1999, 08:20 AM
The problem is that when you access ListViews using the SDK you eventually end up sending a message LVM_GETITEM to the ListView window. The Windows message LPARAM contains a pointer, pitem, to a data structure LVITEM, (SendMessage(hWnd,LVM_GETITEM ,0,(LPARAM) (LPLVITEM) pitem)).

If you look at LVITEM it contains a pointer pszText. You specify this parameter. This parameter is a pointer to the data structure for Windows to copy the text associated with the ListView into. (It is data space allocated by the application.)

typedef struct _LVITEM {
UINT mask;
int iItem;
int iSubItem;
UINT state;
UINT stateMask;
LPTSTR pszText;
int cchTextMax;
int iImage;
LPARAM lParam;
#if (_WIN32_IE >= 0x0300)
int iIndent;
#endif
} LVITEM, FAR *LPLVITEM;

Normally, you access Windows data from within the task that owns the window. Thus, pitem and pszText will be valid addresses. However, when you access this data from a different task Windows will treat this LVM_GETITEM message just like it does WM_GETTEXT or WM_COPYDATA and translate the pointer that is in the message and copies the data to this address. However, the LVITEM data structure is not FLAT like the older messages. It contains a pointer that also needs to be translated. (Microsoft specifically says you cannot have pointers within data structures that are passed between tasks because they will not be translated. In this case I have no choice since Microsoft is specifying it!) Now if you request the text, the operating system will crash when it copies the text data to the location defined by this unmapped pointer in the present task. Naturally, all the other parts of the LVITEM are accessible.
To me it appears to be a pure OS bug or feature as Microsoft would describe it that cannot be worked around. It greatly limits innovation in user interfaces. I was curious why features like auto detection of phone numbers, that were available in Windows 3.1, are no longer available. The real question is why would such a simple problem exists and Microsoft never corrected it?. Is there a workaround? Do I not understand something? Perhaps it is just an attempt by Microsoft to limit some of the innovation that was being done by the dreaded third parties?

For me to use something like ReadProcessMemory I would have to have access to the Windows OS sources that define where Windows keeps the data and its format. If Microsoft ever releases Windows sources than workarounds could be found for many problems and innovation could return to the software development field. However, today trying to solve problem with Windows as a non-Microsoft developer is a shot in the dark and your only hope is that somebody will spill a secret on how to get around blatant OS deficiencies.