공급자 모듈 초기화 및 등록
공급자 모듈은 NMR(네트워크 모듈 등록 기관)에 등록하기 전에 여러 데이터 구조를 초기화해야 합니다. 이러한 구조에는 NPI_MODULEID 구조, NPI_PROVIDER_CHARACTERISTICS 구조, NPI_REGISTRATION_INSTANCE 구조(NPI_PROVIDER_CHARACTERISTICS 구조 내에 포함됨) 및 공급자 모듈의 등록 컨텍스트에 사용되는 공급자 모듈에서 정의한 구조가 포함됩니다.
공급자 모듈이 NPI 관련 공급자 특성을 정의하는 NPI(네트워크 프로그래밍 인터페이스)의 공급자로 NMR에 등록하는 경우 공급자 모듈은 NPI에서 정의한 공급자 특성 구조의 instance 초기화해야 합니다.
공급자 모듈이 NMR에 등록된 한 이러한 모든 데이터 구조는 유효하고 메모리에 상주해야 합니다.
예를 들어 "EXNPI" NPI가 헤더 파일 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;
다음은 EXNPI NPI의 공급자로 자신을 등록하는 공급자 모듈이 이러한 모든 데이터 구조를 초기화하는 방법을 보여 줍니다.
// 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
.
};
공급자 모듈은 일반적으로 DriverEntry 함수 내에서 자신을 초기화합니다. 공급자 모듈에 대한 기본 초기화 작업은 다음과 같습니다.
Unload 함수를 지정합니다. 운영 체제는 공급자 모듈이 시스템에서 언로드될 때 이 함수를 호출합니다. 공급자 모듈이 언로드 함수를 제공하지 않으면 공급자 모듈을 시스템에서 언로드할 수 없습니다.
NmrRegisterProvider 함수를 호출하여 공급자 모듈을 NMR에 등록합니다.
예:
// 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;
}
공급자 모듈이 둘 이상의 NPI 공급자인 경우 독립적인 데이터 구조 집합을 초기화하고 지원하는 각 NPI에 대해 NmrRegisterProvider 를 호출해야 합니다. 네트워크 모듈이 공급자 모듈과 클라이언트 모듈(즉, 하나의 NPI 공급자이고 다른 NPI의 클라이언트)인 경우 공급자 인터페이스와 클라이언트 인터페이스에 대해 하나씩 두 개의 독립적인 데이터 구조 집합을 초기화하고 NmrRegisterProvider 및 NmrRegisterClient를 모두 호출해야 합니다.
공급자 모듈은 DriverEntry 함수 내에서 NmrRegisterProvider를 호출할 필요가 없습니다. 예를 들어 공급자 모듈이 복합 드라이버의 하위 구성 요소인 경우 공급자 모듈 하위 구성 요소가 활성화된 경우에만 공급자 모듈 등록이 발생할 수 있습니다.
공급자 모듈의 언로드 함수 구현에 대한 자세한 내용은 공급자 모듈 언로드를 참조하세요.