用来干什么就不用说了,反正不是什么好事情 =v=

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
typedef struct _DESKTOP_ICON_INFO {
	LVITEMW item;
	WCHAR item_text[MAX_PATH];
	RECT rc;
} DESKTOP_ICON_INFO, *PDESKTOP_ICON_INFO;

BOOL GetDesktopIconInfo(LPCWSTR pattern, RECT &rc, HWND &desktop)
{
	HWND progman = FindWindow(TEXT("Progman"), TEXT("Program Manager"));
	if (progman == NULL) {
		return FALSE;
	}
	

	HWND def_view = FindWindowEx(progman, NULL, TEXT("SHELLDLL_DefView"), NULL);
	if (def_view == NULL) {
		return FALSE;
	}

	HWND list_view = FindWindowEx(def_view, NULL, TEXT("SysListView32"), TEXT("FolderView"));
	if (list_view == NULL) {
		return FALSE;
	}
	desktop = list_view;

	ULONG process_id = 0;
	GetWindowThreadProcessId(progman, &process_id);
	if (process_id == 0) {
		return FALSE;
	}

	int count = (int)::SendMessage(list_view, LVM_GETITEMCOUNT, 0, 0);

	HANDLE process_handle = OpenProcess(
		PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, process_id);
	if (process_handle == NULL) {
		return FALSE;
	}

	PUCHAR remote_addr = (PUCHAR)VirtualAllocEx(process_handle, NULL, 
		sizeof(DESKTOP_ICON_INFO), MEM_COMMIT, PAGE_READWRITE);

	DESKTOP_ICON_INFO icon_info;
	icon_info.item.iItem = 0;
	icon_info.item.iSubItem = 0;
	icon_info.item.mask = LVIF_TEXT;
	icon_info.item.pszText = (WCHAR *)(remote_addr + offsetof(DESKTOP_ICON_INFO, item_text));
	icon_info.item.cchTextMax = MAX_PATH;

	for (int i = 0; i < count; i++) {
		icon_info.rc.left = LVIR_BOUNDS;
		ZeroMemory(icon_info.item_text, sizeof(icon_info.item_text));
		if (WriteProcessMemory(process_handle, remote_addr, &icon_info, sizeof(icon_info), NULL)) {
			 ::SendMessage(list_view, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)(remote_addr + offsetof(DESKTOP_ICON_INFO, item)));
			 ::SendMessage(list_view, LVM_GETITEMRECT, (WPARAM)i, (LPARAM)(remote_addr + offsetof(DESKTOP_ICON_INFO, rc)));
			 ReadProcessMemory(process_handle, remote_addr, &icon_info, sizeof(icon_info), NULL);

			 if (_wcsicmp(icon_info.item_text, pattern) == 0) {
				 rc = icon_info.rc;
				 break;
			 }
		}
	}

	VirtualFreeEx(process_handle, remote_addr, 0, MEM_RELEASE);
	CloseHandle(process_handle);
	return TRUE;
}