Beispiel #1
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();
}
Beispiel #2
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();
}
Beispiel #3
0
static
VOID
NTAPI
AcquireMutexThread(
    PVOID Parameter)
{
    PTHREAD_DATA ThreadData = Parameter;
    KIRQL Irql;
    BOOLEAN Ret = FALSE;
    NTSTATUS Status;

    KeRaiseIrql(ThreadData->Irql, &Irql);

    if (ThreadData->Try)
    {
        Ret = ThreadData->TryAcquire(ThreadData->Mutex);
        ok_eq_bool(Ret, ThreadData->RetExpected);
    }
    else
        ThreadData->Acquire(ThreadData->Mutex);

    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 (!ThreadData->Try || Ret)
        ThreadData->Release(ThreadData->Mutex);

    KeLowerIrql(Irql);
}
Beispiel #4
0
static
VOID
TestVolumeInfo(
    IN HANDLE ServerHandle)
{
    NTSTATUS Status;
    IO_STATUS_BLOCK IoStatusBlock;
    FILE_FS_SIZE_INFORMATION FileFsSizeInfo;
    FILE_FS_DEVICE_INFORMATION FileFsDeviceInfo;
    FILE_FS_FULL_SIZE_INFORMATION FileFsFullSizeInfo;

    struct {
        FILE_FS_VOLUME_INFORMATION;
        WCHAR PartialName[10];
    } VolumeInfo;

    struct {
        FILE_FS_ATTRIBUTE_INFORMATION;
        WCHAR PartialName[6];
    } AttributeInfo;

    RtlFillMemory(&VolumeInfo, sizeof(VolumeInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &VolumeInfo,
                                          sizeof(VolumeInfo),
                                          FileFsVolumeInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_long(VolumeInfo.VolumeCreationTime.LowPart, 0);
    ok_eq_long(VolumeInfo.VolumeCreationTime.HighPart, 0);
    ok_eq_ulong(VolumeInfo.VolumeSerialNumber, 0);
    ok_bool_false(VolumeInfo.SupportsObjects, "VolumeInfo.SupportsObjects");
    ok_eq_ulong(VolumeInfo.VolumeLabelLength, 18);
    ok_eq_size(RtlCompareMemory(VolumeInfo.VolumeLabel, L"NamedPipe", 18), 18);
    ok_eq_wchar(VolumeInfo.VolumeLabel[9], 0xFFFF);
    ok_eq_ulong(IoStatusBlock.Information, (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel) + 9 * sizeof(WCHAR)));

    RtlFillMemory(&VolumeInfo, sizeof(VolumeInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &VolumeInfo,
                                          sizeof(FILE_FS_VOLUME_INFORMATION) + 2 * sizeof(WCHAR),
                                          FileFsVolumeInformation);
    ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW);
    ok_eq_hex(IoStatusBlock.Status, STATUS_BUFFER_OVERFLOW);
    ok_eq_long(VolumeInfo.VolumeCreationTime.LowPart, 0);
    ok_eq_long(VolumeInfo.VolumeCreationTime.HighPart, 0);
    ok_eq_ulong(VolumeInfo.VolumeSerialNumber, 0);
    ok_bool_false(VolumeInfo.SupportsObjects, "VolumeInfo.SupportsObjects");
    ok_eq_ulong(VolumeInfo.VolumeLabelLength, 18);
    ok_eq_size(RtlCompareMemory(VolumeInfo.VolumeLabel, L"NamedP", 10), 10);
    ok_eq_wchar(VolumeInfo.VolumeLabel[5], 0xFFFF);
    ok_eq_ulong(IoStatusBlock.Information, (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel) + 5 * sizeof(WCHAR)));

    RtlFillMemory(&FileFsSizeInfo, sizeof(FileFsSizeInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &FileFsSizeInfo,
                                          sizeof(FileFsSizeInfo),
                                          FileFsSizeInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_longlong(FileFsSizeInfo.TotalAllocationUnits.QuadPart, 0);
    ok_eq_longlong(FileFsSizeInfo.AvailableAllocationUnits.QuadPart, 0);
    ok_eq_ulong(FileFsSizeInfo.SectorsPerAllocationUnit, 1);
    ok_eq_ulong(FileFsSizeInfo.BytesPerSector, 1);
    ok_eq_ulong(IoStatusBlock.Information, sizeof(FileFsSizeInfo));

    RtlFillMemory(&FileFsSizeInfo, sizeof(FileFsSizeInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &FileFsSizeInfo,
                                          sizeof(FileFsSizeInfo) - 4,
                                          FileFsSizeInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_longlong(FileFsSizeInfo.TotalAllocationUnits.QuadPart, 0);
    ok_eq_longlong(FileFsSizeInfo.AvailableAllocationUnits.QuadPart, 0);
    ok_eq_ulong(FileFsSizeInfo.SectorsPerAllocationUnit, 1);
    ok_eq_ulong(FileFsSizeInfo.BytesPerSector, 1);
    ok_eq_ulong(IoStatusBlock.Information, sizeof(FileFsSizeInfo));

    RtlFillMemory(&FileFsDeviceInfo, sizeof(FileFsDeviceInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &FileFsDeviceInfo,
                                          sizeof(FileFsDeviceInfo),
                                          FileFsDeviceInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_ulong(FileFsDeviceInfo.Characteristics, 0);
    ok_eq_ulong(FileFsDeviceInfo.DeviceType, FILE_DEVICE_NAMED_PIPE);
    ok_eq_ulong(IoStatusBlock.Information, sizeof(FileFsDeviceInfo));

    RtlFillMemory(&FileFsDeviceInfo, sizeof(FileFsDeviceInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &FileFsDeviceInfo,
                                          sizeof(FileFsDeviceInfo) - 4,
                                          FileFsDeviceInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_ulong(FileFsDeviceInfo.Characteristics, 0);
    ok_eq_ulong(FileFsDeviceInfo.DeviceType, FILE_DEVICE_NAMED_PIPE);
    ok_eq_ulong(IoStatusBlock.Information, sizeof(FileFsDeviceInfo));

    RtlFillMemory(&AttributeInfo, sizeof(AttributeInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &AttributeInfo,
                                          sizeof(AttributeInfo),
                                          FileFsAttributeInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_ulong(AttributeInfo.FileSystemAttributes, FILE_CASE_PRESERVED_NAMES);
    ok_eq_long(AttributeInfo.MaximumComponentNameLength, 0xFFFFFFFF);
    ok_eq_ulong(AttributeInfo.FileSystemNameLength, 8);
    ok_eq_size(RtlCompareMemory(AttributeInfo.FileSystemName, L"NPFS", 8), 8);
    ok_eq_wchar(AttributeInfo.FileSystemName[4], 0xFFFF);
    ok_eq_ulong(IoStatusBlock.Information, 20);

    RtlFillMemory(&AttributeInfo, sizeof(AttributeInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &AttributeInfo,
                                          sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 2 * sizeof(WCHAR),
                                          FileFsAttributeInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_ulong(AttributeInfo.FileSystemAttributes, FILE_CASE_PRESERVED_NAMES);
    ok_eq_long(AttributeInfo.MaximumComponentNameLength, 0xFFFFFFFF);
    ok_eq_ulong(AttributeInfo.FileSystemNameLength, 8);
    ok_eq_size(RtlCompareMemory(AttributeInfo.FileSystemName, L"NPFS", 8), 8);
    ok_eq_wchar(AttributeInfo.FileSystemName[4], 0xFFFF);
    ok_eq_ulong(IoStatusBlock.Information, 20);

    RtlFillMemory(&FileFsFullSizeInfo, sizeof(FileFsFullSizeInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &FileFsFullSizeInfo,
                                          sizeof(FileFsFullSizeInfo),
                                          FileFsFullSizeInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_longlong(FileFsFullSizeInfo.TotalAllocationUnits.QuadPart, 0);
    ok_eq_longlong(FileFsFullSizeInfo.CallerAvailableAllocationUnits.QuadPart, 0);
    ok_eq_longlong(FileFsFullSizeInfo.ActualAvailableAllocationUnits.QuadPart, 0);
    ok_eq_ulong(FileFsFullSizeInfo.SectorsPerAllocationUnit, 0);
    ok_eq_ulong(FileFsFullSizeInfo.BytesPerSector, 0);
    ok_eq_ulong(IoStatusBlock.Information, sizeof(FileFsFullSizeInfo));

    RtlFillMemory(&FileFsFullSizeInfo, sizeof(FileFsFullSizeInfo), 0xFF);
    Status = ZwQueryVolumeInformationFile(ServerHandle,
                                          &IoStatusBlock,
                                          &FileFsFullSizeInfo,
                                          sizeof(FileFsFullSizeInfo) - 4,
                                          FileFsFullSizeInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    ok_eq_longlong(FileFsFullSizeInfo.TotalAllocationUnits.QuadPart, 0);
    ok_eq_longlong(FileFsFullSizeInfo.CallerAvailableAllocationUnits.QuadPart, 0);
    ok_eq_longlong(FileFsFullSizeInfo.ActualAvailableAllocationUnits.QuadPart, 0);
    ok_eq_ulong(FileFsFullSizeInfo.SectorsPerAllocationUnit, 0);
    ok_eq_ulong(FileFsFullSizeInfo.BytesPerSector, 0);
    ok_eq_ulong(IoStatusBlock.Information, sizeof(FileFsFullSizeInfo));
}
Beispiel #5
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);
}
Beispiel #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);
}
Beispiel #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);
}