在驱动对象中会设置DriverUnload例程,此例程在驱动被卸载的时候调用。在NT式驱动中,DriverUnload一般负责删除在DriverEntry中创建的设备对象,并且将设备对象所关联的符号链接删除。另外DriverUnload还负责对一些资源进行回收。如:
#pragma PAGEDCODE
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pNextObj;
KdPrint(("Enter DriverUnload\n"));
// 得到下一个设备对象
pNextObj = pDriverObject->DeviceObject;
// 枚举所有设备对象
while (pNextObj != NULL)
{
// 得到设备扩展
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pNextObj->DeviceExtension;
//删除符号链接
UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
IoDeleteSymbolicLink(&pLinkName);
pNextObj = pNextObj->NextDevice;
// 删除设备
IoDeleteDevice( pDevExt->pDevice );
}
}
在HelloDDKUnload中传进来驱动对象。前面讲过,根据驱动对象,就可以遍历所有由该驱动对象创建的设备对象。通过驱动对象的DeviceObject域,可以找到驱动对象的第一个设备对象,然后根据设备对象的NextDevice域,就可以找到随后的设备对象。在HelloDDK这个例子中,驱动对象起始只创建了一个设备对象。因此,在HelloDDKUnload的调用中,也只会删除一个设备对象。
删除设备对象的函数是IoDeleteDevice,函数原型是:
VOID IoDeleteDevice(
IN PDEVICE_OBJECT DeviceObject
);
其参数就是要删除的设备的对象指针。在DriverUnload中,除了要删除设备对象,同时,还要对设备对象关联的符号链接进行删除。删除符号链接的函数是IoDeleteSymbolicLink,其函数原型是:
NTSTATUS IoDeleteSymbolicLink(
IN PUNICODE_STRING SymbolicLinkName
);
//* SymbolicLinkName: 表示已经被注册了的符号链接
//* 返回值:表示删除符号链接是否成功。