LVM_GETITEMTEXT for x32 and x64 in C

I am trying to get the text of elements in a listview of another process. I found a great CodeProject tutorial. Thanks to this article, I was able to do this on x32. But when you try to run on x64, this will crash the application that I am trying to access when SendMessage is called. In the comments to the articles, people had problems due to the different sizes of the pointer. Some people have suggested using the x64 compiler, which I cannot use. I need my program to run on x32 / x64. One guy suggested:

I have an answer. LVITEM is an incorrect structure in a 64-bit system. Pointers are now 64-bit, so a dummy value should be followed by a text pointer to compensate for the length of the member correctly.

I think this would be a better solution, since I could run it for x32 and x64 with one exe. I just don’t know how to do what the hydropower plant says. I have included my code, which currently runs on x32. If anyone can help me. It would be nice.

LVITEMLVITEM lvi, *_lvi; char item[512]; char *_item; unsigned long pid; HANDLE process; GetWindowThreadProcessId(procList, &pid); process = OpenProcess(0x001f0fff, FALSE, pid); _lvi = (LVITEM*)VirtualAllocEx(process, NULL, sizeof(LVITEM), 0x1000, 4); _item = (char*)VirtualAllocEx(process, NULL, 512, 0x1000, 4); lvi.cchTextMax = 512; int r, c; for (r = 0; r < rowCount; r++) { for (c = 0; c < columnCount; c++) { lvi.iSubItem = c; lvi.pszText =_item; // Insert lvi into programs memory WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL); // Have program write text to in its memory where we told it to SendMessage(procList, LVM_GETITEMTEXT, (WPARAM)r, (LPARAM)_lvi); // Get TVITEM back from programs ReadProcessMemory(process, _item, item, 512, NULL); } } // Clean up the mess we made VirtualFreeEx(process, _lvi, 0, MEM_RELEASE); VirtualFreeEx(process, _item, 0, MEM_RELEASE); CloseHandle(process); 
+4
source share
2 answers

I do not think you can achieve this. In a 32-bit process, your pointers will be too short. I believe that VirtualAllocEx will fail when called from a 32-bit process and with a 64-bit process descriptor as its first parameter. I think you will see this if you add error checking to your code.

Your only solution is to have 2 versions of x86 and x64. This should not be a real problem - it can usually be done from a single source.

+2
source

Sending LVM_GETITEMTEXT from a 32-bit application to a 64-bit ListView is possible .

I was able to achieve this using not the original LVITEM structure (60 bytes long), but the LVITEM structure (88 bytes long) with seven 4-byte placeholders inserted between the participants. It works on my 64-bit Win7 Pro, although I have not tested this approach on other machines yet.

Below is the structure. This is C ++, but nothing prevents us from doing the same in .NET.

 typedef struct { UINT mask; int iItem; int iSubItem; UINT state; UINT stateMask; int placeholder1; LPTSTR pszText; int placeholder11; int cchTextMax; int iImage; LPARAM lParam; int placeholder2; #if (_WIN32_IE >= 0x0300) int iIndent; #endif #if (_WIN32_WINNT >= 0x0501) int iGroupId; UINT cColumns; int placeholder3; UINT puColumns; int placeholder4; #endif #if (_WIN32_WINNT >= 0x0600) int piColFmt; int placeholder5; int iGroup; int placeholder6; #endif } LVITEM64, *LPLVITEM64; 
+1
source

Source: https://habr.com/ru/post/1333308/


All Articles