Partager via


Initialisation et inscription d’un module fournisseur

Un module fournisseur 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_PROVIDER_CHARACTERISTICS , une structure de NPI_REGISTRATION_INSTANCE (contenue dans la structure NPI_PROVIDER_CHARACTERISTICS) et une structure définie par le module fournisseur utilisée pour le contexte d’inscription du module fournisseur.

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

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

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 provider characteristics structure
typedef struct EXNPI_PROVIDER_CHARACTERISTICS_
{
  .
  . // NPI-specific members
  .
} EXNPI_PROVIDER_CHARACTERISTICS, *PEXNPI_PROVIDER_CHARACTERISTICS;

L’exemple suivant montre comment un module de fournisseur qui s’inscrit lui-même en tant que fournisseur 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 provider module's NPI-specific characteristics
const EXNPI_PROVIDER_CHARACTERISTICS NpiSpecificCharacteristics =
{
  .
  . // The NPI-specific characteristics of the provider module
  .
};

// Structure for the provider module's identification
const NPI_MODULEID ProviderModuleId =
{
  sizeof(NPI_MODULEID),
  MIT_GUID,
  { ... }  // A GUID that uniquely identifies the provider module
};

// Prototypes for the provider module's callback functions
NTSTATUS
  ProviderAttachClient(
    IN HANDLE NmrBindingHandle,
    IN PVOID ProviderContext,
    IN PNPI_REGISTRATION_INSTANCE ClientRegistrationInstance,
    IN PVOID ClientBindingContext,
    IN CONST VOID *ClientDispatch,
    OUT PVOID *ProviderBindingContext,
    OUT PVOID *ProviderDispatch
    );

NTSTATUS
  ProviderDetachClient(
    IN PVOID ProviderBindingContext
    );

VOID
  ProviderCleanupBindingContext(
    IN PVOID ProviderBindingContext
    );

// Structure for the provider module's characteristics
const NPI_PROVIDER_CHARACTERISTICS ProviderCharacteristics =
{
  0,
  sizeof(NPI_PROVIDER_CHARACTERISTICS),
  ProviderAttachClient,
  ProviderDetachClient,
  ProviderCleanupBindingContext,
  {
    0,
    sizeof(NPI_REGISTRATION_INSTANCE),
    &EXNPI_NPIID,
    &ProviderModuleId,
    0,
    &NpiSpecificCharacteristics
  }
};

// Context structure for the provider module's registration
typedef struct PROVIDER_REGISTRATION_CONTEXT_ {
  .
  . // Provider-specific members
  .
} PROVIDER_REGISTRATION_CONTEXT, *PPROVIDER_REGISTRATION_CONTEXT;

// Structure for the provider's registration context
PROVIDER_REGISTRATION_CONTEXT ProviderRegistrationContext =
{
  .
  . // Initial values for the registration context
  .
};

Un module fournisseur s’initialise généralement dans sa fonction DriverEntry . Les tâches d’initialisation main pour un module fournisseur sont les suivantes :

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

  • Appelez la fonction NmrRegisterProvider pour inscrire le module fournisseur auprès de la NMR.

Par exemple :

// Prototype for the provider module's unload function
VOID
  Unload(
    PDRIVER_OBJECT DriverObject
   );

// Variable to contain the handle for the registration
HANDLE ProviderHandle;

// DriverEntry function
NTSTATUS
  DriverEntry(
    PDRIVER_OBJECT DriverObject,
    PUNICODE_STRING RegistryPath
    )
{
  NTSTATUS Status;

  // Specify the unload function
  DriverObject->DriverUnload = Unload;

  .
  . // Other initialization tasks
  .

  // Register the provider module with the NMR
  Status = NmrRegisterProvider(
    &ProviderCharacteristics,
    &ProviderRegistrationContext,
    &ProviderHandle
    );

  // Return the result of the registration
  return Status;
}

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

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

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