다음을 통해 공유


클라이언트 모듈 초기화 및 등록

클라이언트 모듈은 NMR(네트워크 모듈 등록 기관)에 등록하기 전에 여러 데이터 구조를 초기화해야 합니다. 이러한 구조에는 NPI_MODULEID 구조, NPI_CLIENT_CHARACTERISTICS 구조, NPI_REGISTRATION_INSTANCE 구조(NPI_CLIENT_CHARACTERISTICS 구조 내에 포함됨) 및 클라이언트 모듈의 등록 컨텍스트에 사용되는 클라이언트 모듈에서 정의한 구조체가 포함됩니다.

클라이언트 모듈이 NPI 관련 클라이언트 특성을 정의하는 NPI(네트워크 프로그래밍 인터페이스)의 클라이언트로 NMR에 등록하는 경우 클라이언트 모듈은 NPI에서 정의한 클라이언트 특성 구조의 instance 초기화해야 합니다.

클라이언트 모듈이 NMR에 등록된 한 이러한 모든 데이터 구조는 유효하고 메모리에 상주해야 합니다.

예를 들어 "EXNPI" NPI가 헤더 파일 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;

다음은 EXNPI NPI의 클라이언트로 자신을 등록하는 클라이언트 모듈이 이러한 모든 데이터 구조를 초기화하는 방법을 보여 줍니다.

// 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 함수 내에서 자신을 초기화합니다. 클라이언트 모듈에 대한 기본 초기화 작업은 다음과 같습니다.

  • 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 클라이언트인 경우 독립적인 데이터 구조 집합을 초기화하고 지원하는 각 NPI에 대해 NmrRegisterClient 를 호출해야 합니다. 네트워크 모듈이 클라이언트 모듈과 공급자 모듈(즉, 한 NPI의 클라이언트이고 다른 NPI의 공급자)인 경우 클라이언트 인터페이스와 공급자 인터페이스에 대해 하나씩 두 개의 독립적인 데이터 구조 집합을 초기화하고 NmrRegisterClientNmrRegisterProvider를 모두 호출해야 합니다.

클라이언트 모듈은 DriverEntry 함수 내에서 NmrRegisterClient를 호출할 필요가 없습니다. 예를 들어 클라이언트 모듈이 복잡한 드라이버의 하위 구성 요소인 경우 클라이언트 모듈 하위 구성 요소가 활성화된 경우에만 클라이언트 모듈 등록이 발생할 수 있습니다.

클라이언트 모듈의 언로드 함수 구현에 대한 자세한 내용은 클라이언트 모듈 언로드를 참조하세요.