WSK 하위 시스템에 WSK 클라이언트 연결
WSK(Winsock Kernel) 애플리케이션이 NMR(네트워크 모듈 등록 기관) 에 WSK NPI의 클라이언트로 등록한 후 WSK 하위 시스템이 로드되고 NMR에 등록된 경우 NMR은 애플리케이션의 ClientAttachProvider 콜백 함수를 즉시 호출합니다. WSK 하위 시스템이 NMR에 등록되지 않은 경우 WSK 하위 시스템이 NMR에 등록될 때까지 NMR은 애플리케이션의 ClientAttachProvider 콜백 함수를 호출하지 않습니다.
WSK 애플리케이션은 첨부 파일을 완료하기 위해 다음과 같은 일련의 호출을 수행해야 합니다.
NMR은 WSK 애플리케이션의 ClientAttachProvider 콜백 함수를 호출할 때 WSK 하위 시스템에 연결된 NPI_REGISTRATION_INSTANCE 구조에 대한 포인터를 전달합니다. WSK 애플리케이션의 ClientAttachProvider 콜백 함수는 NMR에서 전달된 데이터를 사용하여 WSK 하위 시스템에 연결할 수 있는지 여부를 결정할 수 있습니다. 일반적으로 WSK 애플리케이션에는 WSK 하위 시스템의 NPI_REGISTRATION_INSTANCE 구조의 NpiSpecificCharacteristics 멤버가 가리키는 WSK_PROVIDER_CHARACTERISTICS 구조 내에 포함된 버전 정보만 필요합니다.
WSK 애플리케이션이 WSK 하위 시스템에 연결할 수 있다고 판단하면 WSK 애플리케이션의 ClientAttachProvider 콜백 함수는 WSK 하위 시스템에 대한 첨부 파일에 대한 바인딩 컨텍스트 구조를 할당하고 초기화합니다. 그런 다음, 애플리케이션은 NmrClientAttachProvider 함수를 호출하여 첨부 파일을 계속 진행합니다.
NmrClientAttachProvider가 STATUS_SUCCESS 반환하면 WSK 애플리케이션이 WSK 하위 시스템에 성공적으로 연결됩니다. 이 경우 WSK 애플리케이션의 ClientAttachProvider 콜백 함수는 NMR이 애플리케이션의 ClientAttachProvider 콜백 함수를 호출할 때 NMR이 NmrBindingHandle 매개 변수에 전달한 바인딩 핸들을 저장해야 합니다. WSK 애플리케이션의 ClientAttachProvider 콜백 함수는 Application이 ProviderBindingContext 및 ProviderDispatch 매개 변수의 NmrClientAttachProvider 함수에 전달한 변수에 반환되는 클라이언트 개체(WSK_CLIENT) 및 공급자 디스패치 테이블(WSK_PROVIDER_DISPATCH)에 대한 포인터도 저장해야 합니다. WSK 애플리케이션은 일반적으로 WSK 하위 시스템에 첨부하기 위해 이 데이터를 바인딩 컨텍스트에 저장합니다. WSK 애플리케이션이 WSK 하위 시스템에 성공적으로 연결되면 WSK 애플리케이션의 ClientAttachProvider 콜백 함수는 STATUS_SUCCESS 반환해야 합니다.
NmrClientAttachProvider가 STATUS_NOINTERFACE 반환하는 경우 WSK 애플리케이션은 NmrClientAttachProvider 함수를 다시 호출하여 애플리케이션에서 지원하는 WSK NPI의 대체 버전을 지정하는 다른 WSK_CLIENT_DISPATCH 구조에 ClientDispatch 포인터를 전달하여 WSK 하위 시스템에 연결하려고 할 수 있습니다.
NmrClientAttachProvider 함수에 대한 호출이 STATUS_SUCCESS 반환하지 않고 WSK 애플리케이션이 WSK 하위 시스템에 연결하려고 더 이상 시도하지 않는 경우 WSK 애플리케이션의 ClientAttachProvider 콜백 함수는 NmrClientAttachProvider라고 하기 전에 할당된 리소스를 정리하고 할당 취소해야 합니다. 이 경우 WSK 애플리케이션의 ClientAttachProvider 콜백 함수는 NmrClientAttachProvider 함수에 대한 마지막 호출에서 반환된 상태 코드를 반환해야 합니다.
WSK 애플리케이션이 공급자 모듈에 연결할 수 없다고 결정하면 애플리케이션의 ClientAttachProvider 콜백 함수는 STATUS_NOINTERFACE 반환해야 합니다.
다음 코드 예제에서는 WSK 애플리케이션이 WSK 하위 시스템에 자신을 연결할 수 있는 방법을 보여 줍니다.
// Context structure type for the WSK application's
// binding to the WSK subsystem
typedef struct WSK_APP_BINDING_CONTEXT_ {
HANDLE NmrBindingHandle;
PWSK_CLIENT WskClient;
PWSK_PROVIDER_DISPATCH WskProviderDispatch;
.
. // Other application-specific members
.
} WSK_APP_BINDING_CONTEXT, *PWSK_APP_BINDING_CONTEXT;
// Pool tag used for allocating the binding context
#define BINDING_CONTEXT_POOL_TAG 'tpcb'
// The WSK application uses version 1.0 of WSK
#define WSK_APP_WSK_VERSION MAKE_WSK_VERSION(1,0)
// Structure for the WSK application's dispatch table
const WSK_CLIENT_DISPATCH WskAppDispatch = {
WSK_APP_WSK_VERSION,
0,
NULL // No WskClientEvent callback
};
// ClientAttachProvider NMR API callback function
NTSTATUS
ClientAttachProvider(
IN HANDLE NmrBindingHandle,
IN PVOID ClientContext,
IN PNPI_REGISTRATION_INSTANCE ProviderRegistrationInstance
)
{
PNPI_MODULEID WskProviderModuleId;
PWSK_PROVIDER_CHARACTERISTICS WskProviderCharacteristics;
PWSK_APP_BINDING_CONTEXT BindingContext;
PWSK_CLIENT WskClient;
PWSK_PROVIDER_DISPATCH WskProviderDispatch;
NTSTATUS Status;
// Get pointers to the WSK subsystem's identification and
// characteristics structures
WskProviderModuleId = ProviderRegistrationInstance->ModuleId;
WskProviderCharacteristics =
(PWSK_PROVIDER_CHARACTERISTICS)
ProviderRegistrationInstance->NpiSpecificCharacteristics;
//
// The WSK application can use the data in the structures pointed
// to by ProviderRegistrationInstance, WskProviderModuleId, and
// WskProviderCharacteristics to determine if the WSK application
// can attach to the WSK subsystem.
//
// In this example, the WSK application does not perform any
// checks to determine if it can attach to the WSK subsystem.
//
// Allocate memory for the WSK application's binding
// context structure
BindingContext =
(PWSK_APP_BINDING_CONTEXT)
ExAllocatePoolWithTag(
NonPagedPool,
sizeof(WSK_APP_BINDING_CONTEXT),
BINDING_CONTEXT_POOL_TAG
);
// Check result of allocation
if (BindingContext == NULL)
{
// Return error status code
return STATUS_INSUFFICIENT_RESOURCES;
}
// Initialize the binding context structure
...
// Continue with the attachment to the WSK subsystem
Status = NmrClientAttachProvider(
NmrBindingHandle,
BindingContext,
&WskAppDispatch,
&WskClient,
&WskProviderDispatch
);
// Check result of attachment
if (Status == STATUS_SUCCESS)
{
// Save NmrBindingHandle, WskClient, and
// WskProviderDispatch for future reference
BindingContext->NmrBindingHandle = NmrBindingHandle;
BindingContext->WskClient = WskClient;
BindingContext->WskProviderDispatch = WskProviderDispatch;
}
// Attachment did not succeed
else
{
// Free memory for application's binding context structure
ExFreePoolWithTag(
BindingContext,
BINDING_CONTEXT_POOL_TAG
);
}
// Return result of attachment
return Status;
}