初始化和註冊用戶端模組
用戶端模組必須先初始化數個資料結構,才能向網路模組註冊器註冊本身, (NMR) 。 這些結構包括 NPI_MODULEID 結構、 NPI_CLIENT_CHARACTERISTICS 結構、 NPI_REGISTRATION_INSTANCE 結構 (包含在NPI_CLIENT_CHARACTERISTICS結構) 內,以及用戶端模組用於用戶端模組註冊內容的結構。
如果用戶端模組向 NMR 註冊為 網路程式設計介面用戶端, (NPI) 定義 NPI 特定用戶端特性的用戶端,用戶端模組也必須初始化 NPI 所定義的用戶端特性結構的實例。
只要用戶端模組向 NMR 註冊,所有這些資料結構都必須保持有效且駐留在記憶體中。
例如,假設 「EXNPI」 NPI 會在標頭檔 Exnpi.h 中定義下列專案:
// EXNPI NPI identifier
const NPIID EXNPI_NPIID = { ... };
// EXNPI client characteristics structure
typedef struct EXNPI_CLIENT_CHARACTERISTICS_
{
.
. // NPI-specific members
.
} EXNPI_CLIENT_CHARACTERISTICS, *PEXNPI_CLIENT_CHARACTERISTICS;
以下顯示將本身註冊為 EXNPI NPI 用戶端的用戶端模組如何初始化所有這些資料結構:
// Include the NPI specific header file
#include "exnpi.h"
// Structure for the client module's NPI-specific characteristics
const EXNPI_CLIENT_CHARACTERISTICS NpiSpecificCharacteristics =
{
.
. // The NPI-specific characteristics of the client module
.
};
// Structure for the client module's identification
const NPI_MODULEID ClientModuleId =
{
sizeof(NPI_MODULEID),
MIT_GUID,
{ ... } // A GUID that uniquely identifies the client module
};
// Prototypes for the client module's callback functions
NTSTATUS
ClientAttachProvider(
IN HANDLE NmrBindingHandle,
IN PVOID ClientContext,
IN PNPI_REGISTRATION_INSTANCE ProviderRegistrationInstance
);
NTSTATUS
ClientDetachProvider(
IN PVOID ClientBindingContext
);
VOID
ClientCleanupBindingContext(
IN PVOID ClientBindingContext
);
// Structure for the client module's characteristics
const NPI_CLIENT_CHARACTERISTICS ClientCharacteristics =
{
0,
sizeof(NPI_CLIENT_CHARACTERISTICS),
ClientAttachProvider,
ClientDetachProvider,
ClientCleanupBindingContext,
{
0,
sizeof(NPI_REGISTRATION_INSTANCE),
&EXNPI_NPIID,
&ClientModuleId,
0,
&NpiSpecificCharacteristics
}
};
// Context structure for the client module's registration
typedef struct CLIENT_REGISTRATION_CONTEXT_ {
.
. // Client-specific members
.
} CLIENT_REGISTRATION_CONTEXT, *PCLIENT_REGISTRATION_CONTEXT;
// Structure for the client's registration context
CLIENT_REGISTRATION_CONTEXT ClientRegistrationContext =
{
.
. // Initial values for the registration context
.
};
用戶端模組通常會在其 DriverEntry 函式內自行初始化。 用戶端模組的主要初始化工作如下:
指定 Unload 函式。 當用戶端模組從系統卸載時,作業系統會呼叫此函式。 如果用戶端模組未提供卸載函式,就無法從系統卸載用戶端模組。
呼叫 NmrRegisterClient 函式,以向 NMR 註冊用戶端模組。
例如:
// Prototype for the client module's unload function
VOID
Unload(
PDRIVER_OBJECT DriverObject
);
// Variable to contain the handle for the registration
HANDLE ClientHandle;
// DriverEntry function
NTSTATUS
DriverEntry(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath
)
{
NTSTATUS Status;
// Specify the unload function
DriverObject->DriverUnload = Unload;
.
. // Other initialization tasks
.
// Register the client module with the NMR
Status = NmrRegisterClient(
&ClientCharacteristics,
&ClientRegistrationContext,
&ClientHandle
);
// Return the result of the registration
return Status;
}
如果用戶端模組是多個 NPI 的用戶端,它必須初始化一組獨立的資料結構,並針對它支援的每個 NPI 呼叫 NmrRegisterClient 。 如果網路模組同時是用戶端模組和提供者模組 (,則它是一個 NPI 的用戶端,另一個 NPI 的提供者) ,它必須初始化兩組獨立的資料結構,一組用於用戶端介面,另一個用於提供者介面,然後呼叫 NmrRegisterClient 和 NmrRegisterProvider。
用戶端模組不需要從其DriverEntry函式內呼叫NmrRegisterClient。 例如,在用戶端模組是複雜驅動程式的子元件的情況下,只有在啟用用戶端模組子元件時,才會發生用戶端模組的註冊。
如需實作用戶端 模組 Unload 函 式的詳細資訊,請參閱 卸載用戶端模組。