blob: d863a669023a0816b0dad98b4158653e922b3a91 (
plain)
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
|
#ifndef DDK_THREAD
#define DDK_THREAD 1
#include <ntddk.h>
extern "C" void InterceptorThreadRoutine(PVOID threadContext);
namespace DriverThread
{
class WorkItem;
typedef NTSTATUS (*threadRoutine_t)(PVOID);
typedef NTSTATUS (*workerRoutine_t)(WorkItem * item);
class Mutex
{
public:
Mutex(void);
~Mutex(void);
private:
void Lock();
void Unlock();
volatile long int m_interlock;
friend class LockGuard;
};
class LockGuard
{
public:
LockGuard(Mutex & m);
~LockGuard(void);
private:
Mutex m_Lock;
};
class Thread
{
public:
Thread(void);
~Thread(void);
NTSTATUS Start(threadRoutine_t routine, PVOID threadContext);
NTSTATUS WaitForTermination(LONGLONG timeout = 0);
HANDLE GetThreadId(void);
private:
friend void ::InterceptorThreadRoutine(PVOID threadContext);
HANDLE m_threadId = nullptr;
PETHREAD m_threadObject = nullptr;
Mutex m_mutex;
threadRoutine_t m_routine;
PVOID m_threadContext;
};
class Spinlock
{
public:
Spinlock(void);
NTSTATUS Acquire(void);
void Release(void);
KIRQL GetOldIrql(void);
private:
KIRQL m_oldIrql;
KSPIN_LOCK m_spinLock;
};
class Semaphore
{
public:
Semaphore(LONG initialValue = 0, LONG maxValue = MAXLONG);
NTSTATUS Wait(LONGLONG timeout = 0);
LONG Release(LONG adjustment = 1);
private:
KSEMAPHORE m_semaphore;
};
class WorkItem
{
public:
SLIST_ENTRY QueueEntry;
PSLIST_ENTRY WorkListEntry;
};
class WorkQueue
{
public:
WorkQueue(void);
~WorkQueue(void);
NTSTATUS Start(workerRoutine_t workerRoutine);
void Stop(void);
void Enqueue(WorkItem * item);
private:
Mutex m_mutex;
SLIST_HEADER m_work;
KEVENT m_wakeEvent;
BOOLEAN m_stopWorker; // Work LIST must be empty and StopWorker TRUE to be able to stop!
Thread m_worker;
workerRoutine_t m_workerRoutine;
static NTSTATUS WorkerInterceptorRoutine(PVOID workerContext);
};
}; // namespace DriverThread
#endif
|