INT_PTR CALLBACK HandleCrashDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) /*++ Routine Description: Dialog box used to ask user what action he wants to take when an application crashes. Arguments: Refer to DialogProc in MSDN Returns: TRUE - Message Handled FALSE - Message not handled --*/ { static PROC_DBG_DATA sProcDbgData; switch(msg) { case WM_INITDIALOG: { // // Insert *specific* dialog initialization code here. // lParam can contain information required for initialization. // // // Set dialog and application Icon // HICON hIcon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_APP_ICON_SM)); SendMessage (hDlg, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIcon); hIcon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_APP_ICON)); SendMessage (hDlg, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hIcon); SetWindowText(hDlg, _T("IntellectualHeaven(R) CrashDoctor")); // // Set list control properties // HWND hListCtrl; hListCtrl = GetDlgItem(hDlg, IDC_LIST_DEBUGGER); ListView_SetExtendedListViewStyle( hListCtrl, LVS_EX_FULLROWSELECT); ListView_SetTextColor( hListCtrl, RGB(0, 0, 255)); LVCOLUMN lvColumn; lvColumn.mask = LVCF_TEXT | LVCF_WIDTH; lvColumn.cx = 260; lvColumn.pszText = _T(" Debuggers Available"); ListView_InsertColumn( hListCtrl, 0, &lvColumn); CenterDialog(hDlg); PPROC_DBG_DATA procDbgData = (PPROC_DBG_DATA)lParam; // // Store the PROC_DBG_DATA, it will be needed later // sProcDbgData = *procDbgData; // Find the process given in PROC_DBG_DATA DWORD processId = sProcDbgData.processId; IHU_PROCESS_INFO processInfo; IHU_PROCESS_LIST processList; IHU_PROCESS_LIST_ITER processListIter; bool processFound = false; IhuGetProcessList(processList); for ( processListIter = processList.begin(); processListIter != processList.end(); ++processListIter) { processInfo = *processListIter; if (processId == processInfo.mProcessId) { processFound = true; break; } } // // Set process name and image // if (processFound) { SetWindowText( GetDlgItem(hDlg, IDC_EDIT_PROCESS_NAME), processInfo.mBinaryName.c_str()); hIcon = NULL; IhuGetFileIcon( processInfo.mBinaryName, hIcon); if (hIcon) { SendMessage( GetDlgItem(hDlg, IDC_ICON_PROCESS), STM_SETICON, (WPARAM)hIcon, 0); } } else { SetWindowText( GetDlgItem(hDlg, IDC_EDIT_PROCESS_NAME), _T("<Unknown Process>")); // // To-Do!!! // This should *NEVER* happen. How to handle this? // } // // Add debugger list to the list ctrl // AddDebuggersToListCtrl( hListCtrl); return TRUE; } case WM_COMMAND: { switch(wParam) { case IDC_BTN_RECOVER: { EndDialog(hDlg, IDC_BTN_RECOVER); return TRUE; } case IDC_BTN_TERMINATE: { EndDialog(hDlg, IDC_BTN_TERMINATE); return TRUE; } case IDC_BTN_DEBUG: { HWND hListCtrl = GetDlgItem(hDlg, IDC_LIST_DEBUGGER); int nSelectedItem = ListView_GetSelectionMark(hListCtrl); if (nSelectedItem >= 0) { TCHAR debugCmdFormat[MAX_PATH] = {0}; LVITEM lvItem = {0}; lvItem.mask = LVIF_TEXT; lvItem.iItem = nSelectedItem; lvItem.iSubItem = 0; lvItem.pszText = debugCmdFormat; lvItem.cchTextMax = MAX_PATH; if (ListView_GetItem(hListCtrl, &lvItem)) { if (_tcslen(debugCmdFormat) > 0) { TCHAR launchDebuggerCmd[MAX_PATH * 2] = {0}; _stprintf( launchDebuggerCmd, debugCmdFormat, sProcDbgData.processId, sProcDbgData.eventHandle); STARTUPINFO startupInfo; PROCESS_INFORMATION procInfo; ZeroMemory(&startupInfo, sizeof(startupInfo)); startupInfo.cb = sizeof(startupInfo); ZeroMemory(&procInfo, sizeof(procInfo)); BOOL bResult = CreateProcess( NULL, launchDebuggerCmd, NULL, NULL, TRUE, 0, NULL, NULL, &startupInfo, &procInfo); if (!bResult) { cdHandleError( hDlg, GetLastError(), _T("Unable to launch debugger.")); } else { ShowWindow(hDlg, SW_HIDE); if (sProcDbgData.eventHandle) { // // wait till either the actual debugger dies or it sets the event // This wait is necessary because if we exit before the debugger // got attached to the target. The target dies because it thinks // we are the debugger. // HANDLE waitHandle[2]; waitHandle[0] = sProcDbgData.eventHandle; waitHandle[1] = procInfo.hProcess; WaitForMultipleObjects(2, (const HANDLE *)&waitHandle, FALSE, INFINITE); } else { // // wait till either the actual debugger dies or 10 seconds are over // This wait is necessary because if we exit before the debugger // got attached to the target. The target dies because it thinks // we are the debugger. // WaitForSingleObject(procInfo.hProcess, 10000); } EndDialog(hDlg, IDC_BTN_DEBUG); return FALSE; } } } } break; } case IDC_BTN_ADD_DEBUGGER: { TCHAR tempFileName[MAX_PATH]; tempFileName[0] = 0; OPENFILENAME ofn = {0}; ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; ofn.hwndOwner = hDlg; ofn.hInstance = ghInstance; ofn.lpstrFilter = _T("Executable (*.exe)\0*.exe\0\0"); ofn.lpstrFile = tempFileName; ofn.nMaxFile = MAX_PATH; ofn.lpstrTitle = _T("Select a debugger"); ofn.Flags = OFN_HIDEREADONLY | OFN_LONGNAMES | OFN_PATHMUSTEXIST; if (GetOpenFileName(&ofn)) { DEBUGGER_INFO debuggerInfo; debuggerInfo.debuggerPath = ofn.lpstrFile; debuggerInfo.cmdLine = _T("-p %ld -e %ld"); DialogBoxParam( ghInstance, MAKEINTRESOURCE(IDD_DIALOG_ADD_DEBUGGER), hDlg, (DLGPROC)DebuggerDataDlgProc, (LPARAM)&debuggerInfo); tstring debuggerCmd = _T("\"") + debuggerInfo.debuggerPath + _T("\" ") + debuggerInfo.cmdLine; AddDebuggerToRegistry(hDlg, debuggerCmd); AddDebuggersToListCtrl(GetDlgItem(hDlg, IDC_LIST_DEBUGGER)); } break; } case IDC_BTN_MODIFY_DEBUGGER: { HWND hListCtrl = GetDlgItem(hDlg, IDC_LIST_DEBUGGER); int nSelectedItem = ListView_GetSelectionMark(hListCtrl); if (nSelectedItem >= 0) { TCHAR debugCmdLine[MAX_PATH] = {0}; LVITEM lvItem = {0}; lvItem.mask = LVIF_TEXT | LVIF_PARAM; lvItem.iItem = nSelectedItem; lvItem.iSubItem = 0; lvItem.pszText = debugCmdLine; lvItem.cchTextMax = MAX_PATH; if (ListView_GetItem(hListCtrl, &lvItem)) { LPARAM regIndex = lvItem.lParam; if (_tcslen(debugCmdLine) > 0) { DEBUGGER_INFO debuggerInfo; debuggerInfo.cmdLine = debugCmdLine; DialogBoxParam( ghInstance, MAKEINTRESOURCE(IDD_DIALOG_MODIFY_DEBUGGER), hDlg, (DLGPROC)DebuggerDataDlgProc, (LPARAM)&debuggerInfo); if (_tcscmp(debugCmdLine, debuggerInfo.cmdLine.c_str()) != 0) { // // Modify the particular registry entry // TCHAR valueName[32]; _stprintf(valueName, _T("Debugger%02d"), regIndex); int nReturnValue = 0; HKEY hAppDebuggerKey = NULL; nReturnValue = RegOpenKey( HKEY_LOCAL_MACHINE, REG_APP_ROOT REG_APP_DEBUGGERS, &hAppDebuggerKey); if (hAppDebuggerKey) { if (RegSetValueEx( hAppDebuggerKey, valueName, 0, REG_SZ, (LPBYTE)debuggerInfo.cmdLine.c_str(), (DWORD)(debuggerInfo.cmdLine.length() * sizeof(TCHAR))) != ERROR_SUCCESS) { cdHandleError( hDlg, GetLastError(), _T("Modify Debugger Failed. Unable to update the registry key.")); } RegCloseKey(hAppDebuggerKey); AddDebuggersToListCtrl(GetDlgItem(hDlg, IDC_LIST_DEBUGGER)); } else { cdHandleError( hDlg, GetLastError(), _T("Modify Debugger Failed. Unable to open required registry key.")); } } } } } break; } case IDC_BTN_DELETE_DEBUGGER: { HWND hListCtrl = GetDlgItem(hDlg, IDC_LIST_DEBUGGER); int nSelectedItem = ListView_GetSelectionMark(hListCtrl); if (nSelectedItem >= 0) { TCHAR debugCmdLine[MAX_PATH] = {0}; LVITEM lvItem = {0}; lvItem.mask = LVIF_TEXT | LVIF_PARAM; lvItem.iItem = nSelectedItem; lvItem.iSubItem = 0; lvItem.pszText = debugCmdLine; lvItem.cchTextMax = MAX_PATH; if (ListView_GetItem(hListCtrl, &lvItem)) { LPARAM regIndex = lvItem.lParam; // // Modify the particular registry entry // TCHAR valueName[32]; _stprintf(valueName, _T("Debugger%02d"), regIndex); int nReturnValue = 0; HKEY hAppDebuggerKey = NULL; nReturnValue = RegOpenKey( HKEY_LOCAL_MACHINE, REG_APP_ROOT REG_APP_DEBUGGERS, &hAppDebuggerKey); if (hAppDebuggerKey) { if (RegDeleteValue( hAppDebuggerKey, valueName) != ERROR_SUCCESS) { cdHandleError( hDlg, GetLastError(), _T("Delete Debugger Failed. Unable to delete the registry key.")); } RegCloseKey(hAppDebuggerKey); AddDebuggersToListCtrl(GetDlgItem(hDlg, IDC_LIST_DEBUGGER)); } else { cdHandleError( hDlg, GetLastError(), _T("Delete Debugger Failed. Unable to open required registry key.")); } } } break; } // // Don't allow closing from the title bar button. // /* case IDCANCEL: { EndDialog(hDlg, IDCANCEL); return TRUE; } */ } break; } case WM_CTLCOLORSTATIC: { HDC hdc = (HDC)wParam; HWND hwndCtl = (HWND)lParam; if (hwndCtl == GetDlgItem(hDlg, IDC_EDIT_PROCESS_NAME)) { if (SetTextColor(hdc, RGB(255, 0, 0)) == CLR_INVALID) { cdHandleError(hDlg, GetLastError(), _T("Failed to set control color")); break; } SetBkMode(hdc, TRANSPARENT); SetBkColor(hdc, GetSysColor(COLOR_WINDOW)); SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW)); return TRUE; } break; } case WM_DESTROY: { return TRUE; } case WM_CLOSE: { break; } } // // Not handled by us // return FALSE; }
bool stFillProcessInformation( HWND inListViewHwnd) { ListView_DeleteAllItems(inListViewHwnd); bool funcResult = false; IHU_PROCESS_LIST processList; IHU_PROCESS_LIST_ITER processListIter; IHU_PROCESS_INFO processInfo; if (IhuGetProcessList(processList) < 0) { funcResult = false; goto funcExit; } if (g_hProcessILSmall) { ImageList_Destroy(g_hProcessILSmall); } g_hProcessILSmall = ImageList_Create(16, 16, ILC_COLOR24 | ILC_MASK, 4, 1); if (g_hProcessILSmall) { ListView_SetImageList(inListViewHwnd, g_hProcessILSmall, LVSIL_SMALL); } for ( processListIter = processList.begin(); processListIter != processList.end(); processListIter++) { processInfo = *processListIter; LVITEM lvItem; ZeroMemory(&lvItem, sizeof(LVITEM)); lvItem.mask = LVIF_TEXT; lvItem.iItem = 0; lvItem.iSubItem = 0; lvItem.pszText = (LPWSTR)processInfo.mProcessName.c_str(); if (g_hProcessILSmall) { int iIndex = 0; HICON hIcon; IhuGetFileIcon(processInfo.mBinaryName.c_str(), hIcon); iIndex = ImageList_AddIcon(g_hProcessILSmall, hIcon); DestroyIcon(hIcon); lvItem.mask = LVIF_TEXT | LVIF_IMAGE; lvItem.iImage = iIndex; } int itemIndex = SendMessage(inListViewHwnd, LVM_INSERTITEM, 0, (LPARAM)&lvItem); ListView_SetColumnWidth(inListViewHwnd, 0, LVSCW_AUTOSIZE); wchar_t szPid[32] = {0}; StringCchPrintf(szPid, CHARCOUNT(szPid), L"%d", processInfo.mProcessId); lvItem.iItem = itemIndex; lvItem.iSubItem = 1; lvItem.pszText = szPid; SendMessage(inListViewHwnd, LVM_SETITEM, 0, (LPARAM)&lvItem); ListView_SetColumnWidth(inListViewHwnd, 1, LVSCW_AUTOSIZE); lvItem.iItem = itemIndex; lvItem.iSubItem = 2; lvItem.pszText = (LPWSTR)processInfo.mBinaryName.c_str(); SendMessage(inListViewHwnd, LVM_SETITEM, 0, (LPARAM)&lvItem); ListView_SetColumnWidth(inListViewHwnd, 2, LVSCW_AUTOSIZE); } funcExit: return funcResult; }