卸载客户端模块
若要卸载客户端模块,操作系统会调用客户端模块的 Unload 函数。 有关如何在初始化期间指定客户端模块的 Unload 函数的详细信息,请参阅初始化和注册客户端模块。
客户端模块的 Unload 函数可确保在从系统内存中卸载客户端模块之前,从网络模块注册器 (NMR) 取消注册客户端模块。 客户端模块通过调用 NmrDeregisterClient 函数(它通常从其 Unload 函数调用)从 NMR 启动取消注册。 客户端模块在从 NMR 完全注销之前,不得从其 Unload 函数返回。 如果对 NmrDeregisterClient 的调用返回STATUS_PENDING,则客户端模块必须调用 NmrWaitForClientDeregisterComplete 函数,等待取消注册完成,然后才能从其 Unload 函数返回。
例如:
// Variable containing the handle for the registration
HANDLE ClientHandle;
// Unload function
VOID
Unload(
IN PDRIVER_OBJECT DriverObject
)
{
NTSTATUS Status;
// Deregister the client module from the NMR
Status =
NmrDeregisterClient(
ClientHandle
);
// Check if pending
if (Status == STATUS_PENDING)
{
// Wait for the deregistration to be completed
NmrWaitForClientDeregisterComplete(
ClientHandle
);
}
// An error occurred
else
{
// Handle error
...
}
}
如果客户端模块注册为多个 网络编程接口的客户端, (NPI) ,则必须为其支持的每个 NPI 调用 NmrDeregisterClient 。 如果网络模块同时注册为客户端模块和提供程序模块 (即,它是一个 NPI 的客户端和另一个 NPI) 的提供程序,则它必须同时调用 NmrDeregisterClient 和 NmrDeregisterProvider。
网络模块必须等待所有注销完成,然后才能从其 Unload 函数返回。
客户端模块不需要从其 Unload 函数中调用 NmrDeregisterClient。 例如,在客户端模块是复杂驱动程序的子组件的情况下,在停用客户端模块子组件时,可能会取消注册客户端模块。 但是,在这种情况下,驱动程序仍必须确保客户端模块已从 NMR 中完全注销,然后再从其 Unload 函数返回。