2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Driver Object Test Driver
5 * PROGRAMMER: Michael Martin <martinmnet@hotmail.com>
6 * Thomas Faber <thfabba@gmx.de>
21 static KMT_IRP_HANDLER TestIrpHandler
;
22 static VOID
TestDriverObject(IN PDRIVER_OBJECT DriverObject
, IN DRIVER_STATUS DriverStatus
);
24 static PDEVICE_OBJECT MainDeviceObject
;
25 static PDEVICE_OBJECT AttachDeviceObject
;
26 static PDRIVER_OBJECT ThisDriverObject
;
30 IN PDRIVER_OBJECT DriverObject
,
31 IN PCUNICODE_STRING RegistryPath
,
32 OUT PCWSTR
*DeviceName
,
35 NTSTATUS Status
= STATUS_SUCCESS
;
39 UNREFERENCED_PARAMETER(RegistryPath
);
40 UNREFERENCED_PARAMETER(Flags
);
42 *DeviceName
= L
"IoDriverObject";
44 KmtRegisterIrpHandler(IRP_MJ_CREATE
, NULL
, TestIrpHandler
);
45 KmtRegisterIrpHandler(IRP_MJ_CLOSE
, NULL
, TestIrpHandler
);
47 TestDriverObject(DriverObject
, DriverEntry
);
54 IN PDRIVER_OBJECT DriverObject
)
58 TestDriverObject(DriverObject
, DriverUnload
);
64 IN PDEVICE_OBJECT DeviceObject
,
66 IN PIO_STACK_LOCATION IoStackLocation
)
68 NTSTATUS Status
= STATUS_SUCCESS
;
70 UNREFERENCED_PARAMETER(IoStackLocation
);
72 TestDriverObject(DeviceObject
->DriverObject
, DriverIrp
);
74 Irp
->IoStatus
.Status
= Status
;
75 Irp
->IoStatus
.Information
= 0;
77 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
85 IN PDRIVER_OBJECT DriverObject
,
86 IN DRIVER_STATUS DriverStatus
)
88 BOOLEAN CheckThisDispatchRoutine
;
92 ok(DriverObject
->Size
== sizeof(DRIVER_OBJECT
), "Size does not match, got %x",DriverObject
->Size
);
93 ok(DriverObject
->Type
== 4, "Type does not match 4. got %d",DriverObject
->Type
);
95 if (DriverStatus
== DriverEntry
)
97 ok(DriverObject
->DeviceObject
== NULL
, "Expected DeviceObject pointer to be 0, got %p",
98 DriverObject
->DeviceObject
);
99 ok (DriverObject
->Flags
== DRVO_LEGACY_DRIVER
,
100 "Expected Flags to be DRVO_LEGACY_DRIVER, got %lu",
101 DriverObject
->Flags
);
103 else if (DriverStatus
== DriverIrp
)
105 ok(DriverObject
->DeviceObject
!= NULL
, "Expected DeviceObject pointer to non null");
106 ok (DriverObject
->Flags
== (DRVO_LEGACY_DRIVER
| DRVO_INITIALIZED
),
107 "Expected Flags to be DRVO_LEGACY_DRIVER | DRVO_INITIALIZED, got %lu",
108 DriverObject
->Flags
);
110 else if (DriverStatus
== DriverUnload
)
112 ok(DriverObject
->DeviceObject
!= NULL
, "Expected DeviceObject pointer to non null");
113 ok (DriverObject
->Flags
== (DRVO_LEGACY_DRIVER
| DRVO_INITIALIZED
| DRVO_UNLOAD_INVOKED
),
114 "Expected Flags to be DRVO_LEGACY_DRIVER | DRVO_INITIALIZED | DRVO_UNLOAD_INVOKED, got %lu",
115 DriverObject
->Flags
);
120 /* Select a routine that was not changed */
121 FirstMajorFunc
= DriverObject
->MajorFunction
[1];
122 ok(FirstMajorFunc
!= 0, "Expected MajorFunction[1] to be non NULL");
124 if (!skip(FirstMajorFunc
!= NULL
, "First major function not set!\n"))
126 for (i
= 0; i
<= IRP_MJ_MAXIMUM_FUNCTION
; i
++)
128 if (DriverStatus
> 0) CheckThisDispatchRoutine
= (i
> 3) && (i
!= 14);
129 else CheckThisDispatchRoutine
= TRUE
;
131 if (CheckThisDispatchRoutine
)
133 ok(DriverObject
->MajorFunction
[i
] == FirstMajorFunc
, "Expected MajorFunction[%d] to match %p",
140 BOOLEAN
ZwLoadTest(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING DriverRegistryPath
, PWCHAR NewDriverRegPath
)
142 UNICODE_STRING RegPath
;
145 /* Try to load ourself */
146 Status
= ZwLoadDriver(DriverRegistryPath
);
147 ok (Status
== STATUS_IMAGE_ALREADY_LOADED
, "Expected NTSTATUS STATUS_IMAGE_ALREADY_LOADED, got 0x%lX", Status
);
149 if (Status
!= STATUS_IMAGE_ALREADY_LOADED
)
151 DbgPrint("WARNING: Loading this a second time will cause BUGCHECK!\n");
154 /* Try to load with a Registry Path that doesnt exist */
155 RtlInitUnicodeString(&RegPath
, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\deadbeef");
156 Status
= ZwLoadDriver(&RegPath
);
157 ok (Status
== STATUS_OBJECT_NAME_NOT_FOUND
, "Expected NTSTATUS STATUS_OBJECT_NAME_NOT_FOUND, got 0x%lX", Status
);
159 /* Load the driver */
160 RtlInitUnicodeString(&RegPath
, NewDriverRegPath
);
161 Status
= ZwLoadDriver(&RegPath
);
162 ok(Status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got 0x%lX", Status
);
164 if (!NT_SUCCESS(Status
))
172 BOOLEAN
ZwUnloadTest(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING DriverRegistryPath
, PWCHAR NewDriverRegPath
)
174 UNICODE_STRING RegPath
;
177 /* Try to unload ourself, which should fail as our Unload routine hasnt been set yet. */
178 Status
= ZwUnloadDriver(DriverRegistryPath
);
179 ok (Status
== STATUS_INVALID_DEVICE_REQUEST
, "Expected NTSTATUS STATUS_INVALID_DEVICE_REQUEST, got 0x%lX", Status
);
181 /* Try to unload with a Registry Path that doesnt exist */
182 RtlInitUnicodeString(&RegPath
, L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\deadbeef");
183 Status
= ZwUnloadDriver(&RegPath
);
184 ok (Status
== STATUS_OBJECT_NAME_NOT_FOUND
, "Expected NTSTATUS STATUS_OBJECT_NAME_NOT_FOUND, got 0x%lX", Status
);
186 /* Unload the driver */
187 RtlInitUnicodeString(&RegPath
, NewDriverRegPath
);
188 Status
= ZwUnloadDriver(&RegPath
);
189 ok(Status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got 0x%lX", Status
);
191 if (!NT_SUCCESS(Status
))
199 VOID
LowerDeviceKernelAPITest(PDEVICE_OBJECT DeviceObject
, BOOLEAN UnLoading
)
201 PDEVICE_OBJECT RetObject
;
203 RetObject
= IoGetLowerDeviceObject(DeviceObject
);
208 "Expected no Lower DeviceObject, got %p", RetObject
);
212 ok(RetObject
== AttachDeviceObject
,
213 "Expected an Attached DeviceObject %p, got %p", AttachDeviceObject
, RetObject
);
218 ObDereferenceObject(RetObject
);
221 RetObject
= IoGetDeviceAttachmentBaseRef(DeviceObject
);
222 ok(RetObject
== DeviceObject
,
223 "Expected an Attached DeviceObject %p, got %p", DeviceObject
, RetObject
);
227 ObDereferenceObject(RetObject
);
231 VOID
DeviceCreatedTest(PDEVICE_OBJECT DeviceObject
, BOOLEAN ExclusiveAccess
)
233 PEXTENDED_DEVOBJ_EXTENSION extdev
;
235 /*Check the device object members */
236 ok(DeviceObject
->Type
==3, "Expected Type = 3, got %x", DeviceObject
->Type
);
237 ok(DeviceObject
->Size
= 0xb8, "Expected Size = 0xba, got %x", DeviceObject
->Size
);
238 ok(DeviceObject
->ReferenceCount
== 0, "Expected ReferenceCount = 0, got %lu",
239 DeviceObject
->ReferenceCount
);
240 ok(DeviceObject
->DriverObject
== ThisDriverObject
,
241 "Expected DriverObject member to match this DriverObject %p, got %p",
242 ThisDriverObject
, DeviceObject
->DriverObject
);
243 ok(DeviceObject
->NextDevice
== NULL
, "Expected NextDevice to be NULL, got %p", DeviceObject
->NextDevice
);
244 ok(DeviceObject
->AttachedDevice
== NULL
, "Expected AttachDevice to be NULL, got %p", DeviceObject
->AttachedDevice
);
245 ok(DeviceObject
->Characteristics
== 0, "Expected Characteristics to be 0");
248 ok((DeviceObject
->Flags
== (DO_DEVICE_HAS_NAME
| DO_DEVICE_INITIALIZING
| DO_EXCLUSIVE
)),
249 "Expected Flags DO_DEVICE_HAS_NAME | DO_DEVICE_INITIALIZING | DO_EXCLUSIVE, got %lu", DeviceObject
->Flags
);
253 ok((DeviceObject
->Flags
== (DO_DEVICE_HAS_NAME
| DO_DEVICE_INITIALIZING
)),
254 "Expected Flags DO_DEVICE_HAS_NAME | DO_DEVICE_INITIALIZING, got %lu", DeviceObject
->Flags
);
256 ok(DeviceObject
->DeviceType
== FILE_DEVICE_UNKNOWN
,
257 "Expected DeviceType to match creation parameter FILE_DEVICE_UNKNWOWN, got %lu",
258 DeviceObject
->DeviceType
);
259 ok(DeviceObject
->ActiveThreadCount
== 0, "Expected ActiveThreadCount = 0, got %lu\n", DeviceObject
->ActiveThreadCount
);
261 /*Check the extended extension */
262 extdev
= (PEXTENDED_DEVOBJ_EXTENSION
)DeviceObject
->DeviceObjectExtension
;
263 ok(extdev
->ExtensionFlags
== 0, "Expected Extended ExtensionFlags to be 0, got %lu", extdev
->ExtensionFlags
);
264 ok (extdev
->Type
== 13, "Expected Type of 13, got %d", extdev
->Type
);
265 ok (extdev
->Size
== 0, "Expected Size of 0, got %d", extdev
->Size
);
266 ok (extdev
->DeviceObject
== DeviceObject
, "Expected DeviceOject to match newly created device %p, got %p",
267 DeviceObject
, extdev
->DeviceObject
);
268 ok(extdev
->AttachedTo
== NULL
, "Expected AttachTo to be NULL, got %p", extdev
->AttachedTo
);
269 ok(extdev
->StartIoCount
== 0, "Expected StartIoCount = 0, got %lu", extdev
->StartIoCount
);
270 ok(extdev
->StartIoKey
== 0, "Expected StartIoKey = 0, got %lu", extdev
->StartIoKey
);
271 ok(extdev
->StartIoFlags
== 0, "Expected StartIoFlags = 0, got %lu", extdev
->StartIoFlags
);
274 VOID
DeviceDeletionTest(PDEVICE_OBJECT DeviceObject
, BOOLEAN Lower
)
276 PEXTENDED_DEVOBJ_EXTENSION extdev
;
278 /*Check the device object members */
279 ok(DeviceObject
->Type
==3, "Expected Type = 3, got %d", DeviceObject
->Type
);
280 ok(DeviceObject
->Size
= 0xb8, "Expected Size = 0xba, got %d", DeviceObject
->Size
);
281 ok(DeviceObject
->ReferenceCount
== 0, "Expected ReferenceCount = 0, got %lu",
282 DeviceObject
->ReferenceCount
);
285 ok(DeviceObject
->DriverObject
== ThisDriverObject
,
286 "Expected DriverObject member to match this DriverObject %p, got %p",
287 ThisDriverObject
, DeviceObject
->DriverObject
);
289 ok(DeviceObject
->NextDevice
== NULL
, "Expected NextDevice to be NULL, got %p", DeviceObject
->NextDevice
);
293 ok(DeviceObject
->AttachedDevice
== MainDeviceObject
,
294 "Expected AttachDevice to be %p, got %p", MainDeviceObject
, DeviceObject
->AttachedDevice
);
298 ok(DeviceObject
->AttachedDevice
== NULL
, "Expected AttachDevice to be NULL, got %p", DeviceObject
->AttachedDevice
);
301 ok(DeviceObject
->Flags
==FILE_VIRTUAL_VOLUME
,
302 "Expected Flags FILE_VIRTUAL_VOLUME, got %lu", DeviceObject
->Flags
);
303 ok(DeviceObject
->DeviceType
== FILE_DEVICE_UNKNOWN
,
304 "Expected DeviceType to match creation parameter FILE_DEVICE_UNKNWOWN, got %lu",
305 DeviceObject
->DeviceType
);
306 ok(DeviceObject
->ActiveThreadCount
== 0, "Expected ActiveThreadCount = 0, got %lu\n", DeviceObject
->ActiveThreadCount
);
308 /*Check the extended extension */
309 extdev
= (PEXTENDED_DEVOBJ_EXTENSION
)DeviceObject
->DeviceObjectExtension
;
310 ok(extdev
->ExtensionFlags
== DOE_UNLOAD_PENDING
,
311 "Expected Extended ExtensionFlags to be DOE_UNLOAD_PENDING, got %lu", extdev
->ExtensionFlags
);
312 ok (extdev
->Type
== 13, "Expected Type of 13, got %d", extdev
->Type
);
313 ok (extdev
->Size
== 0, "Expected Size of 0, got %d", extdev
->Size
);
314 ok (extdev
->DeviceObject
== DeviceObject
, "Expected DeviceOject to match newly created device %p, got %p",
315 DeviceObject
, extdev
->DeviceObject
);
318 /* Skip this for now */
319 //ok(extdev->AttachedTo == MainDeviceObject, "Expected AttachTo to %p, got %p", MainDeviceObject, extdev->AttachedTo);
323 ok(extdev
->AttachedTo
== NULL
, "Expected AttachTo to be NULL, got %p", extdev
->AttachedTo
);
325 ok(extdev
->StartIoCount
== 0, "Expected StartIoCount = 0, got %lu", extdev
->StartIoCount
);
326 ok(extdev
->StartIoKey
== 0, "Expected StartIoKey = 0, got %lu", extdev
->StartIoKey
);
327 ok(extdev
->StartIoFlags
== 0, "Expected StartIoFlags = 0, got %lu", extdev
->StartIoFlags
);
330 VOID
DeviceCreateDeleteTest(PDRIVER_OBJECT DriverObject
)
333 UNICODE_STRING DeviceString
;
334 UNICODE_STRING DosDeviceString
;
335 PDEVICE_OBJECT DeviceObject
;
337 /* Create using wrong directory */
338 RtlInitUnicodeString(&DeviceString
, L
"\\Device1\\Kmtest");
339 Status
= IoCreateDevice(DriverObject
,
346 ok(Status
== STATUS_OBJECT_PATH_NOT_FOUND
, "Expected STATUS_OBJECT_PATH_NOT_FOUND, got 0x%lX", Status
);
348 /* Create using correct params with exlusice access */
349 RtlInitUnicodeString(&DeviceString
, L
"\\Device\\Kmtest");
350 Status
= IoCreateDevice(DriverObject
,
357 ok(Status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got 0x%lX", Status
);
359 DeviceCreatedTest(DeviceObject
, TRUE
);
361 /* Delete the device */
362 if (NT_SUCCESS(Status
))
364 IoDeleteDevice(DeviceObject
);
365 ok(DriverObject
->DeviceObject
== 0, "Expected DriverObject->DeviceObject to be NULL, got %p",
366 DriverObject
->DeviceObject
);
369 /* Create using correct params with exlusice access */
370 Status
= IoCreateDevice(DriverObject
,
377 ok(Status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got 0x%lX", Status
);
379 DeviceCreatedTest(DeviceObject
, FALSE
);
381 /* Delete the device */
382 if (NT_SUCCESS(Status
))
384 IoDeleteDevice(DeviceObject
);
385 ok(DriverObject
->DeviceObject
== 0, "Expected DriverObject->DeviceObject to be NULL, got %p",
386 DriverObject
->DeviceObject
);
389 /* Recreate device */
390 Status
= IoCreateDevice(DriverObject
,
397 ok(Status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got 0x%lX", Status
);
399 RtlInitUnicodeString(&DosDeviceString
, L
"\\DosDevices\\kmtest");
400 Status
= IoCreateSymbolicLink(&DosDeviceString
, &DeviceString
);
402 if (!NT_SUCCESS(Status
))
404 /* Delete device object if not successful */
405 IoDeleteDevice(DeviceObject
);
409 MainDeviceObject
= DeviceObject
;
414 BOOLEAN
AttachDeviceTest(PDEVICE_OBJECT DeviceObject
, PWCHAR NewDriverRegPath
)
417 UNICODE_STRING LowerDeviceName
;
419 RtlInitUnicodeString(&LowerDeviceName
, NewDriverRegPath
);
420 Status
= IoAttachDevice(DeviceObject
, &LowerDeviceName
, &AttachDeviceObject
);
422 /* TODO: Add more tests */
427 BOOLEAN
DetachDeviceTest(PDEVICE_OBJECT AttachedDevice
)
430 IoDetachDevice(AttachedDevice
);
432 /* TODO: Add more tests */