Partager via


Initialisation et inscription d’un module client

Un module client doit initialiser un certain nombre de structures de données avant de pouvoir s’inscrire auprès du serveur d’enregistrement de modules réseau (NMR). Ces structures incluent une structure NPI_MODULEID , une structure de NPI_CLIENT_CHARACTERISTICS , une structure NPI_REGISTRATION_INSTANCE (contenue dans la structure NPI_CLIENT_CHARACTERISTICS) et une structure définie par le module client qui est utilisée pour le contexte d’inscription du module client.

Si un module client s’inscrit auprès de la RMN en tant que client d’une interface de programmation réseau (NPI) qui définit des caractéristiques client spécifiques à un NPI, le module client doit également initialiser une instance de la structure des caractéristiques du client définie par l’indicateur de performance réseau.

Toutes ces structures de données doivent rester valides et résider en mémoire tant que le module client est inscrit auprès du NMR.

Par exemple, supposons que l’indicateur NPI « EXNPI » définit les éléments suivants dans le fichier d’en-tête 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;

L’exemple suivant montre comment un module client qui s’inscrit lui-même en tant que client de l’indicateur de performance réseau EXNPI peut initialiser toutes ces structures de données :

// 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 module client s’initialise généralement dans sa fonction DriverEntry . Les tâches d’initialisation main pour un module client sont les suivantes :

  • Spécifiez une fonction Unload . Le système d’exploitation appelle cette fonction lorsque le module client est déchargé du système. Si un module client ne fournit pas de fonction de déchargement, le module client ne peut pas être déchargé du système.

  • Appelez la fonction NmrRegisterClient pour inscrire le module client auprès de la NMR.

Par exemple :

// 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;
}

Si un module client est un client de plusieurs NPI, il doit initialiser un ensemble indépendant de structures de données et appeler NmrRegisterClient pour chaque NPI qu’il prend en charge. Si un module réseau est à la fois un module client et un module fournisseur (c’est-à-dire qu’il est client d’un NPI et fournisseur d’un autre NPI), il doit initialiser deux ensembles indépendants de structures de données, l’un pour l’interface client et l’autre pour l’interface fournisseur, et appeler NmrRegisterClient et NmrRegisterProvider.

Un module client n’est pas nécessaire pour appeler NmrRegisterClient à partir de sa fonction DriverEntry . Par exemple, dans le cas où un module client est un sous-composant d’un pilote complexe, l’inscription du module client peut se produire uniquement lorsque le sous-composant du module client est activé.

Pour plus d’informations sur l’implémentation de la fonction Unload d’un module client, consultez Déchargement d’un module client.