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 static DRIVER_DISPATCH DriverCreate
;
26 static DRIVER_DISPATCH DriverClose
;
27 static DRIVER_DISPATCH DriverIoControl
;
30 static PDEVICE_OBJECT MainDeviceObject
;
41 * Driver Registry Path
48 IN PDRIVER_OBJECT DriverObject
,
49 IN PUNICODE_STRING RegistryPath
)
51 NTSTATUS Status
= STATUS_SUCCESS
;
52 UNICODE_STRING DeviceName
;
53 PKMT_DEVICE_EXTENSION DeviceExtension
;
58 UNREFERENCED_PARAMETER(RegistryPath
);
60 DPRINT("DriverEntry\n");
62 Prcb
= KeGetCurrentPrcb();
63 KmtIsCheckedBuild
= (Prcb
->BuildType
& PRCB_BUILD_DEBUG
) != 0;
64 KmtIsMultiProcessorBuild
= (Prcb
->BuildType
& PRCB_BUILD_UNIPROCESSOR
) == 0;
66 RtlInitUnicodeString(&DeviceName
, KMTEST_DEVICE_DRIVER_PATH
);
67 Status
= IoCreateDevice(DriverObject
, sizeof(KMT_DEVICE_EXTENSION
),
70 FILE_DEVICE_SECURE_OPEN
| FILE_READ_ONLY_DEVICE
,
71 FALSE
, &MainDeviceObject
);
73 if (!NT_SUCCESS(Status
))
76 DPRINT("DriverEntry. Created DeviceObject %p. DeviceExtension %p\n",
77 MainDeviceObject
, MainDeviceObject
->DeviceExtension
);
78 DeviceExtension
= MainDeviceObject
->DeviceExtension
;
79 DeviceExtension
->ResultBuffer
= NULL
;
80 DeviceExtension
->Mdl
= NULL
;
82 DriverObject
->DriverUnload
= DriverUnload
;
83 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = DriverCreate
;
84 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = DriverClose
;
85 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = DriverIoControl
;
88 if (MainDeviceObject
&& !NT_SUCCESS(Status
))
90 IoDeleteDevice(MainDeviceObject
);
91 MainDeviceObject
= NULL
;
97 /* Dispatch functions */
101 * Driver cleanup funtion.
103 * @param DriverObject
110 IN PDRIVER_OBJECT DriverObject
)
114 UNREFERENCED_PARAMETER(DriverObject
);
116 DPRINT("DriverUnload\n");
118 if (MainDeviceObject
)
120 PKMT_DEVICE_EXTENSION DeviceExtension
= MainDeviceObject
->DeviceExtension
;
121 ASSERT(!DeviceExtension
->Mdl
);
122 ASSERT(!DeviceExtension
->ResultBuffer
);
123 ASSERT(!ResultBuffer
);
124 IoDeleteDevice(MainDeviceObject
);
131 * Driver Dispatch function for CreateFile
133 * @param DeviceObject
144 IN PDEVICE_OBJECT DeviceObject
,
147 NTSTATUS Status
= STATUS_SUCCESS
;
148 PIO_STACK_LOCATION IoStackLocation
;
152 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
154 DPRINT("DriverCreate. DeviceObject=%p, RequestorMode=%d, FileObject=%p, FsContext=%p, FsContext2=%p\n",
155 DeviceObject
, Irp
->RequestorMode
, IoStackLocation
->FileObject
,
156 IoStackLocation
->FileObject
->FsContext
, IoStackLocation
->FileObject
->FsContext2
);
158 Irp
->IoStatus
.Status
= Status
;
159 Irp
->IoStatus
.Information
= 0;
161 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
169 * Driver Dispatch function for CloseHandle.
171 * @param DeviceObject
182 IN PDEVICE_OBJECT DeviceObject
,
185 NTSTATUS Status
= STATUS_SUCCESS
;
186 PIO_STACK_LOCATION IoStackLocation
;
187 PKMT_DEVICE_EXTENSION DeviceExtension
;
191 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
193 DPRINT("DriverClose. DeviceObject=%p, RequestorMode=%d, FileObject=%p, FsContext=%p, FsContext2=%p\n",
194 DeviceObject
, Irp
->RequestorMode
, IoStackLocation
->FileObject
,
195 IoStackLocation
->FileObject
->FsContext
, IoStackLocation
->FileObject
->FsContext2
);
197 ASSERT(IoStackLocation
->FileObject
->FsContext2
== NULL
);
198 DeviceExtension
= DeviceObject
->DeviceExtension
;
199 if (DeviceExtension
->Mdl
&& IoStackLocation
->FileObject
->FsContext
== DeviceExtension
->Mdl
)
201 MmUnlockPages(DeviceExtension
->Mdl
);
202 IoFreeMdl(DeviceExtension
->Mdl
);
203 DeviceExtension
->Mdl
= NULL
;
204 ResultBuffer
= DeviceExtension
->ResultBuffer
= NULL
;
208 ASSERT(IoStackLocation
->FileObject
->FsContext
== NULL
);
211 Irp
->IoStatus
.Status
= Status
;
212 Irp
->IoStatus
.Information
= 0;
214 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
220 * @name DriverIoControl
222 * Driver Dispatch function for DeviceIoControl.
224 * @param DeviceObject
235 IN PDEVICE_OBJECT DeviceObject
,
238 NTSTATUS Status
= STATUS_SUCCESS
;
239 PIO_STACK_LOCATION IoStackLocation
;
244 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
246 DPRINT("DriverIoControl. Code=0x%08X, DeviceObject=%p, FileObject=%p, FsContext=%p, FsContext2=%p\n",
247 IoStackLocation
->Parameters
.DeviceIoControl
.IoControlCode
,
248 DeviceObject
, IoStackLocation
->FileObject
,
249 IoStackLocation
->FileObject
->FsContext
, IoStackLocation
->FileObject
->FsContext2
);
251 switch (IoStackLocation
->Parameters
.DeviceIoControl
.IoControlCode
)
253 case IOCTL_KMTEST_GET_TESTS
:
255 PCKMT_TEST TestEntry
;
256 LPSTR OutputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
257 size_t Remaining
= IoStackLocation
->Parameters
.DeviceIoControl
.OutputBufferLength
;
259 DPRINT("DriverIoControl. IOCTL_KMTEST_GET_TESTS, outlen=%lu\n",
260 IoStackLocation
->Parameters
.DeviceIoControl
.OutputBufferLength
);
262 for (TestEntry
= TestList
; TestEntry
->TestName
; ++TestEntry
)
264 RtlStringCbCopyExA(OutputBuffer
, Remaining
, TestEntry
->TestName
, &OutputBuffer
, &Remaining
, 0);
267 *OutputBuffer
++ = '\0';
273 *OutputBuffer
++ = '\0';
276 Length
= IoStackLocation
->Parameters
.DeviceIoControl
.OutputBufferLength
- Remaining
;
279 case IOCTL_KMTEST_RUN_TEST
:
281 ANSI_STRING TestName
;
282 PCKMT_TEST TestEntry
;
284 DPRINT("DriverIoControl. IOCTL_KMTEST_RUN_TEST, inlen=%lu, outlen=%lu\n",
285 IoStackLocation
->Parameters
.DeviceIoControl
.InputBufferLength
,
286 IoStackLocation
->Parameters
.DeviceIoControl
.OutputBufferLength
);
287 TestName
.Length
= TestName
.MaximumLength
= (USHORT
)min(IoStackLocation
->Parameters
.DeviceIoControl
.InputBufferLength
, USHRT_MAX
);
288 TestName
.Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
289 DPRINT("DriverIoControl. Run test: %Z\n", &TestName
);
291 for (TestEntry
= TestList
; TestEntry
->TestName
; ++TestEntry
)
293 ANSI_STRING EntryName
;
294 if (TestEntry
->TestName
[0] == '-')
295 RtlInitAnsiString(&EntryName
, TestEntry
->TestName
+ 1);
297 RtlInitAnsiString(&EntryName
, TestEntry
->TestName
);
299 if (!RtlCompareString(&TestName
, &EntryName
, FALSE
))
301 DPRINT1("DriverIoControl. Starting test %Z\n", &EntryName
);
302 TestEntry
->TestFunction();
303 DPRINT1("DriverIoControl. Finished test %Z\n", &EntryName
);
308 if (!TestEntry
->TestName
)
309 Status
= STATUS_OBJECT_NAME_INVALID
;
313 case IOCTL_KMTEST_SET_RESULTBUFFER
:
315 PKMT_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
317 DPRINT("DriverIoControl. IOCTL_KMTEST_SET_RESULTBUFFER, buffer=%p, inlen=%lu, outlen=%lu\n",
318 IoStackLocation
->Parameters
.DeviceIoControl
.Type3InputBuffer
,
319 IoStackLocation
->Parameters
.DeviceIoControl
.InputBufferLength
,
320 IoStackLocation
->Parameters
.DeviceIoControl
.OutputBufferLength
);
322 if (DeviceExtension
->Mdl
)
324 if (IoStackLocation
->FileObject
->FsContext
!= DeviceExtension
->Mdl
)
326 Status
= STATUS_ACCESS_DENIED
;
329 MmUnlockPages(DeviceExtension
->Mdl
);
330 IoFreeMdl(DeviceExtension
->Mdl
);
331 IoStackLocation
->FileObject
->FsContext
= NULL
;
332 ResultBuffer
= DeviceExtension
->ResultBuffer
= NULL
;
335 DeviceExtension
->Mdl
= IoAllocateMdl(IoStackLocation
->Parameters
.DeviceIoControl
.Type3InputBuffer
,
336 IoStackLocation
->Parameters
.DeviceIoControl
.InputBufferLength
,
338 if (!DeviceExtension
->Mdl
)
340 Status
= STATUS_INSUFFICIENT_RESOURCES
;
346 MmProbeAndLockPages(DeviceExtension
->Mdl
, UserMode
, IoModifyAccess
);
348 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
350 Status
= _SEH2_GetExceptionCode();
351 IoFreeMdl(DeviceExtension
->Mdl
);
352 DeviceExtension
->Mdl
= NULL
;
356 ResultBuffer
= DeviceExtension
->ResultBuffer
= MmGetSystemAddressForMdlSafe(DeviceExtension
->Mdl
, NormalPagePriority
);
357 IoStackLocation
->FileObject
->FsContext
= DeviceExtension
->Mdl
;
359 DPRINT("DriverIoControl. ResultBuffer: %ld %ld %ld %ld\n",
360 ResultBuffer
->Successes
, ResultBuffer
->Failures
,
361 ResultBuffer
->LogBufferLength
, ResultBuffer
->LogBufferMaxLength
);
365 DPRINT1("DriverIoControl. Invalid IoCtl code 0x%08X\n",
366 IoStackLocation
->Parameters
.DeviceIoControl
.IoControlCode
);
367 Status
= STATUS_INVALID_DEVICE_REQUEST
;
371 Irp
->IoStatus
.Status
= Status
;
372 Irp
->IoStatus
.Information
= Length
;
374 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);