Process Hacker
tracert.c
Go to the documentation of this file.
1 /*
2  * Process Hacker Network Tools -
3  * Tracert dialog
4  *
5  * Copyright (C) 2013 dmex
6  *
7  * This file is part of Process Hacker.
8  *
9  * Process Hacker is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * Process Hacker is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #include "nettools.h"
24 
25 static NTSTATUS StdOutNetworkTracertThreadStart(
26  _In_ PVOID Parameter
27  )
28 {
29  NTSTATUS status;
31  IO_STATUS_BLOCK isb;
32  UCHAR buffer[PAGE_SIZE];
33 
34  while (TRUE)
35  {
36  status = NtReadFile(
37  context->PipeReadHandle,
38  NULL,
39  NULL,
40  NULL,
41  &isb,
42  buffer,
43  sizeof(buffer),
44  NULL,
45  NULL
46  );
47 
48  if (!NT_SUCCESS(status))
49  break;
50 
51  SendMessage(context->WindowHandle, NTM_RECEIVEDTRACE, (WPARAM)isb.Information, (LPARAM)buffer);
52  }
53 
54  SendMessage(context->WindowHandle, NTM_RECEIVEDFINISH, 0, 0);
55 
56  return STATUS_SUCCESS;
57 }
58 
60  _In_ PVOID Parameter
61  )
62 {
63  HANDLE pipeWriteHandle = INVALID_HANDLE_VALUE;
65 
66  if (CreatePipe(&context->PipeReadHandle, &pipeWriteHandle, NULL, 0))
67  {
68  HANDLE threadHandle = NULL;
69  STARTUPINFO startupInfo = { sizeof(startupInfo) };
71  PPH_STRING command = NULL;
72 
73  startupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
74  startupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
75  startupInfo.hStdOutput = pipeWriteHandle;
76  startupInfo.hStdError = pipeWriteHandle;
77  startupInfo.wShowWindow = SW_HIDE;
78 
79  if (PhGetIntegerSetting(L"EnableNetworkResolve"))
80  {
81  command = PhFormatString(
82  L"%s\\system32\\tracert.exe %s",
83  USER_SHARED_DATA->NtSystemRoot,
84  context->IpAddressString
85  );
86  }
87  else
88  {
89  // Disable hostname lookup.
90  command = PhFormatString(
91  L"%s\\system32\\tracert.exe -d %s",
92  USER_SHARED_DATA->NtSystemRoot,
93  context->IpAddressString
94  );
95  }
96 
97  // Allow the write handle to be inherited.
98  flagInfo.Inherit = TRUE;
99  flagInfo.ProtectFromClose = FALSE;
100 
101  NtSetInformationObject(
102  pipeWriteHandle,
104  &flagInfo,
106  );
107 
109  NULL,
110  command->Buffer,
111  NULL,
112  NULL,
113  &startupInfo,
115  NULL,
116  NULL,
117  &context->ProcessHandle,
118  NULL
119  );
120 
121  // Essential; when the process exits, the last instance of the pipe will be disconnected and our thread will exit.
122  NtClose(pipeWriteHandle);
123 
124  // Create a thread which will wait for output and display it.
125  if (threadHandle = PhCreateThread(0, StdOutNetworkTracertThreadStart, context))
126  NtClose(threadHandle);
127  }
128 
129  return STATUS_SUCCESS;
130 }