Initialisieren und Registrieren eines Anbietermoduls

Ein Anbietermodul muss eine Reihe von Datenstrukturen initialisieren, bevor es sich bei der Network Module Registrar (NMR) registrieren kann. Zu diesen Strukturen gehören eine NPI_MODULEID-Struktur , eine NPI_PROVIDER_CHARACTERISTICS-Struktur , eine NPI_REGISTRATION_INSTANCE-Struktur (in der NPI_PROVIDER_CHARACTERISTICS-Struktur enthalten) und eine Struktur, die vom Anbietermodul definiert wird, das für den Registrierungskontext des Anbietermoduls verwendet wird.

Wenn sich ein Anbietermodul beim NMR als Anbieter einer Netzwerkprogrammierschnittstelle (Network Programming Interface, NPI) registriert, die NPI-spezifische Anbietermerkmale definiert, muss das Anbietermodul auch eine instance der Vom NPI definierten Struktur der Anbietermerkmale initialisieren.

Alle diese Datenstrukturen müssen gültig bleiben und sich im Arbeitsspeicher befinden, solange das Anbietermodul beim NMR registriert ist.

Angenommen, die NPI "EXNPI" definiert Folgendes in der Headerdatei 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;

Im Folgenden wird gezeigt, wie ein Anbietermodul, das sich selbst als Anbieter der EXNPI-NPI registriert, alle diese Datenstrukturen initialisieren kann:

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

Ein Anbietermodul initialisiert sich in der Regel innerhalb seiner DriverEntry-Funktion . Die Standard Initialisierungsaufgaben für ein Anbietermodul sind:

  • Geben Sie eine Unload-Funktion an . Das Betriebssystem ruft diese Funktion auf, wenn das Anbietermodul vom System entladen wird. Wenn ein Anbietermodul keine Entladefunktion bereitstellt, kann das Anbietermodul nicht aus dem System entladen werden.

  • Rufen Sie die NmrRegisterProvider-Funktion auf, um das Anbietermodul beim NMR zu registrieren.

Beispiel:

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

Wenn ein Anbietermodul ein Anbieter mit mehr als einem NPI ist, muss es einen unabhängigen Satz von Datenstrukturen initialisieren und NmrRegisterProvider für jeden unterstützten NPI aufrufen. Wenn ein Netzwerkmodul sowohl ein Anbietermodul als auch ein Clientmodul ist (d. h., es ist ein Anbieter eines NPI und ein Client einer anderen NPI), muss es zwei unabhängige Sätze von Datenstrukturen initialisieren, eine für die Anbieterschnittstelle und eine für die Clientschnittstelle, und rufen Sowohl NmrRegisterProvider als auch NmrRegisterClient auf.

Ein Anbietermodul ist nicht erforderlich, um NmrRegisterProvider aus seiner DriverEntry-Funktion aufzurufen. In der Situation, in der ein Anbietermodul eine Unterkomponente eines komplexen Treibers ist, kann die Registrierung des Anbietermoduls nur erfolgen, wenn der Anbietermodul-Teilkomponenten aktiviert wird.

Weitere Informationen zum Implementieren der Unload-Funktion eines Anbietermoduls finden Sie unter Entladen eines Anbietermoduls.