aboutsummaryrefslogtreecommitdiff
path: root/examples/dpp-example-cplusplus.cpp
blob: cbdd7c604f73081f4ef076ca5b6cd0e29fddbaaa (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
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
#include <ntddk.h>

#include <DriverThread.hpp>

class TestSmth
{
public:
    TestSmth()
    {
        DbgPrint("%s\n", "ctor");
    }
    ~TestSmth()
    {
        DbgPrint("%s\n", "dtor");
    }
    void doSmth(void)
    {
        DbgPrint("%s\n", "Hello Class!");
    }
};
static TestSmth * cdtor_test;

class Derived : public TestSmth
{
public:
    Derived()
    {
    }
    ~Derived()
    {
    }
    void doSmth(void)
    {
        DbgPrint("%s\n", "Hello Derived!");
    }
};

class DerivedWithCDtor : public Derived
{
public:
    explicit DerivedWithCDtor(unsigned int value)
    {
        some_value = value;
        DbgPrint("%s\n", "DerivedWithCDtor-Ctor.");
    }
    ~DerivedWithCDtor()
    {
        DbgPrint("%s\n", "DerivedWithCDtor-Dtor.");
    }
    void doSmth(void)
    {
        DbgPrint("SomeValue: %X\n", some_value);
    }

private:
    unsigned int some_value = 0;
};

class MyWorkItem : public DriverThread::WorkItem
{
public:
    UINT32 counter;
};

static DriverThread::WorkQueue work_queue;
static DerivedWithCDtor some_static(0xDEADC0DE);

struct threadContext
{
    DriverThread::Semaphore sem;
    DriverThread::Thread dth;
};

static NTSTATUS threadRoutine(PVOID threadContext)
{
    DbgPrint("ThreadRoutine %p, ThreadContext: %p\n", threadRoutine, threadContext);
    for (size_t i = 3; i > 0; --i)
    {
        DbgPrint("ThreadLoop: %zu\n", i);
    }
    struct threadContext * const ctx = (struct threadContext *)threadContext;
    DbgPrint("Fin. ThreadId: %p\n", ctx->dth.GetThreadId());
    ctx->sem.Release();
    DbgPrint("Thread WaitForTermination: 0x%X\n", ctx->dth.WaitForTermination()); // must return STATUS_UNSUCCESSFUL;

    return STATUS_SUCCESS;
}

static void test_cplusplus(void)
{
    TestSmth t;
    t.doSmth();
    Derived d;
    d.doSmth();

    struct threadContext ctx;
    ctx.dth.Start(threadRoutine, (PVOID)&ctx);
    ctx.sem.Wait();
    DbgPrint("MainThread semaphore signaled.\n");
    ctx.dth.WaitForTermination();
    ctx.dth.WaitForTermination();
    DbgPrint("MainThread EOF\n");

    MyWorkItem * wi = new MyWorkItem();
    wi->counter = 3;
    work_queue.Enqueue(wi);
    work_queue.Start(
        [](DriverThread::WorkItem * item)
        {
            MyWorkItem * wi =
                reinterpret_cast<MyWorkItem *>(CONTAINING_RECORD(item, DriverThread::WorkItem, QueueEntry));

            while (wi->counter-- > 0)
            {
                DbgPrint("WorkItem Counter: %u\n", wi->counter);
            }
            DbgPrint("Worker finished.\n");

            delete item;
            return STATUS_SUCCESS;
        });
    work_queue.Stop();

    some_static.doSmth();
}

extern "C"
{

    DRIVER_INITIALIZE DriverEntry;
    DRIVER_UNLOAD DriverUnload;

    NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
    {
        (void)DriverObject;
        (void)RegistryPath;

        DbgPrint("%s\n", "Hello ring0!");
        cdtor_test = new TestSmth();

        test_cplusplus();

        return STATUS_SUCCESS;
    }

    VOID DriverUnload(PDRIVER_OBJECT DriverObject)
    {
        (void)DriverObject;

        delete cdtor_test;
        DbgPrint("%s\n", "Bye ring0!");
    }
}