static VOID NTAPI WaitForEventThread( IN OUT PVOID Context) { NTSTATUS Status; PTHREAD_DATA ThreadData = Context; ok_irql(PASSIVE_LEVEL); ThreadData->Signal = TRUE; Status = KeWaitForSingleObject(ThreadData->Event, Executive, KernelMode, FALSE, NULL); ok_eq_hex(Status, STATUS_SUCCESS); ok_irql(PASSIVE_LEVEL); }
/** * @name TestEntry * * Test entry point. * This is called by DriverEntry as early as possible, but with ResultBuffer * initialized, so that test macros work correctly * * @param DriverObject * Driver Object. * This is guaranteed not to have been touched by DriverEntry before * the call to TestEntry * @param RegistryPath * Driver Registry Path * This is guaranteed not to have been touched by DriverEntry before * the call to TestEntry * @param DeviceName * Pointer to receive a test-specific name for the device to create * @param Flags * Pointer to a flags variable instructing DriverEntry how to proceed. * See the KMT_TESTENTRY_FLAGS enumeration for possible values * Initialized to zero on entry * * @return Status. * DriverEntry will fail if this is a failure status */ NTSTATUS TestEntry( IN PDRIVER_OBJECT DriverObject, IN PCUNICODE_STRING RegistryPath, OUT PCWSTR *DeviceName, IN OUT INT *Flags) { NTSTATUS Status = STATUS_SUCCESS; PAGED_CODE(); UNREFERENCED_PARAMETER(RegistryPath); UNREFERENCED_PARAMETER(Flags); DPRINT("Entry!\n"); ok_irql(PASSIVE_LEVEL); TestDriverObject = DriverObject; *DeviceName = L"Example"; trace("Hi, this is the example driver\n"); KmtRegisterIrpHandler(IRP_MJ_CREATE, NULL, TestIrpHandler); KmtRegisterIrpHandler(IRP_MJ_CLOSE, NULL, TestIrpHandler); KmtRegisterMessageHandler(0, NULL, TestMessageHandler); return Status; }
/** * @name TestIrpHandler * * Test IRP handler routine * * @param DeviceObject * Device Object. * This is guaranteed not to have been touched by the dispatch function * before the call to the IRP handler * @param Irp * Device Object. * This is guaranteed not to have been touched by the dispatch function * before the call to the IRP handler, except for passing it to * IoGetCurrentStackLocation * @param IoStackLocation * Device Object. * This is guaranteed not to have been touched by the dispatch function * before the call to the IRP handler * * @return Status */ static NTSTATUS TestIrpHandler( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation) { NTSTATUS Status = STATUS_SUCCESS; DPRINT("IRP!\n"); ok_irql(PASSIVE_LEVEL); ok_eq_pointer(DeviceObject->DriverObject, TestDriverObject); if (IoStackLocation->MajorFunction == IRP_MJ_CREATE) trace("Got IRP_MJ_CREATE!\n"); else if (IoStackLocation->MajorFunction == IRP_MJ_CLOSE) trace("Got IRP_MJ_CLOSE!\n"); else trace("Got an IRP!\n"); Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
static NTSTATUS NTAPI NotificationCallback( _In_ PVOID NotificationStructure, _Inout_opt_ PVOID Context) { PDEVICE_INTERFACE_CHANGE_NOTIFICATION Notification = NotificationStructure; NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE Handle; ok_irql(PASSIVE_LEVEL); ok_eq_pointer(Context, &NotificationContext); ok_eq_uint(Notification->Version, 1); ok_eq_uint(Notification->Size, sizeof(*Notification)); /* symbolic link must exist */ trace("Interface change: %wZ\n", Notification->SymbolicLinkName); InitializeObjectAttributes(&ObjectAttributes, Notification->SymbolicLinkName, OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenSymbolicLinkObject(&Handle, GENERIC_READ, &ObjectAttributes); ok_eq_hex(Status, STATUS_SUCCESS); if (!skip(NT_SUCCESS(Status), "No symbolic link\n")) { Status = ObCloseHandle(Handle, KernelMode); ok_eq_hex(Status, STATUS_SUCCESS); } return STATUS_SUCCESS; }
/** * @name TestUnload * * Test unload routine. * This is called by the driver's Unload routine as early as possible, with * ResultBuffer and the test device object still valid, so that test macros * work correctly * * @param DriverObject * Driver Object. * This is guaranteed not to have been touched by Unload before the call * to TestEntry * * @return Status */ VOID TestUnload( IN PDRIVER_OBJECT DriverObject) { PAGED_CODE(); DPRINT("Unload!\n"); ok_irql(PASSIVE_LEVEL); ok_eq_pointer(DriverObject, TestDriverObject); trace("Unloading example driver\n"); }
static VOID NTAPI CallbackFunction( IN PVOID CallbackContext, IN PVOID Argument1, IN PVOID Argument2) { INT *InvocationCount = CallbackContext; ok_irql(PASSIVE_LEVEL); (*InvocationCount)++; ok_eq_pointer(Argument1, &CallbackArgument1); ok_eq_pointer(Argument2, &CallbackArgument2); }
static VOID NTAPI DpcHandler( IN PRKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2) { PKPRCB Prcb = KeGetCurrentPrcb(); ok_irql(DISPATCH_LEVEL); InterlockedIncrement(&DpcCount); ok(DeferredContext == Dpc, "DeferredContext = %p, Dpc = %p, expected equal\n", DeferredContext, Dpc); ok_eq_pointer(SystemArgument1, (PVOID)0xabc123); ok_eq_pointer(SystemArgument2, (PVOID)0x5678); /* KDPC object contents */ ok_eq_uint(Dpc->Type, DpcObject); ok_eq_uint(Dpc->Importance, DpcImportance); ok_eq_uint(Dpc->Number, 0); ok(Dpc->DpcListEntry.Blink != NULL, "\n"); ok(Dpc->DpcListEntry.Blink != &Dpc->DpcListEntry, "\n"); if (!skip(Dpc->DpcListEntry.Blink != NULL, "DpcListEntry.Blink == NULL\n")) ok_eq_pointer(Dpc->DpcListEntry.Flink, Dpc->DpcListEntry.Blink->Flink); ok(Dpc->DpcListEntry.Flink != NULL, "\n"); ok(Dpc->DpcListEntry.Flink != &Dpc->DpcListEntry, "\n"); if (!skip(Dpc->DpcListEntry.Flink != NULL, "DpcListEntry.Flink == NULL\n")) ok_eq_pointer(Dpc->DpcListEntry.Blink, Dpc->DpcListEntry.Flink->Blink); ok_eq_pointer(Dpc->DeferredRoutine, DpcHandler); ok_eq_pointer(Dpc->DeferredContext, DeferredContext); ok_eq_pointer(Dpc->SystemArgument1, SystemArgument1); ok_eq_pointer(Dpc->SystemArgument2, SystemArgument2); ok_eq_pointer(Dpc->DpcData, NULL); ok_eq_uint(Prcb->DpcRoutineActive, 1); /* this DPC is not in the list anymore, but it was at the head! */ ok_eq_pointer(Prcb->DpcData[DPC_NORMAL].DpcListHead.Flink, Dpc->DpcListEntry.Flink); ok_eq_pointer(Prcb->DpcData[DPC_NORMAL].DpcListHead.Blink, Dpc->DpcListEntry.Blink); }
static VOID TestEventFunctional( IN PKEVENT Event, IN EVENT_TYPE Type, IN KIRQL OriginalIrql) { LONG State; PKTHREAD Thread = KeGetCurrentThread(); memset(Event, 0x55, sizeof *Event); KeInitializeEvent(Event, Type, FALSE); CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, (PVOID *)NULL, 0); memset(Event, 0x55, sizeof *Event); KeInitializeEvent(Event, Type, TRUE); CheckEvent(Event, Type, 1L, FALSE, OriginalIrql, (PVOID *)NULL, 0); Event->Header.SignalState = 0x12345678L; CheckEvent(Event, Type, 0x12345678L, FALSE, OriginalIrql, (PVOID *)NULL, 0); State = KePulseEvent(Event, 0, FALSE); CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, (PVOID *)NULL, 0); ok_eq_long(State, 0x12345678L); Event->Header.SignalState = 0x12345678L; KeClearEvent(Event); CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, (PVOID *)NULL, 0); State = KeSetEvent(Event, 0, FALSE); CheckEvent(Event, Type, 1L, FALSE, OriginalIrql, (PVOID *)NULL, 0); ok_eq_long(State, 0L); State = KeResetEvent(Event); CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, (PVOID *)NULL, 0); ok_eq_long(State, 1L); Event->Header.SignalState = 0x23456789L; State = KeSetEvent(Event, 0, FALSE); CheckEvent(Event, Type, 1L, FALSE, OriginalIrql, (PVOID *)NULL, 0); ok_eq_long(State, 0x23456789L); Event->Header.SignalState = 0x3456789AL; State = KeResetEvent(Event); CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, (PVOID *)NULL, 0); ok_eq_long(State, 0x3456789AL); /* Irql is raised to DISPATCH_LEVEL here, which kills checked build, * a spinlock is acquired and never released, which kills MP build */ if ((OriginalIrql <= DISPATCH_LEVEL || !KmtIsCheckedBuild) && !KmtIsMultiProcessorBuild) { Event->Header.SignalState = 0x456789ABL; State = KeSetEvent(Event, 0, TRUE); CheckEvent(Event, Type, 1L, TRUE, DISPATCH_LEVEL, (PVOID *)NULL, 0); ok_eq_long(State, 0x456789ABL); ok_eq_uint(Thread->WaitIrql, OriginalIrql); /* repair the "damage" */ Thread->WaitNext = FALSE; KmtSetIrql(OriginalIrql); Event->Header.SignalState = 0x56789ABCL; State = KePulseEvent(Event, 0, TRUE); CheckEvent(Event, Type, 0L, TRUE, DISPATCH_LEVEL, (PVOID *)NULL, 0); ok_eq_long(State, 0x56789ABCL); ok_eq_uint(Thread->WaitIrql, OriginalIrql); /* repair the "damage" */ Thread->WaitNext = FALSE; KmtSetIrql(OriginalIrql); } ok_irql(OriginalIrql); KmtSetIrql(OriginalIrql); }
static VOID TestFastMutex( PFAST_MUTEX Mutex, KIRQL OriginalIrql) { PKTHREAD Thread = KeGetCurrentThread(); ok_irql(OriginalIrql); /* acquire/release normally */ ExAcquireFastMutex(Mutex); CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL); ok_bool_false(ExTryToAcquireFastMutex(Mutex), "ExTryToAcquireFastMutex returned"); CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL); ExReleaseFastMutex(Mutex); CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql); #ifdef _M_IX86 /* ntoskrnl's fastcall version */ ExiAcquireFastMutex(Mutex); CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL); ok_bool_false(ExiTryToAcquireFastMutex(Mutex), "ExiTryToAcquireFastMutex returned"); CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL); ExiReleaseFastMutex(Mutex); CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql); #endif /* try to acquire */ ok_bool_true(ExTryToAcquireFastMutex(Mutex), "ExTryToAcquireFastMutex returned"); CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL); ExReleaseFastMutex(Mutex); CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql); /* shortcut functions with critical region */ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(Mutex); ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(Mutex); /* acquire/release unsafe */ if (!KmtIsCheckedBuild || OriginalIrql == APC_LEVEL) { ExAcquireFastMutexUnsafe(Mutex); CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, OriginalIrql); ExReleaseFastMutexUnsafe(Mutex); CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql); /* mismatched acquire/release */ ExAcquireFastMutex(Mutex); CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL); ExReleaseFastMutexUnsafe(Mutex); CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, APC_LEVEL); KmtSetIrql(OriginalIrql); CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql); Mutex->OldIrql = 0x55555555LU; ExAcquireFastMutexUnsafe(Mutex); CheckMutex(Mutex, 0L, Thread, 0LU, 0x55555555LU, OriginalIrql); Mutex->OldIrql = PASSIVE_LEVEL; ExReleaseFastMutex(Mutex); CheckMutex(Mutex, 1L, NULL, 0LU, PASSIVE_LEVEL, PASSIVE_LEVEL); KmtSetIrql(OriginalIrql); CheckMutex(Mutex, 1L, NULL, 0LU, PASSIVE_LEVEL, OriginalIrql); } if (!KmtIsCheckedBuild) { /* release without acquire */ ExReleaseFastMutexUnsafe(Mutex); CheckMutex(Mutex, 2L, NULL, 0LU, PASSIVE_LEVEL, OriginalIrql); --Mutex->Count; Mutex->OldIrql = OriginalIrql; ExReleaseFastMutex(Mutex); CheckMutex(Mutex, 2L, NULL, 0LU, OriginalIrql, OriginalIrql); ExReleaseFastMutex(Mutex); CheckMutex(Mutex, 3L, NULL, 0LU, OriginalIrql, OriginalIrql); Mutex->Count -= 2; } /* make sure we survive this in case of error */ ok_eq_long(Mutex->Count, 1L); Mutex->Count = 1; ok_irql(OriginalIrql); KmtSetIrql(OriginalIrql); }