// Globals to communicate with our system thread
PVOID ThreadObjectPointer=NULL; // Thread pointer
BOOLEAN ExitNow; // Set to cause thread to exit
KEVENT ThreadEvent; // Set to make thread look at ExitNow.
KEVENT ThreadExiting; // Set when thread exiting
void SystemWorkThread( IN PVOID Context)
{
NTSTATUS status;
LARGE_INTEGER Timeout;
HANDLE threadHandle;
Timeout.QuadPart = -10000*1000; ;
// Lower thread priority
KeSetPriorityThread( KeGetCurrentThread(), LOW_REALTIME_PRIORITY);
while(TRUE)
{
// Wait for a request
KeWaitForSingleObject( &ThreadEvent, Executive, KernelMode, FALSE, &Timeout);
if( ExitNow)
break;
//Working
OutputDebugString(".");
}
KeSetEvent( &ThreadExiting, 0, FALSE);
PsTerminateSystemThread(STATUS_SUCCESS);
return;
}
BOOLEAN CreateSystemThread()
{
HANDLE threadHandle;
NTSTATUS status;
// Prepare for thread start
ExitNow = FALSE;
KeInitializeEvent(&ThreadEvent, SynchronizationEvent, FALSE);
KeInitializeEvent(&ThreadExiting, SynchronizationEvent, FALSE);
// Start system thread
status = PsCreateSystemThread( &threadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL,SystemWorkThread, NULL);
if( !NT_SUCCESS(status))
return FALSE;
// Save a pointer to thread and close handle.
status = ObReferenceObjectByHandle( threadHandle, THREAD_ALL_ACCESS, NULL, KernelMode,
&ThreadObjectPointer, NULL);
if( NT_SUCCESS(status))
{
ZwClose(threadHandle);
}
else
{
// Uh oh... force thread to exit
ExitNow = TRUE;
KeSetEvent( &ThreadEvent, 0, FALSE);
return FALSE;
}
return TRUE;
}
void CloseSystemThread()
{
// Tell thread to stop, and wait for it to stop
ExitNow = TRUE;
KeSetEvent( &ThreadEvent, 0, FALSE);
KeWaitForSingleObject( &ThreadExiting, Executive, KernelMode, FALSE, NULL);
// Dereference thread object
if( ThreadObjectPointer!=NULL)
{
ObDereferenceObject(&ThreadObjectPointer);
ThreadObjectPointer = NULL;
}
}