Condividi tramite


Inizializzazione e registrazione di un modulo provider

Un modulo provider deve inizializzare una serie di strutture di dati prima di potersi registrare con il Network Module Registrar (NMR). Queste strutture includono una struttura NPI_MODULEID, una struttura NPI_PROVIDER_CHARACTERISTICS, una struttura NPI_REGISTRATION_INSTANCE (contenuta all'interno della struttura NPI_PROVIDER_CHARACTERISTICS) e una struttura definita dal modulo provider usato per il contesto di registrazione del modulo del provider.

Se un modulo provider si registra con NMR come provider di un Network Programming Interface (NPI) che definisce le caratteristiche del provider specifiche dell'NPI, il modulo provider deve anche inizializzare un'istanza della struttura delle caratteristiche del provider definita dall'NPI.

Tutte queste strutture di dati devono rimanere valide e residenti in memoria, malgrado il modulo del 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 in genere si inizializza all'interno della relativa funzione DriverEntry. Le attività di inizializzazione principali per un modulo del provider sono:

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

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

Per 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ù NPI, deve inizializzare un set indipendente di strutture di dati e chiamare NmrRegisterProvider per ogni NPI che supporta. Se un modulo di rete è sia un modulo provider che un modulo client ,ovvero un provider di un server dei criteri di rete e un client di un altro server dei criteri di rete, deve inizializzare due set indipendenti di strutture di dati, uno per l'interfaccia del provider e uno per l'interfaccia client e chiamare sia NmrRegisterProvider che NmrRegisterClient.

Non è necessario un modulo del provider per chiamare NmrRegisterProvider dall'interno della relativa funzioneDriverEntry. Ad esempio, nella situazione in cui un modulo provider è un sottocomponente di un driver complesso, la registrazione del modulo provider può verificarsi solo quando viene attivato il sottocomponente del modulo provider.

Per ulteriori informazioni sull'implementazione della funzione di scaricamento di un modulo provider, vedere Scaricamento di un modulo provider.