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(); }
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(); }
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); }
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)); }
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); }
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); }
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); }