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所返回的句柄。