Condividi tramite


Inizializzazione e registrazione di un modulo provider

Un modulo provider deve inizializzare una serie di strutture di dati prima di poter registrarsi con il Registro moduli di rete (NMR). Queste strutture includono una struttura NPI_MODULEID, una struttura NPI_PROVIDER_CHARACTERISTICS, una struttura NPI_REGISTRATION_INSTANCE (contenuta nella struttura NPI_PROVIDER_CHARACTERISTICS) e una struttura definita dal modulo provider utilizzato per il contesto di registrazione del modulo del provider.

Se un modulo provider si registra con nmR come provider di un provider di un'interfaccia di programmazione di rete che definisce le caratteristiche del provider specifiche del provider, il modulo provider deve anche inizializzare un'istanza della struttura delle caratteristiche del provider definita dall'entità di rete.

Tutte queste strutture di dati devono rimanere valide e residenti in memoria, purché il modulo provider 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 provider characteristics structure
typedef struct EXNPI_PROVIDER_CHARACTERISTICS_
{
  .
  . // NPI-specific members
  .
} EXNPI_PROVIDER_CHARACTERISTICS, *PEXNPI_PROVIDER_CHARACTERISTICS;

Di seguito viene illustrato come un modulo provider che si registra come provider dell'NPI EXNPI può inizializzare tutte queste strutture di dati:

// 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 modulo provider inizializza in genere se stesso all'interno della funzione DriverEntry . Le principali attività di inizializzazione per un modulo provider sono:

  • Specificare una funzione Di caricamento . Il sistema operativo chiama questa funzione quando il modulo provider viene scaricato dal sistema. Se un modulo provider non fornisce una funzione di scaricamento, il modulo provider non può essere scaricato dal sistema.

  • Chiamare la funzione NmrRegisterProvider per registrare il modulo del provider con NMR.

Ad esempio:

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

Se un modulo provider è un provider di più criteri di rete, deve inizializzare un set indipendente di strutture di dati e chiamare NmrRegisterProvider per ogni npI supportato. Se un modulo di rete è sia un modulo provider che un modulo client, ovvero un provider di criteri di rete e un client di un altro npI, deve inizializzare due set indipendenti di strutture di dati, una per l'interfaccia del provider e una per l'interfaccia client e chiamare sia NmrRegisterProvider che NmrRegisterClient.

Un modulo provider non è necessario per chiamare NmrRegisterProvider dall'interno della funzione DriverEntry . Ad esempio, nella situazione in cui un modulo provider è un sottocomponente di un driver complesso, la registrazione del modulo provider potrebbe verificarsi solo quando viene attivato il sottocomponente del modulo provider.

Per altre informazioni sull'implementazione della funzione di scaricamento di un modulo del provider, vedere Scaricare un modulo provider.