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
|
// Copyright (C) Microsoft Corporation. All rights reserved.
#include "pch.hpp"
//#include <ntassert.h>
#include "enlthreads.h"
#ifdef _KERNEL_MODE
unique_thread::operator bool(
void
) const
{
return !!NtHandle;
}
void unique_thread::reset(
)
{
NtHandle.reset();
ObHandle.reset();
}
#endif
ENL_THREAD
EnlGetCurrentThread(
void
)
{
#ifdef _KERNEL_MODE
return KeGetCurrentThread();
#else
return GetCurrentThreadId();
#endif
}
_Use_decl_annotations_
NTSTATUS
EnlThreadCreate(
ENL_START_ROUTINE StartRoutine,
void * Context,
unique_thread & Thread
)
{
#ifdef _KERNEL_MODE
unique_zw_handle ntHandle;
unique_pkthread obHandle;
auto const ntStatus = PsCreateSystemThread(
&ntHandle,
THREAD_ALL_ACCESS,
nullptr,
nullptr,
nullptr,
StartRoutine,
Context);
if (ntStatus != STATUS_SUCCESS)
{
return ntStatus;
}
NT_FRE_ASSERT(
NT_SUCCESS(
ObReferenceObjectByHandle(
ntHandle.get(),
THREAD_ALL_ACCESS,
nullptr,
KernelMode,
reinterpret_cast<void **>(&obHandle),
nullptr)));
Thread.NtHandle = wistd::move(ntHandle);
Thread.ObHandle = wistd::move(obHandle);
#else
wil::unique_handle thread{ CreateThread(nullptr, 0, StartRoutine, Context, 0, nullptr) };
if (!thread)
{
return NTSTATUS_FROM_WIN32(GetLastError());
}
Thread = wistd::move(thread);
#endif
return STATUS_SUCCESS;
}
void
EnlThreadSetPriority(
unique_thread & Thread,
ENL_THREAD_PRIORITY Priority
)
{
#ifdef _KERNEL_MODE
// KeSetBasePriorityThread does not take the actual priority, but an increment
// to be added to the current base priority. Calculate this value.
auto const increment = Priority - (LOW_REALTIME_PRIORITY + LOW_PRIORITY) / 2;
KeSetBasePriorityThread(Thread.ObHandle.get(), increment);
#else
SetThreadPriority(Thread.get(), Priority);
#endif
}
_Use_decl_annotations_
void
EnlThreadSetAffinity(
PGROUP_AFFINITY GroupAffinity,
PGROUP_AFFINITY PreviousAffinity
)
{
#ifdef _KERNEL_MODE
KeSetSystemGroupAffinityThread(GroupAffinity, PreviousAffinity);
#else
SetThreadGroupAffinity(GetCurrentThread(), GroupAffinity, PreviousAffinity);
#endif
}
_Use_decl_annotations_
void
EnlThreadWaitForTermination(
unique_thread & Thread
)
{
#ifdef _KERNEL_MODE
KeWaitForSingleObject(
Thread.ObHandle.get(),
KWAIT_REASON::Executive,
KernelMode,
FALSE,
nullptr);
#else
WaitForSingleObject(
Thread.get(),
INFINITE);
#endif
}
|