2025-05-13 19:45:22 +03:00

158 lines
4.8 KiB
C

/*
* 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;
}