2016-02-28 4 views
1

Я пытаюсь сделать что-то с помощью списка рабочего стола. Я могу получить текст элемента с LVM_GETITEM, но член структуры iImage всегда равен нулю, а также состояние. Я запускаю Win 7 64 и скомпилирован для 64 с Dev C++ (gcc). Я также попытался собрать его как 32 бит и протестировал на XP с тем же результатом ... просто текст, изображение и состояние назначены ноль. Я также могу получить элемент count без проблем с ListView_GetItemCount().Windows ListView LVM_GETITEM iImage всегда равен нулю

HWND progman = FindWindow("progman", NULL); 
HWND shell = FindWindowEx(progman, NULL, "shelldll_defview", NULL); 
HWND hwndListView = FindWindowEx(shell, NULL, "syslistview32", NULL); 
int ct = ListView_GetItemCount(hwndListView); 

const DWORD dwBufSize = 1024;  
DWORD dwProcessID; 
DWORD dwResult; 
HANDLE hProcess; 

BYTE *lpRemoteBuffer; 

LVITEM lvItem = {0}; 

BYTE lpLocalBuffer[dwBufSize] = {0}; 

// Get the process id owning the window 
::GetWindowThreadProcessId(hwndListView, &dwProcessID); 

// Open the process wih all access (You may not have the rights to do this) 
hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID); 

// Allocate a buffer in the remote process 
lpRemoteBuffer = (BYTE*)::VirtualAllocEx(hProcess, NULL, dwBufSize, 
MEM_COMMIT, PAGE_READWRITE); 

// Fill in the LVITEM struct, this is in your own process 
// Set the pszText member to somewhere in the remote buffer, 
// For the example I used the address imediately following the LVITEM stuct 
lvItem.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM|LVIF_STATE; 
lvItem.iItem = 0; 
lvItem.iSubItem = 0; 
lvItem.cchTextMax = MAX_PATH; 

// Point to after LVITEM in the remote buffer 
lvItem.pszText = (LPTSTR)(lpRemoteBuffer + sizeof(LVITEM)); 

// Copy the local LVITEM to the remote buffer 
::WriteProcessMemory(hProcess, (LPVOID)lpRemoteBuffer, &lvItem, sizeof(LVITEM), NULL); 

// Send the message 
::SendMessage(hwndListView, LVM_GETITEM, 0, (LPARAM)lpRemoteBuffer); 

// Read the struct back from the remote process into local buffer 
::ReadProcessMemory(hProcess, (LPVOID)lpRemoteBuffer, lpLocalBuffer, dwBufSize, NULL); 

//Fix pszText to point to same offset in local buffer 
lvItem.pszText = (LPTSTR)(lpLocalBuffer + sizeof(LVITEM)); 

MessageBox(hwnd, lvItem.pszText, "", 0); 

char txt[10]; 
ZeroMemory(txt, 10); 
MessageBox(hwnd, itoa(lvItem.iImage, txt, 10), "", 0); 
MessageBox(hwnd, itoa((int)lvItem.state, txt, 10), "", 0); 

// Clean-up 
::VirtualFreeEx(hProcess, (LPVOID)lpRemoteBuffer, 0, MEM_RELEASE); 
::CloseHandle(hProcess); 

ответ

1

Вы назначаете виртуальную память для текста. Вы также должны выделить виртуальную память для LVITEM. Затем назначьте текстовую память lvItem.pszText, а затем прочитайте обе памяти. Он должен быть скомпилирован 64-разрядной для 64-битных систем. Добавьте дополнительные проверки ошибок.

HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | 
    PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, dwProcessID); 

const DWORD dwBufSize = 1024; 
void* pbuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE); 
void* pitem = VirtualAllocEx(hProcess, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE); 

LVITEM lvItem = { 0 }; 
lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE; 
lvItem.iItem = 0; 
lvItem.iSubItem = 0; 
lvItem.cchTextMax = MAX_PATH; 
lvItem.pszText = (char*)pbuf; 

WriteProcessMemory(hProcess, pitem, &lvItem, sizeof(LVITEM), NULL); 

if (SendMessage(hwndListView, LVM_GETITEM, 0, (LPARAM)(LVITEM*)(pitem))) 
{ 
    char buf[dwBufSize]; 
    if (ReadProcessMemory(hProcess, pbuf, buf, dwBufSize, 0)) 
    { 
     OutputDebugString(buf); 
     OutputDebugString(", "); 
     if (ReadProcessMemory(hProcess, pitem, &lvItem, sizeof(LVITEM), 0)) 
     { 
      _itoa_s(lvItem.iImage, buf, 10); 
      OutputDebugString(buf); 
      OutputDebugString("\n"); 
     } 
    } 
} 

VirtualFreeEx(hProcess, pitem, 0, MEM_RELEASE); 
VirtualFreeEx(hProcess, pbuf, 0, MEM_RELEASE); 
CloseHandle(hProcess); 
+0

Отлично, спасибо! Я попробую и опубликую результаты. – kizeloo

+0

Получается, мне больше не нужно это делать, но спасибо за помощь! Я проголосую за ваш ответ. – kizeloo

+0

Это, наверное, самое лучшее. Доступ к рабочему столу с помощью этого метода не рекомендуется. –

Смежные вопросы