LVM_GETITEMTEXT для x32 и x64 в C - PullRequest
       28

LVM_GETITEMTEXT для x32 и x64 в C

4 голосов
/ 24 декабря 2010

Я пытался получить текст элементов в просмотре списка другим процессом.Я нашел потрясающий учебник по CodeProject .Благодаря этой статье я смог сделать это на x32.Но при попытке запуска на x64 происходит сбой приложения, к которому я пытаюсь получить доступ, когда вызывается SendMessage.В комментариях к статьям у людей были одинаковые проблемы из-за разного размера указателя.Некоторые люди предложили использовать компилятор x64, который я не могу использовать.Мне нужно, чтобы моя программа работала на x32 / x64.Один парень предложил:

У меня есть ответ.Структура LVITEM неверна в 64-битных системах.Указатели теперь 64-битные, поэтому за указателем текста должно следовать фиктивное значение, чтобы корректно сместить элемент длины.

Я думаю, что это будет лучшим решением, так как я могу его запуститьдля х32 и х64 с одним exe.Я просто понятия не имею, как делать то, о чем он говорит.Я включил мой код, который в настоящее время работает на x32.Если кто-нибудь может мне помочь.Это было бы здорово.

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's 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);

Ответы [ 2 ]

2 голосов
/ 09 февраля 2012

Отправка сообщения LVM_GETITEMTEXT из 32-битного приложения в 64-битный ListView: фактически возможно .

Мне удалось добиться этого, используя не оригинальную LVITEM (длина 60 байт), а структуру LVITEM (длина 88 байт) с семью 4-байтовыми заполнителями, вставленными между элементами.Он работает на моем 64-битном Win7 Pro, хотя я еще не тестировал этот подход на других машинах.

Ниже приведена структура.Это C ++, но ничто не мешает нам делать то же самое в .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;
2 голосов
/ 25 декабря 2010

Я не думаю, что вы сможете достичь этого. В 32-битном процессе ваши указатели будут слишком короткими. Я полагаю, что VirtualAllocEx потерпит неудачу при вызове из 32-битного процесса и с дескриптором 64-битного процесса в качестве первого параметра. Я думаю, вы бы увидели это, если бы добавили проверку ошибок в свой код.

Ваше единственное решение будет иметь 2 версии, x86 и x64. Это не должно быть настоящей проблемой - обычно это можно сделать с одним источником.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...