Skip to content

Commit 56c0eb7

Browse files
committed
Keep index of tree node item instead of a pointer which can be invalidated due to realloc
1 parent b9f207b commit 56c0eb7

File tree

1 file changed

+24
-17
lines changed

1 file changed

+24
-17
lines changed

src/WinSpyTree.c

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ int FormatWindowText(HWND hwnd, TCHAR szTotal[], int cchTotal)
312312
// are implicitly freed by virtue of g_cTreeNodesInUse being reset back to
313313
// zero. The array slots will then be recycled as the tree is repopulated.
314314
//
315-
TREENODE *AllocateTreeNode()
315+
ptrdiff_t AllocateTreeNode()
316316
{
317317
// Grow the array if it is full.
318318

@@ -324,7 +324,7 @@ TREENODE *AllocateTreeNode()
324324

325325
if (!rgNew)
326326
{
327-
return NULL;
327+
return -1;
328328
}
329329

330330
g_TreeNodes = rgNew;
@@ -336,11 +336,9 @@ TREENODE *AllocateTreeNode()
336336

337337
TREENODE *pNode = &g_TreeNodes[g_cTreeNodesInUse];
338338

339-
g_cTreeNodesInUse++;
340-
341339
ZeroMemory(pNode, sizeof(*pNode));
342340

343-
return pNode;
341+
return g_cTreeNodesInUse++;
344342
}
345343

346344
//
@@ -373,10 +371,12 @@ WinProc *GetProcessWindowStack(HWND hwndTree, HWND hwnd)
373371
GetProcessNameByPid(pid, name, 100, path, MAX_PATH);
374372
_stprintf_s(ach, ARRAYSIZE(ach), _T("%s (%u)"), name, pid);
375373

376-
TREENODE *pNode = AllocateTreeNode();
374+
TREENODE *pNode = NULL;
375+
ptrdiff_t nodeIndex = AllocateTreeNode();
377376

378-
if (pNode)
377+
if (nodeIndex >= 0)
379378
{
379+
pNode = &g_TreeNodes[nodeIndex];
380380
pNode->dwPID = pid;
381381
}
382382
else
@@ -392,7 +392,7 @@ WinProc *GetProcessWindowStack(HWND hwndTree, HWND hwnd)
392392
tv.item.stateMask = 0;//TVIS_EXPANDED;
393393
tv.item.pszText = ach;
394394
tv.item.cchTextMax = ARRAYSIZE(ach);
395-
tv.item.lParam = (LPARAM)pNode;
395+
tv.item.lParam = (LPARAM)nodeIndex;
396396

397397
if (SHGetFileInfo(path, 0, &shfi, sizeof(shfi), SHGFI_SMALLICON | SHGFI_ICON))
398398
{
@@ -447,10 +447,12 @@ BOOL CALLBACK AllWindowProc(HWND hwnd, LPARAM lParam)
447447
static HWND hwndLast;
448448

449449
TVINSERTSTRUCT tv;
450-
TREENODE *pNode = AllocateTreeNode();
450+
TREENODE *pNode = NULL;
451+
ptrdiff_t nodeIndex = AllocateTreeNode();
451452

452-
if (pNode)
453+
if (nodeIndex >= 0)
453454
{
455+
pNode = &g_TreeNodes[nodeIndex];
454456
pNode->hwnd = hwnd;
455457
}
456458
else
@@ -475,7 +477,7 @@ BOOL CALLBACK AllWindowProc(HWND hwnd, LPARAM lParam)
475477
tv.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
476478
tv.item.pszText = szTotal;
477479
tv.item.cchTextMax = ARRAYSIZE(szTotal);
478-
tv.item.lParam = (LPARAM)pNode;
480+
tv.item.lParam = (LPARAM)nodeIndex;
479481

480482
//
481483
// set the image, depending on what type of window we have
@@ -585,10 +587,12 @@ void FillGlobalWindowTree(HWND hwndTree)
585587

586588
FormatWindowText(hwndDesktop, ach, ARRAYSIZE(ach));
587589

588-
TREENODE *pNode = AllocateTreeNode();
590+
TREENODE *pNode = NULL;
591+
ptrdiff_t nodeIndex = AllocateTreeNode();
589592

590-
if (pNode)
593+
if (nodeIndex >= 0)
591594
{
595+
pNode = &g_TreeNodes[nodeIndex];
592596
pNode->hwnd = hwndDesktop;
593597
}
594598
else
@@ -608,7 +612,7 @@ void FillGlobalWindowTree(HWND hwndTree)
608612
tv.item.cchTextMax = ARRAYSIZE(ach);
609613
tv.item.iImage = DESKTOP_IMAGE;
610614
tv.item.iSelectedImage = DESKTOP_IMAGE;
611-
tv.item.lParam = (LPARAM)pNode;
615+
tv.item.lParam = (LPARAM)nodeIndex;
612616

613617
pNode->hTreeItem = TreeView_InsertItem(hwndTree, &tv);
614618
g_hRoot = pNode->hTreeItem;
@@ -786,7 +790,8 @@ void WindowTree_OnRightClick(NMHDR *pnm)
786790

787791
TreeView_GetItem(hwndTree, &tvi);
788792

789-
TREENODE *pNode = (TREENODE *)tvi.lParam;
793+
ptrdiff_t nodeIndex = (ptrdiff_t)tvi.lParam;
794+
TREENODE *pNode = &g_TreeNodes[nodeIndex];
790795

791796
if (pNode->hwnd)
792797
{
@@ -825,7 +830,8 @@ void WindowTree_OnSelectionChanged(NMHDR *pnm)
825830
// Get TVITEM structure
826831
TreeView_GetItem(pnm->hwndFrom, &item);
827832

828-
TREENODE *pNode = (TREENODE *)item.lParam;
833+
ptrdiff_t nodeIndex = (ptrdiff_t)item.lParam;
834+
TREENODE *pNode = &g_TreeNodes[nodeIndex];
829835

830836
g_dwSelectedPID = pNode->dwPID;
831837

@@ -870,7 +876,8 @@ HWND WindowTree_GetSelectedWindow()
870876

871877
if (item.lParam)
872878
{
873-
TREENODE *pNode = (TREENODE *)item.lParam;
879+
ptrdiff_t nodeIndex = (ptrdiff_t)item.lParam;
880+
TREENODE *pNode = &g_TreeNodes[nodeIndex];
874881
hwnd = pNode->hwnd;
875882
}
876883
}

0 commit comments

Comments
 (0)