go my file uploader
This commit is contained in:
24
plugins/NetworkTools/CHANGELOG.txt
Normal file
24
plugins/NetworkTools/CHANGELOG.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
1.6
|
||||
* Added PathPing support
|
||||
|
||||
1.5
|
||||
* Improved ping graph scaling
|
||||
|
||||
1.4
|
||||
* Fixed whois scrolling issue
|
||||
* Fixed ping threading issues
|
||||
* Fixed various memory leaks
|
||||
|
||||
1.3
|
||||
* Added plugin options for ping/tracert/whois
|
||||
* Added native pint/tracert/whois support
|
||||
* Updated UI
|
||||
|
||||
1.2
|
||||
* Fixed encoding bug
|
||||
|
||||
1.1
|
||||
* Fixed handle leak
|
||||
|
||||
1.0
|
||||
* Initial release
|
||||
196
plugins/NetworkTools/NetworkTools.rc
Normal file
196
plugins/NetworkTools/NetworkTools.rc
Normal file
@@ -0,0 +1,196 @@
|
||||
// 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)
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""winres.h""\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,6,0,0
|
||||
PRODUCTVERSION 1,6,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "0c0904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "dmex"
|
||||
VALUE "FileDescription", "Network Tools plugin for Process Hacker"
|
||||
VALUE "FileVersion", "1.6"
|
||||
VALUE "InternalName", "NetworkTools"
|
||||
VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
|
||||
VALUE "OriginalFilename", "NetworkTools.dll"
|
||||
VALUE "ProductName", "Network Tools plugin for Process Hacker"
|
||||
VALUE "ProductVersion", "1.6"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0xc09, 1200
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_OUTPUT DIALOGEX 0, 0, 319, 183
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
|
||||
EXSTYLE WS_EX_APPWINDOW
|
||||
CAPTION "Network Tools"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
EDITTEXT IDC_NETOUTPUTEDIT,7,7,305,152,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_BORDER | WS_VSCROLL,WS_EX_CLIENTEDGE
|
||||
CONTROL "<a>More information</a>",IDC_MORE_INFO,"SysLink",NOT WS_VISIBLE | WS_TABSTOP,7,163,77,12
|
||||
PUSHBUTTON "Close",IDOK,263,162,50,14
|
||||
END
|
||||
|
||||
IDD_OPTIONS DIALOGEX 0, 0, 215, 79
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Options"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
LTEXT "Timeout (milliseconds):",IDC_STATIC,9,7,73,8
|
||||
EDITTEXT IDC_MAXTIMEOUTTEXT,7,17,79,14,ES_AUTOHSCROLL | ES_NUMBER
|
||||
DEFPUSHBUTTON "OK",IDOK,104,58,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,158,58,50,14
|
||||
END
|
||||
|
||||
IDD_PINGDIALOG DIALOGEX 0, 0, 269, 131
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
|
||||
EXSTYLE WS_EX_APPWINDOW
|
||||
CAPTION "Dialog"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
LTEXT "Pinging X with X bytes of data:",IDC_MAINTEXT,7,7,255,16
|
||||
LTEXT "PingGraphLayout",IDC_PING_LAYOUT,7,26,255,27,NOT WS_VISIBLE | WS_BORDER
|
||||
GROUPBOX "Ping statistics",IDC_ICMP_PANEL,7,56,254,52,0,WS_EX_TRANSPARENT
|
||||
LTEXT "Average: 0ms",IDC_ICMP_AVG,13,69,73,8
|
||||
LTEXT "Pings sent: 0",IDC_PINGS_SENT,92,69,88,8
|
||||
LTEXT "Bad hashes: 0",IDC_BAD_HASH,186,69,72,8
|
||||
LTEXT "Minimum: 0ms",IDC_ICMP_MIN,13,81,73,8
|
||||
LTEXT "Pings lost: 0 (0%)",IDC_PINGS_LOST,92,81,88,8
|
||||
LTEXT "Anon replies: 0",IDC_ANON_ADDR,186,81,72,8
|
||||
LTEXT "Maximum: 0ms",IDC_ICMP_MAX,13,93,73,8
|
||||
DEFPUSHBUTTON "Close",IDOK,212,110,50,14
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_OUTPUT, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 312
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 176
|
||||
END
|
||||
|
||||
IDD_OPTIONS, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 208
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 72
|
||||
END
|
||||
|
||||
IDD_PINGDIALOG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 262
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 124
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AFX_DIALOG_LAYOUT
|
||||
//
|
||||
|
||||
IDD_OUTPUT AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
IDD_OPTIONS AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
#endif // English (Australia) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
109
plugins/NetworkTools/NetworkTools.vcxproj
Normal file
109
plugins/NetworkTools/NetworkTools.vcxproj
Normal file
@@ -0,0 +1,109 @@
|
||||
<?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>{B5E0DA09-EA01-4D5A-A9D6-5B22DB0C306E}</ProjectGuid>
|
||||
<RootNamespace>NetworkTools</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectName>NetworkTools</ProjectName>
|
||||
<WindowsTargetPlatformVersion>10.0.10586.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 Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\Plugins.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_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release32</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug64</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Link>
|
||||
<AdditionalDependencies>iphlpapi.lib;winhttp.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>iphlpapi.dll;winhttp.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Link>
|
||||
<AdditionalDependencies>iphlpapi.lib;winhttp.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>iphlpapi.dll;winhttp.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Link>
|
||||
<AdditionalDependencies>iphlpapi.lib;winhttp.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>iphlpapi.dll;winhttp.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Link>
|
||||
<AdditionalDependencies>iphlpapi.lib;winhttp.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>iphlpapi.dll;winhttp.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.c" />
|
||||
<ClCompile Include="options.c" />
|
||||
<ClCompile Include="output.c" />
|
||||
<ClCompile Include="ping.c" />
|
||||
<ClCompile Include="tracert.c" />
|
||||
<ClCompile Include="whois.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="nettools.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="NetworkTools.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CHANGELOG.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
53
plugins/NetworkTools/NetworkTools.vcxproj.filters
Normal file
53
plugins/NetworkTools/NetworkTools.vcxproj.filters
Normal file
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="output.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ping.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="options.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="tracert.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="whois.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="nettools.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="NetworkTools.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CHANGELOG.txt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
164
plugins/NetworkTools/main.c
Normal file
164
plugins/NetworkTools/main.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Process Hacker Network Tools -
|
||||
* main program
|
||||
*
|
||||
* Copyright (C) 2010-2011 wj32
|
||||
* Copyright (C) 2013 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 "nettools.h"
|
||||
|
||||
PPH_PLUGIN PluginInstance;
|
||||
PH_CALLBACK_REGISTRATION PluginLoadCallbackRegistration;
|
||||
PH_CALLBACK_REGISTRATION PluginShowOptionsCallbackRegistration;
|
||||
PH_CALLBACK_REGISTRATION PluginMenuItemCallbackRegistration;
|
||||
PH_CALLBACK_REGISTRATION NetworkMenuInitializingCallbackRegistration;
|
||||
|
||||
VOID NTAPI ShowOptionsCallback(
|
||||
_In_opt_ PVOID Parameter,
|
||||
_In_opt_ PVOID Context
|
||||
)
|
||||
{
|
||||
DialogBox(
|
||||
PluginInstance->DllBase,
|
||||
MAKEINTRESOURCE(IDD_OPTIONS),
|
||||
(HWND)Parameter,
|
||||
OptionsDlgProc
|
||||
);
|
||||
}
|
||||
|
||||
VOID NTAPI MenuItemCallback(
|
||||
_In_opt_ PVOID Parameter,
|
||||
_In_opt_ PVOID Context
|
||||
)
|
||||
{
|
||||
PPH_PLUGIN_MENU_ITEM menuItem = (PPH_PLUGIN_MENU_ITEM)Parameter;
|
||||
PPH_NETWORK_ITEM networkItem = (PPH_NETWORK_ITEM)menuItem->Context;
|
||||
|
||||
switch (menuItem->Id)
|
||||
{
|
||||
case NETWORK_ACTION_PING:
|
||||
PerformNetworkAction(NETWORK_ACTION_PING, networkItem);
|
||||
break;
|
||||
case NETWORK_ACTION_TRACEROUTE:
|
||||
PerformNetworkAction(NETWORK_ACTION_TRACEROUTE, networkItem);
|
||||
break;
|
||||
case NETWORK_ACTION_WHOIS:
|
||||
PerformNetworkAction(NETWORK_ACTION_WHOIS, networkItem);
|
||||
break;
|
||||
case NETWORK_ACTION_PATHPING:
|
||||
PerformNetworkAction(NETWORK_ACTION_PATHPING, networkItem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VOID NTAPI NetworkMenuInitializingCallback(
|
||||
_In_opt_ PVOID Parameter,
|
||||
_In_opt_ PVOID Context
|
||||
)
|
||||
{
|
||||
PPH_PLUGIN_MENU_INFORMATION menuInfo = (PPH_PLUGIN_MENU_INFORMATION)Parameter;
|
||||
PPH_NETWORK_ITEM networkItem;
|
||||
PPH_EMENU_ITEM toolsMenu;
|
||||
PPH_EMENU_ITEM closeMenuItem;
|
||||
|
||||
if (menuInfo->u.Network.NumberOfNetworkItems == 1)
|
||||
networkItem = menuInfo->u.Network.NetworkItems[0];
|
||||
else
|
||||
networkItem = NULL;
|
||||
|
||||
// Create the Tools menu.
|
||||
toolsMenu = PhPluginCreateEMenuItem(PluginInstance, 0, 0, L"Tools", NULL);
|
||||
PhInsertEMenuItem(toolsMenu, PhPluginCreateEMenuItem(PluginInstance, 0, NETWORK_ACTION_PING, L"Ping", networkItem), -1);
|
||||
PhInsertEMenuItem(toolsMenu, PhPluginCreateEMenuItem(PluginInstance, 0, NETWORK_ACTION_TRACEROUTE, L"Traceroute", networkItem), -1);
|
||||
PhInsertEMenuItem(toolsMenu, PhPluginCreateEMenuItem(PluginInstance, 0, NETWORK_ACTION_WHOIS, L"Whois", networkItem), -1);
|
||||
PhInsertEMenuItem(toolsMenu, PhPluginCreateEMenuItem(PluginInstance, 0, NETWORK_ACTION_PATHPING, L"PathPing", networkItem), -1);
|
||||
|
||||
// Insert the Tools menu into the network menu.
|
||||
closeMenuItem = PhFindEMenuItem(menuInfo->Menu, 0, L"Close", 0);
|
||||
PhInsertEMenuItem(menuInfo->Menu, toolsMenu, closeMenuItem ? PhIndexOfEMenuItem(menuInfo->Menu, closeMenuItem) : 1);
|
||||
|
||||
toolsMenu->Flags |= PH_EMENU_DISABLED;
|
||||
|
||||
if (networkItem)
|
||||
{
|
||||
if (!PhIsNullIpAddress(&networkItem->RemoteEndpoint.Address))
|
||||
{
|
||||
toolsMenu->Flags &= ~PH_EMENU_DISABLED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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_TRACERT_WINDOW_POSITION, L"0,0" },
|
||||
{ ScalableIntegerPairSettingType, SETTING_NAME_TRACERT_WINDOW_SIZE, L"@96|600,365" },
|
||||
{ IntegerPairSettingType, SETTING_NAME_PING_WINDOW_POSITION, L"0,0" },
|
||||
{ ScalableIntegerPairSettingType, SETTING_NAME_PING_WINDOW_SIZE, L"@96|420,250" },
|
||||
{ IntegerSettingType, SETTING_NAME_PING_TIMEOUT, L"3e8" } // 1000 timeout.
|
||||
};
|
||||
|
||||
PluginInstance = PhRegisterPlugin(PLUGIN_NAME, Instance, &info);
|
||||
|
||||
if (!PluginInstance)
|
||||
return FALSE;
|
||||
|
||||
info->DisplayName = L"Network Tools";
|
||||
info->Author = L"dmex, wj32";
|
||||
info->Description = L"Provides ping, traceroute and whois for network connections.";
|
||||
info->Url = L"https://wj32.org/processhacker/forums/viewtopic.php?t=1117";
|
||||
info->HasOptions = TRUE;
|
||||
|
||||
PhRegisterCallback(
|
||||
PhGetPluginCallback(PluginInstance, PluginCallbackShowOptions),
|
||||
ShowOptionsCallback,
|
||||
NULL,
|
||||
&PluginShowOptionsCallbackRegistration
|
||||
);
|
||||
PhRegisterCallback(
|
||||
PhGetPluginCallback(PluginInstance, PluginCallbackMenuItem),
|
||||
MenuItemCallback,
|
||||
NULL,
|
||||
&PluginMenuItemCallbackRegistration
|
||||
);
|
||||
|
||||
PhRegisterCallback(
|
||||
PhGetGeneralCallback(GeneralCallbackNetworkMenuInitializing),
|
||||
NetworkMenuInitializingCallback,
|
||||
NULL,
|
||||
&NetworkMenuInitializingCallbackRegistration
|
||||
);
|
||||
|
||||
PhAddSettings(settings, ARRAYSIZE(settings));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
145
plugins/NetworkTools/nettools.h
Normal file
145
plugins/NetworkTools/nettools.h
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Process Hacker ToolStatus -
|
||||
* toolstatus header
|
||||
*
|
||||
* Copyright (C) 2010-2013 wj32
|
||||
* Copyright (C) 2012-2013 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 NETTOOLS_H
|
||||
#define NETTOOLS_H
|
||||
|
||||
#define CINTERFACE
|
||||
#define COBJMACROS
|
||||
#include <windowsx.h>
|
||||
#include <phdk.h>
|
||||
#include <phappresource.h>
|
||||
#include <workqueue.h>
|
||||
#include <windowsx.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <icmpapi.h>
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
#define PLUGIN_NAME L"ProcessHacker.NetworkTools"
|
||||
#define SETTING_NAME_TRACERT_WINDOW_POSITION (PLUGIN_NAME L".WindowPosition")
|
||||
#define SETTING_NAME_TRACERT_WINDOW_SIZE (PLUGIN_NAME L".WindowSize")
|
||||
#define SETTING_NAME_PING_WINDOW_POSITION (PLUGIN_NAME L".PingWindowPosition")
|
||||
#define SETTING_NAME_PING_WINDOW_SIZE (PLUGIN_NAME L".PingWindowSize")
|
||||
#define SETTING_NAME_PING_TIMEOUT (PLUGIN_NAME L".PingMaxTimeout")
|
||||
|
||||
// ICMP Packet Length: (msdn: IcmpSendEcho2/Icmp6SendEcho2)
|
||||
// The buffer must be large enough to hold at least one ICMP_ECHO_REPLY or ICMPV6_ECHO_REPLY structure
|
||||
// + the number of bytes of data specified in the RequestSize parameter.
|
||||
// This buffer should also be large enough to also hold 8 more bytes of data (the size of an ICMP error message)
|
||||
// + space for an IO_STATUS_BLOCK structure.
|
||||
#define ICMP_BUFFER_SIZE(EchoReplyLength, Buffer) (ULONG)(((EchoReplyLength) + (Buffer)->Length) + 8 + sizeof(IO_STATUS_BLOCK))
|
||||
|
||||
extern PPH_PLUGIN PluginInstance;
|
||||
|
||||
typedef enum _PH_NETWORK_ACTION
|
||||
{
|
||||
NETWORK_ACTION_PING,
|
||||
NETWORK_ACTION_TRACEROUTE,
|
||||
NETWORK_ACTION_WHOIS,
|
||||
NETWORK_ACTION_FINISH,
|
||||
NETWORK_ACTION_PATHPING
|
||||
} PH_NETWORK_ACTION;
|
||||
|
||||
// output
|
||||
#define NTM_RECEIVEDTRACE (WM_APP + NETWORK_ACTION_TRACEROUTE)
|
||||
#define NTM_RECEIVEDWHOIS (WM_APP + NETWORK_ACTION_WHOIS)
|
||||
#define NTM_RECEIVEDFINISH (WM_APP + NETWORK_ACTION_FINISH)
|
||||
|
||||
typedef struct _NETWORK_OUTPUT_CONTEXT
|
||||
{
|
||||
PH_NETWORK_ACTION Action;
|
||||
PH_LAYOUT_MANAGER LayoutManager;
|
||||
PH_WORK_QUEUE PingWorkQueue;
|
||||
PH_GRAPH_STATE PingGraphState;
|
||||
PH_CIRCULAR_BUFFER_ULONG PingHistory;
|
||||
PH_CALLBACK_REGISTRATION ProcessesUpdatedRegistration;
|
||||
|
||||
HWND WindowHandle;
|
||||
HWND ParentHandle;
|
||||
HWND StatusHandle;
|
||||
HWND PingGraphHandle;
|
||||
HWND OutputHandle;
|
||||
HANDLE PipeReadHandle;
|
||||
HANDLE ProcessHandle;
|
||||
HFONT FontHandle;
|
||||
HICON IconHandle;
|
||||
|
||||
ULONG CurrentPingMs;
|
||||
ULONG MaxPingTimeout;
|
||||
ULONG HashFailCount;
|
||||
ULONG UnknownAddrCount;
|
||||
ULONG PingMinMs;
|
||||
ULONG PingMaxMs;
|
||||
ULONG PingSentCount;
|
||||
ULONG PingRecvCount;
|
||||
ULONG PingLossCount;
|
||||
|
||||
PPH_NETWORK_ITEM NetworkItem;
|
||||
PH_IP_ADDRESS IpAddress;
|
||||
WCHAR IpAddressString[INET6_ADDRSTRLEN];
|
||||
} NETWORK_OUTPUT_CONTEXT, *PNETWORK_OUTPUT_CONTEXT;
|
||||
|
||||
NTSTATUS PhNetworkPingDialogThreadStart(
|
||||
_In_ PVOID Parameter
|
||||
);
|
||||
|
||||
VOID PerformNetworkAction(
|
||||
_In_ PH_NETWORK_ACTION Action,
|
||||
_In_ PPH_NETWORK_ITEM NetworkItem
|
||||
);
|
||||
|
||||
NTSTATUS NetworkPingThreadStart(
|
||||
_In_ PVOID Parameter
|
||||
);
|
||||
|
||||
NTSTATUS NetworkTracertThreadStart(
|
||||
_In_ PVOID Parameter
|
||||
);
|
||||
|
||||
NTSTATUS NetworkWhoisThreadStart(
|
||||
_In_ PVOID Parameter
|
||||
);
|
||||
|
||||
VOID NTAPI ShowOptionsCallback(
|
||||
_In_opt_ PVOID Parameter,
|
||||
_In_opt_ PVOID Context
|
||||
);
|
||||
|
||||
INT_PTR CALLBACK NetworkOutputDlgProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
);
|
||||
|
||||
INT_PTR CALLBACK OptionsDlgProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
);
|
||||
|
||||
#endif
|
||||
62
plugins/NetworkTools/options.c
Normal file
62
plugins/NetworkTools/options.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Process Hacker Network Tools -
|
||||
* options dialog
|
||||
*
|
||||
* Copyright (C) 2010-2013 wj32
|
||||
* Copyright (C) 2012-2013 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 "nettools.h"
|
||||
|
||||
INT_PTR CALLBACK OptionsDlgProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
SetDlgItemInt(hwndDlg, IDC_MAXTIMEOUTTEXT, PhGetIntegerSetting(SETTING_NAME_PING_TIMEOUT), FALSE);
|
||||
}
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
{
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDCANCEL:
|
||||
EndDialog(hwndDlg, IDCANCEL);
|
||||
break;
|
||||
case IDOK:
|
||||
{
|
||||
ULONG maxPingTimeout = GetDlgItemInt(hwndDlg, IDC_MAXTIMEOUTTEXT, NULL, FALSE);
|
||||
|
||||
PhSetIntegerSetting(SETTING_NAME_PING_TIMEOUT, maxPingTimeout);
|
||||
|
||||
EndDialog(hwndDlg, IDOK);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
423
plugins/NetworkTools/output.c
Normal file
423
plugins/NetworkTools/output.c
Normal file
@@ -0,0 +1,423 @@
|
||||
/*
|
||||
* Process Hacker Network Tools -
|
||||
* output dialog
|
||||
*
|
||||
* Copyright (C) 2010-2015 wj32
|
||||
* Copyright (C) 2012-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 "nettools.h"
|
||||
|
||||
static RECT MinimumSize = { -1, -1, -1, -1 };
|
||||
|
||||
INT_PTR CALLBACK NetworkOutputDlgProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
)
|
||||
{
|
||||
PNETWORK_OUTPUT_CONTEXT context;
|
||||
|
||||
if (uMsg == WM_INITDIALOG)
|
||||
{
|
||||
context = (PNETWORK_OUTPUT_CONTEXT)lParam;
|
||||
SetProp(hwndDlg, L"Context", (HANDLE)context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context = (PNETWORK_OUTPUT_CONTEXT)GetProp(hwndDlg, L"Context");
|
||||
|
||||
if (uMsg == WM_DESTROY)
|
||||
{
|
||||
PhSaveWindowPlacementToSetting(SETTING_NAME_TRACERT_WINDOW_POSITION, SETTING_NAME_TRACERT_WINDOW_SIZE, hwndDlg);
|
||||
PhDeleteLayoutManager(&context->LayoutManager);
|
||||
|
||||
if (context->ProcessHandle)
|
||||
{
|
||||
// Terminate the child process.
|
||||
PhTerminateProcess(context->ProcessHandle, STATUS_SUCCESS);
|
||||
|
||||
// Close the child process handle.
|
||||
NtClose(context->ProcessHandle);
|
||||
}
|
||||
|
||||
// Close the pipe handle.
|
||||
if (context->PipeReadHandle)
|
||||
NtClose(context->PipeReadHandle);
|
||||
|
||||
RemoveProp(hwndDlg, L"Context");
|
||||
PhFree(context);
|
||||
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
PH_RECTANGLE windowRectangle;
|
||||
|
||||
context->WindowHandle = hwndDlg;
|
||||
context->OutputHandle = GetDlgItem(hwndDlg, IDC_NETOUTPUTEDIT);
|
||||
|
||||
PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
|
||||
PhAddLayoutItem(&context->LayoutManager, context->OutputHandle, NULL, PH_ANCHOR_ALL);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_MORE_INFO), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
|
||||
|
||||
windowRectangle.Position = PhGetIntegerPairSetting(SETTING_NAME_TRACERT_WINDOW_POSITION);
|
||||
windowRectangle.Size = PhGetScalableIntegerPairSetting(SETTING_NAME_TRACERT_WINDOW_SIZE, TRUE).Pair;
|
||||
|
||||
if (MinimumSize.left == -1)
|
||||
{
|
||||
RECT rect;
|
||||
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = 190;
|
||||
rect.bottom = 120;
|
||||
MapDialogRect(hwndDlg, &rect);
|
||||
MinimumSize = rect;
|
||||
MinimumSize.left = 0;
|
||||
}
|
||||
|
||||
// Check for first-run default position.
|
||||
if (windowRectangle.Position.X == 0 || windowRectangle.Position.Y == 0)
|
||||
{
|
||||
PhCenterWindow(hwndDlg, GetParent(hwndDlg));
|
||||
}
|
||||
else
|
||||
{
|
||||
PhLoadWindowPlacementFromSetting(SETTING_NAME_TRACERT_WINDOW_POSITION, SETTING_NAME_TRACERT_WINDOW_SIZE, hwndDlg);
|
||||
}
|
||||
|
||||
if (context->IpAddress.Type == PH_IPV4_NETWORK_TYPE)
|
||||
{
|
||||
RtlIpv4AddressToString(&context->IpAddress.InAddr, context->IpAddressString);
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlIpv6AddressToString(&context->IpAddress.In6Addr, context->IpAddressString);
|
||||
}
|
||||
|
||||
switch (context->Action)
|
||||
{
|
||||
case NETWORK_ACTION_TRACEROUTE:
|
||||
{
|
||||
HANDLE dialogThread = INVALID_HANDLE_VALUE;
|
||||
|
||||
Static_SetText(context->WindowHandle,
|
||||
PhaFormatString(L"Tracing route to %s...", context->IpAddressString)->Buffer
|
||||
);
|
||||
|
||||
if (dialogThread = PhCreateThread(0, NetworkTracertThreadStart, (PVOID)context))
|
||||
NtClose(dialogThread);
|
||||
}
|
||||
break;
|
||||
case NETWORK_ACTION_WHOIS:
|
||||
{
|
||||
HANDLE dialogThread = INVALID_HANDLE_VALUE;
|
||||
|
||||
Static_SetText(context->WindowHandle,
|
||||
PhaFormatString(L"Whois %s...", context->IpAddressString)->Buffer
|
||||
);
|
||||
|
||||
ShowWindow(GetDlgItem(hwndDlg, IDC_MORE_INFO), SW_SHOW);
|
||||
|
||||
if (dialogThread = PhCreateThread(0, NetworkWhoisThreadStart, (PVOID)context))
|
||||
NtClose(dialogThread);
|
||||
}
|
||||
break;
|
||||
case NETWORK_ACTION_PATHPING:
|
||||
{
|
||||
HANDLE dialogThread = INVALID_HANDLE_VALUE;
|
||||
|
||||
Static_SetText(context->WindowHandle,
|
||||
PhaFormatString(L"Pathing route to %s...", context->IpAddressString)->Buffer
|
||||
);
|
||||
|
||||
if (dialogThread = PhCreateThread(0, NetworkTracertThreadStart, (PVOID)context))
|
||||
NtClose(dialogThread);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
{
|
||||
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||
{
|
||||
case IDCANCEL:
|
||||
case IDOK:
|
||||
DestroyWindow(hwndDlg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_SIZE:
|
||||
PhLayoutManagerLayout(&context->LayoutManager);
|
||||
break;
|
||||
case WM_SIZING:
|
||||
PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom);
|
||||
break;
|
||||
case WM_CTLCOLORDLG:
|
||||
case WM_CTLCOLORSTATIC:
|
||||
{
|
||||
HDC hDC = (HDC)wParam;
|
||||
HWND hwndChild = (HWND)lParam;
|
||||
|
||||
// Check if old graph colors are enabled.
|
||||
if (!PhGetIntegerSetting(L"GraphColorMode"))
|
||||
break;
|
||||
|
||||
// Check for our edit control and change the color.
|
||||
if (hwndChild == context->OutputHandle)
|
||||
{
|
||||
// Set a transparent background for the control backcolor.
|
||||
//SetBkMode(hDC, TRANSPARENT);
|
||||
|
||||
// Set the Edit control background.
|
||||
SetBkColor(hDC, RGB(0x0, 0x0, 0x0));
|
||||
|
||||
// Set text color as the Green PH graph text color.
|
||||
SetTextColor(hDC, RGB(124, 252, 0));
|
||||
|
||||
// Set a black control backcolor.
|
||||
return (INT_PTR)GetStockBrush(BLACK_BRUSH);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
switch (((LPNMHDR)lParam)->code)
|
||||
{
|
||||
case NM_CLICK:
|
||||
case NM_RETURN:
|
||||
{
|
||||
PNMLINK syslink = (PNMLINK)lParam;
|
||||
|
||||
if (syslink->hdr.idFrom == IDC_MORE_INFO)
|
||||
{
|
||||
PhShellExecute(
|
||||
PhMainWndHandle,
|
||||
PhaConcatStrings2(L"http://wq.apnic.net/apnic-bin/whois.pl?searchtext=", context->IpAddressString)->Buffer,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NTM_RECEIVEDTRACE:
|
||||
{
|
||||
OEM_STRING inputString;
|
||||
UNICODE_STRING convertedString;
|
||||
PH_STRING_BUILDER receivedString;
|
||||
|
||||
if (wParam != 0)
|
||||
{
|
||||
inputString.Buffer = (PCHAR)lParam;
|
||||
inputString.Length = (USHORT)wParam;
|
||||
|
||||
if (NT_SUCCESS(RtlOemStringToUnicodeString(&convertedString, &inputString, TRUE)))
|
||||
{
|
||||
PPH_STRING windowText = NULL;
|
||||
|
||||
PhInitializeStringBuilder(&receivedString, PAGE_SIZE);
|
||||
|
||||
// Get the current output text.
|
||||
windowText = PhGetWindowText(context->OutputHandle);
|
||||
|
||||
// Append the current output text to the New string.
|
||||
if (!PhIsNullOrEmptyString(windowText))
|
||||
PhAppendStringBuilder(&receivedString, &windowText->sr);
|
||||
|
||||
PhAppendFormatStringBuilder(&receivedString, L"%s", convertedString.Buffer);
|
||||
|
||||
// Remove leading newlines.
|
||||
if (receivedString.String->Length >= 2 * 2 &&
|
||||
receivedString.String->Buffer[0] == '\r' &&
|
||||
receivedString.String->Buffer[1] == '\n')
|
||||
{
|
||||
PhRemoveStringBuilder(&receivedString, 0, 2);
|
||||
}
|
||||
|
||||
SetWindowText(context->OutputHandle, receivedString.String->Buffer);
|
||||
SendMessage(
|
||||
context->OutputHandle,
|
||||
EM_SETSEL,
|
||||
receivedString.String->Length / 2 - 1,
|
||||
receivedString.String->Length / 2 - 1
|
||||
);
|
||||
SendMessage(context->OutputHandle, WM_VSCROLL, SB_BOTTOM, 0);
|
||||
|
||||
PhDereferenceObject(windowText);
|
||||
PhDeleteStringBuilder(&receivedString);
|
||||
RtlFreeUnicodeString(&convertedString);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NTM_RECEIVEDWHOIS:
|
||||
{
|
||||
OEM_STRING inputString;
|
||||
UNICODE_STRING convertedString;
|
||||
PH_STRING_BUILDER receivedString;
|
||||
|
||||
if (lParam != 0)
|
||||
{
|
||||
inputString.Buffer = (PCHAR)lParam;
|
||||
inputString.Length = (USHORT)wParam;
|
||||
|
||||
if (NT_SUCCESS(RtlOemStringToUnicodeString(&convertedString, &inputString, TRUE)))
|
||||
{
|
||||
USHORT i;
|
||||
|
||||
PhInitializeStringBuilder(&receivedString, PAGE_SIZE);
|
||||
|
||||
// Convert carriage returns.
|
||||
for (i = 0; i < convertedString.Length; i++)
|
||||
{
|
||||
if (convertedString.Buffer[i] == '\n')
|
||||
{
|
||||
PhAppendStringBuilder2(&receivedString, L"\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
PhAppendCharStringBuilder(&receivedString, convertedString.Buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove leading newlines.
|
||||
if (receivedString.String->Length >= 2 * 2 &&
|
||||
receivedString.String->Buffer[0] == '\r' &&
|
||||
receivedString.String->Buffer[1] == '\n')
|
||||
{
|
||||
PhRemoveStringBuilder(&receivedString, 0, 2);
|
||||
}
|
||||
|
||||
SetWindowText(context->OutputHandle, receivedString.String->Buffer);
|
||||
SendMessage(
|
||||
context->OutputHandle,
|
||||
EM_SETSEL,
|
||||
receivedString.String->Length / 2 - 1,
|
||||
receivedString.String->Length / 2 - 1
|
||||
);
|
||||
SendMessage(context->OutputHandle, WM_VSCROLL, SB_TOP, 0);
|
||||
|
||||
PhDeleteStringBuilder(&receivedString);
|
||||
RtlFreeUnicodeString(&convertedString);
|
||||
}
|
||||
|
||||
PhFree((PVOID)lParam);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NTM_RECEIVEDFINISH:
|
||||
{
|
||||
PPH_STRING windowText = PhGetWindowText(context->WindowHandle);
|
||||
|
||||
if (windowText)
|
||||
{
|
||||
Static_SetText(
|
||||
context->WindowHandle,
|
||||
PhaFormatString(L"%s Finished.", windowText->Buffer)->Buffer
|
||||
);
|
||||
PhDereferenceObject(windowText);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NTSTATUS PhNetworkOutputDialogThreadStart(
|
||||
_In_ PVOID Parameter
|
||||
)
|
||||
{
|
||||
BOOL result;
|
||||
MSG message;
|
||||
HWND windowHandle;
|
||||
PH_AUTO_POOL autoPool;
|
||||
PNETWORK_OUTPUT_CONTEXT context = (PNETWORK_OUTPUT_CONTEXT)Parameter;
|
||||
|
||||
PhInitializeAutoPool(&autoPool);
|
||||
|
||||
windowHandle = CreateDialogParam(
|
||||
(HINSTANCE)PluginInstance->DllBase,
|
||||
MAKEINTRESOURCE(IDD_OUTPUT),
|
||||
PhMainWndHandle,
|
||||
NetworkOutputDlgProc,
|
||||
(LPARAM)Parameter
|
||||
);
|
||||
|
||||
ShowWindow(windowHandle, SW_SHOW);
|
||||
SetForegroundWindow(windowHandle);
|
||||
|
||||
while (result = GetMessage(&message, NULL, 0, 0))
|
||||
{
|
||||
if (result == -1)
|
||||
break;
|
||||
|
||||
if (!IsDialogMessage(context->WindowHandle, &message))
|
||||
{
|
||||
TranslateMessage(&message);
|
||||
DispatchMessage(&message);
|
||||
}
|
||||
|
||||
PhDrainAutoPool(&autoPool);
|
||||
}
|
||||
|
||||
PhDeleteAutoPool(&autoPool);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID PerformNetworkAction(
|
||||
_In_ PH_NETWORK_ACTION Action,
|
||||
_In_ PPH_NETWORK_ITEM NetworkItem
|
||||
)
|
||||
{
|
||||
HANDLE dialogThread = INVALID_HANDLE_VALUE;
|
||||
PNETWORK_OUTPUT_CONTEXT context;
|
||||
|
||||
context = (PNETWORK_OUTPUT_CONTEXT)PhAllocate(sizeof(NETWORK_OUTPUT_CONTEXT));
|
||||
memset(context, 0, sizeof(NETWORK_OUTPUT_CONTEXT));
|
||||
|
||||
context->Action = Action;
|
||||
context->NetworkItem = NetworkItem;
|
||||
context->IpAddress = NetworkItem->RemoteEndpoint.Address;
|
||||
|
||||
if (context->Action == NETWORK_ACTION_PING)
|
||||
{
|
||||
if (dialogThread = PhCreateThread(0, PhNetworkPingDialogThreadStart, (PVOID)context))
|
||||
NtClose(dialogThread);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dialogThread = PhCreateThread(0, PhNetworkOutputDialogThreadStart, (PVOID)context))
|
||||
NtClose(dialogThread);
|
||||
}
|
||||
}
|
||||
757
plugins/NetworkTools/ping.c
Normal file
757
plugins/NetworkTools/ping.c
Normal file
@@ -0,0 +1,757 @@
|
||||
/*
|
||||
* Process Hacker Network Tools -
|
||||
* Ping dialog
|
||||
*
|
||||
* 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 "nettools.h"
|
||||
|
||||
#define WM_PING_UPDATE (WM_APP + 151)
|
||||
|
||||
static RECT NormalGraphTextMargin = { 5, 5, 5, 5 };
|
||||
static RECT NormalGraphTextPadding = { 3, 3, 3, 3 };
|
||||
|
||||
HFONT InitializeFont(
|
||||
_In_ HWND hwnd
|
||||
)
|
||||
{
|
||||
LOGFONT logFont;
|
||||
|
||||
// Create the font handle
|
||||
if (SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &logFont, 0))
|
||||
{
|
||||
HDC hdc;
|
||||
|
||||
if (hdc = GetDC(hwnd))
|
||||
{
|
||||
HFONT fontHandle = CreateFont(
|
||||
-MulDiv(-15, GetDeviceCaps(hdc, LOGPIXELSY), 72),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
FW_MEDIUM,
|
||||
FALSE,
|
||||
FALSE,
|
||||
FALSE,
|
||||
ANSI_CHARSET,
|
||||
OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS,
|
||||
CLEARTYPE_QUALITY | ANTIALIASED_QUALITY,
|
||||
DEFAULT_PITCH,
|
||||
logFont.lfFaceName
|
||||
);
|
||||
|
||||
SendMessage(hwnd, WM_SETFONT, (WPARAM)fontHandle, TRUE);
|
||||
|
||||
ReleaseDC(hwnd, hdc);
|
||||
|
||||
return fontHandle;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VOID NetworkPingUpdateGraph(
|
||||
_In_ PNETWORK_OUTPUT_CONTEXT Context
|
||||
)
|
||||
{
|
||||
Context->PingGraphState.Valid = FALSE;
|
||||
Context->PingGraphState.TooltipIndex = -1;
|
||||
Graph_MoveGrid(Context->PingGraphHandle, 1);
|
||||
Graph_Draw(Context->PingGraphHandle);
|
||||
Graph_UpdateTooltip(Context->PingGraphHandle);
|
||||
InvalidateRect(Context->PingGraphHandle, NULL, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Ansi string using format specifiers.
|
||||
*
|
||||
* \param Format The format-control string.
|
||||
* \param ArgPtr A pointer to the list of arguments.
|
||||
*/
|
||||
PPH_BYTES FormatAnsiString_V(
|
||||
_In_ _Printf_format_string_ PSTR Format,
|
||||
_In_ va_list ArgPtr
|
||||
)
|
||||
{
|
||||
PPH_BYTES string;
|
||||
int length;
|
||||
|
||||
length = _vscprintf(Format, ArgPtr);
|
||||
|
||||
if (length == -1)
|
||||
return NULL;
|
||||
|
||||
string = PhCreateBytesEx(NULL, length * sizeof(CHAR));
|
||||
|
||||
_vsnprintf(
|
||||
string->Buffer,
|
||||
length,
|
||||
Format, ArgPtr
|
||||
);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Ansi string using format specifiers.
|
||||
*
|
||||
* \param Format The format-control string.
|
||||
*/
|
||||
PPH_BYTES FormatAnsiString(
|
||||
_In_ _Printf_format_string_ PSTR Format,
|
||||
...
|
||||
)
|
||||
{
|
||||
va_list argptr;
|
||||
|
||||
va_start(argptr, Format);
|
||||
|
||||
return FormatAnsiString_V(Format, argptr);
|
||||
}
|
||||
|
||||
NTSTATUS NetworkPingThreadStart(
|
||||
_In_ PVOID Parameter
|
||||
)
|
||||
{
|
||||
HANDLE icmpHandle = INVALID_HANDLE_VALUE;
|
||||
ULONG icmpCurrentPingMs = 0;
|
||||
ULONG icmpCurrentPingTtl = 0;
|
||||
ULONG icmpReplyCount = 0;
|
||||
ULONG icmpReplyLength = 0;
|
||||
PVOID icmpReplyBuffer = NULL;
|
||||
PPH_STRING phVersion = NULL;
|
||||
PPH_BYTES icmpEchoBuffer = NULL;
|
||||
IP_OPTION_INFORMATION pingOptions =
|
||||
{
|
||||
255, // Time To Live
|
||||
0, // Type Of Service
|
||||
IP_FLAG_DF, // IP header flags
|
||||
0 // Size of options data
|
||||
};
|
||||
|
||||
PNETWORK_OUTPUT_CONTEXT context = (PNETWORK_OUTPUT_CONTEXT)Parameter;
|
||||
|
||||
__try
|
||||
{
|
||||
// Query PH version.
|
||||
if ((phVersion = PhGetPhVersion()) == NULL)
|
||||
__leave;
|
||||
|
||||
// Create ICMP echo buffer.
|
||||
if ((icmpEchoBuffer = FormatAnsiString("processhacker_%S_0x0D06F00D_x1", phVersion->Buffer)) == NULL)
|
||||
__leave;
|
||||
|
||||
if (context->IpAddress.Type == PH_IPV6_NETWORK_TYPE)
|
||||
{
|
||||
SOCKADDR_IN6 icmp6LocalAddr = { 0 };
|
||||
SOCKADDR_IN6 icmp6RemoteAddr = { 0 };
|
||||
PICMPV6_ECHO_REPLY icmp6ReplyStruct = NULL;
|
||||
|
||||
// Create ICMPv6 handle.
|
||||
if ((icmpHandle = Icmp6CreateFile()) == INVALID_HANDLE_VALUE)
|
||||
__leave;
|
||||
|
||||
// Set Local IPv6-ANY address.
|
||||
icmp6LocalAddr.sin6_addr = in6addr_any;
|
||||
icmp6LocalAddr.sin6_family = AF_INET6;
|
||||
|
||||
// Set Remote IPv6 address.
|
||||
icmp6RemoteAddr.sin6_addr = context->IpAddress.In6Addr;
|
||||
icmp6RemoteAddr.sin6_port = _byteswap_ushort((USHORT)context->NetworkItem->RemoteEndpoint.Port);
|
||||
|
||||
// Allocate ICMPv6 message.
|
||||
icmpReplyLength = ICMP_BUFFER_SIZE(sizeof(ICMPV6_ECHO_REPLY), icmpEchoBuffer);
|
||||
icmpReplyBuffer = PhAllocate(icmpReplyLength);
|
||||
memset(icmpReplyBuffer, 0, icmpReplyLength);
|
||||
|
||||
InterlockedIncrement(&context->PingSentCount);
|
||||
|
||||
// Send ICMPv6 ping...
|
||||
icmpReplyCount = Icmp6SendEcho2(
|
||||
icmpHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&icmp6LocalAddr,
|
||||
&icmp6RemoteAddr,
|
||||
icmpEchoBuffer->Buffer,
|
||||
(USHORT)icmpEchoBuffer->Length,
|
||||
&pingOptions,
|
||||
icmpReplyBuffer,
|
||||
icmpReplyLength,
|
||||
context->MaxPingTimeout
|
||||
);
|
||||
|
||||
icmp6ReplyStruct = (PICMPV6_ECHO_REPLY)icmpReplyBuffer;
|
||||
if (icmpReplyCount > 0 && icmp6ReplyStruct)
|
||||
{
|
||||
BOOLEAN icmpPacketSignature = FALSE;
|
||||
|
||||
if (icmp6ReplyStruct->Status != IP_SUCCESS)
|
||||
{
|
||||
InterlockedIncrement(&context->PingLossCount);
|
||||
}
|
||||
|
||||
if (_memicmp(
|
||||
icmp6ReplyStruct->Address.sin6_addr,
|
||||
context->IpAddress.In6Addr.u.Word,
|
||||
sizeof(icmp6ReplyStruct->Address.sin6_addr)
|
||||
) != 0)
|
||||
{
|
||||
InterlockedIncrement(&context->UnknownAddrCount);
|
||||
}
|
||||
|
||||
//if (icmp6ReplyStruct->DataSize == icmpEchoBuffer->MaximumLength)
|
||||
//{
|
||||
// icmpPacketSignature = (_memicmp(
|
||||
// icmpEchoBuffer->Buffer,
|
||||
// icmp6ReplyStruct->Data,
|
||||
// icmp6ReplyStruct->DataSize
|
||||
// ) == 0);
|
||||
//}
|
||||
|
||||
//if (icmpPacketSignature != TRUE)
|
||||
//{
|
||||
// InterlockedIncrement(&context->HashFailCount);
|
||||
//}
|
||||
|
||||
icmpCurrentPingMs = icmp6ReplyStruct->RoundTripTime;
|
||||
//icmpCurrentPingTtl = icmp6ReplyStruct->Options.Ttl;
|
||||
}
|
||||
else
|
||||
{
|
||||
InterlockedIncrement(&context->PingLossCount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IPAddr icmpLocalAddr = 0;
|
||||
IPAddr icmpRemoteAddr = 0;
|
||||
PICMP_ECHO_REPLY icmpReplyStruct = NULL;
|
||||
|
||||
// Create ICMPv4 handle.
|
||||
if ((icmpHandle = IcmpCreateFile()) == INVALID_HANDLE_VALUE)
|
||||
__leave;
|
||||
|
||||
// Set Local IPv4-ANY address.
|
||||
icmpLocalAddr = in4addr_any.s_addr;
|
||||
|
||||
// Set Remote IPv4 address.
|
||||
icmpRemoteAddr = context->IpAddress.InAddr.s_addr;
|
||||
|
||||
// Allocate ICMPv4 message.
|
||||
icmpReplyLength = ICMP_BUFFER_SIZE(sizeof(ICMP_ECHO_REPLY), icmpEchoBuffer);
|
||||
icmpReplyBuffer = PhAllocate(icmpReplyLength);
|
||||
memset(icmpReplyBuffer, 0, icmpReplyLength);
|
||||
|
||||
InterlockedIncrement(&context->PingSentCount);
|
||||
|
||||
// Send ICMPv4 ping...
|
||||
//if (WindowsVersion > WINDOWS_VISTA)
|
||||
//{
|
||||
// // Vista SP1 and up we can specify the source address:
|
||||
// icmpReplyCount = IcmpSendEcho2Ex(
|
||||
// icmpHandle,
|
||||
// NULL,
|
||||
// NULL,
|
||||
// NULL,
|
||||
// icmpLocalAddr,
|
||||
// icmpRemoteAddr,
|
||||
// icmpEchoBuffer->Buffer,
|
||||
// icmpEchoBuffer->MaximumLength,
|
||||
// &pingOptions,
|
||||
// icmpReplyBuffer,
|
||||
// icmpReplyLength,
|
||||
// context->MaxPingTimeout
|
||||
// );
|
||||
//}
|
||||
|
||||
icmpReplyCount = IcmpSendEcho2(
|
||||
icmpHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
icmpRemoteAddr,
|
||||
icmpEchoBuffer->Buffer,
|
||||
(USHORT)icmpEchoBuffer->Length,
|
||||
&pingOptions,
|
||||
icmpReplyBuffer,
|
||||
icmpReplyLength,
|
||||
context->MaxPingTimeout
|
||||
);
|
||||
|
||||
icmpReplyStruct = (PICMP_ECHO_REPLY)icmpReplyBuffer;
|
||||
|
||||
if (icmpReplyStruct && icmpReplyCount > 0)
|
||||
{
|
||||
BOOLEAN icmpPacketSignature = FALSE;
|
||||
|
||||
if (icmpReplyStruct->Status != IP_SUCCESS)
|
||||
{
|
||||
InterlockedIncrement(&context->PingLossCount);
|
||||
}
|
||||
|
||||
if (icmpReplyStruct->Address != context->IpAddress.InAddr.s_addr)
|
||||
{
|
||||
InterlockedIncrement(&context->UnknownAddrCount);
|
||||
}
|
||||
|
||||
if (icmpReplyStruct->DataSize == icmpEchoBuffer->Length)
|
||||
{
|
||||
icmpPacketSignature = (_memicmp(
|
||||
icmpEchoBuffer->Buffer,
|
||||
icmpReplyStruct->Data,
|
||||
icmpReplyStruct->DataSize
|
||||
) == 0);
|
||||
}
|
||||
|
||||
icmpCurrentPingMs = icmpReplyStruct->RoundTripTime;
|
||||
icmpCurrentPingTtl = icmpReplyStruct->Options.Ttl;
|
||||
|
||||
if (!icmpPacketSignature)
|
||||
{
|
||||
InterlockedIncrement(&context->HashFailCount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InterlockedIncrement(&context->PingLossCount);
|
||||
}
|
||||
}
|
||||
|
||||
InterlockedIncrement(&context->PingRecvCount);
|
||||
|
||||
if (context->PingMinMs == 0 || icmpCurrentPingMs < context->PingMinMs)
|
||||
context->PingMinMs = icmpCurrentPingMs;
|
||||
if (icmpCurrentPingMs > context->PingMaxMs)
|
||||
context->PingMaxMs = icmpCurrentPingMs;
|
||||
|
||||
context->CurrentPingMs = icmpCurrentPingMs;
|
||||
|
||||
PhAddItemCircularBuffer_ULONG(&context->PingHistory, icmpCurrentPingMs);
|
||||
}
|
||||
__finally
|
||||
{
|
||||
if (phVersion)
|
||||
{
|
||||
PhDereferenceObject(phVersion);
|
||||
}
|
||||
|
||||
if (icmpEchoBuffer)
|
||||
{
|
||||
PhDereferenceObject(icmpEchoBuffer);
|
||||
}
|
||||
|
||||
if (icmpHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
IcmpCloseHandle(icmpHandle);
|
||||
}
|
||||
|
||||
if (icmpReplyBuffer)
|
||||
{
|
||||
PhFree(icmpReplyBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
PostMessage(context->WindowHandle, WM_PING_UPDATE, 0, 0);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID NTAPI NetworkPingUpdateHandler(
|
||||
_In_opt_ PVOID Parameter,
|
||||
_In_opt_ PVOID Context
|
||||
)
|
||||
{
|
||||
PNETWORK_OUTPUT_CONTEXT context = (PNETWORK_OUTPUT_CONTEXT)Context;
|
||||
|
||||
// Queue up the next ping into our work queue...
|
||||
PhQueueItemWorkQueue(
|
||||
&context->PingWorkQueue,
|
||||
NetworkPingThreadStart,
|
||||
(PVOID)context
|
||||
);
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK NetworkPingWndProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
)
|
||||
{
|
||||
PNETWORK_OUTPUT_CONTEXT context = NULL;
|
||||
|
||||
if (uMsg == WM_INITDIALOG)
|
||||
{
|
||||
context = (PNETWORK_OUTPUT_CONTEXT)lParam;
|
||||
SetProp(hwndDlg, L"Context", (HANDLE)context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context = (PNETWORK_OUTPUT_CONTEXT)GetProp(hwndDlg, L"Context");
|
||||
}
|
||||
|
||||
if (context == NULL)
|
||||
return FALSE;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
PH_RECTANGLE windowRectangle;
|
||||
PPH_LAYOUT_ITEM panelItem;
|
||||
|
||||
// We have already set the group boxes to have WS_EX_TRANSPARENT to fix
|
||||
// the drawing issue that arises when using WS_CLIPCHILDREN. However
|
||||
// in removing the flicker from the graphs the group boxes will now flicker.
|
||||
// It's a good tradeoff since no one stares at the group boxes.
|
||||
PhSetWindowStyle(hwndDlg, WS_CLIPCHILDREN, WS_CLIPCHILDREN);
|
||||
|
||||
context->WindowHandle = hwndDlg;
|
||||
context->ParentHandle = GetParent(hwndDlg);
|
||||
context->StatusHandle = GetDlgItem(hwndDlg, IDC_MAINTEXT);
|
||||
context->MaxPingTimeout = PhGetIntegerSetting(SETTING_NAME_PING_TIMEOUT);
|
||||
|
||||
windowRectangle.Position = PhGetIntegerPairSetting(SETTING_NAME_PING_WINDOW_POSITION);
|
||||
windowRectangle.Size = PhGetScalableIntegerPairSetting(SETTING_NAME_PING_WINDOW_SIZE, TRUE).Pair;
|
||||
|
||||
// Create the font handle.
|
||||
context->FontHandle = InitializeFont(context->StatusHandle);
|
||||
|
||||
// Create the graph control.
|
||||
context->PingGraphHandle = CreateWindow(
|
||||
PH_GRAPH_CLASSNAME,
|
||||
NULL,
|
||||
WS_VISIBLE | WS_CHILD | WS_BORDER,
|
||||
0,
|
||||
0,
|
||||
3,
|
||||
3,
|
||||
hwndDlg,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
Graph_SetTooltip(context->PingGraphHandle, TRUE);
|
||||
|
||||
// Load the Process Hacker icon.
|
||||
context->IconHandle = (HICON)LoadImage(
|
||||
NtCurrentPeb()->ImageBaseAddress,
|
||||
MAKEINTRESOURCE(PHAPP_IDI_PROCESSHACKER),
|
||||
IMAGE_ICON,
|
||||
GetSystemMetrics(SM_CXICON),
|
||||
GetSystemMetrics(SM_CYICON),
|
||||
LR_SHARED
|
||||
);
|
||||
// Set window icon.
|
||||
if (context->IconHandle)
|
||||
SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)context->IconHandle);
|
||||
|
||||
// Initialize the WorkQueue with a maximum of 20 threads (fix pinging slow-links with a high interval update).
|
||||
PhInitializeWorkQueue(&context->PingWorkQueue, 0, 20, 5000);
|
||||
PhInitializeGraphState(&context->PingGraphState);
|
||||
PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
|
||||
PhInitializeCircularBuffer_ULONG(&context->PingHistory, PhGetIntegerSetting(L"SampleCount"));
|
||||
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_ICMP_PANEL), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_ICMP_AVG), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_ICMP_MIN), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_ICMP_MAX), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_PINGS_SENT), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_PINGS_LOST), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_BAD_HASH), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_ANON_ADDR), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
|
||||
panelItem = PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_PING_LAYOUT), NULL, PH_ANCHOR_ALL);
|
||||
PhAddLayoutItemEx(&context->LayoutManager, context->PingGraphHandle, NULL, PH_ANCHOR_ALL, panelItem->Margin);
|
||||
|
||||
// Load window settings.
|
||||
if (windowRectangle.Position.X == 0 || windowRectangle.Position.Y == 0)
|
||||
PhCenterWindow(hwndDlg, GetParent(hwndDlg));
|
||||
else
|
||||
{
|
||||
PhLoadWindowPlacementFromSetting(SETTING_NAME_PING_WINDOW_POSITION, SETTING_NAME_PING_WINDOW_SIZE, hwndDlg);
|
||||
}
|
||||
|
||||
// Initialize window layout.
|
||||
PhLayoutManagerLayout(&context->LayoutManager);
|
||||
|
||||
// Convert IP Address to string format.
|
||||
if (context->IpAddress.Type == PH_IPV4_NETWORK_TYPE)
|
||||
{
|
||||
RtlIpv4AddressToString(&context->IpAddress.InAddr, context->IpAddressString);
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlIpv6AddressToString(&context->IpAddress.In6Addr, context->IpAddressString);
|
||||
}
|
||||
|
||||
SetWindowText(hwndDlg, PhaFormatString(L"Ping %s", context->IpAddressString)->Buffer);
|
||||
SetWindowText(context->StatusHandle, PhaFormatString(L"Pinging %s with 32 bytes of data:", context->IpAddressString)->Buffer);
|
||||
|
||||
PhRegisterCallback(
|
||||
&PhProcessesUpdatedEvent,
|
||||
NetworkPingUpdateHandler,
|
||||
context,
|
||||
&context->ProcessesUpdatedRegistration
|
||||
);
|
||||
}
|
||||
return TRUE;
|
||||
case WM_COMMAND:
|
||||
{
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDCANCEL:
|
||||
case IDOK:
|
||||
DestroyWindow(hwndDlg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
{
|
||||
PhUnregisterCallback(
|
||||
&PhProcessesUpdatedEvent,
|
||||
&context->ProcessesUpdatedRegistration
|
||||
);
|
||||
|
||||
PhSaveWindowPlacementToSetting(
|
||||
SETTING_NAME_PING_WINDOW_POSITION,
|
||||
SETTING_NAME_PING_WINDOW_SIZE,
|
||||
hwndDlg
|
||||
);
|
||||
|
||||
if (context->PingGraphHandle)
|
||||
DestroyWindow(context->PingGraphHandle);
|
||||
|
||||
if (context->IconHandle)
|
||||
DestroyIcon(context->IconHandle);
|
||||
|
||||
if (context->FontHandle)
|
||||
DeleteObject(context->FontHandle);
|
||||
|
||||
PhDeleteWorkQueue(&context->PingWorkQueue);
|
||||
PhDeleteGraphState(&context->PingGraphState);
|
||||
PhDeleteLayoutManager(&context->LayoutManager);
|
||||
|
||||
RemoveProp(hwndDlg, L"Context");
|
||||
PhFree(context);
|
||||
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
break;
|
||||
case WM_SIZE:
|
||||
PhLayoutManagerLayout(&context->LayoutManager);
|
||||
break;
|
||||
case WM_SIZING:
|
||||
PhResizingMinimumSize((PRECT)lParam, wParam, 420, 250);
|
||||
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_MAINTEXT)
|
||||
{
|
||||
SetTextColor(hDC, RGB(19, 112, 171));
|
||||
}
|
||||
|
||||
// Set a transparent background for the control backcolor.
|
||||
SetBkMode(hDC, TRANSPARENT);
|
||||
|
||||
// set window background color.
|
||||
return (INT_PTR)GetSysColorBrush(COLOR_WINDOW);
|
||||
}
|
||||
break;
|
||||
case WM_PING_UPDATE:
|
||||
{
|
||||
ULONG i = 0;
|
||||
ULONG maxGraphHeight = 0;
|
||||
ULONG pingAvgValue = 0;
|
||||
|
||||
NetworkPingUpdateGraph(context);
|
||||
|
||||
for (i = 0; i < context->PingHistory.Count; i++)
|
||||
{
|
||||
maxGraphHeight = maxGraphHeight + PhGetItemCircularBuffer_ULONG(&context->PingHistory, i);
|
||||
pingAvgValue = maxGraphHeight / context->PingHistory.Count;
|
||||
}
|
||||
|
||||
SetDlgItemText(hwndDlg, IDC_ICMP_AVG, PhaFormatString(
|
||||
L"Average: %lums", pingAvgValue)->Buffer);
|
||||
SetDlgItemText(hwndDlg, IDC_ICMP_MIN, PhaFormatString(
|
||||
L"Minimum: %lums", context->PingMinMs)->Buffer);
|
||||
SetDlgItemText(hwndDlg, IDC_ICMP_MAX, PhaFormatString(
|
||||
L"Maximum: %lums", context->PingMaxMs)->Buffer);
|
||||
|
||||
SetDlgItemText(hwndDlg, IDC_PINGS_SENT, PhaFormatString(
|
||||
L"Pings sent: %lu", context->PingSentCount)->Buffer);
|
||||
SetDlgItemText(hwndDlg, IDC_PINGS_LOST, PhaFormatString(
|
||||
L"Pings lost: %lu (%.0f%%)", context->PingLossCount,
|
||||
((FLOAT)context->PingLossCount / context->PingSentCount * 100)
|
||||
)->Buffer);
|
||||
|
||||
SetDlgItemText(hwndDlg, IDC_BAD_HASH, PhaFormatString(
|
||||
L"Bad hashes: %lu", context->HashFailCount)->Buffer);
|
||||
SetDlgItemText(hwndDlg, IDC_ANON_ADDR, PhaFormatString(
|
||||
L"Anon replies: %lu", context->UnknownAddrCount)->Buffer);
|
||||
}
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
LPNMHDR header = (LPNMHDR)lParam;
|
||||
|
||||
switch (header->code)
|
||||
{
|
||||
case GCN_GETDRAWINFO:
|
||||
{
|
||||
PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)header;
|
||||
PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;
|
||||
|
||||
if (header->hwndFrom == context->PingGraphHandle)
|
||||
{
|
||||
if (PhGetIntegerSetting(L"GraphShowText"))
|
||||
{
|
||||
HDC hdc = Graph_GetBufferedContext(context->PingGraphHandle);
|
||||
|
||||
PhMoveReference(&context->PingGraphState.Text,
|
||||
PhFormatString(L"Ping: %lums", context->CurrentPingMs)
|
||||
);
|
||||
|
||||
SelectObject(hdc, PhApplicationFont);
|
||||
PhSetGraphText(hdc, drawInfo, &context->PingGraphState.Text->sr,
|
||||
&NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawInfo->Text.Buffer = NULL;
|
||||
}
|
||||
|
||||
drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y;
|
||||
PhSiSetColorsGraphDrawInfo(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0);
|
||||
PhGraphStateGetDrawInfo(&context->PingGraphState, getDrawInfo, context->PingHistory.Count);
|
||||
|
||||
if (!context->PingGraphState.Valid)
|
||||
{
|
||||
ULONG i;
|
||||
FLOAT max = 0;
|
||||
|
||||
for (i = 0; i < drawInfo->LineDataCount; i++)
|
||||
{
|
||||
FLOAT data1;
|
||||
|
||||
context->PingGraphState.Data1[i] = data1 = (FLOAT)PhGetItemCircularBuffer_ULONG(&context->PingHistory, i);
|
||||
|
||||
if (max < data1)
|
||||
max = data1;
|
||||
}
|
||||
|
||||
// Minimum scaling of timeout (1000ms default).
|
||||
if (max < (FLOAT)context->MaxPingTimeout)
|
||||
max = (FLOAT)context->MaxPingTimeout;
|
||||
|
||||
// Scale the data.
|
||||
PhDivideSinglesBySingle(
|
||||
context->PingGraphState.Data1,
|
||||
max,
|
||||
drawInfo->LineDataCount
|
||||
);
|
||||
|
||||
context->PingGraphState.Valid = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GCN_GETTOOLTIPTEXT:
|
||||
{
|
||||
PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)lParam;
|
||||
|
||||
if (getTooltipText->Index < getTooltipText->TotalCount)
|
||||
{
|
||||
if (header->hwndFrom == context->PingGraphHandle)
|
||||
{
|
||||
if (context->PingGraphState.TooltipIndex != getTooltipText->Index)
|
||||
{
|
||||
ULONG pingMs = PhGetItemCircularBuffer_ULONG(&context->PingHistory, getTooltipText->Index);
|
||||
|
||||
PhMoveReference(&context->PingGraphState.TooltipText,
|
||||
PhFormatString(L"Ping: %lums", pingMs)
|
||||
);
|
||||
}
|
||||
|
||||
getTooltipText->Text = context->PingGraphState.TooltipText->sr;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NTSTATUS PhNetworkPingDialogThreadStart(
|
||||
_In_ PVOID Parameter
|
||||
)
|
||||
{
|
||||
BOOL result;
|
||||
MSG message;
|
||||
HWND windowHandle;
|
||||
PH_AUTO_POOL autoPool;
|
||||
PNETWORK_OUTPUT_CONTEXT context = (PNETWORK_OUTPUT_CONTEXT)Parameter;
|
||||
|
||||
PhInitializeAutoPool(&autoPool);
|
||||
|
||||
windowHandle = CreateDialogParam(
|
||||
(HINSTANCE)PluginInstance->DllBase,
|
||||
MAKEINTRESOURCE(IDD_PINGDIALOG),
|
||||
PhMainWndHandle,
|
||||
NetworkPingWndProc,
|
||||
(LPARAM)Parameter
|
||||
);
|
||||
|
||||
ShowWindow(windowHandle, SW_SHOW);
|
||||
SetForegroundWindow(windowHandle);
|
||||
|
||||
while (result = GetMessage(&message, NULL, 0, 0))
|
||||
{
|
||||
if (result == -1)
|
||||
break;
|
||||
|
||||
if (!IsDialogMessage(windowHandle, &message))
|
||||
{
|
||||
TranslateMessage(&message);
|
||||
DispatchMessage(&message);
|
||||
}
|
||||
|
||||
PhDrainAutoPool(&autoPool);
|
||||
}
|
||||
|
||||
PhDeleteAutoPool(&autoPool);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
31
plugins/NetworkTools/resource.h
Normal file
31
plugins/NetworkTools/resource.h
Normal file
@@ -0,0 +1,31 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by NetworkTools.rc
|
||||
//
|
||||
#define IDD_OUTPUT 101
|
||||
#define IDD_PINGDIALOG 102
|
||||
#define IDD_OPTIONS 103
|
||||
#define IDC_MAXTIMEOUTTEXT 1008
|
||||
#define IDC_NETOUTPUTEDIT 1009
|
||||
#define IDC_ICMP_PANEL 1011
|
||||
#define IDC_PINGS_LOST 1012
|
||||
#define IDC_ICMP_MIN 1013
|
||||
#define IDC_ICMP_MAX 1014
|
||||
#define IDC_ICMP_AVG 1015
|
||||
#define IDC_MAINTEXT 1016
|
||||
#define IDC_ANON_ADDR 1017
|
||||
#define IDC_MORE_INFO 1019
|
||||
#define IDC_PINGS_SENT 1020
|
||||
#define IDC_PING_LAYOUT 1021
|
||||
#define IDC_BAD_HASH 1022
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 104
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1022
|
||||
#define _APS_NEXT_SYMED_VALUE 104
|
||||
#endif
|
||||
#endif
|
||||
158
plugins/NetworkTools/tracert.c
Normal file
158
plugins/NetworkTools/tracert.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Process Hacker Network Tools -
|
||||
* Tracert dialog
|
||||
*
|
||||
* Copyright (C) 2013 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 "nettools.h"
|
||||
|
||||
NTSTATUS StdOutNetworkTracertThreadStart(
|
||||
_In_ PVOID Parameter
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
PNETWORK_OUTPUT_CONTEXT context = (PNETWORK_OUTPUT_CONTEXT)Parameter;
|
||||
IO_STATUS_BLOCK isb;
|
||||
UCHAR buffer[PAGE_SIZE];
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
status = NtReadFile(
|
||||
context->PipeReadHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&isb,
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
break;
|
||||
|
||||
SendMessage(context->WindowHandle, NTM_RECEIVEDTRACE, (WPARAM)isb.Information, (LPARAM)buffer);
|
||||
}
|
||||
|
||||
SendMessage(context->WindowHandle, NTM_RECEIVEDFINISH, 0, 0);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS NetworkTracertThreadStart(
|
||||
_In_ PVOID Parameter
|
||||
)
|
||||
{
|
||||
HANDLE pipeWriteHandle = INVALID_HANDLE_VALUE;
|
||||
PNETWORK_OUTPUT_CONTEXT context = (PNETWORK_OUTPUT_CONTEXT)Parameter;
|
||||
|
||||
if (CreatePipe(&context->PipeReadHandle, &pipeWriteHandle, NULL, 0))
|
||||
{
|
||||
HANDLE threadHandle = NULL;
|
||||
STARTUPINFO startupInfo = { sizeof(startupInfo) };
|
||||
OBJECT_HANDLE_FLAG_INFORMATION flagInfo;
|
||||
PPH_STRING command = NULL;
|
||||
|
||||
startupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
|
||||
startupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||
startupInfo.hStdOutput = pipeWriteHandle;
|
||||
startupInfo.hStdError = pipeWriteHandle;
|
||||
startupInfo.wShowWindow = SW_HIDE;
|
||||
|
||||
switch (context->Action)
|
||||
{
|
||||
case NETWORK_ACTION_TRACEROUTE:
|
||||
{
|
||||
if (PhGetIntegerSetting(L"EnableNetworkResolve"))
|
||||
{
|
||||
command = PhFormatString(
|
||||
L"%s\\system32\\tracert.exe %s",
|
||||
USER_SHARED_DATA->NtSystemRoot,
|
||||
context->IpAddressString
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disable hostname lookup.
|
||||
command = PhFormatString(
|
||||
L"%s\\system32\\tracert.exe -d %s",
|
||||
USER_SHARED_DATA->NtSystemRoot,
|
||||
context->IpAddressString
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NETWORK_ACTION_PATHPING:
|
||||
{
|
||||
if (PhGetIntegerSetting(L"EnableNetworkResolve"))
|
||||
{
|
||||
command = PhFormatString(
|
||||
L"%s\\system32\\pathping.exe %s",
|
||||
USER_SHARED_DATA->NtSystemRoot,
|
||||
context->IpAddressString
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disable hostname lookup.
|
||||
command = PhFormatString(
|
||||
L"%s\\system32\\pathping.exe -n %s",
|
||||
USER_SHARED_DATA->NtSystemRoot,
|
||||
context->IpAddressString
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Allow the write handle to be inherited.
|
||||
flagInfo.Inherit = TRUE;
|
||||
flagInfo.ProtectFromClose = FALSE;
|
||||
|
||||
NtSetInformationObject(
|
||||
pipeWriteHandle,
|
||||
ObjectHandleFlagInformation,
|
||||
&flagInfo,
|
||||
sizeof(OBJECT_HANDLE_FLAG_INFORMATION)
|
||||
);
|
||||
|
||||
PhCreateProcessWin32Ex(
|
||||
NULL,
|
||||
command->Buffer,
|
||||
NULL,
|
||||
NULL,
|
||||
&startupInfo,
|
||||
PH_CREATE_PROCESS_INHERIT_HANDLES,
|
||||
NULL,
|
||||
NULL,
|
||||
&context->ProcessHandle,
|
||||
NULL
|
||||
);
|
||||
|
||||
// Essential; when the process exits, the last instance of the pipe will be disconnected and our thread will exit.
|
||||
NtClose(pipeWriteHandle);
|
||||
|
||||
// Create a thread which will wait for output and display it.
|
||||
if (threadHandle = PhCreateThread(0, StdOutNetworkTracertThreadStart, context))
|
||||
NtClose(threadHandle);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
216
plugins/NetworkTools/whois.c
Normal file
216
plugins/NetworkTools/whois.c
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Process Hacker Network Tools -
|
||||
* Whois dialog
|
||||
*
|
||||
* Copyright (C) 2013 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 "nettools.h"
|
||||
#include <mxml.h>
|
||||
#include <winhttp.h>
|
||||
|
||||
BOOLEAN ReadRequestString(
|
||||
_In_ HINTERNET Handle,
|
||||
_Out_ _Deref_post_z_cap_(*DataLength) PSTR *Data,
|
||||
_Out_ ULONG *DataLength
|
||||
)
|
||||
{
|
||||
PSTR data;
|
||||
ULONG allocatedLength;
|
||||
ULONG dataLength;
|
||||
ULONG returnLength;
|
||||
BYTE buffer[PAGE_SIZE];
|
||||
|
||||
allocatedLength = sizeof(buffer);
|
||||
data = (PSTR)PhAllocate(allocatedLength);
|
||||
dataLength = 0;
|
||||
|
||||
// Zero the buffer
|
||||
memset(buffer, 0, PAGE_SIZE);
|
||||
|
||||
while (WinHttpReadData(Handle, buffer, PAGE_SIZE, &returnLength))
|
||||
{
|
||||
if (returnLength == 0)
|
||||
break;
|
||||
|
||||
if (allocatedLength < dataLength + returnLength)
|
||||
{
|
||||
allocatedLength *= 2;
|
||||
data = (PSTR)PhReAllocate(data, allocatedLength);
|
||||
}
|
||||
|
||||
// Copy the returned buffer into our pointer
|
||||
memcpy(data + dataLength, buffer, returnLength);
|
||||
// Zero the returned buffer for the next loop
|
||||
//memset(buffer, 0, returnLength);
|
||||
|
||||
dataLength += returnLength;
|
||||
}
|
||||
|
||||
if (allocatedLength < dataLength + 1)
|
||||
{
|
||||
allocatedLength++;
|
||||
data = (PSTR)PhReAllocate(data, allocatedLength);
|
||||
}
|
||||
|
||||
// Ensure that the buffer is null-terminated.
|
||||
data[dataLength] = 0;
|
||||
|
||||
*DataLength = dataLength;
|
||||
*Data = data;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NTSTATUS NetworkWhoisThreadStart(
|
||||
_In_ PVOID Parameter
|
||||
)
|
||||
{
|
||||
BOOLEAN isSuccess = FALSE;
|
||||
ULONG xmlLength = 0;
|
||||
PSTR xmlBuffer = NULL;
|
||||
PPH_STRING phVersion = NULL;
|
||||
PPH_STRING userAgent = NULL;
|
||||
PPH_STRING whoisHttpGetString = NULL;
|
||||
HINTERNET connectionHandle = NULL;
|
||||
HINTERNET requestHandle = NULL;
|
||||
HINTERNET sessionHandle = NULL;
|
||||
PNETWORK_OUTPUT_CONTEXT context = NULL;
|
||||
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig = { 0 };
|
||||
|
||||
//4.4.3. IP Addresses and Networks
|
||||
// https://www.arin.net/resources/whoisrws/whois_api.html
|
||||
//TODO: use REF string from /rest/ip/ lookup for querying the IP network: "/rest/net/NET-74-125-0-0-1?showDetails=true"
|
||||
// or use CIDR string from /rest/ip/ lookup for querying the IP network: "/rest/cidr/216.34.181.0/24?showDetails=true
|
||||
//WinHttpAddRequestHeaders(requestHandle, L"application/arin.whoisrws-v1+xml", -1L, 0);
|
||||
|
||||
__try
|
||||
{
|
||||
// Query thread context.
|
||||
if ((context = (PNETWORK_OUTPUT_CONTEXT)Parameter) == NULL)
|
||||
__leave;
|
||||
|
||||
// Query PH version.
|
||||
if ((phVersion = PhGetPhVersion()) == NULL)
|
||||
__leave;
|
||||
|
||||
// Create a user agent string.
|
||||
if ((userAgent = PhConcatStrings2(L"Process Hacker ", phVersion->Buffer)) == NULL)
|
||||
__leave;
|
||||
|
||||
// Query the current system proxy
|
||||
WinHttpGetIEProxyConfigForCurrentUser(&proxyConfig);
|
||||
|
||||
// Open the HTTP session with the system proxy configuration if available
|
||||
if (!(sessionHandle = WinHttpOpen(
|
||||
userAgent->Buffer,
|
||||
proxyConfig.lpszProxy != NULL ? WINHTTP_ACCESS_TYPE_NAMED_PROXY : WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
|
||||
proxyConfig.lpszProxy,
|
||||
proxyConfig.lpszProxyBypass,
|
||||
0
|
||||
)))
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
if (WindowsVersion >= WINDOWS_8_1)
|
||||
{
|
||||
// Enable GZIP and DEFLATE support on Windows 8.1 and above using undocumented flags.
|
||||
ULONG httpFlags = WINHTTP_DECOMPRESSION_FLAG_GZIP | WINHTTP_DECOMPRESSION_FLAG_DEFLATE;
|
||||
|
||||
WinHttpSetOption(
|
||||
sessionHandle,
|
||||
WINHTTP_OPTION_DECOMPRESSION,
|
||||
&httpFlags,
|
||||
sizeof(ULONG)
|
||||
);
|
||||
}
|
||||
|
||||
if (!(connectionHandle = WinHttpConnect(
|
||||
sessionHandle,
|
||||
L"whois.arin.net",
|
||||
INTERNET_DEFAULT_HTTP_PORT,
|
||||
0
|
||||
)))
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
if (!(whoisHttpGetString = PhFormatString(L"/rest/ip/%s", context->IpAddressString)))
|
||||
__leave;
|
||||
|
||||
if (!(requestHandle = WinHttpOpenRequest(
|
||||
connectionHandle,
|
||||
NULL,
|
||||
whoisHttpGetString->Buffer,
|
||||
NULL,
|
||||
WINHTTP_NO_REFERER,
|
||||
WINHTTP_DEFAULT_ACCEPT_TYPES,
|
||||
WINHTTP_FLAG_REFRESH
|
||||
)))
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
if (!WinHttpAddRequestHeaders(requestHandle, L"Accept: text/plain", -1L, 0))
|
||||
__leave;
|
||||
|
||||
if (!WinHttpSendRequest(
|
||||
requestHandle,
|
||||
WINHTTP_NO_ADDITIONAL_HEADERS, 0,
|
||||
WINHTTP_NO_REQUEST_DATA, 0,
|
||||
WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, 0
|
||||
))
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
if (!WinHttpReceiveResponse(requestHandle, NULL))
|
||||
__leave;
|
||||
|
||||
if (!ReadRequestString(requestHandle, &xmlBuffer, &xmlLength))
|
||||
__leave;
|
||||
|
||||
PostMessage(context->WindowHandle, NTM_RECEIVEDWHOIS, (WPARAM)xmlLength, (LPARAM)xmlBuffer);
|
||||
PostMessage(context->WindowHandle, NTM_RECEIVEDFINISH, 0, 0);
|
||||
|
||||
isSuccess = TRUE;
|
||||
}
|
||||
__finally
|
||||
{
|
||||
if (phVersion)
|
||||
PhDereferenceObject(phVersion);
|
||||
|
||||
if (userAgent)
|
||||
PhDereferenceObject(userAgent);
|
||||
|
||||
if (whoisHttpGetString)
|
||||
PhDereferenceObject(whoisHttpGetString);
|
||||
|
||||
if (requestHandle)
|
||||
WinHttpCloseHandle(requestHandle);
|
||||
|
||||
if (connectionHandle)
|
||||
WinHttpCloseHandle(connectionHandle);
|
||||
|
||||
if (sessionHandle)
|
||||
WinHttpCloseHandle(sessionHandle);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user