1 /* 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 <thomas.faber@reactos.org> 7 */ 8 9 #include <kmt_test.h> 10 11 //#define NDEBUG 12 #include <debug.h> 13 14 #define BASE_POOL_TYPE_MASK 1 15 16 typedef enum 17 { 18 DriverStatusEntry, 19 DriverStatusIrp, 20 DriverStatusUnload 21 } DRIVER_STATUS; 22 23 static DRIVER_DISPATCH TestDispatch; 24 static VOID TestDriverObject(IN PDRIVER_OBJECT DriverObject, IN PCUNICODE_STRING RegistryPath OPTIONAL, IN DRIVER_STATUS DriverStatus); 25 static BOOLEAN TestZwLoad(IN PDRIVER_OBJECT DriverObject, IN PCUNICODE_STRING DriverRegistryPath, IN PWCHAR NewDriverRegPath); 26 static BOOLEAN TestZwUnload(IN PDRIVER_OBJECT DriverObject, IN PCUNICODE_STRING DriverRegistryPath, IN PWCHAR NewDriverRegPath); 27 static VOID TestLowerDeviceKernelAPI(IN PDEVICE_OBJECT DeviceObject); 28 static VOID TestDeviceCreated(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN ExclusiveAccess); 29 static VOID TestDeviceDeletion(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Lower, IN BOOLEAN Attached); 30 static VOID TestDeviceCreateDelete(IN PDRIVER_OBJECT DriverObject); 31 static VOID TestAttachDevice(IN PDEVICE_OBJECT DeviceObject, IN PWCHAR NewDriverRegPath); 32 static VOID TestDetachDevice(IN PDEVICE_OBJECT AttachedDevice); 33 34 static PDEVICE_OBJECT MainDeviceObject; 35 static PDEVICE_OBJECT AttachDeviceObject; 36 static PDRIVER_OBJECT ThisDriverObject; 37 38 NTSTATUS 39 TestEntry( 40 IN PDRIVER_OBJECT DriverObject, 41 IN PCUNICODE_STRING RegistryPath, 42 OUT PCWSTR *DeviceName, 43 IN OUT INT *Flags) 44 { 45 NTSTATUS Status = STATUS_SUCCESS; 46 BOOLEAN Ret; 47 INT i; 48 49 PAGED_CODE(); 50 51 UNREFERENCED_PARAMETER(DeviceName); 52 53 *Flags = TESTENTRY_NO_CREATE_DEVICE | TESTENTRY_NO_REGISTER_DISPATCH; 54 55 ThisDriverObject = DriverObject; 56 57 TestDriverObject(DriverObject, RegistryPath, DriverStatusEntry); 58 59 /* Create and delete device, on return MainDeviceObject has been created */ 60 TestDeviceCreateDelete(DriverObject); 61 62 /* Make sure a device object was created */ 63 if (!skip(MainDeviceObject != NULL, "Device object creation failed\n")) 64 { 65 PWCHAR LowerDriverRegPath = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Kmtest-IoHelper"; 66 67 /* Load driver test and load the lower driver */ 68 Ret = TestZwLoad(DriverObject, RegistryPath, LowerDriverRegPath); 69 if (!skip(Ret, "Failed to load helper driver\n")) 70 { 71 TestAttachDevice(MainDeviceObject, L"\\Device\\Kmtest-IoHelper"); 72 if (!skip(AttachDeviceObject != NULL, "No attached device object\n")) 73 TestLowerDeviceKernelAPI(MainDeviceObject); 74 75 /* Unload lower driver without detaching from its device */ 76 TestZwUnload(DriverObject, RegistryPath, LowerDriverRegPath); 77 TestLowerDeviceKernelAPI(MainDeviceObject); 78 } 79 } 80 81 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i) 82 DriverObject->MajorFunction[i] = NULL; 83 DriverObject->MajorFunction[IRP_MJ_CREATE] = TestDispatch; 84 DriverObject->MajorFunction[IRP_MJ_CLOSE] = TestDispatch; 85 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TestDispatch; 86 87 return Status; 88 } 89 90 VOID 91 TestUnload( 92 IN PDRIVER_OBJECT DriverObject) 93 { 94 PAGED_CODE(); 95 96 if (!skip(AttachDeviceObject != NULL, "no attached device object\n")) 97 { 98 TestDeviceDeletion(MainDeviceObject, FALSE, TRUE); 99 TestDeviceDeletion(AttachDeviceObject, TRUE, FALSE); 100 TestDetachDevice(AttachDeviceObject); 101 } 102 103 TestDeviceDeletion(MainDeviceObject, FALSE, FALSE); 104 TestDriverObject(DriverObject, NULL, DriverStatusUnload); 105 106 if (MainDeviceObject) 107 IoDeleteDevice(MainDeviceObject); 108 } 109 110 static 111 NTSTATUS 112 NTAPI 113 TestDispatch( 114 IN PDEVICE_OBJECT DeviceObject, 115 IN PIRP Irp) 116 { 117 NTSTATUS Status = STATUS_SUCCESS; 118 PIO_STACK_LOCATION IoStackLocation; 119 120 PAGED_CODE(); 121 122 IoStackLocation = IoGetCurrentIrpStackLocation(Irp); 123 124 DPRINT("TestIrpHandler. Function=%s, DeviceObject=%p, AttachDeviceObject=%p\n", 125 KmtMajorFunctionNames[IoStackLocation->MajorFunction], 126 DeviceObject, 127 AttachDeviceObject); 128 129 if (AttachDeviceObject) 130 { 131 IoSkipCurrentIrpStackLocation(Irp); 132 Status = IoCallDriver(AttachDeviceObject, Irp); 133 return Status; 134 } 135 136 TestDriverObject(DeviceObject->DriverObject, NULL, DriverStatusIrp); 137 138 Irp->IoStatus.Status = Status; 139 Irp->IoStatus.Information = 0; 140 141 IoCompleteRequest(Irp, IO_NO_INCREMENT); 142 143 return Status; 144 } 145 146 extern DRIVER_INITIALIZE DriverEntry; 147 148 static 149 VOID 150 TestDriverObject( 151 IN PDRIVER_OBJECT DriverObject, 152 IN PCUNICODE_STRING RegistryPath OPTIONAL, 153 IN DRIVER_STATUS DriverStatus) 154 { 155 BOOLEAN CheckThisDispatchRoutine; 156 PVOID FirstMajorFunc; 157 int i; 158 UNICODE_STRING HardwareDatabase = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM"); 159 UNICODE_STRING RegPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet001\\Services\\Kmtest-IoDeviceObject"); 160 UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"\\Driver\\Kmtest-IoDeviceObject"); 161 UNICODE_STRING ServiceKeyName = RTL_CONSTANT_STRING(L"Kmtest-IoDeviceObject"); 162 BOOLEAN Equal; 163 164 ok(DriverObject->Size == sizeof(DRIVER_OBJECT), "Size does not match, got %x\n",DriverObject->Size); 165 ok(DriverObject->Type == 4, "Type does not match 4. got %d\n", DriverObject->Type); 166 167 if (DriverStatus == DriverStatusEntry) 168 { 169 ok(DriverObject->DeviceObject == NULL, "Expected DeviceObject pointer to be 0, got %p\n", 170 DriverObject->DeviceObject); 171 ok (DriverObject->Flags == DRVO_LEGACY_DRIVER, 172 "Expected Flags to be DRVO_LEGACY_DRIVER, got %lu\n", 173 DriverObject->Flags); 174 175 ok(DriverObject->DriverStart < (PVOID)TestEntry, 176 "DriverStart is %p, expected < %p\n", 177 DriverObject->DriverStart, (PVOID)TestEntry); 178 ok(DriverObject->DriverSize > 0x2000, 179 "DriverSize 0x%lx\n", DriverObject->DriverSize); 180 ok_eq_pointer(DriverObject->DriverExtension, (PDRIVER_EXTENSION)(DriverObject + 1)); 181 ok_eq_pointer(DriverObject->DriverExtension->DriverObject, DriverObject); 182 ok_eq_pointer(DriverObject->DriverExtension->AddDevice, NULL); 183 ok_eq_ulong(DriverObject->DriverExtension->Count, 0UL); 184 Equal = RtlEqualUnicodeString(RegistryPath, 185 &RegPath, 186 FALSE); 187 ok(Equal, "RegistryPath is '%wZ'\n", RegistryPath); 188 ok((ULONG_PTR)RegistryPath % PAGE_SIZE == 0, "RegistryPath %p not page-aligned\n", RegistryPath); 189 ok_eq_pointer(RegistryPath->Buffer, (PWCHAR)(RegistryPath + 1)); 190 ok_eq_uint(RegistryPath->MaximumLength, RegistryPath->Length); 191 Equal = RtlEqualUnicodeString(&DriverObject->DriverExtension->ServiceKeyName, 192 &ServiceKeyName, 193 FALSE); 194 ok(Equal, "ServiceKeyName is '%wZ'\n", &DriverObject->DriverExtension->ServiceKeyName); 195 ok_eq_tag(KmtGetPoolTag(DriverObject->DriverExtension->ServiceKeyName.Buffer), ' oI'); 196 ok_eq_uint((KmtGetPoolType(DriverObject->DriverExtension->ServiceKeyName.Buffer) - 1) & BASE_POOL_TYPE_MASK, NonPagedPool); 197 ok_eq_uint(DriverObject->DriverExtension->ServiceKeyName.MaximumLength, DriverObject->DriverExtension->ServiceKeyName.Length + sizeof(UNICODE_NULL)); 198 ok_eq_uint(DriverObject->DriverExtension->ServiceKeyName.Buffer[DriverObject->DriverExtension->ServiceKeyName.Length / sizeof(WCHAR)], UNICODE_NULL); 199 Equal = RtlEqualUnicodeString(&DriverObject->DriverName, 200 &DriverName, 201 FALSE); 202 ok(Equal, "DriverName is '%wZ'\n", &DriverObject->DriverName); 203 ok_eq_tag(KmtGetPoolTag(DriverObject->DriverName.Buffer), ' oI'); 204 ok_eq_uint((KmtGetPoolType(DriverObject->DriverName.Buffer) - 1) & BASE_POOL_TYPE_MASK, PagedPool); 205 ok_eq_uint(DriverObject->DriverName.MaximumLength, DriverObject->DriverName.Length); 206 // TODO: show that both string and buffer are constants inside ntos 207 Equal = RtlEqualUnicodeString(DriverObject->HardwareDatabase, 208 &HardwareDatabase, 209 FALSE); 210 ok(Equal, "HardwareDatabase is '%wZ'\n", DriverObject->HardwareDatabase); 211 ok_eq_uint(DriverObject->HardwareDatabase->MaximumLength, DriverObject->HardwareDatabase->Length + sizeof(UNICODE_NULL)); 212 ok_eq_uint(DriverObject->HardwareDatabase->Buffer[DriverObject->HardwareDatabase->Length / sizeof(WCHAR)], UNICODE_NULL); 213 ok(DriverObject->DriverInit == DriverEntry, 214 "DriverInit is %p, expected %p\n", 215 (PVOID)DriverObject->DriverInit, (PVOID)DriverEntry); 216 } 217 else if (DriverStatus == DriverStatusIrp) 218 { 219 ok(DriverObject->DeviceObject != NULL, "Expected DeviceObject pointer to non null\n"); 220 ok (DriverObject->Flags == (DRVO_LEGACY_DRIVER | DRVO_INITIALIZED), 221 "Expected Flags to be DRVO_LEGACY_DRIVER | DRVO_INITIALIZED, got %lu\n", 222 DriverObject->Flags); 223 } 224 else if (DriverStatus == DriverStatusUnload) 225 { 226 ok(DriverObject->DeviceObject != NULL, "Expected DeviceObject pointer to non null\n"); 227 ok (DriverObject->Flags == (DRVO_LEGACY_DRIVER | DRVO_INITIALIZED | DRVO_UNLOAD_INVOKED), 228 "Expected Flags to be DRVO_LEGACY_DRIVER | DRVO_INITIALIZED | DRVO_UNLOAD_INVOKED, got %lu\n", 229 DriverObject->Flags); 230 } 231 else 232 ASSERT(FALSE); 233 234 /* Select a routine that was not changed */ 235 FirstMajorFunc = DriverObject->MajorFunction[1]; 236 ok(FirstMajorFunc != 0, "Expected MajorFunction[1] to be non NULL\n"); 237 238 if (!skip(FirstMajorFunc != NULL, "First major function not set!\n")) 239 { 240 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) 241 { 242 if (DriverStatus > 0) CheckThisDispatchRoutine = (i > 3) && (i != 14); 243 else CheckThisDispatchRoutine = TRUE; 244 245 if (CheckThisDispatchRoutine) 246 { 247 ok(DriverObject->MajorFunction[i] == FirstMajorFunc, "Expected MajorFunction[%d] to match %p\n", 248 i, FirstMajorFunc); 249 } 250 } 251 } 252 } 253 254 static 255 BOOLEAN 256 TestZwLoad( 257 IN PDRIVER_OBJECT DriverObject, 258 IN PCUNICODE_STRING DriverRegistryPath, 259 IN PWCHAR NewDriverRegPath) 260 { 261 UNICODE_STRING RegPath; 262 NTSTATUS Status; 263 264 /* Try to load ourself */ 265 Status = ZwLoadDriver((PUNICODE_STRING)DriverRegistryPath); 266 ok (Status == STATUS_IMAGE_ALREADY_LOADED, "Expected NTSTATUS STATUS_IMAGE_ALREADY_LOADED, got 0x%lX\n", Status); 267 268 if (Status != STATUS_IMAGE_ALREADY_LOADED) 269 { 270 DbgPrint("WARNING: Loading this a second time will cause BUGCHECK!\n"); 271 } 272 273 /* Try to load with a Registry Path that doesnt exist */ 274 RtlInitUnicodeString(&RegPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\deadbeef"); 275 Status = ZwLoadDriver(&RegPath); 276 ok (Status == STATUS_OBJECT_NAME_NOT_FOUND, "Expected NTSTATUS STATUS_OBJECT_NAME_NOT_FOUND, got 0x%lX\n", Status); 277 278 /* Load the driver */ 279 RtlInitUnicodeString(&RegPath, NewDriverRegPath); 280 Status = ZwLoadDriver(&RegPath); 281 ok(Status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got 0x%lX\n", Status); 282 283 return NT_SUCCESS(Status); 284 } 285 286 static 287 BOOLEAN 288 TestZwUnload( 289 IN PDRIVER_OBJECT DriverObject, 290 IN PCUNICODE_STRING DriverRegistryPath, 291 IN PWCHAR NewDriverRegPath) 292 { 293 UNICODE_STRING RegPath; 294 NTSTATUS Status; 295 296 /* Try to unload ourself, which should fail as our Unload routine hasnt been set yet. */ 297 Status = ZwUnloadDriver((PUNICODE_STRING)DriverRegistryPath); 298 ok (Status == STATUS_INVALID_DEVICE_REQUEST, "Expected NTSTATUS STATUS_INVALID_DEVICE_REQUEST, got 0x%lX\n", Status); 299 300 /* Try to unload with a Registry Path that doesnt exist */ 301 RtlInitUnicodeString(&RegPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\deadbeef"); 302 Status = ZwUnloadDriver(&RegPath); 303 ok (Status == STATUS_OBJECT_NAME_NOT_FOUND, "Expected NTSTATUS STATUS_OBJECT_NAME_NOT_FOUND, got 0x%lX\n", Status); 304 305 /* Unload the driver */ 306 RtlInitUnicodeString(&RegPath, NewDriverRegPath); 307 Status = ZwUnloadDriver(&RegPath); 308 ok(Status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got 0x%lX\n", Status); 309 310 return NT_SUCCESS(Status); 311 } 312 313 static 314 VOID 315 TestLowerDeviceKernelAPI( 316 IN PDEVICE_OBJECT DeviceObject) 317 { 318 PDEVICE_OBJECT RetObject; 319 320 RetObject = IoGetLowerDeviceObject(DeviceObject); 321 322 ok(RetObject == AttachDeviceObject, 323 "Expected an Attached DeviceObject %p, got %p\n", AttachDeviceObject, RetObject); 324 325 if (RetObject) 326 { 327 ObDereferenceObject(RetObject); 328 } 329 330 RetObject = IoGetDeviceAttachmentBaseRef(DeviceObject); 331 ok(RetObject == AttachDeviceObject, 332 "Expected an Attached DeviceObject %p, got %p\n", AttachDeviceObject, RetObject); 333 334 if (RetObject) 335 { 336 ObDereferenceObject(RetObject); 337 } 338 339 } 340 341 static 342 VOID 343 TestDeviceCreated( 344 IN PDEVICE_OBJECT DeviceObject, 345 IN BOOLEAN ExclusiveAccess) 346 { 347 PEXTENDED_DEVOBJ_EXTENSION extdev; 348 349 /* Check the device object members */ 350 ok(DeviceObject->Type == 3, "Expected Type = 3, got %x\n", DeviceObject->Type); 351 ok(DeviceObject->Size == 0xb8, "Expected Size = 0xb8, got %x\n", DeviceObject->Size); 352 ok(DeviceObject->ReferenceCount == 0, "Expected ReferenceCount = 0, got %lu\n", 353 DeviceObject->ReferenceCount); 354 ok(DeviceObject->DriverObject == ThisDriverObject, 355 "Expected DriverObject member to match this DriverObject %p, got %p\n", 356 ThisDriverObject, DeviceObject->DriverObject); 357 ok(DeviceObject->NextDevice == NULL, "Expected NextDevice to be NULL, got %p\n", DeviceObject->NextDevice); 358 ok(DeviceObject->AttachedDevice == NULL, "Expected AttachDevice to be NULL, got %p\n", DeviceObject->AttachedDevice); 359 ok(DeviceObject->Characteristics == 0, "Expected Characteristics to be 0\n"); 360 if (ExclusiveAccess) 361 { 362 ok((DeviceObject->Flags == (DO_DEVICE_HAS_NAME | DO_DEVICE_INITIALIZING | DO_EXCLUSIVE)), 363 "Expected Flags DO_DEVICE_HAS_NAME | DO_DEVICE_INITIALIZING | DO_EXCLUSIVE, got %lu\n", DeviceObject->Flags); 364 } 365 else 366 { 367 ok((DeviceObject->Flags == (DO_DEVICE_HAS_NAME | DO_DEVICE_INITIALIZING)), 368 "Expected Flags DO_DEVICE_HAS_NAME | DO_DEVICE_INITIALIZING, got %lu\n", DeviceObject->Flags); 369 } 370 ok(DeviceObject->DeviceType == FILE_DEVICE_UNKNOWN, 371 "Expected DeviceType to match creation parameter FILE_DEVICE_UNKNWOWN, got %lu\n", 372 DeviceObject->DeviceType); 373 ok(DeviceObject->ActiveThreadCount == 0, "Expected ActiveThreadCount = 0, got %lu\n", DeviceObject->ActiveThreadCount); 374 375 /* Check the extended extension */ 376 extdev = (PEXTENDED_DEVOBJ_EXTENSION)DeviceObject->DeviceObjectExtension; 377 ok(extdev->ExtensionFlags == 0, "Expected Extended ExtensionFlags to be 0, got %lu\n", extdev->ExtensionFlags); 378 ok (extdev->Type == 13, "Expected Type of 13, got %d\n", extdev->Type); 379 ok (extdev->Size == 0, "Expected Size of 0, got %d\n", extdev->Size); 380 ok (extdev->DeviceObject == DeviceObject, "Expected DeviceOject to match newly created device %p, got %p\n", 381 DeviceObject, extdev->DeviceObject); 382 ok(extdev->AttachedTo == NULL, "Expected AttachTo to be NULL, got %p\n", extdev->AttachedTo); 383 ok(extdev->StartIoCount == 0, "Expected StartIoCount = 0, got %lu\n", extdev->StartIoCount); 384 ok(extdev->StartIoKey == 0, "Expected StartIoKey = 0, got %lu\n", extdev->StartIoKey); 385 ok(extdev->StartIoFlags == 0, "Expected StartIoFlags = 0, got %lu\n", extdev->StartIoFlags); 386 } 387 388 static 389 VOID 390 TestDeviceDeletion( 391 IN PDEVICE_OBJECT DeviceObject, 392 IN BOOLEAN Lower, 393 IN BOOLEAN Attached) 394 { 395 PEXTENDED_DEVOBJ_EXTENSION extdev; 396 397 /* Check the device object members */ 398 ok(DeviceObject->Type == 3, "Expected Type = 3, got %d\n", DeviceObject->Type); 399 ok(DeviceObject->Size == 0xb8, "Expected Size = 0xb8, got %d\n", DeviceObject->Size); 400 ok(DeviceObject->ReferenceCount == 0, "Expected ReferenceCount = 0, got %lu\n", 401 DeviceObject->ReferenceCount); 402 if (!Lower) 403 { 404 ok(DeviceObject->DriverObject == ThisDriverObject, 405 "Expected DriverObject member to match this DriverObject %p, got %p\n", 406 ThisDriverObject, DeviceObject->DriverObject); 407 } 408 ok(DeviceObject->NextDevice == NULL, "Expected NextDevice to be NULL, got %p\n", DeviceObject->NextDevice); 409 410 if (Lower) 411 { 412 ok(DeviceObject->AttachedDevice == MainDeviceObject, 413 "Expected AttachDevice to be %p, got %p\n", MainDeviceObject, DeviceObject->AttachedDevice); 414 } 415 else 416 { 417 ok(DeviceObject->AttachedDevice == NULL, "Expected AttachDevice to be NULL, got %p\n", DeviceObject->AttachedDevice); 418 } 419 420 ok(DeviceObject->Flags == (DO_DEVICE_HAS_NAME | (Lower ? DO_EXCLUSIVE : 0)), 421 "Expected Flags DO_DEVICE_HAS_NAME, got %lu\n", DeviceObject->Flags); 422 ok(DeviceObject->DeviceType == FILE_DEVICE_UNKNOWN, 423 "Expected DeviceType to match creation parameter FILE_DEVICE_UNKNWOWN, got %lu\n", 424 DeviceObject->DeviceType); 425 ok(DeviceObject->ActiveThreadCount == 0, "Expected ActiveThreadCount = 0, got %lu\n", DeviceObject->ActiveThreadCount); 426 427 /*Check the extended extension */ 428 extdev = (PEXTENDED_DEVOBJ_EXTENSION)DeviceObject->DeviceObjectExtension; 429 ok(extdev->ExtensionFlags == DOE_UNLOAD_PENDING, 430 "Expected Extended ExtensionFlags to be DOE_UNLOAD_PENDING, got %lu\n", extdev->ExtensionFlags); 431 ok (extdev->Type == 13, "Expected Type of 13, got %d\n", extdev->Type); 432 ok (extdev->Size == 0, "Expected Size of 0, got %d\n", extdev->Size); 433 ok (extdev->DeviceObject == DeviceObject, "Expected DeviceOject to match newly created device %p, got %p\n", 434 DeviceObject, extdev->DeviceObject); 435 if (Lower || !Attached) 436 { 437 ok(extdev->AttachedTo == NULL, "Expected AttachTo to be NULL, got %p\n", extdev->AttachedTo); 438 } 439 else 440 { 441 ok(extdev->AttachedTo == AttachDeviceObject, "Expected AttachTo to %p, got %p\n", AttachDeviceObject, extdev->AttachedTo); 442 } 443 ok(extdev->StartIoCount == 0, "Expected StartIoCount = 0, got %lu\n", extdev->StartIoCount); 444 ok(extdev->StartIoKey == 0, "Expected StartIoKey = 0, got %lu\n", extdev->StartIoKey); 445 ok(extdev->StartIoFlags == 0, "Expected StartIoFlags = 0, got %lu\n", extdev->StartIoFlags); 446 } 447 448 static 449 VOID 450 TestDeviceCreateDelete( 451 IN PDRIVER_OBJECT DriverObject) 452 { 453 NTSTATUS Status; 454 UNICODE_STRING DeviceString; 455 PDEVICE_OBJECT DeviceObject; 456 457 /* Create using wrong directory */ 458 RtlInitUnicodeString(&DeviceString, L"\\Device1\\Kmtest-IoDeviceObject"); 459 Status = IoCreateDevice(DriverObject, 460 0, 461 &DeviceString, 462 FILE_DEVICE_UNKNOWN, 463 0, 464 FALSE, 465 &DeviceObject); 466 ok(Status == STATUS_OBJECT_PATH_NOT_FOUND, "Expected STATUS_OBJECT_PATH_NOT_FOUND, got 0x%lX\n", Status); 467 468 /* Create using correct params with exclusice access */ 469 RtlInitUnicodeString(&DeviceString, L"\\Device\\Kmtest-IoDeviceObject"); 470 Status = IoCreateDevice(DriverObject, 471 0, 472 &DeviceString, 473 FILE_DEVICE_UNKNOWN, 474 0, 475 TRUE, 476 &DeviceObject); 477 ok(Status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got 0x%lX\n", Status); 478 479 TestDeviceCreated(DeviceObject, TRUE); 480 481 /* Delete the device */ 482 if (NT_SUCCESS(Status)) 483 { 484 IoDeleteDevice(DeviceObject); 485 ok(DriverObject->DeviceObject == 0, "Expected DriverObject->DeviceObject to be NULL, got %p\n", 486 DriverObject->DeviceObject); 487 } 488 489 /* Create using correct params without exclusice access */ 490 Status = IoCreateDevice(DriverObject, 491 0, 492 &DeviceString, 493 FILE_DEVICE_UNKNOWN, 494 0, 495 FALSE, 496 &DeviceObject); 497 ok(Status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got 0x%lX\n", Status); 498 499 TestDeviceCreated(DeviceObject, FALSE); 500 501 /* Delete the device */ 502 if (NT_SUCCESS(Status)) 503 { 504 IoDeleteDevice(DeviceObject); 505 ok(DriverObject->DeviceObject == 0, "Expected DriverObject->DeviceObject to be NULL, got %p\n", 506 DriverObject->DeviceObject); 507 } 508 509 /* Recreate device */ 510 Status = IoCreateDevice(DriverObject, 511 0, 512 &DeviceString, 513 FILE_DEVICE_UNKNOWN, 514 0, 515 FALSE, 516 &DeviceObject); 517 ok(Status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got 0x%lX\n", Status); 518 519 if (NT_SUCCESS(Status)) 520 MainDeviceObject = DeviceObject; 521 } 522 523 static 524 VOID 525 TestAttachDevice( 526 IN PDEVICE_OBJECT DeviceObject, 527 IN PWCHAR NewDriverRegPath) 528 { 529 NTSTATUS Status; 530 UNICODE_STRING LowerDeviceName; 531 532 RtlInitUnicodeString(&LowerDeviceName, NewDriverRegPath); 533 Status = IoAttachDevice(DeviceObject, &LowerDeviceName, &AttachDeviceObject); 534 ok_eq_hex(Status, STATUS_SUCCESS); 535 536 /* TODO: Add more tests */ 537 } 538 539 static 540 VOID 541 TestDetachDevice( 542 IN PDEVICE_OBJECT AttachedDevice) 543 { 544 IoDetachDevice(AttachedDevice); 545 546 /* TODO: Add more tests */ 547 } 548