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

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

2009-12-11 09:35
10283

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

1
2
3
4
_KTIMER = packed record
  Header: DISPATCHER_HEADER;
  ……
end;
1
2
3
4
5
KTHREAD = packed record
  Header: DISPATCHER_HEADER;
  . . .
KTHREAD ENDS
end;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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.
1
2
3
4
5
6
var
  hThread: THANDLE;
  ……
status := PsCreateSystemThread(@hThread,
                            THREAD_ALL_ACCESS, nil, 0,
                            nil, @ThreadProc, nil);
1
2
3
4
5
6
7
8
9
10
11
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;

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
赞赏记录
参与人
雪币
留言
时间
Youlor
为你点赞~
2024-3-25 01:16
QinBeast
为你点赞~
2024-1-7 05:43
伟叔叔
为你点赞~
2024-1-7 00:05
shinratensei
为你点赞~
2023-12-11 00:03
PLEBFE
为你点赞~
2023-11-28 00:30
心游尘世外
为你点赞~
2023-11-15 00:20
飘零丶
为你点赞~
2023-11-6 00:06
最新回复 (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
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册