2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Driver
5 * PROGRAMMER: Thomas Faber <thfabba@gmx.de>
10 #include <ndk/ketypes.h>
11 #include <ntstrsafe.h>
13 #include <pseh/pseh2.h>
18 #include <kmt_public.h>
19 #define KMT_DEFINE_TEST_FUNCTIONS
23 DRIVER_INITIALIZE DriverEntry
;
24 static DRIVER_UNLOAD DriverUnload
;
25 __drv_dispatchType(IRP_MJ_CREATE
)
26 static DRIVER_DISPATCH DriverCreate
;
27 __drv_dispatchType(IRP_MJ_CLEANUP
)
28 static DRIVER_DISPATCH DriverCleanup
;
29 __drv_dispatchType(IRP_MJ_CLOSE
)
30 static DRIVER_DISPATCH DriverClose
;
31 __drv_dispatchType(IRP_MJ_DEVICE_CONTROL
)
32 static DRIVER_DISPATCH DriverIoControl
;
35 static PDEVICE_OBJECT MainDeviceObject
;
36 PDRIVER_OBJECT KmtDriverObject
= NULL
;
47 * Driver Registry Path
54 IN PDRIVER_OBJECT DriverObject
,
55 IN PUNICODE_STRING RegistryPath
)
57 NTSTATUS Status
= STATUS_SUCCESS
;
58 UNICODE_STRING DeviceName
;
59 PKMT_DEVICE_EXTENSION DeviceExtension
;
64 UNREFERENCED_PARAMETER(RegistryPath
);
66 DPRINT("DriverEntry\n");
68 Prcb
= KeGetCurrentPrcb();
69 KmtIsCheckedBuild
= (Prcb
->BuildType
& PRCB_BUILD_DEBUG
) != 0;
70 KmtIsMultiProcessorBuild
= (Prcb
->BuildType
& PRCB_BUILD_UNIPROCESSOR
) == 0;
71 KmtDriverObject
= DriverObject
;
73 RtlInitUnicodeString(&DeviceName
, KMTEST_DEVICE_DRIVER_PATH
);
74 Status
= IoCreateDevice(DriverObject
, sizeof(KMT_DEVICE_EXTENSION
),
77 FILE_DEVICE_SECURE_OPEN
| FILE_READ_ONLY_DEVICE
,
78 FALSE
, &MainDeviceObject
);
80 if (!NT_SUCCESS(Status
))
83 DPRINT("DriverEntry. Created DeviceObject %p. DeviceExtension %p\n",
84 MainDeviceObject
, MainDeviceObject
->DeviceExtension
);
85 DeviceExtension
= MainDeviceObject
->DeviceExtension
;
86 DeviceExtension
->ResultBuffer
= NULL
;
87 DeviceExtension
->Mdl
= NULL
;
89 DriverObject
->DriverUnload
= DriverUnload
;
90 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = DriverCreate
;
91 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = DriverCleanup
;
92 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = DriverClose
;
93 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = DriverIoControl
;
96 if (MainDeviceObject
&& !NT_SUCCESS(Status
))
98 IoDeleteDevice(MainDeviceObject
);
99 MainDeviceObject
= NULL
;
105 /* Dispatch functions */
109 * Driver cleanup funtion.
111 * @param DriverObject
118 IN PDRIVER_OBJECT DriverObject
)
122 UNREFERENCED_PARAMETER(DriverObject
);
124 DPRINT("DriverUnload\n");
126 if (MainDeviceObject
)
128 PKMT_DEVICE_EXTENSION DeviceExtension
= MainDeviceObject
->DeviceExtension
;
129 ASSERT(!DeviceExtension
->Mdl
);
130 ASSERT(!DeviceExtension
->ResultBuffer
);
131 ASSERT(!ResultBuffer
);
132 IoDeleteDevice(MainDeviceObject
);
139 * Driver Dispatch function for IRP_MJ_CREATE
141 * @param DeviceObject
152 IN PDEVICE_OBJECT DeviceObject
,
155 NTSTATUS Status
= STATUS_SUCCESS
;
156 PIO_STACK_LOCATION IoStackLocation
;
160 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
162 DPRINT("DriverCreate. DeviceObject=%p, RequestorMode=%d, FileObject=%p, FsContext=%p, FsContext2=%p\n",
163 DeviceObject
, Irp
->RequestorMode
, IoStackLocation
->FileObject
,
164 IoStackLocation
->FileObject
->FsContext
, IoStackLocation
->FileObject
->FsContext2
);
166 Irp
->IoStatus
.Status
= Status
;
167 Irp
->IoStatus
.Information
= 0;
169 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
175 * @name DriverCleanup
177 * Driver Dispatch function for IRP_MJ_CLEANUP
179 * @param DeviceObject
190 IN PDEVICE_OBJECT DeviceObject
,
193 NTSTATUS Status
= STATUS_SUCCESS
;
194 PIO_STACK_LOCATION IoStackLocation
;
195 PKMT_DEVICE_EXTENSION DeviceExtension
;
199 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
201 DPRINT("DriverCleanup. DeviceObject=%p, RequestorMode=%d, FileObject=%p, FsContext=%p, FsContext2=%p\n",
202 DeviceObject
, Irp
->RequestorMode
, IoStackLocation
->FileObject
,
203 IoStackLocation
->FileObject
->FsContext
, IoStackLocation
->FileObject
->FsContext2
);
205 ASSERT(IoStackLocation
->FileObject
->FsContext2
== NULL
);
206 DeviceExtension
= DeviceObject
->DeviceExtension
;
207 if (DeviceExtension
->Mdl
&& IoStackLocation
->FileObject
->FsContext
== DeviceExtension
->Mdl
)
209 MmUnlockPages(DeviceExtension
->Mdl
);
210 IoFreeMdl(DeviceExtension
->Mdl
);
211 DeviceExtension
->Mdl
= NULL
;
212 ResultBuffer
= DeviceExtension
->ResultBuffer
= NULL
;
216 ASSERT(IoStackLocation
->FileObject
->FsContext
== NULL
);
219 Irp
->IoStatus
.Status
= Status
;
220 Irp
->IoStatus
.Information
= 0;
222 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
230 * Driver Dispatch function for IRP_MJ_CLOSE
232 * @param DeviceObject
243 IN PDEVICE_OBJECT DeviceObject
,
246 NTSTATUS Status
= STATUS_SUCCESS
;
250 DPRINT("DriverClose. DeviceObject=%p, RequestorMode=%d\n",
251 DeviceObject
, Irp
->RequestorMode
);
253 Irp
->IoStatus
.Status
= Status
;
254 Irp
->IoStatus
.Information
= 0;
256 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
262 * @name DriverIoControl
264 * Driver Dispatch function for IRP_MJ_DEVICE_CONTROL
266 * @param DeviceObject
277 IN PDEVICE_OBJECT DeviceObject
,
280 NTSTATUS Status
= STATUS_SUCCESS
;
281 PIO_STACK_LOCATION IoStackLocation
;
286 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
288 DPRINT("DriverIoControl. Code=0x%08X, DeviceObject=%p, FileObject=%p, FsContext=%p, FsContext2=%p\n",
289 IoStackLocation
->Parameters
.DeviceIoControl
.IoControlCode
,
290 DeviceObject
, IoStackLocation
->FileObject
,
291 IoStackLocation
->FileObject
->FsContext
, IoStackLocation
->FileObject
->FsContext2
);
293 switch (IoStackLocation
->Parameters
.DeviceIoControl
.IoControlCode
)
295 case IOCTL_KMTEST_GET_TESTS
:
297 PCKMT_TEST TestEntry
;
298 LPSTR OutputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
299 size_t Remaining
= IoStackLocation
->Parameters
.DeviceIoControl
.OutputBufferLength
;
301 DPRINT("DriverIoControl. IOCTL_KMTEST_GET_TESTS, outlen=%lu\n",
302 IoStackLocation
->Parameters
.DeviceIoControl
.OutputBufferLength
);
304 for (TestEntry
= TestList
; TestEntry
->TestName
; ++TestEntry
)
306 RtlStringCbCopyExA(OutputBuffer
, Remaining
, TestEntry
->TestName
, &OutputBuffer
, &Remaining
, 0);
309 *OutputBuffer
++ = '\0';
315 *OutputBuffer
++ = '\0';
318 Length
= IoStackLocation
->Parameters
.DeviceIoControl
.OutputBufferLength
- Remaining
;
321 case IOCTL_KMTEST_RUN_TEST
:
323 ANSI_STRING TestName
;
324 PCKMT_TEST TestEntry
;
326 DPRINT("DriverIoControl. IOCTL_KMTEST_RUN_TEST, inlen=%lu, outlen=%lu\n",
327 IoStackLocation
->Parameters
.DeviceIoControl
.InputBufferLength
,
328 IoStackLocation
->Parameters
.DeviceIoControl
.OutputBufferLength
);
329 TestName
.Length
= TestName
.MaximumLength
= (USHORT
)min(IoStackLocation
->Parameters
.DeviceIoControl
.InputBufferLength
, USHRT_MAX
);
330 TestName
.Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
331 DPRINT("DriverIoControl. Run test: %Z\n", &TestName
);
333 for (TestEntry
= TestList
; TestEntry
->TestName
; ++TestEntry
)
335 ANSI_STRING EntryName
;
336 if (TestEntry
->TestName
[0] == '-')
337 RtlInitAnsiString(&EntryName
, TestEntry
->TestName
+ 1);
339 RtlInitAnsiString(&EntryName
, TestEntry
->TestName
);
341 if (!RtlCompareString(&TestName
, &EntryName
, FALSE
))
343 DPRINT1("DriverIoControl. Starting test %Z\n", &EntryName
);
344 TestEntry
->TestFunction();
345 DPRINT1("DriverIoControl. Finished test %Z\n", &EntryName
);
350 if (!TestEntry
->TestName
)
351 Status
= STATUS_OBJECT_NAME_INVALID
;
355 case IOCTL_KMTEST_SET_RESULTBUFFER
:
357 PKMT_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
359 DPRINT("DriverIoControl. IOCTL_KMTEST_SET_RESULTBUFFER, buffer=%p, inlen=%lu, outlen=%lu\n",
360 IoStackLocation
->Parameters
.DeviceIoControl
.Type3InputBuffer
,
361 IoStackLocation
->Parameters
.DeviceIoControl
.InputBufferLength
,
362 IoStackLocation
->Parameters
.DeviceIoControl
.OutputBufferLength
);
364 if (DeviceExtension
->Mdl
)
366 if (IoStackLocation
->FileObject
->FsContext
!= DeviceExtension
->Mdl
)
368 Status
= STATUS_ACCESS_DENIED
;
371 MmUnlockPages(DeviceExtension
->Mdl
);
372 IoFreeMdl(DeviceExtension
->Mdl
);
373 IoStackLocation
->FileObject
->FsContext
= NULL
;
374 ResultBuffer
= DeviceExtension
->ResultBuffer
= NULL
;
377 DeviceExtension
->Mdl
= IoAllocateMdl(IoStackLocation
->Parameters
.DeviceIoControl
.Type3InputBuffer
,
378 IoStackLocation
->Parameters
.DeviceIoControl
.InputBufferLength
,
380 if (!DeviceExtension
->Mdl
)
382 Status
= STATUS_INSUFFICIENT_RESOURCES
;
388 MmProbeAndLockPages(DeviceExtension
->Mdl
, UserMode
, IoModifyAccess
);
390 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
392 Status
= _SEH2_GetExceptionCode();
393 IoFreeMdl(DeviceExtension
->Mdl
);
394 DeviceExtension
->Mdl
= NULL
;
398 ResultBuffer
= DeviceExtension
->ResultBuffer
= MmGetSystemAddressForMdlSafe(DeviceExtension
->Mdl
, NormalPagePriority
);
399 IoStackLocation
->FileObject
->FsContext
= DeviceExtension
->Mdl
;
401 DPRINT("DriverIoControl. ResultBuffer: %ld %ld %ld %ld\n",
402 ResultBuffer
->Successes
, ResultBuffer
->Failures
,
403 ResultBuffer
->LogBufferLength
, ResultBuffer
->LogBufferMaxLength
);
407 DPRINT1("DriverIoControl. Invalid IoCtl code 0x%08X\n",
408 IoStackLocation
->Parameters
.DeviceIoControl
.IoControlCode
);
409 Status
= STATUS_INVALID_DEVICE_REQUEST
;
413 Irp
->IoStatus
.Status
= Status
;
414 Irp
->IoStatus
.Information
= Length
;
416 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);