首页
社区
课程
招聘
[原创]Delphi驱动开发研究(十)--内核同步对象—线程与定时器
发表于: 2009-12-11 09:35 10191

[原创]Delphi驱动开发研究(十)--内核同步对象—线程与定时器

2009-12-11 09:35
10191

本篇及下篇教程我们将讲述内核同步对象。同步是一个涉及面非常广的主题,系统提供了多种同步对象,因此两篇文章也仅能让您对其有个大致的了解。
10.1 同步对象
迄今为止,我们都不需要独占访问某个数据,因为我们仅有一个线程在工作。当有两个或多个线程都需要访问同一个资源时,就需要引入同步机制,否则此资源的状态就无法预知了。比如当两个线程同时访问(在一个多处理器的系统中这种情况很常见)一个保存在共亨内存中的变量。常见的解决方法就是后面的线程等待前一个线程完成数据访问。
为解决此类问题,操作系统提供了一些同步对象的机制:事件(Event)、互斥(Mutex)--在内核中被称为突变体(Mutant)、信号灯(Semaphore)等等。这些同步机制在用户模式下也存在,而且使用方法也大同小异。
所有的同步对象结构的第一个字段均为一个DISPATCHER_HEADER结构用以描述此对象所期望的操作。下面是本章将要用到的两个结构:定时器对象(又叫watchdog)和线程对象。

_KTIMER = packed record
  Header: DISPATCHER_HEADER;
  ……
end;
KTHREAD = packed record
  Header: DISPATCHER_HEADER;
  . . . 
KTHREAD ENDS 
end;
unit TimerWorks;

interface

uses
  nt_status, ntoskrnl, hal, native, fcall, macros;

function _DriverEntry(pDriverObject:PDRIVER_OBJECT;
                              pusRegistryPath:PUNICODE_STRING): NTSTATUS; stdcall;

implementation

var
  g_pkThread: PVOID;  {PTR KTHREAD}
  g_fStop: Boolean;
  g_usDeviceName, g_usSymbolicLinkName: UNICODE_STRING;

function ThreadProc(StartContext: PVOID): NTSTATUS;
var
  dwCounter: DWORD;
  pkThread: PVOID;  {PKTHREAD}
  _kTimer: KTIMER;
  liDueTime: LARGE_INTEGER;
  iPriority: KPRIORITY;
