驱动开发之 创建线程函数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
);


参数说明

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 
	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);								
}




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值