add plugins-extra

This commit is contained in:
AirDog46
2025-05-13 19:49:49 +03:00
parent c5fab8aa94
commit 3575d86c17
531 changed files with 70258 additions and 1 deletions

View File

@@ -0,0 +1,2 @@
1.0
* Initial release

View File

@@ -0,0 +1,141 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (Australia) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
#pragma code_page(1252)
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "0c0904b0"
BEGIN
VALUE "CompanyName", "dmex"
VALUE "FileDescription", "DbgView plugin for Process Hacker"
VALUE "FileVersion", "1.0"
VALUE "InternalName", "dmex.DbgView"
VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
VALUE "OriginalFilename", "DbgViewPlugin.dll"
VALUE "ProductName", "DbgView plugin for Process Hacker"
VALUE "ProductVersion", "1.0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0xc09, 1200
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DBGVIEW_DIALOG DIALOGEX 0, 0, 343, 181
STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
CAPTION "Debug View"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "Close",IDCLOSE,286,160,50,14
CONTROL "",IDC_DEBUGLISTVIEW,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,5,329,152
PUSHBUTTON "Options",IDC_OPTIONS,7,160,50,14
CONTROL "Auto-scroll",IDC_AUTOSCROLL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,61,164,50,10
CONTROL "Always on Top",IDC_ALWAYSONTOP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,219,164,63,10
END
IDD_MESSAGE_DIALOG DIALOGEX 0, 0, 309, 176
STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "Message"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Close",IDCLOSE,252,155,50,14
EDITTEXT IDC_MESSAGE,7,7,295,145,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL,WS_EX_CLIENTEDGE
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_DBGVIEW_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 336
TOPMARGIN, 5
BOTTOMMARGIN, 174
END
IDD_MESSAGE_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 302
TOPMARGIN, 7
BOTTOMMARGIN, 169
END
END
#endif // APSTUDIO_INVOKED
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\0"
END
3 TEXTINCLUDE
BEGIN
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (Australia) resources
/////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{AAD42A11-92A7-4918-A76A-862528185199}</ProjectGuid>
<RootNamespace>DbgViewPlugin</RootNamespace>
<Keyword>Win32Proj</Keyword>
<ProjectName>DbgViewPlugin</ProjectName>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\ExtraPlugins.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\ExtraPlugins.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\ExtraPlugins.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\ExtraPlugins.props" />
</ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug32</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release64</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release32</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<TreatWarningAsError>false</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<TreatWarningAsError>false</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<TreatWarningAsError>false</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<TreatWarningAsError>false</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="filter.c" />
<ClCompile Include="log.c" />
<ClCompile Include="main.c" />
<ClCompile Include="dialog.c" />
<ClCompile Include="message.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="main.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="DbgViewPlugin.rc" />
</ItemGroup>
<ItemGroup>
<None Include="CHANGELOG.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<None Include="CHANGELOG.txt" />
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{f52999d5-d374-492f-b42c-0baf337ae22b}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{b028ae70-b630-49a5-95b3-d9196126eb9a}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{d760553d-e87a-480a-9cbd-4e69599125b8}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="main.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="log.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="filter.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dialog.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="message.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="DbgViewPlugin.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,694 @@
/*
* Process Hacker Extra Plugins -
* Debug View Plugin
*
* Copyright (C) 2015 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
static HANDLE DbgDialogThreadHandle = NULL;
static HWND DbgDialogHandle = NULL;
static PH_EVENT InitializedEvent = PH_EVENT_INIT;
VOID NTAPI DbgLoggedEventCallback(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
)
{
PPH_DBGEVENTS_CONTEXT context = (PPH_DBGEVENTS_CONTEXT)Context;
if (context->DialogHandle)
{
PostMessage(context->DialogHandle, WM_DEBUG_LOG_UPDATED, 0, 0);
}
}
VOID DbgUpdateLogList(
_Inout_ PPH_DBGEVENTS_CONTEXT Context
)
{
Context->ListViewCount = Context->LogMessageList->Count;
ListView_SetItemCountEx(Context->ListViewHandle, Context->ListViewCount, LVSICF_NOSCROLL);
if (Context->ListViewCount >= 2 && Button_GetCheck(Context->AutoScrollHandle) == BST_CHECKED)
{
if (ListView_IsItemVisible(Context->ListViewHandle, Context->ListViewCount - 2))
{
ListView_EnsureVisible(Context->ListViewHandle, Context->ListViewCount - 1, FALSE);
}
}
}
PPH_STRING DbgGetStringForSelectedLogEntries(
_Inout_ PPH_DBGEVENTS_CONTEXT Context,
_In_ BOOLEAN All
)
{
PH_STRING_BUILDER stringBuilder;
ULONG i;
if (Context->ListViewCount == 0)
return PhReferenceEmptyString();
PhInitializeStringBuilder(&stringBuilder, 0x100);
i = Context->ListViewCount - 1;
while (TRUE)
{
PDEBUG_LOG_ENTRY entry;
SYSTEMTIME systemTime;
PPH_STRING temp;
if (!All)
{
if (!(ListView_GetItemState(Context->ListViewHandle, i, LVIS_SELECTED) & LVIS_SELECTED))
{
goto ContinueLoop;
}
}
entry = Context->LogMessageList->Items[i];
if (!entry)
goto ContinueLoop;
PhLargeIntegerToLocalSystemTime(&systemTime, &entry->Time);
temp = PhFormatDateTime(&systemTime);
PhAppendStringBuilder(&stringBuilder, &temp->sr);
PhDereferenceObject(temp);
PhAppendStringBuilder2(&stringBuilder, L": ");
temp = PhFormatString(
L"%s (%lu): %s",
entry->ProcessName->Buffer, // entry->FilePath->Buffer;
HandleToUlong(entry->ProcessId),
entry->Message->Buffer
);
PhAppendStringBuilder(&stringBuilder, &temp->sr);
PhDereferenceObject(temp);
PhAppendStringBuilder2(&stringBuilder, L"\r\n");
ContinueLoop:
if (i == 0)
break;
i--;
}
return PhFinalStringBuilderString(&stringBuilder);
}
VOID ShowListViewMenu(
_Inout_ PPH_DBGEVENTS_CONTEXT Context
)
{
INT index;
PDEBUG_LOG_ENTRY entry;
index = PhFindListViewItemByFlags(Context->ListViewHandle, -1, LVNI_SELECTED);
if (index == -1)
return;
entry = Context->LogMessageList->Items[index];
if (entry)
{
POINT cursorPos;
PPH_EMENU menu;
PPH_EMENU_ITEM selectedItem;
GetCursorPos(&cursorPos);
menu = PhCreateEMenu();
PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 1, L"View Message", NULL, NULL), -1);
PhInsertEMenuItem(menu, PhCreateEMenuItem(PH_EMENU_SEPARATOR, 0, NULL, NULL, NULL), -1);
PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 2, L"Go to Owning &Process", NULL, NULL), -1);
PhInsertEMenuItem(menu, PhCreateEMenuItem(PH_EMENU_SEPARATOR, 0, NULL, NULL, NULL), -1);
PhInsertEMenuItem(menu, selectedItem = PhCreateEMenuItem(0, 0, L"E&xclude Process", NULL, NULL), -1);
PhInsertEMenuItem(selectedItem, PhCreateEMenuItem(0, 3, L"By PID", NULL, NULL), -1);
PhInsertEMenuItem(selectedItem, PhCreateEMenuItem(0, 4, L"By Name", NULL, NULL), -1);
PhInsertEMenuItem(menu, PhCreateEMenuItem(PH_EMENU_SEPARATOR, 0, NULL, NULL, NULL), -1);
PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 5, L"&Copy", NULL, NULL), -1);
selectedItem = PhShowEMenu(
menu,
Context->ListViewHandle,
PH_EMENU_SHOW_LEFTRIGHT,
PH_ALIGN_LEFT | PH_ALIGN_TOP,
cursorPos.x,
cursorPos.y
);
if (selectedItem && selectedItem->Id != -1)
{
switch (selectedItem->Id)
{
case 1:
{
DialogBoxParam(
PluginInstance->DllBase,
MAKEINTRESOURCE(IDD_MESSAGE_DIALOG),
Context->DialogHandle,
DbgPropDlgProc,
(LPARAM)entry
);
}
break;
case 2:
{
PPH_PROCESS_NODE processNode;
if (processNode = PhFindProcessNode(entry->ProcessId))
{
ProcessHacker_ToggleVisible(PhMainWndHandle, TRUE);
ProcessHacker_SelectTabPage(PhMainWndHandle, 0);
ProcessHacker_SelectProcessNode(PhMainWndHandle, processNode);
}
}
break;
case 3:
{
AddFilterType(Context, FilterByPid, entry->ProcessId, entry->ProcessName);
DbgUpdateLogList(Context);
}
break;
case 4:
{
AddFilterType(Context, FilterByName, entry->ProcessId, entry->ProcessName);
DbgUpdateLogList(Context);
}
break;
case 5:
{
PPH_STRING string;
string = DbgGetStringForSelectedLogEntries(Context, FALSE);
PhSetClipboardString(Context->DialogHandle, &string->sr);
PhDereferenceObject(string);
SetFocus(Context->ListViewHandle);
}
break;
}
}
PhDestroyEMenu(menu);
}
}
VOID ShowDropdownMenu(
_Inout_ PPH_DBGEVENTS_CONTEXT Context
)
{
RECT rect;
PPH_EMENU menu = NULL;
PPH_EMENU_ITEM selectedItem = NULL;
PPH_EMENU_ITEM resetMenuItem = NULL;
PPH_EMENU_ITEM captureMenuItem = NULL;
PPH_EMENU_ITEM captureGlobalMenuItem = NULL;
GetWindowRect(Context->OptionsHandle, &rect);
menu = PhCreateEMenu();
PhInsertEMenuItem(menu, captureMenuItem = PhCreateEMenuItem(0, ID_CAPTURE_WIN32, L"Capture Win32", NULL, NULL), -1);
PhInsertEMenuItem(menu, captureGlobalMenuItem = PhCreateEMenuItem(0, ID_CAPTURE_WIN32_GLOBAL, L"Capture Global Win32", NULL, NULL), -1);
PhInsertEMenuItem(menu, PhCreateEMenuItem(PH_EMENU_SEPARATOR, 0, NULL, NULL, NULL), -1);
PhInsertEMenuItem(menu, resetMenuItem = PhCreateEMenuItem(PH_EMENU_DISABLED, ID_RESET_FILTERS, L"Reset Filters", NULL, NULL), -1);
PhInsertEMenuItem(menu, PhCreateEMenuItem(PH_EMENU_SEPARATOR, 0, NULL, NULL, NULL), -1);
PhInsertEMenuItem(menu, PhCreateEMenuItem(0, ID_CLEAR_EVENTS, L"Clear", NULL, NULL), -1);
PhInsertEMenuItem(menu, PhCreateEMenuItem(PH_EMENU_SEPARATOR, 0, NULL, NULL, NULL), -1);
PhInsertEMenuItem(menu, PhCreateEMenuItem(0, ID_SAVE_EVENTS, L"Save", NULL, NULL), -1);
if (Context->ExcludeList->Count > 0)
{
resetMenuItem->Text = PhaFormatString(L"Reset Filters [%lu]", Context->ExcludeList->Count)->Buffer;
resetMenuItem->Flags &= ~PH_EMENU_DISABLED;
}
if (Context->CaptureLocalEnabled)
{
captureMenuItem->Flags |= PH_EMENU_CHECKED;
}
if (Context->CaptureGlobalEnabled)
{
captureGlobalMenuItem->Flags |= PH_EMENU_CHECKED;
}
selectedItem = PhShowEMenu(
menu,
Context->DialogHandle,
PH_EMENU_SHOW_LEFTRIGHT,
PH_ALIGN_LEFT | PH_ALIGN_TOP,
rect.left,
rect.bottom
);
if (selectedItem && selectedItem->Id != -1)
{
switch (selectedItem->Id)
{
case ID_CAPTURE_WIN32:
{
if (!Context->CaptureLocalEnabled)
DbgEventsCreate(Context, FALSE);
else
DbgEventsCleanup(Context, FALSE);
}
break;
case ID_CAPTURE_WIN32_GLOBAL:
{
if (!PhGetOwnTokenAttributes().Elevated)
{
PhShowInformation(Context->DialogHandle, L"This option requires elevation.");
break;
}
if (!Context->CaptureGlobalEnabled)
DbgEventsCreate(Context, TRUE);
else
DbgEventsCleanup(Context, TRUE);
}
break;
case ID_RESET_FILTERS:
{
ResetFilters(Context);
}
break;
case ID_CLEAR_EVENTS:
{
DbgClearLogEntries(Context);
DbgUpdateLogList(Context);
}
break;
case ID_SAVE_EVENTS:
{
static PH_FILETYPE_FILTER filters[] =
{
{ L"Text files (*.txt)", L"*.txt" },
{ L"All files (*.*)", L"*.*" }
};
PVOID fileDialog = PhCreateSaveFileDialog();
PhSetFileDialogFilter(fileDialog, filters, ARRAYSIZE(filters));
PhSetFileDialogFileName(fileDialog, L"DbgView.txt");
if (PhShowFileDialog(Context->DialogHandle, fileDialog))
{
NTSTATUS status;
PPH_STRING fileName;
PPH_FILE_STREAM fileStream;
PPH_STRING string;
fileName = PhGetFileDialogFileName(fileDialog);
PhAutoDereferenceObject(fileName);
if (NT_SUCCESS(status = PhCreateFileStream(
&fileStream,
fileName->Buffer,
FILE_GENERIC_WRITE,
FILE_SHARE_READ,
FILE_OVERWRITE_IF,
0
)))
{
PhWritePhTextHeader(fileStream);
string = DbgGetStringForSelectedLogEntries(Context, TRUE);
PhWriteStringAsUtf8FileStreamEx(fileStream, string->Buffer, string->Length);
PhDereferenceObject(string);
PhDereferenceObject(fileStream);
}
if (!NT_SUCCESS(status))
PhShowStatus(PhMainWndHandle, L"Unable to create the file", status, 0);
}
PhFreeFileDialog(fileDialog);
}
break;
}
}
PhDestroyEMenu(menu);
}
INT_PTR CALLBACK DbgViewDlgProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
PPH_DBGEVENTS_CONTEXT context;
if (uMsg == WM_INITDIALOG)
{
context = (PPH_DBGEVENTS_CONTEXT)PhAllocate(sizeof(PH_DBGEVENTS_CONTEXT));
memset(context, 0, sizeof(PH_DBGEVENTS_CONTEXT));
SetProp(hwndDlg, L"Context", (HANDLE)context);
}
else
{
context = (PPH_DBGEVENTS_CONTEXT)GetProp(hwndDlg, L"Context");
if (uMsg == WM_NCDESTROY)
{
RemoveProp(hwndDlg, L"Context");
PhFree(context);
}
}
if (!context)
return FALSE;
switch (uMsg)
{
case WM_INITDIALOG:
{
PhCenterWindow(hwndDlg, PhMainWndHandle);
context->DialogHandle = hwndDlg;
context->ListViewHandle = GetDlgItem(hwndDlg, IDC_DEBUGLISTVIEW);
context->AutoScrollHandle = GetDlgItem(hwndDlg, IDC_AUTOSCROLL);
context->OptionsHandle = GetDlgItem(hwndDlg, IDC_OPTIONS);
context->LogMessageList = PhCreateList(1);
context->ExcludeList = PhCreateList(1);
PhRegisterDialog(hwndDlg);
PhSetListViewStyle(context->ListViewHandle, FALSE, TRUE);
PhSetControlTheme(context->ListViewHandle, L"explorer");
PhAddListViewColumn(context->ListViewHandle, 0, 0, 0, LVCFMT_LEFT, 140, L"Process");
PhAddListViewColumn(context->ListViewHandle, 1, 1, 1, LVCFMT_LEFT, 100, L"Timestamp");
PhAddListViewColumn(context->ListViewHandle, 2, 2, 2, LVCFMT_LEFT, 220, L"Message");
//PhSetExtendedListView(context->ListViewHandle);
if (context->ListViewImageList = ImageList_Create(19, 19, ILC_COLOR32 | ILC_MASK, 0, 40))
{
HICON defaultIcon = PhGetFileShellIcon(NULL, L".exe", TRUE);
ListView_SetImageList(context->ListViewHandle, context->ListViewImageList, LVSIL_SMALL);
ImageList_AddIcon(context->ListViewImageList, defaultIcon);
DestroyIcon(defaultIcon);
}
PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
PhAddLayoutItem(&context->LayoutManager, context->ListViewHandle, NULL, PH_ANCHOR_ALL);
PhAddLayoutItem(&context->LayoutManager, context->OptionsHandle, NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
PhAddLayoutItem(&context->LayoutManager, context->AutoScrollHandle, NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_ALWAYSONTOP), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDCLOSE), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
PhLoadWindowPlacementFromSetting(SETTING_NAME_WINDOW_POSITION, SETTING_NAME_WINDOW_SIZE, hwndDlg);
PhLoadListViewColumnsFromSetting(SETTING_NAME_COLUMNS, context->ListViewHandle);
if (PhGetIntegerSetting(SETTING_NAME_ALWAYSONTOP))
{
context->AlwaysOnTop = TRUE;
SetFocus(hwndDlg);
SetWindowPos(hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE);
Button_SetCheck(GetDlgItem(hwndDlg, IDC_ALWAYSONTOP), BST_CHECKED);
}
if (PhGetIntegerSetting(SETTING_NAME_AUTOSCROLL))
{
context->AutoScroll = TRUE;
Button_SetCheck(context->AutoScrollHandle, BST_CHECKED);
}
DbgCreateSecurityAttributes(context);
DbgUpdateLogList(context);
PhRegisterCallback(&DbgLoggedCallback, DbgLoggedEventCallback, context, &context->DebugLoggedRegistration);
}
return TRUE;
case WM_DESTROY:
{
DbgEventsCleanup(context, FALSE);
DbgEventsCleanup(context, TRUE);
DbgCleanupSecurityAttributes(context);
if (context->ListViewImageList)
ImageList_Destroy(context->ListViewImageList);
if (context->ExcludeList)
{
ResetFilters(context);
PhDereferenceObject(context->ExcludeList);
}
if (context->LogMessageList)
{
DbgClearLogEntries(context);
PhDereferenceObject(context->LogMessageList);
}
PhSaveWindowPlacementToSetting(SETTING_NAME_WINDOW_POSITION, SETTING_NAME_WINDOW_SIZE, hwndDlg);
PhSaveListViewColumnsToSetting(SETTING_NAME_COLUMNS, context->ListViewHandle);
PhDeleteLayoutManager(&context->LayoutManager);
PhUnregisterCallback(&DbgLoggedCallback, &context->DebugLoggedRegistration);
PhUnregisterDialog(hwndDlg);
PostQuitMessage(0);
}
break;
case WM_SIZE:
PhLayoutManagerLayout(&context->LayoutManager);
break;
case WM_SHOWDIALOG:
{
if (IsMinimized(hwndDlg))
ShowWindow(hwndDlg, SW_RESTORE);
else
ShowWindow(hwndDlg, SW_SHOW);
SetForegroundWindow(hwndDlg);
}
break;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_OPTIONS:
ShowDropdownMenu(context);
break;
case IDCLOSE:
case IDCANCEL:
DestroyWindow(hwndDlg);
break;
case IDC_AUTOSCROLL:
{
context->AutoScroll = !context->AutoScroll;
PhSetIntegerSetting(SETTING_NAME_AUTOSCROLL, context->AutoScroll);
Button_SetCheck(context->AutoScrollHandle, context->AutoScroll ? BST_CHECKED : BST_UNCHECKED);
}
break;
case IDC_ALWAYSONTOP:
{
context->AlwaysOnTop = !context->AlwaysOnTop;
SetWindowPos(hwndDlg, context->AlwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,
0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
PhSetIntegerSetting(SETTING_NAME_ALWAYSONTOP, context->AlwaysOnTop);
}
break;
}
}
break;
case WM_NOTIFY:
{
LPNMHDR hdr = (LPNMHDR)lParam;
switch (hdr->code)
{
case NM_RCLICK:
{
if (hdr->hwndFrom == context->ListViewHandle)
{
ShowListViewMenu(context);
}
}
break;
case NM_DBLCLK:
{
PDEBUG_LOG_ENTRY entry;
INT index;
index = PhFindListViewItemByFlags(context->ListViewHandle, -1, LVNI_SELECTED);
if (index == -1)
break;
entry = context->LogMessageList->Items[index];
DialogBoxParam(
PluginInstance->DllBase,
MAKEINTRESOURCE(IDD_MESSAGE_DIALOG),
hwndDlg,
DbgPropDlgProc,
(LPARAM)entry
);
}
break;
case LVN_GETDISPINFO:
{
NMLVDISPINFO* dispInfo = (NMLVDISPINFO*)hdr;
PDEBUG_LOG_ENTRY entry;
entry = context->LogMessageList->Items[dispInfo->item.iItem];
if (dispInfo->item.mask & LVIF_IMAGE)
{
dispInfo->item.iImage = entry->ImageIndex;
}
if (dispInfo->item.iSubItem == 0)
{
if (dispInfo->item.mask & LVIF_TEXT)
{
wcsncpy_s(
dispInfo->item.pszText,
dispInfo->item.cchTextMax,
entry->ProcessName->Buffer,
_TRUNCATE
);
}
}
else if (dispInfo->item.iSubItem == 1)
{
if (dispInfo->item.mask & LVIF_TEXT)
{
SYSTEMTIME systemTime;
PPH_STRING dateTime;
PPH_STRING dateString;
PhLargeIntegerToLocalSystemTime(&systemTime, &entry->Time);
dateTime = PhFormatTime(&systemTime, L"hh:mm:ss");
dateString = PhFormatString(
L"%s.%u",
dateTime->Buffer,
systemTime.wMilliseconds
);
wcsncpy_s(
dispInfo->item.pszText,
dispInfo->item.cchTextMax,
dateString->Buffer,
_TRUNCATE
);
PhDereferenceObject(dateString);
PhDereferenceObject(dateTime);
}
}
else if (dispInfo->item.iSubItem == 2)
{
if (dispInfo->item.mask & LVIF_TEXT)
{
wcsncpy_s(
dispInfo->item.pszText,
dispInfo->item.cchTextMax,
entry->Message->Buffer,
_TRUNCATE
);
}
}
}
break;
}
}
break;
case WM_DEBUG_LOG_UPDATED:
DbgUpdateLogList(context);
break;
}
return FALSE;
}
NTSTATUS DbgViewDialogThread(
_In_ PVOID Parameter
)
{
BOOL result;
MSG message;
PH_AUTO_POOL autoPool;
PhInitializeAutoPool(&autoPool);
DbgDialogHandle = CreateDialog(
PluginInstance->DllBase,
MAKEINTRESOURCE(IDD_DBGVIEW_DIALOG),
NULL,
DbgViewDlgProc
);
PhSetEvent(&InitializedEvent);
while (result = GetMessage(&message, NULL, 0, 0))
{
if (result == -1)
break;
if (!IsDialogMessage(DbgDialogHandle, &message))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
PhDrainAutoPool(&autoPool);
}
PhDeleteAutoPool(&autoPool);
PhResetEvent(&InitializedEvent);
if (DbgDialogThreadHandle)
{
NtClose(DbgDialogThreadHandle);
DbgDialogThreadHandle = NULL;
}
return STATUS_SUCCESS;
}
VOID ShowDebugEventsDialog(
VOID
)
{
if (!DbgDialogThreadHandle)
{
if (!(DbgDialogThreadHandle = PhCreateThread(0, DbgViewDialogThread, NULL)))
{
PhShowStatus(PhMainWndHandle, L"Unable to create the window.", 0, GetLastError());
return;
}
PhWaitForEvent(&InitializedEvent, NULL);
}
PostMessage(DbgDialogHandle, WM_SHOWDIALOG, 0, 0);
}

View File

@@ -0,0 +1,81 @@
/*
* Process Hacker Extra Plugins -
* Debug View Plugin
*
* Copyright (C) 2015 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
VOID AddFilterType(
_Inout_ PPH_DBGEVENTS_CONTEXT Context,
_In_ FILTER_BY_TYPE Type,
_In_ HANDLE ProcessID,
_In_ PPH_STRING ProcessName
)
{
PDBG_FILTER_TYPE newFilterEntry;
newFilterEntry = PhAllocate(sizeof(DBG_FILTER_TYPE));
newFilterEntry->Type = Type;
newFilterEntry->ProcessId = ProcessID;
newFilterEntry->ProcessName = ProcessName;
PhAddItemList(Context->ExcludeList, newFilterEntry);
// Remove any existing entries...
for (ULONG i = 0; i < Context->LogMessageList->Count; i++)
{
PDEBUG_LOG_ENTRY listEntry = Context->LogMessageList->Items[i];
if (Type == FilterByName)
{
if (PhEqualString(listEntry->ProcessName, newFilterEntry->ProcessName, TRUE))
{
PhRemoveItemList(Context->LogMessageList, i);
i--;
}
}
else if (Type == FilterByPid)
{
if (listEntry->ProcessId == ProcessID)
{
PhRemoveItemList(Context->LogMessageList, i);
i--;
}
}
}
}
VOID ResetFilters(
_Inout_ PPH_DBGEVENTS_CONTEXT Context
)
{
for (ULONG i = 0; i < Context->ExcludeList->Count; i++)
{
PDBG_FILTER_TYPE filterEntry = Context->ExcludeList->Items[i];
if (filterEntry->ProcessName)
PhDereferenceObject(filterEntry->ProcessName);
PhFree(filterEntry);
PhRemoveItemList(Context->ExcludeList, i);
i--;
}
}

View File

@@ -0,0 +1,495 @@
/*
* Process Hacker Extra Plugins -
* Debug View Plugin
*
* Copyright (C) 2015 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
PH_CALLBACK_DECLARE(DbgLoggedCallback);
VOID DbgFreeLogEntry(
_Inout_ PDEBUG_LOG_ENTRY Entry
)
{
PhClearReference(&Entry->FilePath);
PhClearReference(&Entry->ProcessName);
PhClearReference(&Entry->Message);
PhFree(Entry);
}
VOID DbgAddLogEntry(
_Inout_ PPH_DBGEVENTS_CONTEXT Context,
_In_ PDEBUG_LOG_ENTRY Entry
)
{
if (Context->LogMessageList->Count > PhGetIntegerSetting(SETTING_NAME_MAX_ENTRIES))
{
DbgFreeLogEntry(Context->LogMessageList->Items[0]);
PhRemoveItemList(Context->LogMessageList, 0);
}
PhAddItemList(Context->LogMessageList, Entry);
PhInvokeCallback(&DbgLoggedCallback, Entry);
}
VOID DbgClearLogEntries(
_Inout_ PPH_DBGEVENTS_CONTEXT Context
)
{
for (ULONG i = 0; i < Context->LogMessageList->Count; i++)
{
if (Context->LogMessageList->Items[i])
{
DbgFreeLogEntry(Context->LogMessageList->Items[i]);
}
}
PhClearList(Context->LogMessageList);
}
VOID DbgShowErrorMessage(
_Inout_ PPH_DBGEVENTS_CONTEXT Context,
_In_ PWSTR Type
)
{
ULONG errorCode = GetLastError();
PPH_STRING errorMessage = PhGetWin32Message(errorCode);
if (errorMessage)
{
PhShowError(Context->DialogHandle, PhaFormatString(L"%s: [%u] %s", Type, errorCode, errorMessage->Buffer)->Buffer);
PhDereferenceObject(errorMessage);
}
}
VOID DbgFormatObjectName(
_In_ BOOLEAN LocalName,
_In_ PWSTR OriginalName,
_Out_ PUNICODE_STRING ObjectName
)
{
SIZE_T length;
SIZE_T originalNameLength;
// Sessions other than session 0 require SeCreateGlobalPrivilege.
if (LocalName && NtCurrentPeb()->SessionId != 0)
{
WCHAR buffer[256] = L"";
memcpy(buffer, L"\\Sessions\\", 10 * sizeof(WCHAR));
_ultow(NtCurrentPeb()->SessionId, buffer + 10, 10);
length = PhCountStringZ(buffer);
originalNameLength = PhCountStringZ(OriginalName);
memcpy(buffer + length, OriginalName, (originalNameLength + 1) * sizeof(WCHAR));
length += originalNameLength;
ObjectName->Buffer = buffer;
ObjectName->MaximumLength = (ObjectName->Length = (USHORT)(length * sizeof(WCHAR))) + sizeof(WCHAR);
}
else
{
RtlInitUnicodeString(ObjectName, OriginalName);
}
}
VOID DbgProcessLogMessageEntry(
_Inout_ PPH_DBGEVENTS_CONTEXT Context,
_In_ BOOLEAN GlobalEvents
)
{
NTSTATUS status;
PDBWIN_PAGE_BUFFER debugMessageBuffer;
PDEBUG_LOG_ENTRY entry = NULL;
HANDLE processHandle = NULL;
PPH_STRING fileName = NULL;
HICON icon = NULL;
debugMessageBuffer = GlobalEvents ? Context->GlobalDebugBuffer : Context->LocalDebugBuffer;
entry = PhAllocate(sizeof(DEBUG_LOG_ENTRY));
memset(entry, 0, sizeof(DEBUG_LOG_ENTRY));
PhQuerySystemTime(&entry->Time);
entry->ProcessId = UlongToHandle(debugMessageBuffer->ProcessId);
entry->Message = PhConvertMultiByteToUtf16(debugMessageBuffer->Buffer);
if (WINDOWS_HAS_IMAGE_FILE_NAME_BY_PROCESS_ID)
{
status = PhGetProcessImageFileNameByProcessId(entry->ProcessId, &fileName);
}
else
{
if (NT_SUCCESS(status = PhOpenProcess(&processHandle, ProcessQueryAccess, entry->ProcessId)))
{
status = PhGetProcessImageFileName(processHandle, &fileName);
NtClose(processHandle);
}
}
if (!NT_SUCCESS(status))
fileName = PhGetKernelFileName();
PhMoveReference(&fileName, PhGetFileName(fileName));
icon = PhGetFileShellIcon(PhGetString(fileName), L".exe", TRUE);
if (icon)
{
entry->ImageIndex = ImageList_AddIcon(Context->ListViewImageList, icon);
DestroyIcon(icon);
}
entry->FilePath = fileName;
entry->ProcessName = PhGetBaseName(fileName);
// Drop event if it matches a filter
for (ULONG i = 0; i < Context->ExcludeList->Count; i++)
{
PDBG_FILTER_TYPE filterEntry = Context->ExcludeList->Items[i];
if (filterEntry->Type == FilterByName)
{
if (PhEqualString(filterEntry->ProcessName, entry->ProcessName, TRUE))
{
DbgFreeLogEntry(entry);
return;
}
}
else if (filterEntry->Type == FilterByPid)
{
if (filterEntry->ProcessId == entry->ProcessId)
{
DbgFreeLogEntry(entry);
return;
}
}
}
DbgAddLogEntry(Context, entry);
}
NTSTATUS DbgEventsLocalThread(
_In_ PVOID Parameter
)
{
LARGE_INTEGER timeout;
NTSTATUS status;
PPH_DBGEVENTS_CONTEXT context = (PPH_DBGEVENTS_CONTEXT)Parameter;
while (TRUE)
{
NtSetEvent(context->LocalBufferReadyEvent, NULL);
status = NtWaitForSingleObject(
context->LocalDataReadyEvent,
FALSE,
PhTimeoutFromMilliseconds(&timeout, 100)
);
if (status == STATUS_TIMEOUT)
continue;
if (status != STATUS_SUCCESS)
break;
// The process calling OutputDebugString is blocked here...
// This gives us some time to extract information without the process exiting.
DbgProcessLogMessageEntry(context, FALSE);
}
return STATUS_SUCCESS;
}
NTSTATUS DbgEventsGlobalThread(
_In_ PVOID Parameter
)
{
LARGE_INTEGER timeout;
NTSTATUS status;
PPH_DBGEVENTS_CONTEXT context = (PPH_DBGEVENTS_CONTEXT)Parameter;
while (TRUE)
{
NtSetEvent(context->GlobalBufferReadyEvent, NULL);
status = NtWaitForSingleObject(
context->GlobalDataReadyEvent,
FALSE,
PhTimeoutFromMilliseconds(&timeout, 100)
);
if (status == STATUS_TIMEOUT)
continue;
if (status != STATUS_SUCCESS)
break;
// The process calling OutputDebugString is blocked here...
// This gives us some time to extract information without the process exiting.
DbgProcessLogMessageEntry(context, TRUE);
}
return STATUS_SUCCESS;
}
BOOLEAN DbgCreateSecurityAttributes(
_Inout_ PPH_DBGEVENTS_CONTEXT Context
)
{
Context->SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
Context->SecurityAttributes.bInheritHandle = TRUE;
if (ConvertStringSecurityDescriptorToSecurityDescriptor(
L"D:(A;;GRGWGX;;;WD)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRGWGX;;;AN)(A;;GRGWGX;;;RC)(A;;GRGWGX;;;S-1-15-2-1)S:(ML;;NW;;;LW)",
SDDL_REVISION,
&Context->SecurityAttributes.lpSecurityDescriptor,
NULL
))
{
return TRUE;
}
return FALSE;
}
BOOLEAN DbgCleanupSecurityAttributes(
_Inout_ PPH_DBGEVENTS_CONTEXT Context
)
{
if (Context->SecurityAttributes.lpSecurityDescriptor)
{
LocalFree(Context->SecurityAttributes.lpSecurityDescriptor);
Context->SecurityAttributes.lpSecurityDescriptor = NULL;
return TRUE;
}
return FALSE;
}
BOOLEAN DbgEventsCreate(
_Inout_ PPH_DBGEVENTS_CONTEXT Context,
_In_ BOOLEAN GlobalEvents
)
{
if (GlobalEvents)
{
SIZE_T viewSize;
LARGE_INTEGER maximumSize;
OBJECT_ATTRIBUTES objectAttributes;
UNICODE_STRING objectName;
HANDLE threadHandle = NULL;
maximumSize.QuadPart = PAGE_SIZE;
viewSize = sizeof(DBWIN_PAGE_BUFFER);
if (!(Context->GlobalBufferReadyEvent = CreateEvent(&Context->SecurityAttributes, FALSE, FALSE, L"Global\\" DBWIN_BUFFER_READY)))
{
DbgShowErrorMessage(Context, L"DBWIN_BUFFER_READY");
return FALSE;
}
if (!(Context->GlobalDataReadyEvent = CreateEvent(&Context->SecurityAttributes, FALSE, FALSE, L"Global\\" DBWIN_DATA_READY)))
{
DbgShowErrorMessage(Context, L"DBWIN_DATA_READY");
return FALSE;
}
DbgFormatObjectName(FALSE, DBWIN_BUFFER_SECTION_NAME, &objectName);
InitializeObjectAttributes(
&objectAttributes,
&objectName,
OBJ_CASE_INSENSITIVE,
NULL,
Context->SecurityAttributes.lpSecurityDescriptor
);
if (!NT_SUCCESS(NtCreateSection(
&Context->GlobalDataBufferHandle,
STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE,
&objectAttributes,
&maximumSize,
PAGE_READWRITE,
SEC_COMMIT,
NULL
)))
{
DbgShowErrorMessage(Context, L"NtCreateSection");
return FALSE;
}
if (!NT_SUCCESS(NtMapViewOfSection(
Context->GlobalDataBufferHandle,
NtCurrentProcess(),
&Context->GlobalDebugBuffer,
0,
0,
NULL,
&viewSize,
ViewShare,
0,
PAGE_READONLY
)))
{
DbgShowErrorMessage(Context, L"NtMapViewOfSection");
return FALSE;
}
Context->CaptureGlobalEnabled = TRUE;
if (threadHandle = PhCreateThread(0, DbgEventsGlobalThread, Context))
{
NtClose(threadHandle);
}
}
else
{
SIZE_T viewSize;
LARGE_INTEGER maximumSize;
OBJECT_ATTRIBUTES objectAttributes;
UNICODE_STRING objectName;
HANDLE threadHandle = NULL;
maximumSize.QuadPart = PAGE_SIZE;
viewSize = sizeof(DBWIN_PAGE_BUFFER);
if (!(Context->LocalBufferReadyEvent = CreateEvent(&Context->SecurityAttributes, FALSE, FALSE, L"Local\\" DBWIN_BUFFER_READY)))
{
DbgShowErrorMessage(Context, L"DBWIN_BUFFER_READY");
return FALSE;
}
if (!(Context->LocalDataReadyEvent = CreateEvent(&Context->SecurityAttributes, FALSE, FALSE, L"Local\\" DBWIN_DATA_READY)))
{
DbgShowErrorMessage(Context, L"DBWIN_DATA_READY");
return FALSE;
}
DbgFormatObjectName(TRUE, DBWIN_BUFFER_SECTION_NAME, &objectName);
InitializeObjectAttributes(
&objectAttributes,
&objectName,
OBJ_CASE_INSENSITIVE,
NULL,
Context->SecurityAttributes.lpSecurityDescriptor
);
if (!NT_SUCCESS(NtCreateSection(
&Context->LocalDataBufferHandle,
STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE,
&objectAttributes,
&maximumSize,
PAGE_READWRITE,
SEC_COMMIT,
NULL
)))
{
DbgShowErrorMessage(Context, L"NtCreateSection");
return FALSE;
}
if (!NT_SUCCESS(NtMapViewOfSection(
Context->LocalDataBufferHandle,
NtCurrentProcess(),
&Context->LocalDebugBuffer,
0,
0,
NULL,
&viewSize,
ViewShare,
0,
PAGE_READONLY
)))
{
DbgShowErrorMessage(Context, L"NtMapViewOfSection");
return FALSE;
}
Context->CaptureLocalEnabled = TRUE;
if (threadHandle = PhCreateThread(0, DbgEventsLocalThread, Context))
{
NtClose(threadHandle);
}
}
return TRUE;
}
VOID DbgEventsCleanup(
_Inout_ PPH_DBGEVENTS_CONTEXT Context,
_In_ BOOLEAN CleanupGlobal
)
{
if (CleanupGlobal)
{
Context->CaptureGlobalEnabled = FALSE;
if (Context->GlobalDebugBuffer)
{
NtUnmapViewOfSection(NtCurrentProcess(), Context->GlobalDebugBuffer);
Context->GlobalDebugBuffer = NULL;
}
if (Context->GlobalDataBufferHandle)
{
NtClose(Context->GlobalDataBufferHandle);
Context->GlobalDataBufferHandle = NULL;
}
if (Context->GlobalBufferReadyEvent)
{
NtClose(Context->GlobalBufferReadyEvent);
Context->GlobalBufferReadyEvent = NULL;
}
if (Context->GlobalDataReadyEvent)
{
NtClose(Context->GlobalDataReadyEvent);
Context->GlobalDataReadyEvent = NULL;
}
}
else
{
Context->CaptureLocalEnabled = FALSE;
if (Context->LocalDebugBuffer)
{
NtUnmapViewOfSection(NtCurrentProcess(), Context->LocalDebugBuffer);
Context->LocalDebugBuffer = NULL;
}
if (Context->LocalDataBufferHandle)
{
NtClose(Context->LocalDataBufferHandle);
Context->LocalDataBufferHandle = NULL;
}
if (Context->LocalBufferReadyEvent)
{
NtClose(Context->LocalBufferReadyEvent);
Context->LocalBufferReadyEvent = NULL;
}
if (Context->LocalDataReadyEvent)
{
NtClose(Context->LocalDataReadyEvent);
Context->LocalDataReadyEvent = NULL;
}
}
}

View File

@@ -0,0 +1,115 @@
/*
* Process Hacker Extra Plugins -
* Debug View Plugin
*
* Copyright (C) 2015 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
PPH_PLUGIN PluginInstance;
static PH_CALLBACK_REGISTRATION PluginMenuItemCallbackRegistration;
static PH_CALLBACK_REGISTRATION MainMenuInitializingCallbackRegistration;
VOID NTAPI MainMenuInitializingCallback(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
)
{
PPH_PLUGIN_MENU_INFORMATION menuInfo = Parameter;
PPH_EMENU_ITEM systemMenu;
PPH_EMENU_ITEM bootMenuItem;
if (menuInfo->u.MainMenu.SubMenuIndex != PH_MENU_ITEM_LOCATION_TOOLS)
return;
if (!(systemMenu = PhFindEMenuItem(menuInfo->Menu, 0, L"System", 0)))
{
PhInsertEMenuItem(menuInfo->Menu, PhPluginCreateEMenuItem(PluginInstance, PH_EMENU_SEPARATOR, 0, L"", NULL), -1);
PhInsertEMenuItem(menuInfo->Menu, systemMenu = PhPluginCreateEMenuItem(PluginInstance, 0, 0, L"System", NULL), -1);
}
PhInsertEMenuItem(systemMenu, bootMenuItem = PhPluginCreateEMenuItem(PluginInstance, 0, DBGVIEW_MENUITEM, L"Debug View", NULL), -1);
}
VOID NTAPI MenuItemCallback(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
)
{
PPH_PLUGIN_MENU_ITEM menuItem = (PPH_PLUGIN_MENU_ITEM)Parameter;
switch (menuItem->Id)
{
case DBGVIEW_MENUITEM:
ShowDebugEventsDialog();
break;
}
}
LOGICAL DllMain(
_In_ HINSTANCE Instance,
_In_ ULONG Reason,
_Reserved_ PVOID Reserved
)
{
switch (Reason)
{
case DLL_PROCESS_ATTACH:
{
PPH_PLUGIN_INFORMATION info;
PH_SETTING_CREATE settings[] =
{
{ IntegerPairSettingType, SETTING_NAME_WINDOW_POSITION, L"350,350" },
{ ScalableIntegerPairSettingType, SETTING_NAME_WINDOW_SIZE, L"@96|510,380" },
{ StringSettingType, SETTING_NAME_COLUMNS, L"" },
{ IntegerSettingType, SETTING_NAME_ALWAYSONTOP, L"0" },
{ IntegerSettingType, SETTING_NAME_AUTOSCROLL, L"1" },
{ IntegerSettingType, SETTING_NAME_MAX_ENTRIES, L"2048" }
};
PluginInstance = PhRegisterPlugin(PLUGIN_NAME, Instance, &info);
if (!PluginInstance)
return FALSE;
info->DisplayName = L"Debug View";
info->Author = L"dmex";
info->Description = L"Plugin for viewing Win32 debug output via the Tools menu.";
info->HasOptions = FALSE;
PhRegisterCallback(
PhGetGeneralCallback(GeneralCallbackMainMenuInitializing),
MainMenuInitializingCallback,
NULL,
&MainMenuInitializingCallbackRegistration
);
PhRegisterCallback(
PhGetPluginCallback(PluginInstance, PluginCallbackMenuItem),
MenuItemCallback,
NULL,
&PluginMenuItemCallbackRegistration
);
PhAddSettings(settings, ARRAYSIZE(settings));
}
break;
}
return TRUE;
}

View File

@@ -0,0 +1,178 @@
/*
* Process Hacker Extra Plugins -
* Debug View Plugin
*
* Copyright (C) 2015 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _DBG_H_
#define _DBG_H_
#define PLUGIN_NAME L"dmex.DbgView"
#define SETTING_NAME_WINDOW_POSITION (PLUGIN_NAME L".WindowPosition")
#define SETTING_NAME_WINDOW_SIZE (PLUGIN_NAME L".WindowSize")
#define SETTING_NAME_COLUMNS (PLUGIN_NAME L".WindowColumns")
#define SETTING_NAME_ALWAYSONTOP (PLUGIN_NAME L".AlwaysOnTop")
#define SETTING_NAME_AUTOSCROLL (PLUGIN_NAME L".AutoScroll")
#define SETTING_NAME_MAX_ENTRIES (PLUGIN_NAME L".MaxEntries")
#define DBGVIEW_MENUITEM 1000
#define WM_SHOWDIALOG (WM_APP + 100)
#define WM_DEBUG_LOG_UPDATED (WM_APP + 101)
#define CINTERFACE
#define COBJMACROS
#include <phdk.h>
#include <phappresource.h>
#include <windowsx.h>
#include <Sddl.h>
#include "resource.h"
#define DBWIN_BUFFER_READY L"DBWIN_BUFFER_READY"
#define DBWIN_DATA_READY L"DBWIN_DATA_READY"
#define DBWIN_BUFFER L"DBWIN_BUFFER"
#define DBWIN_BUFFER_READY_OBJECT_NAME L"\\BaseNamedObjects\\DBWIN_BUFFER_READY"
#define DBWIN_DATA_READY_OBJECT_NAME L"\\BaseNamedObjects\\DBWIN_DATA_READY"
#define DBWIN_BUFFER_SECTION_NAME L"\\BaseNamedObjects\\DBWIN_BUFFER"
// The Win32 OutputDebugString buffer.
typedef struct _DBWIN_PAGE_BUFFER
{
ULONG ProcessId; /** The ID of the process. */
CHAR Buffer[PAGE_SIZE - sizeof(ULONG)]; /** The buffer containing the debug message. */
} DBWIN_PAGE_BUFFER, *PDBWIN_PAGE_BUFFER;
extern PPH_PLUGIN PluginInstance;
extern PH_CALLBACK DbgLoggedCallback;
typedef enum _FILTER_BY_TYPE
{
FilterByUnknown,
FilterByPid,
FilterByName
} FILTER_BY_TYPE;
typedef struct _DBG_FILTER_TYPE
{
FILTER_BY_TYPE Type;
HANDLE ProcessId;
PPH_STRING ProcessName;
} DBG_FILTER_TYPE, *PDBG_FILTER_TYPE;
typedef enum _COMMAND_ID
{
ID_CAPTURE_WIN32 = 1,
ID_CAPTURE_WIN32_GLOBAL,
ID_RESET_FILTERS,
ID_CLEAR_EVENTS,
ID_SAVE_EVENTS,
} COMMAND_ID;
typedef struct _PH_DBGEVENTS_CONTEXT
{
BOOLEAN AlwaysOnTop;
BOOLEAN AutoScroll;
BOOLEAN CaptureLocalEnabled;
BOOLEAN CaptureGlobalEnabled;
ULONG ListViewCount;
HWND DialogHandle;
HWND ListViewHandle;
HWND AutoScrollHandle;
HWND OptionsHandle;
HIMAGELIST ListViewImageList;
PH_LAYOUT_MANAGER LayoutManager;
PH_CALLBACK_REGISTRATION DebugLoggedRegistration;
SECURITY_ATTRIBUTES SecurityAttributes;
PPH_LIST ExcludeList;
PPH_LIST LogMessageList;
HANDLE LocalBufferReadyEvent;
HANDLE LocalDataReadyEvent;
HANDLE LocalDataBufferHandle;
PDBWIN_PAGE_BUFFER LocalDebugBuffer;
HANDLE GlobalBufferReadyEvent;
HANDLE GlobalDataReadyEvent;
HANDLE GlobalDataBufferHandle;
PDBWIN_PAGE_BUFFER GlobalDebugBuffer;
} PH_DBGEVENTS_CONTEXT, *PPH_DBGEVENTS_CONTEXT;
typedef struct _DEBUG_LOG_ENTRY
{
INT ImageIndex;
LARGE_INTEGER Time;
HANDLE ProcessId;
PPH_STRING Message;
PPH_STRING ProcessName;
PPH_STRING FilePath;
} DEBUG_LOG_ENTRY, *PDEBUG_LOG_ENTRY;
INT_PTR CALLBACK DbgPropDlgProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
VOID ShowDebugEventsDialog(
VOID
);
// log.c
VOID DbgClearLogEntries(
_Inout_ PPH_DBGEVENTS_CONTEXT Context
);
BOOLEAN DbgCreateSecurityAttributes(
_Inout_ PPH_DBGEVENTS_CONTEXT Context
);
BOOLEAN DbgCleanupSecurityAttributes(
_Inout_ PPH_DBGEVENTS_CONTEXT Context
);
BOOLEAN DbgEventsCreate(
_Inout_ PPH_DBGEVENTS_CONTEXT Context,
_In_ BOOLEAN GlobalEvents
);
VOID DbgEventsCleanup(
_Inout_ PPH_DBGEVENTS_CONTEXT Context,
_In_ BOOLEAN CleanupGlobal
);
// Filter.c
VOID AddFilterType(
_Inout_ PPH_DBGEVENTS_CONTEXT Context,
_In_ FILTER_BY_TYPE Type,
_In_ HANDLE ProcessID,
_In_ PPH_STRING ProcessName
);
VOID ResetFilters(
_Inout_ PPH_DBGEVENTS_CONTEXT Context
);
#endif

