Files
mirror-processhacker/2.x/trunk/plugins/NetworkTools/output.c
T
dmex 0634884ba4 NetworkTools: fixed options dialog crash/settings issues
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@5463 21ef857c-d57f-4fe0-8362-d861dc6d29cd
2013-10-11 14:51:37 +00:00

357 lines
12 KiB
C

/*
* Process Hacker Network Tools -
* output 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"
static RECT MinimumSize = { -1, -1, -1, -1 };
static 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);
PhDeleteStringBuilder(&context->ReceivedString);
RemoveProp(hwndDlg, L"Context");
}
}
if (!context)
return FALSE;
switch (uMsg)
{
case WM_INITDIALOG:
{
PH_RECTANGLE windowRectangle;
HANDLE dialogThread = INVALID_HANDLE_VALUE;
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);
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
windowRectangle.Position = PhGetIntegerPairSetting(SETTING_NAME_TRACERT_WINDOW_POSITION);
windowRectangle.Size = PhGetIntegerPairSetting(SETTING_NAME_TRACERT_WINDOW_SIZE);
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->addressString);
}
else
{
RtlIpv6AddressToString(&context->IpAddress.In6Addr, context->addressString);
}
switch (context->Action)
{
case NETWORK_ACTION_TRACEROUTE:
{
if (dialogThread = PhCreateThread(0, (PUSER_THREAD_START_ROUTINE)NetworkTracertThreadStart, (PVOID)context))
NtClose(dialogThread);
}
break;
case NETWORK_ACTION_WHOIS:
{
if (dialogThread = PhCreateThread(0, (PUSER_THREAD_START_ROUTINE)NetworkWhoisThreadStart, (PVOID)context))
NtClose(dialogThread);
}
break;
}
}
break;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_NETRETRY:
Button_Enable(GetDlgItem(hwndDlg, IDC_NETRETRY), FALSE);
break;
case IDCANCEL:
case IDOK:
PostQuitMessage(0);
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;
ULONG hwndChildID = 0;
// Check if old graph colors are enabled.
if (!PhGetIntegerSetting(L"GraphColorMode"))
break;
// Get the control ID.
hwndChildID = GetDlgCtrlID(hwndChild);
// Set a transparent background for the control backcolor.
SetBkMode(hDC, TRANSPARENT);
// Check for our edit control and change the color.
if (hwndChildID == IDC_NETOUTPUTEDIT)
{
// 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 NTM_RECEIVEDTRACE:
{
OEM_STRING inputString;
UNICODE_STRING convertedString;
if (wParam != 0)
{
inputString.Buffer = (PCHAR)lParam;
inputString.Length = (USHORT)wParam;
if (NT_SUCCESS(RtlOemStringToUnicodeString(&convertedString, &inputString, TRUE)))
{
PhAppendStringBuilderEx(&context->ReceivedString, convertedString.Buffer, convertedString.Length);
RtlFreeUnicodeString(&convertedString);
// Remove leading newlines.
if (context->ReceivedString.String->Length >= 2 * 2 &&
context->ReceivedString.String->Buffer[0] == '\r' &&
context->ReceivedString.String->Buffer[1] == '\n')
{
PhRemoveStringBuilder(&context->ReceivedString, 0, 2);
}
SetDlgItemText(hwndDlg, IDC_NETOUTPUTEDIT, context->ReceivedString.String->Buffer);
SendMessage(
GetDlgItem(hwndDlg, IDC_NETOUTPUTEDIT),
EM_SETSEL,
context->ReceivedString.String->Length / 2 - 1,
context->ReceivedString.String->Length / 2 - 1
);
SendMessage(GetDlgItem(hwndDlg, IDC_NETOUTPUTEDIT), WM_VSCROLL, SB_BOTTOM, 0);
return TRUE;
}
}
}
break;
case NTM_RECEIVEDWHOIS:
{
OEM_STRING inputString;
UNICODE_STRING convertedString;
PH_STRING_BUILDER receivedString;
if (wParam != 0)
{
inputString.Buffer = (PCHAR)lParam;
inputString.Length = (USHORT)wParam;
PhInitializeStringBuilder(&receivedString, PAGE_SIZE);
if (NT_SUCCESS(RtlOemStringToUnicodeString(&convertedString, &inputString, TRUE)))
{
SIZE_T i;
// Remove leading newlines.
for (i = 0; i < inputString.Length; i++)
{
if (inputString.Buffer[i] == '\n')
{
PhAppendStringBuilder(&receivedString, PhaCreateString(L"\r\n"));
}
else if (inputString.Buffer[i] == '#')
{
// Skip
}
else
{
PhAppendCharStringBuilder(&receivedString, inputString.Buffer[i]);
}
}
if (receivedString.String->Length >= 2 * 2 &&
receivedString.String->Buffer[0] == '\r' &&
receivedString.String->Buffer[1] == '\n')
{
PhRemoveStringBuilder(&receivedString, 0, 4);
}
SetDlgItemText(hwndDlg, IDC_NETOUTPUTEDIT, receivedString.String->Buffer);
SendMessage(
GetDlgItem(hwndDlg, IDC_NETOUTPUTEDIT),
EM_SETSEL,
receivedString.String->Length / 2 - 1,
receivedString.String->Length / 2 - 1
);
SendMessage(GetDlgItem(hwndDlg, IDC_NETOUTPUTEDIT), WM_VSCROLL, SB_BOTTOM, 0);
PhDeleteStringBuilder(&receivedString);
return TRUE;
}
}
}
break;
}
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 = -15;
logFont.lfWeight = 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 PH_NETWORK_ACTION 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;
context->IpAddress = NetworkItem->RemoteEndpoint.Address;
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);
}
}