Exemplo n.º 1
0
static
VOID
TestResourceExclusiveAccess(
    IN PERESOURCE Res)
{
    LONG Count = 0;

    KeEnterCriticalRegion();
    ok_bool_true(ExAcquireResourceExclusiveLite(Res, FALSE), "ExAcquireResourceExclusiveLite returned"); ++Count;

    CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU);

    ok_bool_true(ExAcquireResourceExclusiveLite(Res, TRUE), "ExAcquireResourceExclusiveLite returned"); ++Count;
    CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU);

    ok_bool_true(ExAcquireResourceSharedLite(Res, FALSE), "ExAcquireResourceSharedLite returned"); ++Count;
    ok_bool_true(ExAcquireResourceSharedLite(Res, TRUE), "ExAcquireResourceSharedLite returned"); ++Count;
    ok_bool_true(ExAcquireSharedStarveExclusive(Res, FALSE), "ExAcquireSharedStarveExclusive returned"); ++Count;
    ok_bool_true(ExAcquireSharedStarveExclusive(Res, TRUE), "ExAcquireSharedStarveExclusive returned"); ++Count;
    ok_bool_true(ExAcquireSharedWaitForExclusive(Res, FALSE), "ExAcquireSharedWaitForExclusive returned"); ++Count;
    ok_bool_true(ExAcquireSharedWaitForExclusive(Res, TRUE), "ExAcquireSharedWaitForExclusive returned"); ++Count;
    CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU);

    ExConvertExclusiveToSharedLite(Res);
    CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);

    while (Count--)
        ExReleaseResourceLite(Res);
    KeLeaveCriticalRegion();
}
Exemplo n.º 2
0
static
VOID
NTAPI
AcquireResourceThread(
    PVOID Context)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PTHREAD_DATA ThreadData = Context;
    BOOLEAN Ret;

    KeEnterCriticalRegion();
    Ret = ThreadData->AcquireResource(ThreadData->Res, ThreadData->Wait);
    if (ThreadData->RetExpected)
        ok_bool_true(Ret, "AcquireResource returned");
    else
        ok_bool_false(Ret, "AcquireResource returned");

    ok_bool_false(KeSetEvent(&ThreadData->OutEvent, 0, TRUE), "KeSetEvent returned");
    Status = KeWaitForSingleObject(&ThreadData->InEvent, Executive, KernelMode, FALSE, NULL);
    ok_eq_hex(Status, STATUS_SUCCESS);

    if (Ret)
        ExReleaseResource(ThreadData->Res);
    KeLeaveCriticalRegion();
}
Exemplo n.º 3
0
static
VOID
TestResourceSharedAccess(
    IN PERESOURCE Res)
{
    LONG Count = 0;

    KeEnterCriticalRegion();
    ok_bool_true(ExAcquireResourceSharedLite(Res, FALSE), "ExAcquireResourceSharedLite returned"); ++Count;
    CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);

    ok_bool_true(ExAcquireResourceSharedLite(Res, FALSE), "ExAcquireResourceSharedLite returned"); ++Count;
    ok_bool_true(ExAcquireResourceSharedLite(Res, TRUE), "ExAcquireResourceSharedLite returned"); ++Count;
    ok_bool_true(ExAcquireSharedStarveExclusive(Res, FALSE), "ExAcquireSharedStarveExclusive returned"); ++Count;
    ok_bool_true(ExAcquireSharedStarveExclusive(Res, TRUE), "ExAcquireSharedStarveExclusive returned"); ++Count;
    ok_bool_true(ExAcquireSharedWaitForExclusive(Res, FALSE), "ExAcquireSharedWaitForExclusive returned"); ++Count;
    ok_bool_true(ExAcquireSharedWaitForExclusive(Res, TRUE), "ExAcquireSharedWaitForExclusive returned"); ++Count;
    CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);

    /* this one fails, TRUE would deadlock */
    ok_bool_false(ExAcquireResourceExclusiveLite(Res, FALSE), "ExAcquireResourceExclusiveLite returned");
    CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);

    /* this asserts */
    if (!KmtIsCheckedBuild)
        ExConvertExclusiveToSharedLite(Res);
    CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU);

    while (Count--)
        ExReleaseResourceLite(Res);
    KeLeaveCriticalRegion();
}
Exemplo n.º 4
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);
}
Exemplo n.º 5
0
static
NTSTATUS
TestIrpHandler(
    _In_ PDEVICE_OBJECT DeviceObject,
    _In_ PIRP Irp,
    _In_ PIO_STACK_LOCATION IoStack)
{
    NTSTATUS Status;
    PTEST_FCB Fcb;
    CACHE_UNINITIALIZE_EVENT CacheUninitEvent;

    PAGED_CODE();

    DPRINT("IRP %x/%x\n", IoStack->MajorFunction, IoStack->MinorFunction);
    ASSERT(IoStack->MajorFunction == IRP_MJ_CLEANUP ||
           IoStack->MajorFunction == IRP_MJ_CREATE ||
           IoStack->MajorFunction == IRP_MJ_READ);

    Status = STATUS_NOT_SUPPORTED;
    Irp->IoStatus.Information = 0;

    if (IoStack->MajorFunction == IRP_MJ_CREATE)
    {
        if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR))
        {
            TestDeviceObject = DeviceObject;
            TestFileObject = IoStack->FileObject;
        }
        Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Fcb), 'FwrI');
        RtlZeroMemory(Fcb, sizeof(*Fcb));
        ExInitializeFastMutex(&Fcb->HeaderMutex);
        FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex);
        if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
            IoStack->FileObject->FileName.Buffer[1] == 'B')
        {
            Fcb->Header.AllocationSize.QuadPart = 1000000;
            Fcb->Header.FileSize.QuadPart = 1000000;
            Fcb->Header.ValidDataLength.QuadPart = 1000000;
        }
        else if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
                 IoStack->FileObject->FileName.Buffer[1] == 'S')
        {
            Fcb->Header.AllocationSize.QuadPart = 3000;
            Fcb->Header.FileSize.QuadPart = 3000;
            Fcb->Header.ValidDataLength.QuadPart = 3000;
        }
        else
        {
            Fcb->Header.AllocationSize.QuadPart = 512;
            Fcb->Header.FileSize.QuadPart = 512;
            Fcb->Header.ValidDataLength.QuadPart = 512;
        }
        Fcb->Header.IsFastIoPossible = FALSE;
        IoStack->FileObject->FsContext = Fcb;
        IoStack->FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;

        CcInitializeCacheMap(IoStack->FileObject, 
                             (PCC_FILE_SIZES)&Fcb->Header.AllocationSize,
                             FALSE, &Callbacks, NULL);

        Irp->IoStatus.Information = FILE_OPENED;
        Status = STATUS_SUCCESS;
    }
    else if (IoStack->MajorFunction == IRP_MJ_READ)
    {
        BOOLEAN Ret;
        ULONG Length;
        PVOID Buffer;
        LARGE_INTEGER Offset;

        Offset = IoStack->Parameters.Read.ByteOffset;
        Length = IoStack->Parameters.Read.Length;
        Fcb = IoStack->FileObject->FsContext;

        ok_eq_pointer(DeviceObject, TestDeviceObject);
        ok_eq_pointer(IoStack->FileObject, TestFileObject);

        if (!FlagOn(Irp->Flags, IRP_NOCACHE))
        {
            ok(Offset.QuadPart % 512 != 0, "Offset is aligned: %I64i\n", Offset.QuadPart);
            ok(Length % 512 != 0, "Length is aligned: %I64i\n", Length);

            Buffer = MapUserBuffer(Irp);
            ok(Buffer != NULL, "Null pointer!\n");

            _SEH2_TRY
            {
                Ret = CcCopyRead(IoStack->FileObject, &Offset, Length, TRUE, Buffer,
                                 &Irp->IoStatus);
                ok_bool_true(Ret, "CcCopyRead");
            }
            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
            {
                Irp->IoStatus.Status = _SEH2_GetExceptionCode();
            }
            _SEH2_END;

            Status = Irp->IoStatus.Status;
        }
Exemplo n.º 6
0
static
VOID
TestConnect(
    IN HANDLE ServerHandle,
    IN PCWSTR PipePath)
{
    NTSTATUS Status;
    THREAD_CONTEXT ConnectContext;
    THREAD_CONTEXT ListenContext;
    BOOLEAN Okay;
    HANDLE ClientHandle;

    StartWorkerThread(&ConnectContext);
    StartWorkerThread(&ListenContext);

    /* Server should start out listening */
    CheckServer(ServerHandle, FILE_PIPE_LISTENING_STATE);

    /* Connect a client */
    ClientHandle = NULL;
    Okay = CheckConnectPipe(&ConnectContext, PipePath, 100);
    ok_bool_true(Okay, "CheckConnectPipe returned");
    ok_eq_hex(ConnectContext.Connect.Status, STATUS_SUCCESS);
    if (NT_SUCCESS(ConnectContext.Connect.Status))
    {
        ClientHandle = ConnectContext.Connect.ClientHandle;
        CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE);
    }
    CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);

    /* Connect another client */
    Okay = CheckConnectPipe(&ConnectContext, PipePath, 100);
    ok_bool_true(Okay, "CheckConnectPipe returned");
    ok_eq_hex(ConnectContext.Connect.Status, STATUS_PIPE_NOT_AVAILABLE);
    if (NT_SUCCESS(ConnectContext.Connect.Status))
        ObCloseHandle(ConnectContext.Connect.ClientHandle, KernelMode);
    CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE);
    CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);

    /* Disconnecting the client should fail */
    Status = NpDisconnectPipe(ClientHandle);
    ok_eq_hex(Status, STATUS_ILLEGAL_FUNCTION);
    CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE);
    CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);

    /* Listening on the client should fail */
    Status = NpListenPipe(ClientHandle);
    ok_eq_hex(Status, STATUS_ILLEGAL_FUNCTION);
    CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE);
    CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);

    /* Close client */
    if (ClientHandle)
        ObCloseHandle(ClientHandle, KernelMode);
    CheckServer(ServerHandle, FILE_PIPE_CLOSING_STATE);

    /* Connecting a client now should fail */
    Okay = CheckConnectPipe(&ConnectContext, PipePath, 100);
    ok_bool_true(Okay, "CheckConnectPipe returned");
    ok_eq_hex(ConnectContext.Connect.Status, STATUS_PIPE_NOT_AVAILABLE);
    if (NT_SUCCESS(ConnectContext.Connect.Status))
        ObCloseHandle(ConnectContext.Connect.ClientHandle, KernelMode);
    CheckServer(ServerHandle, FILE_PIPE_CLOSING_STATE);

    /* Listening should fail */
    Okay = CheckListenPipe(&ListenContext, ServerHandle, 100);
    ok_bool_true(Okay, "CheckListenPipe returned");
    if (!skip(Okay, "Listen succeeded unexpectedly\n"))
        CheckServer(ServerHandle, FILE_PIPE_CLOSING_STATE);

    /* Disconnect server */
    Status = NpDisconnectPipe(ServerHandle);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckServer(ServerHandle, FILE_PIPE_DISCONNECTED_STATE);

    /* Disconnecting again should fail */
    Status = NpDisconnectPipe(ServerHandle);
    ok_eq_hex(Status, STATUS_PIPE_DISCONNECTED);
    CheckServer(ServerHandle, FILE_PIPE_DISCONNECTED_STATE);

    /* Connecting a client now should fail */
    Okay = CheckConnectPipe(&ConnectContext, PipePath, 100);
    ok_bool_true(Okay, "CheckConnectPipe returned");
    ok_eq_hex(ConnectContext.Connect.Status, STATUS_PIPE_NOT_AVAILABLE);
    if (NT_SUCCESS(ConnectContext.Connect.Status))
        ObCloseHandle(ConnectContext.Connect.ClientHandle, KernelMode);
    CheckServer(ServerHandle, FILE_PIPE_DISCONNECTED_STATE);

    /**************************************************************************/
    /* Now listen again */
    Okay = CheckListenPipe(&ListenContext, ServerHandle, 100);
    ok_bool_false(Okay, "CheckListenPipe returned");
    //blocks: CheckServer(ServerHandle, FILE_PIPE_LISTENING_STATE);

    /* Connect client */
    ClientHandle = NULL;
    Okay = CheckConnectPipe(&ConnectContext, PipePath, 100);
    ok_bool_true(Okay, "CheckConnectPipe returned");
    ok_eq_hex(ConnectContext.Connect.Status, STATUS_SUCCESS);
    if (NT_SUCCESS(ConnectContext.Connect.Status))
    {
        ClientHandle = ConnectContext.Connect.ClientHandle;
        CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE);
    }
    Okay = WaitForWork(&ListenContext, 100);
    ok_bool_true(Okay, "WaitForWork returned");
    ok_eq_hex(ListenContext.Listen.Status, STATUS_SUCCESS);
    CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);

    /* Listening again should fail */
    Okay = CheckListenPipe(&ListenContext, ServerHandle, 100);
    ok_bool_true(Okay, "CheckListenPipe returned");
    ok_eq_hex(ListenContext.Listen.Status, STATUS_PIPE_CONNECTED);
    CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE);
    CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);

    /* Disconnect server */
    Status = NpDisconnectPipe(ServerHandle);
    ok_eq_hex(Status, STATUS_SUCCESS);
    NpQueryPipe(ClientHandle, STATUS_PIPE_DISCONNECTED);
    CheckServer(ServerHandle, FILE_PIPE_DISCONNECTED_STATE);

    /* Close client */
    if (ClientHandle)
        ObCloseHandle(ClientHandle, KernelMode);
    CheckServer(ServerHandle, FILE_PIPE_DISCONNECTED_STATE);

    /**************************************************************************/
    /* Listen once more */
    Okay = CheckListenPipe(&ListenContext, ServerHandle, 100);
    ok_bool_false(Okay, "CheckListenPipe returned");
    //blocks: CheckServer(ServerHandle, FILE_PIPE_LISTENING_STATE);

    /* Connect client */
    ClientHandle = NULL;
    Okay = CheckConnectPipe(&ConnectContext, PipePath, 100);
    ok_bool_true(Okay, "CheckConnectPipe returned");
    ok_eq_hex(ConnectContext.Connect.Status, STATUS_SUCCESS);
    if (NT_SUCCESS(ConnectContext.Connect.Status))
    {
        ClientHandle = ConnectContext.Connect.ClientHandle;
        CheckClient(ClientHandle, FILE_PIPE_CONNECTED_STATE);
    }
    Okay = WaitForWork(&ListenContext, 100);
    ok_bool_true(Okay, "WaitForWork returned");
    ok_eq_hex(ListenContext.Listen.Status, STATUS_SUCCESS);
    CheckServer(ServerHandle, FILE_PIPE_CONNECTED_STATE);

    /* Close server */
    Status = ObCloseHandle(ServerHandle, KernelMode);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckClient(ClientHandle, FILE_PIPE_CLOSING_STATE);

    /* Close client */
    if (ClientHandle)
        ObCloseHandle(ClientHandle, KernelMode);

    FinishWorkerThread(&ListenContext);
    FinishWorkerThread(&ConnectContext);
}
Exemplo n.º 7
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);
}