Exemple #1
0
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);
}
Exemple #2
0
/**
 * @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;
}
Exemple #3
0
/**
 * @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;
}
Exemple #5
0
/**
 * @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");
}
Exemple #6
0
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);
}
Exemple #7
0
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);
}
Exemple #8
0
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);
}
Exemple #9
0
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);
}