VOID PhpAnalyzeWaitPassive( _In_ HWND hWnd, _In_ HANDLE ProcessId, _In_ HANDLE ThreadId ) { NTSTATUS status; HANDLE processHandle; HANDLE threadHandle; THREAD_LAST_SYSCALL_INFORMATION lastSystemCall; PH_STRING_BUILDER stringBuilder; PPH_STRING string; PhpInitializeServiceNumbers(); if (!NT_SUCCESS(status = PhOpenThread(&threadHandle, THREAD_GET_CONTEXT, ThreadId))) { PhShowStatus(hWnd, L"Unable to open the thread.", status, 0); return; } if (!NT_SUCCESS(status = PhGetThreadLastSystemCall(threadHandle, &lastSystemCall))) { NtClose(threadHandle); PhShowStatus(hWnd, L"Unable to determine whether the thread is waiting.", status, 0); return; } if (!NT_SUCCESS(status = PhOpenProcess(&processHandle, PROCESS_DUP_HANDLE, ProcessId))) { NtClose(threadHandle); PhShowStatus(hWnd, L"Unable to open the process.", status, 0); return; } PhInitializeStringBuilder(&stringBuilder, 100); if (lastSystemCall.SystemCallNumber == NumberForWfso) { string = PhpaGetHandleString(processHandle, lastSystemCall.FirstArgument); PhAppendFormatStringBuilder(&stringBuilder, L"Thread is waiting for:\r\n"); PhAppendStringBuilder(&stringBuilder, &string->sr); } else if (lastSystemCall.SystemCallNumber == NumberForWfmo) { PhAppendFormatStringBuilder(&stringBuilder, L"Thread is waiting for multiple (%lu) objects.", PtrToUlong(lastSystemCall.FirstArgument)); } else if (lastSystemCall.SystemCallNumber == NumberForRf) { string = PhpaGetHandleString(processHandle, lastSystemCall.FirstArgument); PhAppendFormatStringBuilder(&stringBuilder, L"Thread is waiting for file I/O:\r\n"); PhAppendStringBuilder(&stringBuilder, &string->sr); } else { string = PhpaGetSendMessageReceiver(ThreadId); if (string) { PhAppendStringBuilder2(&stringBuilder, L"Thread is sending a USER message:\r\n"); PhAppendStringBuilder(&stringBuilder, &string->sr); } else { string = PhpaGetAlpcInformation(ThreadId); if (string) { PhAppendStringBuilder2(&stringBuilder, L"Thread is waiting for an ALPC port:\r\n"); PhAppendStringBuilder(&stringBuilder, &string->sr); } } } if (stringBuilder.String->Length == 0) PhAppendStringBuilder2(&stringBuilder, L"Unable to determine why the thread is waiting."); PhShowInformationDialog(hWnd, stringBuilder.String->Buffer, 0); PhDeleteStringBuilder(&stringBuilder); NtClose(processHandle); NtClose(threadHandle); }
static INT_PTR CALLBACK PhpAboutDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { PPH_STRING appName; #if (PHAPP_VERSION_REVISION != 0) appName = PhFormatString( L"Process Hacker %u.%u.%u", PHAPP_VERSION_MAJOR, PHAPP_VERSION_MINOR, PHAPP_VERSION_REVISION ); #else appName = PhFormatString( L"Process Hacker %u.%u", PHAPP_VERSION_MAJOR, PHAPP_VERSION_MINOR ); #endif SetDlgItemText(hwndDlg, IDC_ABOUT_NAME, appName->Buffer); PhDereferenceObject(appName); SetDlgItemText(hwndDlg, IDC_CREDITS, L" Installer by XhmikosR\n" L"Thanks to:\n" L" dmex\n" L" Donors - thank you for your support!\n" L" <a href=\"http://forum.sysinternals.com\">Sysinternals Forums</a>\n" L" <a href=\"http://www.reactos.org\">ReactOS</a>\n" L"Process Hacker uses the following components:\n" L" <a href=\"http://www.minixml.org\">Mini-XML</a> by Michael Sweet\n" L" <a href=\"http://www.pcre.org\">PCRE</a>\n" L" MD5 code by Jouni Malinen\n" L" SHA1 code by Filip Navara, based on code by Steve Reid\n" L" <a href=\"http://www.famfamfam.com/lab/icons/silk\">Silk icons</a>\n" ); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: EndDialog(hwndDlg, IDOK); break; case IDC_DIAGNOSTICS: { PhShowInformationDialog(hwndDlg, PH_AUTO_T(PH_STRING, PhGetDiagnosticsString())->Buffer); } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case NM_CLICK: { switch (header->idFrom) { case IDC_CREDITS: case IDC_LINK_SF: PhShellExecute(hwndDlg, ((PNMLINK)header)->item.szUrl, NULL); break; } } break; } } break; } return FALSE; }
VOID PhUiAnalyzeWaitThread( _In_ HWND hWnd, _In_ HANDLE ProcessId, _In_ HANDLE ThreadId, _In_ PPH_SYMBOL_PROVIDER SymbolProvider ) { NTSTATUS status; HANDLE threadHandle; #ifdef _WIN64 HANDLE processHandle; BOOLEAN isWow64; #endif CLIENT_ID clientId; ANALYZE_WAIT_CONTEXT context; #ifdef _WIN64 // Determine if the process is WOW64. If not, we use the passive method. if (!NT_SUCCESS(status = PhOpenProcess(&processHandle, PROCESS_QUERY_LIMITED_INFORMATION, ProcessId))) { PhShowStatus(hWnd, L"Unable to open the process", status, 0); return; } if (!NT_SUCCESS(status = PhGetProcessIsWow64(processHandle, &isWow64)) || !isWow64) { PhpAnalyzeWaitPassive(hWnd, ProcessId, ThreadId); return; } NtClose(processHandle); #endif if (!NT_SUCCESS(status = PhOpenThread( &threadHandle, THREAD_QUERY_LIMITED_INFORMATION | THREAD_GET_CONTEXT | THREAD_SUSPEND_RESUME, ThreadId ))) { PhShowStatus(hWnd, L"Unable to open the thread.", status, 0); return; } memset(&context, 0, sizeof(ANALYZE_WAIT_CONTEXT)); context.ProcessId = ProcessId; context.ThreadId = ThreadId; context.ProcessHandle = SymbolProvider->ProcessHandle; context.SymbolProvider = SymbolProvider; PhInitializeStringBuilder(&context.StringBuilder, 100); clientId.UniqueProcess = ProcessId; clientId.UniqueThread = ThreadId; PhWalkThreadStack( threadHandle, SymbolProvider->ProcessHandle, &clientId, SymbolProvider, PH_WALK_I386_STACK, PhpWalkThreadStackAnalyzeCallback, &context ); NtClose(threadHandle); PhpAnalyzeWaitFallbacks(&context); if (context.Found) { PhShowInformationDialog(hWnd, context.StringBuilder.String->Buffer, 0); } else { PhShowInformation2(hWnd, L"The thread does not appear to be waiting.", L""); } PhDeleteStringBuilder(&context.StringBuilder); }