mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
NetworkTools: Added ping history graph
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@5443 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
@@ -111,6 +111,21 @@ BEGIN
|
||||
LTEXT "Timeout:",IDC_STATIC,67,22,29,8
|
||||
END
|
||||
|
||||
IDD_PINGDIALOG DIALOGEX 0, 0, 351, 187
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
|
||||
CAPTION "Dialog"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,295,166,50,14
|
||||
CONTROL "Custom1",IDC_CUSTOM1,"PhGraph",WS_BORDER,7,27,337,90
|
||||
LTEXT "Pinging X with 32 bytes of data:",IDC_MAINTEXT,7,7,337,16
|
||||
GROUPBOX "Ping statistics",IDC_STATIC3,7,119,109,60
|
||||
LTEXT "Lost: 0",IDC_STATIC5,13,166,73,8
|
||||
LTEXT "Minimum: 0ms",IDC_STATIC6,13,142,73,8
|
||||
LTEXT "Maximum: 0ms",IDC_STATIC7,13,154,73,8
|
||||
LTEXT "Average: 0ms",IDC_STATIC8,13,130,73,8
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -135,6 +150,14 @@ BEGIN
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 69
|
||||
END
|
||||
|
||||
IDD_PINGDIALOG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 344
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 180
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
@@ -115,7 +115,9 @@ LOGICAL DllMain(
|
||||
PH_SETTING_CREATE settings[] =
|
||||
{
|
||||
{ IntegerPairSettingType, L"ProcessHacker.NetTools.NetToolsWindowPosition", L"0,0" },
|
||||
{ IntegerPairSettingType, L"ProcessHacker.NetTools.NetToolsWindowSize", L"600,365" },
|
||||
{ IntegerPairSettingType, L"ProcessHacker.NetTools.NetToolsWindowSize", L"600,365" },
|
||||
{ IntegerPairSettingType, L"ProcessHacker.NetTools.NetToolsPingWindowPosition", L"0,0" },
|
||||
{ IntegerPairSettingType, L"ProcessHacker.NetTools.NetToolsPingWindowSize", L"600,365" },
|
||||
{ IntegerSettingType, L"ProcessHacker.NetTools.MaxPingCount", L"4" },
|
||||
{ IntegerSettingType, L"ProcessHacker.NetTools.MaxPingTimeout", L"5" },
|
||||
{ IntegerSettingType, L"ProcessHacker.NetTools.EnableHostnameLookup", L"1" },
|
||||
|
||||
@@ -52,15 +52,29 @@ typedef struct _NETWORK_OUTPUT_CONTEXT
|
||||
PH_LAYOUT_MANAGER LayoutManager;
|
||||
HWND WindowHandle;
|
||||
BOOLEAN UseOldColors;
|
||||
PH_QUEUED_LOCK TextBufferLock;
|
||||
|
||||
HANDLE ThreadHandle;
|
||||
HANDLE PipeReadHandle;
|
||||
HANDLE ProcessHandle;
|
||||
WCHAR addressString[65];
|
||||
PH_STRING_BUILDER ReceivedString;
|
||||
|
||||
PH_CALLBACK_REGISTRATION ProcessesUpdatedRegistration;
|
||||
ULONG CurrentPingMs;
|
||||
ULONG PingMinMs;
|
||||
ULONG PingMaxMs;
|
||||
ULONG PingAvgMs;
|
||||
ULONG PingSentCount;
|
||||
ULONG PingRecvCount;
|
||||
ULONG PingLossCount;
|
||||
PH_CIRCULAR_BUFFER_ULONG PingHistory;
|
||||
PH_GRAPH_STATE PingGraphState;
|
||||
} NETWORK_OUTPUT_CONTEXT, *PNETWORK_OUTPUT_CONTEXT;
|
||||
|
||||
NTSTATUS PhNetworkPingDialogThreadStart(
|
||||
__in PVOID Parameter
|
||||
);
|
||||
|
||||
VOID PerformNetworkAction(
|
||||
__in ULONG Action,
|
||||
__in PPH_NETWORK_ITEM NetworkItem
|
||||
|
||||
@@ -25,90 +25,7 @@
|
||||
|
||||
static RECT MinimumSize = { -1, -1, -1, -1 };
|
||||
|
||||
static NTSTATUS PhNetworkOutputDialogThreadStart(
|
||||
__in PVOID Parameter
|
||||
)
|
||||
{
|
||||
BOOL result;
|
||||
MSG message;
|
||||
PH_AUTO_POOL autoPool;
|
||||
PNETWORK_OUTPUT_CONTEXT context = (PNETWORK_OUTPUT_CONTEXT)Parameter;
|
||||
|
||||
PhInitializeAutoPool(&autoPool);
|
||||
|
||||
context->WindowHandle = CreateDialogParam(
|
||||
(HINSTANCE)PluginInstance->DllBase,
|
||||
MAKEINTRESOURCE(IDD_OUTPUT),
|
||||
PhMainWndHandle,
|
||||
NetworkOutputDlgProc,
|
||||
(LPARAM)Parameter
|
||||
);
|
||||
|
||||
ShowWindow(context->WindowHandle, SW_SHOW);
|
||||
SetForegroundWindow(context->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);
|
||||
DestroyWindow(context->WindowHandle);
|
||||
PhFree(context);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static HFONT InitializeFont(
|
||||
__in HWND hwndDlg
|
||||
)
|
||||
{
|
||||
LOGFONT logFont = { 0 };
|
||||
HFONT fontHandle = NULL;
|
||||
|
||||
logFont.lfHeight = 14;
|
||||
logFont.lfWeight = FW_NORMAL;//FW_MEDIUM;
|
||||
logFont.lfQuality = CLEARTYPE_QUALITY | ANTIALIASED_QUALITY;
|
||||
|
||||
// GDI uses the first font that matches the above attributes.
|
||||
fontHandle = CreateFontIndirect(&logFont);
|
||||
|
||||
if (fontHandle)
|
||||
{
|
||||
SendMessage(hwndDlg, WM_SETFONT, (WPARAM)fontHandle, FALSE);
|
||||
return fontHandle;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VOID PerformNetworkAction(
|
||||
__in ULONG Action,
|
||||
__in PPH_NETWORK_ITEM NetworkItem
|
||||
)
|
||||
{
|
||||
HANDLE dialogThread = INVALID_HANDLE_VALUE;
|
||||
PNETWORK_OUTPUT_CONTEXT context = (PNETWORK_OUTPUT_CONTEXT)PhAllocate(
|
||||
sizeof(NETWORK_OUTPUT_CONTEXT)
|
||||
);
|
||||
memset(context, 0, sizeof(NETWORK_OUTPUT_CONTEXT));
|
||||
|
||||
context->Action = Action;
|
||||
context->NetworkItem = NetworkItem;
|
||||
|
||||
if (dialogThread = PhCreateThread(0, (PUSER_THREAD_START_ROUTINE)PhNetworkOutputDialogThreadStart, (PVOID)context))
|
||||
NtClose(dialogThread);
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK NetworkOutputDlgProc(
|
||||
static INT_PTR CALLBACK NetworkOutputDlgProc(
|
||||
__in HWND hwndDlg,
|
||||
__in UINT uMsg,
|
||||
__in WPARAM wParam,
|
||||
@@ -129,19 +46,6 @@ INT_PTR CALLBACK NetworkOutputDlgProc(
|
||||
if (uMsg == WM_NCDESTROY)
|
||||
{
|
||||
PhSaveWindowPlacementToSetting(L"ProcessHacker.NetTools.NetToolsWindowPosition", L"ProcessHacker.NetTools.NetToolsWindowSize", hwndDlg);
|
||||
|
||||
if (context->ProcessHandle)
|
||||
{
|
||||
NtClose(context->ProcessHandle);
|
||||
context->ProcessHandle = NULL;
|
||||
}
|
||||
|
||||
if (context->ThreadHandle)
|
||||
{
|
||||
NtClose(context->ThreadHandle);
|
||||
context->ThreadHandle = NULL;
|
||||
}
|
||||
|
||||
PhDeleteStringBuilder(&context->ReceivedString);
|
||||
RemoveProp(hwndDlg, L"Context");
|
||||
}
|
||||
@@ -157,9 +61,7 @@ INT_PTR CALLBACK NetworkOutputDlgProc(
|
||||
PH_RECTANGLE windowRectangle;
|
||||
HANDLE dialogThread = INVALID_HANDLE_VALUE;
|
||||
|
||||
PhInitializeQueuedLock(&context->TextBufferLock);
|
||||
PhInitializeStringBuilder(&context->ReceivedString, PAGE_SIZE);
|
||||
|
||||
PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_NETOUTPUTEDIT), NULL, PH_ANCHOR_ALL);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_NETRETRY), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
|
||||
@@ -203,12 +105,6 @@ INT_PTR CALLBACK NetworkOutputDlgProc(
|
||||
|
||||
switch (context->Action)
|
||||
{
|
||||
case NETWORK_ACTION_PING:
|
||||
{
|
||||
if (dialogThread = PhCreateThread(0, (PUSER_THREAD_START_ROUTINE)NetworkPingThreadStart, (PVOID)context))
|
||||
NtClose(dialogThread);
|
||||
}
|
||||
break;
|
||||
case NETWORK_ACTION_TRACEROUTE:
|
||||
{
|
||||
if (dialogThread = PhCreateThread(0, (PUSER_THREAD_START_ROUTINE)NetworkTracertThreadStart, (PVOID)context))
|
||||
@@ -229,17 +125,7 @@ INT_PTR CALLBACK NetworkOutputDlgProc(
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_NETRETRY:
|
||||
{
|
||||
HANDLE dialogThread = NULL;
|
||||
|
||||
Button_Enable(GetDlgItem(hwndDlg, IDC_NETRETRY), FALSE);
|
||||
|
||||
if (context->Action == NETWORK_ACTION_PING)
|
||||
{
|
||||
if (dialogThread = PhCreateThread(0, (PUSER_THREAD_START_ROUTINE)NetworkPingThreadStart, (PVOID)context))
|
||||
NtClose(dialogThread);
|
||||
}
|
||||
}
|
||||
Button_Enable(GetDlgItem(hwndDlg, IDC_NETRETRY), FALSE);
|
||||
break;
|
||||
case IDCANCEL:
|
||||
case IDOK:
|
||||
@@ -409,4 +295,95 @@ INT_PTR CALLBACK NetworkOutputDlgProc(
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static NTSTATUS PhNetworkOutputDialogThreadStart(
|
||||
__in PVOID Parameter
|
||||
)
|
||||
{
|
||||
BOOL result;
|
||||
MSG message;
|
||||
PH_AUTO_POOL autoPool;
|
||||
PNETWORK_OUTPUT_CONTEXT context = (PNETWORK_OUTPUT_CONTEXT)Parameter;
|
||||
|
||||
PhInitializeAutoPool(&autoPool);
|
||||
|
||||
context->WindowHandle = CreateDialogParam(
|
||||
(HINSTANCE)PluginInstance->DllBase,
|
||||
MAKEINTRESOURCE(IDD_OUTPUT),
|
||||
PhMainWndHandle,
|
||||
NetworkOutputDlgProc,
|
||||
(LPARAM)Parameter
|
||||
);
|
||||
|
||||
ShowWindow(context->WindowHandle, SW_SHOW);
|
||||
SetForegroundWindow(context->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);
|
||||
DestroyWindow(context->WindowHandle);
|
||||
PhFree(context);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static HFONT InitializeFont(
|
||||
__in HWND hwndDlg
|
||||
)
|
||||
{
|
||||
LOGFONT logFont = { 0 };
|
||||
HFONT fontHandle = NULL;
|
||||
|
||||
logFont.lfHeight = 14;
|
||||
logFont.lfWeight = FW_NORMAL;//FW_MEDIUM;
|
||||
logFont.lfQuality = CLEARTYPE_QUALITY | ANTIALIASED_QUALITY;
|
||||
|
||||
// GDI uses the first font that matches the above attributes.
|
||||
fontHandle = CreateFontIndirect(&logFont);
|
||||
|
||||
if (fontHandle)
|
||||
{
|
||||
SendMessage(hwndDlg, WM_SETFONT, (WPARAM)fontHandle, FALSE);
|
||||
return fontHandle;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VOID PerformNetworkAction(
|
||||
__in ULONG Action,
|
||||
__in PPH_NETWORK_ITEM NetworkItem
|
||||
)
|
||||
{
|
||||
HANDLE dialogThread = INVALID_HANDLE_VALUE;
|
||||
PNETWORK_OUTPUT_CONTEXT context = (PNETWORK_OUTPUT_CONTEXT)PhAllocate(
|
||||
sizeof(NETWORK_OUTPUT_CONTEXT)
|
||||
);
|
||||
memset(context, 0, sizeof(NETWORK_OUTPUT_CONTEXT));
|
||||
|
||||
context->Action = Action;
|
||||
context->NetworkItem = NetworkItem;
|
||||
|
||||
if (context->Action == NETWORK_ACTION_PING)
|
||||
{
|
||||
if (dialogThread = PhCreateThread(0, (PUSER_THREAD_START_ROUTINE)PhNetworkPingDialogThreadStart, (PVOID)context))
|
||||
NtClose(dialogThread);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dialogThread = PhCreateThread(0, (PUSER_THREAD_START_ROUTINE)PhNetworkOutputDialogThreadStart, (PVOID)context))
|
||||
NtClose(dialogThread);
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,6 @@
|
||||
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma comment(lib, "IPHLPAPI.lib")
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
|
||||
#include "nettools.h"
|
||||
|
||||
#include <winsock2.h>
|
||||
@@ -30,139 +27,69 @@
|
||||
#include <iphlpapi.h>
|
||||
#include <icmpapi.h>
|
||||
|
||||
ULONG64 PhGetAverage(
|
||||
__in PULONG64 Buffer,
|
||||
__in ULONG BufferSize,
|
||||
__in ULONG BufferPosition,
|
||||
__in ULONG BufferCount,
|
||||
__in ULONG NumberToConsider
|
||||
#pragma comment(lib, "iphlpapi.lib")
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
|
||||
#define WM_PING_UPDATE (WM_APP + 151)
|
||||
static RECT NormalGraphTextMargin = { 5, 5, 5, 5 };
|
||||
static RECT NormalGraphTextPadding = { 3, 3, 3, 3 };
|
||||
|
||||
static HFONT InitializeFont(
|
||||
__in HWND hwndDlg
|
||||
)
|
||||
{
|
||||
ULONG64 sum;
|
||||
ULONG i;
|
||||
ULONG count;
|
||||
LOGFONT logFont = { 0 };
|
||||
HFONT fontHandle = NULL;
|
||||
|
||||
sum = 0;
|
||||
i = BufferPosition;
|
||||
logFont.lfHeight = 20;
|
||||
logFont.lfWeight = FW_MEDIUM;
|
||||
logFont.lfQuality = CLEARTYPE_QUALITY | ANTIALIASED_QUALITY;
|
||||
|
||||
if (NumberToConsider > BufferCount)
|
||||
NumberToConsider = BufferCount;
|
||||
wcscpy_s(logFont.lfFaceName, _countof(logFont.lfFaceName),
|
||||
WindowsVersion > WINDOWS_XP ? L"Segoe UI" : L"MS Shell Dlg 2"
|
||||
);
|
||||
|
||||
if (NumberToConsider == 0)
|
||||
return 0;
|
||||
fontHandle = CreateFontIndirect(&logFont);
|
||||
|
||||
count = NumberToConsider;
|
||||
|
||||
do
|
||||
if (fontHandle)
|
||||
{
|
||||
sum += Buffer[i];
|
||||
i++;
|
||||
SendMessage(hwndDlg, WM_SETFONT, (WPARAM)fontHandle, FALSE);
|
||||
return fontHandle;
|
||||
}
|
||||
|
||||
if (i == BufferSize)
|
||||
i = 0;
|
||||
} while (--count != 0);
|
||||
|
||||
return sum / NumberToConsider;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTSTATUS NetworkPingThreadStart(
|
||||
static NTSTATUS PhPingNetworkPingThreadStart(
|
||||
__in PVOID Parameter
|
||||
)
|
||||
{
|
||||
PNETWORK_OUTPUT_CONTEXT context = (PNETWORK_OUTPUT_CONTEXT)Parameter;
|
||||
|
||||
ULONG i = 0;
|
||||
WSADATA wsaData = { 0 };
|
||||
PPH_ANSI_STRING addrString;
|
||||
SOCKADDR_IN sock_in;
|
||||
|
||||
HANDLE icmpHandle = INVALID_HANDLE_VALUE;
|
||||
PVOID icmpReplyBuffer = NULL;
|
||||
{
|
||||
ULONG icmpReplyLength = 0;
|
||||
ULONG icmpPingReplyCount = 0;
|
||||
|
||||
ULONG pingFirstMs = 0;
|
||||
ULONG pingSecondMs = 0;
|
||||
ULONG pingTotalMs = 0;
|
||||
ULONG pingReplyCount = 0;
|
||||
ULONG pingLossCount = 0;
|
||||
ULONG pingSpeed = 0;
|
||||
ULONG icmpReplyCount = 0;
|
||||
PVOID icmpReplyBuffer = NULL;
|
||||
PICMP_ECHO_REPLY icmpReplyStruct = NULL;
|
||||
HANDLE icmpHandle = INVALID_HANDLE_VALUE;
|
||||
IP_OPTION_INFORMATION pingOptions = { 0 };
|
||||
|
||||
WCHAR hostname[NI_MAXHOST];
|
||||
WCHAR servInfo[NI_MAXSERV];
|
||||
PNETWORK_OUTPUT_CONTEXT context = (PNETWORK_OUTPUT_CONTEXT)Parameter;
|
||||
|
||||
BOOLEAN isLookupEnabled = !!PhGetIntegerSetting(L"ProcessHacker.NetTools.EnableHostnameLookup");
|
||||
ULONG maxPingCount = max(PhGetIntegerSetting(L"ProcessHacker.NetTools.MaxPingCount"), 1);
|
||||
ULONG maxPingTimeout = max(PhGetIntegerSetting(L"ProcessHacker.NetTools.MaxPingTimeout"), 1);
|
||||
ULONG maxPingCount = __max(PhGetIntegerSetting(L"ProcessHacker.NetTools.MaxPingCount"), 1);
|
||||
ULONG maxPingTimeout = __max(PhGetIntegerSetting(L"ProcessHacker.NetTools.MaxPingTimeout"), 1);
|
||||
|
||||
Static_SetText(context->WindowHandle,
|
||||
PhFormatString(L"Pinging %s...", context->addressString)->Buffer);
|
||||
|
||||
addrString = PhCreateAnsiStringFromUnicode(context->addressString);
|
||||
WSAStartup(WINSOCK_VERSION, &wsaData);
|
||||
|
||||
// This value indicates that the packet should not be fragmented.
|
||||
//pingOptions.Flags = IP_FLAG_DF;
|
||||
// Set the TTL field if we are doing a traceroute step.
|
||||
pingOptions.Ttl = 128;
|
||||
|
||||
if (context->NetworkItem->RemoteEndpoint.Address.Type == PH_IPV4_NETWORK_TYPE)
|
||||
__try
|
||||
{
|
||||
pingOptions.Flags = IP_FLAG_DF;
|
||||
pingOptions.Ttl = 128;
|
||||
|
||||
icmpHandle = IcmpCreateFile();
|
||||
|
||||
sock_in.sin_family = AF_INET;
|
||||
sock_in.sin_addr.s_addr = inet_addr(addrString->Buffer);
|
||||
sock_in.sin_port = (USHORT)context->NetworkItem->RemoteEndpoint.Port;
|
||||
}
|
||||
else
|
||||
{
|
||||
icmpHandle = Icmp6CreateFile();
|
||||
|
||||
sock_in.sin_family = AF_INET6;
|
||||
}
|
||||
|
||||
//Pinging 74.125.31.125 with 32 bytes of data:
|
||||
//Reply from 74.125.31.125: bytes=32 time=207ms TTL=37
|
||||
//Reply from 74.125.31.125: bytes=32 time=202ms TTL=38
|
||||
//Reply from 74.125.31.125: bytes=32 time=206ms TTL=37
|
||||
//Reply from 74.125.31.125: bytes=32 time=204ms TTL=38
|
||||
|
||||
if (isLookupEnabled && GetNameInfo(
|
||||
(const PSOCKADDR)&sock_in, sizeof(SOCKADDR_IN),
|
||||
hostname, _countof(hostname),
|
||||
servInfo, _countof(servInfo),
|
||||
0
|
||||
) == 0)
|
||||
{
|
||||
PPH_STRING buffer = PhFormatString(
|
||||
L"Pinging %s:%s [%s] with 32 bytes of data...\r\n\r\n",
|
||||
context->addressString,
|
||||
servInfo,
|
||||
hostname
|
||||
);
|
||||
SendMessage(context->WindowHandle, NTM_RECEIVEDPING, (WPARAM)buffer, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
PPH_STRING buffer = PhFormatString(
|
||||
L"Pinging %s with 32 bytes of data...\r\n\r\n",
|
||||
context->addressString
|
||||
);
|
||||
SendMessage(context->WindowHandle, NTM_RECEIVEDPING, (WPARAM)buffer, 0);
|
||||
}
|
||||
|
||||
// Loop through the 3 sets of pings
|
||||
for (i = 0; i < maxPingCount; i++)
|
||||
{
|
||||
icmpReplyLength = sizeof(ICMP_ECHO_REPLY);
|
||||
icmpReplyBuffer = PhAllocate(icmpReplyLength);
|
||||
|
||||
memset(icmpReplyBuffer, 0, icmpReplyLength);
|
||||
|
||||
// First ping with no data
|
||||
if ((icmpPingReplyCount = IcmpSendEcho(
|
||||
context->PingSentCount++;
|
||||
|
||||
icmpReplyCount = IcmpSendEcho(
|
||||
icmpHandle,
|
||||
context->NetworkItem->RemoteEndpoint.Address.InAddr.S_un.S_addr,
|
||||
NULL, 0,
|
||||
@@ -170,86 +97,400 @@ NTSTATUS NetworkPingThreadStart(
|
||||
icmpReplyBuffer,
|
||||
icmpReplyLength,
|
||||
maxPingTimeout * 1000
|
||||
)) == 0)
|
||||
{
|
||||
if (WSAGetLastError() != IP_REQ_TIMED_OUT)
|
||||
{
|
||||
PPH_STRING buffer = PhFormatString(L"IcmpSendEcho failed: %d\r\n", WSAGetLastError());
|
||||
SendMessage(context->WindowHandle, NTM_RECEIVEDPING, (WPARAM)buffer, 0);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
icmpReplyStruct = (PICMP_ECHO_REPLY)icmpReplyBuffer;
|
||||
if (icmpReplyCount > 0 && icmpReplyStruct)
|
||||
{
|
||||
//Ping statistics for %s:
|
||||
// Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
|
||||
//Approximate round trip times in milli-seconds:
|
||||
// Minimum = 202ms, Maximum = 207ms, Average = 204ms
|
||||
|
||||
if (icmpReplyStruct)
|
||||
{
|
||||
// Reply from different address??
|
||||
// if (icmpReplyStruct->Address == context->Address.InAddr.S_un.S_addr)
|
||||
// if (icmpReplyStruct->DataSize < max_size
|
||||
//if (!icmpReplyStruct->RoundTripTime) PPH_STRING buffer = PhFormatString(L"<1 ms ");
|
||||
pingFirstMs = icmpReplyStruct->RoundTripTime;
|
||||
//if (icmpReplyStruct->Address == context->Address.InAddr.S_un.S_addr)
|
||||
//if (icmpReplyStruct->DataSize < max_size)
|
||||
//if (icmpReplyStruct->RoundTripTime < 1)
|
||||
|
||||
switch (icmpReplyStruct->Status)
|
||||
InterlockedIncrement(&context->PingRecvCount);
|
||||
|
||||
if (icmpReplyStruct->Status != IP_SUCCESS)
|
||||
{
|
||||
case IP_SUCCESS:
|
||||
InterlockedIncrement(&context->PingLossCount);
|
||||
}
|
||||
|
||||
context->CurrentPingMs = icmpReplyStruct->RoundTripTime;
|
||||
|
||||
if (context->CurrentPingMs < context->PingMinMs)
|
||||
context->PingMinMs = context->CurrentPingMs;
|
||||
if (context->CurrentPingMs > context->PingMaxMs)
|
||||
context->PingMaxMs = context->CurrentPingMs;
|
||||
|
||||
PhAddItemCircularBuffer_ULONG(&context->PingHistory, context->CurrentPingMs);
|
||||
}
|
||||
else
|
||||
{
|
||||
InterlockedIncrement(&context->PingLossCount);
|
||||
|
||||
PhAddItemCircularBuffer_ULONG(&context->PingHistory, 0);
|
||||
}
|
||||
}
|
||||
__finally
|
||||
{
|
||||
if (icmpReplyBuffer)
|
||||
{
|
||||
PhFree(icmpReplyBuffer);
|
||||
}
|
||||
|
||||
if (icmpHandle)
|
||||
{
|
||||
IcmpCloseHandle(icmpHandle);
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static VOID NTAPI NetworkPingUpdateHandler(
|
||||
__in_opt PVOID Parameter,
|
||||
__in_opt PVOID Context
|
||||
)
|
||||
{
|
||||
PNETWORK_OUTPUT_CONTEXT context = (PNETWORK_OUTPUT_CONTEXT)Context;
|
||||
HANDLE dialogThread = INVALID_HANDLE_VALUE;
|
||||
|
||||
// Queue up the next ping...
|
||||
// This needs to be done to prevent slow-links from blocking the interval update.
|
||||
if (dialogThread = PhCreateThread(0, (PUSER_THREAD_START_ROUTINE)PhPingNetworkPingThreadStart, (PVOID)context))
|
||||
NtClose(dialogThread);
|
||||
|
||||
PostMessage(context->WindowHandle, WM_PING_UPDATE, 0, 0);
|
||||
}
|
||||
|
||||
static INT_PTR CALLBACK NetworkPingWndProc(
|
||||
__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_NCDESTROY)
|
||||
{
|
||||
PhSaveWindowPlacementToSetting(
|
||||
L"ProcessHacker.NetTools.NetToolsPingWindowPosition",
|
||||
L"ProcessHacker.NetTools.NetToolsPingWindowSize",
|
||||
hwndDlg
|
||||
);
|
||||
RemoveProp(hwndDlg, L"Context");
|
||||
}
|
||||
}
|
||||
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
PH_RECTANGLE windowRectangle;
|
||||
|
||||
// Convert IP Address to string format.
|
||||
if (context->NetworkItem->RemoteEndpoint.Address.Type == PH_IPV4_NETWORK_TYPE)
|
||||
{
|
||||
RtlIpv4AddressToString(
|
||||
&context->NetworkItem->RemoteEndpoint.Address.InAddr,
|
||||
context->addressString
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlIpv6AddressToString(
|
||||
&context->NetworkItem->RemoteEndpoint.Address.In6Addr,
|
||||
context->addressString
|
||||
);
|
||||
}
|
||||
|
||||
SetWindowText(hwndDlg, PhaFormatString(L"Ping (%s)", context->addressString)->Buffer);
|
||||
SetWindowText(GetDlgItem(hwndDlg, IDC_MAINTEXT), PhaFormatString(L"Pinging %s with 32 bytes of data:", context->addressString)->Buffer);
|
||||
|
||||
InitializeFont(GetDlgItem(hwndDlg, IDC_MAINTEXT));
|
||||
PhInitializeGraphState(&context->PingGraphState);
|
||||
PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
|
||||
PhInitializeCircularBuffer_ULONG(&context->PingHistory, PhGetIntegerSetting(L"SampleCount"));
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_CUSTOM1), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_RIGHT | PH_ANCHOR_TOP | PH_ANCHOR_BOTTOM);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_STATIC3), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_STATIC5), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_STATIC6), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_STATIC7), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_STATIC8), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
|
||||
Graph_SetTooltip(GetDlgItem(hwndDlg, IDC_CUSTOM1), TRUE);
|
||||
|
||||
context->UseOldColors = !!PhGetIntegerSetting(L"GraphColorMode");
|
||||
windowRectangle.Position = PhGetIntegerPairSetting(L"ProcessHacker.NetTools.NetToolsPingWindowPosition");
|
||||
windowRectangle.Size = PhGetIntegerPairSetting(L"ProcessHacker.NetTools.NetToolsPingWindowSize");
|
||||
|
||||
// Load window settings.
|
||||
if (windowRectangle.Position.X == 0 || windowRectangle.Position.Y == 0)
|
||||
PhCenterWindow(hwndDlg, GetParent(hwndDlg));
|
||||
else
|
||||
{
|
||||
PhLoadWindowPlacementFromSetting(
|
||||
L"ProcessHacker.NetTools.NetToolsPingWindowPosition",
|
||||
L"ProcessHacker.NetTools.NetToolsPingWindowSize",
|
||||
hwndDlg
|
||||
);
|
||||
}
|
||||
|
||||
PhRegisterCallback(
|
||||
PhGetGeneralCallback(GeneralCallbackProcessesUpdated),
|
||||
NetworkPingUpdateHandler,
|
||||
context,
|
||||
&context->ProcessesUpdatedRegistration
|
||||
);
|
||||
}
|
||||
return TRUE;
|
||||
case WM_COMMAND:
|
||||
{
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDCANCEL:
|
||||
case IDOK:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
{
|
||||
PhUnregisterCallback(
|
||||
PhGetGeneralCallback(GeneralCallbackProcessesUpdated),
|
||||
&context->ProcessesUpdatedRegistration
|
||||
);
|
||||
|
||||
PhDeleteLayoutManager(&context->LayoutManager);
|
||||
}
|
||||
break;
|
||||
case WM_SIZE:
|
||||
PhLayoutManagerLayout(&context->LayoutManager);
|
||||
break;
|
||||
case WM_SIZING:
|
||||
PhResizingMinimumSize((PRECT)lParam, wParam, 100, 100);
|
||||
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:
|
||||
{
|
||||
context->PingGraphState.Valid = FALSE;
|
||||
context->PingGraphState.TooltipIndex = -1;
|
||||
Graph_MoveGrid(GetDlgItem(hwndDlg, IDC_CUSTOM1), 1);
|
||||
Graph_Draw(GetDlgItem(hwndDlg, IDC_CUSTOM1));
|
||||
Graph_UpdateTooltip(GetDlgItem(hwndDlg, IDC_CUSTOM1));
|
||||
InvalidateRect(GetDlgItem(hwndDlg, IDC_CUSTOM1), NULL, FALSE);
|
||||
|
||||
//SetDlgItemText(hwndDlg, IDC_STATIC2, PhaFormatString(
|
||||
// L"Sent: %I64u", context->PingSentCount)->Buffer);
|
||||
SetDlgItemText(hwndDlg, IDC_STATIC5, PhaFormatString(
|
||||
L"Loss: %I64u (0%% loss)", context->PingLossCount)->Buffer);
|
||||
SetDlgItemText(hwndDlg, IDC_STATIC6, PhaFormatString(
|
||||
L"Minimum: %I64ums", context->PingMinMs)->Buffer);
|
||||
SetDlgItemText(hwndDlg, IDC_STATIC7, PhaFormatString(
|
||||
L"Maximum: %I64ums", context->PingMaxMs)->Buffer);
|
||||
SetDlgItemText(hwndDlg, IDC_STATIC8, PhaFormatString(
|
||||
L"Average: %I64ums", context->PingAvgMs)->Buffer);
|
||||
}
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
LPNMHDR header = (LPNMHDR)lParam;
|
||||
|
||||
switch (header->code)
|
||||
{
|
||||
case GCN_GETDRAWINFO:
|
||||
{
|
||||
PPH_STRING buffer = PhFormatString(
|
||||
L"Reply from %s: Time=%dms TTL=%u\r\n",
|
||||
context->addressString,
|
||||
icmpReplyStruct->RoundTripTime,
|
||||
icmpReplyStruct->Options.Ttl
|
||||
);
|
||||
SendMessage(context->WindowHandle, NTM_RECEIVEDPING, (WPARAM)buffer, 0);
|
||||
PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)header;
|
||||
PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;
|
||||
//drawInfo->Flags = ~PH_GRAPH_USE_GRID;
|
||||
|
||||
if (context->UseOldColors)
|
||||
{
|
||||
drawInfo->BackColor = RGB(0x00, 0x00, 0x00);
|
||||
drawInfo->LineColor1 = PhGetIntegerSetting(L"ColorCpuKernel");
|
||||
drawInfo->LineBackColor1 = PhHalveColorBrightness(drawInfo->LineColor1);
|
||||
drawInfo->LineColor2 = PhGetIntegerSetting(L"ColorCpuUser");
|
||||
drawInfo->LineBackColor2 = PhHalveColorBrightness(drawInfo->LineColor2);
|
||||
drawInfo->GridColor = RGB(0x00, 0x57, 0x00);
|
||||
drawInfo->TextColor = RGB(0x00, 0xff, 0x00);
|
||||
drawInfo->TextBoxColor = RGB(0x00, 0x22, 0x00);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawInfo->BackColor = RGB(0xef, 0xef, 0xef);
|
||||
drawInfo->LineColor1 = PhHalveColorBrightness(PhGetIntegerSetting(L"ColorCpuKernel"));
|
||||
drawInfo->LineBackColor1 = PhMakeColorBrighter(drawInfo->LineColor1, 125);
|
||||
drawInfo->LineColor2 = PhHalveColorBrightness(PhGetIntegerSetting(L"ColorCpuUser"));
|
||||
drawInfo->LineBackColor2 = PhMakeColorBrighter(drawInfo->LineColor2, 125);
|
||||
drawInfo->GridColor = RGB(0xc7, 0xc7, 0xc7);
|
||||
drawInfo->TextColor = RGB(0x00, 0x00, 0x00);
|
||||
drawInfo->TextBoxColor = RGB(0xe7, 0xe7, 0xe7);
|
||||
}
|
||||
|
||||
if (header->hwndFrom == GetDlgItem(hwndDlg, IDC_CUSTOM1))
|
||||
{
|
||||
if (PhGetIntegerSetting(L"GraphShowText"))
|
||||
{
|
||||
HDC hdc = Graph_GetBufferedContext(GetDlgItem(hwndDlg, IDC_CUSTOM1));
|
||||
|
||||
PhSwapReference2(&context->PingGraphState.TooltipText,
|
||||
PhFormatString(L"Ping: %I64ums", context->CurrentPingMs)
|
||||
);
|
||||
|
||||
SelectObject(hdc, PhApplicationFont);
|
||||
PhSetGraphText(hdc, drawInfo, &context->PingGraphState.TooltipText->sr,
|
||||
&NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawInfo->Text.Buffer = NULL;
|
||||
}
|
||||
|
||||
PhGraphStateGetDrawInfo(
|
||||
&context->PingGraphState,
|
||||
getDrawInfo,
|
||||
context->PingHistory.Count
|
||||
);
|
||||
|
||||
if (!context->PingGraphState.Valid)
|
||||
{
|
||||
ULONG i = 0;
|
||||
|
||||
for (i = 0; i < drawInfo->LineDataCount; i++)
|
||||
{
|
||||
context->PingGraphState.Data1[i] =
|
||||
(FLOAT)PhGetItemCircularBuffer_ULONG(&context->PingHistory, i);
|
||||
}
|
||||
|
||||
// Scale the data.
|
||||
PhxfDivideSingle2U(
|
||||
context->PingGraphState.Data1,
|
||||
(FLOAT)context->PingMaxMs + 5,
|
||||
drawInfo->LineDataCount
|
||||
);
|
||||
|
||||
context->PingGraphState.Valid = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: // case IP_REQ_TIMED_OUT:
|
||||
case GCN_GETTOOLTIPTEXT:
|
||||
{
|
||||
PPH_STRING buffer = PhFormatString(L"Reply from %s: Timed out...\r\n" , context->addressString);
|
||||
SendMessage(context->WindowHandle, NTM_RECEIVEDPING, (WPARAM)buffer, 0);
|
||||
PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)lParam;
|
||||
|
||||
pingLossCount++;
|
||||
if (getTooltipText->Index < getTooltipText->TotalCount)
|
||||
{
|
||||
if (header->hwndFrom == GetDlgItem(hwndDlg, IDC_CUSTOM1))
|
||||
{
|
||||
if (context->PingGraphState.TooltipIndex != getTooltipText->Index)
|
||||
{
|
||||
ULONG usage = PhGetItemCircularBuffer_ULONG(
|
||||
&context->PingHistory,
|
||||
getTooltipText->Index
|
||||
);
|
||||
|
||||
PhSwapReference2(&context->PingGraphState.TooltipText, PhFormatString(L"Ping: %I64ums", usage));
|
||||
}
|
||||
|
||||
getTooltipText->Text = context->PingGraphState.TooltipText->sr;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GCN_MOUSEEVENT:
|
||||
{
|
||||
PPH_GRAPH_MOUSEEVENT mouseEvent = (PPH_GRAPH_MOUSEEVENT)lParam;
|
||||
|
||||
if (mouseEvent->Message == WM_LBUTTONDBLCLK)
|
||||
{
|
||||
if (header->hwndFrom == GetDlgItem(hwndDlg, IDC_CUSTOM1))
|
||||
{
|
||||
PhShowInformation(hwndDlg, L"Double clicked!");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pingTotalMs += (pingSecondMs - pingFirstMs);
|
||||
pingSecondMs = pingFirstMs;
|
||||
pingReplyCount++;
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NTSTATUS PhNetworkPingDialogThreadStart(
|
||||
__in PVOID Parameter
|
||||
)
|
||||
{
|
||||
BOOL result;
|
||||
MSG message;
|
||||
PH_AUTO_POOL autoPool;
|
||||
PNETWORK_OUTPUT_CONTEXT context = (PNETWORK_OUTPUT_CONTEXT)Parameter;
|
||||
|
||||
PhInitializeAutoPool(&autoPool);
|
||||
|
||||
context->WindowHandle = CreateDialogParam(
|
||||
(HINSTANCE)PluginInstance->DllBase,
|
||||
MAKEINTRESOURCE(IDD_PINGDIALOG),
|
||||
PhMainWndHandle,
|
||||
NetworkPingWndProc,
|
||||
(LPARAM)Parameter
|
||||
);
|
||||
|
||||
ShowWindow(context->WindowHandle, SW_SHOW);
|
||||
SetForegroundWindow(context->WindowHandle);
|
||||
|
||||
while (result = GetMessage(&message, NULL, 0, 0))
|
||||
{
|
||||
//Ping statistics for %s:
|
||||
// Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
|
||||
//Approximate round trip times in milli-seconds:
|
||||
// Minimum = 202ms, Maximum = 207ms, Average = 204ms
|
||||
PPH_STRING buffer = PhFormatString(
|
||||
L"\r\nPing statistics for %s:\r\n"
|
||||
L" Packets: Sent = %d, Received = %d, Lost = %d (%.0f%% loss)\r\n",
|
||||
context->addressString,
|
||||
maxPingCount,
|
||||
pingReplyCount,
|
||||
pingLossCount,
|
||||
(FLOAT)(pingLossCount / maxPingCount) * 100.0f
|
||||
);
|
||||
PPH_STRING buffer2 = PhFormatString(
|
||||
L"Approximate round trip times in milliseconds:\r\n"
|
||||
L" Minimum = 0ms, Maximum = 0ms, Average = 0ms\r\n\r\n"
|
||||
);
|
||||
SendMessage(context->WindowHandle, NTM_RECEIVEDPING, (WPARAM)buffer, 0);
|
||||
SendMessage(context->WindowHandle, NTM_RECEIVEDPING, (WPARAM)buffer2, 0);
|
||||
if (result == -1)
|
||||
break;
|
||||
|
||||
if (!IsDialogMessage(context->WindowHandle, &message))
|
||||
{
|
||||
TranslateMessage(&message);
|
||||
DispatchMessage(&message);
|
||||
}
|
||||
|
||||
PhDrainAutoPool(&autoPool);
|
||||
}
|
||||
|
||||
if (icmpReplyBuffer)
|
||||
{
|
||||
PhFree(icmpReplyBuffer);
|
||||
icmpReplyBuffer = NULL;
|
||||
}
|
||||
|
||||
IcmpCloseHandle(icmpHandle);
|
||||
WSACleanup();
|
||||
|
||||
Button_Enable(GetDlgItem(context->WindowHandle, IDC_NETRETRY), TRUE);
|
||||
PhDeleteAutoPool(&autoPool);
|
||||
DestroyWindow(context->WindowHandle);
|
||||
PhFree(context);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
#define ID_TOOLS_PING 101
|
||||
#define IDD_OUTPUT 101
|
||||
#define ID_TOOLS_TRACEROUTE 102
|
||||
#define IDD_PINGDIALOG 102
|
||||
#define ID_TOOLS_WHOIS 103
|
||||
#define IDD_OPTIONS 109
|
||||
#define IDC_NETRESOLVECHECK 1001
|
||||
@@ -12,16 +13,21 @@
|
||||
#define IDC_MAXPINGTEXT 1007
|
||||
#define IDC_MAXTIMEOUTTEXT 1008
|
||||
#define IDC_NETOUTPUTEDIT 1008
|
||||
#define IDC_COMBOBOXEX1 1009
|
||||
#define IDC_COMBOCMD 1009
|
||||
#define IDC_CUSTOM1 1010
|
||||
#define IDC_STATIC3 1012
|
||||
#define IDC_STATIC5 1014
|
||||
#define IDC_STATIC6 1015
|
||||
#define IDC_STATIC7 1016
|
||||
#define IDC_STATIC8 1017
|
||||
#define IDC_MAINTEXT 1018
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_RESOURCE_VALUE 103
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1010
|
||||
#define _APS_NEXT_CONTROL_VALUE 1019
|
||||
#define _APS_NEXT_SYMED_VALUE 104
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user