I have a piece of C++ code which reads out the text of a tree item (as contained in a plain Common Controls Tree View) using the TVM_GETITEM window message. The tree view which receives the mesage is in a different process, so I'm using a little bit of shared memory for the structure which is pointed to by one of the arguments to the window message. I have to do this work since the remote process is not under my control (I'm writing an application similiar to Spy++).
This works well in principle, but fails in case the target process is substantially different:
If the code of the target process was built with UNICODE defined but my own code wasn't, the two processes will have different ideas about the structure of the string members in the TVITEM structure. I solved this already using an IsWindowUnicode call and then explicitely sending either
TVM_GETITEMA
orTVM_GETITEMW
(recoding the result if necessary).If the calling process was built in 32bit mode and the target process is 64bit (or the other way round), the layout (and size) of the TVITEM structure structure is different since pointers have a different size.
I'm currently trying to find a good way to solve the second issue. This particular use case (getting the tree item text) is just an example, the same issue exists for other window messages which my code is sending. Right now, I'm considering two approaches:
- Build my code twice and then execute either the 32bit or the 64bit code depending on what the target process does. This requires some changes to our build- and packaging system, and it requires factoring the code which is architecture specific out into a dedicated process (right now it's in a DLL). Once that is done, it should work nicely.
- Detect the image format of the target process at runtime and then use custom structs instead of the TVITEM structure structure which explicitely use 32bit or 64bit wide pointers. This requires writing code to detect the architecture of a remote process (I hope I can do this by calling GetModuleFileName on the remote process and then analyzing the PE header using the Image Help Library) and hardcoding two structs (one with 32bit pointers, one with 64bit). Furthermore, I have to make sure that the shared memory address is in the 32bit address space (so that my own code can always access it, even if it's compiled in 32bit mode).
Did anybody else have to solve a similiar problem? Are there easier solutions?