Инициализация и регистрация клиентского модуля

Клиентский модуль должен инициализировать ряд структур данных, прежде чем он сможет зарегистрировать себя в регистраторе сетевых модулей (NMR). Эти структуры включают структуру NPI_MODULEID , структуру NPI_CLIENT_CHARACTERISTICS , структуру NPI_REGISTRATION_INSTANCE (содержащуюся в структуре NPI_CLIENT_CHARACTERISTICS) и структуру, определяемую клиентским модулем, которая используется для контекста регистрации клиентского модуля.

Если клиентский модуль регистрируется в NMR в качестве клиента сетевого интерфейса программирования (NPI), который определяет характеристики клиента для NPI, клиентский модуль должен также инициализировать экземпляр структуры характеристик клиента, определенной NPI.

Все эти структуры данных должны оставаться действительными и находиться в памяти до тех пор, пока клиентский модуль зарегистрирован в NMR.

Например, предположим, что NPI "EXNPI" определяет следующее в файле заголовка 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;

Ниже показано, как клиентский модуль, который регистрирует себя в качестве клиента NPI EXNPI, может инициализировать все эти структуры данных:

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

Клиентский модуль обычно инициализирует себя в своей функции DriverEntry . Задачи main инициализации для клиентского модуля:

  • Укажите функцию Unload . Операционная система вызывает эту функцию при выгрузке клиентского модуля из системы. Если клиентский модуль не предоставляет функцию выгрузки, клиентский модуль не может быть выгружен из системы.

  • Вызовите функцию NmrRegisterClient , чтобы зарегистрировать клиентский модуль в NMR.

Пример:

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

Если клиентский модуль является клиентом с несколькими NPI, он должен инициализировать независимый набор структур данных и вызывать NmrRegisterClient для каждого NPI, который он поддерживает. Если сетевой модуль является клиентским модулем и модулем поставщика (т. е. клиентом одного NPI и поставщиком другого NPI), он должен инициализировать два независимых набора структур данных, один для интерфейса клиента и один для интерфейса поставщика, и вызвать nmrRegisterClient и NmrRegisterProvider.

Клиентский модуль не требуется для вызова NmrRegisterClient из функции DriverEntry . Например, в ситуации, когда клиентский модуль является подкомпонентом сложного драйвера, регистрация клиентского модуля может происходить только при активации подкомпонента клиентского модуля.

Дополнительные сведения о реализации функции Unload клиентского модуля см. в разделе Выгрузка клиентского модуля.