Compartir a través de


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

Un módulo de proveedor 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_PROVIDER_CHARACTERISTICS , una estructura de NPI_REGISTRATION_INSTANCE (incluida en la estructura NPI_PROVIDER_CHARACTERISTICS) y una estructura definida por el módulo de proveedor que se usa para el contexto de registro del módulo de proveedor.

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

Todas estas estructuras de datos deben permanecer válidas y residentes en la memoria siempre que el módulo de proveedor esté registrado con la 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 provider characteristics structure
typedef struct EXNPI_PROVIDER_CHARACTERISTICS_
{
  .
  . // NPI-specific members
  .
} EXNPI_PROVIDER_CHARACTERISTICS, *PEXNPI_PROVIDER_CHARACTERISTICS;

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

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

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

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

  • Llame a la función NmrRegisterProvider para registrar el módulo de proveedor con NMR.

Por ejemplo:

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

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

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

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