29 #define WM_PH_COMPLETED (WM_APP + 301)
30 #define WM_PH_STATUS_UPDATE (WM_APP + 302)
32 typedef struct _THREAD_STACK_CONTEXT
45 HWND ProgressWindowHandle;
51 typedef struct _THREAD_STACK_ITEM
81 static RECT MinimumSize = { -1, -1, -1, -1 };
84 _In_ HWND ParentWindowHandle,
92 HANDLE threadHandle = NULL;
103 threadStackContext.ProcessId =
ProcessId;
104 threadStackContext.ThreadId = ThreadId;
105 threadStackContext.ThreadProvider = ThreadProvider;
106 threadStackContext.SymbolProvider = ThreadProvider->SymbolProvider;
126 PhShowStatus(ParentWindowHandle, L
"Unable to open the thread", status, 0);
130 threadStackContext.ThreadHandle = threadHandle;
140 (LPARAM)&threadStackContext
147 if (threadStackContext.ThreadHandle)
148 NtClose(threadStackContext.ThreadHandle);
171 title =
PhFormatString(L
"Stack - thread %u", (ULONG)threadStackContext->ThreadId);
172 SetWindowText(hwndDlg, title->
Buffer);
175 lvHandle = GetDlgItem(hwndDlg,
IDC_LIST);
182 threadStackContext->ListViewHandle = lvHandle;
186 SetProp(hwndDlg, L
"LayoutManager", (HANDLE)layoutManager);
197 if (MinimumSize.left == -1)
205 MapDialogRect(hwndDlg, &rect);
207 MinimumSize.left = 0;
219 control.
u.
Initializing.ProcessId = threadStackContext->ProcessId;
220 control.
u.
Initializing.ThreadId = threadStackContext->ThreadId;
221 control.
u.
Initializing.ThreadHandle = threadStackContext->ThreadHandle;
222 control.
u.
Initializing.SymbolProvider = threadStackContext->SymbolProvider;
226 threadStackContext->CustomWalk = control.
u.
Initializing.CustomWalk;
231 if (status == STATUS_ABANDONED)
232 EndDialog(hwndDlg, IDCANCEL);
234 PhShowStatus(hwndDlg, L
"Unable to load the stack", status, 0);
258 for (i = 0; i < threadStackContext->List->Count; i++)
265 RemoveProp(hwndDlg, L
"LayoutManager");
270 INT
id = LOWORD(wParam);
276 EndDialog(hwndDlg, IDOK);
287 PhShowStatus(hwndDlg, L
"Unable to load the stack", status, 0);
295 lvHandle = GetDlgItem(hwndDlg,
IDC_LIST);
297 if (ListView_GetSelectedCount(lvHandle) == 0)
301 SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)lvHandle,
TRUE);
309 LPNMHDR header = (LPNMHDR)lParam;
311 switch (header->code)
315 LPNMLVGETINFOTIP getInfoTip = (LPNMLVGETINFOTIP)header;
319 lvHandle = GetDlgItem(hwndDlg,
IDC_LIST);
322 if (header->hwndFrom == lvHandle)
333 stackFrame = &stackItem->StackFrame;
338 L
"Stack: 0x%Ix, Frame: 0x%Ix\n",
348 L
"Parameters: 0x%Ix, 0x%Ix, 0x%Ix, 0x%Ix\n",
357 threadStackContext->SymbolProvider,
366 L
"File: %s: line %u\n",
383 control.
u.
GetTooltip.StringBuilder = &stringBuilder;
429 ThreadStackContext->StopWalk =
FALSE;
437 (LPARAM)ThreadStackContext
440 if (!ThreadStackContext->StopWalk &&
NT_SUCCESS(ThreadStackContext->WalkStatus))
442 for (i = 0; i < ThreadStackContext->List->Count; i++)
446 ThreadStackContext->List = ThreadStackContext->NewList;
449 ListView_DeleteAllItems(ThreadStackContext->ListViewHandle);
450 SendMessage(ThreadStackContext->ListViewHandle, WM_SETREDRAW,
FALSE, 0);
452 for (i = 0; i < ThreadStackContext->List->Count; i++)
459 lvItemIndex =
PhAddListViewItem(ThreadStackContext->ListViewHandle, MAXINT, integerString, item);
463 SendMessage(ThreadStackContext->ListViewHandle, WM_SETREDRAW,
TRUE, 0);
464 InvalidateRect(ThreadStackContext->ListViewHandle, NULL,
FALSE);
468 for (i = 0; i < ThreadStackContext->NewList->Count; i++)
474 if (ThreadStackContext->StopWalk)
475 return STATUS_ABANDONED;
477 return ThreadStackContext->WalkStatus;
480 static BOOLEAN NTAPI PhpWalkThreadStackCallback(
482 _In_opt_ PVOID Context
489 if (threadStackContext->StopWalk)
494 PhFormatString(L
"Processing frame %u...", threadStackContext->NewList->Count));
499 threadStackContext->SymbolProvider,
500 (ULONG64)StackFrame->PcAddress,
515 item->StackFrame = *StackFrame;
516 item->Index = threadStackContext->NewList->Count;
531 item->Symbol = symbol;
537 static NTSTATUS PhpRefreshThreadStackThreadStart(
552 if (threadStackContext->CustomWalk)
558 control.
u.
WalkStack.Status = STATUS_UNSUCCESSFUL;
559 control.
u.
WalkStack.ThreadHandle = threadStackContext->ThreadHandle;
560 control.
u.
WalkStack.ProcessHandle = threadStackContext->SymbolProvider->ProcessHandle;
563 control.
u.
WalkStack.Callback = PhpWalkThreadStackCallback;
564 control.
u.
WalkStack.CallbackContext = threadStackContext;
585 threadStackContext->ThreadHandle,
586 threadStackContext->SymbolProvider->ProcessHandle,
588 threadStackContext->SymbolProvider,
590 PhpWalkThreadStackCallback,
601 if (threadStackContext->NewList->Count != 0)
602 status = STATUS_SUCCESS;
604 threadStackContext->WalkStatus = status;
605 PostMessage(threadStackContext->ProgressWindowHandle,
WM_PH_COMPLETED, 0, 0);
607 return STATUS_SUCCESS;
626 threadStackContext->ProgressWindowHandle = hwndDlg;
628 if (threadHandle =
PhCreateThread(0, PhpRefreshThreadStackThreadStart, threadStackContext))
630 NtClose(threadHandle);
634 threadStackContext->WalkStatus = STATUS_UNSUCCESSFUL;
635 EndDialog(hwndDlg, IDOK);
643 SetWindowText(hwndDlg, L
"Loading stack...");
653 switch (LOWORD(wParam))
659 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL),
FALSE);
660 threadStackContext->StopWalk =
TRUE;
668 EndDialog(hwndDlg, IDOK);
677 message = threadStackContext->StatusMessage;