Esempio n. 1
0
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;
}
Esempio n. 2
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);
}
Esempio n. 3
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);
}
Esempio n. 4
0
static
VOID
TestQueryLink(
    _In_ HANDLE LinkHandle,
    _In_ PCUNICODE_STRING ExpectedTarget)
{
    NTSTATUS Status;
    WCHAR QueriedTargetBuffer[32];
    UNICODE_STRING QueriedTarget;
    ULONG ResultLength;
    PULONG pResultLength;
    ULONG i;

    for (i = 0; i < 2; i++)
    {
        if (i == 0)
        {
            pResultLength = &ResultLength;
        }
        else
        {
            pResultLength = NULL;
        }

        /* Query with NULL Buffer just gives us the length */
        RtlInitEmptyUnicodeString(&QueriedTarget, NULL, 0);
        if (pResultLength) ResultLength = 0x55555555;
        Status = ZwQuerySymbolicLinkObject(LinkHandle,
                                           &QueriedTarget,
                                           pResultLength);
        ok_eq_hex(Status, STATUS_BUFFER_TOO_SMALL);
        ok_eq_uint(QueriedTarget.Length, 0);
        ok_eq_uint(QueriedTarget.MaximumLength, 0);
        ok_eq_pointer(QueriedTarget.Buffer, NULL);
        if (pResultLength) ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength);

        /* Query with Length-1 buffer */
        RtlInitEmptyUnicodeString(&QueriedTarget,
                                  QueriedTargetBuffer,
                                  ExpectedTarget->Length - 1);
        RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55);
        if (pResultLength) ResultLength = 0x55555555;
        Status = ZwQuerySymbolicLinkObject(LinkHandle,
                                           &QueriedTarget,
                                           pResultLength);
        ok_eq_hex(Status, STATUS_BUFFER_TOO_SMALL);
        ok_eq_uint(QueriedTarget.Length, 0);
        ok_eq_uint(QueriedTarget.MaximumLength, ExpectedTarget->Length - 1);
        ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer);
        ok_eq_uint(QueriedTarget.Buffer[0], 0x5555);
        if (pResultLength) ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength);

        /* Query with Length buffer */
        RtlInitEmptyUnicodeString(&QueriedTarget,
                                  QueriedTargetBuffer,
                                  ExpectedTarget->Length);
        RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55);
        if (pResultLength) ResultLength = 0x55555555;
        Status = ZwQuerySymbolicLinkObject(LinkHandle,
                                           &QueriedTarget,
                                           pResultLength);
        ok_eq_uint(QueriedTarget.MaximumLength, ExpectedTarget->Length);
        ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer);
        if (pResultLength &&
            QueriedTarget.MaximumLength < ExpectedTarget->MaximumLength)
        {
            ok_eq_hex(Status, STATUS_BUFFER_TOO_SMALL);
            ok_eq_uint(QueriedTarget.Length, 0);
            ok_eq_uint(QueriedTarget.Buffer[0], 0x5555);
            if (pResultLength) ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength);
        }
        else
        {
            ok_eq_hex(Status, STATUS_SUCCESS);
            ok_eq_uint(QueriedTarget.Length, ExpectedTarget->Length);
            ok(RtlEqualUnicodeString(&QueriedTarget, ExpectedTarget, FALSE), "%wZ != %wZ\n", &QueriedTarget, ExpectedTarget);
            ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0x5555);
        }

        /* Query with Length+1 buffer */
        RtlInitEmptyUnicodeString(&QueriedTarget,
                                  QueriedTargetBuffer,
                                  ExpectedTarget->Length + 1);
        RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55);
        if (pResultLength) ResultLength = 0x55555555;
        Status = ZwQuerySymbolicLinkObject(LinkHandle,
                                           &QueriedTarget,
                                           pResultLength);
        ok_eq_uint(QueriedTarget.MaximumLength, ExpectedTarget->Length + 1);
        ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer);
        if (pResultLength &&
            QueriedTarget.MaximumLength < ExpectedTarget->MaximumLength)
        {
            ok_eq_hex(Status, STATUS_BUFFER_TOO_SMALL);
            ok_eq_uint(QueriedTarget.Length, 0);
            ok_eq_uint(QueriedTarget.Buffer[0], 0x5555);
            if (pResultLength) ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength);
        }
        else
        {
            ok_eq_hex(Status, STATUS_SUCCESS);
            ok_eq_uint(QueriedTarget.Length, ExpectedTarget->Length);
            ok(RtlEqualUnicodeString(&QueriedTarget, ExpectedTarget, FALSE), "%wZ != %wZ\n", &QueriedTarget, ExpectedTarget);
            ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0x5555);
        }

        /* Query with Length+2 buffer */
        RtlInitEmptyUnicodeString(&QueriedTarget,
                                  QueriedTargetBuffer,
                                  ExpectedTarget->Length + sizeof(WCHAR));
        RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55);
        if (pResultLength) ResultLength = 0x55555555;
        Status = ZwQuerySymbolicLinkObject(LinkHandle,
                                           &QueriedTarget,
                                           pResultLength);
        ok_eq_hex(Status, STATUS_SUCCESS);
        ok_eq_uint(QueriedTarget.Length, ExpectedTarget->Length);
        ok_eq_uint(QueriedTarget.MaximumLength, ExpectedTarget->Length + sizeof(WCHAR));
        ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer);
        ok(RtlEqualUnicodeString(&QueriedTarget, ExpectedTarget, FALSE), "%wZ != %wZ\n", &QueriedTarget, ExpectedTarget);
        if (pResultLength)
        {
            if (ExpectedTarget->MaximumLength >= ExpectedTarget->Length + sizeof(UNICODE_NULL))
                ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0);
            ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength);
        }
        else
        {
            ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0x5555);
        }

        /* Query with full-sized buffer */
        RtlInitEmptyUnicodeString(&QueriedTarget,
                                  QueriedTargetBuffer,
                                  sizeof(QueriedTargetBuffer));
        RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55);
        if (pResultLength) ResultLength = 0x55555555;
        Status = ZwQuerySymbolicLinkObject(LinkHandle,
                                           &QueriedTarget,
                                           pResultLength);
        ok_eq_hex(Status, STATUS_SUCCESS);
        ok_eq_uint(QueriedTarget.Length, ExpectedTarget->Length);
        ok_eq_uint(QueriedTarget.MaximumLength, sizeof(QueriedTargetBuffer));
        ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer);
        ok(RtlEqualUnicodeString(&QueriedTarget, ExpectedTarget, FALSE), "%wZ != %wZ\n", &QueriedTarget, ExpectedTarget);
        if (pResultLength)
        {
            if (ExpectedTarget->MaximumLength >= ExpectedTarget->Length + sizeof(UNICODE_NULL))
                ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0);
            ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength);
        }
        else
        {
            ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0x5555);
        }
    }
}
Esempio n. 5
0
static
VOID
TestDriverObject(
    IN PDRIVER_OBJECT DriverObject,
    IN PCUNICODE_STRING RegistryPath OPTIONAL,
    IN DRIVER_STATUS DriverStatus)
{
    BOOLEAN CheckThisDispatchRoutine;
    PVOID FirstMajorFunc;
    int i;
    UNICODE_STRING HardwareDatabase = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM");
    UNICODE_STRING RegPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet001\\Services\\Kmtest-IoDeviceObject");
    UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"\\Driver\\Kmtest-IoDeviceObject");
    UNICODE_STRING ServiceKeyName = RTL_CONSTANT_STRING(L"Kmtest-IoDeviceObject");
    BOOLEAN Equal;

    ok(DriverObject->Size == sizeof(DRIVER_OBJECT), "Size does not match, got %x\n",DriverObject->Size);
    ok(DriverObject->Type == 4, "Type does not match 4. got %d\n", DriverObject->Type);

    if (DriverStatus == DriverStatusEntry)
    {
        ok(DriverObject->DeviceObject == NULL, "Expected DeviceObject pointer to be 0, got %p\n",
            DriverObject->DeviceObject);
        ok (DriverObject->Flags == DRVO_LEGACY_DRIVER,
            "Expected Flags to be DRVO_LEGACY_DRIVER, got %lu\n",
            DriverObject->Flags);

        ok(DriverObject->DriverStart < (PVOID)TestEntry,
           "DriverStart is %p, expected < %p\n",
           DriverObject->DriverStart, (PVOID)TestEntry);
        ok(DriverObject->DriverSize > 0x2000,
           "DriverSize 0x%lx\n", DriverObject->DriverSize);
        ok_eq_pointer(DriverObject->DriverExtension, (PDRIVER_EXTENSION)(DriverObject + 1));
        ok_eq_pointer(DriverObject->DriverExtension->DriverObject, DriverObject);
        ok_eq_pointer(DriverObject->DriverExtension->AddDevice, NULL);
        ok_eq_ulong(DriverObject->DriverExtension->Count, 0UL);
        Equal = RtlEqualUnicodeString(RegistryPath,
                                      &RegPath,
                                      FALSE);
        ok(Equal, "RegistryPath is '%wZ'\n", RegistryPath);
        ok((ULONG_PTR)RegistryPath % PAGE_SIZE == 0, "RegistryPath %p not page-aligned\n", RegistryPath);
        ok_eq_pointer(RegistryPath->Buffer, (PWCHAR)(RegistryPath + 1));
        ok_eq_uint(RegistryPath->MaximumLength, RegistryPath->Length);
        Equal = RtlEqualUnicodeString(&DriverObject->DriverExtension->ServiceKeyName,
                                      &ServiceKeyName,
                                      FALSE);
        ok(Equal, "ServiceKeyName is '%wZ'\n", &DriverObject->DriverExtension->ServiceKeyName);
        ok_eq_tag(KmtGetPoolTag(DriverObject->DriverExtension->ServiceKeyName.Buffer), '  oI');
        ok_eq_uint((KmtGetPoolType(DriverObject->DriverExtension->ServiceKeyName.Buffer) - 1) & BASE_POOL_TYPE_MASK, NonPagedPool);
        ok_eq_uint(DriverObject->DriverExtension->ServiceKeyName.MaximumLength, DriverObject->DriverExtension->ServiceKeyName.Length + sizeof(UNICODE_NULL));
        ok_eq_uint(DriverObject->DriverExtension->ServiceKeyName.Buffer[DriverObject->DriverExtension->ServiceKeyName.Length / sizeof(WCHAR)], UNICODE_NULL);
        Equal = RtlEqualUnicodeString(&DriverObject->DriverName,
                                      &DriverName,
                                      FALSE);
        ok(Equal, "DriverName is '%wZ'\n", &DriverObject->DriverName);
        ok_eq_tag(KmtGetPoolTag(DriverObject->DriverName.Buffer), '  oI');
        ok_eq_uint((KmtGetPoolType(DriverObject->DriverName.Buffer) - 1) & BASE_POOL_TYPE_MASK, PagedPool);
        ok_eq_uint(DriverObject->DriverName.MaximumLength, DriverObject->DriverName.Length);
        // TODO: show that both string and buffer are constants inside ntos
        Equal = RtlEqualUnicodeString(DriverObject->HardwareDatabase,
                                      &HardwareDatabase,
                                      FALSE);
        ok(Equal, "HardwareDatabase is '%wZ'\n", DriverObject->HardwareDatabase);
        ok_eq_uint(DriverObject->HardwareDatabase->MaximumLength, DriverObject->HardwareDatabase->Length + sizeof(UNICODE_NULL));
        ok_eq_uint(DriverObject->HardwareDatabase->Buffer[DriverObject->HardwareDatabase->Length / sizeof(WCHAR)], UNICODE_NULL);
        ok(DriverObject->DriverInit == DriverEntry,
           "DriverInit is %p, expected %p\n",
           (PVOID)DriverObject->DriverInit, (PVOID)DriverEntry);
    }
    else if (DriverStatus == DriverStatusIrp)
    {
        ok(DriverObject->DeviceObject != NULL, "Expected DeviceObject pointer to non null\n");
        ok (DriverObject->Flags == (DRVO_LEGACY_DRIVER | DRVO_INITIALIZED),
            "Expected Flags to be DRVO_LEGACY_DRIVER | DRVO_INITIALIZED, got %lu\n",
            DriverObject->Flags);
    }
    else if (DriverStatus == DriverStatusUnload)
    {
        ok(DriverObject->DeviceObject != NULL, "Expected DeviceObject pointer to non null\n");
        ok (DriverObject->Flags == (DRVO_LEGACY_DRIVER | DRVO_INITIALIZED | DRVO_UNLOAD_INVOKED),
            "Expected Flags to be DRVO_LEGACY_DRIVER | DRVO_INITIALIZED | DRVO_UNLOAD_INVOKED, got %lu\n",
            DriverObject->Flags);
    }
    else
        ASSERT(FALSE);

    /* Select a routine that was not changed */
    FirstMajorFunc = DriverObject->MajorFunction[1];
    ok(FirstMajorFunc != 0, "Expected MajorFunction[1] to be non NULL\n");

    if (!skip(FirstMajorFunc != NULL, "First major function not set!\n"))
    {
        for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
        {
            if (DriverStatus > 0) CheckThisDispatchRoutine = (i > 3) && (i != 14);
            else CheckThisDispatchRoutine = TRUE;

            if (CheckThisDispatchRoutine)
            {
                ok(DriverObject->MajorFunction[i] == FirstMajorFunc, "Expected MajorFunction[%d] to match %p\n",
                    i, FirstMajorFunc);
            }
        }
    }
}
Esempio n. 6
0
static
VOID
TestResourceWithThreads(
    IN PERESOURCE Res)
{
    NTSTATUS Status = STATUS_SUCCESS;
    THREAD_DATA ThreadDataShared;
    THREAD_DATA ThreadDataShared2;
    THREAD_DATA ThreadDataExclusive;
    THREAD_DATA ThreadDataSharedStarve;
    THREAD_DATA ThreadDataSharedWait;
    LARGE_INTEGER Timeout;
    Timeout.QuadPart = -10 * 1000 * 10; /* 10 ms */

    InitThreadData(&ThreadDataShared, Res, ExAcquireResourceSharedLite);
    InitThreadData(&ThreadDataShared2, Res, ExAcquireResourceSharedLite);
    InitThreadData(&ThreadDataExclusive, Res, ExAcquireResourceExclusiveLite);
    InitThreadData(&ThreadDataSharedStarve, Res, ExAcquireSharedStarveExclusive);
    InitThreadData(&ThreadDataSharedWait, Res, ExAcquireSharedWaitForExclusive);

    /* have a thread acquire the resource shared */
    Status = StartThread(&ThreadDataShared, NULL, FALSE, TRUE);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);

    /* a second thread should be able to acquire the resource shared */
    Status = StartThread(&ThreadDataShared2, NULL, FALSE, TRUE);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
    ok_eq_int(Res->ActiveCount, 2);
    FinishThread(&ThreadDataShared2);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);

    /* now have a thread that tries to acquire the resource exclusive -- it should fail */
    Status = StartThread(&ThreadDataExclusive, NULL, FALSE, FALSE);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);
    FinishThread(&ThreadDataExclusive);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);

    /* as above, but this time it should block */
    Status = StartThread(&ThreadDataExclusive, &Timeout, TRUE, TRUE);
    ok_eq_hex(Status, STATUS_TIMEOUT);
    CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);

    /* now try another shared one -- it should fail */
    Status = StartThread(&ThreadDataShared2, NULL, FALSE, FALSE);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);
    FinishThread(&ThreadDataShared2);

    /* same for ExAcquireSharedWaitForExclusive */
    Status = StartThread(&ThreadDataSharedWait, NULL, FALSE, FALSE);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);
    FinishThread(&ThreadDataSharedWait);

    /* ExAcquireSharedStarveExclusive must get access though! */
    Status = StartThread(&ThreadDataSharedStarve, NULL, TRUE, TRUE);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
    ok_eq_int(Res->ActiveCount, 2);
    FinishThread(&ThreadDataSharedStarve);
    CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);

    /* block another shared one */
    Status = StartThread(&ThreadDataShared2, &Timeout, TRUE, TRUE);
    ok_eq_hex(Status, STATUS_TIMEOUT);
    CheckResourceStatus(Res, FALSE, 0LU, 1LU, 1LU);
    ok_eq_int(Res->ActiveCount, 1);

    /* finish the very first one */
    FinishThread(&ThreadDataShared);

    /* now the blocked exclusive one should get the resource */
    Status = KeWaitForSingleObject(&ThreadDataExclusive.OutEvent, Executive, KernelMode, FALSE, NULL);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 1LU);
    ok_eq_int(Res->ActiveCount, 1);
    ok_eq_uint((Res->Flag & ResourceOwnedExclusive) != 0, 1);

    FinishThread(&ThreadDataExclusive);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);

    /* now the blocked shared one should resume */
    Status = KeWaitForSingleObject(&ThreadDataShared2.OutEvent, Executive, KernelMode, FALSE, NULL);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);
    FinishThread(&ThreadDataShared2);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
    ok_eq_int(Res->ActiveCount, 0);
}
Esempio n. 7
0
static
VOID
TestResourceUndocumentedShortcuts(
    IN PERESOURCE Res,
    IN BOOLEAN AreApcsDisabled)
{
    PVOID Ret;
    LONG Count = 0;

    ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
    ok_eq_uint(KeAreAllApcsDisabled(), AreApcsDisabled);

    /* ExEnterCriticalRegionAndAcquireResourceShared, ExEnterCriticalRegionAndAcquireSharedWaitForExclusive */
    Count = 0;
    Ret = ExEnterCriticalRegionAndAcquireResourceShared(Res); ++Count;
    ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread);
    ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
    ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
    CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);

    Ret = ExEnterCriticalRegionAndAcquireResourceShared(Res); ++Count;
    ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread);
    ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
    ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
    CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);

    ExEnterCriticalRegionAndAcquireSharedWaitForExclusive(Res); ++Count;
    ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread);
    ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
    ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
    CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);

    while (Count-- > 1)
    {
        ExReleaseResourceAndLeaveCriticalRegion(Res);
        ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
        ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
        CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
    }

    ExReleaseResourceAndLeaveCriticalRegion(Res);
    ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
    ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
    CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);

    /* ExEnterCriticalRegionAndAcquireResourceExclusive */
    Count = 0;
    ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
    ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
    Ret = ExEnterCriticalRegionAndAcquireResourceExclusive(Res); ++Count;
    ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread);
    ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
    ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
    CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU);

    Ret = ExEnterCriticalRegionAndAcquireResourceExclusive(Res); ++Count;
    ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread);
    ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
    ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
    CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU);

    ExReleaseResourceAndLeaveCriticalRegion(Res); --Count;
    ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
    ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled);
    CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU);

    ExReleaseResourceAndLeaveCriticalRegion(Res); --Count;
    ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
    ok_eq_uint(KeAreAllApcsDisabled(), AreApcsDisabled);
    CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);
}