Inizializzazione e registrazione di un modulo client
Un modulo client deve inizializzare una serie di strutture di dati prima di potersi registrare con il registrar del modulo di rete (NMR). Queste strutture includono una struttura NPI_MODULEID, una struttura NPI_CLIENT_CHARACTERISTICS, una struttura NPI_REGISTRATION_INSTANCE (contenuta all'interno della struttura NPI_CLIENT_CHARACTERISTICS) e una struttura definita dal modulo client usato per il contesto di registrazione del modulo client.
Se un modulo client si registra con NMR come client di un Network Programming Interface (NPI) che definisce caratteristiche client specifiche dell'NPI, il modulo client deve anche inizializzare un'istanza della struttura delle caratteristiche client definita dall'NPI.
Tutte queste strutture di dati devono rimanere valide e residenti in memoria, purché il modulo client sia registrato con nmr.
Si supponga, ad esempio, che l'NPI "EXNPI" definisca quanto segue nel file di intestazione 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;
Di seguito viene illustrato come un modulo client che si registra come client dell'NPI EXNPI può inizializzare tutte queste strutture di dati:
// 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
.
};
Un modulo client in genere si inizializza all'interno della relativa funzione DriverEntry. Le attività di inizializzazione principali per un modulo client sono:
Specificare una funzione di scaricamento . Il sistema operativo chiama questa funzione quando il modulo client viene scaricato dal sistema. Se un modulo client non fornisce una funzione di scaricamento, il modulo client non può essere scaricato dal sistema.
Chiamare la funzione NmrRegisterClient per registrare il modulo client con il NMR.
Per esempio:
// 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;
}
Se un modulo client è un client di più NPI, deve inizializzare un set indipendente di strutture di dati e chiamare NmrRegisterClient per ciascun NPI che supporta. Se un modulo di rete è sia un modulo client che un modulo provider , ovvero un client di un server dei criteri di rete e un provider di un altro server dei criteri di rete, deve inizializzare due set indipendenti di strutture di dati, una per l'interfaccia client e una per l'interfaccia del provider e chiamare sia NmrRegisterClient che NmrRegisterProvider.
Non è necessario un modulo client per chiamare NmrRegisterClient dall'interno della relativa funzione DriverEntry. Ad esempio, nella situazione in cui un modulo client è un sottocomponente di un driver complesso, la registrazione del modulo client può verificarsi solo quando viene attivato il sottocomponente del modulo client.
Per altre informazioni sull'implementazione della funzione unload di un modulo client, vedere Scaricare un modulo client.