2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
4 * PURPOSE: Kernel-Mode Test Suite test framework declarations
5 * COPYRIGHT: Copyright 2011-2018 Thomas Faber <thomas.faber@reactos.org>
6 * Copyright 2013 Nikolay Borisov <nib9@aber.ac.uk>
7 * Copyright 2014-2016 Pierre Schweitzer <pierre@reactos.org>
8 * Copyright 2017 Ged Murphy <gedmurphy@reactos.org>
11 /* Inspired by Wine C unit tests, Copyright (C) 2002 Alexandre Julliard
12 * Inspired by ReactOS kernel-mode regression tests,
13 * Copyright (C) Aleksey Bragin, Filip Navara
16 #ifndef _KMTEST_TEST_H_
17 #define _KMTEST_TEST_H_
19 #include <kmt_platform.h>
21 typedef VOID
KMT_TESTFUNC(VOID
);
22 typedef KMT_TESTFUNC
*PKMT_TESTFUNC
;
27 KMT_TESTFUNC
*TestFunction
;
28 } KMT_TEST
, *PKMT_TEST
;
30 typedef const KMT_TEST CKMT_TEST
, *PCKMT_TEST
;
32 extern const KMT_TEST TestList
[];
36 volatile LONG Successes
;
37 volatile LONG Failures
;
38 volatile LONG Skipped
;
39 volatile LONG LogBufferLength
;
40 LONG LogBufferMaxLength
;
41 CHAR LogBuffer
[ANYSIZE_ARRAY
];
42 } KMT_RESULTBUFFER
, *PKMT_RESULTBUFFER
;
44 #ifndef KMT_STANDALONE_DRIVER
46 /* usermode call-back mechanism */
48 /* list of supported operations */
49 typedef enum _KMT_CALLBACK_INFORMATION_CLASS
52 } KMT_CALLBACK_INFORMATION_CLASS
, *PKMT_CALLBACK_INFORMATION_CLASS
;
54 /* TODO: "response" is a little generic */
55 typedef union _KMT_RESPONSE
57 MEMORY_BASIC_INFORMATION MemInfo
;
58 } KMT_RESPONSE
, *PKMT_RESPONSE
;
60 /* this struct is sent from driver to usermode */
61 typedef struct _KMT_CALLBACK_REQUEST_PACKET
64 KMT_CALLBACK_INFORMATION_CLASS OperationClass
;
66 } KMT_CALLBACK_REQUEST_PACKET
, *PKMT_CALLBACK_REQUEST_PACKET
;
68 PKMT_RESPONSE
KmtUserModeCallback(KMT_CALLBACK_INFORMATION_CLASS Operation
, PVOID Parameters
);
69 VOID
KmtFreeCallbackResponse(PKMT_RESPONSE Response
);
71 //macro to simplify using the mechanism
72 #define Test_NtQueryVirtualMemory(BaseAddress, Size, AllocationType, ProtectionType) \
74 PKMT_RESPONSE NtQueryTest = KmtUserModeCallback(QueryVirtualMemory, BaseAddress); \
75 if (NtQueryTest != NULL) \
77 ok_eq_hex(NtQueryTest->MemInfo.Protect, ProtectionType); \
78 ok_eq_hex(NtQueryTest->MemInfo.State, AllocationType); \
79 ok_eq_size(NtQueryTest->MemInfo.RegionSize, Size); \
80 KmtFreeCallbackResponse(NtQueryTest); \
86 #ifdef KMT_STANDALONE_DRIVER
87 #define KMT_KERNEL_MODE
89 typedef NTSTATUS (KMT_IRP_HANDLER
)(
90 IN PDEVICE_OBJECT DeviceObject
,
92 IN PIO_STACK_LOCATION IoStackLocation
);
93 typedef KMT_IRP_HANDLER
*PKMT_IRP_HANDLER
;
95 NTSTATUS
KmtRegisterIrpHandler(IN UCHAR MajorFunction
, IN PDEVICE_OBJECT DeviceObject OPTIONAL
, IN PKMT_IRP_HANDLER IrpHandler
);
96 NTSTATUS
KmtUnregisterIrpHandler(IN UCHAR MajorFunction
, IN PDEVICE_OBJECT DeviceObject OPTIONAL
, IN PKMT_IRP_HANDLER IrpHandler
);
98 typedef NTSTATUS (KMT_MESSAGE_HANDLER
)(
99 IN PDEVICE_OBJECT DeviceObject
,
100 IN ULONG ControlCode
,
101 IN PVOID Buffer OPTIONAL
,
103 IN OUT PSIZE_T OutLength
);
104 typedef KMT_MESSAGE_HANDLER
*PKMT_MESSAGE_HANDLER
;
106 NTSTATUS
KmtRegisterMessageHandler(IN ULONG ControlCode OPTIONAL
, IN PDEVICE_OBJECT DeviceObject OPTIONAL
, IN PKMT_MESSAGE_HANDLER MessageHandler
);
107 NTSTATUS
KmtUnregisterMessageHandler(IN ULONG ControlCode OPTIONAL
, IN PDEVICE_OBJECT DeviceObject OPTIONAL
, IN PKMT_MESSAGE_HANDLER MessageHandler
);
111 TESTENTRY_NO_CREATE_DEVICE
= 1,
112 TESTENTRY_NO_REGISTER_DISPATCH
= 2,
113 TESTENTRY_NO_REGISTER_UNLOAD
= 4,
114 TESTENTRY_NO_EXCLUSIVE_DEVICE
= 8,
115 TESTENTRY_NO_READONLY_DEVICE
= 16,
116 TESTENTRY_BUFFERED_IO_DEVICE
= 32,
117 } KMT_TESTENTRY_FLAGS
;
119 NTSTATUS
TestEntry(IN PDRIVER_OBJECT DriverObject
, IN PCUNICODE_STRING RegistryPath
, OUT PCWSTR
*DeviceName
, IN OUT INT
*Flags
);
120 VOID
TestUnload(IN PDRIVER_OBJECT DriverObject
);
121 #endif /* defined KMT_STANDALONE_DRIVER */
123 #ifdef KMT_FILTER_DRIVER
124 #ifndef KMT_KERNEL_MODE
125 #define KMT_KERNEL_MODE
128 NTSTATUS
KmtFilterRegisterCallbacks(_In_ CONST FLT_OPERATION_REGISTRATION
*OperationRegistration
);
132 TESTENTRY_NO_REGISTER_FILTER
= 0x01,
133 TESTENTRY_NO_CREATE_COMMS_PORT
= 0x02,
134 TESTENTRY_NO_START_FILTERING
= 0x04,
135 TESTENTRY_NO_INSTANCE_SETUP
= 0x08,
136 TESTENTRY_NO_QUERY_TEARDOWN
= 0x10,
137 TESTENTRY_NO_ALL
= 0xFF
138 } KMT_MINIFILTER_FLAGS
;
140 VOID
TestFilterUnload(_In_ ULONG Flags
);
141 NTSTATUS
TestInstanceSetup(_In_ PCFLT_RELATED_OBJECTS FltObjects
, _In_ FLT_INSTANCE_SETUP_FLAGS Flags
, _In_ DEVICE_TYPE VolumeDeviceType
, _In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType
, _In_ PUNICODE_STRING VolumeName
, _In_ ULONG RealSectorSize
, _In_ ULONG SectorSize
);
142 VOID
TestQueryTeardown(_In_ PCFLT_RELATED_OBJECTS FltObjects
, _In_ FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
);
144 NTSTATUS
KmtFilterRegisterComms(_In_ PFLT_CONNECT_NOTIFY ConnectNotifyCallback
, _In_ PFLT_DISCONNECT_NOTIFY DisconnectNotifyCallback
, _In_opt_ PFLT_MESSAGE_NOTIFY MessageNotifyCallback
, _In_ LONG MaxClientConnections
);
146 #endif/* defined KMT_FILTER_DRIVER */
149 #ifdef KMT_KERNEL_MODE
150 /* Device Extension layout */
153 PKMT_RESULTBUFFER ResultBuffer
;
155 } KMT_DEVICE_EXTENSION
, *PKMT_DEVICE_EXTENSION
;
157 extern BOOLEAN KmtIsCheckedBuild
;
158 extern BOOLEAN KmtIsMultiProcessorBuild
;
159 extern PCSTR KmtMajorFunctionNames
[];
160 extern PDRIVER_OBJECT KmtDriverObject
;
162 VOID
KmtSetIrql(IN KIRQL NewIrql
);
163 BOOLEAN
KmtAreInterruptsEnabled(VOID
);
164 ULONG
KmtGetPoolTag(PVOID Memory
);
165 USHORT
KmtGetPoolType(PVOID Memory
);
166 PVOID
KmtGetSystemRoutineAddress(IN PCWSTR RoutineName
);
167 PKTHREAD
KmtStartThread(IN PKSTART_ROUTINE StartRoutine
, IN PVOID StartContext OPTIONAL
);
168 VOID
KmtFinishThread(IN PKTHREAD Thread OPTIONAL
, IN PKEVENT Event OPTIONAL
);
169 #elif defined KMT_USER_MODE
170 DWORD
KmtRunKernelTest(IN PCSTR TestName
);
172 VOID
KmtLoadDriver(IN PCWSTR ServiceName
, IN BOOLEAN RestartIfRunning
);
173 VOID
KmtUnloadDriver(VOID
);
174 VOID
KmtOpenDriver(VOID
);
175 VOID
KmtCloseDriver(VOID
);
177 DWORD
KmtSendToDriver(IN DWORD ControlCode
);
178 DWORD
KmtSendStringToDriver(IN DWORD ControlCode
, IN PCSTR String
);
179 DWORD
KmtSendWStringToDriver(IN DWORD ControlCode
, IN PCWSTR String
);
180 DWORD
KmtSendUlongToDriver(IN DWORD ControlCode
, IN DWORD Value
);
181 DWORD
KmtSendBufferToDriver(IN DWORD ControlCode
, IN OUT PVOID Buffer OPTIONAL
, IN DWORD InLength
, IN OUT PDWORD OutLength
);
184 DWORD
KmtFltCreateService(_In_z_ PCWSTR ServiceName
, _In_z_ PCWSTR DisplayName
, _Out_ SC_HANDLE
*ServiceHandle
);
185 DWORD
KmtFltDeleteService(_In_opt_z_ PCWSTR ServiceName
, _Inout_ SC_HANDLE
*ServiceHandle
);
186 DWORD
KmtFltAddAltitude(_In_z_ LPWSTR Altitude
);
187 DWORD
KmtFltLoadDriver(_In_ BOOLEAN EnableDriverLoadPrivlege
, _In_ BOOLEAN RestartIfRunning
, _In_ BOOLEAN ConnectComms
, _Out_ HANDLE
*hPort
);
188 DWORD
KmtFltUnloadDriver(_In_ HANDLE
*hPort
, _In_ BOOLEAN DisonnectComms
);
189 DWORD
KmtFltConnectComms(_Out_ HANDLE
*hPort
);
190 DWORD
KmtFltDisconnectComms(_In_ HANDLE hPort
);
191 DWORD
KmtFltRunKernelTest(_In_ HANDLE hPort
, _In_z_ PCSTR TestName
);
192 DWORD
KmtFltSendToDriver(_In_ HANDLE hPort
, _In_ DWORD Message
);
193 DWORD
KmtFltSendStringToDriver(_In_ HANDLE hPort
, _In_ DWORD Message
, _In_ PCSTR String
);
194 DWORD
KmtFltSendWStringToDriver(_In_ HANDLE hPort
, _In_ DWORD Message
, _In_ PCWSTR String
);
195 DWORD
KmtFltSendUlongToDriver(_In_ HANDLE hPort
, _In_ DWORD Message
, _In_ DWORD Value
);
196 DWORD
KmtFltSendBufferToDriver(_In_ HANDLE hPort
, _In_ DWORD Message
, _In_reads_bytes_(BufferSize
) LPVOID Buffer
, _In_ DWORD BufferSize
, _Out_writes_bytes_to_opt_(dwOutBufferSize
, *lpBytesReturned
) LPVOID lpOutBuffer
, _In_ DWORD dwOutBufferSize
, _Out_opt_ LPDWORD lpBytesReturned
);
198 #else /* if !defined KMT_KERNEL_MODE && !defined KMT_USER_MODE */
199 #error either KMT_KERNEL_MODE or KMT_USER_MODE must be defined
200 #endif /* !defined KMT_KERNEL_MODE && !defined KMT_USER_MODE */
202 extern PKMT_RESULTBUFFER ResultBuffer
;
205 /* TODO: GCC doesn't understand %wZ :( */
206 #define KMT_FORMAT(type, fmt, first) /*__attribute__((__format__(type, fmt, first)))*/
207 #elif !defined __GNUC__
208 #define KMT_FORMAT(type, fmt, first)
209 #endif /* !defined __GNUC__ */
211 #define START_TEST(name) VOID Test_##name(VOID)
213 #ifndef KMT_STRINGIZE
214 #define KMT_STRINGIZE(x) #x
215 #endif /* !defined KMT_STRINGIZE */
216 #define ok(test, ...) ok_(test, __FILE__, __LINE__, __VA_ARGS__)
217 #define trace(...) trace_( __FILE__, __LINE__, __VA_ARGS__)
218 #define skip(test, ...) skip_(test, __FILE__, __LINE__, __VA_ARGS__)
220 #define ok_(test, file, line, ...) KmtOk(test, file ":" KMT_STRINGIZE(line), __VA_ARGS__)
221 #define trace_(file, line, ...) KmtTrace( file ":" KMT_STRINGIZE(line), __VA_ARGS__)
222 #define skip_(test, file, line, ...) KmtSkip(test, file ":" KMT_STRINGIZE(line), __VA_ARGS__)
224 BOOLEAN
KmtVOk(INT Condition
, PCSTR FileAndLine
, PCSTR Format
, va_list Arguments
) KMT_FORMAT(ms_printf
, 3, 0);
225 BOOLEAN
KmtOk(INT Condition
, PCSTR FileAndLine
, PCSTR Format
, ...) KMT_FORMAT(ms_printf
, 3, 4);
226 VOID
KmtVTrace(PCSTR FileAndLine
, PCSTR Format
, va_list Arguments
) KMT_FORMAT(ms_printf
, 2, 0);
227 VOID
KmtTrace(PCSTR FileAndLine
, PCSTR Format
, ...) KMT_FORMAT(ms_printf
, 2, 3);
228 BOOLEAN
KmtVSkip(INT Condition
, PCSTR FileAndLine
, PCSTR Format
, va_list Arguments
) KMT_FORMAT(ms_printf
, 3, 0);
229 BOOLEAN
KmtSkip(INT Condition
, PCSTR FileAndLine
, PCSTR Format
, ...) KMT_FORMAT(ms_printf
, 3, 4);
230 PVOID
KmtAllocateGuarded(SIZE_T SizeRequested
);
231 VOID
KmtFreeGuarded(PVOID Pointer
);
233 #ifdef KMT_KERNEL_MODE
234 #define ok_irql(irql) ok(KeGetCurrentIrql() == irql, "IRQL is %d, expected %d\n", KeGetCurrentIrql(), irql)
235 #endif /* defined KMT_KERNEL_MODE */
236 #define ok_eq_print(value, expected, spec) ok((value) == (expected), #value " = " spec ", expected " spec "\n", value, expected)
237 #define ok_eq_pointer(value, expected) ok_eq_print(value, expected, "%p")
238 #define ok_eq_int(value, expected) ok_eq_print(value, expected, "%d")
239 #define ok_eq_uint(value, expected) ok_eq_print(value, expected, "%u")
240 #define ok_eq_long(value, expected) ok_eq_print(value, expected, "%ld")
241 #define ok_eq_ulong(value, expected) ok_eq_print(value, expected, "%lu")
242 #define ok_eq_longlong(value, expected) ok_eq_print(value, expected, "%I64d")
243 #define ok_eq_ulonglong(value, expected) ok_eq_print(value, expected, "%I64u")
244 #define ok_eq_char(value, expected) ok_eq_print(value, expected, "%c")
245 #define ok_eq_wchar(value, expected) ok_eq_print(value, expected, "%C")
247 #define ok_eq_size(value, expected) ok_eq_print(value, (SIZE_T)(expected), "%lu")
248 #define ok_eq_longptr(value, expected) ok_eq_print(value, (LONG_PTR)(expected), "%ld")
249 #define ok_eq_ulongptr(value, expected) ok_eq_print(value, (ULONG_PTR)(expected), "%lu")
251 #define ok_eq_size(value, expected) ok_eq_print(value, (SIZE_T)(expected), "%I64u")
252 #define ok_eq_longptr(value, expected) ok_eq_print(value, (LONG_PTR)(expected), "%I64d")
253 #define ok_eq_ulongptr(value, expected) ok_eq_print(value, (ULONG_PTR)(expected), "%I64u")
254 #endif /* defined _WIN64 */
255 #define ok_eq_hex(value, expected) ok_eq_print(value, expected, "0x%08lx")
256 #define ok_bool_true(value, desc) ok((value) == TRUE, desc " FALSE, expected TRUE\n")
257 #define ok_bool_false(value, desc) ok((value) == FALSE, desc " TRUE, expected FALSE\n")
258 #define ok_eq_bool(value, expected) ok((value) == (expected), #value " = %s, expected %s\n", \
259 (value) ? "TRUE" : "FALSE", \
260 (expected) ? "TRUE" : "FALSE")
261 #define ok_eq_str(value, expected) ok(!strcmp(value, expected), #value " = \"%s\", expected \"%s\"\n", value, expected)
262 #define ok_eq_wstr(value, expected) ok(!wcscmp(value, expected), #value " = \"%ls\", expected \"%ls\"\n", value, expected)
263 #define ok_eq_tag(value, expected) ok_eq_print(value, expected, "0x%08lx")
265 #define KMT_MAKE_CODE(ControlCode) CTL_CODE(FILE_DEVICE_UNKNOWN, \
266 0xC00 + (ControlCode), \
270 #define MICROSECOND 10
271 #define MILLISECOND (1000 * MICROSECOND)
272 #define SECOND (1000 * MILLISECOND)
274 /* See apitests/include/apitest.h */
275 #define KmtInvalidPointer ((PVOID)0x5555555555555555ULL)
277 #define KmtStartSeh() \
279 NTSTATUS ExceptionStatus = STATUS_SUCCESS; \
283 #define KmtEndSeh(ExpectedStatus) \
285 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) \
287 ExceptionStatus = _SEH2_GetExceptionCode(); \
290 ok_eq_hex(ExceptionStatus, (ExpectedStatus)); \
293 #define KmtGetSystemOrEmbeddedRoutineAddress(RoutineName) \
294 p##RoutineName = KmtGetSystemRoutineAddress(L ## #RoutineName); \
295 if (!p##RoutineName) \
297 p##RoutineName = RoutineName; \
298 trace("Using embedded routine for " #RoutineName "\n"); \
301 trace("Using system routine for " #RoutineName "\n");
303 #if defined KMT_DEFINE_TEST_FUNCTIONS
305 #if defined KMT_KERNEL_MODE
306 #include "kmt_test_kernel.h"
307 #elif defined KMT_USER_MODE
308 #include "kmt_test_user.h"
309 #endif /* defined KMT_USER_MODE */
311 PKMT_RESULTBUFFER ResultBuffer
= NULL
;
313 static VOID
KmtAddToLogBuffer(PKMT_RESULTBUFFER Buffer
, PCSTR String
, SIZE_T Length
)
323 OldLength
= Buffer
->LogBufferLength
;
324 NewLength
= OldLength
+ (ULONG
)Length
;
325 if (NewLength
> Buffer
->LogBufferMaxLength
)
327 } while (InterlockedCompareExchange(&Buffer
->LogBufferLength
, NewLength
, OldLength
) != OldLength
);
329 memcpy(&Buffer
->LogBuffer
[OldLength
], String
, Length
);
332 KMT_FORMAT(ms_printf
, 5, 0)
333 static SIZE_T
KmtXVSNPrintF(PSTR Buffer
, SIZE_T BufferMaxLength
, PCSTR FileAndLine
, PCSTR Prepend
, PCSTR Format
, va_list Arguments
)
335 SIZE_T BufferLength
= 0;
341 Slash
= strrchr(FileAndLine
, '\\');
343 FileAndLine
= Slash
+ 1;
344 Slash
= strrchr(FileAndLine
, '/');
346 FileAndLine
= Slash
+ 1;
348 Length
= min(BufferMaxLength
, strlen(FileAndLine
));
349 memcpy(Buffer
, FileAndLine
, Length
);
351 BufferLength
+= Length
;
352 BufferMaxLength
-= Length
;
356 Length
= min(BufferMaxLength
, strlen(Prepend
));
357 memcpy(Buffer
, Prepend
, Length
);
359 BufferLength
+= Length
;
360 BufferMaxLength
-= Length
;
364 Length
= KmtVSNPrintF(Buffer
, BufferMaxLength
, Format
, Arguments
);
365 /* vsnprintf can return more than maxLength, we don't want to do that */
366 BufferLength
+= min(Length
, BufferMaxLength
);
371 KMT_FORMAT(ms_printf
, 5, 6)
372 static SIZE_T
KmtXSNPrintF(PSTR Buffer
, SIZE_T BufferMaxLength
, PCSTR FileAndLine
, PCSTR Prepend
, PCSTR Format
, ...)
376 va_start(Arguments
, Format
);
377 BufferLength
= KmtXVSNPrintF(Buffer
, BufferMaxLength
, FileAndLine
, Prepend
, Format
, Arguments
);
382 VOID
KmtFinishTest(PCSTR TestName
)
384 CHAR MessageBuffer
[512];
385 SIZE_T MessageLength
;
390 MessageLength
= KmtXSNPrintF(MessageBuffer
, sizeof MessageBuffer
, NULL
, NULL
,
391 "%s: %ld tests executed (0 marked as todo, %ld failures), %ld skipped.\n",
393 ResultBuffer
->Successes
+ ResultBuffer
->Failures
,
394 ResultBuffer
->Failures
,
395 ResultBuffer
->Skipped
);
396 KmtAddToLogBuffer(ResultBuffer
, MessageBuffer
, MessageLength
);
399 BOOLEAN
KmtVOk(INT Condition
, PCSTR FileAndLine
, PCSTR Format
, va_list Arguments
)
401 CHAR MessageBuffer
[512];
402 SIZE_T MessageLength
;
405 return Condition
!= 0;
409 InterlockedIncrement(&ResultBuffer
->Successes
);
411 if (0/*KmtReportSuccess*/)
413 MessageLength
= KmtXSNPrintF(MessageBuffer
, sizeof MessageBuffer
, FileAndLine
, ": Test succeeded\n", NULL
);
414 KmtAddToLogBuffer(ResultBuffer
, MessageBuffer
, MessageLength
);
419 InterlockedIncrement(&ResultBuffer
->Failures
);
420 MessageLength
= KmtXVSNPrintF(MessageBuffer
, sizeof MessageBuffer
, FileAndLine
, ": Test failed: ", Format
, Arguments
);
421 KmtAddToLogBuffer(ResultBuffer
, MessageBuffer
, MessageLength
);
424 return Condition
!= 0;
427 BOOLEAN
KmtOk(INT Condition
, PCSTR FileAndLine
, PCSTR Format
, ...)
431 va_start(Arguments
, Format
);
432 Ret
= KmtVOk(Condition
, FileAndLine
, Format
, Arguments
);
437 VOID
KmtVTrace(PCSTR FileAndLine
, PCSTR Format
, va_list Arguments
)
439 CHAR MessageBuffer
[512];
440 SIZE_T MessageLength
;
442 MessageLength
= KmtXVSNPrintF(MessageBuffer
, sizeof MessageBuffer
, FileAndLine
, ": ", Format
, Arguments
);
443 KmtAddToLogBuffer(ResultBuffer
, MessageBuffer
, MessageLength
);
446 VOID
KmtTrace(PCSTR FileAndLine
, PCSTR Format
, ...)
449 va_start(Arguments
, Format
);
450 KmtVTrace(FileAndLine
, Format
, Arguments
);
454 BOOLEAN
KmtVSkip(INT Condition
, PCSTR FileAndLine
, PCSTR Format
, va_list Arguments
)
456 CHAR MessageBuffer
[512];
457 SIZE_T MessageLength
;
464 InterlockedIncrement(&ResultBuffer
->Skipped
);
465 MessageLength
= KmtXVSNPrintF(MessageBuffer
, sizeof MessageBuffer
, FileAndLine
, ": Tests skipped: ", Format
, Arguments
);
466 KmtAddToLogBuffer(ResultBuffer
, MessageBuffer
, MessageLength
);
472 BOOLEAN
KmtSkip(INT Condition
, PCSTR FileAndLine
, PCSTR Format
, ...)
476 va_start(Arguments
, Format
);
477 Ret
= KmtVSkip(Condition
, FileAndLine
, Format
, Arguments
);
482 PVOID
KmtAllocateGuarded(SIZE_T SizeRequested
)
485 SIZE_T Size
= PAGE_ROUND_UP(SizeRequested
+ PAGE_SIZE
);
486 PVOID VirtualMemory
= NULL
;
489 Status
= ZwAllocateVirtualMemory(ZwCurrentProcess(), &VirtualMemory
, 0, &Size
, MEM_RESERVE
, PAGE_NOACCESS
);
491 if (!NT_SUCCESS(Status
))
495 Status
= ZwAllocateVirtualMemory(ZwCurrentProcess(), &VirtualMemory
, 0, &Size
, MEM_COMMIT
, PAGE_READWRITE
);
496 if (!NT_SUCCESS(Status
))
499 Status
= ZwFreeVirtualMemory(ZwCurrentProcess(), &VirtualMemory
, &Size
, MEM_RELEASE
);
500 ok_eq_hex(Status
, STATUS_SUCCESS
);
504 StartOfBuffer
= VirtualMemory
;
505 StartOfBuffer
+= Size
- SizeRequested
;
507 return StartOfBuffer
;
510 VOID
KmtFreeGuarded(PVOID Pointer
)
513 PVOID VirtualMemory
= (PVOID
)PAGE_ROUND_DOWN((SIZE_T
)Pointer
);
516 Status
= ZwFreeVirtualMemory(ZwCurrentProcess(), &VirtualMemory
, &Size
, MEM_RELEASE
);
517 ok_eq_hex(Status
, STATUS_SUCCESS
);
520 #endif /* defined KMT_DEFINE_TEST_FUNCTIONS */
522 #endif /* !defined _KMTEST_TEST_H_ */