第一个驱动是NT式驱动,一共有两个源文件。Driver.h和Driver.c。
首先来看Driver.h文件。
1: #pragma once
2:
3: #ifdef __cplusplus
4: extern "C"
5: {
6: #endif
7: #include <NTDDK.h>
8: #ifdef __cplusplus
9: }
10: #endif
11:
12: #define PAGEDCODE code_seg("PAGE")
13: #define LOCKEDCODE code_seg()
14: #define INITCODE code_seg("INIT")
15:
16: #define PAGEDDATA data_seg("PAGE")
17: #define LOCKEDDATA data_seg()
18: #define INITDATA data_seg("INIT")
19:
20: #define arraysize(p) (sizeof(p)/sizeof((p)[0]))
21:
22: typedef struct _DEVICE_EXTENSION {
23: PDEVICE_OBJECT pDevice;
24: UNICODE_STRING ustrDeviceName;
25: UNICODE_STRING ustrSymLinkName;
26: } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
27:
28:
29:
30: NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject);
31: VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);
32: NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
33: IN PIRP pIrp);
第1行,#pragma once 保证该头文件只被编译一次。
3到10行实际为了include一个NTDDK.h文件,该文件包含了DDK提供的函数,已经许多宏定义。但是内核是用c语
言编译的,所以这里用了一句extern "C"来保证该头文件一定是以c语言方式编译的,否则在连接时会提示找不
到函数。
12到18行定义了分页标记(PAGEDCODE),非分页标记(LOCKEDCODE),以及初始化内存块(INITCODE)。其中初
始化内存块中的内容只有在驱动加载过程中需要调入内存,而当驱动成功加载后,便可从内存中卸载掉。
20行顾名思义,定义了一个计算数组元素个数的宏。
22到26行定义了,DEVICE_EXTENSION以及其指针,包含了一个指向该设备扩展所属设备的指针,以及该设备的名
字,以及其SymLinkName。
30行到33行声明了3个函数,分别用于创建设备,卸载例程,以及一个响应IRP事件的函数。
几个问题,这段代码里有几个数据结构需要说明。
NTSTATUS:
这实际上是个32位无符号长整型。习惯上,0x7FFF FFFF之前用于表示正确的状态,之后用于表示错误的状态。
当然不同的正确或者错误对应着不同的数。
UNICODE_STRING:
定义如下:typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING *PUNICODE_STRING; USHORT当然是无符号短整,用处当然是顾名思义了。至于PWSTR,定义如下:typedef __nullterminated WCHAR *NWPSTR, *LPWSTR, *PWSTR;__nullterminated 并没有实际的意思,只是暗示\'\0\'并不代表字符串的结尾,这对于UNICODE来说,是理所当然的事情。所以PWSTR所定义的Buffer实际上是一个指向宽字符集WCHAR的指针罢了。
接下来是NT式驱动的Driver.c文件。
1: #include "Driver.h"
2:
3: /************************************************************************
4: * 函数名称:DriverEntry
5: * 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象
6: * 参数列表:
7: pDriverObject:从I/O管理器中传进来的驱动对象
8: pRegistryPath:驱动程序在注册表的中的路径
9: * 返回 值:返回初始化驱动状态
10: *************************************************************************/
11: #pragma INITCODE
12: extern "C" NTSTATUS DriverEntry (
13: IN PDRIVER_OBJECT pDriverObject,
14: IN PUNICODE_STRING pRegistryPath )
15: {
16: NTSTATUS status;
17: KdPrint(("Enter DriverEntryn"));
18:
19: //注册其他驱动调用函数入口
20: pDriverObject->DriverUnload = HelloDDKUnload;
21: pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;
22: pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;
23: pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;
24: pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;
25:
26: //创建驱动设备对象
27: status = CreateDevice(pDriverObject);
28:
29: KdPrint(("DriverEntry endn"));
30: return status;
31: }
32:
33: /************************************************************************