1 /*
2  * PROJECT:         ReactOS kernel-mode tests
3  * LICENSE:         LGPLv2.1+ - See COPYING.LIB in the top level directory
4  * PURPOSE:         Kernel-Mode Test Suite test framework declarations
5  * PROGRAMMER:      Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #ifndef _KMTEST_TEST_KERNEL_H_
9 #define _KMTEST_TEST_KERNEL_H_
10 
11 #if !defined _KMTEST_TEST_H_
12 #error include kmt_test.h instead of including kmt_test_kernel.h
13 #endif /* !defined _KMTEST_TEST_H_ */
14 
15 BOOLEAN KmtIsCheckedBuild;
16 BOOLEAN KmtIsMultiProcessorBuild;
17 PCSTR KmtMajorFunctionNames[] =
18 {
19     "Create",
20     "CreateNamedPipe",
21     "Close",
22     "Read",
23     "Write",
24     "QueryInformation",
25     "SetInformation",
26     "QueryEa",
27     "SetEa",
28     "FlushBuffers",
29     "QueryVolumeInformation",
30     "SetVolumeInformation",
31     "DirectoryControl",
32     "FileSystemControl",
33     "DeviceControl",
34     "InternalDeviceControl/Scsi",
35     "Shutdown",
36     "LockControl",
37     "Cleanup",
38     "CreateMailslot",
39     "QuerySecurity",
40     "SetSecurity",
41     "Power",
42     "SystemControl",
43     "DeviceChange",
44     "QueryQuota",
45     "SetQuota",
46     "Pnp/PnpPower"
47 };
48 
49 VOID KmtSetIrql(IN KIRQL NewIrql)
50 {
51     KIRQL Irql = KeGetCurrentIrql();
52     if (Irql > NewIrql)
53         KeLowerIrql(NewIrql);
54     else if (Irql < NewIrql)
55         KeRaiseIrql(NewIrql, &Irql);
56 }
57 
58 BOOLEAN KmtAreInterruptsEnabled(VOID)
59 {
60     return (__readeflags() & (1 << 9)) != 0;
61 }
62 
63 typedef struct _POOL_HEADER
64 {
65     union
66     {
67         struct
68         {
69 #ifdef _M_AMD64
70             USHORT PreviousSize:8;
71             USHORT PoolIndex:8;
72             USHORT BlockSize:8;
73             USHORT PoolType:8;
74 #else
75             USHORT PreviousSize:9;
76             USHORT PoolIndex:7;
77             USHORT BlockSize:9;
78             USHORT PoolType:7;
79 #endif
80         };
81         ULONG Ulong1;
82     };
83 #ifdef _M_AMD64
84     ULONG PoolTag;
85 #endif
86     union
87     {
88 #ifdef _M_AMD64
89         PEPROCESS ProcessBilled;
90 #else
91         ULONG PoolTag;
92 #endif
93         struct
94         {
95             USHORT AllocatorBackTraceIndex;
96             USHORT PoolTagHash;
97         };
98     };
99 } POOL_HEADER, *PPOOL_HEADER;
100 
101 ULONG KmtGetPoolTag(PVOID Memory)
102 {
103     PPOOL_HEADER Header;
104 
105     /* it's not so easy for allocations of PAGE_SIZE */
106     if (((ULONG_PTR)Memory & (PAGE_SIZE - 1)) == 0)
107         return 'TooL';
108 
109     Header = Memory;
110     Header--;
111 
112     return Header->PoolTag;
113 }
114 
115 USHORT KmtGetPoolType(PVOID Memory)
116 {
117     PPOOL_HEADER Header;
118 
119     /* it's not so easy for allocations of PAGE_SIZE */
120     if (((ULONG_PTR)Memory & (PAGE_SIZE - 1)) == 0)
121         return 0;
122 
123     Header = Memory;
124     Header--;
125 
126     return Header->PoolType;
127 }
128 
129 PVOID KmtGetSystemRoutineAddress(IN PCWSTR RoutineName)
130 {
131     UNICODE_STRING RoutineNameString;
132     RtlInitUnicodeString(&RoutineNameString, (PWSTR)RoutineName);
133     return MmGetSystemRoutineAddress(&RoutineNameString);
134 }
135 
136 PKTHREAD KmtStartThread(IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext OPTIONAL)
137 {
138     NTSTATUS Status;
139     OBJECT_ATTRIBUTES ObjectAttributes;
140     HANDLE ThreadHandle;
141     PVOID ThreadObject = NULL;
142 
143     InitializeObjectAttributes(&ObjectAttributes,
144                                NULL,
145                                OBJ_KERNEL_HANDLE,
146                                NULL,
147                                NULL);
148     ThreadHandle = INVALID_HANDLE_VALUE;
149     Status = PsCreateSystemThread(&ThreadHandle,
150                                   SYNCHRONIZE,
151                                   &ObjectAttributes,
152                                   NULL,
153                                   NULL,
154                                   StartRoutine,
155                                   StartContext);
156     ok_eq_hex(Status, STATUS_SUCCESS);
157     if (!skip(NT_SUCCESS(Status) && ThreadHandle != NULL && ThreadHandle != INVALID_HANDLE_VALUE, "No thread\n"))
158     {
159         Status = ObReferenceObjectByHandle(ThreadHandle,
160                                            SYNCHRONIZE,
161                                            *PsThreadType,
162                                            KernelMode,
163                                            &ThreadObject,
164                                            NULL);
165         ok_eq_hex(Status, STATUS_SUCCESS);
166         ObCloseHandle(ThreadHandle, KernelMode);
167     }
168     return ThreadObject;
169 }
170 
171 VOID KmtFinishThread(IN PKTHREAD Thread OPTIONAL, IN PKEVENT Event OPTIONAL)
172 {
173     NTSTATUS Status;
174 
175     if (skip(Thread != NULL, "No thread\n"))
176         return;
177 
178     if (Event)
179         KeSetEvent(Event, IO_NO_INCREMENT, TRUE);
180     Status = KeWaitForSingleObject(Thread,
181                                    Executive,
182                                    KernelMode,
183                                    FALSE,
184                                    NULL);
185     ok_eq_hex(Status, STATUS_SUCCESS);
186     ObDereferenceObject(Thread);
187 }
188 
189 INT __cdecl KmtVSNPrintF(PSTR Buffer, SIZE_T BufferMaxLength, PCSTR Format, va_list Arguments) KMT_FORMAT(ms_printf, 3, 0);
190 
191 #endif /* !defined _KMTEST_TEST_KERNEL_H_ */
192