线程与事件--windows内核安全与驱动开发

驱动中生成的线程一般是系统线程。线程所在的进程名就是"System",用到的内核API就是PsCreateSystemThread,
线程与事件--windows内核安全与驱动开发
需要注意的是倒数第二个参数,是线程的启动执行的函数,最后一个参数是启动执行的函数的参数,就是说线程启动执行的函数可以带一个参数。同时,线程不会自动消亡,所以最后还需要执行一个
PsTerminateSystemThread();来干掉自己。创建了线程最后结束还需要调用ZwClose来关闭句柄。

另外有一些需要注意的地方,结合以下例子。
void MyThreadPro(IN PVOID context) //线程函数
{
PUNICODE_STRING str=(PUNICODE_STRING)context;
//打印一下
KdPrint(("%x",context));
PsTerminateSystemThread(STATUS_SUCESS);
}

void MyFunction()
{
UNICODE_STRING st=RTL_CONSTANT_STRING(L"HELLO");
HANDLE thread=NULL;
NTSTATUS status;
status=PsCreateSystemThread(&thread,0,NULL,NULL,NULL,MyThreadPro,&st);

ZwClose(thread);
}
上面代码有个错误,就是线程在执行MyThreadPro的时候,MyFunction可能已经执行完毕了,这时候
st已经释放,那么传递的参数可能无效,执行打印的时候就会蓝屏。还是一个变量声明周期的问题。
这个问题解决可以在MyFunction执行完PsCreateSystemThread后就让他睡眠或者等待。
内核中可以用KeDelayExecutionThread:
线程与事件--windows内核安全与驱动开发
实例
线程与事件--windows内核安全与驱动开发
除此之外,还可以使用事件同步,这里,内核中的事件是一个数据结构。这个结构是KEVENT,
这个结构总是被KeInitlizeEvent初始化,
线程与事件--windows内核安全与驱动开发
第一个参数是,要初始化的事件
第二个参数是事件类型
第三个参数是初始化状态,一般FALSE,也就是未设置状态。
设置事件使用KeSetEvent
线程与事件--windows内核安全与驱动开发
wait设置为TRUE
表示是否后面要紧跟一个WaitForSingleObject来接受事件。
用到前面的代码,就是在PsCreateSystemThread之前初始化一个事件,在线程函数中,
打印函数之后调用设置事件函数,然后在ZwClose之后调用WaitForSingleObject接到事件结束。
这样可以保证线程执行函数在执行完打印函数之后,MyFunction才会结束。

其实和R3差不多。R3会这个很容易理解。