Calling TreeView_GetItem Crashes RegEdit

Hello,

With the below code, I am just trying to get the item info of the currently selected tree node that is in RegEdit:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//find's the handle to the RegEdit window
HWND regEdit = FindRegEdit();

if (regEdit != NULL) {
	//finds the handle to the tree view in the RegEdit window
	HWND treeView = FindTreeView(regEdit);

	if (treeView != NULL) {
		HTREEITEM item = TreeView_GetSelection(treeView);

		if (item != NULL) {
			TVITEMEX info;
			info.mask = TVIF_PARAM;
			info.hItem = item;

			//crashes RegEdit.exe and tries to send error report
			BOOL result = TreeView_GetItem(treeView, &info);
		}
	}
}

However it crashes RegEdit, can anyone guide me on what I am doing wrong?
Last edited on
Didn't I answer this question in the MSDN Forums? You need to allocate memory in the RegEdit process using VirtualAllocEx() and then read the memory using ReadProcessMemory().
Wow, I missed the reply from the MSDN forum. Sorry about that, I didn't actually know someone replied.

I switched over to C++ because I thought I might be more successful with direct access to the macros instead of a bunch of p/invokes. Thank you for the reply on both. I will look into what you have said, and will probably post back to this thread instead of the other one. I will mark your reply in the MSDN forum as the answer.
I know I'm missing something here. I'm not sure how I would instruct the TreeView to write the TVITEM values into this newly allocated memory. This is what I have so far:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// get the regedit process handle
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, entry.th32ProcessID);

if (hProcess != NULL) {

	LPVOID address = VirtualAllocEx(hProcess, NULL, sizeof(TVITEM), 
				        MEM_COMMIT, PAGE_EXECUTE_READWRITE);

	// i must have to do something here... so that the process knows to write
	// into this new memory. but how do i do that?

	ReadProcessMemory(hProcess, address, NULL, sizeof(TVITEM), NULL);
	CloseHandle(hProcess);
}
Last edited on
Well, this is where I've gotten. It doesn't crash regedit, but TreeView_GetItem returns false. It looks like the process memory is written/read properly. There are no errors:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, entry.th32ProcessID);

if (hProcess != NULL) {

	LPVOID address = VirtualAllocEx(hProcess, NULL, sizeof(TVITEM), 
				        MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	TVITEM pitem;
	pitem.mask = TVIF_STATE | TVIF_PARAM;
	pitem.hItem = item;

	int latestError = 0;
	
	if(!WriteProcessMemory(hProcess, address, &pitem, sizeof(pitem), NULL))
		latestError = GetLastError();

	if(!TreeView_GetItem(treeView, (TVITEM *)address))
		latestError = GetLastError();

	if(!ReadProcessMemory(hProcess, address, &pitem, sizeof(pitem), NULL))
		latestError = GetLastError();

	VirtualFreeEx(hProcess, address, NULL, MEM_RELEASE);
	CloseHandle(hProcess);
}


Am I going about this wrong?
It seems to me that you need to study the members of the TVITEM struct more carefully. I am no expert, but by glancing the documentation I can see that you are asking for TVIF_PARAM, which seems to be a user-defined value. Do you even know for sure that items in the RegEdit TreeView contain that user-defined value? And you are asking for it. Can you interpret it? Do you know what it is? If yes, then OK, don't mind my rambling about it.

But then you also set hItem and don't specify in the mask that you are passing it. I know, the documentation says that if it is used with GetItem, the mask means it is what you are asking for, but I have a hunch: I think you also need to add TVIF_HANDLE to the mask so the TreeView knows the hItem value is valid, which I presume is the item identifier.

Study http://msdn.microsoft.com/en-us/library/windows/desktop/bb773456(v=vs.85).aspx a bit. I think your answer is there.

Also note that the pszText item is a pointer to a buffer (on GetItem) that you must provide. This means another call to VirtualAllocEx().
Thanks for the reply.

I've had a chance to look back at this (holidays and all...) and I think you are right about your hunch. However, when changing the mask to this:

pitem.mask = TVIF_STATE | TVIF_HANDLE;

It still does the same thing: TreeView_GetItem returns false. I'm really at a loss here. I've studied the TVITEM documentation and TreeView_GetItem documentation and can't seem to find what I'm doing wrong.
Suggestion: Learn the quirks of the treeview in a sample project. Once you know how it works, try to get it to work in an external process. You can even start trying to read the treeview of an external process of your own! That way you may have some more control over the environment.

Hopefully you'll gather enough data to make this work with regedit.exe eventually.

Sorry I'm not more helpful; I just haven't done this before.
Topic archived. No new replies allowed.