Compartilhar via


Inicializando e registrando um módulo de provedor

Um módulo do provedor deve inicializar várias estruturas de dados antes de se registrar no NMR (Registrador de Módulos de Rede). Essas estruturas incluem uma estrutura NPI_MODULEID , uma estrutura NPI_PROVIDER_CHARACTERISTICS , uma estrutura NPI_REGISTRATION_INSTANCE (contida na estrutura NPI_PROVIDER_CHARACTERISTICS) e uma estrutura definida pelo módulo do provedor que é usada para o contexto de registro do módulo do provedor.

Se um módulo de provedor se registrar com o NMR como um provedor de uma NPI (Interface de Programação de Rede) que define características de provedor específicas de NPI, o módulo do provedor também deverá inicializar uma instância da estrutura de características do provedor definida pela NPI.

Todas essas estruturas de dados devem permanecer válidas e residentes na memória, desde que o módulo do provedor seja registrado com o NMR.

Por exemplo, suponha que o NPI "EXNPI" defina o seguinte no arquivo de cabeçalho 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;

O seguinte mostra como um módulo de provedor que se registra como um provedor do NPI EXNPI pode inicializar todas essas estruturas de dados:

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

Um módulo de provedor normalmente se inicializa dentro de sua função DriverEntry . As tarefas de inicialização main para um módulo de provedor são:

  • Especifique uma função Unload . O sistema operacional chama essa função quando o módulo do provedor é descarregado do sistema. Se um módulo do provedor não fornecer uma função de descarregamento, o módulo do provedor não poderá ser descarregado do sistema.

  • Chame a função NmrRegisterProvider para registrar o módulo do provedor com o NMR.

Por exemplo:

// 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 um módulo de provedor for um provedor de mais de uma NPI, ele deverá inicializar um conjunto independente de estruturas de dados e chamar NmrRegisterProvider para cada NPI compatível. Se um módulo de rede for um módulo de provedor e um módulo de cliente (ou seja, ele for um provedor de uma NPI e um cliente de outra NPI), ele deverá inicializar dois conjuntos independentes de estruturas de dados, um para a interface do provedor e outro para a interface do cliente e chamar NmrRegisterProvider e NmrRegisterClient.

Um módulo de provedor não é necessário para chamar NmrRegisterProvider de dentro de sua função DriverEntry . Por exemplo, na situação em que um módulo de provedor é um subcomponente de um driver complexo, o registro do módulo do provedor pode ocorrer somente quando o subcomponente do módulo do provedor for ativado.

Para obter mais informações sobre como implementar a função Unload de um módulo de provedor, consulte Descarregando um módulo de provedor.