begin
  dwCounter := 0;
  DbgPrint(#13#10'TimerWorks: Entering ThreadProc'#13#10);

  DbgPrint('TimerWorks: IRQL = %d'#13#10, KeGetCurrentIrql);
  pkThread := KeGetCurrentThread;
  iPriority := KeQueryPriorityThread(pkThread);
  DbgPrint('TimerWorks: Thread Priority = %d'#13#10, iPriority);
  Inc(iPriority, 2);
  KeSetPriorityThread(pkThread, iPriority);

  iPriority := KeQueryPriorityThread(pkThread);
  DbgPrint('TimerWorks: Thread Priority = %d'#13#10, iPriority);
 
  KeInitializeTimerEx(@_kTimer, SynchronizationTimer);

  liDueTime.HighPart := liDueTime.HighPart or -1;
  liDueTime.LowPart := $FD050F80; {-50000000}
 
  KeSetTimerEx(@_kTimer, liDueTime.LowPart, liDueTime.HighPart, 1000, nil);
  DbgPrint('TimerWorks: Timer is set. It starts counting in 5 seconds...'#13#10);

  while dwCounter < 10 do
  begin
    KeWaitForSingleObject(@_kTimer, Executive, KernelMode,
                                    FALSE, nil);
    Inc(dwCounter);
    DbgPrint('TimerWorks: Counter = %d'#13#10, dwCounter);
    if g_fStop then
    begin
        DbgPrint('TimerWorks: Stop counting to let the driver to be uloaded'#13#10);
        Break;
    end;
  end;
  KeCancelTimer(@_kTimer);
  DbgPrint('TimerWorks: Timer is canceled. Leaving ThreadProc'#13#10);
  DbgPrint('TimerWorks: Our thread is about to terminate'#13#10);
  PsTerminateSystemThread(STATUS_SUCCESS);
  Result := STATUS_SUCCESS;
end;

procedure DriverUnload(p_DriverObject:PDRIVER_OBJECT); stdcall;
begin
  DbgPrint(#13#10'TimerWorks: Entering DriverUnload'#13#10);
  g_fStop := TRUE;  {Break the timer loop if it's counting}

  DbgPrint('TimerWorks: Wait for thread exits...'#13#10);
  KeWaitForSingleObject(@g_pkThread, Executive, KernelMode, FALSE, nil);

  ObfDereferenceObject(@g_pkThread);
  IoDeleteSymbolicLink(@g_usSymbolicLinkName);
  IoDeleteDevice(p_DriverObject^.DeviceObject);
  DbgPrint('TimerWorks: Leaving DriverUnload'#13#10);
end;

function StartThread: NTSTATUS;
var
  status: NTSTATUS;
  hThread: THANDLE;
begin
  DbgPrint(#13#10'TimerWorks: Entering StartThread'#13#10);
  status := PsCreateSystemThread(@hThread,
                                 THREAD_ALL_ACCESS, nil, 0,
                                 nil, @ThreadProc, nil);
  if status = STATUS_SUCCESS then
  begin
    ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS,
                              nil, KernelMode, @g_pkThread, nil);

    ZwClose(hThread);
    DbgPrint('TimerWorks: Thread created'#13#10);
  end else
  begin
    DbgPrint('TimerWorks: Can''t create Thread. Status: %08X'#13#10, status);
  end;
  DbgPrint('TimerWorks: Leaving StartThread'#13#10);
  Result := status;
end;

function _DriverEntry(pDriverObject:PDRIVER_OBJECT;
                      pusRegistryPath:PUNICODE_STRING): NTSTATUS; stdcall;
var
  status: NTSTATUS;
  pDeviceObject: TDeviceObject;
begin
  status := STATUS_DEVICE_CONFIGURATION_ERROR;
  RtlInitUnicodeString(g_usDeviceName, '\Device\TimerWorks');
  RtlInitUnicodeString(g_usSymbolicLinkName, '\DosDevices\TimerWorks');

  if IoCreateDevice(pDriverObject, 0, @g_usDeviceName,
                    FILE_DEVICE_UNKNOWN, 0, TRUE,
                    pDeviceObject) = STATUS_SUCCESS then
  begin
    if IoCreateSymbolicLink(@g_usSymbolicLinkName,
                            @g_usDeviceName) = STATUS_SUCCESS then
    begin
      if StartThread = STATUS_SUCCESS then
      begin
        g_fStop := false; {reset global flag}
        pDriverObject^.DriverUnload := @DriverUnload;
        status := STATUS_SUCCESS;
      end else
      begin
        IoDeleteSymbolicLink(@g_usSymbolicLinkName);
        IoDeleteDevice(@pDeviceObject);
      end;
    end else
    begin
      IoDeleteDevice(@pDeviceObject);
    end;
  end;
  Result := status;
end;

end. 
var
  hThread: THANDLE;
  ……
status := PsCreateSystemThread(@hThread,
                            THREAD_ALL_ACCESS, nil, 0,
                            nil, @ThreadProc, nil); 
if status = STATUS_SUCCESS then
begin
ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS,
                          nil, KernelMode, @g_pkThread, nil);

ZwClose(hThread);
DbgPrint('TimerWorks: Thread created'#13#10);
end else
begin
DbgPrint('TimerWorks: Can''t create Thread. Status: %08X'#13#10, status);
end;

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (7)
雪    币: 237
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
占座学习,多谢分享
2009-12-11 21:41
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
大牛 等你好久 你终于出现了
2009-12-12 19:20
0
雪    币: 622
活跃值: (65)
能力值: ( LV13,RANK:290 )
在线值:
发帖
回帖
粉丝
4
顶一下。。。
2009-12-31 22:23
0
雪    币: 280
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5

一般说Delphi不能开发驱动
厉害
2009-12-31 23:04
0
雪    币: 759
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
拜访高人..
2010-2-2 09:54
0
雪    币: 241
活跃值: (15)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
牛人,delphi给你玩转了。
2010-2-9 19:57
0
雪    币: 163
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
这个系列的教程非常的棒,继续学习中
2010-12-15 15:48
0
游客
登录 | 注册 方可回帖
返回
//