驱动开发之 创建线程函数PsCreateSystemThread
PsCreateSystemThread 创建一个执行在内核模式的系统线程。
注意:创建线程必须用函数PsTerminateSystemThread强制线程结束。否则该线程是无法自动退出的。
函数原型:
- NTSTATUS PsCreateSystemThread(
- _Out_ PHANDLE ThreadHandle,
- _In_ ULONG DesiredAccess,
- _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
- _In_opt_ HANDLE ProcessHandle,
- _Out_opt_ PCLIENT_ID ClientId,
- _In_ PKSTART_ROUTINE StartRoutine,
- _In_opt_ PVOID StartContext
- );
- NTSTATUS PsCreateSystemThread(
- _Out_ PHANDLE ThreadHandle,
- _In_ ULONG DesiredAccess,
- _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
- _In_opt_ HANDLE ProcessHandle,
- _Out_opt_ PCLIENT_ID ClientId,
- _In_ PKSTART_ROUTINE StartRoutine,
- _In_opt_ PVOID StartContext
- );
NTSTATUS PsCreateSystemThread(
_Out_ PHANDLE ThreadHandle,
_In_ ULONG DesiredAccess,
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_opt_ HANDLE ProcessHandle,
_Out_opt_ PCLIENT_ID ClientId,
_In_ PKSTART_ROUTINE StartRoutine,
_In_opt_ PVOID StartContext
);
参数说明
ThreadHandle [out]
返回的handle。当此handle不再使用时,调用ZwClose关闭。对于windows vista以及以后版本,这个handle是一个内核句柄。
DesiredAccess [in]
ACCESS_MASK值,创建的权限。一般取THREAD_ALL_ACCESS。
ObjectAttributes [in,
optional]
线程属性,一般设为null。
ProcessHandle [in,
optional]
线程所在地址空间的进程的handle。对于驱动线程,通常设为NULL。也可以设为NtCurrentProcess()指定为当前进程。
ClientId [out,
optional]
对于驱动线程设为null。
StartRoutine [in]
函数指针,创建的系统线程的入口指针。此函数接受一个参数,就是StartContext。
StartContext [in,
optional]
线程执行时传给StartRoutine的参数。
返回值
PsCreateSystemThread成功返回 STATUS_SUCCESS。
例子1:
- NTSTATUS lstatus;
- lstatus = PsCreateSystemThread( &hThread,
- 0,
- NULL, //或者THREAD_ALL_ACCESS
- NtCurrentProcess(),
- NULL,
- (PKSTART_ROUTINE)ThreadProc,
- NULL );
- if (!NT_SUCCESS(lstatus))
- {
- ;
- }
- NTSTATUS lstatus;
- lstatus = PsCreateSystemThread( &hThread,
- 0,
- NULL, //或者THREAD_ALL_ACCESS
- NtCurrentProcess(),
- NULL,
- (PKSTART_ROUTINE)ThreadProc,
- NULL );
- if (!NT_SUCCESS(lstatus))
- {
- ;
- }
NTSTATUS lstatus;
lstatus = PsCreateSystemThread( &hThread,
0,
NULL, //或者THREAD_ALL_ACCESS
NtCurrentProcess(),
NULL,
(PKSTART_ROUTINE)ThreadProc,
NULL );
if (!NT_SUCCESS(lstatus))
{
;
}
- NTSTATUS
- ThreadProc()
- {
- DbgPrint("CreateThread Successfully");
- //创建线程必须用函数PsTerminateSystemThread强制线程结束。否则该线程是无法自动退出的。
- PsTerminateSystemThread(STATUS_SUCCESS);
- }
- NTSTATUS
- ThreadProc()
- {
- DbgPrint("CreateThread Successfully");
- //创建线程必须用函数PsTerminateSystemThread强制线程结束。否则该线程是无法自动退出的。
- PsTerminateSystemThread(STATUS_SUCCESS);
- }
NTSTATUS
ThreadProc()
{
DbgPrint("CreateThread Successfully");
//创建线程必须用函数PsTerminateSystemThread强制线程结束。否则该线程是无法自动退出的。
PsTerminateSystemThread(STATUS_SUCCESS);
}
2.提供一种方式来通知线程终止并等待终止发生。
- typedef struct _DEVICE_EXTENSION {
- ...
- KEVENT evKill;//在设备扩展中声明一个KEVENT对象
- PKTHREAD thread;
- };
- NTSTATUS StartThread(PDEVICE_EXTENSION pdx)
- {
- NTSTATUS status;
- HANDLE hthread;
- KeInitializeEvent(&pdx->evKill, NotificationEvent, FALSE);
- status = PsCreateSystemThread(&hthread, //创建新线程
- THREAD_ALL_ACCESS,
- NULL,
- NULL,
- NULL,
- (PKSTART_ROUTINE) ThreadProc,
- pdx);
- if (!NT_SUCCESS(status))
- return status;
- ObReferenceObjectByHandle(hthread, //为了等待线程终止,你需要KTHREAD对象的地址来代替从PsCreateSystemThread获得的线程句柄。
- THREAD_ALL_ACCESS, //调用ObReferenceObjectByHandle获得这个地址。
- NULL,
- KernelMode,
- (PVOID*) &pdx->thread,
- NULL);
- ZwClose(hthread); //现在可以关闭线程句柄了,因为已经得到thread
- return STATUS_SUCCESS;
- }
- VOID StopThread(PDEVICE_EXTENSION pdx)
- {
- KeSetEvent(&pdx->evKill, 0, FALSE);
- KeWaitForSingleObject(pdx->thread, Executive, KernelMode, FALSE, NULL);
- ObDereferenceObject(pdx->thread);
- }
- VOID ThreadProc(PDEVICE_EXTENSION pdx)
- {
- ...
- KeWaitForXxx(<at least pdx->evKill>);
- ...
- PsTerminateSystemThread(STATUS_SUCCESS);
- }
- typedef struct _DEVICE_EXTENSION {
- ...
- KEVENT evKill;//在设备扩展中声明一个KEVENT对象
- PKTHREAD thread;
- };
- NTSTATUS StartThread(PDEVICE_EXTENSION pdx)
- {
- NTSTATUS status;
- HANDLE hthread;
- KeInitializeEvent(&pdx->evKill, NotificationEvent, FALSE);
- status = PsCreateSystemThread(&hthread, //创建新线程
- THREAD_ALL_ACCESS,
- NULL,
- NULL,
- NULL,
- (PKSTART_ROUTINE) ThreadProc,
- pdx);
- if (!NT_SUCCESS(status))
- return status;
- ObReferenceObjectByHandle(hthread, //为了等待线程终止,你需要KTHREAD对象的地址来代替从PsCreateSystemThread获得的线程句柄。
- THREAD_ALL_ACCESS, //调用ObReferenceObjectByHandle获得这个地址。
- NULL,
- KernelMode,
- (PVOID*) &pdx->thread,
- NULL);
- ZwClose(hthread); //现在可以关闭线程句柄了,因为已经得到thread
- return STATUS_SUCCESS;
- }
- VOID StopThread(PDEVICE_EXTENSION pdx)
- {
- KeSetEvent(&pdx->evKill, 0, FALSE);
- KeWaitForSingleObject(pdx->thread, Executive, KernelMode, FALSE, NULL);
- ObDereferenceObject(pdx->thread);
- }
- VOID ThreadProc(PDEVICE_EXTENSION pdx)
- {
- ...
- KeWaitForXxx(<at least pdx->evKill>);
- ...
- PsTerminateSystemThread(STATUS_SUCCESS);
- }
typedef struct _DEVICE_EXTENSION {
...
KEVENT evKill;//在设备扩展中声明一个KEVENT对象
PKTHREAD thread;
};
NTSTATUS StartThread(PDEVICE_EXTENSION pdx)
{
NTSTATUS status;
HANDLE hthread;
KeInitializeEvent(&pdx->evKill, NotificationEvent, FALSE);
status = PsCreateSystemThread(&hthread, //创建新线程
THREAD_ALL_ACCESS,
NULL,
NULL,
NULL,
(PKSTART_ROUTINE) ThreadProc,
pdx);
if (!NT_SUCCESS(status))
return status;
ObReferenceObjectByHandle(hthread, //为了等待线程终止,你需要KTHREAD对象的地址来代替从PsCreateSystemThread获得的线程句柄。
THREAD_ALL_ACCESS, //调用ObReferenceObjectByHandle获得这个地址。
NULL,
KernelMode,
(PVOID*) &pdx->thread,
NULL);
ZwClose(hthread); //现在可以关闭线程句柄了,因为已经得到thread
return STATUS_SUCCESS;
}
VOID StopThread(PDEVICE_EXTENSION pdx)
{
KeSetEvent(&pdx->evKill, 0, FALSE);
KeWaitForSingleObject(pdx->thread, Executive, KernelMode, FALSE, NULL);
ObDereferenceObject(pdx->thread);
}
VOID ThreadProc(PDEVICE_EXTENSION pdx)
{
...
KeWaitForXxx(<at least pdx->evKill>);
...
PsTerminateSystemThread(STATUS_SUCCESS);
}
jpg改rar
驱动开发之 创建线程函数PsCreateSystemThread的更多相关文章
- [笔记]linux下和windows下的 创建线程函数
linux下和windows下的 创建线程函数 #ifdef __GNUC__ //Linux #include <pthread.h> #define CreateThreadEx(ti ...
- Windows驱动开发-手动创建IRP
手动创建IRP有以下几个步骤: 1,先得到设备的指针,一种方法是用IoGetDeviceObjectPointer内核函数得到设备对象指针,另外一种方法是用zwCreateFile内核函数先得到设备句 ...
- Windows驱动开发-内核常用内存函数
搞内存常用函数 C语言 内核 malloc ExAllocatePool memset RtlFillMemory memcpy RtlMoveMemory free ExFreePool
- WordPress 主题开发 - (六) 创建主题函数 待翻译
We’ve got a file structure in place, now let’s start adding things to them! First, we’re going to ad ...
- linux线程笔记1之创建线程
1 线程与进程的对比 这里有一个笔记详细的阐述 http://blog.csdn.net/laviolette/article/details/51506953 2 创建线程函数 int pthrea ...
- 4、linux下应用创建线程
1.linux创建线程之pthread_create 函数简介 pthread_create是UNIX环境创建线程函数 头文件 #include<pthread.h> 函数声明 int p ...
- Windows驱动开发之线程与同步事件
转载请注明来源: enjoy5512的博客 : http://blog.csdn.net/enjoy5512 GitHub : https://github.com/whu-enjoy .1. 使用系 ...
- 《Windows内核安全与驱动开发》 4.4 线程与事件
<Windows内核安全与驱动开发>阅读笔记 -- 索引目录 <Windows内核安全与驱动开发> 4.4 线程与事件 一.开辟一个线程,参数为(打印内容+打印次数),利用线程 ...
- iOS开发多线程篇—创建线程
iOS开发多线程篇—创建线程 一.创建和启动线程简单说明 一个NSThread对象就代表一条线程 创建.启动线程 (1) NSThread *thread = [[NSThread alloc] in ...
随机推荐
- POJ 1002
#include <stdio.h> #include <string.h> #include <stdlib.h> struct In{ int a; ]; }p ...
- Shell 语法 if 、 case 、for 、 while、 until 、select 、repeat、子函数
if语法 : if [ expression ] then commandselif [ expression2 ] then commandselse commandsfi ...
- ios 转发一篇对于6 plus的分辨率模式的说明
http://segmentfault.com/q/1010000002545515 分为兼容模式和高分辨率模式. 兼容模式 当你的 app 没有提供 3x 的 LaunchImage 时,系统默认进 ...
- sed小知识总结
1)sed默认是打印出文件中的所有行的,使用 -n 选项可以只打印出 匹配 的行 2)当用到sed不同的编辑命令时,用{},且不同编辑命令之间用分号
- QPS计算方法
2016年3月14日 13:55:39 星期一 好久没写文章了, 神烦.....
- Sql Server事务简单用法
var conStr = "server=localhost;database=Data;user=sa;pwd=123456"; using (var connection = ...
- jQuery 调用jsonp实现与原理
jQuery 调用jsonp实现与原理 您的评价: 收藏该经验 阅读目录 1.客户端代码 2.服务器端 通过jQuery实现JSONP 一般的ajax是不能跨域请求的,因此需要使 ...
- nyoj739_笨蛋难题四
笨蛋难题四 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 这些日子笨蛋一直研究股票,经过调研,终于发现xxx公司股票规律,更可喜的是 笨蛋推算出这家公司每天的股价, ...
- JavaScript高级程序设计学习笔记--引用类型
Object类型 对象字面量表示法: var person={ name:"Nicholas", age:29, 5:true }; 这人例子会创建一个对象,包含三个属性:name ...
- 手把手教你实现折线图之------安卓最好用的图表库hellocharts之最详细的使用介绍
因为项目需要搞一个折线图,按照日期显示相应的成绩,所以有了本文. 以前用过一次XCL-chart,但是感觉只适合固定图表,不去滑动的那种,因为你一滑动太卡了你懂得(毕竟作者好久没更新优化了),拙言大神 ...