对于NT式驱动程序,主要的函数是DriverEntry例程、卸载程序以及各个IRP的派遣函数,基本结构如下:
#include "Driver.h"
#pragma INITCODE
extern "C" NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject
IN PUNICODE_STRING pRegistryPath)
{
.......
pDriverObject->DriverUnload=UnloadFunction;//设置驱动函数
pDriverObject->MajorFunction[IRP_MJ_XXXXX]=DispatchRoutine; //设置每个IRP派遣函数
.......
//创建驱动设备函数
status=CreateDevice(pDriverObject);
........
}
#pragma INITCODE
NTSTATUS CreateDevice(IN PDRIVER_OBJECT)
{
......
}
#pragma INITCODE
NTSTATUS UnloadFunction(IN PDRIVER_OBJECT)
{
......
}
#pragma INITCODE
NTSTATUS DispatchRoutine(IN PDRIVER_OBJECT)
{
......
}
稍微解释下:DriverEntry有两个输入参数,pDriverObject和pRegistryPath。前一个指向刚创建的驱动对象的指针,后一个指向设备服务键的键名字符串的指针。DriverEntry函数的返回值是NTSTATUS的数据,NTSTATUS是被定义为32位的无符号长整型。
驱动程序创建的设备有个设备名,设备名用UNICODE字符串指定,并且字符串必须是"/Device/设备名"。这个设备名只能被内核模式下的程序识别,为了让在用户模式下的程序识别,就要用到符号链接。创建符号链接的函数是IoCreateSymbolicLink,其函数声明是:
NTSTATUS
IoCreateSymbolicLink(IN PUNICODE_STRING SymbolicLinkName
IN PUNICODE_STRING DeviceName)
在内核模式下,符号链接是以"/??/"开头的,或者有以"DosDevices"开头,如C盘就是"/>>/C:"或者"DosDevices/C:"。而在用户模式下,则是以"//./"开头的。如果是要删除符号链接,则是用函数IoDeleteSymbolicLink。