View File

@@ -0,0 +1,87 @@
/*
* Process Hacker Extra Plugins -
* Debug View Plugin
*
* Copyright (C) 2015 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
static PH_LAYOUT_MANAGER LayoutManager;
INT_PTR CALLBACK DbgPropDlgProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
switch (uMsg)
{
case WM_INITDIALOG:
{
PDEBUG_LOG_ENTRY entry = (PDEBUG_LOG_ENTRY)lParam;
PhCenterWindow(hwndDlg, GetParent(hwndDlg));
PhInitializeLayoutManager(&LayoutManager, hwndDlg);
PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDC_MESSAGE), NULL, PH_ANCHOR_ALL);
PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDCLOSE), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
Edit_SetText(GetDlgItem(hwndDlg, IDC_MESSAGE), entry->Message->Buffer);
//SendMessage(GetDlgItem(hwndDlg, IDC_MESSAGE), WM_SETFONT, (WPARAM)PhApplicationFont, FALSE);
}
return TRUE;
case WM_DESTROY:
PhDeleteLayoutManager(&LayoutManager);
break;
case WM_SIZE:
PhLayoutManagerLayout(&LayoutManager);
break;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDCANCEL:
case IDCLOSE:
EndDialog(hwndDlg, IDOK);
break;
}
}
break;
case WM_CTLCOLORBTN:
case WM_CTLCOLORDLG:
case WM_CTLCOLORSTATIC:
{
HDC hDC = (HDC)wParam;
HWND hwndChild = (HWND)lParam;
// Check for our static label and change the color.
if (GetDlgCtrlID(hwndChild) == IDC_MESSAGE)
{
SetBkMode(hDC, TRANSPARENT);
// set window background color.
return (INT_PTR)GetSysColorBrush(COLOR_WINDOW);
}
}
break;
}
return FALSE;
}

View File

@@ -0,0 +1,22 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by DbgViewPlugin.rc
//
#define IDD_DBGVIEW_DIALOG 101
#define IDD_MESSAGE_DIALOG 103
#define IDC_DEBUGLISTVIEW 1001
#define IDC_MESSAGE 1002
#define IDC_OPTIONS 1003
#define IDC_AUTOSCROLL 1004
#define IDC_ALWAYSONTOP 1005
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 104
#define _APS_NEXT_COMMAND_VALUE 40006
#define _APS_NEXT_CONTROL_VALUE 1006
#define _APS_NEXT_SYMED_VALUE 105
#endif
#endif