1 /*
2  * PROJECT:         ReactOS kernel-mode tests
3  * LICENSE:         GPLv2+ - See COPYING in the top level directory
4  * PURPOSE:         Kernel-Mode Test Suite Process Notification Routines test
5  * PROGRAMMER:      Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #include <kmt_test.h>
9 
10 //#define NDEBUG
11 #include <debug.h>
12 
13 static
14 VOID
15 NTAPI
CreateProcessNotifyRoutine(IN HANDLE ParentId,IN HANDLE ProcessId,IN BOOLEAN Create)16 CreateProcessNotifyRoutine(
17     IN HANDLE ParentId,
18     IN HANDLE ProcessId,
19     IN BOOLEAN Create)
20 {
21     ok_irql(PASSIVE_LEVEL);
22     if (!Create)
23         ok_eq_pointer(ProcessId, PsGetCurrentProcessId());
24     else
25         ok(ProcessId != PsGetCurrentProcessId(),
26            "ProcessId %p equals current\n", ProcessId);
27     DPRINT("%s(%p, %p, %d)\n", __FUNCTION__, ParentId, ProcessId, Create);
28 }
29 
30 static
31 VOID
TestCreateProcessNotify(VOID)32 TestCreateProcessNotify(VOID)
33 {
34     NTSTATUS Status;
35 
36     Status = PsSetCreateProcessNotifyRoutine(NULL, TRUE);
37     ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
38 
39     Status = PsSetCreateProcessNotifyRoutine(NULL, FALSE);
40     ok_eq_hex(Status, STATUS_SUCCESS);
41 
42     Status = PsSetCreateProcessNotifyRoutine(NULL, TRUE);
43     ok_eq_hex(Status, STATUS_SUCCESS);
44 
45     Status = PsSetCreateProcessNotifyRoutine(NULL, TRUE);
46     ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
47 
48     Status = PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine, TRUE);
49     ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
50 
51     Status = PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine, FALSE);
52     ok_eq_hex(Status, STATUS_SUCCESS);
53 
54     /* TODO: test whether the callback is notified on process creation */
55 
56     Status = PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine, TRUE);
57     ok_eq_hex(Status, STATUS_SUCCESS);
58 
59     Status = PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine, TRUE);
60     ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
61 
62     /* TODO: register the same routine twice */
63     /* TODO: register more than the maximum number of notifications */
64 }
65 
66 static
67 VOID
68 NTAPI
CreateThreadNotifyRoutine(IN HANDLE ProcessId,IN HANDLE ThreadId,IN BOOLEAN Create)69 CreateThreadNotifyRoutine(
70     IN HANDLE ProcessId,
71     IN HANDLE ThreadId,
72     IN BOOLEAN Create)
73 {
74     ok_irql(PASSIVE_LEVEL);
75     if (!Create)
76     {
77         ok_eq_pointer(ProcessId, PsGetCurrentProcessId());
78         ok_eq_pointer(ThreadId, PsGetCurrentThreadId());
79     }
80     else
81     {
82         ok(ThreadId != PsGetCurrentThreadId(),
83            "ThreadId %p equals current\n", ThreadId);
84     }
85     DPRINT("%s(%p, %p, %d)\n", __FUNCTION__, ProcessId, ThreadId, Create);
86 }
87 
88 static
89 VOID
TestCreateThreadNotify(VOID)90 TestCreateThreadNotify(VOID)
91 {
92     NTSTATUS Status;
93 
94     Status = PsRemoveCreateThreadNotifyRoutine(NULL);
95     ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
96 
97     Status = PsSetCreateThreadNotifyRoutine(NULL);
98     ok_eq_hex(Status, STATUS_SUCCESS);
99 
100     Status = PsRemoveCreateThreadNotifyRoutine(NULL);
101     ok_eq_hex(Status, STATUS_SUCCESS);
102 
103     Status = PsRemoveCreateThreadNotifyRoutine(NULL);
104     ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
105 
106     Status = PsRemoveCreateThreadNotifyRoutine(CreateThreadNotifyRoutine);
107     ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
108 
109     Status = PsSetCreateThreadNotifyRoutine(CreateThreadNotifyRoutine);
110     ok_eq_hex(Status, STATUS_SUCCESS);
111 
112     /* TODO: test whether the callback is notified on thread creation */
113 
114     Status = PsRemoveCreateThreadNotifyRoutine(CreateThreadNotifyRoutine);
115     ok_eq_hex(Status, STATUS_SUCCESS);
116 
117     Status = PsRemoveCreateThreadNotifyRoutine(CreateThreadNotifyRoutine);
118     ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
119 
120     /* TODO: register the same routine twice */
121     /* TODO: register more than the maximum number of notifications */
122 }
123 
124 static
125 VOID
126 NTAPI
LoadImageNotifyRoutine(IN PUNICODE_STRING FullImageName OPTIONAL,IN HANDLE ProcessId,IN PIMAGE_INFO ImageInfo)127 LoadImageNotifyRoutine(
128     IN PUNICODE_STRING FullImageName OPTIONAL,
129     IN HANDLE ProcessId,
130     IN PIMAGE_INFO ImageInfo)
131 {
132     ok_irql(PASSIVE_LEVEL);
133     DPRINT("%s('%wZ', %p, %p)\n", __FUNCTION__, FullImageName, ProcessId, ImageInfo);
134 }
135 
136 static
137 VOID
TestLoadImageNotify(VOID)138 TestLoadImageNotify(VOID)
139 {
140     NTSTATUS Status;
141 
142     Status = PsRemoveLoadImageNotifyRoutine(NULL);
143     ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
144 
145     Status = PsSetLoadImageNotifyRoutine(NULL);
146     ok_eq_hex(Status, STATUS_SUCCESS);
147 
148     Status = PsRemoveLoadImageNotifyRoutine(NULL);
149     ok_eq_hex(Status, STATUS_SUCCESS);
150 
151     Status = PsRemoveLoadImageNotifyRoutine(NULL);
152     ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
153 
154     Status = PsRemoveLoadImageNotifyRoutine(LoadImageNotifyRoutine);
155     ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
156 
157     Status = PsSetLoadImageNotifyRoutine(LoadImageNotifyRoutine);
158     ok_eq_hex(Status, STATUS_SUCCESS);
159 
160     /* TODO: test whether the callback is notified on image load */
161 
162     Status = PsRemoveLoadImageNotifyRoutine(LoadImageNotifyRoutine);
163     ok_eq_hex(Status, STATUS_SUCCESS);
164 
165     Status = PsRemoveLoadImageNotifyRoutine(LoadImageNotifyRoutine);
166     ok_eq_hex(Status, STATUS_PROCEDURE_NOT_FOUND);
167 
168     /* TODO: register the same routine twice */
169     /* TODO: register more than the maximum number of notifications */
170 }
171 
START_TEST(PsNotify)172 START_TEST(PsNotify)
173 {
174     TestCreateProcessNotify();
175     TestCreateThreadNotify();
176     TestLoadImageNotify();
177 }
178