다음을 통해 공유


확장 인터페이스 등록

Winsock Kernel(WSK) 애플리케이션이 소켓을 성공적으로 만든 후에는 WSK 하위 시스템이 지원하는 확장 인터페이스 중 하나 이상에 대해 해당 소켓을 등록할 수 있습니다. WSK 애플리케이션은 WSK 하위 시스템이 첨부하는 동안 애플리케이션에 반환된 WSK_PROVIDER_DISPATCH 구조의 버전 멤버를 검사하여 WSK 하위 시스템이 지원하는 확장 인터페이스 집합을 결정합니다.

각 확장 인터페이스는 WSK NPI와 독립적인 NPI에 의해 정의됩니다. 그러나 확장 인터페이스용 NPI는 NPI 관련 특성을 지원하지 않습니다.

WSK 애플리케이션은 소켓에서 SIO_WSK_REGISTER_EXTENSION 소켓 IOCTL 작업을 실행하여 확장 인터페이스에 등록합니다. 소켓 IOCTL 작업을 실행하는 방법에 대한 자세한 내용은 소켓에서 제어 작업 수행을 참조하세요.

WSK 애플리케이션이 WSK 하위 시스템이 지원하지 않는 확장 인터페이스에 대한 소켓을 등록하려고 하면 SIO_WSK_REGISTER_EXTENSION 소켓 IOCTL 작업은 STATUS_NOT_SUPPORTED 반환합니다.

예를 들어 확장 인터페이스가 다음 코드 예제와 같이 정의되어 있다고 가정합니다.

const NPIID EXAMPLE_EXTIF_NPIID = {...};

typedef struct _EXAMPLE_EXTIF_PROVIDER_DISPATCH {
  .
  . // Function pointers for the functions that are
  . // defined by the extension interface.
  .
} EXAMPLE_EXTIF_PROVIDER_DISPATCH, *PEXAMPLE_EXTIF_PROVIDER_DISPATCH;

typedef struct _EXAMPLE_EXTIF_CLIENT_DISPATCH {
  .
  . // Function pointers for the callback functions
  . // that are defined by the extension interface.
  .
} EXAMPLE_EXTIF_CLIENT_DISPATCH, *PEXAMPLE_EXTIF_CLIENT_DISPATCH;

다음은 WSK 애플리케이션이 연결 지향 소켓에 대해 이 확장 인터페이스에 등록하는 방법을 보여 줍니다.

// Client dispatch structure for the extension interface
const EXAMPLE_EXTIF_CLIENT_DISPATCH ExtIfClientDispatch = {
  .
  . // The WSK application's callback functions
  . // for the extension interface
  .
};

// Context structure type for the example extension interface
typedef struct _EXAMPLE_EXTIF_CLIENT_CONTEXT
{
  const EXAMPLE_EXTIF_PROVIDER_DISPATCH *ExtIfProviderDispatch;
  PVOID ExtIfProviderContext;
    .
    .  // Other application-specific members
    .
} EXAMPLE_EXTIF_CLIENT_CONTEXT, *PEXAMPLE_EXTIF_CLIENT_CONTEXT;

// Function to register the example extension interface
NTSTATUS
  RegisterExampleExtIf(
    PWSK_SOCKET Socket,
    PEXAMPLE_EXTIF_CLIENT_CONTEXT ExtIfClientContext
    )
{
  PWSK_PROVIDER_CONNECTION_DISPATCH Dispatch;
  WSK_EXTENSION_CONTROL_IN ExtensionControlIn;
  WSK_EXTENSION_CONTROL_OUT ExtensionControlOut;
  NTSTATUS Status;

  // Get pointer to the socket's provider dispatch structure
  Dispatch =
    (PWSK_PROVIDER_CONNECTION_DISPATCH)(Socket->Dispatch);

  // Fill in the WSK_EXTENSION_CONTROL_IN structure
  ExtensionControlIn.NpiId = &EXAMPLE_EXTIF_NPIID;
  ExtensionControlIn.ClientContext = ExtIfClientContext;
  ExtensionControlIn.ClientDispatch = &ExtIfClientDispatch;

  // Initiate the IOCTL operation on the socket
  Status =
    Dispatch->WskControlSocket(
      Socket,
      WskIoctl,
      SIO_WSK_REGISTER_EXTENSION,
      0,
      sizeof(WSK_EXTENSION_CONTROL_IN),
      &ExtensionControlIn,
      sizeof(WSK_EXTENSION_CONTROL_OUT),
      &ExtensionControlOut,
      NULL,
      NULL  // No IRP used for this IOCTL operation
      );

  // Check result
  if (Status == STATUS_SUCCESS)
  {
    // Save provider dispatch table and provider context
    ExtIfClientContext->ExtIfProviderDispatch =
      (const EXAMPLE_EXTIF_PROVIDER_DISPATCH *)
        ExtensionControlOut.ProviderDispatch;
    ExtIfClientContext->ExtIfProviderContext =
      ExtensionControlOut.ProviderContext;
  }

  // Return the status of the call to WskControlSocket()
  return Status;
}

WSK 애플리케이션은 소켓 단위로 확장 인터페이스를 등록합니다.