介绍:这个驱动程序是一个最小化的驱动程序,它仅仅只有入口函数和退出函数。
Note : This driver is a minimization of the driver, it only functions only entrance and exit function
//
// MinDriver.h
//
// 输出调试信息宏
//
#define DBGPRINT(Fmt) /
{ /
DbgPrint("MinDriver debug: %s (%d)", __FILE__, __LINE__); /
DbgPrint (Fmt); /
}
//——————————————————————————————————————
//Driver's Function
//——————————————————————————————————————
// 驱动程序入口函数
//
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
//——————————————————————————————————————
// 驱动程序卸载函数
//
VOID
PacketUnload(
IN PDRIVER_OBJECT DriverObject
);
//
// MinDriver.c
//
#include <ndis.h>
#include "MinDriver.h"
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
DBGPRINT("DriverEntry Loading.../n");
DriverObject->DriverUnload = PacketUnload;
return(0);
}
VOID
PacketUnload(
IN PDRIVER_OBJECT DriverObject
)
{
PDEVICE_OBJECT DeviceObject;
PDEVICE_OBJECT OldDeviceObject;
DBGPRINT("DriverEntry unLoading.../n");
DeviceObject = DriverObject->DeviceObject;
while (DeviceObject != NULL)
{
OldDeviceObject=DeviceObject;
DeviceObject=DeviceObject->NextDevice;
IoDeleteDevice(OldDeviceObject);
}
}
说明:每个驱动程序必须有一个DriverEntry例程以用来初始化驱动程序范围的数据结构和资源,优点类似main函数一样。
DriverObject输入指针允许DriverEntry例程为它在驱动程序对象中的Dispatch、AddDevice、StartIo和Unload例程设置适当入口点。在当前的MinDriver中,仅仅实现了Unload的例程。
DriverEntry例程返回一个NTSTATUS值,它不是STATUS_SUCCESS就是一个具体的错误信息。
DriverEntry例程在它返回STATUS_SUCCESS之前将延迟任何对oRegisterDriverReinitialization的调用。如果它不返回STATUS_SUCCESS,就不必进行这种调用。如果DriverEntry例程返回的不是STATUS_SUCCESS,那么驱动程序就不再被继续加载。DriverEntry例程在它返回控制之前必须释放所有它已经安装的系统对象、系统资源和注册表资源,否则初始化将失败。如果驱动程序支持这些请求,它应该将驱动程序对象的IRP_MJ_FLUSH_BUFFERS重置为驱动程序Dispatch入口点,并且/或者将IRP_MJ_SHUTDOWN设为NULL。
DriverEntry例程在以下阶段中初始化:
1. 为需要与其设备通信的硬件配置信息(如果有)分配内存。
2. 在驱动程序对象中设置驱动程序的Dispatch、AddDevice、StartIo(如果有)和Unload(如果有)入口点。
3. 建立所有驱动程序对象或其他系统资源,例如自旋锁,使驱动程序可以用它们来处理I/O请求。
4. 释放任何不再需要的已分配内存,可能调用IoRegisterDriverReinitialization,并返回一个适当的NTSTATUS值。
Unload:任何在系统运行时可以被替换或卸载并重载的驱动程序都必须有Unload例程。
视频、键盘或鼠标设备和能保存系统当前页文件的海量存储设备的驱动程序没有Unload例
程,因为这些类型的设备必须在当前系统运行时始终可用。位于这些设备驱动程序之上的高
层驱动程序也没有Unload例程。
虽然各个驱动程序的Unload例程不尽相同,但是它大致执行下列工作:
1. 对于一些硬件,设备的状态应该存储在注册表中。在下次DriverEntry例程执行的时候驱动程序可以恢复到最近的状态。例如,声卡驱动程序可能存储当前它的音量设置信息。
2. 如果这个设备支持中断,Unload例程必须禁止它们和断开它们与中断对象的连接。一旦中断对象被删除,设备将不会产生任何中断请求。
3. 释放属于驱动程序的任何硬件。
4. 从Win32的名字空间移除符号连接名。这个动作可以调用IoDeleteSymbolicLink来实现。
5. 使用IoDeleteDevice移除设备对象。
6. 如果管理多部件的控制器,为每一个连接到控制器的设备重复步骤4和5,然后移除控制器对象它自己,使用IoDeleteController函数。
7. 重复步骤4到6,移除所有的术语这个驱动程序的控制器和设备。
8. 释放驱动程序持有的任何缓冲池。
对于WDM驱动程序,这些任务在RemoveDevice例程中执行。
注意,一个驱动程序的Unload例程不是在系统被关闭的时候被调用。在系统被关闭的时候任何特殊的工作在特殊的shutdown例程中执行。