Compartir a través de


Inicialización y registro de un módulo de cliente

Un módulo cliente debe inicializar una serie de estructuras de datos para poder registrarse con el Registrador de módulos de red (NMR). Estas estructuras incluyen una estructura de NPI_MODULEID , una estructura de NPI_CLIENT_CHARACTERISTICS , una estructura de NPI_REGISTRATION_INSTANCE (incluida en la estructura de NPI_CLIENT_CHARACTERISTICS) y una estructura definida por el módulo cliente que se usa para el contexto de registro del módulo cliente.

Si un módulo cliente se registra con nmR como cliente de una interfaz de programación de red (NPI) que define las características de cliente específicas de NPI, el módulo de cliente también debe inicializar una instancia de la estructura de características del cliente definida por el NPI.

Todas estas estructuras de datos deben permanecer válidas y residentes en la memoria siempre y cuando el módulo cliente se registre con el NMR.

Por ejemplo, supongamos que el NPI "EXNPI" define lo siguiente en el archivo de encabezado 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;

A continuación se muestra cómo un módulo de cliente que se registra como un cliente del NPI de EXNPI puede inicializar todas estas estructuras de datos:

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

Normalmente, un módulo cliente se inicializa dentro de su función DriverEntry . Las tareas de inicialización principales de un módulo cliente son:

  • Especifique una función Unload . El sistema operativo llama a esta función cuando el módulo cliente se descarga del sistema. Si un módulo cliente no proporciona una función de descarga, el módulo cliente no se puede descargar desde el sistema.

  • Llame a la función NmrRegisterClient para registrar el módulo cliente con NMR.

Por ejemplo:

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

Si un módulo cliente es un cliente de más de un NPI, debe inicializar un conjunto independiente de estructuras de datos y llamar a NmrRegisterClient para cada NPI que admita. Si un módulo de red es un módulo cliente y un módulo de proveedor (es decir, es un cliente de un NPI y un proveedor de otro NPI), debe inicializar dos conjuntos independientes de estructuras de datos, una para la interfaz de cliente y otra para la interfaz del proveedor, y llamar a NmrRegisterClient y NmrRegisterProvider.

No es necesario un módulo cliente para llamar a NmrRegisterClient desde su función DriverEntry . Por ejemplo, en la situación en la que un módulo cliente es un subcomponente de un controlador complejo, el registro del módulo cliente solo puede producirse cuando se activa el subcomponente del módulo cliente.

Para obtener más información sobre cómo implementar la función Unload de un módulo cliente, vea Descargar un módulo cliente.