Compartilhar via


Registrando uma interface de extensão

Depois que um aplicativo WSK (Winsock Kernel) tiver criado com êxito um soquete, ele poderá registrar esse soquete para uma ou mais das interfaces de extensão compatíveis com o subsistema WSK. Um aplicativo WSK determina qual conjunto de interfaces de extensão tem suporte pelo subsistema WSK examinando o membro Version da estrutura WSK_PROVIDER_DISPATCH que o subsistema WSK retornou ao aplicativo durante o anexo.

Cada interface de extensão é definida por um NPI que é independente do NPI do WSK. No entanto, observe que os NPIs para interfaces de extensão não dão suporte a características específicas de NPI.

Um aplicativo WSK registra uma interface de extensão executando a operação IOCTL do soquete SIO_WSK_REGISTER_EXTENSION no soquete. Para obter mais informações sobre como executar operações IOCTL de soquete, consulte Executando operações de controle em um soquete.

Se um aplicativo WSK tentar registrar um soquete para uma interface de extensão sem suporte pelo subsistema WSK, a operação IOCTL do soquete SIO_WSK_REGISTER_EXTENSION retornará STATUS_NOT_SUPPORTED.

Por exemplo, suponha que uma interface de extensão seja definida como no exemplo de código a seguir.

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;

Veja a seguir como um aplicativo WSK pode se registrar para essa interface de extensão para um soquete orientado a conexão.

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

Um aplicativo WSK registra interfaces de extensão em uma base de soquete por soquete.