5.2 驱动程序中的卸载函数DriverUnload
驱动程序的DriverUnload函数主要负责删除设备与符号连接,同时释放在DriverEntry中所分配的资源。当数据包捕获驱动程序卸载时,操作系统调用NPF_Unload函数。在该函数中,会调用IoDeleteSymbolicLink函数删除符号连接,调用IoDeleteDevice函数删除设备对象,调用NdisDeregisterProtocol函数从NDIS库中取消NPF协议驱动程序的注册,同时释放各相关资源。
DriverUnload函数的具体实现如下:
VOID NPF_Unload(IN PDRIVER_OBJECT DriverObject)
{
PDEVICE_OBJECT DeviceObject;
PDEVICE_OBJECT OldDeviceObject;
PDEVICE_EXTENSION DeviceExtension;
NDIS_STATUS Status;
NDIS_STRING SymLink;
DeviceObject=DriverObject->DeviceObject;
/遍历设备对象,释放资源/
while(DeviceObject!=NULL)
{
OldDeviceObject=DeviceObject;
DeviceObject=DeviceObject->NextDevice;
DeviceExtension=OldDeviceObject->DeviceExtension;
if(DeviceExtension->ExportString)
{
RtlInitUnicodeString(&SymLink,
DeviceExtension->ExportString);
//删除符号连接,并释放相关资源
IoDeleteSymbolicLink(&SymLink);
ExFreePool(DeviceExtension->ExportString);
}
//删除设备对象
IoDeleteDevice(OldDeviceObject);
}
/从NDIS库中取消注册/
NdisDeregisterProtocol(&Status,g_NdisProtocolHandle);
/释放储存适配器名称的内存/
ExFreePool(bindP);
}
关于IoDeleteSymbolicLink、IoDeleteDevice与NdisDeregisterProtocol这三个函数的说明如下所示。
IoDeleteSymbolicLink函数会从系统中删除一个符号连接,其原型如下:
NTSTATUS IoDeleteSymbolicLink(
IN PUNICODE_STRING SymbolicLinkName
);
上述函数中,输入参数SymbolicLinkName指向一个Unicode字符串,该字符串是用户可见的符号连接。如果符号连接删除成功,则函数返回STATUS_SUCCESS。
IoDeleteDevice函数用于从系统中删除一个设备对象,例如,要从系统中删除一个底层的设备,就会调用该函数。该函数原型如下:
VOID IoDeleteDevice(
IN PDEVICE_OBJECT DeviceObject
);
上述函数中,输入参数DeviceObject指向被删除的设备对象。
NdisDeregisterProtocol函数会释放驱动程序调用NdisRegisterProtocol函数所分配的资源,其原型如下:
VOID NdisDeregisterProtocol(
OUT PNDIS_STATUS Status,
IN NDIS_HANDLE NdisProtocolHandle
);
上述函数中,输出参数Status指向调用者提供的一个变量,如果函数调用成功,则它在返回时被设置为NDIS_STATUS_SUCCESS;输入参数NdisProtocolHandle指定驱动程序初始化时调用NdisRegisterProtocol所返回的句柄。