ReactOS 0.4.16-dev-109-gf4cb10f
kmtest_standalone.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
4 * PURPOSE: Kernel-Mode Test Suite standalone driver routines
5 * COPYRIGHT: Copyright 2011-2018 Thomas Faber <thomas.faber@reactos.org>
6 */
7
8#include <ntddk.h>
9#include <ntifs.h>
10#include <ndk/ketypes.h>
11
12#define KMT_DEFINE_TEST_FUNCTIONS
13#include <kmt_test.h>
14
15#define NDEBUG
16#include <debug.h>
17
18#include <kmt_public.h>
19
20/* types */
21typedef struct
22{
25 PKMT_IRP_HANDLER IrpHandler;
27
28typedef struct
29{
32 PKMT_MESSAGE_HANDLER MessageHandler;
34
35/* Prototypes */
36DRIVER_INITIALIZE DriverEntry;
37static DRIVER_UNLOAD DriverUnload;
39static KMT_IRP_HANDLER DeviceControlHandler;
40
41/* Globals */
44
45#define KMT_MAX_IRP_HANDLERS 256
47#define KMT_MAX_MESSAGE_HANDLERS 256
49
67{
69 WCHAR DeviceNameBuffer[128] = L"\\Device\\Kmtest-";
70 UNICODE_STRING KmtestDeviceName;
72 PKMT_DEVICE_EXTENSION KmtestDeviceExtension;
74 PCWSTR DeviceNameSuffix;
75 INT Flags = 0;
76 int i;
77 PKPRCB Prcb;
78
79 PAGED_CODE();
80
81 DPRINT("DriverEntry\n");
82
83 Prcb = KeGetCurrentPrcb();
86
87 /* get the Kmtest device, so that we get a ResultBuffer pointer */
90
91 if (!NT_SUCCESS(Status))
92 {
93 DPRINT1("Failed to get Kmtest device object pointer\n");
94 goto cleanup;
95 }
96
98
99 if (!NT_SUCCESS(Status))
100 {
101 DPRINT1("Failed to reference Kmtest device object\n");
102 goto cleanup;
103 }
104
107 KmtestDeviceExtension = KmtestDeviceObject->DeviceExtension;
108 ResultBuffer = KmtestDeviceExtension->ResultBuffer;
109 DPRINT("KmtestDeviceObject: %p\n", (PVOID)KmtestDeviceObject);
110 DPRINT("KmtestDeviceExtension: %p\n", (PVOID)KmtestDeviceExtension);
111 DPRINT("Setting ResultBuffer: %p\n", (PVOID)ResultBuffer);
112
113 /* call TestEntry */
114 RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
115 DeviceName.MaximumLength = sizeof DeviceNameBuffer;
116 TestEntry(DriverObject, RegistryPath, &DeviceNameSuffix, &Flags);
117
118 /* create test device */
119 if (!(Flags & TESTENTRY_NO_CREATE_DEVICE))
120 {
121 RtlAppendUnicodeToString(&DeviceName, DeviceNameSuffix);
125 (Flags & TESTENTRY_NO_READONLY_DEVICE ? 0 : FILE_READ_ONLY_DEVICE),
126 Flags & TESTENTRY_NO_EXCLUSIVE_DEVICE ? FALSE : TRUE,
128
129 if (!NT_SUCCESS(Status))
130 {
131 DPRINT1("Could not create device object %wZ\n", &DeviceName);
132 goto cleanup;
133 }
134
135 if (Flags & TESTENTRY_BUFFERED_IO_DEVICE)
137
138 DPRINT("DriverEntry. Created DeviceObject %p\n",
140 }
141
142 /* initialize dispatch functions */
143 if (!(Flags & TESTENTRY_NO_REGISTER_UNLOAD))
144 DriverObject->DriverUnload = DriverUnload;
145 if (!(Flags & TESTENTRY_NO_REGISTER_DISPATCH))
146 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i)
147 DriverObject->MajorFunction[i] = DriverDispatch;
148
149cleanup:
151 {
154 }
155
157 {
162 }
163
164 return Status;
165}
166
175static
176VOID
177NTAPI
180{
181 PAGED_CODE();
182
184
185 DPRINT("DriverUnload\n");
186
188
191
194}
195
217 IN PKMT_IRP_HANDLER IrpHandler)
218{
220 int i;
221
223 {
225 goto cleanup;
226 }
227
228 if (IrpHandler == NULL)
229 {
231 goto cleanup;
232 }
233
234 for (i = 0; i < sizeof IrpHandlers / sizeof IrpHandlers[0]; ++i)
235 if (IrpHandlers[i].IrpHandler == NULL)
236 {
239 IrpHandlers[i].IrpHandler = IrpHandler;
240 goto cleanup;
241 }
242
244
245cleanup:
246 return Status;
247}
248
270 IN PKMT_IRP_HANDLER IrpHandler)
271{
273 int i;
274
275 for (i = 0; i < sizeof IrpHandlers / sizeof IrpHandlers[0]; ++i)
278 IrpHandlers[i].IrpHandler == IrpHandler)
279 {
281 goto cleanup;
282 }
283
285
286cleanup:
287 return Status;
288}
289
302static
304NTAPI
307 IN PIRP Irp)
308{
310 PIO_STACK_LOCATION IoStackLocation;
311 int i;
312
313 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
314
315 DPRINT("DriverDispatch: Function=%s, Device=%p\n",
316 KmtMajorFunctionNames[IoStackLocation->MajorFunction],
318
319 for (i = 0; i < sizeof IrpHandlers / sizeof IrpHandlers[0]; ++i)
320 {
321 if (IrpHandlers[i].MajorFunction == IoStackLocation->MajorFunction &&
324 return IrpHandlers[i].IrpHandler(DeviceObject, Irp, IoStackLocation);
325 }
326
327 /* default handler for DeviceControl */
328 if (IoStackLocation->MajorFunction == IRP_MJ_DEVICE_CONTROL ||
330 return DeviceControlHandler(DeviceObject, Irp, IoStackLocation);
331
332 /* Return success for create, close, and cleanup */
333 if (IoStackLocation->MajorFunction == IRP_MJ_CREATE ||
334 IoStackLocation->MajorFunction == IRP_MJ_CLOSE ||
335 IoStackLocation->MajorFunction == IRP_MJ_CLEANUP)
337
338 /* default handler */
339 Irp->IoStatus.Status = Status;
340 Irp->IoStatus.Information = 0;
341
343
344 return Status;
345}
346
371 IN PKMT_MESSAGE_HANDLER MessageHandler)
372{
374 int i;
375
376 if (ControlCode >= 0x400)
377 {
379 goto cleanup;
380 }
381
382 if (MessageHandler == NULL)
383 {
385 goto cleanup;
386 }
387
388 for (i = 0; i < sizeof MessageHandlers / sizeof MessageHandlers[0]; ++i)
389 if (MessageHandlers[i].MessageHandler == NULL)
390 {
393 MessageHandlers[i].MessageHandler = MessageHandler;
394 goto cleanup;
395 }
396
398
399cleanup:
400 return Status;
401}
402
424 IN PKMT_MESSAGE_HANDLER MessageHandler)
425{
427 int i;
428
429 for (i = 0; i < sizeof MessageHandlers / sizeof MessageHandlers[0]; ++i)
432 MessageHandlers[i].MessageHandler == MessageHandler)
433 {
435 goto cleanup;
436 }
437
439
440cleanup:
441 return Status;
442}
443
465static
469 IN PIRP Irp,
470 IN PIO_STACK_LOCATION IoStackLocation)
471{
473 ULONG ControlCode = (IoStackLocation->Parameters.DeviceIoControl.IoControlCode & 0x00000FFC) >> 2;
474 SIZE_T OutLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength;
475 int i;
476
477 for (i = 0; i < sizeof MessageHandlers / sizeof MessageHandlers[0]; ++i)
478 {
479 if ((MessageHandlers[i].ControlCode == 0 ||
482 MessageHandlers[i].MessageHandler != NULL)
483 {
484 Status = MessageHandlers[i].MessageHandler(DeviceObject, ControlCode, Irp->AssociatedIrp.SystemBuffer,
485 IoStackLocation->Parameters.DeviceIoControl.InputBufferLength,
486 &OutLength);
487 break;
488 }
489 }
490
491 Irp->IoStatus.Status = Status;
492 Irp->IoStatus.Information = OutLength;
493
495
496 return Status;
497}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
VOID TestUnload(IN PDRIVER_OBJECT DriverObject)
Definition: Example_drv.c:93
static void TestEntry(const ENTRY *pEntry)
static OBJECT_ATTRIBUTES KmtestFileObject
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
static void cleanup(void)
Definition: main.c:1335
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define KMTEST_DEVICE_DRIVER_PATH
Definition: kmt_public.h:34
PKMT_RESULTBUFFER ResultBuffer
PCSTR KmtMajorFunctionNames[]
BOOLEAN KmtIsCheckedBuild
BOOLEAN KmtIsMultiProcessorBuild
NTSTATUS KmtRegisterMessageHandler(IN ULONG ControlCode OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_MESSAGE_HANDLER MessageHandler)
static PDEVICE_OBJECT TestDeviceObject
static PDEVICE_OBJECT KmtestDeviceObject
DRIVER_INITIALIZE DriverEntry
struct KMT_MESSAGE_HANDLER_ENTRY * PKMT_MESSAGE_HANDLER_ENTRY
static KMT_IRP_HANDLER_ENTRY IrpHandlers[KMT_MAX_IRP_HANDLERS]
NTSTATUS KmtUnregisterMessageHandler(IN ULONG ControlCode OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_MESSAGE_HANDLER MessageHandler)
#define KMT_MAX_IRP_HANDLERS
static KMT_MESSAGE_HANDLER_ENTRY MessageHandlers[KMT_MAX_MESSAGE_HANDLERS]
NTSTATUS KmtUnregisterIrpHandler(IN UCHAR MajorFunction, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_IRP_HANDLER IrpHandler)
NTSTATUS KmtRegisterIrpHandler(IN UCHAR MajorFunction, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_IRP_HANDLER IrpHandler)
#define KMT_MAX_MESSAGE_HANDLERS
struct KMT_IRP_HANDLER_ENTRY * PKMT_IRP_HANDLER_ENTRY
static DRIVER_DISPATCH DriverDispatch
static DRIVER_UNLOAD DriverUnload
static KMT_IRP_HANDLER DeviceControlHandler
if(dx< 0)
Definition: linetemp.h:194
#define KernelMode
Definition: asm.h:34
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1161
#define PRCB_BUILD_UNIPROCESSOR
Definition: ketypes.h:324
#define PRCB_BUILD_DEBUG
Definition: ketypes.h:323
DRIVER_DISPATCH(nfs41_FsdDispatch)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define FILE_READ_ONLY_DEVICE
Definition: nt_native.h:808
#define FILE_ALL_ACCESS
Definition: nt_native.h:651
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:476
#define STATUS_ALLOTTED_SPACE_EXCEEDED
Definition: ntstatus.h:389
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:475
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:477
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:381
#define FILE_DEVICE_UNKNOWN
Definition: winioctl.h:79
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define DPRINT
Definition: sndvol32.h:73
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
UCHAR MajorFunction
PDEVICE_OBJECT DeviceObject
PKMT_IRP_HANDLER IrpHandler
PKMT_MESSAGE_HANDLER MessageHandler
ULONG ControlCode
PDEVICE_OBJECT DeviceObject
PVOID DeviceExtension
Definition: env_spec_w32.h:418
UCHAR BuildType
Definition: ketypes.h:683
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1697
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_IRQL_requires_same_ typedef _In_ ULONG ControlCode
Definition: wmitypes.h:55
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define IO_NO_INCREMENT
Definition: iotypes.h:598
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
#define IRP_MJ_CLEANUP
#define IRP_MJ_MAXIMUM_FUNCTION
#define ObDereferenceObject
Definition: obfuncs.h:203
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180