Compartilhar via


Inicializando e registrando um módulo de cliente

Um módulo cliente 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_CLIENT_CHARACTERISTICS , uma estrutura NPI_REGISTRATION_INSTANCE (contida na estrutura NPI_CLIENT_CHARACTERISTICS) e uma estrutura definida pelo módulo cliente que é usada para o contexto de registro do módulo cliente.

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

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

Por exemplo, suponha que a NPI "EXNPI" defina o seguinte no arquivo de cabeçalho Exnpi.h:

// EXNPI NPI identifier
const NPIID EXNPI_NPIID = { ... };

// EXNPI client characteristics structure
typedef struct EXNPI_CLIENT_CHARACTERISTICS_
{
  .
  . // NPI-specific members
  .
} EXNPI_CLIENT_CHARACTERISTICS, *PEXNPI_CLIENT_CHARACTERISTICS;

Veja a seguir como um módulo cliente que se registra como um cliente da NPI EXNPI pode inicializar todas essas estruturas de dados:

// Include the NPI specific header file
#include "exnpi.h"

// Structure for the client module's NPI-specific characteristics
const EXNPI_CLIENT_CHARACTERISTICS NpiSpecificCharacteristics =
{
  .
  . // The NPI-specific characteristics of the client module
  .
};

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

// Prototypes for the client module's callback functions
NTSTATUS
  ClientAttachProvider(
    IN HANDLE NmrBindingHandle,
    IN PVOID ClientContext,
    IN PNPI_REGISTRATION_INSTANCE ProviderRegistrationInstance
    );

NTSTATUS
  ClientDetachProvider(
    IN PVOID ClientBindingContext
    );

VOID
  ClientCleanupBindingContext(
    IN PVOID ClientBindingContext
    );

// Structure for the client module's characteristics
const NPI_CLIENT_CHARACTERISTICS ClientCharacteristics =
{
  0,
  sizeof(NPI_CLIENT_CHARACTERISTICS),
  ClientAttachProvider,
  ClientDetachProvider,
  ClientCleanupBindingContext,
  {
    0,
    sizeof(NPI_REGISTRATION_INSTANCE),
    &EXNPI_NPIID,
    &ClientModuleId,
    0,
    &NpiSpecificCharacteristics
  }
};

// Context structure for the client module's registration
typedef struct CLIENT_REGISTRATION_CONTEXT_ {
  .
  . // Client-specific members
  .
} CLIENT_REGISTRATION_CONTEXT, *PCLIENT_REGISTRATION_CONTEXT;

// Structure for the client's registration context
CLIENT_REGISTRATION_CONTEXT ClientRegistrationContext =
{
  .
  . // Initial values for the registration context
  .
};

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

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

  • Chame a função NmrRegisterClient para registrar o módulo cliente com o NMR.

Por exemplo:

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

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

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

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

  .
  . // Other initialization tasks
  .

  // Register the client module with the NMR
  Status = NmrRegisterClient(
    &ClientCharacteristics,
    &ClientRegistrationContext,
    &ClientHandle
    );

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

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

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

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