void rnd_reseed_now() { seed_data seed; KeQuerySystemTime(&seed.seed20); seed.seed1 = PsGetCurrentProcess(); seed.seed2 = PsGetCurrentProcessId(); seed.seed3 = KeGetCurrentThread(); seed.seed4 = PsGetCurrentThreadId(); seed.seed5 = KeGetCurrentProcessorNumber(); seed.seed6 = KeQueryInterruptTime(); seed.seed10 = KeQueryPerformanceCounter(NULL); seed.seed11 = __rdtsc(); seed.seed12 = ExGetPreviousMode(); seed.seed14 = IoGetTopLevelIrp(); seed.seed15 = MmQuerySystemSize(); seed.seed24 = KeGetCurrentIrql(); if (KeGetCurrentIrql() == PASSIVE_LEVEL) { seed.seed7 = KeQueryPriorityThread(seed.seed3); seed.seed17 = ExUuidCreate(&seed.seed18); seed.seed19 = RtlRandom(&seed.seed8); } if (KeGetCurrentIrql() <= APC_LEVEL) { seed.seed13 = IoGetInitialStack(); seed.seed16 = PsGetProcessExitTime(); IoGetStackLimits(&seed.seed22, &seed.seed23); } KeQueryTickCount(&seed.seed21); rnd_add_buff(&seed, sizeof(seed)); /* Prevent leaks */ zeroauto(&seed, sizeof(seed)); }
static VOID TestEventConcurrent( IN PKEVENT Event, IN EVENT_TYPE Type, IN KIRQL OriginalIrql, PSET_EVENT_FUNCTION SetEvent, KPRIORITY PriorityIncrement, LONG ExpectedState, BOOLEAN SatisfiesAll) { NTSTATUS Status; THREAD_DATA Threads[5]; const INT ThreadCount = sizeof Threads / sizeof Threads[0]; KPRIORITY Priority; LARGE_INTEGER LongTimeout, ShortTimeout; INT i; KWAIT_BLOCK WaitBlock[MAXIMUM_WAIT_OBJECTS]; PVOID ThreadObjects[MAXIMUM_WAIT_OBJECTS]; LONG State; PKTHREAD Thread = KeGetCurrentThread(); LongTimeout.QuadPart = -100 * MILLISECOND; ShortTimeout.QuadPart = -1 * MILLISECOND; KeInitializeEvent(Event, Type, FALSE); for (i = 0; i < ThreadCount; ++i) { Threads[i].Event = Event; Threads[i].Signal = FALSE; Status = PsCreateSystemThread(&Threads[i].Handle, GENERIC_ALL, NULL, NULL, NULL, WaitForEventThread, &Threads[i]); ok_eq_hex(Status, STATUS_SUCCESS); Status = ObReferenceObjectByHandle(Threads[i].Handle, SYNCHRONIZE, PsThreadType, KernelMode, (PVOID *)&Threads[i].Thread, NULL); ok_eq_hex(Status, STATUS_SUCCESS); ThreadObjects[i] = Threads[i].Thread; Priority = KeQueryPriorityThread(Threads[i].Thread); ok_eq_long(Priority, 8L); while (!Threads[i].Signal) { Status = KeDelayExecutionThread(KernelMode, FALSE, &ShortTimeout); ok_eq_hex(Status, STATUS_SUCCESS); } CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, ThreadObjects, i + 1); } /* the threads shouldn't wake up on their own */ Status = KeDelayExecutionThread(KernelMode, FALSE, &ShortTimeout); ok_eq_hex(Status, STATUS_SUCCESS); for (i = 0; i < ThreadCount; ++i) { CheckEvent(Event, Type, 0L, FALSE, OriginalIrql, ThreadObjects + i, ThreadCount - i); State = SetEvent(Event, PriorityIncrement + i, FALSE); ok_eq_long(State, 0L); CheckEvent(Event, Type, ExpectedState, FALSE, OriginalIrql, ThreadObjects + i + 1, SatisfiesAll ? 0 : ThreadCount - i - 1); Status = KeWaitForMultipleObjects(ThreadCount, ThreadObjects, SatisfiesAll ? WaitAll : WaitAny, Executive, KernelMode, FALSE, &LongTimeout, WaitBlock); ok_eq_hex(Status, STATUS_WAIT_0 + i); if (SatisfiesAll) { for (; i < ThreadCount; ++i) { Priority = KeQueryPriorityThread(Threads[i].Thread); ok_eq_long(Priority, max(min(8L + PriorityIncrement, 15L), 8L)); } break; } Priority = KeQueryPriorityThread(Threads[i].Thread); ok_eq_long(Priority, max(min(8L + PriorityIncrement + i, 15L), 8L)); /* replace the thread with the current thread - which will never signal */ if (!skip((Status & 0x3F) < ThreadCount, "Index out of bounds")) ThreadObjects[Status & 0x3F] = Thread; Status = KeWaitForMultipleObjects(ThreadCount, ThreadObjects, WaitAny, Executive, KernelMode, FALSE, &ShortTimeout, WaitBlock); ok_eq_hex(Status, STATUS_TIMEOUT); } for (i = 0; i < ThreadCount; ++i) { ObDereferenceObject(Threads[i].Thread); Status = ZwClose(Threads[i].Handle); ok_eq_hex(Status, STATUS_SUCCESS); } }