forked from winsiderss/systeminformer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtreeext.c
More file actions
296 lines (252 loc) · 7.65 KB
/
Copy pathtreeext.c
File metadata and controls
296 lines (252 loc) · 7.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
/*
* Process Hacker .NET Tools -
* thread list extensions
*
* Copyright (C) 2015 wj32
*
* 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 "dn.h"
#include "clrsup.h"
VOID NTAPI ThreadsContextCreateCallback(
_In_ PVOID Object,
_In_ PH_EM_OBJECT_TYPE ObjectType,
_In_ PVOID Extension
);
VOID NTAPI ThreadsContextDeleteCallback(
_In_ PVOID Object,
_In_ PH_EM_OBJECT_TYPE ObjectType,
_In_ PVOID Extension
);
VOID ThreadTreeNewMessage(
_In_ PVOID Parameter
);
LONG ThreadTreeNewSortFunction(
_In_ PVOID Node1,
_In_ PVOID Node2,
_In_ ULONG SubId,
_In_ PVOID Context
);
#define THREAD_TREE_CONTEXT_TYPE 1
typedef struct _THREAD_TREE_CONTEXT
{
ULONG Type;
HANDLE ProcessId;
PH_CALLBACK_REGISTRATION AddedCallbackRegistration;
PCLR_PROCESS_SUPPORT Support;
} THREAD_TREE_CONTEXT, *PTHREAD_TREE_CONTEXT;
static PPH_HASHTABLE ContextHashtable;
static PH_QUEUED_LOCK ContextHashtableLock = PH_QUEUED_LOCK_INIT;
static PH_INITONCE ContextHashtableInitOnce = PH_INITONCE_INIT;
VOID InitializeTreeNewObjectExtensions(
VOID
)
{
PhPluginSetObjectExtension(
PluginInstance,
EmThreadsContextType,
sizeof(THREAD_TREE_CONTEXT),
ThreadsContextCreateCallback,
ThreadsContextDeleteCallback
);
}
VOID AddTreeNewColumn(
_In_ PPH_PLUGIN_TREENEW_INFORMATION TreeNewInfo,
_In_ PVOID Context,
_In_ ULONG SubId,
_In_ BOOLEAN Visible,
_In_ PWSTR Text,
_In_ ULONG Width,
_In_ ULONG Alignment,
_In_ ULONG TextFlags,
_In_ BOOLEAN SortDescending,
_In_ PPH_PLUGIN_TREENEW_SORT_FUNCTION SortFunction
)
{
PH_TREENEW_COLUMN column;
memset(&column, 0, sizeof(PH_TREENEW_COLUMN));
column.Visible = Visible;
column.SortDescending = SortDescending;
column.Text = Text;
column.Width = Width;
column.Alignment = Alignment;
column.DisplayIndex = TreeNew_GetVisibleColumnCount(TreeNewInfo->TreeNewHandle);
column.TextFlags = TextFlags;
PhPluginAddTreeNewColumn(
PluginInstance,
TreeNewInfo->CmData,
&column,
SubId,
Context,
SortFunction
);
}
VOID DispatchTreeNewMessage(
_In_ PVOID Parameter
)
{
PPH_PLUGIN_TREENEW_MESSAGE message = Parameter;
switch (*(PULONG)message->Context)
{
case THREAD_TREE_CONTEXT_TYPE:
ThreadTreeNewMessage(Parameter);
break;
}
}
static VOID ThreadAddedHandler(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
)
{
PPH_THREAD_ITEM threadItem = Parameter;
PDN_THREAD_ITEM dnThread;
PTHREAD_TREE_CONTEXT context = Context;
dnThread = PhPluginGetObjectExtension(PluginInstance, threadItem, EmThreadItemType);
memset(dnThread, 0, sizeof(DN_THREAD_ITEM));
dnThread->ThreadItem = threadItem;
}
VOID NTAPI ThreadsContextCreateCallback(
_In_ PVOID Object,
_In_ PH_EM_OBJECT_TYPE ObjectType,
_In_ PVOID Extension
)
{
PPH_THREADS_CONTEXT threadsContext = Object;
PTHREAD_TREE_CONTEXT context = Extension;
memset(context, 0, sizeof(THREAD_TREE_CONTEXT));
context->Type = THREAD_TREE_CONTEXT_TYPE;
context->ProcessId = threadsContext->Provider->ProcessId;
PhRegisterCallback(
&threadsContext->Provider->ThreadAddedEvent,
ThreadAddedHandler,
context,
&context->AddedCallbackRegistration
);
}
VOID NTAPI ThreadsContextDeleteCallback(
_In_ PVOID Object,
_In_ PH_EM_OBJECT_TYPE ObjectType,
_In_ PVOID Extension
)
{
PPH_THREADS_CONTEXT threadsContext = Object;
PTHREAD_TREE_CONTEXT context = Extension;
PhUnregisterCallback(
&threadsContext->Provider->ThreadAddedEvent,
&context->AddedCallbackRegistration
);
if (context->Support)
FreeClrProcessSupport(context->Support);
}
VOID ThreadTreeNewInitializing(
_In_ PVOID Parameter
)
{
PPH_PLUGIN_TREENEW_INFORMATION info = Parameter;
PPH_THREADS_CONTEXT threadsContext;
PTHREAD_TREE_CONTEXT context;
BOOLEAN isDotNet;
threadsContext = info->SystemContext;
context = PhPluginGetObjectExtension(PluginInstance, threadsContext, EmThreadsContextType);
if (NT_SUCCESS(PhGetProcessIsDotNet(threadsContext->Provider->ProcessId, &isDotNet)) && isDotNet)
{
PCLR_PROCESS_SUPPORT support;
support = CreateClrProcessSupport(threadsContext->Provider->ProcessId);
if (!support)
return;
context->Support = support;
AddTreeNewColumn(info, context, DNTHTNC_APPDOMAIN, TRUE, L"AppDomain", 120, PH_ALIGN_LEFT, 0, FALSE, ThreadTreeNewSortFunction);
}
}
VOID ThreadTreeNewUninitializing(
_In_ PVOID Parameter
)
{
NOTHING;
}
VOID UpdateThreadClrData(
_In_ PTHREAD_TREE_CONTEXT Context,
_Inout_ PDN_THREAD_ITEM DnThread
)
{
if (!DnThread->ClrDataValid)
{
IXCLRDataProcess *process;
IXCLRDataTask *task;
IXCLRDataAppDomain *appDomain;
if (Context->Support)
process = Context->Support->DataProcess;
else
return;
if (SUCCEEDED(IXCLRDataProcess_GetTaskByOSThreadID(process, HandleToUlong(DnThread->ThreadItem->ThreadId), &task)))
{
if (SUCCEEDED(IXCLRDataTask_GetCurrentAppDomain(task, &appDomain)))
{
DnThread->AppDomainText = GetNameXClrDataAppDomain(appDomain);
IXCLRDataAppDomain_Release(appDomain);
}
IXCLRDataTask_Release(task);
}
DnThread->ClrDataValid = TRUE;
}
}
VOID ThreadTreeNewMessage(
_In_ PVOID Parameter
)
{
PPH_PLUGIN_TREENEW_MESSAGE message = Parameter;
PTHREAD_TREE_CONTEXT context = message->Context;
if (message->Message == TreeNewGetCellText)
{
PPH_TREENEW_GET_CELL_TEXT getCellText = message->Parameter1;
PPH_THREAD_NODE threadNode = (PPH_THREAD_NODE)getCellText->Node;
PDN_THREAD_ITEM dnThread;
dnThread = PhPluginGetObjectExtension(PluginInstance, threadNode->ThreadItem, EmThreadItemType);
switch (message->SubId)
{
case DNTHTNC_APPDOMAIN:
UpdateThreadClrData(context, dnThread);
getCellText->Text = PhGetStringRef(dnThread->AppDomainText);
break;
}
}
}
LONG ThreadTreeNewSortFunction(
_In_ PVOID Node1,
_In_ PVOID Node2,
_In_ ULONG SubId,
_In_ PVOID Context
)
{
PTHREAD_TREE_CONTEXT context = Context;
LONG result;
PPH_THREAD_NODE node1 = Node1;
PPH_THREAD_NODE node2 = Node2;
PDN_THREAD_ITEM dnThread1;
PDN_THREAD_ITEM dnThread2;
dnThread1 = PhPluginGetObjectExtension(PluginInstance, node1->ThreadItem, EmThreadItemType);
dnThread2 = PhPluginGetObjectExtension(PluginInstance, node2->ThreadItem, EmThreadItemType);
result = 0;
switch (SubId)
{
case DNTHTNC_APPDOMAIN:
UpdateThreadClrData(context, dnThread1);
UpdateThreadClrData(context, dnThread2);
result = PhCompareStringWithNull(dnThread1->AppDomainText, dnThread2->AppDomainText, TRUE);
break;
}
return result;
}