驱动开发之 创建线程函数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 ...
随机推荐
- Qt qss 使用
1.在资源文件建立一个qss文件.如blue.qss 2. 调用 #include "mainwindow.h" #include <QApplication> #in ...
- DELPHI控件:DBLookupComboBOX组件的使用方法
在许多数据表中,数据是以代码方式存放的,如在班级编码数据表tB03(表5.5)中,系部字段TB0309采用编码方式存放,系部真实名称则存放在系部编码表TB06.使用代码的好处是,用户可在编码表TB06 ...
- 18. javacript高级程序设计-JavaScript与XML
1. JavaScript与XML IE采取了下列方式: l 通过ActiveX对象来支持处理XML,而相同的对象也可以用来构建桌面应用程序 l Windows携带了MSXML库,JavaScript ...
- java 入门 第二季2
(1). 封装 封装类的时候属性用private,方法getter和setter用public 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问 ...
- Xcode无法启动ios模拟器的问题
一.问题描述 开发过程需要来回切换ios模拟器调试程序,开始在iPhone 4s下调试,然后切换到iPhone 6s Plus,再切换回iPhone 4s,遇到无法启动ios模拟器.错误提示如下: 二 ...
- Mysql 基础2
创建数据库: create database/*条件*/+ text3/*数据库名称*/ 创建数据库 步骤:查询 创建查询 查询编辑器 (写代码) 删除数据库: drop datab ...
- 由浅入深剖析.htaccess
转自:http://blog.csdn.net/21aspnet/article/details/6908025 [-] htaccess文件使用前提 htaccess基本语法介绍 现学现用学习正则表 ...
- CSS实现限制显示的字数,超出显示"..."
一.背景 在实际项目中,我们常常需要对某些页面的某些特定区域显示指定数量的内容,超出的内容显示"..."来进行美化页面,那么应该怎么做呢?今天就让我们来看看如何达到这一效果. 二. ...
- 宠物收养所(bzoj1208)
Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特 ...
- python基础——单元测试
python基础——单元测试 如果你听说过“测试驱动开发”(TDD:Test-Driven Development),单元测试就不陌生. 单元测试是用来对一个模块.一个函数或者一个类来进行正确性检验的 ...